@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.
- package/dist/index.d.ts +481 -0
- package/dist/index.js +836 -0
- package/docs/context.md +85 -0
- package/docs/jay-element.md +81 -0
- package/docs/kindergarten.md +51 -0
- package/docs/refs.md +200 -0
- package/docs/runtime.md +310 -0
- package/package.json +43 -0
- package/readme.md +113 -0
package/docs/runtime.md
ADDED
|
@@ -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.
|