@alloy-js/core 0.5.0 → 0.7.0
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/CHANGELOG.md +55 -0
- package/babel.config.cjs +4 -1
- package/dist/src/binder.d.ts +8 -2
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +41 -15
- package/dist/src/binder.js.map +1 -1
- package/dist/src/code.d.ts +2 -2
- package/dist/src/code.d.ts.map +1 -1
- package/dist/src/code.js +4 -4
- package/dist/src/code.js.map +1 -1
- package/dist/src/components/Block.d.ts +25 -0
- package/dist/src/components/Block.d.ts.map +1 -0
- package/dist/src/components/Block.js +25 -0
- package/dist/src/components/Block.js.map +1 -0
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +4 -0
- package/dist/src/components/Declaration.js.map +1 -1
- package/dist/src/components/For.d.ts +44 -0
- package/dist/src/components/For.d.ts.map +1 -0
- package/dist/src/components/For.js +41 -0
- package/dist/src/components/For.js.map +1 -0
- package/dist/src/components/Indent.d.ts +5 -9
- package/dist/src/components/Indent.d.ts.map +1 -1
- package/dist/src/components/Indent.js +7 -18
- package/dist/src/components/Indent.js.map +1 -1
- package/dist/src/components/List.d.ts +38 -0
- package/dist/src/components/List.d.ts.map +1 -0
- package/dist/src/components/List.js +40 -0
- package/dist/src/components/List.js.map +1 -0
- package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
- package/dist/src/components/MemberDeclaration.js.map +1 -1
- package/dist/src/components/MemberName.js +1 -1
- package/dist/src/components/MemberName.js.map +1 -1
- package/dist/src/components/MemberScope.d.ts.map +1 -1
- package/dist/src/components/MemberScope.js.map +1 -1
- package/dist/src/components/Name.js +1 -1
- package/dist/src/components/Name.js.map +1 -1
- package/dist/src/components/Output.d.ts +2 -1
- package/dist/src/components/Output.d.ts.map +1 -1
- package/dist/src/components/Output.js +9 -1
- package/dist/src/components/Output.js.map +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js.map +1 -1
- package/dist/src/components/Show.d.ts +8 -0
- package/dist/src/components/Show.d.ts.map +1 -0
- package/dist/src/components/Show.js +4 -0
- package/dist/src/components/Show.js.map +1 -0
- package/dist/src/components/SourceDirectory.d.ts.map +1 -1
- package/dist/src/components/SourceDirectory.js +1 -0
- package/dist/src/components/SourceDirectory.js.map +1 -1
- package/dist/src/components/SourceFile.d.ts +2 -6
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +6 -13
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/components/StatementList.d.ts +9 -0
- package/dist/src/components/StatementList.d.ts.map +1 -0
- package/dist/src/components/StatementList.js +17 -0
- package/dist/src/components/StatementList.js.map +1 -0
- package/dist/src/components/Switch.d.ts +41 -0
- package/dist/src/components/Switch.d.ts.map +1 -0
- package/dist/src/components/Switch.js +41 -0
- package/dist/src/components/Switch.js.map +1 -0
- package/dist/src/components/Wrap.d.ts +20 -0
- package/dist/src/components/Wrap.d.ts.map +1 -0
- package/dist/src/components/Wrap.js +15 -0
- package/dist/src/components/Wrap.js.map +1 -0
- package/dist/src/components/index.d.ts +8 -1
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +7 -0
- package/dist/src/components/index.js.map +1 -1
- package/dist/src/components/stc/index.d.ts +77 -6
- package/dist/src/components/stc/index.d.ts.map +1 -1
- package/dist/src/components/stc/index.js +17 -1
- package/dist/src/components/stc/index.js.map +1 -1
- package/dist/src/context/index.d.ts +0 -1
- package/dist/src/context/index.d.ts.map +1 -1
- package/dist/src/context/index.js +0 -1
- package/dist/src/context/index.js.map +1 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +3 -3
- package/dist/src/context.js.map +1 -1
- package/dist/src/index.browser.d.ts +3 -0
- package/dist/src/index.browser.d.ts.map +1 -0
- package/dist/src/index.browser.js +3 -0
- package/dist/src/index.browser.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/jsx-runtime.d.ts +139 -8
- package/dist/src/jsx-runtime.d.ts.map +1 -1
- package/dist/src/jsx-runtime.js +102 -12
- package/dist/src/jsx-runtime.js.map +1 -1
- package/dist/src/render.d.ts +107 -132
- package/dist/src/render.d.ts.map +1 -1
- package/dist/src/render.js +281 -177
- package/dist/src/render.js.map +1 -1
- package/dist/src/stc.d.ts +14 -0
- package/dist/src/stc.d.ts.map +1 -0
- package/dist/src/stc.js +52 -0
- package/dist/src/stc.js.map +1 -0
- package/dist/src/utils.d.ts +22 -15
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +95 -59
- package/dist/src/utils.js.map +1 -1
- package/dist/src/write-output.js +3 -3
- package/dist/src/write-output.js.map +1 -1
- package/dist/test/browser-build.test.d.ts +2 -0
- package/dist/test/browser-build.test.d.ts.map +1 -0
- package/dist/test/components/block.test.d.ts +2 -0
- package/dist/test/components/block.test.d.ts.map +1 -0
- package/dist/test/components/declaration.test.d.ts +2 -0
- package/dist/test/components/declaration.test.d.ts.map +1 -0
- package/dist/test/components/list.test.d.ts +2 -0
- package/dist/test/components/list.test.d.ts.map +1 -0
- package/dist/test/components/wrap.test.d.ts +2 -0
- package/dist/test/components/wrap.test.d.ts.map +1 -0
- package/dist/test/control-flow/for.test.d.ts +2 -0
- package/dist/test/control-flow/for.test.d.ts.map +1 -0
- package/dist/test/control-flow/match.test.d.ts +2 -0
- package/dist/test/control-flow/match.test.d.ts.map +1 -0
- package/dist/test/control-flow/show.test.d.ts +2 -0
- package/dist/test/control-flow/show.test.d.ts.map +1 -0
- package/dist/test/reactivity/cleanup.test.d.ts +2 -0
- package/dist/test/reactivity/cleanup.test.d.ts.map +1 -0
- package/dist/test/reactivity/memo.test.d.ts +2 -0
- package/dist/test/reactivity/memo.test.d.ts.map +1 -0
- package/dist/test/reactivity/untrack.test.d.ts +2 -0
- package/dist/test/reactivity/untrack.test.d.ts.map +1 -0
- package/dist/test/rendering/formatting.test.d.ts +2 -0
- package/dist/test/rendering/formatting.test.d.ts.map +1 -0
- package/dist/test/rendering/memoization.test.d.ts +2 -0
- package/dist/test/rendering/memoization.test.d.ts.map +1 -0
- package/dist/test/split-props.test.d.ts +2 -0
- package/dist/test/split-props.test.d.ts.map +1 -0
- package/dist/test/stc.test.d.ts.map +1 -1
- package/dist/test/utils.test.d.ts.map +1 -1
- package/dist/testing/extend-expect.js +4 -4
- package/dist/testing/extend-expect.js.map +1 -1
- package/dist/testing/render.d.ts +2 -3
- package/dist/testing/render.d.ts.map +1 -1
- package/dist/testing/render.js +2 -4
- package/dist/testing/render.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -8
- package/src/binder.ts +54 -18
- package/src/code.ts +17 -12
- package/src/components/Block.tsx +44 -0
- package/src/components/Declaration.tsx +10 -4
- package/src/components/For.tsx +81 -0
- package/src/components/Indent.tsx +20 -27
- package/src/components/List.tsx +94 -0
- package/src/components/MemberDeclaration.tsx +9 -6
- package/src/components/MemberScope.tsx +4 -2
- package/src/components/Output.tsx +25 -13
- package/src/components/Scope.tsx +4 -2
- package/src/components/Show.tsx +11 -0
- package/src/components/SourceDirectory.tsx +5 -1
- package/src/components/SourceFile.tsx +12 -16
- package/src/components/StatementList.tsx +16 -0
- package/src/components/Switch.tsx +62 -0
- package/src/components/Wrap.tsx +29 -0
- package/src/components/index.tsx +8 -1
- package/src/components/stc/index.ts +18 -1
- package/src/context/index.ts +0 -1
- package/src/context.ts +2 -3
- package/src/index.browser.ts +2 -0
- package/src/index.ts +1 -0
- package/src/jsx-runtime.ts +245 -23
- package/src/render.ts +392 -198
- package/src/stc.ts +95 -0
- package/src/utils.ts +162 -95
- package/src/write-output.ts +3 -3
- package/temp/api.json +8407 -3301
- package/test/browser-build.test.ts +91 -0
- package/test/children.test.tsx +8 -10
- package/test/components/block.test.tsx +48 -0
- package/test/components/declaration.test.tsx +37 -0
- package/test/components/list.test.tsx +91 -0
- package/test/components/slot.test.tsx +31 -25
- package/test/components/source-file.test.tsx +11 -31
- package/test/components/wrap.test.tsx +42 -0
- package/test/control-flow/for.test.tsx +194 -0
- package/test/control-flow/match.test.tsx +49 -0
- package/test/control-flow/show.test.tsx +25 -0
- package/test/name-policy.test.tsx +5 -5
- package/test/reactivity/cleanup.test.tsx +91 -0
- package/test/reactivity/memo.test.tsx +17 -0
- package/test/reactivity/ref-rendering.test.tsx +3 -8
- package/test/reactivity/test.test.tsx +7 -6
- package/test/reactivity/untrack.test.ts +33 -0
- package/test/rendering/basic.test.tsx +25 -47
- package/test/rendering/code.test.tsx +3 -3
- package/test/rendering/formatting.test.tsx +487 -0
- package/test/rendering/indent.test.tsx +42 -529
- package/test/rendering/memoization.test.tsx +30 -0
- package/test/split-props.test.ts +87 -0
- package/test/stc.test.tsx +29 -8
- package/test/symbols.test.ts +87 -8
- package/test/utils.test.tsx +129 -20
- package/testing/extend-expect.ts +14 -4
- package/testing/render.ts +2 -4
- package/testing/vitest.d.ts +6 -1
- package/vitest.config.ts +1 -1
- package/dist/src/context/indent.d.ts +0 -5
- package/dist/src/context/indent.d.ts.map +0 -1
- package/dist/src/context/indent.js +0 -8
- package/dist/src/context/indent.js.map +0 -1
- package/dist/test/rendering/linebreaks.test.d.ts +0 -2
- package/dist/test/rendering/linebreaks.test.d.ts.map +0 -1
- package/src/context/indent.ts +0 -17
- package/test/rendering/linebreaks.test.tsx +0 -72
package/src/stc.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
ComponentCreator,
|
|
4
|
+
ComponentDefinition,
|
|
5
|
+
createIntrinsic,
|
|
6
|
+
IntrinsicElementBase,
|
|
7
|
+
JSX,
|
|
8
|
+
} from "@alloy-js/core/jsx-runtime";
|
|
9
|
+
import { code } from "./code.js";
|
|
10
|
+
|
|
11
|
+
export function sti<T extends keyof JSX.IntrinsicElements>(name: T) {
|
|
12
|
+
return (
|
|
13
|
+
...args: unknown extends T ? []
|
|
14
|
+
: {} extends Omit<JSX.IntrinsicElements[T], "children"> ?
|
|
15
|
+
[props?: JSX.IntrinsicElements[T]]
|
|
16
|
+
: [props: JSX.IntrinsicElements[T]]
|
|
17
|
+
) => {
|
|
18
|
+
const props: JSX.IntrinsicElements[T] | undefined = args[0];
|
|
19
|
+
const fn = () => createIntrinsic(name, props!);
|
|
20
|
+
fn.children = (
|
|
21
|
+
...children: Children[]
|
|
22
|
+
): (() => IntrinsicElementBase<T>) => {
|
|
23
|
+
const propsWithChildren = {
|
|
24
|
+
...(props ?? {}),
|
|
25
|
+
children,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return () => createIntrinsic(name, propsWithChildren as any);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
fn.code = (
|
|
32
|
+
template: TemplateStringsArray,
|
|
33
|
+
...substitutions: Children[]
|
|
34
|
+
): (() => IntrinsicElementBase<T>) => {
|
|
35
|
+
const propsWithChildren = {
|
|
36
|
+
...(args[0] ?? {}),
|
|
37
|
+
children: code(template, ...substitutions),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return () => createIntrinsic(name, propsWithChildren as any);
|
|
41
|
+
};
|
|
42
|
+
return fn;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type MakeChildrenOptional<T extends object> =
|
|
47
|
+
T extends { children?: any } ?
|
|
48
|
+
Omit<T, "children"> & Partial<Pick<T, "children">>
|
|
49
|
+
: T;
|
|
50
|
+
|
|
51
|
+
export function stc<T extends {}>(Component: ComponentDefinition<T>) {
|
|
52
|
+
return (
|
|
53
|
+
...args: unknown extends T ? []
|
|
54
|
+
: {} extends Omit<T, "children"> ? [props?: MakeChildrenOptional<T>]
|
|
55
|
+
: [props: MakeChildrenOptional<T>]
|
|
56
|
+
) => {
|
|
57
|
+
const fn: ComponentCreator<T> & {
|
|
58
|
+
code(
|
|
59
|
+
template: TemplateStringsArray,
|
|
60
|
+
...substitutions: Children[]
|
|
61
|
+
): ComponentCreator<T>;
|
|
62
|
+
children(...children: Children[]): ComponentCreator<T>;
|
|
63
|
+
} = () => Component(args[0] as any);
|
|
64
|
+
fn.component = Component;
|
|
65
|
+
fn.props = args[0]!;
|
|
66
|
+
fn.code = (
|
|
67
|
+
template: TemplateStringsArray,
|
|
68
|
+
...substitutions: Children[]
|
|
69
|
+
): ComponentCreator<T> => {
|
|
70
|
+
const propsWithChildren = {
|
|
71
|
+
...(args[0] ?? {}),
|
|
72
|
+
children: code(template, ...substitutions),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const fn = () => Component(propsWithChildren as any);
|
|
76
|
+
fn.component = Component;
|
|
77
|
+
fn.props = args[0]!;
|
|
78
|
+
return fn;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
fn.children = (...children: Children[]): ComponentCreator<T> => {
|
|
82
|
+
const propsWithChildren = {
|
|
83
|
+
...(args[0] ?? {}),
|
|
84
|
+
children,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const fn = () => Component(propsWithChildren as any);
|
|
88
|
+
fn.component = Component;
|
|
89
|
+
fn.props = args[0]!;
|
|
90
|
+
return fn;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return fn;
|
|
94
|
+
};
|
|
95
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toRaw } from "@vue/reactivity";
|
|
2
2
|
import {
|
|
3
|
-
Child,
|
|
4
3
|
Children,
|
|
5
4
|
ComponentCreator,
|
|
6
|
-
|
|
5
|
+
createCustomContext,
|
|
6
|
+
CustomContext,
|
|
7
|
+
Disposable,
|
|
7
8
|
isComponentCreator,
|
|
8
9
|
memo,
|
|
10
|
+
onCleanup,
|
|
11
|
+
root,
|
|
12
|
+
untrack,
|
|
9
13
|
} from "./jsx-runtime.js";
|
|
10
14
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
15
|
import { OutputDirectory, OutputFile, render } from "./render.js";
|
|
@@ -14,14 +18,19 @@ export interface JoinOptions {
|
|
|
14
18
|
/**
|
|
15
19
|
* The string to place between each element.
|
|
16
20
|
*/
|
|
17
|
-
joiner?:
|
|
21
|
+
joiner?: Children;
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* When true, the joiner is placed at the end of the array. When a string,
|
|
21
25
|
* that string is placed at the end of the array. The ender is only emitted
|
|
22
26
|
* when the array has at least one element.
|
|
23
27
|
*/
|
|
24
|
-
ender?:
|
|
28
|
+
ender?: Children;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* When true, falsy values with the exception of 0 are skipped.
|
|
32
|
+
*/
|
|
33
|
+
skipFalsy?: boolean;
|
|
25
34
|
}
|
|
26
35
|
const defaultJoinOptions: JoinOptions = {
|
|
27
36
|
joiner: "\n",
|
|
@@ -40,10 +49,10 @@ const defaultJoinOptions: JoinOptions = {
|
|
|
40
49
|
*
|
|
41
50
|
*/
|
|
42
51
|
export function mapJoin<T, U, V>(
|
|
43
|
-
src: Map<T, U>,
|
|
44
|
-
cb: (key: T, value: U) => V,
|
|
52
|
+
src: () => Map<T, U>,
|
|
53
|
+
cb: (key: T, value: U, index: number) => V,
|
|
45
54
|
options?: JoinOptions,
|
|
46
|
-
): (V | string)[];
|
|
55
|
+
): () => (V | string | undefined | CustomContext)[];
|
|
47
56
|
/**
|
|
48
57
|
* Map a array or iterator to another array using a mapper and place a joiner
|
|
49
58
|
* between each element. Defaults to joining with a newline.
|
|
@@ -55,47 +64,122 @@ export function mapJoin<T, U, V>(
|
|
|
55
64
|
* @returns The mapped and joined array.
|
|
56
65
|
*/
|
|
57
66
|
export function mapJoin<T, V>(
|
|
58
|
-
src: T[] | IterableIterator<T>,
|
|
59
|
-
cb: (value: T) => V,
|
|
67
|
+
src: () => T[] | IterableIterator<T>,
|
|
68
|
+
cb: (value: T, index: number) => V,
|
|
60
69
|
options?: JoinOptions,
|
|
61
|
-
): (V | string)[];
|
|
70
|
+
): () => (V | string | undefined | CustomContext)[];
|
|
62
71
|
export function mapJoin<T, U, V>(
|
|
63
|
-
src: Map<T, U> | T[] | Iterable<T>,
|
|
64
|
-
cb: (key: T,
|
|
72
|
+
src: () => Map<T, U> | T[] | Iterable<T>,
|
|
73
|
+
cb: (key: T, valueOrIndex: U | number, index: number) => V,
|
|
65
74
|
rawOptions: JoinOptions = {},
|
|
66
|
-
): (
|
|
75
|
+
): () => Children {
|
|
67
76
|
const options = { ...defaultJoinOptions, ...rawOptions };
|
|
68
|
-
const ender =
|
|
77
|
+
const ender =
|
|
78
|
+
options.ender === true ? options.joiner : options.ender || undefined;
|
|
79
|
+
const currentItems: (T | [T, U])[] = [];
|
|
80
|
+
const disposables: Disposable[] = [];
|
|
81
|
+
const mapped: Children[] = [];
|
|
82
|
+
let previousItemsLen = 0;
|
|
69
83
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
84
|
+
onCleanup(() => {
|
|
85
|
+
for (const d of disposables) d();
|
|
86
|
+
});
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
return () => {
|
|
89
|
+
const itemsSource = src();
|
|
90
|
+
// need to unpack reactives for branding checks
|
|
91
|
+
const itemsSourceRaw = toRaw(itemsSource);
|
|
92
|
+
let items =
|
|
93
|
+
Array.isArray(itemsSourceRaw) ? (itemsSource as T[]) : [...itemsSource];
|
|
94
|
+
if (options.skipFalsy) {
|
|
95
|
+
items = items.filter(
|
|
96
|
+
(item) =>
|
|
97
|
+
item !== null && item !== undefined && typeof item !== "boolean",
|
|
98
|
+
);
|
|
81
99
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
100
|
+
// this is important to access here in reactive context so we are
|
|
101
|
+
// notified of new items from reactives.
|
|
102
|
+
const itemsLen = items.length;
|
|
103
|
+
const compare: any = getCompareFunction(itemsSource);
|
|
104
|
+
const mapper: any = getMapperFunction(itemsSource);
|
|
105
|
+
|
|
106
|
+
return untrack(() => {
|
|
107
|
+
let startIndex = 0;
|
|
108
|
+
for (
|
|
109
|
+
;
|
|
110
|
+
startIndex < itemsLen && startIndex < currentItems.length;
|
|
111
|
+
startIndex++
|
|
112
|
+
) {
|
|
113
|
+
if (!compare(items[startIndex], currentItems[startIndex])) {
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
91
116
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
117
|
+
|
|
118
|
+
if (startIndex > 0 && startIndex < itemsLen) {
|
|
119
|
+
// need to update the previous joiner (might be ender or absent)
|
|
120
|
+
mapped[startIndex * 2 - 1] = options.joiner;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (; startIndex < itemsLen; startIndex++) {
|
|
124
|
+
currentItems[startIndex] = items[startIndex];
|
|
125
|
+
if (disposables[startIndex]) {
|
|
126
|
+
disposables[startIndex]();
|
|
127
|
+
}
|
|
128
|
+
const cleanupIndex = startIndex;
|
|
129
|
+
mapped[startIndex * 2] = createCustomContext((cb) => {
|
|
130
|
+
return root((disposer) => {
|
|
131
|
+
disposables[cleanupIndex] = disposer;
|
|
132
|
+
disposer();
|
|
133
|
+
cb(mapper(items[cleanupIndex], cleanupIndex));
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
mapped[startIndex * 2 + 1] =
|
|
138
|
+
startIndex < items.length - 1 ? options.joiner : ender;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
mapped.length = startIndex * 2;
|
|
142
|
+
mapped[mapped.length - 1] = ender;
|
|
143
|
+
for (; startIndex < previousItemsLen; startIndex++) {
|
|
144
|
+
disposables[startIndex]?.();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
previousItemsLen = itemsLen;
|
|
148
|
+
|
|
149
|
+
return mapped;
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
function getCompareFunction(itemsSource: Map<T, U> | T[] | Iterable<T>) {
|
|
154
|
+
return Array.isArray(itemsSource) || isIterable(itemsSource) ?
|
|
155
|
+
compareArray
|
|
156
|
+
: compareMap;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function getMapperFunction(itemsSource: Map<T, U> | T[] | Iterable<T>) {
|
|
160
|
+
return Array.isArray(itemsSource) || isIterable(itemsSource) ?
|
|
161
|
+
mapArray
|
|
162
|
+
: mapMap;
|
|
163
|
+
}
|
|
164
|
+
function compareArray(elem1: T, elem2: T) {
|
|
165
|
+
return elem1 === elem2;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function compareMap(record1: [T, U], record2: [T, U]) {
|
|
169
|
+
return record1[0] === record2[0] && record1[1] === record2[1];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function mapArray(item: T, index: number) {
|
|
173
|
+
return (cb as any)(item, index);
|
|
96
174
|
}
|
|
97
175
|
|
|
98
|
-
|
|
176
|
+
function mapMap(item: [T, U], index: number) {
|
|
177
|
+
return cb(item[0], item[1], index);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function isIterable<T>(x: unknown): x is Iterable<T> {
|
|
181
|
+
return typeof (x as any).next === "function";
|
|
182
|
+
}
|
|
99
183
|
}
|
|
100
184
|
|
|
101
185
|
/**
|
|
@@ -105,12 +189,12 @@ export function mapJoin<T, U, V>(
|
|
|
105
189
|
* @see mapJoin for mapping before joining.
|
|
106
190
|
* @returns The joined array
|
|
107
191
|
*/
|
|
108
|
-
export function join<T>(
|
|
192
|
+
export function join<T extends Children>(
|
|
109
193
|
src: T[] | Iterator<T>,
|
|
110
194
|
options: JoinOptions = {},
|
|
111
|
-
):
|
|
195
|
+
): Children {
|
|
112
196
|
const mergedOptions = { ...defaultJoinOptions, ...options };
|
|
113
|
-
const joined = [];
|
|
197
|
+
const joined: Children[] = [];
|
|
114
198
|
const ender =
|
|
115
199
|
mergedOptions.ender === true ? mergedOptions.joiner : mergedOptions.ender;
|
|
116
200
|
src = Array.from(src as Iterable<T>);
|
|
@@ -129,12 +213,28 @@ export function join<T>(
|
|
|
129
213
|
return joined;
|
|
130
214
|
}
|
|
131
215
|
|
|
216
|
+
export interface ChildrenOptions {
|
|
217
|
+
/**
|
|
218
|
+
* When true, fragments and arrays are not flattened.
|
|
219
|
+
*/
|
|
220
|
+
preserveFragments?: boolean;
|
|
221
|
+
}
|
|
132
222
|
/**
|
|
133
223
|
* Returns a memo which is a list of all the provided children.
|
|
134
224
|
* If you want this as an array, see {@link childrenArray}.
|
|
135
225
|
*/
|
|
136
|
-
export function children(
|
|
137
|
-
|
|
226
|
+
export function children(
|
|
227
|
+
fn: () => Children,
|
|
228
|
+
options: ChildrenOptions = {},
|
|
229
|
+
): () => Children {
|
|
230
|
+
return memo(() => {
|
|
231
|
+
const children = fn();
|
|
232
|
+
if (options.preserveFragments && Array.isArray(children)) {
|
|
233
|
+
return children.map(collectChildren);
|
|
234
|
+
} else {
|
|
235
|
+
return collectChildren(children);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
138
238
|
|
|
139
239
|
function collectChildren(children: Children): Children {
|
|
140
240
|
if (Array.isArray(children)) {
|
|
@@ -150,8 +250,11 @@ export function children(fn: () => Children): () => Children {
|
|
|
150
250
|
}
|
|
151
251
|
}
|
|
152
252
|
|
|
153
|
-
export function childrenArray(
|
|
154
|
-
|
|
253
|
+
export function childrenArray(
|
|
254
|
+
fn: () => Children,
|
|
255
|
+
options?: ChildrenOptions,
|
|
256
|
+
): Children[] {
|
|
257
|
+
const c = children(fn, options)();
|
|
155
258
|
if (Array.isArray(c)) {
|
|
156
259
|
return c;
|
|
157
260
|
} else if (c === undefined) {
|
|
@@ -161,7 +264,7 @@ export function childrenArray(fn: () => Children): Child[] {
|
|
|
161
264
|
}
|
|
162
265
|
}
|
|
163
266
|
|
|
164
|
-
export function findKeyedChild(children:
|
|
267
|
+
export function findKeyedChild(children: Children[], tag: symbol) {
|
|
165
268
|
for (const child of children) {
|
|
166
269
|
if (isKeyedChild(child) && child.tag === tag) {
|
|
167
270
|
return child;
|
|
@@ -171,58 +274,22 @@ export function findKeyedChild(children: Child[], tag: symbol) {
|
|
|
171
274
|
return null;
|
|
172
275
|
}
|
|
173
276
|
|
|
174
|
-
export function
|
|
175
|
-
|
|
277
|
+
export function findKeyedChildren(children: Children[], tag: symbol) {
|
|
278
|
+
const keyedChildren: ComponentCreator[] = [];
|
|
279
|
+
for (const child of children) {
|
|
280
|
+
if (isKeyedChild(child) && child.tag === tag) {
|
|
281
|
+
keyedChildren.push(child);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return keyedChildren;
|
|
176
285
|
}
|
|
177
286
|
|
|
178
|
-
export function
|
|
179
|
-
return
|
|
287
|
+
export function findUnkeyedChildren(children: Children[]) {
|
|
288
|
+
return children.filter((child) => !isKeyedChild(child));
|
|
180
289
|
}
|
|
181
290
|
|
|
182
|
-
export function
|
|
183
|
-
return (
|
|
184
|
-
...args: unknown extends T ? []
|
|
185
|
-
: {} extends Omit<T, "children"> ? [props?: T]
|
|
186
|
-
: [props: T]
|
|
187
|
-
) => {
|
|
188
|
-
const fn: ComponentCreator<T> & {
|
|
189
|
-
code(
|
|
190
|
-
template: TemplateStringsArray,
|
|
191
|
-
...substitutions: Children[]
|
|
192
|
-
): ComponentCreator<T>;
|
|
193
|
-
children(...children: Children[]): ComponentCreator<T>;
|
|
194
|
-
} = () => Component(args[0]!);
|
|
195
|
-
fn.component = Component;
|
|
196
|
-
fn.props = args[0]!;
|
|
197
|
-
fn.code = (
|
|
198
|
-
template: TemplateStringsArray,
|
|
199
|
-
...substitutions: Children[]
|
|
200
|
-
): ComponentCreator<T> => {
|
|
201
|
-
const propsWithChildren = {
|
|
202
|
-
...(args[0] ?? {}),
|
|
203
|
-
children: code(template, ...substitutions),
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
const fn = () => Component(propsWithChildren as any);
|
|
207
|
-
fn.component = Component;
|
|
208
|
-
fn.props = args[0]!;
|
|
209
|
-
return fn;
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
fn.children = (...children: Children[]): ComponentCreator<T> => {
|
|
213
|
-
const propsWithChildren = {
|
|
214
|
-
...(args[0] ?? {}),
|
|
215
|
-
children,
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
const fn = () => Component(propsWithChildren as any);
|
|
219
|
-
fn.component = Component;
|
|
220
|
-
fn.props = args[0]!;
|
|
221
|
-
return fn;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
return fn;
|
|
225
|
-
};
|
|
291
|
+
export function isKeyedChild(child: Children): child is ComponentCreator {
|
|
292
|
+
return isComponentCreator(child) && !!child.tag;
|
|
226
293
|
}
|
|
227
294
|
|
|
228
295
|
/**
|
package/src/write-output.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { relative, resolve } from "pathe";
|
|
3
3
|
import { OutputDirectory } from "./render.js";
|
|
4
4
|
import { traverseOutput } from "./utils.js";
|
|
@@ -10,7 +10,7 @@ export function writeOutput(output: OutputDirectory, basePath: string = "") {
|
|
|
10
10
|
traverseOutput(output, {
|
|
11
11
|
visitDirectory(directory) {
|
|
12
12
|
const path = resolve(basePath, directory.path);
|
|
13
|
-
if (
|
|
13
|
+
if (existsSync(path)) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
// eslint-disable-next-line no-console
|
|
@@ -19,7 +19,7 @@ export function writeOutput(output: OutputDirectory, basePath: string = "") {
|
|
|
19
19
|
},
|
|
20
20
|
visitFile(file) {
|
|
21
21
|
const path = resolve(basePath, file.path);
|
|
22
|
-
if (
|
|
22
|
+
if (existsSync(path)) {
|
|
23
23
|
// eslint-disable-next-line no-console
|
|
24
24
|
console.log("overwrite", relative(process.cwd(), path));
|
|
25
25
|
} else {
|