@estjs/template 0.0.12 → 0.0.13-beta.2
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/template.cjs.js +15 -18
- package/dist/template.cjs.js.map +1 -1
- package/dist/template.d.cts +146 -84
- package/dist/template.d.ts +146 -84
- package/dist/template.dev.cjs.js +484 -361
- package/dist/template.dev.esm.js +485 -360
- package/dist/template.esm.js +5 -6
- package/dist/template.esm.js.map +1 -1
- package/package.json +3 -3
- package/types/component.d.ts +3 -0
- package/types/node.d.ts +1 -2
package/dist/template.dev.esm.js
CHANGED
|
@@ -1,28 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isString, isFunction, isSymbol, isArray, escape, startsWith, isNil, capitalizeFirstLetter, coerceArray, isFalsy, kebabCase } from '@estjs/shared';
|
|
2
|
+
import { shallowSignal, isSignal, useReactive, useEffect, useSignal } from '@estjs/signal';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @estjs/template v0.0.
|
|
5
|
+
* @estjs/template v0.0.13-beta.2
|
|
6
6
|
* (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
|
|
7
7
|
* @license MIT
|
|
8
8
|
**/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// src/shared-config.ts
|
|
12
|
+
var componentMap = /* @__PURE__ */ new Map();
|
|
13
|
+
var RenderContext = class {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.renderMode = 0 /* CLIENT */;
|
|
16
|
+
}
|
|
17
|
+
get isSSG() {
|
|
18
|
+
return this.renderMode === 1 /* SSG */;
|
|
19
|
+
}
|
|
20
|
+
get isSSR() {
|
|
21
|
+
return this.renderMode === 2 /* SSR */;
|
|
22
|
+
}
|
|
23
|
+
get isClient() {
|
|
24
|
+
return this.renderMode === 0 /* CLIENT */;
|
|
25
|
+
}
|
|
26
|
+
setSSR() {
|
|
27
|
+
this.renderMode = 2 /* SSR */;
|
|
28
|
+
}
|
|
29
|
+
setSSG() {
|
|
30
|
+
this.renderMode = 1 /* SSG */;
|
|
31
|
+
}
|
|
32
|
+
setClient() {
|
|
33
|
+
this.renderMode = 0 /* CLIENT */;
|
|
34
|
+
}
|
|
24
35
|
};
|
|
25
|
-
var
|
|
36
|
+
var renderContext = new RenderContext();
|
|
37
|
+
function enterComponent(temp, index) {
|
|
38
|
+
componentMap.set(temp, {
|
|
39
|
+
index
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function getComponentIndex(temp) {
|
|
43
|
+
return componentMap.get(temp).index;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/lifecycle-context.ts
|
|
47
|
+
var _LifecycleContext = class _LifecycleContext {
|
|
26
48
|
constructor() {
|
|
27
49
|
this.hooks = {
|
|
28
50
|
mounted: /* @__PURE__ */ new Set(),
|
|
@@ -38,158 +60,125 @@ var _Hooks = class _Hooks {
|
|
|
38
60
|
(_a = this.hooks[hook]) == null ? void 0 : _a.add(cb);
|
|
39
61
|
}
|
|
40
62
|
getContext(context) {
|
|
41
|
-
return
|
|
63
|
+
return _LifecycleContext.context[context];
|
|
42
64
|
}
|
|
43
65
|
setContext(context, value) {
|
|
44
|
-
|
|
66
|
+
_LifecycleContext.context[context] = value;
|
|
45
67
|
}
|
|
46
68
|
initRef() {
|
|
47
|
-
|
|
69
|
+
_LifecycleContext.ref = this;
|
|
48
70
|
}
|
|
49
71
|
removeRef() {
|
|
50
|
-
|
|
72
|
+
_LifecycleContext.ref = null;
|
|
73
|
+
}
|
|
74
|
+
clearHooks() {
|
|
75
|
+
Object.values(this.hooks).forEach((set) => set.clear());
|
|
51
76
|
}
|
|
52
77
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
var
|
|
57
|
-
|
|
78
|
+
// current context ref
|
|
79
|
+
_LifecycleContext.ref = null;
|
|
80
|
+
_LifecycleContext.context = {};
|
|
81
|
+
var LifecycleContext = _LifecycleContext;
|
|
82
|
+
|
|
83
|
+
// src/ssg-node.ts
|
|
84
|
+
function isSSGNode(node) {
|
|
85
|
+
return node instanceof SSGNode;
|
|
86
|
+
}
|
|
87
|
+
var componentIndex = 1;
|
|
88
|
+
var SSGNode = class extends LifecycleContext {
|
|
89
|
+
constructor(template, props = {}, key) {
|
|
58
90
|
super();
|
|
59
|
-
this.template =
|
|
91
|
+
this.template = template;
|
|
60
92
|
this.props = props;
|
|
61
93
|
this.key = key;
|
|
62
|
-
|
|
63
|
-
this.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
get isConnected() {
|
|
79
|
-
var _a, _b;
|
|
80
|
-
return (_b = (_a = this.rootNode) == null ? void 0 : _a.isConnected) != null ? _b : false;
|
|
81
|
-
}
|
|
82
|
-
inheritNode(node) {
|
|
83
|
-
this.context = node.context;
|
|
84
|
-
this.hooks = node.hooks;
|
|
85
|
-
Object.assign(this.proxyProps, node.proxyProps);
|
|
86
|
-
this.rootNode = node.rootNode;
|
|
87
|
-
this.trackMap = node.trackMap;
|
|
88
|
-
const props = this.props;
|
|
89
|
-
this.props = node.props;
|
|
90
|
-
this.patchProps(props);
|
|
91
|
-
}
|
|
92
|
-
mount(parent, before) {
|
|
93
|
-
var _a, _b, _c, _d;
|
|
94
|
-
if (!isFunction(this.template)) {
|
|
95
|
-
throw new Error("Template must be a function");
|
|
96
|
-
}
|
|
97
|
-
if (this.isConnected) {
|
|
98
|
-
return (_b = (_a = this.rootNode) == null ? void 0 : _a.mount(parent, before)) != null ? _b : [];
|
|
94
|
+
enterComponent(template, componentIndex);
|
|
95
|
+
if (isArray(this.template)) {
|
|
96
|
+
const PLACEHOLDER = " __PLACEHOLDER__ ";
|
|
97
|
+
const htmlString = this.template.join(PLACEHOLDER);
|
|
98
|
+
const processedString = htmlString.replaceAll(/(<[^>]+>)|([^<]+)/g, (match, p1, p2) => {
|
|
99
|
+
if (p1) {
|
|
100
|
+
if (p1.includes("data-ci")) return match;
|
|
101
|
+
return p1.replace(/<\s*([\da-z]+)(\s[^>]*)?>/i, (_, tagName, attrs) => {
|
|
102
|
+
return `<${tagName} data-ci="${componentIndex}"${attrs || ""}>`;
|
|
103
|
+
});
|
|
104
|
+
} else if (p2 && p2.replace(PLACEHOLDER, "").trim()) {
|
|
105
|
+
return `<!--${0 /* TEXT */}-${componentIndex}-->${p2}<!$>`;
|
|
106
|
+
}
|
|
107
|
+
return match;
|
|
108
|
+
});
|
|
109
|
+
this.template = processedString.split(PLACEHOLDER);
|
|
99
110
|
}
|
|
111
|
+
}
|
|
112
|
+
mount() {
|
|
100
113
|
this.initRef();
|
|
101
|
-
|
|
114
|
+
const output = this.render();
|
|
102
115
|
this.removeRef();
|
|
103
|
-
|
|
104
|
-
const mountedNode = (_d = (_c = this.rootNode) == null ? void 0 : _c.mount(parent, before)) != null ? _d : [];
|
|
105
|
-
this.hooks.mounted.forEach((handler) => handler());
|
|
106
|
-
this.patchProps(this.props);
|
|
107
|
-
return mountedNode;
|
|
108
|
-
}
|
|
109
|
-
unmount() {
|
|
110
|
-
var _a;
|
|
111
|
-
this.hooks.destroy.forEach((handler) => handler());
|
|
112
|
-
Object.values(this.hooks).forEach((set) => set.clear());
|
|
113
|
-
(_a = this.rootNode) == null ? void 0 : _a.unmount();
|
|
114
|
-
this.rootNode = null;
|
|
115
|
-
this.proxyProps = {};
|
|
116
|
-
this.mounted = false;
|
|
117
|
-
this.emitter.forEach((emitter) => emitter());
|
|
116
|
+
return output;
|
|
118
117
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
track.cleanup();
|
|
118
|
+
render() {
|
|
119
|
+
if (isFunction(this.template)) {
|
|
120
|
+
const root = this.template(this.props);
|
|
121
|
+
if (isSSGNode(root)) {
|
|
122
|
+
return root.mount();
|
|
123
|
+
} else {
|
|
124
|
+
return String(root);
|
|
125
|
+
}
|
|
128
126
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
props[key].value = (_b = this.rootNode) == null ? void 0 : _b.nodes[0];
|
|
141
|
-
} else if (startsWith(key, "update")) {
|
|
142
|
-
props[key] = isSignal(prop) ? prop.value : prop;
|
|
143
|
-
} else if (key !== "children") {
|
|
144
|
-
const newValue = (_d = (_c = this.proxyProps)[key]) != null ? _d : _c[key] = useSignal(prop);
|
|
145
|
-
const track = this.getNodeTrack(key);
|
|
146
|
-
track.cleanup = useEffect(() => {
|
|
147
|
-
newValue.value = isFunction(prop) ? prop() : prop;
|
|
127
|
+
const template = this.template;
|
|
128
|
+
Object.keys(this.props).forEach((key) => {
|
|
129
|
+
const cur = this.props[key];
|
|
130
|
+
const childrens = cur.children;
|
|
131
|
+
normalizeProp(cur);
|
|
132
|
+
const findIndex = template.findIndex((t) => t.includes(`data-hk="${key}"`));
|
|
133
|
+
if (childrens) {
|
|
134
|
+
childrens.forEach(([child]) => {
|
|
135
|
+
componentIndex++;
|
|
136
|
+
const children = renderChildren(child, cur);
|
|
137
|
+
this.template[findIndex] += children;
|
|
148
138
|
});
|
|
149
139
|
}
|
|
150
|
-
|
|
151
|
-
|
|
140
|
+
this.template[findIndex].replaceAll(
|
|
141
|
+
`data-hk="${key}"`,
|
|
142
|
+
`data-hk="${key}" ${generateAttributes(cur)}`
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
return template.join("");
|
|
152
146
|
}
|
|
153
147
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
if (_template === "") {
|
|
165
|
-
props = {
|
|
166
|
-
0: props
|
|
167
|
-
};
|
|
148
|
+
function normalizeProp(props) {
|
|
149
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
150
|
+
if (key === "children") {
|
|
151
|
+
delete props[key];
|
|
152
|
+
} else if (isFunction(value)) {
|
|
153
|
+
delete props[key];
|
|
154
|
+
} else if (isSignal(value)) {
|
|
155
|
+
props[key] = value.value;
|
|
168
156
|
}
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
return isFunction(_template) ? new ComponentNode(_template, props, key) : new TemplateNode(_template, props, key);
|
|
172
|
-
}
|
|
173
|
-
function isComponent(node) {
|
|
174
|
-
return node instanceof ComponentNode;
|
|
175
|
-
}
|
|
176
|
-
function isJsxElement(node) {
|
|
177
|
-
return node instanceof ComponentNode || node instanceof TemplateNode;
|
|
178
|
-
}
|
|
179
|
-
function template(html) {
|
|
180
|
-
const template2 = document.createElement("template");
|
|
181
|
-
template2.innerHTML = closeHtmlTags(html);
|
|
182
|
-
return template2;
|
|
157
|
+
});
|
|
183
158
|
}
|
|
184
|
-
function
|
|
185
|
-
return props.children;
|
|
159
|
+
function generateAttributes(props) {
|
|
160
|
+
return Object.entries(props).filter(([key, value]) => key !== "children" && !isFunction(value)).map(([key, value]) => `${key}="${escape(String(value))}"`).join(" ");
|
|
161
|
+
}
|
|
162
|
+
function renderChildren(children, prop) {
|
|
163
|
+
if (isFunction(children)) {
|
|
164
|
+
return renderChildren(children(prop), prop);
|
|
165
|
+
} else if (isSignal(children)) {
|
|
166
|
+
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${children.value}<!$>`;
|
|
167
|
+
} else if (isSSGNode(children)) {
|
|
168
|
+
const childResult = children.mount();
|
|
169
|
+
return isFunction(childResult) ? childResult(prop) : extractSignal(childResult);
|
|
170
|
+
} else {
|
|
171
|
+
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${children}<!$>`;
|
|
172
|
+
}
|
|
186
173
|
}
|
|
187
174
|
|
|
188
175
|
// src/utils.ts
|
|
189
|
-
var selfClosingTags = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr";
|
|
190
|
-
var htmlTags = "a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,body,br,button,canvas,caption,center,cite,code,col,colgroup,command,content,data,datalist,dd,del,details,dfn,dialog,dir,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,i,iframe,image,img,input,ins,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,menu,menuitem,meta,meter,nav,nobr,noframes,noscript,object,ol,optgroup,option,output,p,param,picture,plaintext,pre,progress,q,rb,rp,rt,rtc,ruby,s,samp,script,section,select,shadow,small,source,spacer,span,strike,strong,style,sub,summary,sup,table,tbody,td,template,textarea,tfoot,th,thead,time,title,tr,track,tt,u,ul,var,video,wbr,xmp"
|
|
176
|
+
var selfClosingTags = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr".split(",");
|
|
177
|
+
var htmlTags = "a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,body,br,button,canvas,caption,center,cite,code,col,colgroup,command,content,data,datalist,dd,del,details,dfn,dialog,dir,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,i,iframe,image,img,input,ins,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,menu,menuitem,meta,meter,nav,nobr,noframes,noscript,object,ol,optgroup,option,output,p,param,picture,plaintext,pre,progress,q,rb,rp,rt,rtc,ruby,s,samp,script,section,select,shadow,small,source,spacer,span,strike,strong,style,sub,summary,sup,table,tbody,td,template,textarea,tfoot,th,thead,time,title,tr,track,tt,u,ul,var,video,wbr,xmp".split(
|
|
178
|
+
","
|
|
179
|
+
);
|
|
191
180
|
function coerceNode(data) {
|
|
192
|
-
if (isJsxElement(data) || data instanceof Node) {
|
|
181
|
+
if (isJsxElement(data) || data instanceof Node || isSSGNode(data)) {
|
|
193
182
|
return data;
|
|
194
183
|
}
|
|
195
184
|
const text = isFalsy(data) ? "" : String(data);
|
|
@@ -197,11 +186,12 @@ function coerceNode(data) {
|
|
|
197
186
|
}
|
|
198
187
|
function insertChild(parent, child, before = null) {
|
|
199
188
|
const beforeNode = isJsxElement(before) ? before.firstChild : before;
|
|
189
|
+
const ssr = renderContext.isSSR;
|
|
200
190
|
if (isJsxElement(child)) {
|
|
201
191
|
child.mount(parent, beforeNode);
|
|
202
|
-
} else if (beforeNode) {
|
|
192
|
+
} else if (beforeNode && !ssr) {
|
|
203
193
|
beforeNode.before(child);
|
|
204
|
-
} else {
|
|
194
|
+
} else if (!ssr) {
|
|
205
195
|
parent.append(child);
|
|
206
196
|
}
|
|
207
197
|
}
|
|
@@ -223,7 +213,7 @@ function setAttribute(element, attr, value) {
|
|
|
223
213
|
if (attr === "class") {
|
|
224
214
|
if (typeof value === "string") {
|
|
225
215
|
element.className = value;
|
|
226
|
-
} else if (
|
|
216
|
+
} else if (isArray(value)) {
|
|
227
217
|
element.className = value.join(" ");
|
|
228
218
|
} else if (value && typeof value === "object") {
|
|
229
219
|
element.className = Object.entries(value).reduce((acc, [key, value2]) => acc + (value2 ? ` ${key}` : ""), "").trim();
|
|
@@ -246,14 +236,14 @@ function setAttribute(element, attr, value) {
|
|
|
246
236
|
} else if (value === true) {
|
|
247
237
|
element.setAttribute(attr, "");
|
|
248
238
|
} else {
|
|
249
|
-
if (element instanceof HTMLInputElement) {
|
|
239
|
+
if (element instanceof HTMLInputElement && attr === "value") {
|
|
250
240
|
element.value = String(value);
|
|
251
241
|
} else {
|
|
252
242
|
element.setAttribute(attr, String(value));
|
|
253
243
|
}
|
|
254
244
|
}
|
|
255
245
|
}
|
|
256
|
-
function
|
|
246
|
+
function bindNode(node, setter) {
|
|
257
247
|
if (node instanceof HTMLInputElement) {
|
|
258
248
|
switch (node.type) {
|
|
259
249
|
case "checkbox":
|
|
@@ -296,16 +286,12 @@ function binNode(node, setter) {
|
|
|
296
286
|
});
|
|
297
287
|
}
|
|
298
288
|
}
|
|
299
|
-
|
|
300
|
-
function nextTick(fn) {
|
|
301
|
-
return fn ? p.then(fn) : p;
|
|
302
|
-
}
|
|
289
|
+
Promise.resolve();
|
|
303
290
|
function addEventListener(node, eventName, handler) {
|
|
304
291
|
node.addEventListener(eventName, handler);
|
|
305
292
|
return () => node.removeEventListener(eventName, handler);
|
|
306
293
|
}
|
|
307
294
|
function closeHtmlTags(input) {
|
|
308
|
-
const selfClosingTagList = selfClosingTags.split(",");
|
|
309
295
|
const tagStack = [];
|
|
310
296
|
const output = [];
|
|
311
297
|
const tagPattern = /<\/?([\da-z-]+)([^>]*)>/gi;
|
|
@@ -327,7 +313,7 @@ function closeHtmlTags(input) {
|
|
|
327
313
|
if (tagStack.length > 0) {
|
|
328
314
|
tagStack.pop();
|
|
329
315
|
}
|
|
330
|
-
} else if (!
|
|
316
|
+
} else if (!selfClosingTags.includes(tagName)) {
|
|
331
317
|
tagStack.push(tagName);
|
|
332
318
|
}
|
|
333
319
|
output.push(fullMatch);
|
|
@@ -342,46 +328,147 @@ function closeHtmlTags(input) {
|
|
|
342
328
|
return output.join("");
|
|
343
329
|
}
|
|
344
330
|
function isHtmlTagName(tagName) {
|
|
345
|
-
|
|
346
|
-
return htmlTagsList.includes(tagName);
|
|
331
|
+
return htmlTags.includes(tagName);
|
|
347
332
|
}
|
|
348
333
|
function convertToHtmlTag(tagName) {
|
|
349
|
-
|
|
350
|
-
if (selfClosingTagList.includes(tagName)) {
|
|
334
|
+
if (selfClosingTags.includes(tagName)) {
|
|
351
335
|
return `<${tagName}/>`;
|
|
352
336
|
} else {
|
|
353
337
|
return `<${tagName}></${tagName}>`;
|
|
354
338
|
}
|
|
355
339
|
}
|
|
340
|
+
function extractSignal(signal) {
|
|
341
|
+
if (isSignal(signal)) {
|
|
342
|
+
return signal.value;
|
|
343
|
+
} else {
|
|
344
|
+
return signal;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
var ComponentNode = class extends LifecycleContext {
|
|
348
|
+
constructor(template, props, key) {
|
|
349
|
+
super();
|
|
350
|
+
this.template = template;
|
|
351
|
+
this.props = props;
|
|
352
|
+
this.key = key;
|
|
353
|
+
this.emitter = /* @__PURE__ */ new Set();
|
|
354
|
+
this.rootNode = null;
|
|
355
|
+
this.trackMap = /* @__PURE__ */ new Map();
|
|
356
|
+
this.proxyProps = props ? useReactive(
|
|
357
|
+
props,
|
|
358
|
+
(key2) => startsWith(key2, "on") || startsWith(key2, "update") || key2 === "children"
|
|
359
|
+
) : {};
|
|
360
|
+
}
|
|
361
|
+
get firstChild() {
|
|
362
|
+
var _a, _b;
|
|
363
|
+
return (_b = (_a = this.rootNode) == null ? void 0 : _a.firstChild) != null ? _b : null;
|
|
364
|
+
}
|
|
365
|
+
get isConnected() {
|
|
366
|
+
var _a, _b;
|
|
367
|
+
return (_b = (_a = this.rootNode) == null ? void 0 : _a.isConnected) != null ? _b : false;
|
|
368
|
+
}
|
|
369
|
+
mount(parent, before) {
|
|
370
|
+
var _a, _b, _c, _d;
|
|
371
|
+
if (!isFunction(this.template)) {
|
|
372
|
+
throw new Error("Template must be a function");
|
|
373
|
+
}
|
|
374
|
+
if (this.isConnected) {
|
|
375
|
+
return (_b = (_a = this.rootNode) == null ? void 0 : _a.mount(parent, before)) != null ? _b : [];
|
|
376
|
+
}
|
|
377
|
+
this.initRef();
|
|
378
|
+
this.rootNode = this.template(this.proxyProps);
|
|
379
|
+
const mountedNode = (_d = (_c = this.rootNode) == null ? void 0 : _c.mount(parent, before)) != null ? _d : [];
|
|
380
|
+
this.hooks.mounted.forEach((handler) => handler());
|
|
381
|
+
this.patchProps(this.props);
|
|
382
|
+
this.removeRef();
|
|
383
|
+
return mountedNode;
|
|
384
|
+
}
|
|
385
|
+
unmount() {
|
|
386
|
+
var _a;
|
|
387
|
+
this.hooks.destroy.forEach((handler) => handler());
|
|
388
|
+
this.clearHooks();
|
|
389
|
+
(_a = this.rootNode) == null ? void 0 : _a.unmount();
|
|
390
|
+
this.rootNode = null;
|
|
391
|
+
this.proxyProps = {};
|
|
392
|
+
for (const cleanup of this.emitter) {
|
|
393
|
+
cleanup();
|
|
394
|
+
}
|
|
395
|
+
this.emitter.clear();
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Inherit props and state from another ComponentNode.
|
|
399
|
+
* It will:
|
|
400
|
+
* 1. Copy props from the node to this proxyProps.
|
|
401
|
+
* 2. Copy the rootNode, trackMap and hooks from the node.
|
|
402
|
+
* 3. Copy the props from the node to this.
|
|
403
|
+
* 4. Patch props from the props passed in the constructor.
|
|
404
|
+
* @param node The node to inherit from.
|
|
405
|
+
*/
|
|
406
|
+
inheritNode(node) {
|
|
407
|
+
Object.assign(this.proxyProps, node.proxyProps);
|
|
408
|
+
this.rootNode = node.rootNode;
|
|
409
|
+
this.trackMap = node.trackMap;
|
|
410
|
+
this.hooks = node.hooks;
|
|
411
|
+
const props = this.props;
|
|
412
|
+
this.props = node.props;
|
|
413
|
+
this.patchProps(props);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Get a NodeTrack from the trackMap. If the track is not in the trackMap, create a new one.
|
|
417
|
+
* Then, call the cleanup function to remove any previously registered hooks.
|
|
418
|
+
* @param trackKey the key of the node track to get.
|
|
419
|
+
* @returns the NodeTrack, cleaned up and ready to use.
|
|
420
|
+
*/
|
|
421
|
+
getNodeTrack(trackKey) {
|
|
422
|
+
let track = this.trackMap.get(trackKey);
|
|
423
|
+
if (!track) {
|
|
424
|
+
track = { cleanup: () => {
|
|
425
|
+
} };
|
|
426
|
+
this.trackMap.set(trackKey, track);
|
|
427
|
+
}
|
|
428
|
+
track.cleanup();
|
|
429
|
+
return track;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Patch the props of this node.
|
|
433
|
+
* It will:
|
|
434
|
+
* 1. Iterate the props and patch it.
|
|
435
|
+
* 2. If the prop is a event handler, add a event listener to the first child of the node.
|
|
436
|
+
* 3. If the prop is a ref, set the first child of the node to the ref.
|
|
437
|
+
* 4. If the prop is a update handler, update the prop in the node's props.
|
|
438
|
+
* 5. If the prop is a normal prop, create a signal for it and then patch it.
|
|
439
|
+
* @param props The props to patch.
|
|
440
|
+
*/
|
|
441
|
+
patchProps(props) {
|
|
442
|
+
var _a, _b;
|
|
443
|
+
if (!props) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
for (const [key, prop] of Object.entries(props)) {
|
|
447
|
+
if (startsWith(key, "on") && ((_a = this.rootNode) == null ? void 0 : _a.firstChild)) {
|
|
448
|
+
const event = key.slice(2).toLowerCase();
|
|
449
|
+
const cleanup = addEventListener(this.rootNode.nodes[0], event, prop);
|
|
450
|
+
this.emitter.add(cleanup);
|
|
451
|
+
} else if (key === "ref") {
|
|
452
|
+
prop.value = (_b = this.rootNode) == null ? void 0 : _b.firstChild;
|
|
453
|
+
} else if (startsWith(key, "update")) {
|
|
454
|
+
this.props[key] = extractSignal(prop);
|
|
455
|
+
} else if (key !== "children") {
|
|
456
|
+
const track = this.getNodeTrack(key);
|
|
457
|
+
track.cleanup = useEffect(() => {
|
|
458
|
+
this.proxyProps[key] = isFunction(prop) ? prop() : prop;
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
this.props = props;
|
|
463
|
+
}
|
|
464
|
+
};
|
|
356
465
|
|
|
357
466
|
// src/patch.ts
|
|
358
467
|
function patchChildren(parent, childrenMap, nextChildren, before) {
|
|
359
468
|
const result = /* @__PURE__ */ new Map();
|
|
360
469
|
const children = Array.from(childrenMap.values());
|
|
361
|
-
const childrenLength = children.length;
|
|
362
470
|
if (childrenMap.size > 0 && nextChildren.length === 0) {
|
|
363
|
-
|
|
364
|
-
parent.innerHTML = "";
|
|
365
|
-
if (before) {
|
|
366
|
-
insertChild(parent, before);
|
|
367
|
-
}
|
|
368
|
-
} else {
|
|
369
|
-
const range = document.createRange();
|
|
370
|
-
const child = children[0];
|
|
371
|
-
const start = isJsxElement(child) ? child.firstChild : child;
|
|
372
|
-
range.setStartBefore(start);
|
|
373
|
-
if (before) {
|
|
374
|
-
range.setEndBefore(before);
|
|
375
|
-
} else {
|
|
376
|
-
range.setEndAfter(parent);
|
|
377
|
-
}
|
|
378
|
-
range.deleteContents();
|
|
379
|
-
}
|
|
380
|
-
children.forEach((node) => {
|
|
381
|
-
if (isJsxElement(node)) {
|
|
382
|
-
node.unmount();
|
|
383
|
-
}
|
|
384
|
-
});
|
|
471
|
+
clearChildren(parent, children, before);
|
|
385
472
|
return result;
|
|
386
473
|
}
|
|
387
474
|
const replaces = [];
|
|
@@ -422,6 +509,30 @@ function patchChildren(parent, childrenMap, nextChildren, before) {
|
|
|
422
509
|
});
|
|
423
510
|
return result;
|
|
424
511
|
}
|
|
512
|
+
function clearChildren(parent, children, before) {
|
|
513
|
+
if (parent.childNodes.length === children.length + (before ? 1 : 0)) {
|
|
514
|
+
parent.innerHTML = "";
|
|
515
|
+
if (before) {
|
|
516
|
+
insertChild(parent, before);
|
|
517
|
+
}
|
|
518
|
+
} else {
|
|
519
|
+
const range = document.createRange();
|
|
520
|
+
const child = children[0];
|
|
521
|
+
const start = isJsxElement(child) ? child.firstChild : child;
|
|
522
|
+
range.setStartBefore(start);
|
|
523
|
+
if (before) {
|
|
524
|
+
range.setEndBefore(before);
|
|
525
|
+
} else {
|
|
526
|
+
range.setEndAfter(parent);
|
|
527
|
+
}
|
|
528
|
+
range.deleteContents();
|
|
529
|
+
}
|
|
530
|
+
children.forEach((node) => {
|
|
531
|
+
if (isJsxElement(node)) {
|
|
532
|
+
node.unmount();
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
425
536
|
function patch(parent, node, next) {
|
|
426
537
|
if (node === next) {
|
|
427
538
|
return node;
|
|
@@ -458,30 +569,34 @@ function getKey(node, index) {
|
|
|
458
569
|
}
|
|
459
570
|
|
|
460
571
|
// src/template-node.ts
|
|
461
|
-
var TemplateNode = class
|
|
462
|
-
constructor(
|
|
463
|
-
this.template =
|
|
572
|
+
var TemplateNode = class {
|
|
573
|
+
constructor(template, props, key) {
|
|
574
|
+
this.template = template;
|
|
464
575
|
this.props = props;
|
|
465
576
|
this.key = key;
|
|
466
577
|
this.treeMap = /* @__PURE__ */ new Map();
|
|
467
578
|
this.mounted = false;
|
|
468
579
|
this.nodes = [];
|
|
469
|
-
this.provides = {};
|
|
470
580
|
this.trackMap = /* @__PURE__ */ new Map();
|
|
581
|
+
this.bindValueKeys = [];
|
|
471
582
|
this.parent = null;
|
|
472
|
-
this.key
|
|
583
|
+
this.key || (this.key = props == null ? void 0 : props.key);
|
|
584
|
+
if (renderContext.isSSR) {
|
|
585
|
+
this.componentIndex = getComponentIndex(this.template);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
addEventListener() {
|
|
589
|
+
}
|
|
590
|
+
removeEventListener() {
|
|
473
591
|
}
|
|
474
592
|
get firstChild() {
|
|
475
593
|
var _a;
|
|
476
594
|
return (_a = this.nodes[0]) != null ? _a : null;
|
|
477
595
|
}
|
|
596
|
+
// is mounted
|
|
478
597
|
get isConnected() {
|
|
479
598
|
return this.mounted;
|
|
480
599
|
}
|
|
481
|
-
addEventListener() {
|
|
482
|
-
}
|
|
483
|
-
removeEventListener() {
|
|
484
|
-
}
|
|
485
600
|
mount(parent, before) {
|
|
486
601
|
var _a;
|
|
487
602
|
this.parent = parent;
|
|
@@ -489,6 +604,9 @@ var TemplateNode = class _TemplateNode {
|
|
|
489
604
|
this.nodes.forEach((node) => insertChild(parent, node, before));
|
|
490
605
|
return this.nodes;
|
|
491
606
|
}
|
|
607
|
+
if (isArray(this.template)) {
|
|
608
|
+
this.template = createTemplate(this.template.join(""));
|
|
609
|
+
}
|
|
492
610
|
const cloneNode = this.template.content.cloneNode(true);
|
|
493
611
|
const firstChild = cloneNode.firstChild;
|
|
494
612
|
if ((_a = firstChild == null ? void 0 : firstChild.hasAttribute) == null ? void 0 : _a.call(firstChild, "_svg_")) {
|
|
@@ -498,23 +616,20 @@ var TemplateNode = class _TemplateNode {
|
|
|
498
616
|
});
|
|
499
617
|
}
|
|
500
618
|
this.nodes = Array.from(cloneNode.childNodes);
|
|
501
|
-
|
|
619
|
+
if (renderContext.isSSR) {
|
|
620
|
+
this.mapSSGNodeTree(parent);
|
|
621
|
+
} else {
|
|
622
|
+
this.mapNodeTree(parent, cloneNode);
|
|
623
|
+
}
|
|
502
624
|
insertChild(parent, cloneNode, before);
|
|
503
|
-
this.
|
|
625
|
+
this.patchProps(this.props);
|
|
504
626
|
this.mounted = true;
|
|
505
627
|
return this.nodes;
|
|
506
628
|
}
|
|
507
629
|
unmount() {
|
|
508
630
|
this.trackMap.forEach((track) => {
|
|
509
|
-
var _a
|
|
631
|
+
var _a;
|
|
510
632
|
(_a = track.cleanup) == null ? void 0 : _a.call(track);
|
|
511
|
-
(_b = track.lastNodes) == null ? void 0 : _b.forEach((node) => {
|
|
512
|
-
if (track.isRoot) {
|
|
513
|
-
removeChild(node);
|
|
514
|
-
} else if (node instanceof _TemplateNode) {
|
|
515
|
-
node.unmount();
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
633
|
});
|
|
519
634
|
this.trackMap.clear();
|
|
520
635
|
this.treeMap.clear();
|
|
@@ -522,6 +637,52 @@ var TemplateNode = class _TemplateNode {
|
|
|
522
637
|
this.nodes = [];
|
|
523
638
|
this.mounted = false;
|
|
524
639
|
}
|
|
640
|
+
patchProps(props) {
|
|
641
|
+
if (!props) return;
|
|
642
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
643
|
+
const index = Number(key);
|
|
644
|
+
const node = this.treeMap.get(index);
|
|
645
|
+
if (node) {
|
|
646
|
+
this.patchProp(key, node, value, index === 0);
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
this.props = props;
|
|
650
|
+
}
|
|
651
|
+
inheritNode(node) {
|
|
652
|
+
this.mounted = node.mounted;
|
|
653
|
+
this.nodes = node.nodes;
|
|
654
|
+
this.trackMap = node.trackMap;
|
|
655
|
+
this.treeMap = node.treeMap;
|
|
656
|
+
const props = this.props;
|
|
657
|
+
this.props = node.props;
|
|
658
|
+
this.patchProps(props);
|
|
659
|
+
}
|
|
660
|
+
mapSSGNodeTree(parent) {
|
|
661
|
+
this.treeMap.set(0, parent);
|
|
662
|
+
const walk = (node) => {
|
|
663
|
+
var _a;
|
|
664
|
+
if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
|
665
|
+
if (node.nodeType === Node.COMMENT_NODE) {
|
|
666
|
+
const [type, index] = ((_a = node.textContent) == null ? void 0 : _a.split("-")) || "";
|
|
667
|
+
if (0 /* TEXT */ === +type && +index === this.componentIndex) {
|
|
668
|
+
const textNode = node.nextSibling;
|
|
669
|
+
this.treeMap.set(+index, textNode);
|
|
670
|
+
}
|
|
671
|
+
} else if (node.nodeType !== Node.TEXT_NODE) {
|
|
672
|
+
const { ci = "-1", hk } = (node == null ? void 0 : node.dataset) || {};
|
|
673
|
+
if (hk && +ci === this.componentIndex) {
|
|
674
|
+
this.treeMap.set(+hk, node);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
let child = node.firstChild;
|
|
679
|
+
while (child) {
|
|
680
|
+
walk(child);
|
|
681
|
+
child = child.nextSibling;
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
walk(parent);
|
|
685
|
+
}
|
|
525
686
|
mapNodeTree(parent, tree) {
|
|
526
687
|
let index = 1;
|
|
527
688
|
this.treeMap.set(0, parent);
|
|
@@ -537,17 +698,14 @@ var TemplateNode = class _TemplateNode {
|
|
|
537
698
|
};
|
|
538
699
|
walk(tree);
|
|
539
700
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
this.props = props;
|
|
550
|
-
}
|
|
701
|
+
/**
|
|
702
|
+
* Get a NodeTrack from the trackMap. If the track is not in the trackMap, create a new one.
|
|
703
|
+
* Then, call the cleanup function to remove any previously registered hooks.
|
|
704
|
+
* @param trackKey the key of the node track to get.
|
|
705
|
+
* @param trackLastNodes if true, the track will record the last nodes it has rendered.
|
|
706
|
+
* @param isRoot if true, the track will be treated as a root track.
|
|
707
|
+
* @returns the NodeTrack, cleaned up and ready to use.
|
|
708
|
+
*/
|
|
551
709
|
getNodeTrack(trackKey, trackLastNodes, isRoot) {
|
|
552
710
|
var _a;
|
|
553
711
|
let track = this.trackMap.get(trackKey);
|
|
@@ -565,16 +723,7 @@ var TemplateNode = class _TemplateNode {
|
|
|
565
723
|
(_a = track.cleanup) == null ? void 0 : _a.call(track);
|
|
566
724
|
return track;
|
|
567
725
|
}
|
|
568
|
-
|
|
569
|
-
this.mounted = node.mounted;
|
|
570
|
-
this.nodes = node.nodes;
|
|
571
|
-
this.trackMap = node.trackMap;
|
|
572
|
-
this.treeMap = node.treeMap;
|
|
573
|
-
const props = this.props;
|
|
574
|
-
this.props = node.props;
|
|
575
|
-
this.patchNodes(props);
|
|
576
|
-
}
|
|
577
|
-
patchNode(key, node, props, isRoot) {
|
|
726
|
+
patchProp(key, node, props, isRoot) {
|
|
578
727
|
for (const attr in props) {
|
|
579
728
|
if (attr === "children" && props.children) {
|
|
580
729
|
if (!isArray(props.children)) {
|
|
@@ -598,7 +747,14 @@ var TemplateNode = class _TemplateNode {
|
|
|
598
747
|
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
599
748
|
const listener = props[attr];
|
|
600
749
|
track.cleanup = addEventListener(node, eventName, listener);
|
|
601
|
-
} else
|
|
750
|
+
} else {
|
|
751
|
+
const updateKey = `update${capitalizeFirstLetter(attr)}`;
|
|
752
|
+
if (this.bindValueKeys.includes(attr)) {
|
|
753
|
+
break;
|
|
754
|
+
}
|
|
755
|
+
if (props[updateKey]) {
|
|
756
|
+
this.bindValueKeys.push(updateKey);
|
|
757
|
+
}
|
|
602
758
|
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
603
759
|
const val = props[attr];
|
|
604
760
|
const triggerValue = isSignal(val) ? val : useSignal(val);
|
|
@@ -608,9 +764,8 @@ var TemplateNode = class _TemplateNode {
|
|
|
608
764
|
patchAttribute(track, node, attr, triggerValue.value);
|
|
609
765
|
});
|
|
610
766
|
let cleanupBind;
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
cleanupBind = binNode(node, (value) => {
|
|
767
|
+
if (props[updateKey] && !isComponent(attr)) {
|
|
768
|
+
cleanupBind = bindNode(node, (value) => {
|
|
614
769
|
props[updateKey](value);
|
|
615
770
|
});
|
|
616
771
|
}
|
|
@@ -622,6 +777,52 @@ var TemplateNode = class _TemplateNode {
|
|
|
622
777
|
}
|
|
623
778
|
}
|
|
624
779
|
};
|
|
780
|
+
function patchChild(track, parent, child, before) {
|
|
781
|
+
if (isFunction(child)) {
|
|
782
|
+
track.cleanup = useEffect(() => {
|
|
783
|
+
const nextNodes = coerceArray(child()).map(coerceNode);
|
|
784
|
+
if (renderContext.isSSR) {
|
|
785
|
+
track.lastNodes = reconcileChildren(parent, nextNodes, before);
|
|
786
|
+
} else {
|
|
787
|
+
track.lastNodes = patchChildren(parent, track.lastNodes, nextNodes, before);
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
} else {
|
|
791
|
+
coerceArray(child).forEach((node, index) => {
|
|
792
|
+
const newNode = coerceNode(node);
|
|
793
|
+
const key = getKey(newNode, index);
|
|
794
|
+
if (renderContext.isSSR) {
|
|
795
|
+
track.lastNodes = reconcileChildren(parent, [newNode], before);
|
|
796
|
+
} else {
|
|
797
|
+
track.lastNodes.set(key, newNode);
|
|
798
|
+
insertChild(parent, newNode, before);
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
function reconcileChildren(parent, nextNodes, before) {
|
|
804
|
+
const result = /* @__PURE__ */ new Map();
|
|
805
|
+
const textNodes = Array.from(parent.childNodes).filter(
|
|
806
|
+
(node) => {
|
|
807
|
+
var _a, _b;
|
|
808
|
+
return node.nodeType === Node.TEXT_NODE && ((_a = node.previousSibling) == null ? void 0 : _a.nodeType) === Node.COMMENT_NODE && ((_b = node.nextSibling) == null ? void 0 : _b.nodeType) === Node.COMMENT_NODE;
|
|
809
|
+
}
|
|
810
|
+
);
|
|
811
|
+
nextNodes.forEach((node, index) => {
|
|
812
|
+
const key = getKey(node, index);
|
|
813
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
814
|
+
textNodes.forEach((ne) => {
|
|
815
|
+
if (node.textContent === ne.textContent) {
|
|
816
|
+
parent.replaceChild(node, ne);
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
} else {
|
|
820
|
+
insertChild(parent, node, before);
|
|
821
|
+
}
|
|
822
|
+
result.set(key, node);
|
|
823
|
+
});
|
|
824
|
+
return result;
|
|
825
|
+
}
|
|
625
826
|
function patchAttribute(track, node, attr, data) {
|
|
626
827
|
const element = node;
|
|
627
828
|
if (!element.setAttribute) {
|
|
@@ -635,165 +836,89 @@ function patchAttribute(track, node, attr, data) {
|
|
|
635
836
|
setAttribute(element, attr, data);
|
|
636
837
|
}
|
|
637
838
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
});
|
|
839
|
+
|
|
840
|
+
// src/jsx-renderer.ts
|
|
841
|
+
function h(template, props, key) {
|
|
842
|
+
if (isString(template)) {
|
|
843
|
+
if (isHtmlTagName(template)) {
|
|
844
|
+
template = convertToHtmlTag(template);
|
|
845
|
+
props = { "1": props };
|
|
846
|
+
} else if (template === "") {
|
|
847
|
+
props = { "0": props };
|
|
848
|
+
}
|
|
849
|
+
template = createTemplate(template);
|
|
650
850
|
}
|
|
851
|
+
return isFunction(template) ? new ComponentNode(template, props, key) : new TemplateNode(template, props, key);
|
|
852
|
+
}
|
|
853
|
+
function isComponent(node) {
|
|
854
|
+
return node instanceof ComponentNode;
|
|
855
|
+
}
|
|
856
|
+
function isJsxElement(node) {
|
|
857
|
+
return node instanceof ComponentNode || node instanceof TemplateNode;
|
|
858
|
+
}
|
|
859
|
+
function createTemplate(html) {
|
|
860
|
+
const template = document.createElement("template");
|
|
861
|
+
template.innerHTML = closeHtmlTags(html);
|
|
862
|
+
return template;
|
|
863
|
+
}
|
|
864
|
+
function Fragment(props) {
|
|
865
|
+
return props.children;
|
|
651
866
|
}
|
|
652
867
|
function onMount(cb) {
|
|
653
868
|
var _a;
|
|
654
|
-
|
|
655
|
-
(_a =
|
|
869
|
+
assertInsideComponent("onMounted");
|
|
870
|
+
(_a = LifecycleContext.ref) == null ? void 0 : _a.addHook("mounted", cb);
|
|
656
871
|
}
|
|
657
872
|
function onDestroy(cb) {
|
|
658
873
|
var _a;
|
|
659
|
-
|
|
660
|
-
(_a =
|
|
874
|
+
assertInsideComponent("onDestroy");
|
|
875
|
+
(_a = LifecycleContext.ref) == null ? void 0 : _a.addHook("destroy", cb);
|
|
661
876
|
}
|
|
662
|
-
function
|
|
663
|
-
if (!
|
|
877
|
+
function assertInsideComponent(hookName, key) {
|
|
878
|
+
if (!LifecycleContext.ref && true) {
|
|
664
879
|
console.error(
|
|
665
|
-
`"${
|
|
880
|
+
`"${hookName}"(key: ${isSymbol(key) ? key.toString() : key}) can only be called within the component function body
|
|
666
881
|
and cannot be used in asynchronous or deferred calls.`
|
|
667
882
|
);
|
|
668
883
|
}
|
|
669
884
|
}
|
|
670
885
|
function useProvide(key, value) {
|
|
671
886
|
var _a;
|
|
672
|
-
|
|
673
|
-
(_a =
|
|
887
|
+
assertInsideComponent("useProvide", key);
|
|
888
|
+
(_a = LifecycleContext.ref) == null ? void 0 : _a.setContext(key, value);
|
|
674
889
|
}
|
|
675
890
|
function useInject(key, defaultValue) {
|
|
676
891
|
var _a;
|
|
677
|
-
|
|
678
|
-
return ((_a =
|
|
892
|
+
assertInsideComponent("useInject", key);
|
|
893
|
+
return ((_a = LifecycleContext.ref) == null ? void 0 : _a.getContext(key)) || defaultValue;
|
|
679
894
|
}
|
|
680
895
|
function useRef() {
|
|
681
896
|
const ref = shallowSignal(null);
|
|
682
897
|
return ref;
|
|
683
898
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
if (isFunction(props[propKey])) {
|
|
693
|
-
delete props[propKey];
|
|
694
|
-
}
|
|
695
|
-
if (isSignal(props[propKey])) {
|
|
696
|
-
props[propKey] = props[propKey].value;
|
|
697
|
-
}
|
|
698
|
-
});
|
|
899
|
+
|
|
900
|
+
// src/hydration.ts
|
|
901
|
+
function renderToString(component, props) {
|
|
902
|
+
renderContext.setSSG();
|
|
903
|
+
const ssrNode = new SSGNode(component, props || {});
|
|
904
|
+
const html = ssrNode.mount();
|
|
905
|
+
renderContext.setClient();
|
|
906
|
+
return html;
|
|
699
907
|
}
|
|
700
|
-
function
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
const mapKey = path ? String(path) : `${key}`;
|
|
705
|
-
if (!childNodesMap[mapKey]) childNodesMap[mapKey] = [];
|
|
706
|
-
const childResult = result.mount();
|
|
707
|
-
childNodesMap[mapKey].push(
|
|
708
|
-
isFunction(childResult) ? childResult(prop) : isSignal(childResult) ? childResult.value : childResult
|
|
709
|
-
);
|
|
710
|
-
} else {
|
|
711
|
-
tmpl.template += isFunction(result) ? result(prop) : String(result);
|
|
908
|
+
function hydrate(component, container) {
|
|
909
|
+
const rootElement = typeof container === "string" ? document.querySelector(container) : container;
|
|
910
|
+
if (!rootElement) {
|
|
911
|
+
throw new Error(`Could not find container: ${container}`);
|
|
712
912
|
}
|
|
913
|
+
renderContext.setSSR();
|
|
914
|
+
h(component).mount(rootElement);
|
|
915
|
+
renderContext.setClient();
|
|
713
916
|
}
|
|
714
|
-
var ServerNode = class _ServerNode extends Hooks {
|
|
715
|
-
constructor(template2, props = {}, key) {
|
|
716
|
-
super();
|
|
717
|
-
this.template = template2;
|
|
718
|
-
this.props = props;
|
|
719
|
-
this.key = key;
|
|
720
|
-
this.childNodesMap = {};
|
|
721
|
-
this.processedTemplates = {};
|
|
722
|
-
}
|
|
723
|
-
/**
|
|
724
|
-
* Mount and render the component
|
|
725
|
-
*/
|
|
726
|
-
mount() {
|
|
727
|
-
this.initRef();
|
|
728
|
-
const output = this.render();
|
|
729
|
-
this.removeRef();
|
|
730
|
-
return output;
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Initialize template entries and props
|
|
734
|
-
*/
|
|
735
|
-
initTemplates() {
|
|
736
|
-
const templateCollection = Array.isArray(this.template) ? this.template.reduce((acc, tmpl, index) => {
|
|
737
|
-
acc[index + 1] = { template: tmpl };
|
|
738
|
-
return acc;
|
|
739
|
-
}, {}) : this.template;
|
|
740
|
-
if (isObject(templateCollection)) {
|
|
741
|
-
Object.entries(templateCollection).forEach(([key, tmpl]) => {
|
|
742
|
-
const prop = __spreadValues({}, this.props[key]);
|
|
743
|
-
normalizeProps(prop);
|
|
744
|
-
if (prop.children) {
|
|
745
|
-
prop.children.forEach((item) => {
|
|
746
|
-
const [child, path] = isArray(item) ? item : [item, null];
|
|
747
|
-
if (isFunction(child)) {
|
|
748
|
-
const result = child(prop);
|
|
749
|
-
handleChildResult(result, prop, key, tmpl, this.childNodesMap, path);
|
|
750
|
-
} else {
|
|
751
|
-
tmpl.template += isSignal(child) ? child.value : String(child);
|
|
752
|
-
}
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
this.processedTemplates[key] = {
|
|
756
|
-
template: tmpl.template,
|
|
757
|
-
props: prop
|
|
758
|
-
};
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
* Render component and its children into a string
|
|
764
|
-
*/
|
|
765
|
-
render() {
|
|
766
|
-
if (isFunction(this.template)) {
|
|
767
|
-
const root = this.template(this.props);
|
|
768
|
-
return root instanceof _ServerNode ? root.mount() : String(root);
|
|
769
|
-
}
|
|
770
|
-
if (this.template instanceof _ServerNode) {
|
|
771
|
-
return this.template.mount();
|
|
772
|
-
}
|
|
773
|
-
this.initTemplates();
|
|
774
|
-
return Object.entries(this.processedTemplates).map(([key, { template: template2, props }]) => {
|
|
775
|
-
let content = template2;
|
|
776
|
-
if (props && Object.keys(props).length > 0) {
|
|
777
|
-
content += ` ${generateAttributes(props)}`;
|
|
778
|
-
}
|
|
779
|
-
if (this.childNodesMap[key]) {
|
|
780
|
-
content = content.replace("<!>", this.renderChildren(this.childNodesMap[key]));
|
|
781
|
-
}
|
|
782
|
-
return content;
|
|
783
|
-
}).join("");
|
|
784
|
-
}
|
|
785
|
-
/**
|
|
786
|
-
* Render child nodes into a string
|
|
787
|
-
*/
|
|
788
|
-
renderChildren(children) {
|
|
789
|
-
return coerceArray(children).map(String).join("");
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
917
|
function ssg(component, props) {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
return
|
|
918
|
+
if (renderContext.isSSG) {
|
|
919
|
+
return new SSGNode(component, props);
|
|
920
|
+
}
|
|
921
|
+
return h(component, props);
|
|
797
922
|
}
|
|
798
923
|
|
|
799
|
-
export {
|
|
924
|
+
export { Fragment, h, hydrate, isComponent, isJsxElement, onDestroy, onMount, renderToString, ssg, createTemplate as template, useInject, useProvide, useRef };
|