neutronium 2.9.3 → 2.9.5
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 +1 -1
- package/ts-neutronium/index.d.ts +117 -0
- package/ts-neutronium/package.json +14 -0
package/package.json
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// @types/netronium/index.d.ts
|
|
2
|
+
|
|
3
|
+
type StateUpdater<T> = (newValue: T) => void;
|
|
4
|
+
type Component<T = any> = (props?: T) => HTMLElement | DocumentFragment;
|
|
5
|
+
|
|
6
|
+
let globalState: any[] = [];
|
|
7
|
+
let stateIndex = 0;
|
|
8
|
+
|
|
9
|
+
// Reset index before each render
|
|
10
|
+
export function resetStateIndex(): void {
|
|
11
|
+
stateIndex = 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Custom useState
|
|
15
|
+
export function useState<T>(initialValue: T): [T, StateUpdater<T>] {
|
|
16
|
+
const currentIndex = stateIndex;
|
|
17
|
+
|
|
18
|
+
if (globalState[currentIndex] === undefined) {
|
|
19
|
+
globalState[currentIndex] = initialValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function setState(newValue: T): void {
|
|
23
|
+
globalState[currentIndex] = newValue;
|
|
24
|
+
|
|
25
|
+
// Re-render
|
|
26
|
+
const root = window.__NEUTRONIUM_ROOT__ as HTMLElement | null;
|
|
27
|
+
const renderFn = window.__NEUTRONIUM_RENDER_FN__ as (() => Node) | null;
|
|
28
|
+
|
|
29
|
+
if (root && typeof renderFn === 'function') {
|
|
30
|
+
root.innerHTML = '';
|
|
31
|
+
resetStateIndex();
|
|
32
|
+
const newVNode = renderFn();
|
|
33
|
+
root.appendChild(newVNode);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
stateIndex++;
|
|
38
|
+
return [globalState[currentIndex], setState];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// JSX-compatible hyperscript function
|
|
42
|
+
export function h(
|
|
43
|
+
type: string | Component,
|
|
44
|
+
props: { [key: string]: any } = {},
|
|
45
|
+
...children: any[]
|
|
46
|
+
): HTMLElement | DocumentFragment {
|
|
47
|
+
if (typeof type === 'function') {
|
|
48
|
+
props = props || {};
|
|
49
|
+
props.children = children.flat();
|
|
50
|
+
return type(props);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const el = document.createElement(type);
|
|
54
|
+
|
|
55
|
+
for (const [key, value] of Object.entries(props)) {
|
|
56
|
+
if (key.startsWith('on') && typeof value === 'function') {
|
|
57
|
+
el.addEventListener(key.slice(2).toLowerCase(), value);
|
|
58
|
+
} else if (key === 'ref' && typeof value === 'function') {
|
|
59
|
+
value(el);
|
|
60
|
+
} else {
|
|
61
|
+
el.setAttribute(key, value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
children.flat().forEach(child => {
|
|
66
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
67
|
+
el.appendChild(document.createTextNode(child));
|
|
68
|
+
} else if (child instanceof Node) {
|
|
69
|
+
el.appendChild(child);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return el;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Mount app to DOM
|
|
77
|
+
export function createApp(component: () => Node) {
|
|
78
|
+
return {
|
|
79
|
+
mount(selector: string | HTMLElement): Node | null {
|
|
80
|
+
const root =
|
|
81
|
+
typeof selector === 'string'
|
|
82
|
+
? document.querySelector(selector)
|
|
83
|
+
: selector;
|
|
84
|
+
|
|
85
|
+
if (!root) {
|
|
86
|
+
console.error(`❌ Root element '${selector}' not found`);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
window.__NEUTRONIUM_ROOT__ = root;
|
|
91
|
+
window.__NEUTRONIUM_RENDER_FN__ = component;
|
|
92
|
+
|
|
93
|
+
resetStateIndex();
|
|
94
|
+
const vnode = component();
|
|
95
|
+
root.innerHTML = '';
|
|
96
|
+
root.appendChild(vnode);
|
|
97
|
+
|
|
98
|
+
return vnode;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Fragment support
|
|
104
|
+
export function Fragment(props: { children?: any[] }): DocumentFragment {
|
|
105
|
+
const frag = document.createDocumentFragment();
|
|
106
|
+
const children = props.children ?? [];
|
|
107
|
+
|
|
108
|
+
(Array.isArray(children) ? children : [children]).forEach(child => {
|
|
109
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
110
|
+
frag.appendChild(document.createTextNode(child));
|
|
111
|
+
} else if (child instanceof Node) {
|
|
112
|
+
frag.appendChild(child);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return frag;
|
|
117
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ts-neutronium",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"types": "./index.d.ts"
|
|
14
|
+
}
|