@estjs/template 0.0.14-beta.9 → 0.0.14
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 +2 -2
- package/dist/template.cjs.js.map +1 -1
- package/dist/template.d.cts +76 -40
- package/dist/template.d.ts +76 -40
- package/dist/template.dev.cjs.js +84 -117
- package/dist/template.dev.esm.js +85 -117
- package/dist/template.esm.js +3 -3
- package/dist/template.esm.js.map +1 -1
- package/package.json +3 -3
package/dist/template.d.cts
CHANGED
|
@@ -4,6 +4,17 @@ import * as csstype from 'csstype';
|
|
|
4
4
|
type EssorComponent = (props: Record<string, unknown>) => JSX.Element | TemplateNode;
|
|
5
5
|
type Hook = 'mounted' | 'destroy';
|
|
6
6
|
|
|
7
|
+
interface NodeTrack {
|
|
8
|
+
cleanup: () => void;
|
|
9
|
+
isRoot?: boolean;
|
|
10
|
+
lastNodes?: Map<string, Node | JSX.Element>;
|
|
11
|
+
}
|
|
12
|
+
interface NodeTrack {
|
|
13
|
+
cleanup: () => void;
|
|
14
|
+
isRoot?: boolean;
|
|
15
|
+
lastNodes?: Map<string, Node | JSX.Element>;
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
type Props = Record<string, any>;
|
|
8
19
|
|
|
9
20
|
interface EssorNode<T = Record<string, any>> {
|
|
@@ -2212,30 +2223,71 @@ declare class LifecycleContext {
|
|
|
2212
2223
|
clearHooks(): void;
|
|
2213
2224
|
}
|
|
2214
2225
|
|
|
2226
|
+
declare class TemplateNode$1 implements JSX.Element {
|
|
2227
|
+
template: HTMLTemplateElement;
|
|
2228
|
+
props: Props;
|
|
2229
|
+
key?: string | undefined;
|
|
2230
|
+
protected treeMap: Map<number, Node>;
|
|
2231
|
+
protected mounted: boolean;
|
|
2232
|
+
protected nodes: Node[];
|
|
2233
|
+
protected trackMap: Map<string, NodeTrack>;
|
|
2234
|
+
protected bindValueKeys: string[];
|
|
2235
|
+
protected componentIndex: number;
|
|
2236
|
+
protected parent: Node | null;
|
|
2237
|
+
constructor(template: HTMLTemplateElement, props: Props, key?: string | undefined);
|
|
2238
|
+
get firstChild(): Node | null;
|
|
2239
|
+
get isConnected(): boolean;
|
|
2240
|
+
addEventListener(): void;
|
|
2241
|
+
removeEventListener(): void;
|
|
2242
|
+
mount(parent: Node, before?: Node | null): Node[];
|
|
2243
|
+
unmount(): void;
|
|
2244
|
+
inheritNode(node: TemplateNode$1): void;
|
|
2245
|
+
protected mapSSGNodeTree(parent: Node): void;
|
|
2246
|
+
protected mapNodeTree(parent: Node, tree: Node): void;
|
|
2247
|
+
protected walkNodeTree(node: Node, handler: (node: Node) => void): void;
|
|
2248
|
+
protected handleSSGNode(node: Node): void;
|
|
2249
|
+
protected patchProps(props: Record<string, Record<string, unknown>> | undefined): void;
|
|
2250
|
+
protected patchProp(key: string, node: Node, props: Record<string, unknown>, isRoot: boolean): void;
|
|
2251
|
+
protected getBindUpdateValue(props: Record<string, any>, key: string, attr: string): any;
|
|
2252
|
+
protected patchChildren(key: string, node: Node, children: unknown, isRoot: boolean): void;
|
|
2253
|
+
protected patchEventListener(key: string, node: Node, attr: string, listener: EventListener): void;
|
|
2254
|
+
protected patchAttribute(key: string, element: HTMLElement, attr: string, value: unknown, updateFn?: Function): void;
|
|
2255
|
+
protected getNodeTrack(trackKey: string, trackLastNodes?: boolean, isRoot?: boolean): NodeTrack;
|
|
2256
|
+
protected patchChild(track: NodeTrack, parent: Node, child: unknown, before: Node | null): void;
|
|
2257
|
+
protected reconcileChildren(parent: Node, nextNodes: Node[], before: Node | null): Map<string, Node>;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2215
2260
|
declare class ComponentNode$1 extends LifecycleContext implements JSX.Element {
|
|
2216
2261
|
template: EssorComponent;
|
|
2217
|
-
props
|
|
2262
|
+
props: Props;
|
|
2218
2263
|
key?: string | undefined;
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2264
|
+
protected proxyProps: Record<string, Signal$1<unknown>>;
|
|
2265
|
+
protected emitter: Set<() => void>;
|
|
2266
|
+
protected rootNode: TemplateNode$1 | null;
|
|
2267
|
+
protected trackMap: Map<string, NodeTrack>;
|
|
2268
|
+
protected nodes: Node[];
|
|
2269
|
+
protected parent: Node | null;
|
|
2270
|
+
protected before: Node | null;
|
|
2271
|
+
constructor(template: EssorComponent, props: Props, key?: string | undefined);
|
|
2225
2272
|
get firstChild(): Node | null;
|
|
2226
2273
|
get isConnected(): boolean;
|
|
2227
|
-
mount(parent: Node, before
|
|
2274
|
+
mount(parent: Node, before: Node | null): Node[];
|
|
2228
2275
|
unmount(): void;
|
|
2229
|
-
private
|
|
2230
|
-
|
|
2231
|
-
|
|
2276
|
+
private resetState;
|
|
2277
|
+
protected callLifecycleHooks(type: 'mounted' | 'destroy'): void;
|
|
2278
|
+
protected callMountHooks(): void;
|
|
2279
|
+
protected callDestroyHooks(): void;
|
|
2280
|
+
protected clearEmitter(): void;
|
|
2232
2281
|
inheritNode(node: ComponentNode$1): void;
|
|
2233
|
-
|
|
2282
|
+
protected getNodeTrack(trackKey: string): NodeTrack;
|
|
2234
2283
|
patchProps(props: Record<string, any> | undefined): void;
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2284
|
+
protected patchEventListener(key: string, prop: any): void;
|
|
2285
|
+
protected patchRef(prop: {
|
|
2286
|
+
value: Node | null;
|
|
2287
|
+
}): void;
|
|
2288
|
+
protected patchUpdateHandler(key: string, prop: any): void;
|
|
2289
|
+
protected patchNormalProp(key: string, prop: any): void;
|
|
2290
|
+
protected cleanup(): void;
|
|
2239
2291
|
}
|
|
2240
2292
|
|
|
2241
2293
|
/**
|
|
@@ -2270,14 +2322,12 @@ declare function isJsxElement(node: unknown): node is EssorNode;
|
|
|
2270
2322
|
* @returns A new HTML template element.
|
|
2271
2323
|
*/
|
|
2272
2324
|
declare function createTemplate(html: string): HTMLTemplateElement;
|
|
2273
|
-
|
|
2274
|
-
* @param props - An object containing the `children` prop.
|
|
2275
|
-
* @param props.children - The children to be rendered. Can be a single JSX element, string, number, boolean,
|
|
2276
|
-
* or an array of these. Falsy values in arrays will be filtered out.
|
|
2277
|
-
* @returns A JSX element representing the fragment, wrapping the filtered children.
|
|
2278
|
-
*/
|
|
2279
|
-
declare function Fragment<T extends JSX.JSXElement | string | number | boolean | (JSX.JSXElement | string | number | boolean)[]>(props: {
|
|
2325
|
+
declare function Fragment<T extends JSX.JSXElement | string | number | boolean | Array<JSX.JSXElement | string | number | boolean>>(template: HTMLTemplateElement | '', props: {
|
|
2280
2326
|
children: T;
|
|
2327
|
+
} | {
|
|
2328
|
+
[key: string]: {
|
|
2329
|
+
children: T;
|
|
2330
|
+
};
|
|
2281
2331
|
}): JSX.Element;
|
|
2282
2332
|
|
|
2283
2333
|
/**
|
|
@@ -2309,7 +2359,7 @@ interface InjectionKey<T> extends Symbol {
|
|
|
2309
2359
|
* @param key - The key to store the value in the LifecycleContext with.
|
|
2310
2360
|
* @param value - The value to store in the LifecycleContext with the given key.
|
|
2311
2361
|
*/
|
|
2312
|
-
declare function
|
|
2362
|
+
declare function provide<T, K = InjectionKey<T> | string | number>(key: K, value: K extends InjectionKey<infer V> ? V : T): void;
|
|
2313
2363
|
/**
|
|
2314
2364
|
* Injects a value from the current component LifecycleContext.
|
|
2315
2365
|
*
|
|
@@ -2322,21 +2372,7 @@ declare function useProvide<T, K = InjectionKey<T> | string | number>(key: K, va
|
|
|
2322
2372
|
* @returns The value stored in the LifecycleContext with the given key, or the default
|
|
2323
2373
|
* value if the key is not present in the LifecycleContext.
|
|
2324
2374
|
*/
|
|
2325
|
-
declare function
|
|
2326
|
-
/**
|
|
2327
|
-
* Creates a reactive ref that can be used to reference a DOM node
|
|
2328
|
-
* or a component instance within the component function body.
|
|
2329
|
-
*
|
|
2330
|
-
* @returns a reactive ref signal
|
|
2331
|
-
*
|
|
2332
|
-
* @example
|
|
2333
|
-
* const inputRef = useRef<HTMLInputElement>()
|
|
2334
|
-
*
|
|
2335
|
-
* <input ref={inputRef} />
|
|
2336
|
-
*
|
|
2337
|
-
* inputRef.value // input element
|
|
2338
|
-
*/
|
|
2339
|
-
declare function useRef<T>(): Signal$1<T | null>;
|
|
2375
|
+
declare function inject<T, K = InjectionKey<T> | string | number>(key: K, defaultValue?: K extends InjectionKey<infer V> ? V : T): (K extends InjectionKey<infer V> ? V : T) | undefined;
|
|
2340
2376
|
|
|
2341
2377
|
declare class SSGNode extends LifecycleContext {
|
|
2342
2378
|
private template;
|
|
@@ -2386,4 +2422,4 @@ declare function hydrate(component: EssorComponent, container: string | Element)
|
|
|
2386
2422
|
*/
|
|
2387
2423
|
declare function ssg(component: EssorComponent, props?: Props): SSGNode | JSX.Element;
|
|
2388
2424
|
|
|
2389
|
-
export { Fragment, type InjectionKey, h, hydrate, isComponent, isJsxElement, onDestroy, onMount, renderToString, ssg, createTemplate as template
|
|
2425
|
+
export { Fragment, type InjectionKey, h, hydrate, inject, isComponent, isJsxElement, onDestroy, onMount, provide, renderToString, ssg, createTemplate as template };
|
package/dist/template.d.ts
CHANGED
|
@@ -4,6 +4,17 @@ import * as csstype from 'csstype';
|
|
|
4
4
|
type EssorComponent = (props: Record<string, unknown>) => JSX.Element | TemplateNode;
|
|
5
5
|
type Hook = 'mounted' | 'destroy';
|
|
6
6
|
|
|
7
|
+
interface NodeTrack {
|
|
8
|
+
cleanup: () => void;
|
|
9
|
+
isRoot?: boolean;
|
|
10
|
+
lastNodes?: Map<string, Node | JSX.Element>;
|
|
11
|
+
}
|
|
12
|
+
interface NodeTrack {
|
|
13
|
+
cleanup: () => void;
|
|
14
|
+
isRoot?: boolean;
|
|
15
|
+
lastNodes?: Map<string, Node | JSX.Element>;
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
type Props = Record<string, any>;
|
|
8
19
|
|
|
9
20
|
interface EssorNode<T = Record<string, any>> {
|
|
@@ -2212,30 +2223,71 @@ declare class LifecycleContext {
|
|
|
2212
2223
|
clearHooks(): void;
|
|
2213
2224
|
}
|
|
2214
2225
|
|
|
2226
|
+
declare class TemplateNode$1 implements JSX.Element {
|
|
2227
|
+
template: HTMLTemplateElement;
|
|
2228
|
+
props: Props;
|
|
2229
|
+
key?: string | undefined;
|
|
2230
|
+
protected treeMap: Map<number, Node>;
|
|
2231
|
+
protected mounted: boolean;
|
|
2232
|
+
protected nodes: Node[];
|
|
2233
|
+
protected trackMap: Map<string, NodeTrack>;
|
|
2234
|
+
protected bindValueKeys: string[];
|
|
2235
|
+
protected componentIndex: number;
|
|
2236
|
+
protected parent: Node | null;
|
|
2237
|
+
constructor(template: HTMLTemplateElement, props: Props, key?: string | undefined);
|
|
2238
|
+
get firstChild(): Node | null;
|
|
2239
|
+
get isConnected(): boolean;
|
|
2240
|
+
addEventListener(): void;
|
|
2241
|
+
removeEventListener(): void;
|
|
2242
|
+
mount(parent: Node, before?: Node | null): Node[];
|
|
2243
|
+
unmount(): void;
|
|
2244
|
+
inheritNode(node: TemplateNode$1): void;
|
|
2245
|
+
protected mapSSGNodeTree(parent: Node): void;
|
|
2246
|
+
protected mapNodeTree(parent: Node, tree: Node): void;
|
|
2247
|
+
protected walkNodeTree(node: Node, handler: (node: Node) => void): void;
|
|
2248
|
+
protected handleSSGNode(node: Node): void;
|
|
2249
|
+
protected patchProps(props: Record<string, Record<string, unknown>> | undefined): void;
|
|
2250
|
+
protected patchProp(key: string, node: Node, props: Record<string, unknown>, isRoot: boolean): void;
|
|
2251
|
+
protected getBindUpdateValue(props: Record<string, any>, key: string, attr: string): any;
|
|
2252
|
+
protected patchChildren(key: string, node: Node, children: unknown, isRoot: boolean): void;
|
|
2253
|
+
protected patchEventListener(key: string, node: Node, attr: string, listener: EventListener): void;
|
|
2254
|
+
protected patchAttribute(key: string, element: HTMLElement, attr: string, value: unknown, updateFn?: Function): void;
|
|
2255
|
+
protected getNodeTrack(trackKey: string, trackLastNodes?: boolean, isRoot?: boolean): NodeTrack;
|
|
2256
|
+
protected patchChild(track: NodeTrack, parent: Node, child: unknown, before: Node | null): void;
|
|
2257
|
+
protected reconcileChildren(parent: Node, nextNodes: Node[], before: Node | null): Map<string, Node>;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2215
2260
|
declare class ComponentNode$1 extends LifecycleContext implements JSX.Element {
|
|
2216
2261
|
template: EssorComponent;
|
|
2217
|
-
props
|
|
2262
|
+
props: Props;
|
|
2218
2263
|
key?: string | undefined;
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2264
|
+
protected proxyProps: Record<string, Signal$1<unknown>>;
|
|
2265
|
+
protected emitter: Set<() => void>;
|
|
2266
|
+
protected rootNode: TemplateNode$1 | null;
|
|
2267
|
+
protected trackMap: Map<string, NodeTrack>;
|
|
2268
|
+
protected nodes: Node[];
|
|
2269
|
+
protected parent: Node | null;
|
|
2270
|
+
protected before: Node | null;
|
|
2271
|
+
constructor(template: EssorComponent, props: Props, key?: string | undefined);
|
|
2225
2272
|
get firstChild(): Node | null;
|
|
2226
2273
|
get isConnected(): boolean;
|
|
2227
|
-
mount(parent: Node, before
|
|
2274
|
+
mount(parent: Node, before: Node | null): Node[];
|
|
2228
2275
|
unmount(): void;
|
|
2229
|
-
private
|
|
2230
|
-
|
|
2231
|
-
|
|
2276
|
+
private resetState;
|
|
2277
|
+
protected callLifecycleHooks(type: 'mounted' | 'destroy'): void;
|
|
2278
|
+
protected callMountHooks(): void;
|
|
2279
|
+
protected callDestroyHooks(): void;
|
|
2280
|
+
protected clearEmitter(): void;
|
|
2232
2281
|
inheritNode(node: ComponentNode$1): void;
|
|
2233
|
-
|
|
2282
|
+
protected getNodeTrack(trackKey: string): NodeTrack;
|
|
2234
2283
|
patchProps(props: Record<string, any> | undefined): void;
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2284
|
+
protected patchEventListener(key: string, prop: any): void;
|
|
2285
|
+
protected patchRef(prop: {
|
|
2286
|
+
value: Node | null;
|
|
2287
|
+
}): void;
|
|
2288
|
+
protected patchUpdateHandler(key: string, prop: any): void;
|
|
2289
|
+
protected patchNormalProp(key: string, prop: any): void;
|
|
2290
|
+
protected cleanup(): void;
|
|
2239
2291
|
}
|
|
2240
2292
|
|
|
2241
2293
|
/**
|
|
@@ -2270,14 +2322,12 @@ declare function isJsxElement(node: unknown): node is EssorNode;
|
|
|
2270
2322
|
* @returns A new HTML template element.
|
|
2271
2323
|
*/
|
|
2272
2324
|
declare function createTemplate(html: string): HTMLTemplateElement;
|
|
2273
|
-
|
|
2274
|
-
* @param props - An object containing the `children` prop.
|
|
2275
|
-
* @param props.children - The children to be rendered. Can be a single JSX element, string, number, boolean,
|
|
2276
|
-
* or an array of these. Falsy values in arrays will be filtered out.
|
|
2277
|
-
* @returns A JSX element representing the fragment, wrapping the filtered children.
|
|
2278
|
-
*/
|
|
2279
|
-
declare function Fragment<T extends JSX.JSXElement | string | number | boolean | (JSX.JSXElement | string | number | boolean)[]>(props: {
|
|
2325
|
+
declare function Fragment<T extends JSX.JSXElement | string | number | boolean | Array<JSX.JSXElement | string | number | boolean>>(template: HTMLTemplateElement | '', props: {
|
|
2280
2326
|
children: T;
|
|
2327
|
+
} | {
|
|
2328
|
+
[key: string]: {
|
|
2329
|
+
children: T;
|
|
2330
|
+
};
|
|
2281
2331
|
}): JSX.Element;
|
|
2282
2332
|
|
|
2283
2333
|
/**
|
|
@@ -2309,7 +2359,7 @@ interface InjectionKey<T> extends Symbol {
|
|
|
2309
2359
|
* @param key - The key to store the value in the LifecycleContext with.
|
|
2310
2360
|
* @param value - The value to store in the LifecycleContext with the given key.
|
|
2311
2361
|
*/
|
|
2312
|
-
declare function
|
|
2362
|
+
declare function provide<T, K = InjectionKey<T> | string | number>(key: K, value: K extends InjectionKey<infer V> ? V : T): void;
|
|
2313
2363
|
/**
|
|
2314
2364
|
* Injects a value from the current component LifecycleContext.
|
|
2315
2365
|
*
|
|
@@ -2322,21 +2372,7 @@ declare function useProvide<T, K = InjectionKey<T> | string | number>(key: K, va
|
|
|
2322
2372
|
* @returns The value stored in the LifecycleContext with the given key, or the default
|
|
2323
2373
|
* value if the key is not present in the LifecycleContext.
|
|
2324
2374
|
*/
|
|
2325
|
-
declare function
|
|
2326
|
-
/**
|
|
2327
|
-
* Creates a reactive ref that can be used to reference a DOM node
|
|
2328
|
-
* or a component instance within the component function body.
|
|
2329
|
-
*
|
|
2330
|
-
* @returns a reactive ref signal
|
|
2331
|
-
*
|
|
2332
|
-
* @example
|
|
2333
|
-
* const inputRef = useRef<HTMLInputElement>()
|
|
2334
|
-
*
|
|
2335
|
-
* <input ref={inputRef} />
|
|
2336
|
-
*
|
|
2337
|
-
* inputRef.value // input element
|
|
2338
|
-
*/
|
|
2339
|
-
declare function useRef<T>(): Signal$1<T | null>;
|
|
2375
|
+
declare function inject<T, K = InjectionKey<T> | string | number>(key: K, defaultValue?: K extends InjectionKey<infer V> ? V : T): (K extends InjectionKey<infer V> ? V : T) | undefined;
|
|
2340
2376
|
|
|
2341
2377
|
declare class SSGNode extends LifecycleContext {
|
|
2342
2378
|
private template;
|
|
@@ -2386,4 +2422,4 @@ declare function hydrate(component: EssorComponent, container: string | Element)
|
|
|
2386
2422
|
*/
|
|
2387
2423
|
declare function ssg(component: EssorComponent, props?: Props): SSGNode | JSX.Element;
|
|
2388
2424
|
|
|
2389
|
-
export { Fragment, type InjectionKey, h, hydrate, isComponent, isJsxElement, onDestroy, onMount, renderToString, ssg, createTemplate as template
|
|
2425
|
+
export { Fragment, type InjectionKey, h, hydrate, inject, isComponent, isJsxElement, onDestroy, onMount, provide, renderToString, ssg, createTemplate as template };
|
package/dist/template.dev.cjs.js
CHANGED
|
@@ -4,7 +4,7 @@ var shared = require('@estjs/shared');
|
|
|
4
4
|
var signal = require('@estjs/signal');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @estjs/template v0.0.14
|
|
7
|
+
* @estjs/template v0.0.14
|
|
8
8
|
* (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
|
|
9
9
|
* @license MIT
|
|
10
10
|
**/
|
|
@@ -184,10 +184,10 @@ var SSGNode = class extends LifecycleContext {
|
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
renderChild(child) {
|
|
187
|
-
if (
|
|
188
|
-
return this.renderChild(child(this.props));
|
|
189
|
-
} else if (signal.isSignal(child)) {
|
|
187
|
+
if (signal.isSignal(child)) {
|
|
190
188
|
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${child.value}<!$>`;
|
|
189
|
+
} else if (shared.isFunction(child)) {
|
|
190
|
+
return this.renderChild(child(this.props));
|
|
191
191
|
} else if (isSSGNode(child)) {
|
|
192
192
|
const childResult = child.mount();
|
|
193
193
|
return shared.isFunction(childResult) ? childResult(this.props) : extractSignal(childResult);
|
|
@@ -319,42 +319,6 @@ function addEventListener(node, eventName, handler) {
|
|
|
319
319
|
node.addEventListener(eventName, handler);
|
|
320
320
|
return () => node.removeEventListener(eventName, handler);
|
|
321
321
|
}
|
|
322
|
-
function closeHtmlTags(input) {
|
|
323
|
-
const tagStack = [];
|
|
324
|
-
const output = [];
|
|
325
|
-
const tagPattern = /<\/?([\da-z-]+)([^>]*)>/gi;
|
|
326
|
-
let lastIndex = 0;
|
|
327
|
-
while (true) {
|
|
328
|
-
const match = tagPattern.exec(input);
|
|
329
|
-
if (!match) break;
|
|
330
|
-
const [fullMatch, tagName] = match;
|
|
331
|
-
const isEndTag = fullMatch[1] === "/";
|
|
332
|
-
output.push(input.slice(lastIndex, match.index));
|
|
333
|
-
lastIndex = match.index + fullMatch.length;
|
|
334
|
-
if (isEndTag) {
|
|
335
|
-
while (tagStack.length > 0 && tagStack[tagStack.length - 1] !== tagName) {
|
|
336
|
-
const unclosedTag = tagStack.pop();
|
|
337
|
-
if (unclosedTag) {
|
|
338
|
-
output.push(`</${unclosedTag}>`);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
if (tagStack.length > 0) {
|
|
342
|
-
tagStack.pop();
|
|
343
|
-
}
|
|
344
|
-
} else if (!SELF_CLOSING_TAGS.includes(tagName)) {
|
|
345
|
-
tagStack.push(tagName);
|
|
346
|
-
}
|
|
347
|
-
output.push(fullMatch);
|
|
348
|
-
}
|
|
349
|
-
output.push(input.slice(lastIndex));
|
|
350
|
-
while (tagStack.length > 0) {
|
|
351
|
-
const unclosedTag = tagStack.pop();
|
|
352
|
-
if (unclosedTag) {
|
|
353
|
-
output.push(`</${unclosedTag}>`);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return output.join("");
|
|
357
|
-
}
|
|
358
322
|
function convertToHtmlTag(tagName) {
|
|
359
323
|
return SELF_CLOSING_TAGS.includes(tagName) ? `<${tagName}/>` : `<${tagName}></${tagName}>`;
|
|
360
324
|
}
|
|
@@ -374,15 +338,11 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
374
338
|
this.emitter = /* @__PURE__ */ new Set();
|
|
375
339
|
this.rootNode = null;
|
|
376
340
|
this.trackMap = /* @__PURE__ */ new Map();
|
|
341
|
+
this.nodes = [];
|
|
342
|
+
this.parent = null;
|
|
343
|
+
this.before = null;
|
|
377
344
|
this.key || (this.key = props && props.key);
|
|
378
|
-
this.proxyProps
|
|
379
|
-
}
|
|
380
|
-
createProxyProps(props) {
|
|
381
|
-
if (!props) return {};
|
|
382
|
-
return signal.signalObject(
|
|
383
|
-
props,
|
|
384
|
-
(key) => shared.startsWith(key, EVENT_PREFIX) || shared.startsWith(key, UPDATE_PREFIX) || key === CHILDREN_PROP
|
|
385
|
-
);
|
|
345
|
+
this.proxyProps || (this.proxyProps = signal.shallowReactive(props || {}));
|
|
386
346
|
}
|
|
387
347
|
get firstChild() {
|
|
388
348
|
var _a, _b;
|
|
@@ -394,6 +354,7 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
394
354
|
}
|
|
395
355
|
mount(parent, before) {
|
|
396
356
|
var _a, _b, _c, _d;
|
|
357
|
+
this.parent = parent;
|
|
397
358
|
if (!shared.isFunction(this.template)) {
|
|
398
359
|
throw new Error("Template must be a function");
|
|
399
360
|
}
|
|
@@ -402,20 +363,30 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
402
363
|
}
|
|
403
364
|
this.initRef();
|
|
404
365
|
this.rootNode = this.template(signal.useReactive(this.proxyProps, [CHILDREN_PROP]));
|
|
405
|
-
|
|
366
|
+
this.nodes = (_d = (_c = this.rootNode) == null ? void 0 : _c.mount(parent, before)) != null ? _d : [];
|
|
406
367
|
this.callMountHooks();
|
|
407
368
|
this.patchProps(this.props);
|
|
408
369
|
this.removeRef();
|
|
409
|
-
return
|
|
370
|
+
return this.nodes;
|
|
410
371
|
}
|
|
411
372
|
unmount() {
|
|
412
373
|
var _a;
|
|
413
|
-
this.
|
|
414
|
-
this.
|
|
374
|
+
this.callLifecycleHooks("destroy");
|
|
375
|
+
this.cleanup();
|
|
415
376
|
(_a = this.rootNode) == null ? void 0 : _a.unmount();
|
|
377
|
+
this.resetState();
|
|
378
|
+
if (this.key) {
|
|
379
|
+
componentCache.delete(this.key);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
resetState() {
|
|
416
383
|
this.rootNode = null;
|
|
417
384
|
this.proxyProps = {};
|
|
418
|
-
this.
|
|
385
|
+
this.nodes = [];
|
|
386
|
+
this.parent = null;
|
|
387
|
+
}
|
|
388
|
+
callLifecycleHooks(type) {
|
|
389
|
+
this.hooks[type].forEach((handler) => handler());
|
|
419
390
|
}
|
|
420
391
|
callMountHooks() {
|
|
421
392
|
this.hooks.mounted.forEach((handler) => handler());
|
|
@@ -434,9 +405,11 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
434
405
|
this.rootNode = node.rootNode;
|
|
435
406
|
this.trackMap = node.trackMap;
|
|
436
407
|
this.hooks = node.hooks;
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
408
|
+
if (shared.hasChanged(node.props, this.props)) {
|
|
409
|
+
const props = this.props;
|
|
410
|
+
this.props = node.props;
|
|
411
|
+
this.patchProps(props);
|
|
412
|
+
}
|
|
440
413
|
}
|
|
441
414
|
getNodeTrack(trackKey) {
|
|
442
415
|
let track = this.trackMap.get(trackKey);
|
|
@@ -476,16 +449,23 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
476
449
|
prop.value = (_b = (_a = this.rootNode) == null ? void 0 : _a.firstChild) != null ? _b : null;
|
|
477
450
|
}
|
|
478
451
|
patchUpdateHandler(key, prop) {
|
|
479
|
-
this.
|
|
452
|
+
this.proxyProps[key] = extractSignal(prop);
|
|
480
453
|
}
|
|
481
454
|
patchNormalProp(key, prop) {
|
|
482
|
-
var _a, _b;
|
|
483
|
-
const newValue = (_b = (_a = this.proxyProps)[key]) != null ? _b : _a[key] = signal.useSignal(prop);
|
|
484
455
|
const track = this.getNodeTrack(key);
|
|
485
456
|
track.cleanup = signal.useEffect(() => {
|
|
486
|
-
|
|
457
|
+
this.proxyProps[key] = shared.isFunction(prop) ? prop() : prop;
|
|
487
458
|
});
|
|
488
459
|
}
|
|
460
|
+
cleanup() {
|
|
461
|
+
this.trackMap.forEach((track) => {
|
|
462
|
+
var _a;
|
|
463
|
+
return (_a = track.cleanup) == null ? void 0 : _a.call(track);
|
|
464
|
+
});
|
|
465
|
+
this.trackMap.clear();
|
|
466
|
+
this.emitter.forEach((cleanup) => cleanup());
|
|
467
|
+
this.emitter.clear();
|
|
468
|
+
}
|
|
489
469
|
};
|
|
490
470
|
|
|
491
471
|
// src/patch.ts
|
|
@@ -601,14 +581,12 @@ var TemplateNode = class {
|
|
|
601
581
|
this.template = template;
|
|
602
582
|
this.props = props;
|
|
603
583
|
this.key = key;
|
|
604
|
-
// Private properties for managing the node's state
|
|
605
584
|
this.treeMap = /* @__PURE__ */ new Map();
|
|
606
585
|
this.mounted = false;
|
|
607
586
|
this.nodes = [];
|
|
608
587
|
this.trackMap = /* @__PURE__ */ new Map();
|
|
609
588
|
this.bindValueKeys = [];
|
|
610
589
|
this.parent = null;
|
|
611
|
-
this.key || (this.key = props && props.key);
|
|
612
590
|
if (renderContext.isSSR) {
|
|
613
591
|
this.componentIndex = getComponentIndex(this.template);
|
|
614
592
|
}
|
|
@@ -654,39 +632,16 @@ var TemplateNode = class {
|
|
|
654
632
|
return this.nodes;
|
|
655
633
|
}
|
|
656
634
|
unmount() {
|
|
657
|
-
var _a, _b;
|
|
658
635
|
this.trackMap.forEach((track) => {
|
|
659
636
|
track.cleanup && track.cleanup();
|
|
660
637
|
});
|
|
661
638
|
this.trackMap.clear();
|
|
662
639
|
this.treeMap.clear();
|
|
663
640
|
this.nodes.forEach((node) => removeChild(node));
|
|
664
|
-
if (!this.template.innerHTML && !this.nodes.length) {
|
|
665
|
-
const children = (_b = (_a = this.props) == null ? void 0 : _a[FRAGMENT_PROP_KEY]) == null ? void 0 : _b.children;
|
|
666
|
-
if (children) {
|
|
667
|
-
if (shared.isArray(children)) {
|
|
668
|
-
children.forEach((child) => {
|
|
669
|
-
this.deleteFragmentTextNode(child);
|
|
670
|
-
});
|
|
671
|
-
} else {
|
|
672
|
-
this.deleteFragmentTextNode(children);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
641
|
this.nodes = [];
|
|
677
642
|
this.mounted = false;
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
if (shared.isPrimitive(child)) {
|
|
681
|
-
if (this.parent && this.parent.childNodes.length) {
|
|
682
|
-
this.parent.childNodes.forEach((node) => {
|
|
683
|
-
if (node.nodeType === Node.TEXT_NODE && node.textContent === `${child}`) {
|
|
684
|
-
this.parent.removeChild(node);
|
|
685
|
-
}
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
} else {
|
|
689
|
-
removeChild(child);
|
|
643
|
+
if (this.key) {
|
|
644
|
+
componentCache.delete(this.key);
|
|
690
645
|
}
|
|
691
646
|
}
|
|
692
647
|
inheritNode(node) {
|
|
@@ -702,7 +657,7 @@ var TemplateNode = class {
|
|
|
702
657
|
this.treeMap.set(0, parent);
|
|
703
658
|
this.walkNodeTree(parent, this.handleSSGNode.bind(this));
|
|
704
659
|
}
|
|
705
|
-
//
|
|
660
|
+
// protected method to map node tree
|
|
706
661
|
mapNodeTree(parent, tree) {
|
|
707
662
|
let index = 1;
|
|
708
663
|
this.treeMap.set(0, parent);
|
|
@@ -795,14 +750,9 @@ var TemplateNode = class {
|
|
|
795
750
|
}
|
|
796
751
|
patchAttribute(key, element, attr, value, updateFn) {
|
|
797
752
|
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
798
|
-
const
|
|
799
|
-
const triggerValue = signal.isSignal(val) ? val : signal.shallowSignal(val);
|
|
800
|
-
setAttribute(element, attr, triggerValue.value);
|
|
753
|
+
const triggerValue = signal.shallowSignal();
|
|
801
754
|
const cleanup = signal.useEffect(() => {
|
|
802
|
-
|
|
803
|
-
if (shared.isPlainObject(val2) && shared.isPlainObject(triggerValue.peek()) && JSON.stringify(triggerValue.value) === JSON.stringify(val2))
|
|
804
|
-
return;
|
|
805
|
-
triggerValue.value = signal.isSignal(val2) ? val2.value : val2;
|
|
755
|
+
triggerValue.value = signal.isSignal(value) || signal.isComputed(value) ? value.value : value;
|
|
806
756
|
setAttribute(element, attr, triggerValue.value);
|
|
807
757
|
});
|
|
808
758
|
let cleanupBind;
|
|
@@ -881,17 +831,36 @@ var TemplateNode = class {
|
|
|
881
831
|
};
|
|
882
832
|
|
|
883
833
|
// src/jsxRenderer.ts
|
|
884
|
-
|
|
834
|
+
var componentCache = /* @__PURE__ */ new Map();
|
|
835
|
+
function createNodeCache(NodeConstructor, template, props = {}, key) {
|
|
836
|
+
if (key) {
|
|
837
|
+
const cached = componentCache.get(key);
|
|
838
|
+
if (cached) {
|
|
839
|
+
return cached;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
if (typeof template === "string") {
|
|
843
|
+
template = createTemplate(template);
|
|
844
|
+
}
|
|
845
|
+
const newNode = new NodeConstructor(template, props, key);
|
|
846
|
+
if (key && newNode instanceof ComponentNode) {
|
|
847
|
+
componentCache.set(key, newNode);
|
|
848
|
+
}
|
|
849
|
+
return newNode;
|
|
850
|
+
}
|
|
851
|
+
function h(template, props = {}, key) {
|
|
852
|
+
if (template === EMPTY_TEMPLATE) {
|
|
853
|
+
return Fragment(template, props);
|
|
854
|
+
}
|
|
885
855
|
if (shared.isString(template)) {
|
|
886
|
-
const
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
return new TemplateNode(createTemplate(htmlTemplate), props, key);
|
|
856
|
+
const htmlTemplate = convertToHtmlTag(template);
|
|
857
|
+
const wrappedProps = { [SINGLE_PROP_KEY]: props };
|
|
858
|
+
return createNodeCache(TemplateNode, htmlTemplate, wrappedProps, key);
|
|
890
859
|
}
|
|
891
860
|
if (shared.isFunction(template)) {
|
|
892
|
-
return
|
|
861
|
+
return createNodeCache(ComponentNode, template, props, key);
|
|
893
862
|
}
|
|
894
|
-
return
|
|
863
|
+
return createNodeCache(TemplateNode, template, props, key);
|
|
895
864
|
}
|
|
896
865
|
function isComponent(node) {
|
|
897
866
|
return node instanceof ComponentNode;
|
|
@@ -901,15 +870,17 @@ function isJsxElement(node) {
|
|
|
901
870
|
}
|
|
902
871
|
function createTemplate(html) {
|
|
903
872
|
const template = document.createElement("template");
|
|
904
|
-
template.innerHTML =
|
|
873
|
+
template.innerHTML = html;
|
|
905
874
|
return template;
|
|
906
875
|
}
|
|
907
|
-
function Fragment(props) {
|
|
908
|
-
|
|
876
|
+
function Fragment(template, props) {
|
|
877
|
+
const processedProps = props.children ? {
|
|
909
878
|
[FRAGMENT_PROP_KEY]: {
|
|
910
|
-
children:
|
|
879
|
+
children: Array.isArray(props.children) ? props.children.filter(Boolean) : [props.children]
|
|
911
880
|
}
|
|
912
|
-
}
|
|
881
|
+
} : props;
|
|
882
|
+
const templateElement = template === EMPTY_TEMPLATE ? createTemplate(EMPTY_TEMPLATE) : template;
|
|
883
|
+
return createNodeCache(TemplateNode, templateElement, processedProps);
|
|
913
884
|
}
|
|
914
885
|
function onMount(cb) {
|
|
915
886
|
assertInsideComponent("onMounted");
|
|
@@ -927,18 +898,15 @@ function assertInsideComponent(hookName, key) {
|
|
|
927
898
|
);
|
|
928
899
|
}
|
|
929
900
|
}
|
|
930
|
-
function
|
|
931
|
-
assertInsideComponent("
|
|
901
|
+
function provide(key, value) {
|
|
902
|
+
assertInsideComponent("provide", key);
|
|
932
903
|
LifecycleContext.ref && LifecycleContext.ref.setContext(key, value);
|
|
933
904
|
}
|
|
934
|
-
function
|
|
905
|
+
function inject(key, defaultValue) {
|
|
935
906
|
var _a;
|
|
936
|
-
assertInsideComponent("
|
|
907
|
+
assertInsideComponent("inject", key);
|
|
937
908
|
return (_a = LifecycleContext.ref && LifecycleContext.ref.getContext(key)) != null ? _a : defaultValue;
|
|
938
909
|
}
|
|
939
|
-
function useRef() {
|
|
940
|
-
return signal.shallowSignal(null);
|
|
941
|
-
}
|
|
942
910
|
|
|
943
911
|
// src/server.ts
|
|
944
912
|
function renderToString(component, props) {
|
|
@@ -967,13 +935,12 @@ function ssg(component, props) {
|
|
|
967
935
|
exports.Fragment = Fragment;
|
|
968
936
|
exports.h = h;
|
|
969
937
|
exports.hydrate = hydrate;
|
|
938
|
+
exports.inject = inject;
|
|
970
939
|
exports.isComponent = isComponent;
|
|
971
940
|
exports.isJsxElement = isJsxElement;
|
|
972
941
|
exports.onDestroy = onDestroy;
|
|
973
942
|
exports.onMount = onMount;
|
|
943
|
+
exports.provide = provide;
|
|
974
944
|
exports.renderToString = renderToString;
|
|
975
945
|
exports.ssg = ssg;
|
|
976
946
|
exports.template = createTemplate;
|
|
977
|
-
exports.useInject = useInject;
|
|
978
|
-
exports.useProvide = useProvide;
|
|
979
|
-
exports.useRef = useRef;
|