@estjs/template 0.0.10 → 0.0.12-beta.1

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.
@@ -2216,19 +2216,20 @@ declare global {
2216
2216
  declare class TemplateNode$1 implements JSX.Element {
2217
2217
  template: HTMLTemplateElement;
2218
2218
  props: Record<string, unknown>;
2219
+ key?: string | undefined;
2220
+ constructor(template: HTMLTemplateElement, props: Record<string, unknown>, key?: string | undefined);
2219
2221
  treeMap: Map<number, Node>;
2220
- constructor(template: HTMLTemplateElement, props: Record<string, unknown>);
2221
2222
  mounted: boolean;
2222
2223
  nodes: Node[];
2223
2224
  provides: Record<string, unknown>;
2224
2225
  trackMap: Map<string, NodeTrack>;
2226
+ parent: Node | null;
2225
2227
  get firstChild(): Node | null;
2226
2228
  get isConnected(): boolean;
2227
2229
  addEventListener(): void;
2228
2230
  removeEventListener(): void;
2229
- unmount(): void;
2230
- parent: Node | null;
2231
2231
  mount(parent: Node, before?: Node | null): Node[];
2232
+ unmount(): void;
2232
2233
  mapNodeTree(parent: Node, tree: Node): void;
2233
2234
  patchNodes(props: any): void;
2234
2235
  getNodeTrack(trackKey: string, trackLastNodes?: boolean, isRoot?: boolean): NodeTrack;
@@ -2237,27 +2238,31 @@ declare class TemplateNode$1 implements JSX.Element {
2237
2238
  }
2238
2239
 
2239
2240
  type Hook = 'mounted' | 'destroy';
2240
- declare class ComponentNode$1 implements JSX.Element {
2241
- template: EssorComponent;
2242
- props: Record<string, any>;
2243
- constructor(template: EssorComponent, props: Record<string, any>);
2241
+ declare class Hooks {
2244
2242
  addEventListener(): void;
2245
2243
  removeEventListener(): void;
2246
- static ref: ComponentNode$1 | null;
2244
+ static ref: Hooks | null;
2247
2245
  static context: Record<symbol, Signal$1<any>>;
2248
- id?: string;
2246
+ hooks: Record<Hook, Set<() => void>>;
2247
+ addHook(hook: Hook, cb: () => void): void;
2248
+ getContext<T>(context: symbol | string | number): T | undefined;
2249
+ setContext<T>(context: symbol | string | number, value: T): void;
2250
+ initRef(): void;
2251
+ removeRef(): void;
2252
+ }
2253
+ declare class ComponentNode$1 extends Hooks implements JSX.Element {
2254
+ template: EssorComponent;
2255
+ props: Record<string, any>;
2256
+ key?: string | undefined;
2257
+ constructor(template: EssorComponent, props: Record<string, any>, key?: string | undefined);
2249
2258
  private proxyProps;
2250
- context: Record<symbol | string | number, any>;
2251
2259
  emitter: Set<Function>;
2252
2260
  mounted: boolean;
2253
2261
  rootNode: TemplateNode$1 | null;
2254
- hooks: Record<Hook, Set<() => void>>;
2262
+ context: Record<symbol | string | number, any>;
2255
2263
  private trackMap;
2256
2264
  get firstChild(): Node | null;
2257
2265
  get isConnected(): boolean;
2258
- addHook(hook: Hook, cb: () => void): void;
2259
- getContext<T>(context: symbol | string | number): T | undefined;
2260
- setContext<T>(context: symbol | string | number, value: T): void;
2261
2266
  inheritNode(node: ComponentNode$1): void;
2262
2267
  mount(parent: Node, before?: Node | null): Node[];
2263
2268
  unmount(): void;
@@ -2265,7 +2270,8 @@ declare class ComponentNode$1 implements JSX.Element {
2265
2270
  patchProps(props: Record<string, any>): void;
2266
2271
  }
2267
2272
 
2268
- declare function h<K extends keyof HTMLElementTagNameMap>(_template: EssorComponent | HTMLTemplateElement | K | '', props: Record<string, any>): JSX.Element;
2273
+ declare function h<K extends keyof HTMLElementTagNameMap>(_template: EssorComponent | HTMLTemplateElement | K | '', props: Record<string, unknown>, key?: string): JSX.Element;
2274
+ declare function isComponent(node: unknown): node is ComponentNode$1;
2269
2275
  declare function isJsxElement(node: unknown): node is EssorNode;
2270
2276
  declare function template(html: string): HTMLTemplateElement;
2271
2277
  declare function Fragment(props: {
@@ -2280,29 +2286,54 @@ interface InjectionKey<T> extends Symbol {
2280
2286
  }
2281
2287
  declare function useProvide<T, K = InjectionKey<T> | string | number>(key: K, value: K extends InjectionKey<infer V> ? V : T): void;
2282
2288
  declare function useInject<T, K = InjectionKey<T> | string | number>(key: K, defaultValue?: K extends InjectionKey<infer V> ? V : T): (K extends InjectionKey<infer V> ? V : T) | undefined;
2283
-
2284
- type Props = Record<string, any>;
2285
2289
  /**
2286
- * Renders a template to a string based on provided props.
2287
- * Handles both function-based and object-based templates.
2288
- * @param template - The template to render, which can be an array, an object, or a function.
2289
- * @param props - The properties used for rendering the template.
2290
- * @returns The rendered template as a string.
2290
+ * Creates a reactive ref that can be used to reference a DOM node
2291
+ * or a component instance within the component function body.
2292
+ *
2293
+ * @returns a reactive ref signal
2294
+ *
2295
+ * @example
2296
+ * const inputRef = useRef(')
2297
+ *
2298
+ * <input ref={inputRef} />
2299
+ *
2300
+ * inputRef.value // input element
2291
2301
  */
2292
- declare function renderTemplate(template: string[] | EssorNode | Function, props: Props): string;
2302
+ declare function useRef<T>(): Signal$1<T | null>;
2303
+
2304
+ type Props = Record<string, any>;
2305
+ declare class ServerNode extends Hooks {
2306
+ private template;
2307
+ private props;
2308
+ key?: string | undefined;
2309
+ private childNodesMap;
2310
+ private processedTemplates;
2311
+ constructor(template: string[] | EssorNode | Function, props?: Props, key?: string | undefined);
2312
+ /**
2313
+ * Mount and render the component
2314
+ */
2315
+ mount(): string;
2316
+ /**
2317
+ * Initialize template entries and props
2318
+ */
2319
+ private initTemplates;
2320
+ /**
2321
+ * Render component and its children into a string
2322
+ */
2323
+ render(): string;
2324
+ /**
2325
+ * Render child nodes into a string
2326
+ */
2327
+ private renderChildren;
2328
+ }
2329
+ type ServerNodeType = (props: Props) => ServerNode;
2293
2330
  /**
2294
- * Renders a component to a string using the given properties.
2295
- * @param component - The component function to be rendered.
2296
- * @param props - The properties to be passed to the component.
2297
- * @returns The rendered component as a string.
2331
+ * Create ServerNode for server-side generation (SSG)
2298
2332
  */
2299
- declare function renderToString(component: (...args: any[]) => string, props: Props): string;
2333
+ declare function ssg(component: string[] | ServerNodeType, props?: Props): ServerNode;
2300
2334
  /**
2301
- * Renders a component to a string and sets it as the innerHTML of the specified root element.
2302
- * @param component - The component function to be rendered.
2303
- * @param root - The root element in which to render the component.
2304
- * @param props - The properties to be passed to the component.
2335
+ * Render a component to string for SSR
2305
2336
  */
2306
- declare function renderSSG(component: any, root: HTMLElement, props?: Props): void;
2337
+ declare function renderToString(component: any, props?: Props): string;
2307
2338
 
2308
- export { ComponentNode$1 as ComponentNode, type EssorComponent, type EssorNode, Fragment, type Hook$1 as Hook, type InjectionKey, type NodeTrack, type Output, TemplateNode$1 as TemplateNode, h, isJsxElement, nextTick, onDestroy, onMount, renderSSG, renderTemplate, renderToString, template, useInject, useProvide };
2339
+ export { ComponentNode$1 as ComponentNode, type EssorComponent, type EssorNode, Fragment, type Hook$1 as Hook, type InjectionKey, type NodeTrack, type Output, TemplateNode$1 as TemplateNode, h, isComponent, isJsxElement, nextTick, onDestroy, onMount, renderToString, ssg, template, useInject, useProvide, useRef };
@@ -4,33 +4,74 @@ var shared = require('@estjs/shared');
4
4
  var signal = require('@estjs/signal');
5
5
 
6
6
  /**
7
- * @estjs/template v0.0.10
7
+ * @estjs/template v0.0.12-beta.1
8
8
  * (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
9
9
  * @license MIT
10
10
  **/
11
-
12
- var _ComponentNode = class _ComponentNode {
13
- constructor(template2, props) {
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
15
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
16
+ var __spreadValues = (a, b) => {
17
+ for (var prop in b || (b = {}))
18
+ if (__hasOwnProp.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ if (__getOwnPropSymbols)
21
+ for (var prop of __getOwnPropSymbols(b)) {
22
+ if (__propIsEnum.call(b, prop))
23
+ __defNormalProp(a, prop, b[prop]);
24
+ }
25
+ return a;
26
+ };
27
+ var _Hooks = class _Hooks {
28
+ constructor() {
29
+ this.hooks = {
30
+ mounted: /* @__PURE__ */ new Set(),
31
+ destroy: /* @__PURE__ */ new Set()
32
+ };
33
+ }
34
+ addEventListener() {
35
+ }
36
+ removeEventListener() {
37
+ }
38
+ addHook(hook, cb) {
39
+ var _a;
40
+ (_a = this.hooks[hook]) == null ? void 0 : _a.add(cb);
41
+ }
42
+ getContext(context) {
43
+ return _Hooks.context[context];
44
+ }
45
+ setContext(context, value) {
46
+ _Hooks.context[context] = value;
47
+ }
48
+ initRef() {
49
+ _Hooks.ref = this;
50
+ }
51
+ removeRef() {
52
+ _Hooks.ref = null;
53
+ }
54
+ };
55
+ _Hooks.ref = null;
56
+ _Hooks.context = {};
57
+ var Hooks = _Hooks;
58
+ var ComponentNode = class extends Hooks {
59
+ constructor(template2, props, key) {
60
+ super();
14
61
  this.template = template2;
15
62
  this.props = props;
63
+ this.key = key;
16
64
  this.proxyProps = {};
17
- this.context = {};
18
65
  this.emitter = /* @__PURE__ */ new Set();
19
66
  this.mounted = false;
20
67
  this.rootNode = null;
21
- this.hooks = {
22
- mounted: /* @__PURE__ */ new Set(),
23
- destroy: /* @__PURE__ */ new Set()
24
- };
68
+ this.context = {};
25
69
  this.trackMap = /* @__PURE__ */ new Map();
26
70
  this.proxyProps = signal.signalObject(
27
71
  props,
28
- (key) => shared.startsWith(key, "on") || shared.startsWith(key, "update")
72
+ (key2) => shared.startsWith(key2, "on") || shared.startsWith(key2, "update")
29
73
  );
30
- }
31
- addEventListener() {
32
- }
33
- removeEventListener() {
74
+ this.key = this.key || props.key;
34
75
  }
35
76
  get firstChild() {
36
77
  var _a, _b;
@@ -40,16 +81,6 @@ var _ComponentNode = class _ComponentNode {
40
81
  var _a, _b;
41
82
  return (_b = (_a = this.rootNode) == null ? void 0 : _a.isConnected) != null ? _b : false;
42
83
  }
43
- addHook(hook, cb) {
44
- var _a;
45
- (_a = this.hooks[hook]) == null ? void 0 : _a.add(cb);
46
- }
47
- getContext(context) {
48
- return _ComponentNode.context[context];
49
- }
50
- setContext(context, value) {
51
- _ComponentNode.context[context] = value;
52
- }
53
84
  inheritNode(node) {
54
85
  this.context = node.context;
55
86
  this.hooks = node.hooks;
@@ -68,9 +99,9 @@ var _ComponentNode = class _ComponentNode {
68
99
  if (this.isConnected) {
69
100
  return (_b = (_a = this.rootNode) == null ? void 0 : _a.mount(parent, before)) != null ? _b : [];
70
101
  }
71
- _ComponentNode.ref = this;
102
+ this.initRef();
72
103
  this.rootNode = this.template(signal.useReactive(this.proxyProps, ["children"]));
73
- _ComponentNode.ref = null;
104
+ this.removeRef();
74
105
  this.mounted = true;
75
106
  const mountedNode = (_d = (_c = this.rootNode) == null ? void 0 : _c.mount(parent, before)) != null ? _d : [];
76
107
  this.hooks.mounted.forEach((handler) => handler());
@@ -100,7 +131,7 @@ var _ComponentNode = class _ComponentNode {
100
131
  return track;
101
132
  }
102
133
  patchProps(props) {
103
- var _a, _b, _c, _d, _e;
134
+ var _a, _b, _c, _d;
104
135
  for (const [key, prop] of Object.entries(props)) {
105
136
  if (shared.startsWith(key, "on") && ((_a = this.rootNode) == null ? void 0 : _a.nodes)) {
106
137
  const event = key.slice(2).toLowerCase();
@@ -108,15 +139,11 @@ var _ComponentNode = class _ComponentNode {
108
139
  const cleanup = addEventListener(this.rootNode.nodes[0], event, listener);
109
140
  this.emitter.add(cleanup);
110
141
  } else if (key === "ref") {
111
- if (signal.isSignal(prop)) {
112
- props[key].value = (_b = this.rootNode) == null ? void 0 : _b.nodes[0];
113
- } else if (shared.isFunction(prop)) {
114
- props[key]((_c = this.rootNode) == null ? void 0 : _c.nodes[0]);
115
- }
142
+ props[key].value = (_b = this.rootNode) == null ? void 0 : _b.nodes[0];
116
143
  } else if (shared.startsWith(key, "update")) {
117
144
  props[key] = signal.isSignal(prop) ? prop.value : prop;
118
145
  } else if (key !== "children") {
119
- const newValue = (_e = (_d = this.proxyProps)[key]) != null ? _e : _d[key] = signal.useSignal(prop);
146
+ const newValue = (_d = (_c = this.proxyProps)[key]) != null ? _d : _c[key] = signal.useSignal(prop);
120
147
  const track = this.getNodeTrack(key);
121
148
  track.cleanup = signal.useEffect(() => {
122
149
  newValue.value = shared.isFunction(prop) ? prop() : prop;
@@ -126,12 +153,9 @@ var _ComponentNode = class _ComponentNode {
126
153
  this.props = props;
127
154
  }
128
155
  };
129
- _ComponentNode.ref = null;
130
- _ComponentNode.context = {};
131
- var ComponentNode = _ComponentNode;
132
156
 
133
157
  // src/template.ts
134
- function h(_template, props) {
158
+ function h(_template, props, key) {
135
159
  if (shared.isString(_template)) {
136
160
  if (isHtmlTagName(_template)) {
137
161
  _template = convertToHtmlTag(_template);
@@ -146,15 +170,17 @@ function h(_template, props) {
146
170
  }
147
171
  _template = template(_template);
148
172
  }
149
- return shared.isFunction(_template) ? new ComponentNode(_template, props) : new TemplateNode(_template, props);
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;
150
177
  }
151
178
  function isJsxElement(node) {
152
179
  return node instanceof ComponentNode || node instanceof TemplateNode;
153
180
  }
154
181
  function template(html) {
155
- html = closeHtmlTags(html);
156
182
  const template2 = document.createElement("template");
157
- template2.innerHTML = html;
183
+ template2.innerHTML = closeHtmlTags(html);
158
184
  return template2;
159
185
  }
160
186
  function Fragment(props) {
@@ -424,22 +450,28 @@ function mapKeys(children) {
424
450
  return result;
425
451
  }
426
452
  function getKey(node, index) {
427
- const id = node instanceof Element ? node.id : void 0;
428
- const result = id === "" ? void 0 : id;
429
- return result != null ? result : `_$${index}$`;
453
+ if (isJsxElement(node)) {
454
+ const jsxKey = node.key;
455
+ if (jsxKey !== void 0 && jsxKey !== null) {
456
+ return String(jsxKey);
457
+ }
458
+ }
459
+ return `_$${index}$`;
430
460
  }
431
461
 
432
462
  // src/template-node.ts
433
463
  var TemplateNode = class _TemplateNode {
434
- constructor(template2, props) {
464
+ constructor(template2, props, key) {
435
465
  this.template = template2;
436
466
  this.props = props;
467
+ this.key = key;
437
468
  this.treeMap = /* @__PURE__ */ new Map();
438
469
  this.mounted = false;
439
470
  this.nodes = [];
440
471
  this.provides = {};
441
472
  this.trackMap = /* @__PURE__ */ new Map();
442
473
  this.parent = null;
474
+ this.key = this.key || props.key;
443
475
  }
444
476
  get firstChild() {
445
477
  var _a;
@@ -452,24 +484,6 @@ var TemplateNode = class _TemplateNode {
452
484
  }
453
485
  removeEventListener() {
454
486
  }
455
- unmount() {
456
- this.trackMap.forEach((track) => {
457
- var _a, _b;
458
- (_a = track.cleanup) == null ? void 0 : _a.call(track);
459
- (_b = track.lastNodes) == null ? void 0 : _b.forEach((node) => {
460
- if (track.isRoot) {
461
- removeChild(node);
462
- } else if (node instanceof _TemplateNode) {
463
- node.unmount();
464
- }
465
- });
466
- });
467
- this.trackMap.clear();
468
- this.treeMap.clear();
469
- this.nodes.forEach((node) => removeChild(node));
470
- this.nodes = [];
471
- this.mounted = false;
472
- }
473
487
  mount(parent, before) {
474
488
  var _a;
475
489
  this.parent = parent;
@@ -492,6 +506,24 @@ var TemplateNode = class _TemplateNode {
492
506
  this.mounted = true;
493
507
  return this.nodes;
494
508
  }
509
+ unmount() {
510
+ this.trackMap.forEach((track) => {
511
+ var _a, _b;
512
+ (_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
+ });
521
+ this.trackMap.clear();
522
+ this.treeMap.clear();
523
+ this.nodes.forEach((node) => removeChild(node));
524
+ this.nodes = [];
525
+ this.mounted = false;
526
+ }
495
527
  mapNodeTree(parent, tree) {
496
528
  let index = 1;
497
529
  this.treeMap.set(0, parent);
@@ -562,11 +594,7 @@ var TemplateNode = class _TemplateNode {
562
594
  });
563
595
  }
564
596
  } else if (attr === "ref") {
565
- if (signal.isSignal(props[attr])) {
566
- props[attr].value = node;
567
- } else if (shared.isFunction(props[attr])) {
568
- props[attr](node);
569
- }
597
+ props[attr].value = node;
570
598
  } else if (shared.startsWith(attr, "on")) {
571
599
  const eventName = attr.slice(2).toLocaleLowerCase();
572
600
  const track = this.getNodeTrack(`${key}:${attr}`);
@@ -623,98 +651,165 @@ function patchChild(track, parent, child, before) {
623
651
  });
624
652
  }
625
653
  }
626
-
627
- // src/hooks.ts
628
654
  function onMount(cb) {
629
655
  var _a;
630
656
  throwIfOutsideComponent("onMounted");
631
- (_a = ComponentNode.ref) == null ? void 0 : _a.addHook("mounted", cb);
657
+ (_a = Hooks.ref) == null ? void 0 : _a.addHook("mounted", cb);
632
658
  }
633
659
  function onDestroy(cb) {
634
660
  var _a;
635
661
  throwIfOutsideComponent("onDestroy");
636
- (_a = ComponentNode.ref) == null ? void 0 : _a.addHook("destroy", cb);
662
+ (_a = Hooks.ref) == null ? void 0 : _a.addHook("destroy", cb);
637
663
  }
638
- function throwIfOutsideComponent(hook) {
639
- if (!ComponentNode.ref) {
664
+ function throwIfOutsideComponent(hook, key) {
665
+ if (!Hooks.ref) {
640
666
  console.error(
641
- `"${hook}" can only be called within the component function body
667
+ `"${hook}"(key: ${shared.isSymbol(key) ? key.toString() : key}) can only be called within the component function body
642
668
  and cannot be used in asynchronous or deferred calls.`
643
669
  );
644
670
  }
645
671
  }
646
672
  function useProvide(key, value) {
647
673
  var _a;
648
- throwIfOutsideComponent("useProvide");
649
- (_a = ComponentNode.ref) == null ? void 0 : _a.setContext(key, value);
674
+ throwIfOutsideComponent("useProvide", key);
675
+ (_a = Hooks.ref) == null ? void 0 : _a.setContext(key, value);
650
676
  }
651
677
  function useInject(key, defaultValue) {
652
678
  var _a;
653
- throwIfOutsideComponent("useInject");
654
- return ((_a = ComponentNode.ref) == null ? void 0 : _a.getContext(key)) || defaultValue;
655
- }
656
- function convertJsonToAttributes(json) {
657
- return Object.entries(json).map(([key, value]) => `${key}=${JSON.stringify(escape(String(value)))}`).join(" ");
658
- }
659
- function renderTemplate(template2, props) {
660
- if (shared.isFunction(template2)) {
661
- return template2(props);
662
- }
663
- const templateCollection = Array.isArray(template2) ? template2.reduce((acc, tmpl, index) => {
664
- acc[index + 1] = { template: tmpl };
665
- return acc;
666
- }, {}) : template2;
667
- const childNodesMap = {};
668
- const processedTemplates = {};
669
- if (shared.isObject(templateCollection)) {
670
- for (const [key, tmpl] of Object.entries(templateCollection)) {
671
- const prop = props[key];
672
- if (prop) {
673
- for (const propKey in prop) {
674
- if (shared.startsWith(propKey, "on") && shared.isFunction(prop[propKey])) {
675
- delete prop[propKey];
676
- }
677
- }
679
+ throwIfOutsideComponent("useInject", key);
680
+ return ((_a = Hooks.ref) == null ? void 0 : _a.getContext(key)) || defaultValue;
681
+ }
682
+ function useRef() {
683
+ const ref = signal.shallowSignal(null);
684
+ return ref;
685
+ }
686
+ function generateAttributes(props) {
687
+ return Object.entries(props).map(([key, value]) => {
688
+ if (key === "children" || shared.isFunction(value)) return "";
689
+ return `${key}="${shared.escape(String(value))}"`;
690
+ }).filter(Boolean).join(" ");
691
+ }
692
+ function normalizeProps(props) {
693
+ Object.keys(props).forEach((propKey) => {
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
+ });
701
+ }
702
+ function handleChildResult(result, prop, key, tmpl, childNodesMap, path) {
703
+ if (signal.isSignal(result)) {
704
+ tmpl.template += result.value;
705
+ } else if (result instanceof ServerNode) {
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);
714
+ }
715
+ }
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);
678
746
  if (prop.children) {
679
- for (const [child, idx] of prop.children) {
680
- if (!childNodesMap[idx]) childNodesMap[idx] = [];
681
- childNodesMap[idx].push(child);
682
- }
683
- delete 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
+ });
684
756
  }
685
- }
686
- processedTemplates[key] = { template: tmpl.template, props: prop };
757
+ this.processedTemplates[key] = {
758
+ template: tmpl.template,
759
+ props: prop
760
+ };
761
+ });
687
762
  }
688
763
  }
689
- return Object.entries(processedTemplates).map(([key, { template: tmpl, props: prop }]) => {
690
- let renderedString = tmpl;
691
- if (prop) {
692
- renderedString += ` ${convertJsonToAttributes(prop)}`;
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);
693
771
  }
694
- if (childNodesMap[key]) {
695
- renderedString += childNodesMap[key].map((child) => renderTemplate(child, prop)).join("");
772
+ if (this.template instanceof _ServerNode) {
773
+ return this.template.mount();
696
774
  }
697
- return renderedString;
698
- }).join("");
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
+ function ssg(component, props) {
795
+ return new ServerNode(component, props);
699
796
  }
700
797
  function renderToString(component, props) {
701
- return renderTemplate(component, props);
702
- }
703
- function renderSSG(component, root, props = {}) {
704
- root.innerHTML = renderTemplate(component, props);
798
+ return ssg(component, props).mount();
705
799
  }
706
800
 
707
801
  exports.ComponentNode = ComponentNode;
708
802
  exports.Fragment = Fragment;
709
803
  exports.TemplateNode = TemplateNode;
710
804
  exports.h = h;
805
+ exports.isComponent = isComponent;
711
806
  exports.isJsxElement = isJsxElement;
712
807
  exports.nextTick = nextTick;
713
808
  exports.onDestroy = onDestroy;
714
809
  exports.onMount = onMount;
715
- exports.renderSSG = renderSSG;
716
- exports.renderTemplate = renderTemplate;
717
810
  exports.renderToString = renderToString;
811
+ exports.ssg = ssg;
718
812
  exports.template = template;
719
813
  exports.useInject = useInject;
720
814
  exports.useProvide = useProvide;
815
+ exports.useRef = useRef;