@fluixi/devtools 0.2.0-alpha.1 → 0.2.0-alpha.3
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/README.md +80 -2
- package/dist/callsite.d.ts +22 -0
- package/dist/callsite.d.ts.map +1 -0
- package/dist/callsite.js +82 -0
- package/dist/change-view.d.ts +10 -0
- package/dist/change-view.d.ts.map +1 -0
- package/dist/change-view.js +102 -0
- package/dist/copy.d.ts +9 -0
- package/dist/copy.d.ts.map +1 -0
- package/dist/copy.js +52 -0
- package/dist/describe.d.ts +3 -0
- package/dist/describe.d.ts.map +1 -0
- package/dist/describe.js +47 -0
- package/dist/detail-panel.d.ts +17 -0
- package/dist/detail-panel.d.ts.map +1 -0
- package/dist/detail-panel.js +217 -0
- package/dist/diff.d.ts +31 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +132 -0
- package/dist/dom.d.ts +81 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +269 -0
- package/dist/export.d.ts +55 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +90 -0
- package/dist/float.d.ts +54 -0
- package/dist/float.d.ts.map +1 -0
- package/dist/float.js +256 -0
- package/dist/format.d.ts +16 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +188 -0
- package/dist/graph-view.d.ts +79 -2
- package/dist/graph-view.d.ts.map +1 -1
- package/dist/graph-view.js +866 -50
- package/dist/highlight.d.ts +56 -0
- package/dist/highlight.d.ts.map +1 -0
- package/dist/highlight.js +154 -0
- package/dist/history.d.ts +59 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +85 -0
- package/dist/hook.d.ts +60 -0
- package/dist/hook.d.ts.map +1 -0
- package/dist/hook.js +142 -0
- package/dist/index.d.ts +44 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -1
- package/dist/inspector.d.ts +60 -0
- package/dist/inspector.d.ts.map +1 -0
- package/dist/inspector.js +415 -0
- package/dist/instrument.d.ts +147 -5
- package/dist/instrument.d.ts.map +1 -1
- package/dist/instrument.js +164 -44
- package/dist/kind-filter.d.ts +39 -0
- package/dist/kind-filter.d.ts.map +1 -0
- package/dist/kind-filter.js +151 -0
- package/dist/menu.d.ts +37 -0
- package/dist/menu.d.ts.map +1 -0
- package/dist/menu.js +125 -0
- package/dist/observe.d.ts +80 -0
- package/dist/observe.d.ts.map +1 -0
- package/dist/observe.js +893 -0
- package/dist/palette.d.ts +11 -0
- package/dist/palette.d.ts.map +1 -0
- package/dist/palette.js +27 -0
- package/dist/path.d.ts +19 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +49 -0
- package/dist/plugin.d.ts +121 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +74 -0
- package/dist/plugins/context.d.ts +10 -0
- package/dist/plugins/context.d.ts.map +1 -0
- package/dist/plugins/context.js +80 -0
- package/dist/plugins/directives.d.ts +25 -0
- package/dist/plugins/directives.d.ts.map +1 -0
- package/dist/plugins/directives.js +78 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +9 -0
- package/dist/source.d.ts +72 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +153 -0
- package/dist/timeline.d.ts +30 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +271 -0
- package/dist/tree.d.ts +128 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +645 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/value-pane.d.ts +10 -0
- package/dist/value-pane.d.ts.map +1 -0
- package/dist/value-pane.js +61 -0
- package/dist/wire.d.ts +100 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +93 -0
- package/package.json +10 -3
package/dist/instrument.d.ts
CHANGED
|
@@ -1,9 +1,56 @@
|
|
|
1
|
-
|
|
1
|
+
import { Immutable, StoreSetter } from '@fluixi/reactive/store';
|
|
2
|
+
import { type ReactiveSourceLocation } from './source.js';
|
|
3
|
+
import type { DomNode } from './dom.js';
|
|
4
|
+
export type NodeKind = 'state' | 'memo' | 'effect' | 'store' | 'resource' | 'component'
|
|
5
|
+
/** Control flow the framework supplies: `Show`, `For`, `Switch`, `Suspense`, `Await`. */
|
|
6
|
+
| 'control'
|
|
7
|
+
/** The router's own tags: `Router`, `Outlet`, `Link`, `Redirect`. */
|
|
8
|
+
| 'router'
|
|
9
|
+
/** A server route handler: `GET`, `POST` in an api file. */
|
|
10
|
+
| 'handler'
|
|
11
|
+
/** Not a node: a card a view draws to stand for several of them. */
|
|
12
|
+
| 'group'
|
|
13
|
+
/** Not a node: a place in the document a signal writes to. */
|
|
14
|
+
| 'binding'
|
|
15
|
+
/** A directive applied to an element: `use:`, `class:`, `bind:`. */
|
|
16
|
+
| 'directive'
|
|
17
|
+
/** A context, and the components that provide or read it. */
|
|
18
|
+
| 'context'
|
|
19
|
+
/** A component whose job is providing a context. */
|
|
20
|
+
| 'provider'
|
|
21
|
+
/** Not a node: a place in the code that sets a signal. */
|
|
22
|
+
| 'setter';
|
|
2
23
|
export type NodeState = 'clean' | 'check' | 'dirty';
|
|
24
|
+
/**
|
|
25
|
+
* The names the compiler supplies without an import, and what each one is. A control-flow
|
|
26
|
+
* tag stamps its name the same way an author's component does, so without this `Match` and
|
|
27
|
+
* `Switch` are drawn as components the author wrote.
|
|
28
|
+
*
|
|
29
|
+
* Mirrors `resolve/builtins.ts` in @fluixi/compiler. Not imported from there: this package
|
|
30
|
+
* runs beside the application, and the compiler is not on that side of the wall.
|
|
31
|
+
*/
|
|
32
|
+
export declare const KIND_OF_BUILTIN: Record<string, NodeKind>;
|
|
33
|
+
/** One place in the document that a signal drives. */
|
|
34
|
+
export interface DomTarget {
|
|
35
|
+
/** `content` for a text or element hole, `attribute` or `property` otherwise. */
|
|
36
|
+
kind: string;
|
|
37
|
+
/** The attribute or property name, when there is one. */
|
|
38
|
+
name?: string;
|
|
39
|
+
/** The element, as a selector-ish description: `li.done`, `#total`. */
|
|
40
|
+
element: string;
|
|
41
|
+
/** The line of the application that wired this binding up. */
|
|
42
|
+
source?: ReactiveSourceLocation;
|
|
43
|
+
}
|
|
3
44
|
export interface RNode {
|
|
4
45
|
id: number;
|
|
5
46
|
label: string;
|
|
6
47
|
kind: NodeKind;
|
|
48
|
+
/**
|
|
49
|
+
* Whether the label is the author's own, from a compiler mark. False for a positional
|
|
50
|
+
* label and for one the runtime supplied, which between them are the framework's own
|
|
51
|
+
* machinery, which is what a view offers to keep behind one card.
|
|
52
|
+
*/
|
|
53
|
+
authored?: boolean;
|
|
7
54
|
/** Source ids read on the last run (read edges: source → this). */
|
|
8
55
|
deps: Set<number>;
|
|
9
56
|
/** Signal ids written while this node ran (write edges: this → signal). */
|
|
@@ -12,19 +59,88 @@ export interface RNode {
|
|
|
12
59
|
read?: () => unknown;
|
|
13
60
|
/** Last serialized value, for change detection / display. */
|
|
14
61
|
value?: string;
|
|
62
|
+
/** The same value with room to read it, for a tooltip or an inspector. */
|
|
63
|
+
detail?: string;
|
|
15
64
|
/** Times this node recomputed / re-ran. */
|
|
16
65
|
runs: number;
|
|
17
|
-
/** performance.now() of the last change
|
|
66
|
+
/** performance.now() of the last change. Drives the flash. */
|
|
18
67
|
lastPulse: number;
|
|
19
|
-
/** Live core node, when reachable
|
|
68
|
+
/** Live core node, when reachable. Gives the real version and state. */
|
|
20
69
|
core?: {
|
|
21
70
|
version?: number;
|
|
22
71
|
state?: number;
|
|
23
72
|
} | null;
|
|
73
|
+
/** Where the author created this node, when the compiler said so. Always optional. */
|
|
74
|
+
source?: ReactiveSourceLocation;
|
|
75
|
+
/**
|
|
76
|
+
* The node whose run created this one. A component's memo reads nothing of its own, so
|
|
77
|
+
* what it created is what connects it to the rest of the graph.
|
|
78
|
+
*/
|
|
79
|
+
createdIn?: number;
|
|
80
|
+
/**
|
|
81
|
+
* Components only: where the component itself was declared, which is a different place
|
|
82
|
+
* from where it was used and the node made.
|
|
83
|
+
*/
|
|
84
|
+
declaredAt?: ReactiveSourceLocation;
|
|
85
|
+
/**
|
|
86
|
+
* The line of the application that led to this node, for one the compiler did not mark:
|
|
87
|
+
* a signal a package created on the caller's behalf.
|
|
88
|
+
*/
|
|
89
|
+
usedAt?: ReactiveSourceLocation;
|
|
90
|
+
/**
|
|
91
|
+
* How many dom bindings read this node. They are not drawn, since one per attribute and
|
|
92
|
+
* text hole would bury the graph, but a signal read only by them is still read.
|
|
93
|
+
*/
|
|
94
|
+
bindings?: number;
|
|
95
|
+
/**
|
|
96
|
+
* What those bindings write: the text of an `<li>`, the `class` of a `<div>`. Described,
|
|
97
|
+
* never referenced: holding dom nodes would keep a removed subtree alive.
|
|
98
|
+
*/
|
|
99
|
+
targets?: DomTarget[];
|
|
100
|
+
/**
|
|
101
|
+
* Set from outside any computation, by a handler or a timer. The graph has no node to draw an
|
|
102
|
+
* edge from for these, so this is the only record of where they came from.
|
|
103
|
+
*/
|
|
104
|
+
setAt?: ReactiveSourceLocation[];
|
|
105
|
+
/**
|
|
106
|
+
* What this tag rendered, when a producer described it. A panel in the page reads the
|
|
107
|
+
* elements instead; this is for one that cannot.
|
|
108
|
+
*/
|
|
109
|
+
dom?: DomNode[];
|
|
110
|
+
/**
|
|
111
|
+
* Where this tag's element sits in the document, counted across every tag that owns one.
|
|
112
|
+
*
|
|
113
|
+
* Siblings would otherwise sort by id, which is creation order. A keyed list rebuilds a row
|
|
114
|
+
* rather than mutating it, so the replacement takes the highest id and sorted last: toggling
|
|
115
|
+
* the first item in a list moved its card to the end of the band and the flash always landed
|
|
116
|
+
* on the bottom row. Only a producer in the page can work this out.
|
|
117
|
+
*/
|
|
118
|
+
order?: number;
|
|
24
119
|
/** Resource only. */
|
|
25
120
|
loading?: boolean;
|
|
121
|
+
/** This tag arrived as its own chunk, so it is not in the bundle the page started with. */
|
|
122
|
+
lazy?: boolean;
|
|
123
|
+
/** Components only: what the tag was handed, and where each was written. */
|
|
124
|
+
props?: PropReport[];
|
|
125
|
+
/**
|
|
126
|
+
* What plugins have attached, by plugin name. Serialisable, and carried across the wire
|
|
127
|
+
* untouched by anything that does not know the plugin that wrote it.
|
|
128
|
+
*/
|
|
129
|
+
extra?: Record<string, unknown>;
|
|
26
130
|
depth?: number;
|
|
27
131
|
}
|
|
132
|
+
/** One prop of a component tag. The value is read untracked, and only when asked for. */
|
|
133
|
+
export interface PropReport {
|
|
134
|
+
name: string;
|
|
135
|
+
/** Formatted at the moment it was read. Absent when reading threw. */
|
|
136
|
+
value?: string;
|
|
137
|
+
/** Where it was written on the tag. */
|
|
138
|
+
at?: {
|
|
139
|
+
file?: string;
|
|
140
|
+
line?: number;
|
|
141
|
+
column?: number;
|
|
142
|
+
};
|
|
143
|
+
}
|
|
28
144
|
/** The real version (signals/memos) or recompute count fallback. */
|
|
29
145
|
export declare function nodeVersion(n: RNode): number;
|
|
30
146
|
/** The real CLEAN/CHECK/DIRTY state when the core node is reachable (memos), else undefined. */
|
|
@@ -34,7 +150,7 @@ export interface ReactorApi {
|
|
|
34
150
|
name?: string;
|
|
35
151
|
equals?: false | ((a: T, b: T) => boolean);
|
|
36
152
|
}): [() => T, (v: T | ((prev: T) => T)) => T];
|
|
37
|
-
createMemo<T>(fn: () => T, options?: {
|
|
153
|
+
createMemo<T>(fn: () => T, value?: T, options?: {
|
|
38
154
|
name?: string;
|
|
39
155
|
}): () => T;
|
|
40
156
|
createEffect(fn: () => void, options?: {
|
|
@@ -44,7 +160,31 @@ export interface ReactorApi {
|
|
|
44
160
|
name?: string;
|
|
45
161
|
immutable?: boolean;
|
|
46
162
|
}): [T, (...args: unknown[]) => void];
|
|
47
|
-
createResource(...args: unknown[]): [((
|
|
163
|
+
createResource(...args: unknown[]): [(() => unknown) & Record<string, unknown>, unknown];
|
|
164
|
+
signal<T>(value: T, options?: {
|
|
165
|
+
name?: string;
|
|
166
|
+
equals?: false | ((a: T, b: T) => boolean);
|
|
167
|
+
}): (() => T) & ((v: T | ((prev: T) => T)) => T);
|
|
168
|
+
memo<T>(fn: () => T, value?: T, options?: {
|
|
169
|
+
name?: string;
|
|
170
|
+
}): () => T;
|
|
171
|
+
effect(fn: () => void, options?: {
|
|
172
|
+
name?: string;
|
|
173
|
+
}): void;
|
|
174
|
+
store<T extends object>(initial: T, options?: {
|
|
175
|
+
name?: string;
|
|
176
|
+
immutable?: boolean;
|
|
177
|
+
}): Immutable<T> & {
|
|
178
|
+
set: StoreSetter<T>;
|
|
179
|
+
};
|
|
180
|
+
resource<T extends object, S>(fetcher: (source: S) => T | Promise<T>, source?: () => S, options?: {
|
|
181
|
+
name?: string;
|
|
182
|
+
initialValue?: T | (() => T);
|
|
183
|
+
}): () => T | (undefined & {
|
|
184
|
+
loading: boolean;
|
|
185
|
+
error: unknown;
|
|
186
|
+
refetch: () => void;
|
|
187
|
+
});
|
|
48
188
|
}
|
|
49
189
|
export interface Reactor {
|
|
50
190
|
readonly graph: Map<number, RNode>;
|
|
@@ -52,5 +192,7 @@ export interface Reactor {
|
|
|
52
192
|
sample(): number[];
|
|
53
193
|
dispose(): void;
|
|
54
194
|
}
|
|
195
|
+
export declare const fmt: (v: unknown) => string;
|
|
196
|
+
export declare const short: (s: string, n?: number) => string;
|
|
55
197
|
export declare function createReactor(): Reactor;
|
|
56
198
|
//# sourceMappingURL=instrument.d.ts.map
|
package/dist/instrument.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"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"}
|
package/dist/instrument.js
CHANGED
|
@@ -3,9 +3,25 @@
|
|
|
3
3
|
// into a graph. A read is a subscription, so edges come from real reads; writes (setX) made inside
|
|
4
4
|
// a consumer become write edges. Nodes carry the live core node so the inspector reads the real
|
|
5
5
|
// version + CLEAN/CHECK/DIRTY state, and onCleanup removes a node when its owner disposes.
|
|
6
|
-
import { createSignal, createMemo, createEffect, createResource, createRoot, untrack, onCleanup, Signal, } from '@fluixi/reactive/signal';
|
|
6
|
+
import { createSignal, createMemo, createEffect, createResource, createRoot, untrack, onCleanup, getOwner, runWithOwner, Signal, } from '@fluixi/reactive/signal';
|
|
7
7
|
import { createStore } from '@fluixi/reactive/store';
|
|
8
|
+
import { componentSource, installSourceMarker, takeReactiveSource } from './source.js';
|
|
9
|
+
import { formatValue, shorten } from './format.js';
|
|
8
10
|
const $NODE = Symbol.for('signal-node');
|
|
11
|
+
/**
|
|
12
|
+
* The names the compiler supplies without an import, and what each one is. A control-flow
|
|
13
|
+
* tag stamps its name the same way an author's component does, so without this `Match` and
|
|
14
|
+
* `Switch` are drawn as components the author wrote.
|
|
15
|
+
*
|
|
16
|
+
* Mirrors `resolve/builtins.ts` in @fluixi/compiler. Not imported from there: this package
|
|
17
|
+
* runs beside the application, and the compiler is not on that side of the wall.
|
|
18
|
+
*/
|
|
19
|
+
export const KIND_OF_BUILTIN = {
|
|
20
|
+
Show: 'control', For: 'control', Index: 'control', Switch: 'control', Match: 'control',
|
|
21
|
+
Portal: 'control', Dynamic: 'control', ErrorBoundary: 'control',
|
|
22
|
+
Suspense: 'control', SuspenseList: 'control', Await: 'control',
|
|
23
|
+
Router: 'router', Outlet: 'router', Redirect: 'router', Link: 'router',
|
|
24
|
+
};
|
|
9
25
|
const CORE_STATE = { 0: 'clean', 1: 'check', 2: 'dirty' };
|
|
10
26
|
/** The real version (signals/memos) or recompute count fallback. */
|
|
11
27
|
export function nodeVersion(n) {
|
|
@@ -15,28 +31,51 @@ export function nodeVersion(n) {
|
|
|
15
31
|
export function nodeState(n) {
|
|
16
32
|
return n.core && typeof n.core.state === 'number' ? CORE_STATE[n.core.state] : undefined;
|
|
17
33
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return JSON.stringify(v);
|
|
22
|
-
if (typeof v === 'function')
|
|
23
|
-
return 'ƒ';
|
|
24
|
-
if (typeof v === 'bigint')
|
|
25
|
-
return `${v}n`;
|
|
26
|
-
if (typeof v === 'object' && v)
|
|
27
|
-
return JSON.stringify(v);
|
|
28
|
-
return String(v);
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return '?';
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
const short = (s, n = 18) => (s.length > n ? s.slice(0, n - 1) + '…' : s);
|
|
34
|
+
// Kept as the names the rest of this package already uses.
|
|
35
|
+
export const fmt = (v) => formatValue(v);
|
|
36
|
+
export const short = (s, n = 18) => shorten(s, n);
|
|
35
37
|
export function createReactor() {
|
|
38
|
+
installSourceMarker();
|
|
36
39
|
const graph = new Map();
|
|
40
|
+
/** Run counts as of the last sample, so a node with no readable value can still pulse. */
|
|
41
|
+
const runsAtLastSample = new Map();
|
|
42
|
+
/** Nodes still carrying a positional label, so a better one can replace it later. */
|
|
43
|
+
const unnamed = new Set();
|
|
37
44
|
const consumerStack = [];
|
|
38
45
|
let seq = 0;
|
|
39
46
|
let dispose = () => { };
|
|
47
|
+
// The root's owner, kept so a node created after `run` returned still has somewhere to
|
|
48
|
+
// hang its cleanup. A project's modules load asynchronously, so most registration lands
|
|
49
|
+
// well after the synchronous setup. With no owner, `onCleanup` runs immediately and the
|
|
50
|
+
// node disappears the moment it is made, which is why the graph came up empty.
|
|
51
|
+
let rootOwner = null;
|
|
52
|
+
/**
|
|
53
|
+
* Whether this node is the wrapper that made the stamped value, rather than one further
|
|
54
|
+
* down that only passes it along.
|
|
55
|
+
*
|
|
56
|
+
* `$name` is set on what a component returns, so it travels with the value: every memo
|
|
57
|
+
* holding it looks like the component. The one that made it is the one none of its
|
|
58
|
+
* dependencies already has. Otherwise a component under `Suspense` draws twice.
|
|
59
|
+
*/
|
|
60
|
+
const claims = (node, value) => {
|
|
61
|
+
for (const dep of node.deps) {
|
|
62
|
+
const other = graph.get(dep);
|
|
63
|
+
if (other?.read && other.read() === value)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
68
|
+
/** Remove a node when whatever created it goes away, or when the reactor is torn down. */
|
|
69
|
+
const forget = (id) => {
|
|
70
|
+
const owner = getOwner() ?? rootOwner;
|
|
71
|
+
if (owner) {
|
|
72
|
+
runWithOwner(owner, () => onCleanup(() => {
|
|
73
|
+
graph.delete(id);
|
|
74
|
+
runsAtLastSample.delete(id);
|
|
75
|
+
unnamed.delete(id);
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
};
|
|
40
79
|
const recordRead = (sourceId) => {
|
|
41
80
|
const c = consumerStack[consumerStack.length - 1];
|
|
42
81
|
if (c != null)
|
|
@@ -47,24 +86,34 @@ export function createReactor() {
|
|
|
47
86
|
if (c != null && c !== targetId)
|
|
48
87
|
graph.get(c)?.writes.add(targetId);
|
|
49
88
|
};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
89
|
+
// Every tracked primitive comes through here, so it is the one place a mark is taken. An
|
|
90
|
+
// explicit `{ name }` wins; otherwise the node borrows the variable name the compiler
|
|
91
|
+
// read, which is why `const count = signal(0)` shows as `count` rather than `s0`.
|
|
92
|
+
const base = (id, named, kind, fallback) => {
|
|
93
|
+
const mark = takeReactiveSource();
|
|
94
|
+
if (!named && !mark?.name)
|
|
95
|
+
unnamed.add(id);
|
|
96
|
+
return {
|
|
97
|
+
id,
|
|
98
|
+
label: named ?? mark?.name ?? fallback,
|
|
99
|
+
kind,
|
|
100
|
+
deps: new Set(),
|
|
101
|
+
writes: new Set(),
|
|
102
|
+
runs: 0,
|
|
103
|
+
lastPulse: 0,
|
|
104
|
+
...(mark?.location ? { source: mark.location } : {}),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
59
107
|
const trackedCreateSignal = (value, options) => {
|
|
60
108
|
const id = seq++;
|
|
61
109
|
const [get, set] = createSignal(value, options);
|
|
62
|
-
const node = base(id, options?.name
|
|
110
|
+
const node = base(id, options?.name, 'state', `s${id}`);
|
|
63
111
|
node.read = () => untrack(get);
|
|
64
|
-
node.
|
|
112
|
+
node.detail = formatValue(value);
|
|
113
|
+
node.value = shorten(node.detail);
|
|
65
114
|
node.core = get[$NODE] ?? null;
|
|
66
115
|
graph.set(id, node);
|
|
67
|
-
|
|
116
|
+
forget(id);
|
|
68
117
|
const read = () => {
|
|
69
118
|
recordRead(id);
|
|
70
119
|
return get();
|
|
@@ -75,11 +124,11 @@ export function createReactor() {
|
|
|
75
124
|
};
|
|
76
125
|
return [read, write];
|
|
77
126
|
};
|
|
78
|
-
const trackedCreateMemo = (fn, options) => {
|
|
127
|
+
const trackedCreateMemo = (fn, value, options) => {
|
|
79
128
|
const id = seq++;
|
|
80
|
-
const node = base(id, options?.name
|
|
129
|
+
const node = base(id, options?.name, 'memo', `m${id}`);
|
|
81
130
|
graph.set(id, node);
|
|
82
|
-
|
|
131
|
+
forget(id);
|
|
83
132
|
const m = createMemo(() => {
|
|
84
133
|
node.core ??= Signal.subtle.currentComputed(); // capture the live Computed
|
|
85
134
|
node.deps.clear();
|
|
@@ -92,7 +141,7 @@ export function createReactor() {
|
|
|
92
141
|
finally {
|
|
93
142
|
consumerStack.pop();
|
|
94
143
|
}
|
|
95
|
-
});
|
|
144
|
+
}, value, options);
|
|
96
145
|
node.read = () => untrack(m);
|
|
97
146
|
return () => {
|
|
98
147
|
recordRead(id);
|
|
@@ -101,9 +150,9 @@ export function createReactor() {
|
|
|
101
150
|
};
|
|
102
151
|
const trackedCreateEffect = (fn, options) => {
|
|
103
152
|
const id = seq++;
|
|
104
|
-
const node = base(id, options?.name
|
|
153
|
+
const node = base(id, options?.name, 'effect', `e${id}`);
|
|
105
154
|
graph.set(id, node);
|
|
106
|
-
|
|
155
|
+
forget(id);
|
|
107
156
|
createEffect(() => {
|
|
108
157
|
node.core ??= Signal.subtle.currentComputed();
|
|
109
158
|
node.deps.clear();
|
|
@@ -122,7 +171,7 @@ export function createReactor() {
|
|
|
122
171
|
const trackedCreateStore = (initial, options) => {
|
|
123
172
|
const id = seq++;
|
|
124
173
|
const [proxy, setter] = createStore(initial, { immutable: true, ...options });
|
|
125
|
-
const node = base(id, options?.name
|
|
174
|
+
const node = base(id, options?.name, 'store', `store${id}`);
|
|
126
175
|
node.read = () => {
|
|
127
176
|
try {
|
|
128
177
|
return untrack(() => JSON.stringify(proxy));
|
|
@@ -133,7 +182,7 @@ export function createReactor() {
|
|
|
133
182
|
};
|
|
134
183
|
node.value = '{…}';
|
|
135
184
|
graph.set(id, node);
|
|
136
|
-
|
|
185
|
+
forget(id);
|
|
137
186
|
const recording = new Proxy(proxy, {
|
|
138
187
|
get(t, p, r) {
|
|
139
188
|
recordRead(id);
|
|
@@ -150,7 +199,7 @@ export function createReactor() {
|
|
|
150
199
|
const id = seq++;
|
|
151
200
|
const last = args[args.length - 1];
|
|
152
201
|
const name = last && typeof last === 'object' && !Array.isArray(last) && typeof last !== 'function' ? last.name : undefined;
|
|
153
|
-
const node = base(id, name
|
|
202
|
+
const node = base(id, name, 'resource', `res${id}`);
|
|
154
203
|
const [data, actions] = createResource(...args);
|
|
155
204
|
node.read = () => {
|
|
156
205
|
try {
|
|
@@ -162,7 +211,7 @@ export function createReactor() {
|
|
|
162
211
|
};
|
|
163
212
|
node.value = '⏳ loading';
|
|
164
213
|
graph.set(id, node);
|
|
165
|
-
|
|
214
|
+
forget(id);
|
|
166
215
|
const accessor = (() => {
|
|
167
216
|
recordRead(id);
|
|
168
217
|
return data();
|
|
@@ -172,38 +221,109 @@ export function createReactor() {
|
|
|
172
221
|
}
|
|
173
222
|
return [accessor, actions];
|
|
174
223
|
};
|
|
224
|
+
// The short API is the long one with a handle around it. `signal` is
|
|
225
|
+
// `Object.assign(createSignal(...), { set })`, `memo` and `effect` are the same function
|
|
226
|
+
// under another name. Deriving them keeps one definition of what tracking means, instead
|
|
227
|
+
// of a second copy of the node bookkeeping that drifts from the first.
|
|
228
|
+
const trackedSignal = (value, options) => {
|
|
229
|
+
const [read, write] = trackedCreateSignal(value, options);
|
|
230
|
+
Object.defineProperty(read, 'set', { value: write });
|
|
231
|
+
return read;
|
|
232
|
+
};
|
|
233
|
+
const trackedMemo = trackedCreateMemo;
|
|
234
|
+
const trackedEffect = trackedCreateEffect;
|
|
235
|
+
const trackedStore = (initial, options) => {
|
|
236
|
+
const [state, set] = trackedCreateStore(initial, options);
|
|
237
|
+
// A wrapper rather than assigning onto the state: the proxy is the tracking boundary,
|
|
238
|
+
// and writing a key through it would read as a state change.
|
|
239
|
+
return new Proxy(state, {
|
|
240
|
+
get: (target, key) => (key === 'set' ? set : target[key]),
|
|
241
|
+
has: (target, key) => key === 'set' || Reflect.has(target, key),
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
const trackedResource = (...args) => {
|
|
245
|
+
const [accessor, controls] = trackedCreateResource(...args);
|
|
246
|
+
return Object.assign(accessor, controls);
|
|
247
|
+
};
|
|
175
248
|
const api = {
|
|
176
249
|
createSignal: trackedCreateSignal,
|
|
177
250
|
createMemo: trackedCreateMemo,
|
|
178
251
|
createEffect: trackedCreateEffect,
|
|
179
252
|
createStore: trackedCreateStore,
|
|
180
253
|
createResource: trackedCreateResource,
|
|
254
|
+
signal: trackedSignal,
|
|
255
|
+
memo: trackedMemo,
|
|
256
|
+
store: trackedStore,
|
|
257
|
+
effect: trackedEffect,
|
|
258
|
+
resource: trackedResource
|
|
181
259
|
};
|
|
182
260
|
return {
|
|
183
261
|
graph,
|
|
184
262
|
run(setup) {
|
|
185
263
|
dispose();
|
|
186
264
|
graph.clear();
|
|
265
|
+
runsAtLastSample.clear();
|
|
266
|
+
unnamed.clear();
|
|
187
267
|
seq = 0;
|
|
188
268
|
consumerStack.length = 0;
|
|
189
269
|
createRoot((d) => {
|
|
190
270
|
dispose = d;
|
|
271
|
+
rootOwner = getOwner();
|
|
191
272
|
setup(api);
|
|
192
273
|
});
|
|
193
274
|
},
|
|
194
275
|
sample() {
|
|
195
276
|
const changed = [];
|
|
196
|
-
|
|
277
|
+
// Date.now rather than performance.now: the reactor may run in one realm and the view
|
|
278
|
+
// in another, which an iframe preview does, and each realm's performance
|
|
279
|
+
// clock has its own origin, so the age the view computed was nonsense and nothing
|
|
280
|
+
// ever pulsed.
|
|
281
|
+
const now = Date.now();
|
|
197
282
|
for (const node of graph.values()) {
|
|
198
|
-
|
|
283
|
+
// An effect has no value to read, so what marks it as having done something is the
|
|
284
|
+
// run count the wrapper keeps. Without this an effect never pulsed.
|
|
285
|
+
if (!node.read) {
|
|
286
|
+
const seen = runsAtLastSample.get(node.id);
|
|
287
|
+
if (seen !== undefined && node.runs > seen) {
|
|
288
|
+
node.lastPulse = now;
|
|
289
|
+
changed.push(node.id);
|
|
290
|
+
}
|
|
291
|
+
runsAtLastSample.set(node.id, node.runs);
|
|
199
292
|
continue;
|
|
200
|
-
|
|
201
|
-
|
|
293
|
+
}
|
|
294
|
+
const raw = node.read();
|
|
295
|
+
// The compiler wraps each component in a memo, and `createComponent` stamps the
|
|
296
|
+
// component's name on what it returns. A memo that has no name of its own is that
|
|
297
|
+
// wrapper, so it can say `Counter` rather than `m5`.
|
|
298
|
+
// The runtime stamps a component's name on what it returned, so a memo holding
|
|
299
|
+
// that is the wrapper the compiler put round a component. Not gated on the node
|
|
300
|
+
// being unnamed: the compiler marks the tag with the component's name too, which
|
|
301
|
+
// would leave the node named and never recognised.
|
|
302
|
+
const stamped = raw?.$name;
|
|
303
|
+
if (node.kind === 'memo' && typeof stamped === 'string' && stamped && claims(node, raw)) {
|
|
304
|
+
// Still a memo underneath. This only says so, so a renderer can draw it as what
|
|
305
|
+
// the author wrote rather than as the wrapper around it.
|
|
306
|
+
node.kind = KIND_OF_BUILTIN[stamped] ?? 'component';
|
|
307
|
+
// `source` stays what it is for every other node: where this one was created,
|
|
308
|
+
// which for a wrapper is where the tag was written. Where the component itself
|
|
309
|
+
// lives is a second fact, and it stands in for the first when nothing marked it.
|
|
310
|
+
node.declaredAt = componentSource(stamped);
|
|
311
|
+
node.source ??= node.declaredAt;
|
|
312
|
+
if (unnamed.has(node.id)) {
|
|
313
|
+
node.label = stamped;
|
|
314
|
+
unnamed.delete(node.id);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
const detail = formatValue(raw);
|
|
318
|
+
const next = shorten(detail);
|
|
319
|
+
if (next !== node.value || detail !== node.detail) {
|
|
320
|
+
node.detail = detail;
|
|
202
321
|
node.value = next;
|
|
203
322
|
node.runs++;
|
|
204
323
|
node.lastPulse = now;
|
|
205
324
|
changed.push(node.id);
|
|
206
325
|
}
|
|
326
|
+
runsAtLastSample.set(node.id, node.runs);
|
|
207
327
|
}
|
|
208
328
|
return changed;
|
|
209
329
|
},
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Picks which kinds of node the graph draws.
|
|
3
|
+
*
|
|
4
|
+
* Nine checkboxes took up too much of the toolbar, so they sit in a dropdown. The button
|
|
5
|
+
* shows the count while a filter is active.
|
|
6
|
+
*
|
|
7
|
+
* Not a `<select multiple>`: it renders as a list box, takes the full height, and needs
|
|
8
|
+
* ctrl-click to select more than one.
|
|
9
|
+
*/
|
|
10
|
+
import type { NodeKind } from './instrument.js';
|
|
11
|
+
/** Every kind a graph can hold, in the order they are offered. */
|
|
12
|
+
export declare const FILTERABLE_KINDS: readonly NodeKind[];
|
|
13
|
+
export interface KindFilterOptions {
|
|
14
|
+
/** Offered, in this order. Defaults to every kind a graph can hold. */
|
|
15
|
+
kinds?: readonly NodeKind[];
|
|
16
|
+
/**
|
|
17
|
+
* Called when the selection changes. Null means every kind is on — passing a set of all
|
|
18
|
+
* nine instead would hide any kind that has no checkbox here.
|
|
19
|
+
*/
|
|
20
|
+
onChange: (kinds: NodeKind[] | null) => void;
|
|
21
|
+
/** What the button says. @default 'Kinds' */
|
|
22
|
+
label?: string;
|
|
23
|
+
panelClass?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface KindFilter {
|
|
26
|
+
/** The kinds currently on. */
|
|
27
|
+
readonly selected: readonly NodeKind[];
|
|
28
|
+
/** Set from outside, e.g. a host restoring the last used selection. */
|
|
29
|
+
select(kinds: Iterable<NodeKind> | null): void;
|
|
30
|
+
destroy(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Builds the control inside `host`. Call `destroy` to remove it — it holds a document
|
|
34
|
+
* listener for closing the panel on an outside click.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createKindFilter(host: HTMLElement, options: KindFilterOptions): KindFilter;
|
|
37
|
+
export declare const KIND_FILTER_CSS = "\n.fx-kinds { position: relative; display: inline-flex; }\n.fx-kinds-button { white-space: nowrap; }\n/* The hidden attribute is display:none from the user agent, which a class setting display outranks. */\n.fx-kinds-panel[hidden] { display: none; }\n.fx-kinds-panel {\n position: absolute; top: calc(100% + 4px); z-index: 40;\n display: grid; gap: 2px; padding: 6px 8px; min-width: 132px;\n background: var(--fx-panel, #14161c);\n border: 1px solid var(--fx-line, #262a35); border-radius: 6px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, .38);\n }\n.fx-kinds-panel:not(.fx-panel-left){ right: 0; }\n.fx-kinds-panel.fx-panel-left { left: 0; }\n.fx-kinds-panel label {\n display: flex; align-items: center; gap: 6px;\n font-size: 11px; color: var(--fx-muted, #8a90a2); cursor: pointer; user-select: none;\n}\n.fx-kinds-panel label:hover { color: var(--fx-label, #e7e9ee); }\n.fx-kinds-panel input { width: 11px; height: 11px; margin: 0; accent-color: var(--fx-accent, #5eead4); }\n.fx-kinds-all {\n padding-bottom: 4px; margin-bottom: 2px;\n border-bottom: 1px solid var(--fx-line, #262a35);\n color: var(--fx-label, #e7e9ee) !important;\n}\n";
|
|
38
|
+
export declare const DROPDOWN_FILTER_CSS = "\n.fx-dropdown-btn { background-color: transparent; appearance: none; border: 1px solid var(--line-strong); outline: none; border-radius: .25rem; padding-block: .25rem; padding-inline: .875rem; font-size: .75rem; cursor: pointer }\n.fx-dropdown-btn:hover { border-color: color-mix(in oklab, var(--accent) 50%, transparent); background-color: var(--bg); }\n.fx-dropdown-caret { width: 0;height: 0;border-left: .15rem solid transparent; border-right: .15rem solid transparent; border-top: .15rem solid currentColor; transition: transform 0.2s ease; right: .4rem; top: 50%; color: color-mix(in oklab, var(--muted) 50%, transparent); position: absolute; }\n";
|
|
39
|
+
//# sourceMappingURL=kind-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kind-filter.d.ts","sourceRoot":"","sources":["../src/kind-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,SAAS,QAAQ,EAG/C,CAAC;AAKF,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,KAAK,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC5B;;;OAGG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAC;IACvC,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC/C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAqH1F;AAED,eAAO,MAAM,eAAe,goCAyB3B,CAAC;AAEF,eAAO,MAAM,mBAAmB,kpBAI/B,CAAC"}
|