@jay-framework/runtime 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,310 @@
1
+ # Generated JayElement creation Functions
2
+
3
+ > note: this is an "how it works doc"
4
+
5
+ While in Jay the Jay compiler generates the code for `JayElement` from `jay-html` files, the below explains how to
6
+ code Jay elements directly. In most cases, it is not to be coded directly.
7
+
8
+ ```typescript
9
+ import { element as e, dynamicText as dt, ConstructContext } from '@jay-framework/runtime';
10
+
11
+ interface ViewState {
12
+ text: string;
13
+ text2: string;
14
+ }
15
+
16
+ export default function render(viewState: ViewState) {
17
+ return ConstructContext.withRootContext(viewState, () =>
18
+ e('div', {}, [
19
+ e('div', {}, [dt((vs) => vs.text)]),
20
+ e('div', {}, ['static']),
21
+ e('div', {}, [dt((vs) => vs.text2)]),
22
+ ]),
23
+ );
24
+ }
25
+ ```
26
+
27
+ # Jay element building blocks
28
+
29
+ ## element
30
+
31
+ The `element` function creates a simple 'static' element - element who has a fixed number of dom children. The static
32
+ element itself can have dynamic attributes or inner text. To create dynamic number of dom children use `dynamicElement`
33
+ discussed below.
34
+
35
+ The `element` function signature is
36
+
37
+ ```typescript
38
+ declare function element<ViewState>(
39
+ tagName: string,
40
+ attributes: Attributes<ViewState>,
41
+ children?: Array<JayElement<ViewState> | TextElement<ViewState> | string>,
42
+ ): BaseJayElement<ViewState>;
43
+ ```
44
+
45
+ at which
46
+
47
+ - `ViewState` - is the type of the current view state, used as input to the update function for this element
48
+ - `tagName` - the name of the HTML tag, like `div` or `button`
49
+ - `attributes` - an object who's keys are attribute names, and values are static attributes values (strings), dynamic
50
+ attributes `DynamicAttribute<T>` or dynamic properties `DynamicProperty<T>`
51
+ - `children` - the children of the element - can be more elements, static text (string) or dynamic text (TextElement<T>)
52
+
53
+ Given the Jay HTML
54
+
55
+ ```html
56
+ <button>-</button>
57
+ ```
58
+
59
+ It is compiled into
60
+
61
+ ```javascript
62
+ import { element as e } from '@jay-framework/runtime';
63
+ e('button', {}, ['-']);
64
+ ```
65
+
66
+ ## Static Text Content
67
+
68
+ Static text content is supported as a string constant that is passed as a member of the `children` parameter of the
69
+ `element` or `dynamicElement` functions.
70
+
71
+ A simple example
72
+
73
+ ```typescript
74
+ e('div', {}, ['some static text']);
75
+ ```
76
+
77
+ ## Static Attribute Value
78
+
79
+ Static attribute values are supported as a string constant that is passed as a member of the `attributes` parameter of
80
+ the
81
+ `element` or `dynamicElement` functions.
82
+
83
+ A simple example
84
+
85
+ ```typescript
86
+ e(
87
+ 'div',
88
+ {
89
+ 'data-attribute': 'some static value',
90
+ class: 'class1 class2',
91
+ style: {
92
+ border: '1px solid red',
93
+ 'border-radius': '5px',
94
+ },
95
+ },
96
+ [],
97
+ );
98
+ ```
99
+
100
+ ## dynamicElement
101
+
102
+ Dynamic element is a constructor for an element that supports dynamic adding and removing children. Internally, it is
103
+ using a [Kindergarten](kindergarten.md) to manage groups of childrens.
104
+
105
+ The signature of dynamic element is
106
+
107
+ ```typescript
108
+ declare function dynamicElement<TViewState>(
109
+ tagName: string,
110
+ attributes: Attributes<TViewState>,
111
+ children?: Array<
112
+ | Conditional<TViewState>
113
+ | ForEach<TViewState, any>
114
+ | TextElement<TViewState>
115
+ | JayElement<TViewState>
116
+ | string
117
+ >,
118
+ ): BaseJayElement<TViewState>;
119
+ ```
120
+
121
+ at which
122
+
123
+ - `ViewState` - is the type of the current view state, used as input to the update function for this element
124
+ - `tagName` - the name of the HTML tag, like `div` or `button`
125
+ - `attributes` - an object who's keys are attribute names, and values are static attributes values (strings), dynamic
126
+ attributes `DynamicAttribute<T>` or dynamic properties `DynamicProperty<T>`
127
+ - `children` - the children of the element - can be any of
128
+ - `Conditional` - for supporting conditional children, using the `if` directive in the jay file
129
+ - `ForEach` - for supporting collection children, using the `forEach` directive in the jay file
130
+ - `elements` - for child elements, who can be dynamic, but the element inclusion itself is static
131
+ - static text (string)
132
+ - dynamic text (TextElement<T>)
133
+
134
+ ## dynamicText
135
+
136
+ Dynamic Text creates a text element that is dynamic and can be updated as data changes.
137
+
138
+ Dynamic text looks like
139
+
140
+ ```typescript
141
+ import { dynamicText as dt } from '@jay-framework/runtime';
142
+ dt((vs) => vs.text);
143
+ dt((vs) => `${vs.firstName} ${vs.lastName}`);
144
+ ```
145
+
146
+ The signature of dynamic text is
147
+
148
+ ```typescript
149
+ declare function dynamicText<ViewState>(
150
+ textContent: (vs: ViewState) => string,
151
+ ): TextElement<ViewState>;
152
+ ```
153
+
154
+ at which
155
+
156
+ - `textContent` - a function that renders the text from the current data item
157
+
158
+ ## dynamicAttribute
159
+
160
+ Dynamic Attribute creates an attribute whos value updates as the data changes.
161
+
162
+ Dynamic Attribute looks like
163
+
164
+ ```typescript
165
+ {
166
+ "class": da(vs => `${vs.bool1 ? 'main' : 'second'}`)
167
+ }
168
+ ```
169
+
170
+ The signature of dynamic attribute is
171
+
172
+ ```typescript
173
+ declare function dynamicAttribute<ViewState, S>(
174
+ attributeValue: (data: ViewState) => string,
175
+ ): DynamicAttribute<ViewState>;
176
+ ```
177
+
178
+ at which
179
+
180
+ - `attributeValue` - a function that renders the attribute value from the current data item
181
+
182
+ ## dynamicProperty
183
+
184
+ Dynamic Property creates a property whos value updates as the data changes.
185
+
186
+ Dynamic Property looks like
187
+
188
+ ```typescript
189
+ {
190
+ textContent: dp((vs) => `${vs.bool1 ? 'main' : 'second'}`);
191
+ }
192
+ ```
193
+
194
+ The signature of dynamic property is
195
+
196
+ ```typescript
197
+ declare function dynamicAttribute<ViewState, S>(
198
+ propertyValue: (data: ViewState) => string,
199
+ ): DynamicAttribute<ViewState>;
200
+ ```
201
+
202
+ at which
203
+
204
+ - `propertyValue` - a function that renders the property value from the current data item
205
+
206
+ ## Jay Component
207
+
208
+ Jay Components are logic wrappers over a Jay Element, and can be coded using any coding methodology. They have to
209
+ conform to the Jay Component interface below
210
+
211
+ ```typescript
212
+ interface JayComponent<Props, ViewState, jayElement extends BaseJayElement<ViewState>> {
213
+ element: jayElement;
214
+ update: updateFunc<Props>;
215
+ mount: mountFunc;
216
+ unmount: mountFunc;
217
+ }
218
+ ```
219
+
220
+ at which
221
+
222
+ - `Props` are the type of the component propeties, used to create and update the component
223
+ - `ViewState` is the data type of the component's element
224
+ - `jayElement` is the concrete type of the component's element
225
+ - `element` is a JayElement of this component
226
+ - `update`, `mount` and `unmount` have the same signature as the Jay Element functions allowing the component to wrap
227
+ the element functions to add update and lifecycle logic.
228
+
229
+ ## childComp
230
+
231
+ Child components are components nested into the jay file of another component. The nesting itself is done using
232
+ the `childComp` constructor which accepts a function that returns a `JayComponent`
233
+
234
+ using child components looks like
235
+
236
+ ```typescript
237
+ childComp(
238
+ (props: ItemData) => Item(props),
239
+ (vs) => ({ text: vs.staticItem }),
240
+ );
241
+ ```
242
+
243
+ The signature of `childComp` is
244
+
245
+ ```typescript
246
+ declare function childComp<
247
+ ParentT,
248
+ Props,
249
+ ChildT,
250
+ ChildElement extends JayElement<ChildT>,
251
+ ChildComp extends JayComponent<Props, ChildT, ChildElement>,
252
+ >(
253
+ compCreator: (props: Props) => ChildComp,
254
+ getProps: (t: ParentT) => Props,
255
+ ): BaseJayElement<ParentT>;
256
+ ```
257
+
258
+ at which
259
+
260
+ - `ParentT` is the view data type of the parent element
261
+ - `Props` is the type of the component properties
262
+ - `ChildT` is the view data type of the child component element
263
+ - `ChildElement` is the child component element type
264
+ - `childComp` is the child component type
265
+ - `compCreator` is a function that given props, returns the component instance
266
+ - `getProps` is a function that given the parent element view state, returns the props of the component
267
+
268
+ ## forEach
269
+
270
+ ```typescript
271
+ declare function forEach<ViewState, Item>(
272
+ getItems: (T: any) => Array<Item>,
273
+ elemCreator: (Item: any) => JayElement<Item>,
274
+ matchBy: string,
275
+ ): ForEach<ViewState, Item>;
276
+ ```
277
+
278
+ ## conditional
279
+
280
+ ```typescript
281
+ declare function conditional<ViewState>(
282
+ condition: (newData: ViewState) => boolean,
283
+ elem: JayElement<ViewState> | TextElement<ViewState> | string,
284
+ ): Conditional<ViewState>;
285
+ ```
286
+
287
+ ## ConstructionContext
288
+
289
+ ```typescript
290
+ declare class ConstructContext<A extends Array<any>> {
291
+ refManager: ReferencesManager;
292
+ data: A;
293
+ forStaticElements: boolean;
294
+
295
+ constructor(data: A, dm?: ReferencesManager, forStaticElements?: boolean);
296
+
297
+ get currData(): any;
298
+
299
+ static acc<A extends Array<any>, B>(a: A, b: B): [...A, B];
300
+
301
+ forItem<T>(t: T): ConstructContext<[...A, T]>;
302
+
303
+ static root<T>(t: T): ConstructContext<[T]>;
304
+
305
+ static withRootContext<T, A extends ConstructContext<[T]>>(
306
+ t: T,
307
+ elementConstructor: () => BaseJayElement<T>,
308
+ ): JayElement<T>;
309
+ }
310
+ ```
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@jay-framework/runtime",
3
+ "version": "0.5.0",
4
+ "type": "module",
5
+ "license": "Apache-2.0",
6
+ "main": "dist/index.js",
7
+ "files": [
8
+ "dist",
9
+ "docs",
10
+ "readme.md"
11
+ ],
12
+ "scripts": {
13
+ "build": "npm run build:js && npm run build:types && npm run build:fix-dts",
14
+ "build:watch": "npm run build:js -- --watch & npm run build:types -- --watch & npm run build:watch:fix-dts",
15
+ "build:js": "vite build",
16
+ "build:types": "tsup lib/index.ts --dts-only --format esm",
17
+ "build:check-types": "tsc",
18
+ "build:fix-dts": "node scripts/fix-dts.js",
19
+ "build:watch:fix-dts": "nodemon --watch dist -e d.ts -x \"npm run build:fix-dts\"",
20
+ "clean": "rimraf dist",
21
+ "confirm": "npm run clean && npm run build && npm run build:check-types && npm run test",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest"
24
+ },
25
+ "dependencies": {
26
+ "@jay-framework/list-compare": "workspace:^",
27
+ "@jay-framework/reactive": "workspace:^",
28
+ "jsdom": "^23.2.0"
29
+ },
30
+ "devDependencies": {
31
+ "@jay-framework/dev-environment": "workspace:^",
32
+ "@testing-library/jest-dom": "^6.2.0",
33
+ "@types/jsdom": "^21.1.6",
34
+ "@types/node": "^20.11.5",
35
+ "nodemon": "^3.0.3",
36
+ "replace-in-file": "^7.1.0",
37
+ "rimraf": "^5.0.5",
38
+ "tsup": "^8.0.1",
39
+ "typescript": "^5.3.3",
40
+ "vite": "^5.0.11",
41
+ "vitest": "^1.2.1"
42
+ }
43
+ }
package/readme.md ADDED
@@ -0,0 +1,113 @@
1
+ # Jay Runtime
2
+
3
+ The Jay Runtime library is an efficient dom manipulation library, built to be the output of code generation (`@jay-framework/compiler`).
4
+ See the `@jay-framework/compiler` docs for the format of the `jay-html` file that compiles to `@jay-framework/runtime` types.
5
+
6
+ # Usage
7
+
8
+ For example, a simple a jay-html is
9
+
10
+ ```html
11
+ <html>
12
+ <head>
13
+ <script type="application/yaml-jay">
14
+ data:
15
+ count: number
16
+ </script>
17
+ </head>
18
+ <body>
19
+ <div>
20
+ <button ref="subtracter">-</button>
21
+ <span style="margin: 0 16px">{count}</span>
22
+ <button ref="adder-button">+</button>
23
+ </div>
24
+ </body>
25
+ </html>
26
+ ```
27
+
28
+ which is then compiled into
29
+
30
+ ```typescript
31
+ import {
32
+ JayElement,
33
+ RenderElement,
34
+ HTMLElementProxy,
35
+ RenderElementOptions,
36
+ } from '@jay-framework/runtime';
37
+
38
+ export interface CounterViewState {
39
+ count: number;
40
+ }
41
+
42
+ export interface CounterElementRefs {
43
+ subtracter: HTMLElementProxy<CounterViewState, HTMLButtonElement>;
44
+ adderButton: HTMLElementProxy<CounterViewState, HTMLButtonElement>;
45
+ }
46
+
47
+ export type CounterElement = JayElement<CounterViewState, CounterElementRefs>;
48
+ export type CounterElementRender = RenderElement<
49
+ CounterViewState,
50
+ CounterElementRefs,
51
+ CounterElement
52
+ >;
53
+ export type CounterElementPreRender = [CounterElementRefs, CounterElementRender];
54
+
55
+ export declare function render(options?: RenderElementOptions): CounterElementPreRender;
56
+ ```
57
+
58
+ A Jay element can be used directly (without a Jay Component) as the below example.
59
+
60
+ ```typescript
61
+ import { render } from 'counter.jay-html';
62
+
63
+ const [refs, render2] = render();
64
+ const jayElement: CounterElement = render2({ count: 12 });
65
+ ```
66
+
67
+ > However, in most cases, the generated `JayElement` is used by a jay component, and there is no need to use Jay Element members directly
68
+
69
+ The members above in the jay element creation sequence:
70
+
71
+ - `render`: the generated function from the `jay-html` file.
72
+ - `refs`: an object holding the references for DOM elements or child components.
73
+ In the example above, it has two members - `subtracter` and `adderButton`.
74
+ Read more about `refs` in [refs.md](./docs/refs.md)
75
+ - `render2`: a function, that given the element view state will create the actual element, including the DOM, `update`, `mount` and `unmount` functions
76
+ as well as wire the DOM into the `refs`.
77
+ - `jayElement: CounterElement = JayElement<CounterViewState, CounterElementRefs>`: the created Jay element
78
+
79
+ The `JayElement<ViewState, refs>` is defined as
80
+
81
+ ```typescript
82
+ interface BaseJayElement<ViewState> {
83
+ dom: HTMLElement;
84
+ update: updateFunc<ViewState>;
85
+ mount: mountFunc;
86
+ unmount: mountFunc;
87
+ }
88
+
89
+ interface JayElement<ViewState, Refs> extends BaseJayElement<ViewState> {
90
+ refs: Refs;
91
+ }
92
+ ```
93
+
94
+ ### Properties:
95
+
96
+ - `dom`: An HTMLElement instance representing the DOM element associated with this JayElement.
97
+ This is the element that will be rendered to the page, and can be added as a child to any other DOM element.
98
+ - `update`: A function of type `type updateFunc<ViewState> = (newData: ViewState) => void`.
99
+ This function is responsible for updating the internal state (ViewState) of the JayElement and re-rendering its
100
+ DOM representation if necessary. The ViewState is considered an **immutable** object by the internals of the `update` function.
101
+ - `mount`: A function of type `type mountFunc = () => void`. This function is used to mount a previously unmounted `JayElement`.
102
+ `JayElement`s are created in mount state.
103
+ - `unmount`: A function of type `type mountFunc = () => void`. This function is designed to be called when the JayElement is removed from the DOM.
104
+ - `refs`: This property holds references by `ref` to DOM elements or other components within the JayElement.
105
+ These references can be used to set event listeners, interact with child elements or component APIs.
106
+ Read more about `refs` in [refs.md](./docs/refs.md).
107
+
108
+ ## implementation details
109
+
110
+ - See the [Generated JayElement](./docs/jay-element.md) for the details of the `jay-html` generated target.
111
+ - See the [Generated JayElement creation Functions](./docs/runtime.md) for the details of the jay element creation functions used by the `jay-html` generated target.
112
+ - See the [Context Implementation](./docs/context.md) for the details of the context API internals (not the public API).
113
+ - See the [Kindergarten](./docs/kindergarten.md) for the class responsible to manage the children of a DOM element.