@zoijs/core 1.3.2 → 1.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/CHANGELOG.md +132 -103
- package/README.md +173 -154
- package/package.json +71 -63
- package/src/core/each.js +24 -24
- package/src/core/html.js +24 -5
- package/src/core/renderer.js +472 -470
- package/src/devtools.d.ts +56 -0
- package/src/index.d.ts +185 -185
- package/src/reactivity/core.js +7 -0
- package/src/reactivity/devtools.js +77 -0
- package/src/server.d.ts +53 -0
- package/src/server.js +42 -0
- package/src/utils/security.js +21 -0
package/package.json
CHANGED
|
@@ -1,63 +1,71 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@zoijs/core",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Zoijs — a beginner-friendly, no-build, no-Virtual-DOM frontend framework. Plain HTML, CSS, and JavaScript.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "src/index.js",
|
|
7
|
-
"types": "src/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./src/index.d.ts",
|
|
11
|
-
"default": "./src/index.js"
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
},
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@zoijs/core",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "Zoijs — a beginner-friendly, no-build, no-Virtual-DOM frontend framework. Plain HTML, CSS, and JavaScript.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"types": "src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.d.ts",
|
|
11
|
+
"default": "./src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./devtools": {
|
|
14
|
+
"types": "./src/devtools.d.ts",
|
|
15
|
+
"default": "./src/reactivity/devtools.js"
|
|
16
|
+
},
|
|
17
|
+
"./server": {
|
|
18
|
+
"types": "./src/server.d.ts",
|
|
19
|
+
"default": "./src/server.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"src",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"CHANGELOG.md"
|
|
27
|
+
],
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"author": "Zoijs contributors (https://zoijs.dev)",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"homepage": "https://zoijs.dev",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/Zoijs/zoijs.git",
|
|
38
|
+
"directory": "framework"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/Zoijs/zoijs/issues"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"zoijs",
|
|
45
|
+
"framework",
|
|
46
|
+
"frontend",
|
|
47
|
+
"ui",
|
|
48
|
+
"reactive",
|
|
49
|
+
"reactivity",
|
|
50
|
+
"signals",
|
|
51
|
+
"no-build",
|
|
52
|
+
"no-jsx",
|
|
53
|
+
"no-virtual-dom",
|
|
54
|
+
"fine-grained",
|
|
55
|
+
"beginner-friendly",
|
|
56
|
+
"html",
|
|
57
|
+
"spa"
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"test": "node --test --import ./tests/setup-dom.js",
|
|
61
|
+
"test:unit": "node --test",
|
|
62
|
+
"test:types": "tsc --noEmit -p tsconfig.json",
|
|
63
|
+
"test:browser": "playwright test",
|
|
64
|
+
"dev": "npx serve -l 7310 ."
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@playwright/test": "^1.61.1",
|
|
68
|
+
"jsdom": "^29.1.1",
|
|
69
|
+
"typescript": "^5.9.3"
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/core/each.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
// each() — keyed list rendering (Milestone 3).
|
|
2
|
-
//
|
|
3
|
-
// Returns a small marker object that the renderer recognizes in a text slot and
|
|
4
|
-
// turns into a keyed list binding. Keeping this factory tiny (and separate from
|
|
5
|
-
// the renderer) avoids a circular import — the renderer just checks the marker.
|
|
6
|
-
//
|
|
7
|
-
// ${each(
|
|
8
|
-
// () => todos.get(), // items: a reactive function (or a plain array)
|
|
9
|
-
// todo => todo.id, // keyFn: a stable unique key per item
|
|
10
|
-
// todo => html`<li>...</li>` // renderFn: builds DOM for one item
|
|
11
|
-
// )}
|
|
12
|
-
//
|
|
13
|
-
// When the array changes, items with matching keys reuse their DOM nodes (moved
|
|
14
|
-
// if reordered); new keys are inserted; removed keys are disposed and removed.
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @param {Function|Array} items a function returning the array, or an array
|
|
18
|
-
* @param {Function} keyFn item -> unique key
|
|
19
|
-
* @param {Function} renderFn item -> html() result
|
|
20
|
-
* @returns {{ __zoijsEach: true, items: any, keyFn: Function, renderFn: Function }}
|
|
21
|
-
*/
|
|
22
|
-
export function each(items, keyFn, renderFn) {
|
|
23
|
-
return { __zoijsEach: true, items, keyFn, renderFn };
|
|
24
|
-
}
|
|
1
|
+
// each() — keyed list rendering (Milestone 3).
|
|
2
|
+
//
|
|
3
|
+
// Returns a small marker object that the renderer recognizes in a text slot and
|
|
4
|
+
// turns into a keyed list binding. Keeping this factory tiny (and separate from
|
|
5
|
+
// the renderer) avoids a circular import — the renderer just checks the marker.
|
|
6
|
+
//
|
|
7
|
+
// ${each(
|
|
8
|
+
// () => todos.get(), // items: a reactive function (or a plain array)
|
|
9
|
+
// todo => todo.id, // keyFn: a stable unique key per item
|
|
10
|
+
// todo => html`<li>...</li>` // renderFn: builds DOM for one item
|
|
11
|
+
// )}
|
|
12
|
+
//
|
|
13
|
+
// When the array changes, items with matching keys reuse their DOM nodes (moved
|
|
14
|
+
// if reordered); new keys are inserted; removed keys are disposed and removed.
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {Function|Array} items a function returning the array, or an array
|
|
18
|
+
* @param {Function} keyFn item -> unique key
|
|
19
|
+
* @param {Function} renderFn item -> html() result
|
|
20
|
+
* @returns {{ __zoijsEach: true, items: any, keyFn: Function, renderFn: Function }}
|
|
21
|
+
*/
|
|
22
|
+
export function each(items, keyFn, renderFn) {
|
|
23
|
+
return { __zoijsEach: true, items, keyFn, renderFn };
|
|
24
|
+
}
|
package/src/core/html.js
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
// attribute value, an event, etc. Dynamic values are kept in a separate channel
|
|
8
8
|
// from the static HTML; a value can never change the template's structure.
|
|
9
9
|
//
|
|
10
|
-
// Output of the parse (cached per `strings`)
|
|
11
|
-
//
|
|
10
|
+
// Output of the parse (cached per `strings`) is DOM-free — a static HTML string
|
|
11
|
+
// plus part descriptors. The <template> element is built lazily on first client
|
|
12
|
+
// render; on a server, @zoijs/ssr reads the static HTML + parts directly.
|
|
13
|
+
// html : the static HTML string, with unique markers (no DOM)
|
|
12
14
|
// parts : ordered list of binding descriptors
|
|
13
15
|
// { type: "child" } ← a comment-marker anchor
|
|
14
16
|
// { type: "element", attrs: [AttrPart] } ← element carrying data-zoijs-bind
|
|
@@ -29,10 +31,24 @@ const cache = new WeakMap();
|
|
|
29
31
|
export function html(strings, ...values) {
|
|
30
32
|
let compiled = cache.get(strings);
|
|
31
33
|
if (!compiled) {
|
|
32
|
-
compiled = compile(strings);
|
|
34
|
+
compiled = compile(strings); // pure: a static HTML string + parts, NO DOM
|
|
33
35
|
cache.set(strings, compiled);
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
// The <template> element is created lazily, on first client render — so html()
|
|
38
|
+
// itself touches no DOM and works on a server (where @zoijs/ssr reads the static
|
|
39
|
+
// HTML + parts instead). The brand lets consumers detect a result without
|
|
40
|
+
// tripping the getter.
|
|
41
|
+
return {
|
|
42
|
+
__zoijsTemplate: true,
|
|
43
|
+
parts: compiled.parts,
|
|
44
|
+
hasElements: compiled.hasElements,
|
|
45
|
+
__staticHTML: compiled.html,
|
|
46
|
+
get template() {
|
|
47
|
+
if (!compiled.template) compiled.template = createTemplate(compiled.html);
|
|
48
|
+
return compiled.template;
|
|
49
|
+
},
|
|
50
|
+
values,
|
|
51
|
+
};
|
|
36
52
|
}
|
|
37
53
|
|
|
38
54
|
// ---- scanner ----------------------------------------------------------------
|
|
@@ -239,5 +255,8 @@ function compile(strings) {
|
|
|
239
255
|
}
|
|
240
256
|
|
|
241
257
|
const hasElements = parts.some((p) => p.type === "element");
|
|
242
|
-
|
|
258
|
+
// Pure output: the static HTML string and the part descriptors. The DOM
|
|
259
|
+
// <template> is built later, lazily (see html()), so compile() needs no DOM and
|
|
260
|
+
// its result can be serialized on a server.
|
|
261
|
+
return { html: out, parts, hasElements, template: null };
|
|
243
262
|
}
|