@estjs/template 0.0.14-beta.2 → 0.0.14-beta.21
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 +3 -23
- package/dist/template.cjs.js.map +1 -1
- package/dist/template.d.cts +77 -40
- package/dist/template.d.ts +77 -40
- package/dist/template.dev.cjs.js +111 -189
- package/dist/template.dev.esm.js +112 -189
- package/dist/template.esm.js +3 -9
- package/dist/template.esm.js.map +1 -1
- package/package.json +3 -3
package/dist/template.dev.esm.js
CHANGED
|
@@ -1,46 +1,41 @@
|
|
|
1
|
-
import { isString, isFunction,
|
|
2
|
-
import {
|
|
1
|
+
import { isString, isFunction, isSymbol, isArray, escape, startsWith, hasChanged, capitalize, isNil, isPlainObject, isHTMLElement, coerceArray, isFalsy, kebabCase } from '@estjs/shared';
|
|
2
|
+
import { isSignal, shallowReactive, reactive, effect, shallowSignal } from '@estjs/signal';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @estjs/template v0.0.14-beta.
|
|
5
|
+
* @estjs/template v0.0.14-beta.21
|
|
6
6
|
* (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
|
|
7
7
|
* @license MIT
|
|
8
8
|
**/
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
// src/
|
|
11
|
+
// src/sharedConfig.ts
|
|
12
12
|
var EVENT_PREFIX = "on";
|
|
13
13
|
var UPDATE_PREFIX = "update";
|
|
14
14
|
var CHILDREN_PROP = "children";
|
|
15
15
|
var EMPTY_TEMPLATE = "";
|
|
16
16
|
var FRAGMENT_PROP_KEY = "0";
|
|
17
17
|
var SINGLE_PROP_KEY = "1";
|
|
18
|
+
var REF_KEY = "ref";
|
|
18
19
|
var PLACEHOLDER = " __PLACEHOLDER__ ";
|
|
19
20
|
var RenderContext = class {
|
|
20
21
|
constructor() {
|
|
21
22
|
this.renderMode = 0 /* CLIENT */;
|
|
22
23
|
}
|
|
23
|
-
// Getter to check if the current mode is SSG
|
|
24
24
|
get isSSG() {
|
|
25
25
|
return this.renderMode === 1 /* SSG */;
|
|
26
26
|
}
|
|
27
|
-
// Getter to check if the current mode is SSR
|
|
28
27
|
get isSSR() {
|
|
29
28
|
return this.renderMode === 2 /* SSR */;
|
|
30
29
|
}
|
|
31
|
-
// Getter to check if the current mode is Client
|
|
32
30
|
get isClient() {
|
|
33
31
|
return this.renderMode === 0 /* CLIENT */;
|
|
34
32
|
}
|
|
35
|
-
// Set render mode to SSR
|
|
36
33
|
setSSR() {
|
|
37
34
|
this.renderMode = 2 /* SSR */;
|
|
38
35
|
}
|
|
39
|
-
// Set render mode to SSG
|
|
40
36
|
setSSG() {
|
|
41
37
|
this.renderMode = 1 /* SSG */;
|
|
42
38
|
}
|
|
43
|
-
// Set render mode to Client
|
|
44
39
|
setClient() {
|
|
45
40
|
this.renderMode = 0 /* CLIENT */;
|
|
46
41
|
}
|
|
@@ -57,7 +52,7 @@ function getComponentIndex(temp) {
|
|
|
57
52
|
return (_a = componentMap.get(temp)) == null ? void 0 : _a.index;
|
|
58
53
|
}
|
|
59
54
|
|
|
60
|
-
// src/
|
|
55
|
+
// src/lifecycleContext.ts
|
|
61
56
|
var _LifecycleContext = class _LifecycleContext {
|
|
62
57
|
constructor() {
|
|
63
58
|
// Hooks for different lifecycle stages
|
|
@@ -83,11 +78,9 @@ var _LifecycleContext = class _LifecycleContext {
|
|
|
83
78
|
setContext(context, value) {
|
|
84
79
|
_LifecycleContext.context[context] = value;
|
|
85
80
|
}
|
|
86
|
-
// Initialize the static reference
|
|
87
81
|
initRef() {
|
|
88
82
|
_LifecycleContext.ref = this;
|
|
89
83
|
}
|
|
90
|
-
// Remove the static reference
|
|
91
84
|
removeRef() {
|
|
92
85
|
_LifecycleContext.ref = null;
|
|
93
86
|
}
|
|
@@ -96,13 +89,11 @@ var _LifecycleContext = class _LifecycleContext {
|
|
|
96
89
|
Object.values(this.hooks).forEach((set) => set.clear());
|
|
97
90
|
}
|
|
98
91
|
};
|
|
99
|
-
// Static reference to the current context
|
|
100
92
|
_LifecycleContext.ref = null;
|
|
101
|
-
// Static context to store shared values
|
|
102
93
|
_LifecycleContext.context = {};
|
|
103
94
|
var LifecycleContext = _LifecycleContext;
|
|
104
95
|
|
|
105
|
-
// src/
|
|
96
|
+
// src/ssgNode.ts
|
|
106
97
|
function isSSGNode(node) {
|
|
107
98
|
return node instanceof SSGNode;
|
|
108
99
|
}
|
|
@@ -116,7 +107,6 @@ var SSGNode = class extends LifecycleContext {
|
|
|
116
107
|
enterComponent(template, componentIndex);
|
|
117
108
|
this.templates = this.processTemplate();
|
|
118
109
|
}
|
|
119
|
-
// Process the template and return an array of processed strings
|
|
120
110
|
processTemplate() {
|
|
121
111
|
if (isArray(this.template)) {
|
|
122
112
|
const htmlString = this.template.join(PLACEHOLDER);
|
|
@@ -125,7 +115,6 @@ var SSGNode = class extends LifecycleContext {
|
|
|
125
115
|
}
|
|
126
116
|
return [];
|
|
127
117
|
}
|
|
128
|
-
// Process HTML string by adding component index and handling text nodes
|
|
129
118
|
processHtmlString(htmlString) {
|
|
130
119
|
return htmlString.replaceAll(/(<[^>]+>)|([^<]+)/g, (match, p1, p2) => {
|
|
131
120
|
if (p1) {
|
|
@@ -139,14 +128,12 @@ var SSGNode = class extends LifecycleContext {
|
|
|
139
128
|
return match;
|
|
140
129
|
});
|
|
141
130
|
}
|
|
142
|
-
// Mount the SSGNode and return the rendered string
|
|
143
131
|
mount() {
|
|
144
132
|
this.initRef();
|
|
145
133
|
const output = this.render();
|
|
146
134
|
this.removeRef();
|
|
147
135
|
return output;
|
|
148
136
|
}
|
|
149
|
-
// Render the SSGNode
|
|
150
137
|
render() {
|
|
151
138
|
if (isFunction(this.template)) {
|
|
152
139
|
const root = this.template(this.props);
|
|
@@ -158,7 +145,6 @@ var SSGNode = class extends LifecycleContext {
|
|
|
158
145
|
}
|
|
159
146
|
return this.renderTemplate();
|
|
160
147
|
}
|
|
161
|
-
// Render the template by processing props and children
|
|
162
148
|
renderTemplate() {
|
|
163
149
|
Object.entries(this.props).forEach(([key, cur]) => {
|
|
164
150
|
const children = cur.children;
|
|
@@ -174,10 +160,9 @@ var SSGNode = class extends LifecycleContext {
|
|
|
174
160
|
});
|
|
175
161
|
return this.templates.join("");
|
|
176
162
|
}
|
|
177
|
-
// Normalize props by removing children and handling signals
|
|
178
163
|
normalizeProps(props) {
|
|
179
164
|
Object.entries(props).forEach(([key, value]) => {
|
|
180
|
-
if (key ===
|
|
165
|
+
if (key === CHILDREN_PROP) {
|
|
181
166
|
delete props[key];
|
|
182
167
|
} else if (isFunction(value)) {
|
|
183
168
|
delete props[key];
|
|
@@ -186,11 +171,9 @@ var SSGNode = class extends LifecycleContext {
|
|
|
186
171
|
}
|
|
187
172
|
});
|
|
188
173
|
}
|
|
189
|
-
// Generate HTML attributes string from props
|
|
190
174
|
generateAttributes(props) {
|
|
191
|
-
return Object.entries(props).filter(([key, value]) => key !==
|
|
175
|
+
return Object.entries(props).filter(([key, value]) => key !== CHILDREN_PROP && !isFunction(value)).map(([key, value]) => `${key}="${escape(String(value))}"`).join(" ");
|
|
192
176
|
}
|
|
193
|
-
// Render children and append them to the template
|
|
194
177
|
renderChildren(children, findIndex) {
|
|
195
178
|
children.forEach(([child]) => {
|
|
196
179
|
componentIndex++;
|
|
@@ -198,12 +181,11 @@ var SSGNode = class extends LifecycleContext {
|
|
|
198
181
|
this.templates[findIndex] += renderedChild;
|
|
199
182
|
});
|
|
200
183
|
}
|
|
201
|
-
// Render a single child node
|
|
202
184
|
renderChild(child) {
|
|
203
|
-
if (
|
|
204
|
-
return this.renderChild(child(this.props));
|
|
205
|
-
} else if (isSignal(child)) {
|
|
185
|
+
if (isSignal(child)) {
|
|
206
186
|
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${child.value}<!$>`;
|
|
187
|
+
} else if (isFunction(child)) {
|
|
188
|
+
return this.renderChild(child(this.props));
|
|
207
189
|
} else if (isSSGNode(child)) {
|
|
208
190
|
const childResult = child.mount();
|
|
209
191
|
return isFunction(childResult) ? childResult(this.props) : extractSignal(childResult);
|
|
@@ -215,9 +197,6 @@ var SSGNode = class extends LifecycleContext {
|
|
|
215
197
|
|
|
216
198
|
// src/utils.ts
|
|
217
199
|
var SELF_CLOSING_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr".split(",");
|
|
218
|
-
var HTML_TAGS = "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(
|
|
219
|
-
","
|
|
220
|
-
);
|
|
221
200
|
function coerceNode(data) {
|
|
222
201
|
if (isJsxElement(data) || data instanceof Node || isSSGNode(data)) {
|
|
223
202
|
return data;
|
|
@@ -334,50 +313,10 @@ function bindNode(node, setter) {
|
|
|
334
313
|
});
|
|
335
314
|
}
|
|
336
315
|
}
|
|
337
|
-
Promise.resolve();
|
|
338
316
|
function addEventListener(node, eventName, handler) {
|
|
339
317
|
node.addEventListener(eventName, handler);
|
|
340
318
|
return () => node.removeEventListener(eventName, handler);
|
|
341
319
|
}
|
|
342
|
-
function closeHtmlTags(input) {
|
|
343
|
-
const tagStack = [];
|
|
344
|
-
const output = [];
|
|
345
|
-
const tagPattern = /<\/?([\da-z-]+)([^>]*)>/gi;
|
|
346
|
-
let lastIndex = 0;
|
|
347
|
-
while (true) {
|
|
348
|
-
const match = tagPattern.exec(input);
|
|
349
|
-
if (!match) break;
|
|
350
|
-
const [fullMatch, tagName] = match;
|
|
351
|
-
const isEndTag = fullMatch[1] === "/";
|
|
352
|
-
output.push(input.slice(lastIndex, match.index));
|
|
353
|
-
lastIndex = match.index + fullMatch.length;
|
|
354
|
-
if (isEndTag) {
|
|
355
|
-
while (tagStack.length > 0 && tagStack[tagStack.length - 1] !== tagName) {
|
|
356
|
-
const unclosedTag = tagStack.pop();
|
|
357
|
-
if (unclosedTag) {
|
|
358
|
-
output.push(`</${unclosedTag}>`);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (tagStack.length > 0) {
|
|
362
|
-
tagStack.pop();
|
|
363
|
-
}
|
|
364
|
-
} else if (!SELF_CLOSING_TAGS.includes(tagName)) {
|
|
365
|
-
tagStack.push(tagName);
|
|
366
|
-
}
|
|
367
|
-
output.push(fullMatch);
|
|
368
|
-
}
|
|
369
|
-
output.push(input.slice(lastIndex));
|
|
370
|
-
while (tagStack.length > 0) {
|
|
371
|
-
const unclosedTag = tagStack.pop();
|
|
372
|
-
if (unclosedTag) {
|
|
373
|
-
output.push(`</${unclosedTag}>`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return output.join("");
|
|
377
|
-
}
|
|
378
|
-
function isHtmlTagName(tagName) {
|
|
379
|
-
return HTML_TAGS.includes(tagName);
|
|
380
|
-
}
|
|
381
320
|
function convertToHtmlTag(tagName) {
|
|
382
321
|
return SELF_CLOSING_TAGS.includes(tagName) ? `<${tagName}/>` : `<${tagName}></${tagName}>`;
|
|
383
322
|
}
|
|
@@ -397,30 +336,30 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
397
336
|
this.emitter = /* @__PURE__ */ new Set();
|
|
398
337
|
this.rootNode = null;
|
|
399
338
|
this.trackMap = /* @__PURE__ */ new Map();
|
|
400
|
-
this.
|
|
401
|
-
this.
|
|
339
|
+
this.nodes = [];
|
|
340
|
+
this.parent = null;
|
|
341
|
+
this.before = null;
|
|
342
|
+
this.key || (this.key = props && props.key);
|
|
343
|
+
this.proxyProps || (this.proxyProps = this.createProxyProps(props));
|
|
402
344
|
}
|
|
403
|
-
// Create reactive props
|
|
404
345
|
createProxyProps(props) {
|
|
405
346
|
if (!props) return {};
|
|
406
|
-
return
|
|
347
|
+
return shallowReactive(
|
|
407
348
|
props,
|
|
408
349
|
(key) => startsWith(key, EVENT_PREFIX) || startsWith(key, UPDATE_PREFIX) || key === CHILDREN_PROP
|
|
409
350
|
);
|
|
410
351
|
}
|
|
411
|
-
// Getter for the first child node
|
|
412
352
|
get firstChild() {
|
|
413
353
|
var _a, _b;
|
|
414
354
|
return (_b = (_a = this.rootNode) == null ? void 0 : _a.firstChild) != null ? _b : null;
|
|
415
355
|
}
|
|
416
|
-
// Getter to check if the node is connected to the DOM
|
|
417
356
|
get isConnected() {
|
|
418
357
|
var _a, _b;
|
|
419
358
|
return (_b = (_a = this.rootNode) == null ? void 0 : _a.isConnected) != null ? _b : false;
|
|
420
359
|
}
|
|
421
|
-
// Method to mount the component to the DOM
|
|
422
360
|
mount(parent, before) {
|
|
423
361
|
var _a, _b, _c, _d;
|
|
362
|
+
this.parent = parent;
|
|
424
363
|
if (!isFunction(this.template)) {
|
|
425
364
|
throw new Error("Template must be a function");
|
|
426
365
|
}
|
|
@@ -428,49 +367,55 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
428
367
|
return (_b = (_a = this.rootNode) == null ? void 0 : _a.mount(parent, before)) != null ? _b : [];
|
|
429
368
|
}
|
|
430
369
|
this.initRef();
|
|
431
|
-
this.rootNode = this.template(this.proxyProps);
|
|
432
|
-
|
|
370
|
+
this.rootNode = this.template(reactive(this.proxyProps, [CHILDREN_PROP]));
|
|
371
|
+
this.nodes = (_d = (_c = this.rootNode) == null ? void 0 : _c.mount(parent, before)) != null ? _d : [];
|
|
433
372
|
this.callMountHooks();
|
|
434
373
|
this.patchProps(this.props);
|
|
435
374
|
this.removeRef();
|
|
436
|
-
return
|
|
375
|
+
return this.nodes;
|
|
437
376
|
}
|
|
438
|
-
// Method to unmount the component from the DOM
|
|
439
377
|
unmount() {
|
|
440
378
|
var _a;
|
|
441
|
-
this.
|
|
442
|
-
this.
|
|
379
|
+
this.callLifecycleHooks("destroy");
|
|
380
|
+
this.cleanup();
|
|
443
381
|
(_a = this.rootNode) == null ? void 0 : _a.unmount();
|
|
382
|
+
this.resetState();
|
|
383
|
+
if (this.key) {
|
|
384
|
+
componentCache.delete(this.key);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
resetState() {
|
|
444
388
|
this.rootNode = null;
|
|
445
389
|
this.proxyProps = {};
|
|
446
|
-
this.
|
|
390
|
+
this.nodes = [];
|
|
391
|
+
this.parent = null;
|
|
392
|
+
}
|
|
393
|
+
callLifecycleHooks(type) {
|
|
394
|
+
this.hooks[type].forEach((handler) => handler());
|
|
447
395
|
}
|
|
448
|
-
// Private method to call mount hooks
|
|
449
396
|
callMountHooks() {
|
|
450
397
|
this.hooks.mounted.forEach((handler) => handler());
|
|
451
398
|
}
|
|
452
|
-
// Private method to call destroy hooks
|
|
453
399
|
callDestroyHooks() {
|
|
454
400
|
this.hooks.destroy.forEach((handler) => handler());
|
|
455
401
|
}
|
|
456
|
-
// Private method to clear the event emitter
|
|
457
402
|
clearEmitter() {
|
|
458
403
|
for (const cleanup of this.emitter) {
|
|
459
404
|
cleanup();
|
|
460
405
|
}
|
|
461
406
|
this.emitter.clear();
|
|
462
407
|
}
|
|
463
|
-
// Method to inherit properties from another ComponentNode
|
|
464
408
|
inheritNode(node) {
|
|
465
409
|
Object.assign(this.proxyProps, node.proxyProps);
|
|
466
410
|
this.rootNode = node.rootNode;
|
|
467
411
|
this.trackMap = node.trackMap;
|
|
468
412
|
this.hooks = node.hooks;
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
413
|
+
if (hasChanged(node.props, this.props)) {
|
|
414
|
+
const props = this.props;
|
|
415
|
+
this.props = node.props;
|
|
416
|
+
this.patchProps(props);
|
|
417
|
+
}
|
|
472
418
|
}
|
|
473
|
-
// Private method to get or create a NodeTrack
|
|
474
419
|
getNodeTrack(trackKey) {
|
|
475
420
|
let track = this.trackMap.get(trackKey);
|
|
476
421
|
if (!track) {
|
|
@@ -481,7 +426,6 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
481
426
|
track.cleanup();
|
|
482
427
|
return track;
|
|
483
428
|
}
|
|
484
|
-
// Method to patch props onto the component
|
|
485
429
|
patchProps(props) {
|
|
486
430
|
var _a;
|
|
487
431
|
if (!props) {
|
|
@@ -490,7 +434,7 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
490
434
|
for (const [key, prop] of Object.entries(props)) {
|
|
491
435
|
if (startsWith(key, EVENT_PREFIX) && ((_a = this.rootNode) == null ? void 0 : _a.firstChild)) {
|
|
492
436
|
this.patchEventListener(key, prop);
|
|
493
|
-
} else if (key ===
|
|
437
|
+
} else if (key === REF_KEY) {
|
|
494
438
|
this.patchRef(prop);
|
|
495
439
|
} else if (startsWith(key, UPDATE_PREFIX)) {
|
|
496
440
|
this.patchUpdateHandler(key, prop);
|
|
@@ -500,28 +444,33 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
500
444
|
}
|
|
501
445
|
this.props = props;
|
|
502
446
|
}
|
|
503
|
-
// Private method to patch event listeners
|
|
504
447
|
patchEventListener(key, prop) {
|
|
505
448
|
const event = key.slice(2).toLowerCase();
|
|
506
449
|
const cleanup = addEventListener(this.rootNode.nodes[0], event, prop);
|
|
507
450
|
this.emitter.add(cleanup);
|
|
508
451
|
}
|
|
509
|
-
// Private method to patch ref
|
|
510
452
|
patchRef(prop) {
|
|
511
453
|
var _a, _b;
|
|
512
454
|
prop.value = (_b = (_a = this.rootNode) == null ? void 0 : _a.firstChild) != null ? _b : null;
|
|
513
455
|
}
|
|
514
|
-
// Private method to patch update handlers
|
|
515
456
|
patchUpdateHandler(key, prop) {
|
|
516
|
-
this.
|
|
457
|
+
this.proxyProps[key] = extractSignal(prop);
|
|
517
458
|
}
|
|
518
|
-
// Private method to patch normal props
|
|
519
459
|
patchNormalProp(key, prop) {
|
|
520
460
|
const track = this.getNodeTrack(key);
|
|
521
|
-
track.cleanup =
|
|
461
|
+
track.cleanup = effect(() => {
|
|
522
462
|
this.proxyProps[key] = isFunction(prop) ? prop() : prop;
|
|
523
463
|
});
|
|
524
464
|
}
|
|
465
|
+
cleanup() {
|
|
466
|
+
this.trackMap.forEach((track) => {
|
|
467
|
+
var _a;
|
|
468
|
+
return (_a = track.cleanup) == null ? void 0 : _a.call(track);
|
|
469
|
+
});
|
|
470
|
+
this.trackMap.clear();
|
|
471
|
+
this.emitter.forEach((cleanup) => cleanup());
|
|
472
|
+
this.emitter.clear();
|
|
473
|
+
}
|
|
525
474
|
};
|
|
526
475
|
|
|
527
476
|
// src/patch.ts
|
|
@@ -631,39 +580,33 @@ function getKey(node, index) {
|
|
|
631
580
|
return `_$${index}$`;
|
|
632
581
|
}
|
|
633
582
|
|
|
634
|
-
// src/
|
|
583
|
+
// src/templateNode.ts
|
|
635
584
|
var TemplateNode = class {
|
|
636
585
|
constructor(template, props, key) {
|
|
637
586
|
this.template = template;
|
|
638
587
|
this.props = props;
|
|
639
588
|
this.key = key;
|
|
640
|
-
// Private properties for managing the node's state
|
|
641
589
|
this.treeMap = /* @__PURE__ */ new Map();
|
|
642
590
|
this.mounted = false;
|
|
643
591
|
this.nodes = [];
|
|
644
592
|
this.trackMap = /* @__PURE__ */ new Map();
|
|
645
593
|
this.bindValueKeys = [];
|
|
646
594
|
this.parent = null;
|
|
647
|
-
this.key || (this.key = props == null ? void 0 : props.key);
|
|
648
595
|
if (renderContext.isSSR) {
|
|
649
596
|
this.componentIndex = getComponentIndex(this.template);
|
|
650
597
|
}
|
|
651
598
|
}
|
|
652
|
-
// Getter for the first child node
|
|
653
599
|
get firstChild() {
|
|
654
600
|
var _a;
|
|
655
601
|
return (_a = this.nodes[0]) != null ? _a : null;
|
|
656
602
|
}
|
|
657
|
-
// Getter to check if the node is connected to the DOM
|
|
658
603
|
get isConnected() {
|
|
659
604
|
return this.mounted;
|
|
660
605
|
}
|
|
661
|
-
// Placeholder methods for event handling
|
|
662
606
|
addEventListener() {
|
|
663
607
|
}
|
|
664
608
|
removeEventListener() {
|
|
665
609
|
}
|
|
666
|
-
// Method to mount the node to the DOM
|
|
667
610
|
mount(parent, before) {
|
|
668
611
|
var _a;
|
|
669
612
|
this.parent = parent;
|
|
@@ -678,7 +621,7 @@ var TemplateNode = class {
|
|
|
678
621
|
const firstChild = cloneNode.firstChild;
|
|
679
622
|
if ((_a = firstChild == null ? void 0 : firstChild.hasAttribute) == null ? void 0 : _a.call(firstChild, "_svg_")) {
|
|
680
623
|
firstChild.remove();
|
|
681
|
-
firstChild
|
|
624
|
+
firstChild.childNodes.forEach((node) => {
|
|
682
625
|
cloneNode.append(node);
|
|
683
626
|
});
|
|
684
627
|
}
|
|
@@ -693,45 +636,19 @@ var TemplateNode = class {
|
|
|
693
636
|
this.mounted = true;
|
|
694
637
|
return this.nodes;
|
|
695
638
|
}
|
|
696
|
-
// Method to unmount the node from the DOM
|
|
697
639
|
unmount() {
|
|
698
|
-
var _a, _b;
|
|
699
640
|
this.trackMap.forEach((track) => {
|
|
700
|
-
|
|
701
|
-
(_a2 = track.cleanup) == null ? void 0 : _a2.call(track);
|
|
641
|
+
track.cleanup && track.cleanup();
|
|
702
642
|
});
|
|
703
643
|
this.trackMap.clear();
|
|
704
644
|
this.treeMap.clear();
|
|
705
645
|
this.nodes.forEach((node) => removeChild(node));
|
|
706
|
-
if (!this.template.innerHTML && !this.nodes.length) {
|
|
707
|
-
const children = (_b = (_a = this.props) == null ? void 0 : _a[FRAGMENT_PROP_KEY]) == null ? void 0 : _b.children;
|
|
708
|
-
if (children) {
|
|
709
|
-
if (isArray(children)) {
|
|
710
|
-
children.forEach((child) => {
|
|
711
|
-
this.deleteFragmentTextNode(child);
|
|
712
|
-
});
|
|
713
|
-
} else {
|
|
714
|
-
this.deleteFragmentTextNode(children);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
646
|
this.nodes = [];
|
|
719
647
|
this.mounted = false;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
var _a;
|
|
723
|
-
if (isPrimitive(child)) {
|
|
724
|
-
(_a = this.parent) == null ? void 0 : _a.childNodes.forEach((node) => {
|
|
725
|
-
var _a2;
|
|
726
|
-
if (node.nodeType === Node.TEXT_NODE && node.textContent === `${child}`) {
|
|
727
|
-
(_a2 = this.parent) == null ? void 0 : _a2.removeChild(node);
|
|
728
|
-
}
|
|
729
|
-
});
|
|
730
|
-
} else {
|
|
731
|
-
removeChild(child);
|
|
648
|
+
if (this.key) {
|
|
649
|
+
componentCache.delete(this.key);
|
|
732
650
|
}
|
|
733
651
|
}
|
|
734
|
-
// Method to inherit properties from another TemplateNode
|
|
735
652
|
inheritNode(node) {
|
|
736
653
|
this.mounted = node.mounted;
|
|
737
654
|
this.nodes = node.nodes;
|
|
@@ -741,12 +658,11 @@ var TemplateNode = class {
|
|
|
741
658
|
this.props = node.props;
|
|
742
659
|
this.patchProps(props);
|
|
743
660
|
}
|
|
744
|
-
// Private method to map SSG node tree
|
|
745
661
|
mapSSGNodeTree(parent) {
|
|
746
662
|
this.treeMap.set(0, parent);
|
|
747
663
|
this.walkNodeTree(parent, this.handleSSGNode.bind(this));
|
|
748
664
|
}
|
|
749
|
-
//
|
|
665
|
+
// protected method to map node tree
|
|
750
666
|
mapNodeTree(parent, tree) {
|
|
751
667
|
let index = 1;
|
|
752
668
|
this.treeMap.set(0, parent);
|
|
@@ -757,7 +673,6 @@ var TemplateNode = class {
|
|
|
757
673
|
};
|
|
758
674
|
this.walkNodeTree(tree, handleNode);
|
|
759
675
|
}
|
|
760
|
-
// Private method to walk through the node tree
|
|
761
676
|
walkNodeTree(node, handler) {
|
|
762
677
|
if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
|
763
678
|
handler(node);
|
|
@@ -768,7 +683,6 @@ var TemplateNode = class {
|
|
|
768
683
|
child = child.nextSibling;
|
|
769
684
|
}
|
|
770
685
|
}
|
|
771
|
-
// Private method to handle SSG nodes
|
|
772
686
|
handleSSGNode(node) {
|
|
773
687
|
var _a;
|
|
774
688
|
if (node.nodeType === Node.COMMENT_NODE) {
|
|
@@ -784,7 +698,6 @@ var TemplateNode = class {
|
|
|
784
698
|
}
|
|
785
699
|
}
|
|
786
700
|
}
|
|
787
|
-
// Method to patch props onto the node
|
|
788
701
|
patchProps(props) {
|
|
789
702
|
if (!props) return;
|
|
790
703
|
Object.entries(props).forEach(([key, value]) => {
|
|
@@ -796,15 +709,14 @@ var TemplateNode = class {
|
|
|
796
709
|
});
|
|
797
710
|
this.props = props;
|
|
798
711
|
}
|
|
799
|
-
// Private method to patch a single prop
|
|
800
712
|
patchProp(key, node, props, isRoot) {
|
|
801
713
|
if (!props) return;
|
|
802
714
|
Object.entries(props).forEach(([attr, value]) => {
|
|
803
715
|
if (attr === CHILDREN_PROP && value) {
|
|
804
716
|
this.patchChildren(key, node, value, isRoot);
|
|
805
|
-
} else if (attr ===
|
|
717
|
+
} else if (attr === REF_KEY) {
|
|
806
718
|
props[attr].value = node;
|
|
807
|
-
} else if (startsWith(attr,
|
|
719
|
+
} else if (startsWith(attr, EVENT_PREFIX)) {
|
|
808
720
|
this.patchEventListener(key, node, attr, value);
|
|
809
721
|
} else {
|
|
810
722
|
if (this.bindValueKeys.includes(attr)) return;
|
|
@@ -814,14 +726,12 @@ var TemplateNode = class {
|
|
|
814
726
|
});
|
|
815
727
|
}
|
|
816
728
|
getBindUpdateValue(props, key, attr) {
|
|
817
|
-
const
|
|
818
|
-
const updateKey = `${UPDATE_PREFIX2}${capitalizeFirstLetter(attr)}`;
|
|
729
|
+
const updateKey = `${UPDATE_PREFIX}${capitalize(attr)}`;
|
|
819
730
|
if (updateKey && props[updateKey] && isFunction(props[updateKey])) {
|
|
820
731
|
this.bindValueKeys.push(updateKey);
|
|
821
732
|
return props[updateKey];
|
|
822
733
|
}
|
|
823
734
|
}
|
|
824
|
-
// Private method to patch children
|
|
825
735
|
patchChildren(key, node, children, isRoot) {
|
|
826
736
|
if (!isArray(children)) {
|
|
827
737
|
const trackKey = `${key}:${CHILDREN_PROP}:0`;
|
|
@@ -838,21 +748,19 @@ var TemplateNode = class {
|
|
|
838
748
|
});
|
|
839
749
|
}
|
|
840
750
|
}
|
|
841
|
-
// Private method to patch event listeners
|
|
842
751
|
patchEventListener(key, node, attr, listener) {
|
|
843
752
|
const eventName = attr.slice(2).toLowerCase();
|
|
844
753
|
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
845
754
|
track.cleanup = addEventListener(node, eventName, listener);
|
|
846
755
|
}
|
|
847
|
-
// Private method to patch attributes
|
|
848
756
|
patchAttribute(key, element, attr, value, updateFn) {
|
|
849
757
|
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
850
|
-
const
|
|
851
|
-
const
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
triggerValue.value = isSignal(
|
|
758
|
+
const triggerValue = shallowSignal();
|
|
759
|
+
const cleanup = effect(() => {
|
|
760
|
+
const unFnValue = isFunction(value) ? value() : value;
|
|
761
|
+
if (isPlainObject(unFnValue) && isPlainObject(triggerValue.peek()) && JSON.stringify(triggerValue.value) === JSON.stringify(unFnValue))
|
|
762
|
+
return;
|
|
763
|
+
triggerValue.value = isSignal(unFnValue) ? unFnValue.value : unFnValue;
|
|
856
764
|
setAttribute(element, attr, triggerValue.value);
|
|
857
765
|
});
|
|
858
766
|
let cleanupBind;
|
|
@@ -866,9 +774,7 @@ var TemplateNode = class {
|
|
|
866
774
|
cleanupBind && cleanupBind();
|
|
867
775
|
};
|
|
868
776
|
}
|
|
869
|
-
// Private method to get or create a NodeTrack
|
|
870
777
|
getNodeTrack(trackKey, trackLastNodes, isRoot) {
|
|
871
|
-
var _a;
|
|
872
778
|
let track = this.trackMap.get(trackKey);
|
|
873
779
|
if (!track) {
|
|
874
780
|
track = { cleanup: () => {
|
|
@@ -881,13 +787,12 @@ var TemplateNode = class {
|
|
|
881
787
|
}
|
|
882
788
|
this.trackMap.set(trackKey, track);
|
|
883
789
|
}
|
|
884
|
-
|
|
790
|
+
track.cleanup && track.cleanup();
|
|
885
791
|
return track;
|
|
886
792
|
}
|
|
887
|
-
// Private method to patch a child node
|
|
888
793
|
patchChild(track, parent, child, before) {
|
|
889
794
|
if (isFunction(child)) {
|
|
890
|
-
track.cleanup =
|
|
795
|
+
track.cleanup = effect(() => {
|
|
891
796
|
const nextNodes = coerceArray(child()).map(coerceNode);
|
|
892
797
|
if (renderContext.isSSR) {
|
|
893
798
|
track.lastNodes = this.reconcileChildren(parent, nextNodes, before);
|
|
@@ -908,7 +813,6 @@ var TemplateNode = class {
|
|
|
908
813
|
});
|
|
909
814
|
}
|
|
910
815
|
}
|
|
911
|
-
// Private method to reconcile children nodes
|
|
912
816
|
reconcileChildren(parent, nextNodes, before) {
|
|
913
817
|
const result = /* @__PURE__ */ new Map();
|
|
914
818
|
const textNodes = Array.from(parent.childNodes).filter(
|
|
@@ -934,19 +838,37 @@ var TemplateNode = class {
|
|
|
934
838
|
}
|
|
935
839
|
};
|
|
936
840
|
|
|
937
|
-
// src/
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
return
|
|
944
|
-
} else if (template === EMPTY_TEMPLATE) {
|
|
945
|
-
props = { [FRAGMENT_PROP_KEY]: props };
|
|
946
|
-
return new TemplateNode(createTemplate(EMPTY_TEMPLATE), props, key);
|
|
841
|
+
// src/jsxRenderer.ts
|
|
842
|
+
var componentCache = /* @__PURE__ */ new Map();
|
|
843
|
+
function createNodeCache(NodeConstructor, template, props = {}, key) {
|
|
844
|
+
if (key) {
|
|
845
|
+
const cached = componentCache.get(key);
|
|
846
|
+
if (cached) {
|
|
847
|
+
return cached;
|
|
947
848
|
}
|
|
948
849
|
}
|
|
949
|
-
|
|
850
|
+
if (typeof template === "string") {
|
|
851
|
+
template = createTemplate(template);
|
|
852
|
+
}
|
|
853
|
+
const newNode = new NodeConstructor(template, props, key);
|
|
854
|
+
if (key && newNode instanceof ComponentNode) {
|
|
855
|
+
componentCache.set(key, newNode);
|
|
856
|
+
}
|
|
857
|
+
return newNode;
|
|
858
|
+
}
|
|
859
|
+
function h(template, props = {}, key) {
|
|
860
|
+
if (template === EMPTY_TEMPLATE) {
|
|
861
|
+
return Fragment(template, props);
|
|
862
|
+
}
|
|
863
|
+
if (isString(template)) {
|
|
864
|
+
const htmlTemplate = convertToHtmlTag(template);
|
|
865
|
+
const wrappedProps = { [SINGLE_PROP_KEY]: props };
|
|
866
|
+
return createNodeCache(TemplateNode, htmlTemplate, wrappedProps, key);
|
|
867
|
+
}
|
|
868
|
+
if (isFunction(template)) {
|
|
869
|
+
return createNodeCache(ComponentNode, template, props, key);
|
|
870
|
+
}
|
|
871
|
+
return createNodeCache(TemplateNode, template, props, key);
|
|
950
872
|
}
|
|
951
873
|
function isComponent(node) {
|
|
952
874
|
return node instanceof ComponentNode;
|
|
@@ -956,13 +878,17 @@ function isJsxElement(node) {
|
|
|
956
878
|
}
|
|
957
879
|
function createTemplate(html) {
|
|
958
880
|
const template = document.createElement("template");
|
|
959
|
-
template.innerHTML =
|
|
881
|
+
template.innerHTML = html;
|
|
960
882
|
return template;
|
|
961
883
|
}
|
|
962
|
-
function Fragment(props) {
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
884
|
+
function Fragment(template, props) {
|
|
885
|
+
const processedProps = props.children ? {
|
|
886
|
+
[FRAGMENT_PROP_KEY]: {
|
|
887
|
+
children: Array.isArray(props.children) ? props.children.filter(Boolean) : [props.children]
|
|
888
|
+
}
|
|
889
|
+
} : props;
|
|
890
|
+
const templateElement = template === EMPTY_TEMPLATE ? createTemplate(EMPTY_TEMPLATE) : template;
|
|
891
|
+
return createNodeCache(TemplateNode, templateElement, processedProps);
|
|
966
892
|
}
|
|
967
893
|
function onMount(cb) {
|
|
968
894
|
assertInsideComponent("onMounted");
|
|
@@ -980,18 +906,15 @@ function assertInsideComponent(hookName, key) {
|
|
|
980
906
|
);
|
|
981
907
|
}
|
|
982
908
|
}
|
|
983
|
-
function
|
|
984
|
-
assertInsideComponent("
|
|
909
|
+
function provide(key, value) {
|
|
910
|
+
assertInsideComponent("provide", key);
|
|
985
911
|
LifecycleContext.ref && LifecycleContext.ref.setContext(key, value);
|
|
986
912
|
}
|
|
987
|
-
function
|
|
913
|
+
function inject(key, defaultValue) {
|
|
988
914
|
var _a;
|
|
989
|
-
assertInsideComponent("
|
|
915
|
+
assertInsideComponent("inject", key);
|
|
990
916
|
return (_a = LifecycleContext.ref && LifecycleContext.ref.getContext(key)) != null ? _a : defaultValue;
|
|
991
917
|
}
|
|
992
|
-
function useRef() {
|
|
993
|
-
return shallowSignal(null);
|
|
994
|
-
}
|
|
995
918
|
|
|
996
919
|
// src/server.ts
|
|
997
920
|
function renderToString(component, props) {
|
|
@@ -1017,4 +940,4 @@ function ssg(component, props) {
|
|
|
1017
940
|
return h(component, props);
|
|
1018
941
|
}
|
|
1019
942
|
|
|
1020
|
-
export { Fragment, h, hydrate, isComponent, isJsxElement, onDestroy, onMount, renderToString, ssg, createTemplate as template
|
|
943
|
+
export { Fragment, h, hydrate, inject, isComponent, isJsxElement, onDestroy, onMount, provide, renderToString, ssg, createTemplate as template };
|