@novility/react-converter-core 1.0.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/README.md +76 -0
- package/dist/index.js +1338 -0
- package/dist/runtime/dom.js +114 -0
- package/dist/runtime/hooks.js +223 -0
- package/package.json +51 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const domRuntime = `
|
|
2
|
+
function __appendChild(parent, child) {
|
|
3
|
+
if (child === null || child === undefined || child === false || child === true) return;
|
|
4
|
+
if (Array.isArray(child)) {
|
|
5
|
+
for (const item of child) __appendChild(parent, item);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const isNode = child && (child.nodeType || (typeof Node !== "undefined" && child instanceof Node));
|
|
9
|
+
if (isNode) {
|
|
10
|
+
parent.appendChild(child);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
parent.appendChild(document.createTextNode(String(child)));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function __renderInstance(instance) {
|
|
17
|
+
const nextRoot = instance.component(instance.props || {});
|
|
18
|
+
if (instance.root && instance.root.parentNode) {
|
|
19
|
+
instance.root.parentNode.replaceChild(nextRoot, instance.root);
|
|
20
|
+
} else {
|
|
21
|
+
instance.mountTarget.appendChild(nextRoot);
|
|
22
|
+
}
|
|
23
|
+
instance.root = nextRoot;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function __mount(component, mountTarget, props) {
|
|
27
|
+
const instance = {
|
|
28
|
+
component,
|
|
29
|
+
props: props || {},
|
|
30
|
+
root: null,
|
|
31
|
+
mountTarget: mountTarget || document.body,
|
|
32
|
+
};
|
|
33
|
+
__renderInstance(instance);
|
|
34
|
+
return instance;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function __setAttribute(el, name, value) {
|
|
38
|
+
if (value === null || value === undefined || value === false) return;
|
|
39
|
+
el.setAttribute(name, String(value));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function __setStyle(el, value) {
|
|
43
|
+
if (!value) return;
|
|
44
|
+
if (typeof value === "string") {
|
|
45
|
+
el.setAttribute("style", value);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (typeof value !== "object") return;
|
|
49
|
+
for (const key of Object.keys(value)) {
|
|
50
|
+
const styleValue = value[key];
|
|
51
|
+
if (styleValue === null || styleValue === undefined) continue;
|
|
52
|
+
if (key.includes("-")) {
|
|
53
|
+
el.style.setProperty(key, String(styleValue));
|
|
54
|
+
} else {
|
|
55
|
+
el.style[key] = String(styleValue);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function __addEventListener(el, event, handler) {
|
|
61
|
+
if (typeof handler !== "function") return;
|
|
62
|
+
el.addEventListener(event, handler);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function __renderComponent(component, props) {
|
|
66
|
+
return component(props || {});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function __toCamelCase(name) {
|
|
70
|
+
return String(name).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function __getElementProps(el, lightChildren) {
|
|
74
|
+
const props = {};
|
|
75
|
+
if (!el || !el.attributes) return props;
|
|
76
|
+
for (const attr of Array.from(el.attributes)) {
|
|
77
|
+
if (attr.name === 'data-props') continue;
|
|
78
|
+
const key = __toCamelCase(attr.name);
|
|
79
|
+
props[key] = attr.value;
|
|
80
|
+
}
|
|
81
|
+
const dataProps = el.getAttribute && el.getAttribute('data-props');
|
|
82
|
+
if (dataProps) {
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(dataProps);
|
|
85
|
+
if (parsed && typeof parsed === 'object') {
|
|
86
|
+
Object.assign(props, parsed);
|
|
87
|
+
}
|
|
88
|
+
} catch (_) {}
|
|
89
|
+
}
|
|
90
|
+
if (lightChildren && lightChildren.length) {
|
|
91
|
+
props.children = lightChildren;
|
|
92
|
+
}
|
|
93
|
+
return props;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function __getRootProps() {
|
|
97
|
+
if (typeof window !== "undefined" && window.__COMPILER_PROPS__) {
|
|
98
|
+
return window.__COMPILER_PROPS__ || {};
|
|
99
|
+
}
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function __applyShadowStyles(cssText, styleId, shadowRoot, host) {
|
|
104
|
+
if (!cssText || !shadowRoot) return;
|
|
105
|
+
if (host && host.__styleSheet) return;
|
|
106
|
+
if (typeof injectStyles === "function") {
|
|
107
|
+
injectStyles(cssText, styleId, shadowRoot);
|
|
108
|
+
if (host) host.__styleSheet = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
export {
|
|
113
|
+
domRuntime
|
|
114
|
+
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
function getHookRuntime(hooksUsed) {
|
|
2
|
+
const hooks = new Set(hooksUsed);
|
|
3
|
+
const needsDeps = hooks.has("useEffect") || hooks.has("useMemo") || hooks.has("useCallback");
|
|
4
|
+
const needsEffects = hooks.has("useEffect");
|
|
5
|
+
let code = "";
|
|
6
|
+
code += "let __currentInstance = null;\n";
|
|
7
|
+
code += "function __getCurrentInstance() {\n";
|
|
8
|
+
code += " if (!__currentInstance) {\n";
|
|
9
|
+
code += ' throw new Error("Hooks can only be called inside a component render.");\n';
|
|
10
|
+
code += " }\n";
|
|
11
|
+
code += " return __currentInstance;\n";
|
|
12
|
+
code += "}\n\n";
|
|
13
|
+
if (needsDeps) {
|
|
14
|
+
code += "function __areHookDepsEqual(prevDeps, nextDeps) {\n";
|
|
15
|
+
code += " if (!Array.isArray(prevDeps) || !Array.isArray(nextDeps)) return false;\n";
|
|
16
|
+
code += " if (prevDeps.length !== nextDeps.length) return false;\n";
|
|
17
|
+
code += " for (let i = 0; i < prevDeps.length; i += 1) {\n";
|
|
18
|
+
code += " if (!Object.is(prevDeps[i], nextDeps[i])) return false;\n";
|
|
19
|
+
code += " }\n";
|
|
20
|
+
code += " return true;\n";
|
|
21
|
+
code += "}\n\n";
|
|
22
|
+
}
|
|
23
|
+
if (needsEffects) {
|
|
24
|
+
code += "function __flushEffects(instance) {\n";
|
|
25
|
+
code += " if (!instance.pendingEffects.length) return;\n";
|
|
26
|
+
code += " const effects = instance.pendingEffects.slice();\n";
|
|
27
|
+
code += " instance.pendingEffects.length = 0;\n";
|
|
28
|
+
code += " const run = () => {\n";
|
|
29
|
+
code += " for (const item of effects) {\n";
|
|
30
|
+
code += " const previous = instance.hooks[item.index];\n";
|
|
31
|
+
code += ' if (previous && typeof previous.cleanup === "function") {\n';
|
|
32
|
+
code += " previous.cleanup();\n";
|
|
33
|
+
code += " }\n";
|
|
34
|
+
code += " const cleanup = item.effect();\n";
|
|
35
|
+
code += " instance.hooks[item.index] = {\n";
|
|
36
|
+
code += " deps: item.deps,\n";
|
|
37
|
+
code += ' cleanup: typeof cleanup === "function" ? cleanup : null,\n';
|
|
38
|
+
code += " };\n";
|
|
39
|
+
code += " }\n";
|
|
40
|
+
code += " };\n";
|
|
41
|
+
code += ' if (typeof queueMicrotask === "function") {\n';
|
|
42
|
+
code += " queueMicrotask(run);\n";
|
|
43
|
+
code += " } else {\n";
|
|
44
|
+
code += " setTimeout(run, 0);\n";
|
|
45
|
+
code += " }\n";
|
|
46
|
+
code += "}\n\n";
|
|
47
|
+
}
|
|
48
|
+
code += "function __renderInstance(instance) {\n";
|
|
49
|
+
code += " instance.hookIndex = 0;\n";
|
|
50
|
+
code += " instance.pendingEffects = [];\n";
|
|
51
|
+
code += " instance.childIndex = 0;\n";
|
|
52
|
+
code += " __currentInstance = instance;\n";
|
|
53
|
+
code += " const nextRoot = instance.component(instance.props || {});\n";
|
|
54
|
+
code += " __currentInstance = null;\n";
|
|
55
|
+
code += " if (instance.root && instance.root.parentNode) {\n";
|
|
56
|
+
code += " instance.root.parentNode.replaceChild(nextRoot, instance.root);\n";
|
|
57
|
+
code += " } else {\n";
|
|
58
|
+
code += " instance.mountTarget.appendChild(nextRoot);\n";
|
|
59
|
+
code += " }\n";
|
|
60
|
+
code += " instance.root = nextRoot;\n";
|
|
61
|
+
if (needsEffects) {
|
|
62
|
+
code += " __flushEffects(instance);\n";
|
|
63
|
+
}
|
|
64
|
+
code += "}\n\n";
|
|
65
|
+
code += "function __mount(component, mountTarget, props) {\n";
|
|
66
|
+
code += " const instance = {\n";
|
|
67
|
+
code += " component,\n";
|
|
68
|
+
code += " props: props || {},\n";
|
|
69
|
+
code += " hooks: [],\n";
|
|
70
|
+
code += " hookIndex: 0,\n";
|
|
71
|
+
code += " pendingEffects: [],\n";
|
|
72
|
+
code += " children: [],\n";
|
|
73
|
+
code += " childIndex: 0,\n";
|
|
74
|
+
code += " root: null,\n";
|
|
75
|
+
code += " mountTarget: mountTarget || document.body,\n";
|
|
76
|
+
code += " };\n";
|
|
77
|
+
code += " __renderInstance(instance);\n";
|
|
78
|
+
code += " return instance;\n";
|
|
79
|
+
code += "}\n\n";
|
|
80
|
+
code += "function __renderComponent(component, props) {\n";
|
|
81
|
+
code += " const parent = __getCurrentInstance();\n";
|
|
82
|
+
code += " const index = parent.childIndex++;\n";
|
|
83
|
+
code += " let instance = parent.children[index];\n";
|
|
84
|
+
code += " if (!instance || instance.component !== component) {\n";
|
|
85
|
+
code += " instance = {\n";
|
|
86
|
+
code += " component,\n";
|
|
87
|
+
code += " props: {},\n";
|
|
88
|
+
code += " hooks: [],\n";
|
|
89
|
+
code += " hookIndex: 0,\n";
|
|
90
|
+
code += " pendingEffects: [],\n";
|
|
91
|
+
code += " children: [],\n";
|
|
92
|
+
code += " childIndex: 0,\n";
|
|
93
|
+
code += " root: null,\n";
|
|
94
|
+
code += " mountTarget: null,\n";
|
|
95
|
+
code += " };\n";
|
|
96
|
+
code += " parent.children[index] = instance;\n";
|
|
97
|
+
code += " }\n";
|
|
98
|
+
code += " instance.props = props || {};\n";
|
|
99
|
+
code += " instance.hookIndex = 0;\n";
|
|
100
|
+
code += " instance.pendingEffects = [];\n";
|
|
101
|
+
code += " instance.childIndex = 0;\n";
|
|
102
|
+
code += " const prev = __currentInstance;\n";
|
|
103
|
+
code += " __currentInstance = instance;\n";
|
|
104
|
+
code += " const nextRoot = component(instance.props);\n";
|
|
105
|
+
code += " __currentInstance = prev;\n";
|
|
106
|
+
code += " instance.root = nextRoot;\n";
|
|
107
|
+
if (needsEffects) {
|
|
108
|
+
code += " __flushEffects(instance);\n";
|
|
109
|
+
}
|
|
110
|
+
code += " return nextRoot;\n";
|
|
111
|
+
code += "}\n\n";
|
|
112
|
+
code += "function __teardownInstance(instance) {\n";
|
|
113
|
+
code += " if (!instance) return;\n";
|
|
114
|
+
code += " if (instance.children) {\n";
|
|
115
|
+
code += " for (const child of instance.children) {\n";
|
|
116
|
+
code += " __teardownInstance(child);\n";
|
|
117
|
+
code += " }\n";
|
|
118
|
+
code += " }\n";
|
|
119
|
+
code += " if (instance.hooks) {\n";
|
|
120
|
+
code += " for (const hook of instance.hooks) {\n";
|
|
121
|
+
code += ' if (hook && typeof hook.cleanup === "function") {\n';
|
|
122
|
+
code += " hook.cleanup();\n";
|
|
123
|
+
code += " }\n";
|
|
124
|
+
code += " }\n";
|
|
125
|
+
code += " }\n";
|
|
126
|
+
code += "}\n\n";
|
|
127
|
+
if (hooks.has("useState")) {
|
|
128
|
+
code += "function useState(initialValue) {\n";
|
|
129
|
+
code += " const instance = __getCurrentInstance();\n";
|
|
130
|
+
code += " const index = instance.hookIndex++;\n";
|
|
131
|
+
code += " if (!Object.prototype.hasOwnProperty.call(instance.hooks, index)) {\n";
|
|
132
|
+
code += ' instance.hooks[index] = typeof initialValue === "function" ? initialValue() : initialValue;\n';
|
|
133
|
+
code += " }\n";
|
|
134
|
+
code += " const setState = (value) => {\n";
|
|
135
|
+
code += ' const nextValue = typeof value === "function" ? value(instance.hooks[index]) : value;\n';
|
|
136
|
+
code += " if (!Object.is(nextValue, instance.hooks[index])) {\n";
|
|
137
|
+
code += " instance.hooks[index] = nextValue;\n";
|
|
138
|
+
code += " __renderInstance(instance);\n";
|
|
139
|
+
code += " }\n";
|
|
140
|
+
code += " };\n";
|
|
141
|
+
code += " return [instance.hooks[index], setState];\n";
|
|
142
|
+
code += "}\n\n";
|
|
143
|
+
}
|
|
144
|
+
if (hooks.has("useReducer")) {
|
|
145
|
+
code += "function useReducer(reducer, initialArg, init) {\n";
|
|
146
|
+
code += " const instance = __getCurrentInstance();\n";
|
|
147
|
+
code += " const index = instance.hookIndex++;\n";
|
|
148
|
+
code += " if (!Object.prototype.hasOwnProperty.call(instance.hooks, index)) {\n";
|
|
149
|
+
code += " instance.hooks[index] = init ? init(initialArg) : initialArg;\n";
|
|
150
|
+
code += " }\n";
|
|
151
|
+
code += " const dispatch = (action) => {\n";
|
|
152
|
+
code += " const nextValue = reducer(instance.hooks[index], action);\n";
|
|
153
|
+
code += " if (!Object.is(nextValue, instance.hooks[index])) {\n";
|
|
154
|
+
code += " instance.hooks[index] = nextValue;\n";
|
|
155
|
+
code += " __renderInstance(instance);\n";
|
|
156
|
+
code += " }\n";
|
|
157
|
+
code += " };\n";
|
|
158
|
+
code += " return [instance.hooks[index], dispatch];\n";
|
|
159
|
+
code += "}\n\n";
|
|
160
|
+
}
|
|
161
|
+
if (hooks.has("useRef")) {
|
|
162
|
+
code += "function useRef(initialValue) {\n";
|
|
163
|
+
code += " const instance = __getCurrentInstance();\n";
|
|
164
|
+
code += " const index = instance.hookIndex++;\n";
|
|
165
|
+
code += " if (!Object.prototype.hasOwnProperty.call(instance.hooks, index)) {\n";
|
|
166
|
+
code += " instance.hooks[index] = { current: initialValue };\n";
|
|
167
|
+
code += " }\n";
|
|
168
|
+
code += " return instance.hooks[index];\n";
|
|
169
|
+
code += "}\n\n";
|
|
170
|
+
}
|
|
171
|
+
if (hooks.has("useMemo")) {
|
|
172
|
+
code += "function useMemo(factory, deps) {\n";
|
|
173
|
+
code += " const instance = __getCurrentInstance();\n";
|
|
174
|
+
code += " const index = instance.hookIndex++;\n";
|
|
175
|
+
code += " const prev = instance.hooks[index];\n";
|
|
176
|
+
code += " if (prev && deps && __areHookDepsEqual(prev.deps, deps)) {\n";
|
|
177
|
+
code += " return prev.value;\n";
|
|
178
|
+
code += " }\n";
|
|
179
|
+
code += " const value = factory();\n";
|
|
180
|
+
code += " instance.hooks[index] = { value, deps };\n";
|
|
181
|
+
code += " return value;\n";
|
|
182
|
+
code += "}\n\n";
|
|
183
|
+
}
|
|
184
|
+
if (hooks.has("useCallback")) {
|
|
185
|
+
code += "function useCallback(callback, deps) {\n";
|
|
186
|
+
code += " const instance = __getCurrentInstance();\n";
|
|
187
|
+
code += " const index = instance.hookIndex++;\n";
|
|
188
|
+
code += " const prev = instance.hooks[index];\n";
|
|
189
|
+
code += " if (prev && deps && __areHookDepsEqual(prev.deps, deps)) {\n";
|
|
190
|
+
code += " return prev.callback;\n";
|
|
191
|
+
code += " }\n";
|
|
192
|
+
code += " instance.hooks[index] = { callback, deps };\n";
|
|
193
|
+
code += " return callback;\n";
|
|
194
|
+
code += "}\n\n";
|
|
195
|
+
}
|
|
196
|
+
if (hooks.has("useEffect")) {
|
|
197
|
+
code += "function useEffect(effect, deps) {\n";
|
|
198
|
+
code += " const instance = __getCurrentInstance();\n";
|
|
199
|
+
code += " const index = instance.hookIndex++;\n";
|
|
200
|
+
code += " const prev = instance.hooks[index];\n";
|
|
201
|
+
code += " const hasChanged = !prev || !deps || !__areHookDepsEqual(prev.deps, deps);\n";
|
|
202
|
+
code += " if (hasChanged) {\n";
|
|
203
|
+
code += " instance.pendingEffects.push({ index, effect, deps });\n";
|
|
204
|
+
code += " }\n";
|
|
205
|
+
code += " if (!prev) {\n";
|
|
206
|
+
code += " instance.hooks[index] = { deps, cleanup: null };\n";
|
|
207
|
+
code += " }\n";
|
|
208
|
+
code += "}\n\n";
|
|
209
|
+
}
|
|
210
|
+
if (hooks.has("useContext")) {
|
|
211
|
+
code += "function useContext(context) {\n";
|
|
212
|
+
code += " if (!context) return undefined;\n";
|
|
213
|
+
code += ' if (Object.prototype.hasOwnProperty.call(context, "value")) {\n';
|
|
214
|
+
code += " return context.value;\n";
|
|
215
|
+
code += " }\n";
|
|
216
|
+
code += " return context.current;\n";
|
|
217
|
+
code += "}\n\n";
|
|
218
|
+
}
|
|
219
|
+
return code;
|
|
220
|
+
}
|
|
221
|
+
export {
|
|
222
|
+
getHookRuntime
|
|
223
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@novility/react-converter-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./runtime/*": "./dist/runtime/*.js"
|
|
10
|
+
},
|
|
11
|
+
"description": "Core conversion engine for React-Converter",
|
|
12
|
+
"author": "Mohamed Khaled",
|
|
13
|
+
"contributors": [
|
|
14
|
+
"Ali Badawi"
|
|
15
|
+
],
|
|
16
|
+
"license": "Proprietary",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "esbuild src/index.js --bundle --platform=node --format=esm --outfile=dist/index.js --external:@babel/* --external:postcss --external:tailwindcss --external:fs-extra && esbuild src/runtime/*.js --outdir=dist/runtime --platform=node --format=esm",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/Novility/react-converter-core.git"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"react",
|
|
34
|
+
"converter",
|
|
35
|
+
"vanilla",
|
|
36
|
+
"jsx",
|
|
37
|
+
"ast"
|
|
38
|
+
],
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@babel/parser": "^7.29.3",
|
|
41
|
+
"@babel/traverse": "^7.29.0",
|
|
42
|
+
"@babel/types": "^7.29.0",
|
|
43
|
+
"@tailwindcss/postcss": "^4.3.0",
|
|
44
|
+
"fs-extra": "^11.3.4",
|
|
45
|
+
"postcss": "^8.5.14",
|
|
46
|
+
"tailwindcss": "^4.3.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"esbuild": "^0.28.0"
|
|
50
|
+
}
|
|
51
|
+
}
|