@alloy-js/core 0.23.0-dev.8 → 0.23.0-dev.9
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/src/components/Prose.js +2 -2
- package/dist/src/components/Prose.js.map +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +2 -0
- package/dist/src/components/Scope.js.map +1 -1
- package/dist/src/components/SourceDirectory.d.ts.map +1 -1
- package/dist/src/components/SourceDirectory.js +1 -2
- package/dist/src/components/SourceDirectory.js.map +1 -1
- package/dist/src/content-slot.js +2 -2
- package/dist/src/content-slot.js.map +1 -1
- package/dist/src/context.js +2 -2
- package/dist/src/context.js.map +1 -1
- package/dist/src/debug/effects.d.ts +4 -0
- package/dist/src/debug/effects.d.ts.map +1 -1
- package/dist/src/debug/effects.js.map +1 -1
- package/dist/src/debug/effects.test.js +22 -24
- package/dist/src/debug/effects.test.js.map +1 -1
- package/dist/src/debug/index.d.ts +2 -1
- package/dist/src/debug/index.d.ts.map +1 -1
- package/dist/src/debug/index.js +2 -1
- package/dist/src/debug/index.js.map +1 -1
- package/dist/src/debug/symbols.d.ts +6 -0
- package/dist/src/debug/symbols.d.ts.map +1 -1
- package/dist/src/debug/symbols.js +9 -0
- package/dist/src/debug/symbols.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/reactive-union-set.d.ts.map +1 -1
- package/dist/src/reactive-union-set.js +13 -3
- package/dist/src/reactive-union-set.js.map +1 -1
- package/dist/src/reactivity.d.ts +34 -6
- package/dist/src/reactivity.d.ts.map +1 -1
- package/dist/src/reactivity.js +161 -123
- package/dist/src/reactivity.js.map +1 -1
- package/dist/src/render-stack.d.ts +1 -0
- package/dist/src/render-stack.d.ts.map +1 -1
- package/dist/src/render-stack.js +4 -0
- package/dist/src/render-stack.js.map +1 -1
- package/dist/src/render.d.ts.map +1 -1
- package/dist/src/render.js +15 -13
- package/dist/src/render.js.map +1 -1
- package/dist/src/scheduler.d.ts +5 -0
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +24 -1
- package/dist/src/scheduler.js.map +1 -1
- package/dist/src/symbols/output-scope.d.ts.map +1 -1
- package/dist/src/symbols/output-scope.js +2 -2
- package/dist/src/symbols/output-scope.js.map +1 -1
- package/dist/src/symbols/output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/output-symbol.js +2 -2
- package/dist/src/symbols/output-symbol.js.map +1 -1
- package/dist/src/symbols/symbol-flow.d.ts.map +1 -1
- package/dist/src/symbols/symbol-flow.js +2 -2
- package/dist/src/symbols/symbol-flow.js.map +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +2 -5
- package/dist/src/utils.js.map +1 -1
- package/dist/test/lazy-isempty.test.d.ts +2 -0
- package/dist/test/lazy-isempty.test.d.ts.map +1 -0
- package/dist/test/lazy-isempty.test.js +89 -0
- package/dist/test/lazy-isempty.test.js.map +1 -0
- package/dist/test/reactive-union-set-disposers.test.d.ts +2 -0
- package/dist/test/reactive-union-set-disposers.test.d.ts.map +1 -0
- package/dist/test/reactive-union-set-disposers.test.js +98 -0
- package/dist/test/reactive-union-set-disposers.test.js.map +1 -0
- package/dist/test/reactivity/shallow-reactive.test.d.ts +2 -0
- package/dist/test/reactivity/shallow-reactive.test.d.ts.map +1 -0
- package/dist/test/reactivity/shallow-reactive.test.js +52 -0
- package/dist/test/reactivity/shallow-reactive.test.js.map +1 -0
- package/dist/test/scheduler-extended.test.d.ts +2 -0
- package/dist/test/scheduler-extended.test.d.ts.map +1 -0
- package/dist/test/scheduler-extended.test.js +96 -0
- package/dist/test/scheduler-extended.test.js.map +1 -0
- package/dist/test/scheduler.test.d.ts +2 -0
- package/dist/test/scheduler.test.d.ts.map +1 -0
- package/dist/test/scheduler.test.js +46 -0
- package/dist/test/scheduler.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/Prose.tsx +1 -1
- package/src/components/Scope.tsx +2 -0
- package/src/components/SourceDirectory.tsx +1 -2
- package/src/content-slot.tsx +2 -2
- package/src/context.ts +3 -3
- package/src/debug/effects.test.tsx +24 -31
- package/src/debug/effects.ts +4 -0
- package/src/debug/index.ts +2 -0
- package/src/debug/symbols.ts +9 -0
- package/src/index.ts +0 -1
- package/src/reactive-union-set.ts +14 -3
- package/src/reactivity.ts +189 -130
- package/src/render-stack.ts +5 -0
- package/src/render.ts +16 -14
- package/src/scheduler.ts +25 -1
- package/src/symbols/output-scope.ts +1 -2
- package/src/symbols/output-symbol.ts +1 -2
- package/src/symbols/symbol-flow.ts +8 -2
- package/src/utils.tsx +2 -4
- package/temp/api.json +425 -14
- package/test/lazy-isempty.test.tsx +106 -0
- package/test/reactive-union-set-disposers.test.tsx +112 -0
- package/test/reactivity/shallow-reactive.test.tsx +56 -0
- package/test/scheduler-extended.test.tsx +122 -0
- package/test/scheduler.test.tsx +50 -0
package/package.json
CHANGED
package/src/components/Prose.tsx
CHANGED
package/src/components/Scope.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createScope } from "../binder.js";
|
|
2
2
|
import { ScopeContext, useScope } from "../context/scope.js";
|
|
3
|
+
import { debug } from "../debug/index.js";
|
|
3
4
|
import type { Children } from "../runtime/component.js";
|
|
4
5
|
import { BasicScope } from "../symbols/basic-scope.js";
|
|
5
6
|
import { OutputScope } from "../symbols/output-scope.js";
|
|
@@ -52,6 +53,7 @@ export function Scope(props: ScopeProps) {
|
|
|
52
53
|
let scope: OutputScope;
|
|
53
54
|
if ("value" in props) {
|
|
54
55
|
scope = props.value;
|
|
56
|
+
debug.symbols.relocateScope(scope);
|
|
55
57
|
} else {
|
|
56
58
|
const parentScope = useScope();
|
|
57
59
|
if (parentScope && !(parentScope instanceof BasicScope)) {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { shallowReactive } from "@vue/reactivity";
|
|
2
1
|
import { join } from "pathe";
|
|
3
2
|
import { useContext } from "../context.js";
|
|
4
3
|
import { SourceDirectoryContext } from "../context/source-directory.js";
|
|
5
|
-
import { getContext } from "../reactivity.js";
|
|
4
|
+
import { getContext, shallowReactive } from "../reactivity.js";
|
|
6
5
|
import type { Children } from "../runtime/component.js";
|
|
7
6
|
|
|
8
7
|
export interface SourceDirectoryProps {
|
package/src/content-slot.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computed, Ref, shallowRef } from "@vue/reactivity";
|
|
2
2
|
import { Show } from "./components/Show.jsx";
|
|
3
|
-
import { getContext } from "./reactivity.js";
|
|
3
|
+
import { ensureIsEmpty, getContext } from "./reactivity.js";
|
|
4
4
|
import { Children, Component } from "./runtime/component.js";
|
|
5
5
|
|
|
6
6
|
export interface ContentSlot {
|
|
@@ -61,7 +61,7 @@ export function createContentSlot(): ContentSlot {
|
|
|
61
61
|
|
|
62
62
|
function ContentSlot(props: { children: Children }) {
|
|
63
63
|
const context = getContext()!;
|
|
64
|
-
isEmptySource.value = context
|
|
64
|
+
isEmptySource.value = ensureIsEmpty(context);
|
|
65
65
|
return props.children;
|
|
66
66
|
}
|
|
67
67
|
ContentSlot.ref = isEmpty;
|
package/src/context.ts
CHANGED
|
@@ -20,8 +20,8 @@ export function useContext<T>(context: ComponentContext<T>): T | undefined {
|
|
|
20
20
|
// context must come from a parent
|
|
21
21
|
let current = getContext();
|
|
22
22
|
while (current) {
|
|
23
|
-
if (Object.hasOwn(current.context
|
|
24
|
-
return current.context
|
|
23
|
+
if (current.context && Object.hasOwn(current.context, context.id)) {
|
|
24
|
+
return current.context[context.id] as T | undefined;
|
|
25
25
|
}
|
|
26
26
|
current = current.owner;
|
|
27
27
|
}
|
|
@@ -43,7 +43,7 @@ export function createContext<T = unknown>(
|
|
|
43
43
|
const rendered = shallowRef();
|
|
44
44
|
effect(
|
|
45
45
|
() => {
|
|
46
|
-
context!.context
|
|
46
|
+
(context!.context ??= {})[id] = props.value;
|
|
47
47
|
rendered.value = () => props.children;
|
|
48
48
|
},
|
|
49
49
|
undefined,
|
|
@@ -39,58 +39,51 @@ afterEach(async () => {
|
|
|
39
39
|
it("emits effect, ref, edge, and update messages", async () => {
|
|
40
40
|
const collector = createMessageCollector(socket!);
|
|
41
41
|
const r1 = ref(0);
|
|
42
|
-
const r2 = ref(1);
|
|
43
42
|
|
|
43
|
+
// Create an effect that reads r1.
|
|
44
|
+
let observed = 0;
|
|
44
45
|
effect(() => {
|
|
45
|
-
|
|
46
|
+
observed = r1.value;
|
|
46
47
|
});
|
|
47
48
|
|
|
49
|
+
// Mutate r1 to trigger the effect.
|
|
50
|
+
r1.value = 42;
|
|
51
|
+
|
|
48
52
|
await renderAsync(<Output>{"ok"}</Output>);
|
|
49
53
|
|
|
50
54
|
const messages = await collector.waitForRender();
|
|
51
55
|
const effectsMessages = filterEffectsMessages(messages);
|
|
52
56
|
collector.stop();
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
// Check that core message types are present
|
|
59
|
+
const byType = (type: string) =>
|
|
60
|
+
effectsMessages.filter((m: any) => m.type === type);
|
|
61
|
+
expect(byType("effect:refAdded").length).toBeGreaterThanOrEqual(1);
|
|
62
|
+
expect(byType("effect:effectAdded").length).toBeGreaterThanOrEqual(1);
|
|
63
|
+
expect(byType("effect:track").length).toBeGreaterThanOrEqual(1);
|
|
64
|
+
expect(byType("effect:trigger").length).toBeGreaterThanOrEqual(1);
|
|
65
|
+
expect(byType("effect:effectUpdated").length).toBeGreaterThanOrEqual(1);
|
|
66
|
+
|
|
67
|
+
// Verify message shapes
|
|
68
|
+
expect(byType("effect:refAdded")[0]).toMatchObject({
|
|
69
|
+
ref: expect.objectContaining({ id: expect.any(Number), kind: "ref" }),
|
|
60
70
|
});
|
|
61
|
-
expect(
|
|
62
|
-
|
|
63
|
-
ref: expect.objectContaining({
|
|
64
|
-
id: expect.any(Number),
|
|
65
|
-
kind: "ref",
|
|
66
|
-
}),
|
|
71
|
+
expect(byType("effect:effectAdded")[0]).toMatchObject({
|
|
72
|
+
effect: expect.objectContaining({ id: expect.any(Number) }),
|
|
67
73
|
});
|
|
68
|
-
expect(
|
|
69
|
-
type: "effect:effectAdded",
|
|
70
|
-
effect: expect.objectContaining({
|
|
71
|
-
id: expect.any(Number),
|
|
72
|
-
}),
|
|
73
|
-
});
|
|
74
|
-
expect(effectsMessages[3]).toMatchObject({
|
|
75
|
-
type: "effect:track",
|
|
74
|
+
expect(byType("effect:track")[0]).toMatchObject({
|
|
76
75
|
edge: expect.objectContaining({
|
|
77
76
|
type: "track",
|
|
78
77
|
effectId: expect.any(Number),
|
|
79
78
|
refId: expect.any(Number),
|
|
80
79
|
}),
|
|
81
80
|
});
|
|
82
|
-
expect(
|
|
83
|
-
type: "effect:trigger",
|
|
81
|
+
expect(byType("effect:trigger")[0]).toMatchObject({
|
|
84
82
|
edge: expect.objectContaining({
|
|
85
|
-
type: "trigger",
|
|
86
83
|
effectId: expect.any(Number),
|
|
87
84
|
refId: expect.any(Number),
|
|
88
85
|
}),
|
|
89
86
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
effect: expect.objectContaining({
|
|
93
|
-
id: expect.any(Number),
|
|
94
|
-
}),
|
|
95
|
-
});
|
|
87
|
+
|
|
88
|
+
expect(observed).toBe(42);
|
|
96
89
|
});
|
package/src/debug/effects.ts
CHANGED
|
@@ -211,6 +211,8 @@ export function register(input: {
|
|
|
211
211
|
name?: string;
|
|
212
212
|
type?: string;
|
|
213
213
|
createdAt?: SourceLocation;
|
|
214
|
+
contextId?: number;
|
|
215
|
+
ownerContextId?: number | null;
|
|
214
216
|
}): number {
|
|
215
217
|
if (!isDevtoolsEnabled()) return -1;
|
|
216
218
|
const id = effectIdCounter++;
|
|
@@ -230,6 +232,7 @@ export function registerRef(input: {
|
|
|
230
232
|
kind?: string;
|
|
231
233
|
createdAt?: SourceLocation;
|
|
232
234
|
createdByEffectId?: number;
|
|
235
|
+
isInfrastructure?: boolean;
|
|
233
236
|
}) {
|
|
234
237
|
if (!isDevtoolsEnabled()) return;
|
|
235
238
|
if (refs.has(input.id)) return;
|
|
@@ -275,6 +278,7 @@ export function trigger(input: {
|
|
|
275
278
|
targetKey?: unknown;
|
|
276
279
|
location?: SourceLocation;
|
|
277
280
|
kind?: "trigger" | "triggered-by";
|
|
281
|
+
causedBy?: number;
|
|
278
282
|
}) {
|
|
279
283
|
if (!isDevtoolsEnabled()) return;
|
|
280
284
|
const edge: EffectEdgeDebugInfo = {
|
package/src/debug/index.ts
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
import {
|
|
41
41
|
registerScope,
|
|
42
42
|
registerSymbol,
|
|
43
|
+
relocateScope,
|
|
43
44
|
reset as resetSymbols,
|
|
44
45
|
unregisterScope,
|
|
45
46
|
unregisterSymbol,
|
|
@@ -107,6 +108,7 @@ export const debug = {
|
|
|
107
108
|
},
|
|
108
109
|
symbols: {
|
|
109
110
|
registerScope,
|
|
111
|
+
relocateScope,
|
|
110
112
|
unregisterScope,
|
|
111
113
|
registerSymbol,
|
|
112
114
|
unregisterSymbol,
|
package/src/debug/symbols.ts
CHANGED
|
@@ -184,6 +184,15 @@ export function unregisterScope(scope: OutputScope) {
|
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Re-register a pre-existing scope under the current render context.
|
|
189
|
+
* Called when `<Scope value={existingScope}>` mounts an already-created scope
|
|
190
|
+
* into a new location in the render tree.
|
|
191
|
+
*/
|
|
192
|
+
export function relocateScope(_scope: OutputScope) {
|
|
193
|
+
// Placeholder — real implementation added in the trace-writer branch.
|
|
194
|
+
}
|
|
195
|
+
|
|
187
196
|
export function registerSymbol(symbol: OutputSymbol) {
|
|
188
197
|
if (!isDevtoolsEnabled()) return;
|
|
189
198
|
if (symbolWatchers.has(symbol.id)) return;
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ITERATE_KEY,
|
|
3
3
|
ReactiveFlags,
|
|
4
|
-
shallowReactive,
|
|
5
4
|
shallowReadonly,
|
|
6
5
|
track,
|
|
7
6
|
TrackOpTypes,
|
|
8
7
|
trigger,
|
|
9
8
|
TriggerOpTypes,
|
|
10
9
|
} from "@vue/reactivity";
|
|
11
|
-
import { effect, untrack } from "./reactivity.js";
|
|
10
|
+
import { effect, root, shallowReactive, untrack } from "./reactivity.js";
|
|
12
11
|
|
|
13
12
|
export interface ReactiveUnionSetOptions<T> {
|
|
14
13
|
onAdd?: OnReactiveSetAddCallback<T>;
|
|
@@ -129,6 +128,7 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
129
128
|
* that were added to the parent set.
|
|
130
129
|
*/
|
|
131
130
|
const prevValues = new Map<T, T>();
|
|
131
|
+
const itemDisposers = new Map<T, () => void>();
|
|
132
132
|
|
|
133
133
|
effect(
|
|
134
134
|
() => {
|
|
@@ -137,13 +137,24 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
137
137
|
untrack(() => onDelete?.(prevSourceValue));
|
|
138
138
|
prevValues.delete(prevSourceValue);
|
|
139
139
|
this.delete(prevTargetValue);
|
|
140
|
+
const disposer = itemDisposers.get(prevSourceValue);
|
|
141
|
+
if (disposer) {
|
|
142
|
+
disposer();
|
|
143
|
+
itemDisposers.delete(prevSourceValue);
|
|
144
|
+
}
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
|
|
143
148
|
for (const value of subset) {
|
|
144
149
|
if (!prevValues.has(value)) {
|
|
145
150
|
if (onAdd) {
|
|
146
|
-
const added = untrack(() =>
|
|
151
|
+
const added = untrack(() =>
|
|
152
|
+
root((disposer) => {
|
|
153
|
+
const result = onAdd(value);
|
|
154
|
+
itemDisposers.set(value, disposer);
|
|
155
|
+
return result;
|
|
156
|
+
}),
|
|
157
|
+
);
|
|
147
158
|
prevValues.set(value, added);
|
|
148
159
|
} else {
|
|
149
160
|
this.add(value);
|