what-core 0.4.0 → 0.4.1
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/package.json +7 -1
- package/src/dom.js +26 -0
- package/src/h.js +3 -0
- package/src/jsx-dev-runtime.js +19 -0
- package/src/jsx-runtime.js +21 -0
- package/src/reactive.js +20 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "what-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "What Framework - The closest framework to vanilla JS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/what.js",
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
"import": "./src/index.js",
|
|
13
13
|
"require": "./dist/what.cjs"
|
|
14
14
|
},
|
|
15
|
+
"./jsx-runtime": {
|
|
16
|
+
"import": "./src/jsx-runtime.js"
|
|
17
|
+
},
|
|
18
|
+
"./jsx-dev-runtime": {
|
|
19
|
+
"import": "./src/jsx-dev-runtime.js"
|
|
20
|
+
},
|
|
15
21
|
"./render": {
|
|
16
22
|
"import": "./src/render.js"
|
|
17
23
|
},
|
package/src/dom.js
CHANGED
|
@@ -101,6 +101,18 @@ function createDOM(vnode, parent, isSvg) {
|
|
|
101
101
|
return document.createTextNode(String(vnode));
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
// Reactive function child — creates a text node that updates fine-grained
|
|
105
|
+
if (typeof vnode === 'function') {
|
|
106
|
+
const textNode = document.createTextNode('');
|
|
107
|
+
effect(() => {
|
|
108
|
+
const val = vnode();
|
|
109
|
+
// If the function returns a vnode, we can't upgrade a text node to an element.
|
|
110
|
+
// For now, stringify the result. Component-level re-render handles complex cases.
|
|
111
|
+
textNode.textContent = (val == null || val === false || val === true) ? '' : String(val);
|
|
112
|
+
});
|
|
113
|
+
return textNode;
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
// Array (fragment)
|
|
105
117
|
if (Array.isArray(vnode)) {
|
|
106
118
|
const frag = document.createDocumentFragment();
|
|
@@ -615,6 +627,20 @@ function patchNode(parent, domNode, vnode) {
|
|
|
615
627
|
return placeholder;
|
|
616
628
|
}
|
|
617
629
|
|
|
630
|
+
// Reactive function child — replace whatever's there with a reactive text node
|
|
631
|
+
if (typeof vnode === 'function') {
|
|
632
|
+
const textNode = document.createTextNode('');
|
|
633
|
+
effect(() => {
|
|
634
|
+
const val = vnode();
|
|
635
|
+
textNode.textContent = (val == null || val === false || val === true) ? '' : String(val);
|
|
636
|
+
});
|
|
637
|
+
if (domNode && domNode.parentNode) {
|
|
638
|
+
disposeTree(domNode);
|
|
639
|
+
parent.replaceChild(textNode, domNode);
|
|
640
|
+
}
|
|
641
|
+
return textNode;
|
|
642
|
+
}
|
|
643
|
+
|
|
618
644
|
// Text
|
|
619
645
|
if (typeof vnode === 'string' || typeof vnode === 'number') {
|
|
620
646
|
const text = String(vnode);
|
package/src/h.js
CHANGED
|
@@ -36,6 +36,9 @@ function flattenChildren(children) {
|
|
|
36
36
|
out.push(...flattenChildren(child));
|
|
37
37
|
} else if (typeof child === 'object' && child._vnode) {
|
|
38
38
|
out.push(child);
|
|
39
|
+
} else if (typeof child === 'function') {
|
|
40
|
+
// Reactive child — preserve function for fine-grained DOM updates
|
|
41
|
+
out.push(child);
|
|
39
42
|
} else {
|
|
40
43
|
// Text node
|
|
41
44
|
out.push(String(child));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// What Framework — JSX Dev Runtime
|
|
2
|
+
// Same as jsx-runtime but used in development mode by Vite.
|
|
3
|
+
|
|
4
|
+
import { h, Fragment } from './h.js';
|
|
5
|
+
|
|
6
|
+
export { Fragment };
|
|
7
|
+
|
|
8
|
+
export function jsxDEV(type, props, key) {
|
|
9
|
+
if (props == null) return h(type, null);
|
|
10
|
+
const { children, ...rest } = props;
|
|
11
|
+
if (key !== undefined) rest.key = key;
|
|
12
|
+
if (children === undefined) return h(type, rest);
|
|
13
|
+
if (Array.isArray(children)) return h(type, rest, ...children);
|
|
14
|
+
return h(type, rest, children);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Also export jsx/jsxs for compatibility — some bundlers use these even in dev
|
|
18
|
+
export const jsx = jsxDEV;
|
|
19
|
+
export const jsxs = jsxDEV;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// What Framework — JSX Automatic Runtime
|
|
2
|
+
// Used by: jsxImportSource: "what-framework" (or "what-core")
|
|
3
|
+
// Vite/esbuild import this automatically when using the "react-jsx" transform.
|
|
4
|
+
|
|
5
|
+
import { h, Fragment } from './h.js';
|
|
6
|
+
|
|
7
|
+
export { Fragment };
|
|
8
|
+
|
|
9
|
+
// Automatic JSX transform signature: jsx(type, { children, ...props }, key)
|
|
10
|
+
// What's h() signature: h(type, props, ...children)
|
|
11
|
+
export function jsx(type, props, key) {
|
|
12
|
+
if (props == null) return h(type, null);
|
|
13
|
+
const { children, ...rest } = props;
|
|
14
|
+
if (key !== undefined) rest.key = key;
|
|
15
|
+
if (children === undefined) return h(type, rest);
|
|
16
|
+
if (Array.isArray(children)) return h(type, rest, ...children);
|
|
17
|
+
return h(type, rest, children);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// jsxs = jsx for static children (multiple). Same behavior for What.
|
|
21
|
+
export const jsxs = jsx;
|
package/src/reactive.js
CHANGED
|
@@ -17,29 +17,38 @@ export function signal(initial) {
|
|
|
17
17
|
let value = initial;
|
|
18
18
|
const subs = new Set();
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
// Unified getter/setter: sig() reads, sig(newVal) writes
|
|
21
|
+
function sig(...args) {
|
|
22
|
+
if (args.length === 0) {
|
|
23
|
+
// Read
|
|
24
|
+
if (currentEffect) {
|
|
25
|
+
subs.add(currentEffect);
|
|
26
|
+
currentEffect.deps.push(subs);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
24
29
|
}
|
|
25
|
-
|
|
30
|
+
// Write
|
|
31
|
+
const nextVal = typeof args[0] === 'function' ? args[0](value) : args[0];
|
|
32
|
+
if (Object.is(value, nextVal)) return;
|
|
33
|
+
value = nextVal;
|
|
34
|
+
notify(subs);
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
sig.set = (next) => {
|
|
29
38
|
const nextVal = typeof next === 'function' ? next(value) : next;
|
|
30
39
|
if (Object.is(value, nextVal)) return;
|
|
31
40
|
value = nextVal;
|
|
32
41
|
notify(subs);
|
|
33
42
|
};
|
|
34
43
|
|
|
35
|
-
|
|
44
|
+
sig.peek = () => value;
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
return effect(() => fn(
|
|
46
|
+
sig.subscribe = (fn) => {
|
|
47
|
+
return effect(() => fn(sig()));
|
|
39
48
|
};
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
return
|
|
50
|
+
sig._signal = true;
|
|
51
|
+
return sig;
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
// --- Computed ---
|