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