@alloy-js/core 0.23.0-dev.1 → 0.23.0-dev.8
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 +0 -22
- package/dist/devtools/index.html +68 -0
- package/dist/src/binder.d.ts +2 -0
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +55 -12
- package/dist/src/binder.js.map +1 -1
- package/dist/src/components/AppendFile.d.ts.map +1 -1
- package/dist/src/components/AppendFile.js +14 -3
- package/dist/src/components/AppendFile.js.map +1 -1
- package/dist/src/components/Block.js +1 -1
- package/dist/src/components/Block.js.map +1 -1
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +2 -1
- package/dist/src/components/Declaration.js.map +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +4 -1
- package/dist/src/components/Scope.js.map +1 -1
- package/dist/src/components/TemplateFile.d.ts.map +1 -1
- package/dist/src/components/TemplateFile.js +18 -3
- package/dist/src/components/TemplateFile.js.map +1 -1
- package/dist/src/content-slot.d.ts.map +1 -1
- package/dist/src/content-slot.js +6 -5
- package/dist/src/content-slot.js.map +1 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +8 -1
- package/dist/src/context.js.map +1 -1
- package/dist/src/debug/cli.d.ts +6 -0
- package/dist/src/debug/cli.d.ts.map +1 -0
- package/dist/src/{debug.js → debug/cli.js} +79 -82
- package/dist/src/debug/cli.js.map +1 -0
- package/dist/src/debug/diagnostics.test.d.ts +2 -0
- package/dist/src/debug/diagnostics.test.d.ts.map +1 -0
- package/dist/src/debug/diagnostics.test.js +45 -0
- package/dist/src/debug/diagnostics.test.js.map +1 -0
- package/dist/src/debug/effects.d.ts +69 -0
- package/dist/src/debug/effects.d.ts.map +1 -0
- package/dist/src/debug/effects.js +228 -0
- package/dist/src/debug/effects.js.map +1 -0
- package/dist/src/debug/effects.test.d.ts +2 -0
- package/dist/src/debug/effects.test.d.ts.map +1 -0
- package/dist/src/debug/effects.test.js +86 -0
- package/dist/src/debug/effects.test.js.map +1 -0
- package/dist/src/debug/files.d.ts +14 -0
- package/dist/src/debug/files.d.ts.map +1 -0
- package/dist/src/debug/files.js +40 -0
- package/dist/src/debug/files.js.map +1 -0
- package/dist/src/debug/files.test.d.ts +2 -0
- package/dist/src/debug/files.test.d.ts.map +1 -0
- package/dist/src/debug/files.test.js +89 -0
- package/dist/src/debug/files.test.js.map +1 -0
- package/dist/src/debug/index.d.ts +60 -0
- package/dist/src/debug/index.d.ts.map +1 -0
- package/dist/src/debug/index.js +68 -0
- package/dist/src/debug/index.js.map +1 -0
- package/dist/src/debug/render.d.ts +57 -0
- package/dist/src/debug/render.d.ts.map +1 -0
- package/dist/src/debug/render.js +519 -0
- package/dist/src/debug/render.js.map +1 -0
- package/dist/src/debug/render.test.d.ts +2 -0
- package/dist/src/debug/render.test.d.ts.map +1 -0
- package/dist/src/debug/render.test.js +328 -0
- package/dist/src/debug/render.test.js.map +1 -0
- package/dist/src/debug/serialize.d.ts +9 -0
- package/dist/src/debug/serialize.d.ts.map +1 -0
- package/dist/src/debug/serialize.js +70 -0
- package/dist/src/debug/serialize.js.map +1 -0
- package/dist/src/debug/symbols.d.ts +9 -0
- package/dist/src/debug/symbols.d.ts.map +1 -0
- package/dist/src/debug/symbols.js +164 -0
- package/dist/src/debug/symbols.js.map +1 -0
- package/dist/src/debug/symbols.test.d.ts +2 -0
- package/dist/src/debug/symbols.test.d.ts.map +1 -0
- package/dist/src/debug/symbols.test.js +104 -0
- package/dist/src/debug/symbols.test.js.map +1 -0
- package/dist/src/debug/trace.d.ts +342 -0
- package/dist/src/debug/trace.d.ts.map +1 -0
- package/dist/src/debug/trace.js +443 -0
- package/dist/src/debug/trace.js.map +1 -0
- package/dist/src/devtools/devtools-protocol.d.ts +232 -0
- package/dist/src/devtools/devtools-protocol.d.ts.map +1 -0
- package/dist/src/devtools/devtools-protocol.js +2 -0
- package/dist/src/devtools/devtools-protocol.js.map +1 -0
- package/dist/src/devtools/devtools-server.browser.d.ts +28 -0
- package/dist/src/devtools/devtools-server.browser.d.ts.map +1 -0
- package/dist/src/devtools/devtools-server.browser.js +36 -0
- package/dist/src/devtools/devtools-server.browser.js.map +1 -0
- package/dist/src/devtools/devtools-server.d.ts +72 -0
- package/dist/src/devtools/devtools-server.d.ts.map +1 -0
- package/dist/src/devtools/devtools-server.js +256 -0
- package/dist/src/devtools/devtools-server.js.map +1 -0
- package/dist/src/devtools/devtools-transport.d.ts +23 -0
- package/dist/src/devtools/devtools-transport.d.ts.map +1 -0
- package/dist/src/devtools/devtools-transport.js +114 -0
- package/dist/src/devtools/devtools-transport.js.map +1 -0
- package/dist/src/devtools-entry.browser.d.ts +4 -0
- package/dist/src/devtools-entry.browser.d.ts.map +1 -0
- package/dist/src/devtools-entry.browser.js +2 -0
- package/dist/src/devtools-entry.browser.js.map +1 -0
- package/dist/src/devtools-entry.d.ts +4 -0
- package/dist/src/devtools-entry.d.ts.map +1 -0
- package/dist/src/devtools-entry.js +2 -0
- package/dist/src/devtools-entry.js.map +1 -0
- package/dist/src/diagnostics.d.ts +34 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +89 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/print-hook.d.ts +14 -0
- package/dist/src/print-hook.d.ts.map +1 -0
- package/dist/src/print-hook.js +10 -0
- package/dist/src/print-hook.js.map +1 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -1
- package/dist/src/reactive-union-set.js +15 -0
- package/dist/src/reactive-union-set.js.map +1 -1
- package/dist/src/reactivity.d.ts +17 -3
- package/dist/src/reactivity.d.ts.map +1 -1
- package/dist/src/reactivity.js +162 -14
- package/dist/src/reactivity.js.map +1 -1
- package/dist/src/render-stack.d.ts +17 -1
- package/dist/src/render-stack.d.ts.map +1 -1
- package/dist/src/render-stack.js +57 -1
- package/dist/src/render-stack.js.map +1 -1
- package/dist/src/render.d.ts +8 -15
- package/dist/src/render.d.ts.map +1 -1
- package/dist/src/render.js +362 -103
- package/dist/src/render.js.map +1 -1
- package/dist/src/resource.d.ts.map +1 -1
- package/dist/src/resource.js +5 -0
- package/dist/src/resource.js.map +1 -1
- package/dist/src/scheduler.d.ts +3 -0
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +45 -2
- package/dist/src/scheduler.js.map +1 -1
- package/dist/src/symbols/basic-symbol.d.ts.map +1 -1
- package/dist/src/symbols/basic-symbol.js +6 -1
- package/dist/src/symbols/basic-symbol.js.map +1 -1
- package/dist/src/symbols/decl.d.ts.map +1 -1
- package/dist/src/symbols/decl.js +5 -1
- package/dist/src/symbols/decl.js.map +1 -1
- package/dist/src/symbols/output-scope.d.ts +2 -1
- package/dist/src/symbols/output-scope.d.ts.map +1 -1
- package/dist/src/symbols/output-scope.js +13 -8
- package/dist/src/symbols/output-scope.js.map +1 -1
- package/dist/src/symbols/output-symbol.d.ts +1 -0
- package/dist/src/symbols/output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/output-symbol.js +23 -6
- 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 +22 -6
- package/dist/src/symbols/symbol-flow.js.map +1 -1
- package/dist/src/symbols/symbol-slot.d.ts.map +1 -1
- package/dist/src/symbols/symbol-slot.js +15 -0
- package/dist/src/symbols/symbol-slot.js.map +1 -1
- package/dist/src/symbols/symbol-slot.test.d.ts +2 -0
- package/dist/src/symbols/symbol-slot.test.d.ts.map +1 -0
- package/dist/src/symbols/symbol-slot.test.js +35 -0
- package/dist/src/symbols/symbol-slot.test.js.map +1 -0
- package/dist/src/symbols/symbol-table.d.ts.map +1 -1
- package/dist/src/symbols/symbol-table.js +6 -5
- package/dist/src/symbols/symbol-table.js.map +1 -1
- package/dist/src/trace.d.ts +2 -0
- package/dist/src/trace.d.ts.map +1 -0
- package/dist/src/trace.js +2 -0
- package/dist/src/trace.js.map +1 -0
- package/dist/src/tracer.d.ts +2 -228
- package/dist/src/tracer.d.ts.map +1 -1
- package/dist/src/tracer.js +5 -298
- package/dist/src/tracer.js.map +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +5 -0
- package/dist/src/utils.js.map +1 -1
- package/dist/test/components/append-file.test.d.ts.map +1 -1
- package/dist/test/components/append-file.test.js +18 -10
- package/dist/test/components/append-file.test.js.map +1 -1
- package/dist/test/components/template-file.test.d.ts.map +1 -1
- package/dist/test/components/template-file.test.js +6 -4
- package/dist/test/components/template-file.test.js.map +1 -1
- package/dist/test/rendering/basic.test.js +3 -0
- package/dist/test/rendering/basic.test.js.map +1 -1
- package/dist/test/rendering/print-render-stack.test.d.ts.map +1 -1
- package/dist/test/rendering/print-render-stack.test.js +91 -98
- package/dist/test/rendering/print-render-stack.test.js.map +1 -1
- package/dist/testing/create-test-wrapper.d.ts +1 -1
- package/dist/testing/create-test-wrapper.d.ts.map +1 -1
- package/dist/testing/create-test-wrapper.js +1 -1
- package/dist/testing/create-test-wrapper.js.map +1 -1
- package/dist/testing/devtools-utils.d.ts +26 -0
- package/dist/testing/devtools-utils.d.ts.map +1 -0
- package/dist/testing/devtools-utils.js +140 -0
- package/dist/testing/devtools-utils.js.map +1 -0
- package/dist/testing/extend-expect.d.ts.map +1 -1
- package/dist/testing/extend-expect.js +63 -1
- package/dist/testing/extend-expect.js.map +1 -1
- package/dist/testing/render.d.ts +2 -2
- package/dist/testing/render.d.ts.map +1 -1
- package/dist/testing/render.js +2 -2
- package/dist/testing/render.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -7
- package/scripts/copy-devtools-ui.mjs +26 -0
- package/src/binder.ts +71 -16
- package/src/components/AppendFile.tsx +14 -9
- package/src/components/Block.tsx +1 -1
- package/src/components/Declaration.tsx +2 -1
- package/src/components/Scope.tsx +4 -1
- package/src/components/TemplateFile.tsx +18 -9
- package/src/content-slot.tsx +6 -6
- package/src/context.ts +15 -4
- package/src/{debug.ts → debug/cli.ts} +114 -125
- package/src/debug/diagnostics.test.tsx +55 -0
- package/src/debug/effects.test.tsx +96 -0
- package/src/debug/effects.ts +313 -0
- package/src/debug/files.test.tsx +96 -0
- package/src/debug/files.ts +40 -0
- package/src/debug/index.ts +126 -0
- package/src/debug/render.test.tsx +379 -0
- package/src/debug/render.ts +639 -0
- package/src/debug/serialize.ts +85 -0
- package/src/debug/symbols.test.tsx +106 -0
- package/src/debug/symbols.ts +230 -0
- package/src/debug/trace.ts +312 -0
- package/src/devtools/devtools-protocol.ts +312 -0
- package/src/devtools/devtools-server.browser.ts +71 -0
- package/src/devtools/devtools-server.ts +290 -0
- package/src/devtools/devtools-transport.ts +154 -0
- package/src/devtools-entry.browser.ts +52 -0
- package/src/devtools-entry.ts +54 -0
- package/src/diagnostics.ts +141 -0
- package/src/index.ts +2 -6
- package/src/print-hook.ts +22 -0
- package/src/reactive-union-set.ts +71 -41
- package/src/reactivity.ts +206 -23
- package/src/render-stack.ts +68 -1
- package/src/render.ts +464 -157
- package/src/resource.ts +28 -19
- package/src/scheduler.ts +55 -3
- package/src/symbols/basic-symbol.ts +6 -1
- package/src/symbols/decl.ts +5 -1
- package/src/symbols/output-scope.ts +21 -12
- package/src/symbols/output-symbol.ts +33 -12
- package/src/symbols/symbol-flow.ts +68 -37
- package/src/symbols/symbol-slot.test.tsx +41 -0
- package/src/symbols/symbol-slot.tsx +47 -20
- package/src/symbols/symbol-table.ts +6 -10
- package/src/trace.ts +1 -0
- package/src/tracer.ts +13 -242
- package/src/utils.tsx +22 -13
- package/temp/api.json +1675 -162
- package/test/components/append-file.test.tsx +36 -29
- package/test/components/template-file.test.tsx +11 -11
- package/test/rendering/basic.test.tsx +4 -0
- package/test/rendering/print-render-stack.test.tsx +52 -43
- package/testing/create-test-wrapper.tsx +1 -1
- package/testing/devtools-utils.ts +203 -0
- package/testing/extend-expect.ts +89 -0
- package/testing/render.ts +2 -2
- package/testing/vitest.d.ts +9 -0
- package/dist/src/debug.d.ts +0 -14
- package/dist/src/debug.d.ts.map +0 -1
- package/dist/src/debug.js.map +0 -1
package/src/reactivity.ts
CHANGED
|
@@ -2,21 +2,61 @@ import {
|
|
|
2
2
|
isRef,
|
|
3
3
|
pauseTracking,
|
|
4
4
|
ReactiveEffectRunner,
|
|
5
|
-
ref,
|
|
6
5
|
Ref,
|
|
7
6
|
resetTracking,
|
|
8
7
|
ShallowReactive,
|
|
9
|
-
shallowRef,
|
|
10
8
|
stop,
|
|
9
|
+
computed as vueComputed,
|
|
11
10
|
effect as vueEffect,
|
|
11
|
+
ref as vueRef,
|
|
12
|
+
shallowRef as vueShallowRef,
|
|
13
|
+
toRef as vueToRef,
|
|
14
|
+
toRefs as vueToRefs,
|
|
12
15
|
} from "@vue/reactivity";
|
|
13
|
-
import
|
|
14
|
-
|
|
16
|
+
import {
|
|
17
|
+
captureSourceLocation,
|
|
18
|
+
debug,
|
|
19
|
+
isDevtoolsEnabled,
|
|
20
|
+
} from "./debug/index.js";
|
|
21
|
+
import { RenderedTextTree } from "./render.js";
|
|
22
|
+
import { Children, ComponentCreator } from "./runtime/component.js";
|
|
15
23
|
import { scheduler } from "./scheduler.js";
|
|
16
24
|
import type { OutputSymbol } from "./symbols/output-symbol.js";
|
|
17
|
-
import { trace, TracePhase } from "./tracer.js";
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
function attachEffectWriteDebug(refValue: Ref<unknown>, kind: string) {
|
|
27
|
+
if (!isDevtoolsEnabled()) return;
|
|
28
|
+
const descriptor =
|
|
29
|
+
Object.getOwnPropertyDescriptor(refValue, "value") ??
|
|
30
|
+
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(refValue), "value");
|
|
31
|
+
if (!descriptor?.get || !descriptor?.set) return;
|
|
32
|
+
if ((refValue as any).__alloyDebugWrapped) return;
|
|
33
|
+
Object.defineProperty(refValue, "value", {
|
|
34
|
+
get: descriptor.get,
|
|
35
|
+
set(value: unknown) {
|
|
36
|
+
descriptor.set!.call(this, value);
|
|
37
|
+
const effectId = globalContext?.meta?.effectId;
|
|
38
|
+
if (effectId !== undefined && effectId !== -1) {
|
|
39
|
+
const id = refId(refValue);
|
|
40
|
+
debug.effect.ensureRef({ id, kind });
|
|
41
|
+
debug.effect.trigger({
|
|
42
|
+
effectId,
|
|
43
|
+
target: refValue,
|
|
44
|
+
refId: id,
|
|
45
|
+
location: captureSourceLocation(),
|
|
46
|
+
kind: "trigger",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
enumerable: descriptor.enumerable ?? true,
|
|
51
|
+
configurable: true,
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(refValue, "__alloyDebugWrapped", {
|
|
54
|
+
value: true,
|
|
55
|
+
enumerable: false,
|
|
56
|
+
configurable: false,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
20
60
|
if ((globalThis as any).__ALLOY__) {
|
|
21
61
|
throw new Error(
|
|
22
62
|
"Multiple versions of Alloy are loaded for this project. This will likely cause undesirable behavior.",
|
|
@@ -116,7 +156,7 @@ export function root<T>(fn: (d: Disposable) => T, options?: RootOptions): T {
|
|
|
116
156
|
ret = untrack(() =>
|
|
117
157
|
fn(() => {
|
|
118
158
|
for (const d of context!.disposables) {
|
|
119
|
-
d
|
|
159
|
+
untrack(d);
|
|
120
160
|
}
|
|
121
161
|
}),
|
|
122
162
|
);
|
|
@@ -127,6 +167,15 @@ export function root<T>(fn: (d: Disposable) => T, options?: RootOptions): T {
|
|
|
127
167
|
return ret;
|
|
128
168
|
}
|
|
129
169
|
|
|
170
|
+
export interface EffectDebugOptions {
|
|
171
|
+
name?: string;
|
|
172
|
+
type?: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface EffectOptions {
|
|
176
|
+
debug?: EffectDebugOptions;
|
|
177
|
+
}
|
|
178
|
+
|
|
130
179
|
export function untrack<T>(fn: () => T): T {
|
|
131
180
|
pauseTracking();
|
|
132
181
|
const v = fn();
|
|
@@ -135,17 +184,27 @@ export function untrack<T>(fn: () => T): T {
|
|
|
135
184
|
}
|
|
136
185
|
|
|
137
186
|
export function memo<T>(fn: () => T, equal?: boolean): () => T {
|
|
138
|
-
const o = shallowRef();
|
|
139
|
-
effect(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
187
|
+
const o = shallowRef<T>();
|
|
188
|
+
effect(
|
|
189
|
+
(prev) => {
|
|
190
|
+
const res = fn();
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
192
|
+
(!equal || prev !== res) && (o.value = res);
|
|
193
|
+
return res;
|
|
194
|
+
},
|
|
195
|
+
undefined as T,
|
|
196
|
+
{
|
|
197
|
+
debug: { name: "memo" },
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
return () => o.value as T;
|
|
146
201
|
}
|
|
147
202
|
|
|
148
|
-
export function effect<T>(
|
|
203
|
+
export function effect<T>(
|
|
204
|
+
fn: (prev?: T) => T,
|
|
205
|
+
current?: T,
|
|
206
|
+
options?: EffectOptions,
|
|
207
|
+
) {
|
|
149
208
|
const context: Context = {
|
|
150
209
|
context: {},
|
|
151
210
|
disposables: [] as (() => void)[],
|
|
@@ -157,10 +216,22 @@ export function effect<T>(fn: (prev?: T) => T, current?: T) {
|
|
|
157
216
|
isRoot: false,
|
|
158
217
|
};
|
|
159
218
|
|
|
219
|
+
const debugInfo = options?.debug;
|
|
220
|
+
const effectId = debug.effect.register({
|
|
221
|
+
name: debugInfo?.name ?? fn.name,
|
|
222
|
+
type: debugInfo?.type,
|
|
223
|
+
createdAt: captureSourceLocation(),
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
context.meta ??= {};
|
|
227
|
+
if (effectId !== -1) {
|
|
228
|
+
context.meta.effectId = effectId;
|
|
229
|
+
}
|
|
230
|
+
|
|
160
231
|
const cleanupFn = (final: boolean) => {
|
|
161
232
|
const d = context.disposables;
|
|
162
233
|
context.disposables = [];
|
|
163
|
-
for (let k = 0, len = d.length; k < len; k++) d[k]
|
|
234
|
+
for (let k = 0, len = d.length; k < len; k++) untrack(d[k]);
|
|
164
235
|
|
|
165
236
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
166
237
|
final && stop(runner);
|
|
@@ -185,14 +256,56 @@ export function effect<T>(fn: (prev?: T) => T, current?: T) {
|
|
|
185
256
|
flags: 1 | 4 | 32,
|
|
186
257
|
scheduler: scheduler(),
|
|
187
258
|
onTrack(event) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
259
|
+
if (effectId !== -1) {
|
|
260
|
+
const targetKey =
|
|
261
|
+
typeof event.key === "symbol" ? event.key.toString() : event.key;
|
|
262
|
+
if (isRef(event.target)) {
|
|
263
|
+
const id = refId(event.target);
|
|
264
|
+
debug.effect.ensureRef({ id, kind: "ref" });
|
|
265
|
+
debug.effect.track({
|
|
266
|
+
effectId,
|
|
267
|
+
target: event.target,
|
|
268
|
+
refId: id,
|
|
269
|
+
targetKey,
|
|
270
|
+
location: captureSourceLocation(),
|
|
271
|
+
});
|
|
272
|
+
} else {
|
|
273
|
+
debug.effect.track({
|
|
274
|
+
effectId,
|
|
275
|
+
target: event.target,
|
|
276
|
+
targetKey,
|
|
277
|
+
location: captureSourceLocation(),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// track edge emitted via recordEffectTrack
|
|
191
282
|
},
|
|
192
283
|
onTrigger(event) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
284
|
+
if (effectId !== -1) {
|
|
285
|
+
const targetKey =
|
|
286
|
+
typeof event.key === "symbol" ? event.key.toString() : event.key;
|
|
287
|
+
if (isRef(event.target)) {
|
|
288
|
+
const id = refId(event.target);
|
|
289
|
+
debug.effect.ensureRef({ id, kind: "ref" });
|
|
290
|
+
debug.effect.trigger({
|
|
291
|
+
effectId,
|
|
292
|
+
target: event.target,
|
|
293
|
+
refId: id,
|
|
294
|
+
targetKey,
|
|
295
|
+
location: captureSourceLocation(),
|
|
296
|
+
kind: "triggered-by",
|
|
297
|
+
});
|
|
298
|
+
} else {
|
|
299
|
+
debug.effect.trigger({
|
|
300
|
+
effectId,
|
|
301
|
+
target: event.target,
|
|
302
|
+
targetKey,
|
|
303
|
+
location: captureSourceLocation(),
|
|
304
|
+
kind: "triggered-by",
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// trigger edge emitted via recordEffectTrigger
|
|
196
309
|
},
|
|
197
310
|
},
|
|
198
311
|
);
|
|
@@ -253,6 +366,76 @@ export function isCustomContext(child: Children): child is CustomContext {
|
|
|
253
366
|
);
|
|
254
367
|
}
|
|
255
368
|
|
|
369
|
+
export function ref<T>(value?: T): Ref<T> {
|
|
370
|
+
const result = vueRef(value) as Ref<T>;
|
|
371
|
+
attachEffectWriteDebug(result, "ref");
|
|
372
|
+
debug.effect.registerRef({
|
|
373
|
+
id: refId(result),
|
|
374
|
+
kind: "ref",
|
|
375
|
+
createdAt: captureSourceLocation(),
|
|
376
|
+
createdByEffectId: globalContext?.meta?.effectId,
|
|
377
|
+
});
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export function shallowRef<T>(value?: T): Ref<T> {
|
|
382
|
+
const result = vueShallowRef(value) as Ref<T>;
|
|
383
|
+
attachEffectWriteDebug(result, "shallowRef");
|
|
384
|
+
debug.effect.registerRef({
|
|
385
|
+
id: refId(result),
|
|
386
|
+
kind: "shallowRef",
|
|
387
|
+
createdAt: captureSourceLocation(),
|
|
388
|
+
createdByEffectId: globalContext?.meta?.effectId,
|
|
389
|
+
});
|
|
390
|
+
return result;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export function computed<T>(getter: () => T): Ref<T> {
|
|
394
|
+
const result = vueComputed(getter) as Ref<T>;
|
|
395
|
+
debug.effect.registerRef({
|
|
396
|
+
id: refId(result),
|
|
397
|
+
kind: "computed",
|
|
398
|
+
createdAt: captureSourceLocation(),
|
|
399
|
+
createdByEffectId: globalContext?.meta?.effectId,
|
|
400
|
+
});
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export function toRef<T extends object, K extends keyof T>(
|
|
405
|
+
object: T,
|
|
406
|
+
key: K,
|
|
407
|
+
defaultValue?: T[K],
|
|
408
|
+
): Ref<T[K]> {
|
|
409
|
+
const result =
|
|
410
|
+
defaultValue === undefined ?
|
|
411
|
+
(vueToRef(object, key) as Ref<T[K]>)
|
|
412
|
+
: (vueToRef(object, key, defaultValue) as Ref<T[K]>);
|
|
413
|
+
attachEffectWriteDebug(result, "toRef");
|
|
414
|
+
debug.effect.registerRef({
|
|
415
|
+
id: refId(result),
|
|
416
|
+
kind: "toRef",
|
|
417
|
+
createdAt: captureSourceLocation(),
|
|
418
|
+
createdByEffectId: globalContext?.meta?.effectId,
|
|
419
|
+
});
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export function toRefs<T extends object>(
|
|
424
|
+
object: T,
|
|
425
|
+
): { [K in keyof T]: Ref<T[K]> } {
|
|
426
|
+
const result = vueToRefs(object) as { [K in keyof T]: Ref<T[K]> };
|
|
427
|
+
for (const refValue of Object.values(result) as Ref<unknown>[]) {
|
|
428
|
+
attachEffectWriteDebug(refValue, "toRef");
|
|
429
|
+
debug.effect.registerRef({
|
|
430
|
+
id: refId(refValue),
|
|
431
|
+
kind: "toRef",
|
|
432
|
+
createdAt: captureSourceLocation(),
|
|
433
|
+
createdByEffectId: globalContext?.meta?.effectId,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
|
|
256
439
|
const seenRefs = new WeakMap<Ref<unknown>, number>();
|
|
257
440
|
let refIdCounter = 1;
|
|
258
441
|
|
package/src/render-stack.ts
CHANGED
|
@@ -13,6 +13,14 @@ const renderStack: Array<{
|
|
|
13
13
|
source?: SourceLocation;
|
|
14
14
|
}> = [];
|
|
15
15
|
|
|
16
|
+
export interface RenderStackSnapshotEntry {
|
|
17
|
+
component: Component<any>;
|
|
18
|
+
props: Props;
|
|
19
|
+
context: Context | null;
|
|
20
|
+
source?: SourceLocation;
|
|
21
|
+
displayName: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
export function pushStack(
|
|
17
25
|
component: Component<any>,
|
|
18
26
|
props: Props,
|
|
@@ -29,6 +37,42 @@ export function clearRenderStack() {
|
|
|
29
37
|
renderStack.length = 0;
|
|
30
38
|
}
|
|
31
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Get the current rendering path from the render stack context.
|
|
42
|
+
* Prefers SourceFileContext over SourceDirectoryContext.
|
|
43
|
+
*/
|
|
44
|
+
export function getCurrentRenderPath(): string | undefined {
|
|
45
|
+
let currentPath: string | undefined;
|
|
46
|
+
for (let i = renderStack.length - 1; i >= 0; i--) {
|
|
47
|
+
const { context } = renderStack[i];
|
|
48
|
+
// Prefer SourceFileContext over SourceDirectoryContext
|
|
49
|
+
if (context?.context?.[SourceFileContext.id]) {
|
|
50
|
+
const fileContext = context.context[
|
|
51
|
+
SourceFileContext.id
|
|
52
|
+
] as SourceFileContext;
|
|
53
|
+
return fileContext.path;
|
|
54
|
+
}
|
|
55
|
+
if (!currentPath && context?.context?.[SourceDirectoryContext.id]) {
|
|
56
|
+
const dirContext = context.context[
|
|
57
|
+
SourceDirectoryContext.id
|
|
58
|
+
] as SourceDirectoryContext;
|
|
59
|
+
currentPath = dirContext.path;
|
|
60
|
+
// Don't break - keep looking for a SourceFileContext
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return currentPath;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function getRenderStackSnapshot(): RenderStackSnapshotEntry[] {
|
|
67
|
+
return renderStack.map((entry) => ({
|
|
68
|
+
component: entry.component,
|
|
69
|
+
props: entry.props,
|
|
70
|
+
context: entry.context,
|
|
71
|
+
source: entry.source,
|
|
72
|
+
displayName: getComponentDisplayName(entry.component, entry.props),
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
|
|
32
76
|
// Helper functions
|
|
33
77
|
function getComponentDisplayName(
|
|
34
78
|
component: Component<any>,
|
|
@@ -93,8 +137,10 @@ function formatSourceLocation(source: SourceLocation): string {
|
|
|
93
137
|
* This differs from debug.component.stack in that this uses a purpose-built
|
|
94
138
|
* stack rather than walking the context chain. When this is called, the context
|
|
95
139
|
* chain has been restored. In the future this can probably be unified nicely.
|
|
140
|
+
*
|
|
141
|
+
* @param error - Optional error to print the stack trace from
|
|
96
142
|
*/
|
|
97
|
-
export function printRenderStack() {
|
|
143
|
+
export function printRenderStack(error?: unknown) {
|
|
98
144
|
// Find the nearest SourceFileContext or SourceDirectoryContext from the render stack
|
|
99
145
|
let currentPath: string | undefined;
|
|
100
146
|
for (let i = renderStack.length - 1; i >= 0; i--) {
|
|
@@ -124,6 +170,27 @@ export function printRenderStack() {
|
|
|
124
170
|
console.error(pc.red("Error rendering:"));
|
|
125
171
|
}
|
|
126
172
|
|
|
173
|
+
// Print the error message and stack if provided
|
|
174
|
+
if (error) {
|
|
175
|
+
if (error instanceof Error) {
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.error(pc.red(` ${error.message}`));
|
|
178
|
+
if (error.stack) {
|
|
179
|
+
// Print stack lines (skip the first line which is the error message)
|
|
180
|
+
const stackLines = error.stack.split("\n").slice(1);
|
|
181
|
+
for (const line of stackLines) {
|
|
182
|
+
// eslint-disable-next-line no-console
|
|
183
|
+
console.error(pc.gray(line));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
// eslint-disable-next-line no-console
|
|
188
|
+
console.error(pc.red(` ${String(error)}`));
|
|
189
|
+
}
|
|
190
|
+
// eslint-disable-next-line no-console
|
|
191
|
+
console.error(); // Empty line before component stack
|
|
192
|
+
}
|
|
193
|
+
|
|
127
194
|
// First pass: determine which providers should be nested vs standalone
|
|
128
195
|
// A provider should be nested under its parent if it's from a different file
|
|
129
196
|
// (i.e., it's part of the component's implementation, not user-provided)
|