@alloy-js/core 0.15.0 → 0.17.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 +23 -0
- package/dist/src/binder.d.ts +18 -235
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +85 -386
- package/dist/src/components/Block.d.ts +1 -1
- package/dist/src/components/Block.d.ts.map +1 -1
- package/dist/src/components/Block.js +3 -1
- package/dist/src/components/Declaration.d.ts +1 -1
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +5 -4
- package/dist/src/components/For.d.ts +1 -1
- package/dist/src/components/For.d.ts.map +1 -1
- package/dist/src/components/For.js +1 -1
- package/dist/src/components/Indent.d.ts +1 -1
- package/dist/src/components/Indent.d.ts.map +1 -1
- package/dist/src/components/List.d.ts +1 -1
- package/dist/src/components/List.d.ts.map +1 -1
- package/dist/src/components/List.js +2 -1
- package/dist/src/components/MemberDeclaration.d.ts +1 -1
- package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
- package/dist/src/components/MemberDeclaration.js +3 -4
- package/dist/src/components/MemberScope.d.ts +1 -1
- package/dist/src/components/MemberScope.d.ts.map +1 -1
- package/dist/src/components/MemberScope.js +0 -2
- package/dist/src/components/Prose.d.ts +1 -1
- package/dist/src/components/Prose.d.ts.map +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
- package/dist/src/components/Scope.d.ts +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +3 -6
- package/dist/src/components/Show.d.ts +1 -1
- package/dist/src/components/Show.d.ts.map +1 -1
- package/dist/src/components/StatementList.d.ts +1 -1
- package/dist/src/components/StatementList.d.ts.map +1 -1
- package/dist/src/components/StatementList.js +1 -1
- package/dist/src/components/Switch.d.ts +1 -1
- package/dist/src/components/Switch.d.ts.map +1 -1
- package/dist/src/components/Switch.js +1 -1
- package/dist/src/components/Wrap.d.ts +1 -1
- package/dist/src/components/Wrap.d.ts.map +1 -1
- package/dist/src/context/assignment.d.ts +1 -1
- package/dist/src/context/assignment.d.ts.map +1 -1
- package/dist/src/context/binder.d.ts +2 -2
- package/dist/src/context/binder.d.ts.map +1 -1
- package/dist/src/context/declaration.d.ts +1 -1
- package/dist/src/context/declaration.d.ts.map +1 -1
- package/dist/src/context/member-declaration.d.ts +1 -1
- package/dist/src/context/member-declaration.d.ts.map +1 -1
- package/dist/src/context/member-declaration.js +0 -1
- package/dist/src/context/member-scope.d.ts +1 -1
- package/dist/src/context/member-scope.d.ts.map +1 -1
- package/dist/src/context/name-policy.d.ts +1 -1
- package/dist/src/context/name-policy.d.ts.map +1 -1
- package/dist/src/context/scope.d.ts +1 -1
- package/dist/src/context/scope.d.ts.map +1 -1
- package/dist/src/context/source-directory.d.ts +1 -1
- package/dist/src/context/source-directory.d.ts.map +1 -1
- package/dist/src/context/source-file.d.ts +2 -2
- package/dist/src/context/source-file.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/jsx-runtime.d.ts +12 -3
- package/dist/src/jsx-runtime.d.ts.map +1 -1
- package/dist/src/jsx-runtime.js +6 -2
- package/dist/src/reactive-union-set.d.ts +29 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -0
- package/dist/src/reactive-union-set.js +183 -0
- package/dist/src/refkey.d.ts +36 -0
- package/dist/src/refkey.d.ts.map +1 -1
- package/dist/src/refkey.js +40 -0
- package/dist/src/scheduler.d.ts +2 -2
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +27 -6
- package/dist/src/slot.d.ts +1 -1
- package/dist/src/slot.d.ts.map +1 -1
- package/dist/src/stc.d.ts +1 -1
- package/dist/src/stc.d.ts.map +1 -1
- package/dist/src/sti.d.ts +1 -1
- package/dist/src/sti.d.ts.map +1 -1
- package/dist/src/sti.js +1 -1
- package/dist/src/symbols/index.d.ts +6 -0
- package/dist/src/symbols/index.d.ts.map +1 -0
- package/dist/src/symbols/index.js +5 -0
- package/dist/src/symbols/output-scope.d.ts +116 -0
- package/dist/src/symbols/output-scope.d.ts.map +1 -0
- package/dist/src/symbols/output-scope.js +246 -0
- package/dist/src/symbols/output-symbol.d.ts +134 -0
- package/dist/src/symbols/output-symbol.d.ts.map +1 -0
- package/dist/src/symbols/output-symbol.js +379 -0
- package/dist/src/symbols/symbol-flow.d.ts +13 -0
- package/dist/src/symbols/symbol-flow.d.ts.map +1 -0
- package/dist/src/symbols/symbol-flow.js +74 -0
- package/dist/src/symbols/symbol-slot.d.ts +12 -0
- package/dist/src/symbols/symbol-slot.d.ts.map +1 -0
- package/dist/src/symbols/symbol-slot.js +36 -0
- package/dist/src/symbols/symbol-table.d.ts +14 -0
- package/dist/src/symbols/symbol-table.d.ts.map +1 -0
- package/dist/src/symbols/symbol-table.js +42 -0
- package/dist/src/tap.d.ts +2 -1
- package/dist/src/tap.d.ts.map +1 -1
- package/dist/src/tracer.d.ts +181 -0
- package/dist/src/tracer.d.ts.map +1 -0
- package/dist/src/tracer.js +441 -0
- package/dist/src/tsdoc-metadata.json +1 -1
- package/dist/test/components/slot.test.js +5 -7
- package/dist/test/reactive-union-set.test.d.ts +2 -0
- package/dist/test/reactive-union-set.test.d.ts.map +1 -0
- package/dist/test/reactive-union-set.test.js +170 -0
- package/dist/test/symbols/output-scope.test.d.ts +2 -0
- package/dist/test/symbols/output-scope.test.d.ts.map +1 -0
- package/dist/test/symbols/output-scope.test.js +342 -0
- package/dist/test/symbols/output-symbol.test.d.ts +2 -0
- package/dist/test/symbols/output-symbol.test.d.ts.map +1 -0
- package/dist/test/symbols/output-symbol.test.js +446 -0
- package/dist/test/symbols/resolution.test.d.ts +2 -0
- package/dist/test/symbols/resolution.test.d.ts.map +1 -0
- package/dist/test/symbols/resolution.test.js +140 -0
- package/dist/test/symbols/utils.d.ts +24 -0
- package/dist/test/symbols/utils.d.ts.map +1 -0
- package/dist/test/symbols/utils.js +46 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/binder.ts +148 -672
- package/src/components/Block.tsx +4 -1
- package/src/components/Declaration.tsx +6 -6
- package/src/components/For.tsx +1 -1
- package/src/components/Indent.tsx +1 -1
- package/src/components/List.tsx +1 -1
- package/src/components/MemberDeclaration.tsx +4 -4
- package/src/components/MemberScope.tsx +2 -5
- package/src/components/Prose.tsx +1 -1
- package/src/components/ReferenceOrContent.tsx +1 -1
- package/src/components/Scope.tsx +2 -6
- package/src/components/Show.tsx +1 -1
- package/src/components/StatementList.tsx +2 -1
- package/src/components/Switch.tsx +1 -1
- package/src/components/Wrap.tsx +1 -1
- package/src/context/assignment.ts +1 -1
- package/src/context/binder.ts +2 -2
- package/src/context/declaration.ts +1 -1
- package/src/context/member-declaration.ts +1 -1
- package/src/context/member-scope.ts +1 -1
- package/src/context/name-policy.ts +1 -1
- package/src/context/scope.ts +1 -1
- package/src/context/source-directory.ts +1 -1
- package/src/context/source-file.ts +2 -2
- package/src/index.ts +15 -0
- package/src/jsx-runtime.ts +18 -2
- package/src/reactive-union-set.ts +238 -0
- package/src/refkey.ts +40 -0
- package/src/scheduler.ts +31 -6
- package/src/slot.ts +1 -1
- package/src/stc.ts +3 -3
- package/src/sti.ts +5 -5
- package/src/symbols/index.ts +5 -0
- package/src/symbols/output-scope.ts +323 -0
- package/src/symbols/output-symbol.ts +512 -0
- package/src/symbols/symbol-flow.ts +104 -0
- package/src/symbols/symbol-slot.tsx +47 -0
- package/src/symbols/symbol-table.ts +72 -0
- package/src/tap.ts +2 -1
- package/src/tracer.ts +440 -0
- package/temp/api.json +4172 -1582
- package/test/components/slot.test.tsx +8 -11
- package/test/reactive-union-set.test.tsx +191 -0
- package/test/symbols/output-scope.test.ts +302 -0
- package/test/symbols/output-symbol.test.ts +459 -0
- package/test/symbols/resolution.test.ts +172 -0
- package/test/symbols/utils.ts +95 -0
- package/dist/test/symbols.test.d.ts +0 -2
- package/dist/test/symbols.test.d.ts.map +0 -1
- package/dist/test/symbols.test.js +0 -884
- package/test/symbols.test.ts +0 -1006
package/src/components/Block.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { computed } from "@vue/reactivity";
|
|
2
|
+
import { Children } from "../jsx-runtime.js";
|
|
3
|
+
import { childrenArray } from "../utils.jsx";
|
|
4
|
+
import { Indent } from "./Indent.jsx";
|
|
2
5
|
|
|
3
6
|
export interface BlockProps {
|
|
4
7
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { OutputSymbol } from "../binder.js";
|
|
2
1
|
import { useContext } from "../context.js";
|
|
3
2
|
import { BinderContext } from "../context/binder.js";
|
|
4
3
|
import { DeclarationContext } from "../context/declaration.js";
|
|
5
4
|
import { Children, onCleanup } from "../jsx-runtime.js";
|
|
6
5
|
import { Refkey } from "../refkey.js";
|
|
6
|
+
import { OutputSymbol } from "../symbols/output-symbol.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Create a declaration by providing an already created symbol. The symbol is
|
|
@@ -68,18 +68,18 @@ export function Declaration(props: DeclarationProps) {
|
|
|
68
68
|
throw new Error("Need binder context to create declarations");
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
let declaration;
|
|
71
|
+
let declaration: OutputSymbol;
|
|
72
72
|
if ("symbol" in props) {
|
|
73
73
|
declaration = props.symbol;
|
|
74
74
|
} else {
|
|
75
|
-
declaration =
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
declaration = new OutputSymbol(props.name, {
|
|
76
|
+
binder,
|
|
77
|
+
refkeys: [props.refkey ?? []].flat(),
|
|
78
78
|
metadata: props.metadata,
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
onCleanup(() => {
|
|
82
|
-
|
|
82
|
+
declaration.delete();
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
|
package/src/components/For.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Children, memo } from "@alloy-js/core/jsx-runtime";
|
|
2
1
|
import { isRef, Ref } from "@vue/reactivity";
|
|
2
|
+
import { type Children, memo } from "../jsx-runtime.js";
|
|
3
3
|
import { baseListPropsToMapJoinArgs, mapJoin } from "../utils.js";
|
|
4
4
|
import { BaseListProps } from "./List.jsx";
|
|
5
5
|
|
package/src/components/List.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { OutputSymbol, OutputSymbolFlags } from "../binder.js";
|
|
2
1
|
import { useContext } from "../context.js";
|
|
3
2
|
import { BinderContext } from "../context/binder.js";
|
|
4
3
|
import { MemberDeclarationContext } from "../context/member-declaration.js";
|
|
5
4
|
import { Children } from "../jsx-runtime.js";
|
|
6
5
|
import { Refkey } from "../refkey.js";
|
|
6
|
+
import { OutputSymbol, OutputSymbolFlags } from "../symbols/output-symbol.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Create a member declaration by providing a symbol name and optional symbol
|
|
@@ -85,9 +85,9 @@ export function MemberDeclaration(props: MemberDeclarationProps) {
|
|
|
85
85
|
"Must provide a member name, or else provide a member symbol",
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
|
|
89
|
+
declaration = new OutputSymbol(infoProps.name!, {
|
|
90
|
+
refkeys: infoProps.refkey,
|
|
91
91
|
metadata: infoProps.metadata,
|
|
92
92
|
flags:
|
|
93
93
|
infoProps.static ?
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { OutputSymbol } from "../binder.js";
|
|
2
|
-
import { Children } from "../jsx-runtime.js";
|
|
3
|
-
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5
|
-
import { OutputSymbolFlags } from "../binder.js";
|
|
6
1
|
import { MemberScopeContext } from "../context/member-scope.js";
|
|
2
|
+
import { Children } from "../jsx-runtime.js";
|
|
3
|
+
import { OutputSymbol } from "../symbols/output-symbol.js";
|
|
7
4
|
export interface MemberScopeProps {
|
|
8
5
|
/**
|
|
9
6
|
* The name of the member scope.
|
package/src/components/Prose.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Children } from "@alloy-js/core/jsx-runtime";
|
|
2
1
|
import { computed } from "@vue/reactivity";
|
|
3
2
|
import { useContext } from "../context.js";
|
|
4
3
|
import { BinderContext } from "../context/binder.js";
|
|
4
|
+
import type { Children } from "../jsx-runtime.js";
|
|
5
5
|
import type { Refkey } from "../refkey.js";
|
|
6
6
|
|
|
7
7
|
export interface ReferenceOrContentProps {
|
package/src/components/Scope.tsx
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { OutputScope } from "../binder.js";
|
|
2
|
-
import { useContext } from "../context.js";
|
|
3
|
-
import { BinderContext } from "../context/binder.js";
|
|
4
1
|
import { ScopeContext } from "../context/scope.js";
|
|
5
2
|
import { Children } from "../jsx-runtime.js";
|
|
3
|
+
import { OutputScope } from "../symbols/output-scope.js";
|
|
6
4
|
|
|
7
5
|
/**
|
|
8
6
|
* Declare a scope by providing an already created scope. The scope is merely
|
|
@@ -53,11 +51,9 @@ export function Scope(props: ScopeProps) {
|
|
|
53
51
|
if ("value" in props) {
|
|
54
52
|
scope = props.value;
|
|
55
53
|
} else {
|
|
56
|
-
|
|
57
|
-
scope = binder.createScope({
|
|
54
|
+
scope = new OutputScope(props.name ?? "", {
|
|
58
55
|
kind: props.kind,
|
|
59
56
|
metadata: props.metadata,
|
|
60
|
-
name: props.name ?? "",
|
|
61
57
|
});
|
|
62
58
|
}
|
|
63
59
|
|
package/src/components/Show.tsx
CHANGED
package/src/components/Wrap.tsx
CHANGED
package/src/context/binder.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Binder } from "../binder.js";
|
|
1
|
+
import type { Binder } from "../binder.js";
|
|
2
2
|
import {
|
|
3
3
|
ComponentContext,
|
|
4
4
|
createNamedContext,
|
|
@@ -15,5 +15,5 @@ export const BinderContext: ComponentContext<Binder> =
|
|
|
15
15
|
createNamedContext("Binder");
|
|
16
16
|
|
|
17
17
|
export function useBinder() {
|
|
18
|
-
return useContext(BinderContext)
|
|
18
|
+
return useContext(BinderContext);
|
|
19
19
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { OutputSymbol } from "../binder.js";
|
|
2
1
|
import { ComponentContext, createNamedContext } from "../context.js";
|
|
2
|
+
import type { OutputSymbol } from "../symbols/output-symbol.js";
|
|
3
3
|
|
|
4
4
|
export const DeclarationContext: ComponentContext<OutputSymbol> =
|
|
5
5
|
createNamedContext("Declaration");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { OutputSymbol } from "../binder.js";
|
|
2
1
|
import {
|
|
3
2
|
ComponentContext,
|
|
4
3
|
createNamedContext,
|
|
5
4
|
useContext,
|
|
6
5
|
} from "../context.js";
|
|
6
|
+
import type { OutputSymbol } from "../symbols/output-symbol.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Provides the symbol for the member currently being declared.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { OutputScope } from "../binder.js";
|
|
2
1
|
import {
|
|
3
2
|
ComponentContext,
|
|
4
3
|
createNamedContext,
|
|
5
4
|
useContext,
|
|
6
5
|
} from "../context.js";
|
|
6
|
+
import type { OutputScope } from "../symbols/output-scope.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The member scope context provides the instance and static member scopes that
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createNamedContext,
|
|
4
4
|
useContext,
|
|
5
5
|
} from "../context.js";
|
|
6
|
-
import { NamePolicy } from "../name-policy.js";
|
|
6
|
+
import type { NamePolicy } from "../name-policy.js";
|
|
7
7
|
|
|
8
8
|
export const NamePolicyContext: ComponentContext<NamePolicy<string>> =
|
|
9
9
|
createNamedContext<NamePolicy<string>>("NamePolicy", {
|
package/src/context/scope.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { OutputScope } from "../binder.js";
|
|
2
1
|
import {
|
|
3
2
|
ComponentContext,
|
|
4
3
|
createNamedContext,
|
|
5
4
|
useContext,
|
|
6
5
|
} from "../context.js";
|
|
6
|
+
import type { OutputScope } from "../symbols/output-scope.js";
|
|
7
7
|
|
|
8
8
|
export const ScopeContext: ComponentContext<OutputScope> =
|
|
9
9
|
createNamedContext("Scope");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentContext, createNamedContext } from "../context.js";
|
|
2
|
-
import { SourceFileContext } from "./source-file.js";
|
|
2
|
+
import type { SourceFileContext } from "./source-file.js";
|
|
3
3
|
|
|
4
4
|
export interface SourceDirectoryContext {
|
|
5
5
|
contents: (SourceDirectoryContext | SourceFileContext)[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComponentContext, createNamedContext } from "../context.js";
|
|
2
|
-
import { ComponentDefinition } from "../jsx-runtime.js";
|
|
3
|
-
import { Refkey } from "../refkey.js";
|
|
2
|
+
import type { ComponentDefinition } from "../jsx-runtime.js";
|
|
3
|
+
import type { Refkey } from "../refkey.js";
|
|
4
4
|
|
|
5
5
|
export interface SourceFileContext {
|
|
6
6
|
path: string;
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export {
|
|
2
|
+
TrackOpTypes,
|
|
3
|
+
TriggerOpTypes,
|
|
2
4
|
computed,
|
|
3
5
|
isProxy,
|
|
6
|
+
isReactive,
|
|
7
|
+
isRef,
|
|
4
8
|
reactive,
|
|
5
9
|
ref,
|
|
6
10
|
shallowReactive,
|
|
@@ -8,7 +12,15 @@ export {
|
|
|
8
12
|
toRaw,
|
|
9
13
|
toRef,
|
|
10
14
|
toRefs,
|
|
15
|
+
track,
|
|
16
|
+
trigger,
|
|
17
|
+
watch,
|
|
18
|
+
type Reactive,
|
|
11
19
|
type Ref,
|
|
20
|
+
type ShallowReactive,
|
|
21
|
+
type ShallowRef,
|
|
22
|
+
type ToRef,
|
|
23
|
+
type ToRefs,
|
|
12
24
|
} from "@vue/reactivity";
|
|
13
25
|
export * from "./binder.js";
|
|
14
26
|
export * from "./code.js";
|
|
@@ -17,10 +29,13 @@ export * from "./context.js";
|
|
|
17
29
|
export * from "./context/index.js";
|
|
18
30
|
export * from "./jsx-runtime.js";
|
|
19
31
|
export * from "./name-policy.js";
|
|
32
|
+
export * from "./reactive-union-set.js";
|
|
20
33
|
export * from "./refkey.js";
|
|
21
34
|
export * from "./render.js";
|
|
22
35
|
export * from "./stc.js";
|
|
23
36
|
export * from "./sti.js";
|
|
37
|
+
export * from "./symbols/index.js";
|
|
38
|
+
export * from "./symbols/symbol-flow.js";
|
|
24
39
|
export * from "./tap.js";
|
|
25
40
|
export * from "./utils.js";
|
|
26
41
|
export * from "./write-output.js";
|
package/src/jsx-runtime.ts
CHANGED
|
@@ -8,14 +8,16 @@ import {
|
|
|
8
8
|
ReactiveEffectRunner,
|
|
9
9
|
Ref,
|
|
10
10
|
resetTracking,
|
|
11
|
+
ShallowReactive,
|
|
11
12
|
shallowRef,
|
|
12
13
|
stop,
|
|
13
14
|
toRefs,
|
|
14
15
|
effect as vueEffect,
|
|
15
16
|
} from "@vue/reactivity";
|
|
16
|
-
import { Refkey } from "./refkey.js";
|
|
17
|
-
import { RenderedTextTree } from "./render.js";
|
|
17
|
+
import type { Refkey } from "./refkey.js";
|
|
18
|
+
import type { RenderedTextTree } from "./render.js";
|
|
18
19
|
import { scheduler } from "./scheduler.js";
|
|
20
|
+
import type { OutputSymbol } from "./symbols/output-symbol.js";
|
|
19
21
|
|
|
20
22
|
if ((globalThis as any).ALLOY) {
|
|
21
23
|
throw new Error(
|
|
@@ -48,6 +50,16 @@ export interface Context {
|
|
|
48
50
|
* be the component that created it.
|
|
49
51
|
*/
|
|
50
52
|
componentOwner?: ComponentCreator<unknown>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Whether this context will take an emitted symbol.
|
|
56
|
+
*/
|
|
57
|
+
takesSymbols: boolean;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The symbol that this component has taken.
|
|
61
|
+
*/
|
|
62
|
+
takenSymbols?: ShallowReactive<Set<OutputSymbol>>;
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
let globalContext: Context | null = null;
|
|
@@ -76,6 +88,8 @@ export function root<T>(fn: (d: Disposable) => T, options?: RootOptions): T {
|
|
|
76
88
|
owner: globalContext,
|
|
77
89
|
context: {},
|
|
78
90
|
elementCache: new Map(),
|
|
91
|
+
takesSymbols: false,
|
|
92
|
+
takenSymbols: undefined,
|
|
79
93
|
};
|
|
80
94
|
|
|
81
95
|
globalContext = context;
|
|
@@ -119,6 +133,8 @@ export function effect<T>(fn: (prev?: T) => T, current?: T) {
|
|
|
119
133
|
disposables: [] as (() => void)[],
|
|
120
134
|
owner: globalContext,
|
|
121
135
|
elementCache: new Map(),
|
|
136
|
+
takesSymbols: false,
|
|
137
|
+
takenSymbols: undefined,
|
|
122
138
|
};
|
|
123
139
|
|
|
124
140
|
const cleanupFn = (final: boolean) => {
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { effect } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import {
|
|
3
|
+
ITERATE_KEY,
|
|
4
|
+
ReactiveFlags,
|
|
5
|
+
shallowReactive,
|
|
6
|
+
shallowReadonly,
|
|
7
|
+
track,
|
|
8
|
+
TrackOpTypes,
|
|
9
|
+
trigger,
|
|
10
|
+
TriggerOpTypes,
|
|
11
|
+
} from "@vue/reactivity";
|
|
12
|
+
|
|
13
|
+
export interface ReactiveUnionSetOptions<T> {
|
|
14
|
+
onAdd?: OnReactiveSetAddCallback<T>;
|
|
15
|
+
onDelete?: OnReactiveSetDeleteCallback<T>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type OnReactiveSetDeleteCallback<T> = (value: T) => void;
|
|
19
|
+
export type OnReactiveSetAddCallback<T> = (value: T) => T;
|
|
20
|
+
|
|
21
|
+
export class ReactiveUnionSet<T> extends Set<T> {
|
|
22
|
+
private _subsets: Set<Set<T>>;
|
|
23
|
+
private _onAdd?: OnReactiveSetAddCallback<T>;
|
|
24
|
+
private _onDelete?: OnReactiveSetDeleteCallback<T>;
|
|
25
|
+
private _refcounts: Map<T, number> = new Map();
|
|
26
|
+
private _indexes: { add: (arg: T) => void; delete: (arg: T) => void }[] = [];
|
|
27
|
+
|
|
28
|
+
[ReactiveFlags.IS_REACTIVE] = true;
|
|
29
|
+
|
|
30
|
+
private _handleAdd(value: T) {
|
|
31
|
+
value = this._onAdd ? this._onAdd(value) : value;
|
|
32
|
+
|
|
33
|
+
for (const index of this._indexes) {
|
|
34
|
+
index.add(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private _handleDelete(value: T) {
|
|
41
|
+
if (this._onDelete) {
|
|
42
|
+
this._onDelete(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const index of this._indexes) {
|
|
46
|
+
index.delete(value);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
constructor(options: ReactiveUnionSetOptions<T> = {}) {
|
|
53
|
+
super();
|
|
54
|
+
|
|
55
|
+
this._subsets = new Set();
|
|
56
|
+
this._onAdd = options.onAdd;
|
|
57
|
+
this._onDelete = options.onDelete;
|
|
58
|
+
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get size() {
|
|
63
|
+
track(this, TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
64
|
+
return super.size;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
[Symbol.iterator](): SetIterator<T> {
|
|
68
|
+
track(this, TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
69
|
+
return super[Symbol.iterator]();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
keys(): SetIterator<T> {
|
|
73
|
+
track(this, TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
74
|
+
return super.keys();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
values(): SetIterator<T> {
|
|
78
|
+
track(this, TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
79
|
+
return super.values();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
entries(): SetIterator<[T, T]> {
|
|
83
|
+
track(this, TrackOpTypes.ITERATE, ITERATE_KEY);
|
|
84
|
+
return super.entries();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
add(item: T) {
|
|
88
|
+
if (this._refcounts.has(item)) {
|
|
89
|
+
this._refcounts.set(item, this._refcounts.get(item)! + 1);
|
|
90
|
+
} else {
|
|
91
|
+
this._refcounts.set(item, 1);
|
|
92
|
+
super.add(item);
|
|
93
|
+
this._handleAdd(item);
|
|
94
|
+
trigger(this, TriggerOpTypes.ADD, item, item);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
delete(item: T) {
|
|
101
|
+
const count = this._refcounts.get(item);
|
|
102
|
+
if (count === undefined) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (count > 1) {
|
|
107
|
+
this._refcounts.set(item, count - 1);
|
|
108
|
+
} else {
|
|
109
|
+
this._refcounts.delete(item);
|
|
110
|
+
super.delete(item);
|
|
111
|
+
this._handleDelete(item);
|
|
112
|
+
trigger(this, TriggerOpTypes.DELETE, undefined, item);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
addSubset(subset: Set<T>, options: ReactiveUnionSetOptions<T> = {}) {
|
|
119
|
+
if (this._subsets.has(subset)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const { onAdd, onDelete } = options;
|
|
124
|
+
|
|
125
|
+
this._subsets.add(subset);
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Contains a map of the previous values and their mapped values
|
|
129
|
+
* that were added to the parent set.
|
|
130
|
+
*/
|
|
131
|
+
const prevValues = new Map<T, T>();
|
|
132
|
+
|
|
133
|
+
effect(() => {
|
|
134
|
+
for (const [prevSourceValue, prevTargetValue] of prevValues) {
|
|
135
|
+
if (!subset.has(prevSourceValue)) {
|
|
136
|
+
onDelete?.(prevSourceValue);
|
|
137
|
+
prevValues.delete(prevSourceValue);
|
|
138
|
+
this.delete(prevTargetValue);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const value of subset) {
|
|
143
|
+
if (!prevValues.has(value)) {
|
|
144
|
+
if (onAdd) {
|
|
145
|
+
const added = onAdd(value);
|
|
146
|
+
prevValues.set(value, added);
|
|
147
|
+
} else {
|
|
148
|
+
this.add(value);
|
|
149
|
+
prevValues.set(value, value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
createDerivedSet<U>(mapper: (value: T) => U | U[]) {
|
|
157
|
+
const set = shallowReactive(new Set<U>());
|
|
158
|
+
const refcounts = new Map<U, number>();
|
|
159
|
+
|
|
160
|
+
function ref(value: U) {
|
|
161
|
+
if (refcounts.has(value)) {
|
|
162
|
+
const count = refcounts.get(value)! + 1;
|
|
163
|
+
refcounts.set(value, count);
|
|
164
|
+
return count;
|
|
165
|
+
} else {
|
|
166
|
+
refcounts.set(value, 1);
|
|
167
|
+
set.add(value);
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function unref(value: U) {
|
|
173
|
+
const count = refcounts.get(value)!;
|
|
174
|
+
|
|
175
|
+
if (count > 1) {
|
|
176
|
+
refcounts.set(value, count - 1);
|
|
177
|
+
return count - 1;
|
|
178
|
+
} else {
|
|
179
|
+
refcounts.delete(value);
|
|
180
|
+
set.delete(value);
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this._indexes.push({
|
|
186
|
+
add: (value: T) => {
|
|
187
|
+
effect((prev: U[] | U | undefined) => {
|
|
188
|
+
for (const id of [prev].flat()) {
|
|
189
|
+
unref(id as any);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const mappedValue = mapper(value);
|
|
193
|
+
for (const id of [mappedValue].flat()) {
|
|
194
|
+
ref(id as any);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return mappedValue;
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
delete: (value: T) => {
|
|
201
|
+
const mappedValue = mapper(value);
|
|
202
|
+
for (const id of [mappedValue].flat()) {
|
|
203
|
+
unref(id as any);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
return shallowReadonly(set);
|
|
209
|
+
}
|
|
210
|
+
createIndex<U>(mapper: (value: T) => U | U[]): ReadonlyMap<U, T> {
|
|
211
|
+
const index = shallowReactive(new Map<U, T>());
|
|
212
|
+
this._indexes.push({
|
|
213
|
+
add: (value: T) => {
|
|
214
|
+
effect((oldValue) => {
|
|
215
|
+
for (const id of [oldValue].flat()) {
|
|
216
|
+
index.delete(id as U);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const mappedValue = mapper(value);
|
|
220
|
+
|
|
221
|
+
for (const id of [mappedValue].flat()) {
|
|
222
|
+
index.set(id as U, value as any);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return mappedValue;
|
|
226
|
+
});
|
|
227
|
+
},
|
|
228
|
+
delete: (value: T) => {
|
|
229
|
+
const mappedValue = mapper(value);
|
|
230
|
+
for (const id of [mappedValue].flat()) {
|
|
231
|
+
index.delete(id as U);
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
return shallowReadonly(index);
|
|
237
|
+
}
|
|
238
|
+
}
|
package/src/refkey.ts
CHANGED
|
@@ -48,6 +48,20 @@ function getKey(value: unknown): Refkey {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const knownRefkeys = new Map<string, Refkey>();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create a refkey for the provided arguments. Passing no arguments returns a
|
|
54
|
+
* fresh refkey that is guaranteed to be unique. Otherwise, the arguments passed
|
|
55
|
+
* will be used to create a refkey for those values. Providing the same
|
|
56
|
+
* arguments will always return the same refkey.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
*
|
|
60
|
+
* Values are compared using the SameValueZero algorithm, which considers
|
|
61
|
+
* objects the same if they are reference identical, and primitives the same if
|
|
62
|
+
* they are the same value, with the exception of `NaN`, which is always considered
|
|
63
|
+
* equal to other `NaN` values, and `-0`, which is considered identical to `+0`
|
|
64
|
+
*/
|
|
51
65
|
export function refkey(...args: unknown[]): Refkey {
|
|
52
66
|
const keys = args.length === 0 ? [getKey({})] : args.map((v) => getKey(v));
|
|
53
67
|
|
|
@@ -60,3 +74,29 @@ export function refkey(...args: unknown[]): Refkey {
|
|
|
60
74
|
knownRefkeys.set(compositeKey, key);
|
|
61
75
|
return key;
|
|
62
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Create a refkey for an instantiation of a symbol.
|
|
80
|
+
*
|
|
81
|
+
* @param base - The refkey of the symbol holding the instantiation.
|
|
82
|
+
* @param member - The refkey of the non-instantiated member symbol (either the
|
|
83
|
+
* instance or static member symbol)
|
|
84
|
+
*
|
|
85
|
+
* @remarks
|
|
86
|
+
*
|
|
87
|
+
* Refkeys for instantiated and copied members are a composite refkey of the
|
|
88
|
+
* owner's refkey and the member's refkey. So for example, given a refkey for an
|
|
89
|
+
* instantiation of a class `rk1`, and a refkey for the instance member of that
|
|
90
|
+
* class `rk2`, the refkey for the instantiated static member is
|
|
91
|
+
* `refkey(rk1, rk2)`. This function will return the same refkey given those
|
|
92
|
+
* same parameters.
|
|
93
|
+
*
|
|
94
|
+
* When a static member symbol `rk3` is owned by another static or instance
|
|
95
|
+
* member symbol (i.e. the outer symbol is itself a member container), the
|
|
96
|
+
* refkey of the instaniated static member is still just the composite of the
|
|
97
|
+
* instantiated variable refkey and the refkey of the inner member
|
|
98
|
+
* `refkey(rk1, rk3)`.
|
|
99
|
+
*/
|
|
100
|
+
export function memberRefkey(base: Refkey, member: Refkey): Refkey {
|
|
101
|
+
return refkey(base, member);
|
|
102
|
+
}
|