@expressive/inspect 0.2.0 → 0.4.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/dist/{bracket-CWa4p56P.js → bracket-BYmLIpQH.js} +2 -1
- package/dist/bracket-BYmLIpQH.js.map +1 -0
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/{inspect-FXOcmfKP.js → inspect-Cj3S6CdL.js} +115 -63
- package/dist/inspect-Cj3S6CdL.js.map +1 -0
- package/dist/{inspect-CEXzL-mC.d.ts → inspect-UHBNq02g.d.ts} +8 -8
- package/dist/install.js +1 -1
- package/dist/vite/client.js +28 -1
- package/dist/vite/client.js.map +1 -1
- package/package.json +5 -3
- package/dist/bracket-CWa4p56P.js.map +0 -1
- package/dist/inspect-FXOcmfKP.js.map +0 -1
|
@@ -30,6 +30,7 @@ function unreached(timeout, pending, missing, frames, hint = "") {
|
|
|
30
30
|
/** Resolve `address.key` to the instance `address` names - label, id, or owner path - as the `id.key` its frames carry. */
|
|
31
31
|
async function locate(remote, target) {
|
|
32
32
|
const dot = target.lastIndexOf(".");
|
|
33
|
+
if (target[dot + 1] == "_") throw new Error(`until ${target}: _ keys are unmanaged and emit no events - wait on a value instead.`);
|
|
33
34
|
const found = await remote.get(target.slice(0, dot));
|
|
34
35
|
if (!found?.$ref) throw new Error(`until ${target}: ${target.slice(0, dot)} names no State.`);
|
|
35
36
|
return `${found.$ref}.${target.slice(dot + 1)}`;
|
|
@@ -95,4 +96,4 @@ async function bracket(remote, step, wait, { until = [], timeout = SETTLE_TIMEOU
|
|
|
95
96
|
|
|
96
97
|
//#endregion
|
|
97
98
|
export { unsettled as i, tick as n, unreached as r, bracket as t };
|
|
98
|
-
//# sourceMappingURL=bracket-
|
|
99
|
+
//# sourceMappingURL=bracket-BYmLIpQH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bracket-BYmLIpQH.js","names":[],"sources":["../src/settle.ts","../src/bracket.ts"],"sourcesContent":["import type { Frame, Options } from './journal';\n\nexport const SETTLE_TIMEOUT = 1000;\n\nexport interface Act {\n /**\n * What to wait for before settling: `Type.key` / `id.key` addresses that must each see a frame after the\n * step's synchronous writes, or `{ [address]: value }` pairs that must each hold that value.\n */\n until?: string | string[] | Record<string, unknown>;\n /** Longest to wait, in ms; default 1000. */\n timeout?: number;\n /** Recording filters for this window, instead of the journal's - `{ paths: [], types: [], keys: [] }` records everything. */\n record?: Omit<Options, 'level'>;\n}\n\nexport const tick = () => new Promise((resolve) => setTimeout(resolve, 0));\n\n/** Wait a macrotask at a time until one passes with no new frame. Resolves `false` if `timeout` passes first. */\nexport async function settle(seq: () => number | Promise<number>, wait: () => unknown = tick, timeout = SETTLE_TIMEOUT) {\n const end = Date.now() + timeout;\n\n for (let last = await seq(); ; ) {\n await wait();\n\n const next = await seq();\n\n if (next === last) return true;\n if (Date.now() >= end) return false;\n\n last = next;\n }\n}\n\nexport function unsettled(timeout = SETTLE_TIMEOUT) {\n console.warn(\n `Still active after ${timeout}ms - frames may be incomplete. Narrow the recording ({ record: { types, paths, keys } }) to exclude background work, or pass { timeout }.`\n );\n}\n\n/** `until` not met within `timeout` - carries the frames recorded so far and what never arrived. */\nexport function unreached(timeout: number, pending: string[], missing: string[], frames: Frame[], hint = '') {\n const list = pending.map((address) => (missing.includes(address) ? `${address} (names no instance)` : address));\n return Object.assign(new Error(`Not reached within ${timeout}ms: ${list.join(', ')}.${hint}`), { frames, pending });\n}\n","import type { Frame, Options, Query } from './journal';\nimport { SETTLE_TIMEOUT, settle, type Act } from './settle';\n\nexport interface Remote {\n record(options?: Options): Required<Options> | Promise<Required<Options>>;\n seq(): number | Promise<number>;\n frames(query: Query): Frame[] | Promise<Frame[]>;\n get(address: string): unknown;\n}\n\n/** Resolve `address.key` to the instance `address` names - label, id, or owner path - so frames match it alone. */\n/** Resolve `address.key` to the instance `address` names - label, id, or owner path - as the `id.key` its frames carry. */\nasync function locate(remote: Remote, target: string) {\n const dot = target.lastIndexOf('.');\n\n if (target[dot + 1] == '_')\n throw new Error(`until ${target}: _ keys are unmanaged and emit no events - wait on a value instead.`);\n const found = (await remote.get(target.slice(0, dot))) as { $ref?: string } | undefined;\n\n if (!found?.$ref) throw new Error(`until ${target}: ${target.slice(0, dot)} names no State.`);\n\n return `${found.$ref}.${target.slice(dot + 1)}`;\n}\n\n/**\n * Run `step` recording values, wait for `until`, settle, and return what it produced; the prior recording is restored.\n * `local` steps run here, so activity for `until` counts once their synchronous writes flush, not once they resolve.\n */\nexport async function bracket(\n remote: Remote,\n step: () => unknown,\n wait: () => unknown,\n { until = [], timeout = SETTLE_TIMEOUT, record }: Act = {},\n local?: boolean\n) {\n const before = await remote.record();\n const since = await remote.seq();\n const window = { ...before, ...record };\n const filtered = window.types.length + window.paths.length + window.keys.length > 0;\n const values = typeof until == 'string' || Array.isArray(until) ? undefined : until;\n const addresses = values ? [] : ([] as string[]).concat(until as string | string[]);\n const paths = filtered ? [...window.paths, ...addresses.filter((address) => address.indexOf('.') === address.lastIndexOf('.'))] : [];\n\n await remote.record({ ...record, level: 'values', ...(filtered && { paths }) });\n\n try {\n const running = step();\n let from: number | undefined;\n\n if (local) {\n await undefined;\n from = await remote.seq();\n }\n\n const value = await running;\n\n from ??= await remote.seq();\n const end = Date.now() + timeout;\n const pending = new Set(values ? Object.keys(values) : addresses);\n const targets = new Map<string, string>();\n\n for (const address of addresses) targets.set(address, await locate(remote, address));\n\n if (filtered && addresses.some((address) => address.indexOf('.') !== address.lastIndexOf('.')))\n await remote.record({ paths: [...paths, ...targets.values()] });\n\n while (pending.size) {\n if (values) {\n for (const address of pending)\n if (JSON.stringify(await remote.get(address)) === JSON.stringify(values[address])) pending.delete(address);\n } else\n for (const frame of await remote.frames({ since: from }))\n for (const event of frame.events)\n for (const address of pending) if (targets.get(address) === `${event.id}.${event.key}`) pending.delete(address);\n\n if (!pending.size || Date.now() >= end) break;\n\n await wait();\n }\n\n const settled = !pending.size && (await settle(remote.seq, wait, Math.max(0, end - Date.now())));\n const missing: string[] = [];\n\n if (values)\n for (const address of pending)\n if ((await remote.get(address.slice(0, address.lastIndexOf('.')))) === undefined) missing.push(address);\n\n return { value, frames: await remote.frames({ since }), settled, pending: [...pending], missing, timeout };\n } finally {\n await remote.record(before);\n }\n}\n"],"mappings":"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"}
|
package/dist/bridge.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as Summary, E as Frame, O as Options, S as Select, k as Query, x as Act } from "./inspect-
|
|
1
|
+
import { A as Summary, E as Frame, O as Options, S as Select, k as Query, x as Act } from "./inspect-UHBNq02g.js";
|
|
2
2
|
import inspect$1 from "./index.js";
|
|
3
3
|
|
|
4
4
|
//#region src/devtools.d.ts
|
package/dist/bridge.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as unsettled, n as tick, r as unreached, t as bracket } from "./bracket-
|
|
1
|
+
import { i as unsettled, n as tick, r as unreached, t as bracket } from "./bracket-BYmLIpQH.js";
|
|
2
2
|
import { t as dispatch } from "./dispatch-Dnd88-J9.js";
|
|
3
3
|
|
|
4
4
|
//#region src/devtools.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { A as Summary, C as parsePath, D as Level, E as Frame, O as Options, S as Select, T as Event, _ as tree, a as act, b as resolve, c as detach, d as health, f as instances, g as set, h as roots, i as Node, k as Query, l as find, m as orphans, n as Instance, o as attach, p as models, r as Model, s as call, t as Health, u as get, v as TypeInfo, w as serialize, x as Act, y as label } from "./inspect-
|
|
1
|
+
import { A as Summary, C as parsePath, D as Level, E as Frame, O as Options, S as Select, T as Event, _ as tree, a as act, b as resolve, c as detach, d as health, f as instances, g as set, h as roots, i as Node, k as Query, l as find, m as orphans, n as Instance, o as attach, p as models, r as Model, s as call, t as Health, u as get, v as TypeInfo, w as serialize, x as Act, y as label } from "./inspect-UHBNq02g.js";
|
|
2
2
|
|
|
3
3
|
//#region src/index.d.ts
|
|
4
4
|
declare const journal: {
|
|
5
|
-
record(options?: Options): Required<Options>;
|
|
6
5
|
clear(): void;
|
|
6
|
+
record(options?: Options): Required<Options>;
|
|
7
7
|
frames(query?: Query): Frame[];
|
|
8
8
|
history(query: Query): Array<{
|
|
9
9
|
seq: number;
|
|
@@ -14,6 +14,7 @@ declare const journal: {
|
|
|
14
14
|
seq(): number;
|
|
15
15
|
export(query?: Query): string;
|
|
16
16
|
summary(query?: Query): Summary[];
|
|
17
|
+
hot(key: string, value?: unknown): void;
|
|
17
18
|
reset(): void;
|
|
18
19
|
};
|
|
19
20
|
declare const inspect: {
|
|
@@ -33,8 +34,8 @@ declare const inspect: {
|
|
|
33
34
|
label: typeof label;
|
|
34
35
|
resolve: typeof resolve;
|
|
35
36
|
journal: {
|
|
36
|
-
record(options?: Options): Required<Options>;
|
|
37
37
|
clear(): void;
|
|
38
|
+
record(options?: Options): Required<Options>;
|
|
38
39
|
frames(query?: Query): Frame[];
|
|
39
40
|
history(query: Query): Array<{
|
|
40
41
|
seq: number;
|
|
@@ -45,6 +46,7 @@ declare const inspect: {
|
|
|
45
46
|
seq(): number;
|
|
46
47
|
export(query?: Query): string;
|
|
47
48
|
summary(query?: Query): Summary[];
|
|
49
|
+
hot(key: string, value?: unknown): void;
|
|
48
50
|
reset(): void;
|
|
49
51
|
};
|
|
50
52
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as label, a as clearCaught, b as serialize, c as get, d as models, f as orphans, g as journal$1, h as tree, i as call, l as health, m as set, n as act, o as detach, p as roots, r as attach, s as find, t as Instance, u as instances, v as resolve, y as parsePath } from "./inspect-Cj3S6CdL.js";
|
|
2
2
|
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
const journal = {
|
|
5
5
|
...journal$1,
|
|
6
|
-
record(options) {
|
|
7
|
-
const config = journal$1.record(options);
|
|
8
|
-
if (config.calls && config.level !== "off") wrapAll();
|
|
9
|
-
return config;
|
|
10
|
-
},
|
|
11
6
|
clear() {
|
|
12
7
|
journal$1.clear();
|
|
13
8
|
clearCaught();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["base"],"sources":["../src/index.ts"],"sourcesContent":["import { act, attach, call, clearCaught, detach, find, get, health, Instance, instances, models, orphans, roots, set, tree
|
|
1
|
+
{"version":3,"file":"index.js","names":["base"],"sources":["../src/index.ts"],"sourcesContent":["import { act, attach, call, clearCaught, detach, find, get, health, Instance, instances, models, orphans, roots, set, tree } from './inspect';\nimport { journal as base } from './journal';\nimport { label, resolve } from './types';\n\nexport type { Health, Model, Node } from './inspect';\nexport type { Event, Frame, Level, Options, Query, Summary } from './journal';\nexport type { Act } from './settle';\nexport type { Select } from './serialize';\nexport type { TypeInfo } from './types';\nexport { Instance, act, attach, call, detach, find, get, health, instances, label, models, orphans, resolve, roots, set, tree };\nexport { parsePath, serialize } from './serialize';\n\nexport const journal = {\n ...base,\n clear() {\n base.clear();\n clearCaught();\n }\n};\n\nexport const inspect = {\n attach,\n detach,\n find,\n instances,\n roots,\n orphans,\n health,\n models,\n tree,\n get,\n set,\n call,\n act,\n label,\n resolve,\n journal\n};\n\ndeclare global {\n var __EXPRESSIVE_INSPECT__: typeof inspect | undefined;\n}\n\nexport default inspect;\n"],"mappings":";;;AAYA,MAAa,UAAU;CACrB,GAAGA;CACH,QAAQ;AACN,YAAK,OAAO;AACZ,eAAa;;CAEhB;AAED,MAAa,UAAU;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { i as unsettled, n as tick, r as unreached, t as bracket } from "./bracket-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { i as unsettled, n as tick, r as unreached, t as bracket } from "./bracket-BYmLIpQH.js";
|
|
2
|
+
import { Context, State, unbind } from "@expressive/mvc";
|
|
3
|
+
import { listener } from "@expressive/mvc/observable";
|
|
4
|
+
import { isElement } from "@expressive/mvc/jsx-runtime";
|
|
4
5
|
|
|
5
6
|
//#region src/serialize.ts
|
|
6
7
|
const MAX_STRING = 240;
|
|
@@ -25,7 +26,7 @@ function walk(value, path) {
|
|
|
25
26
|
let cur = value;
|
|
26
27
|
for (const part of path.split(".")) {
|
|
27
28
|
if (cur == null || typeof cur !== "object") return void 0;
|
|
28
|
-
if (cur instanceof State) cur = entries(cur).get(part);
|
|
29
|
+
if (cur instanceof State) cur = part[0] == "_" ? Object.getOwnPropertyDescriptor(cur, part)?.get?.() : entries(cur).get(part);
|
|
29
30
|
else if (cur instanceof Map) cur = cur.get(part);
|
|
30
31
|
else cur = cur[part];
|
|
31
32
|
}
|
|
@@ -210,6 +211,7 @@ const journal = {
|
|
|
210
211
|
summary(query = {}) {
|
|
211
212
|
const by = /* @__PURE__ */ new Map();
|
|
212
213
|
for (const frame of journal.frames(query)) for (const event of frame.events) {
|
|
214
|
+
if (!event.id) continue;
|
|
213
215
|
let entry = by.get(event.id);
|
|
214
216
|
if (!entry) by.set(event.id, entry = {
|
|
215
217
|
id: event.id,
|
|
@@ -218,12 +220,14 @@ const journal = {
|
|
|
218
220
|
keys: {},
|
|
219
221
|
calls: {},
|
|
220
222
|
caught: 0,
|
|
223
|
+
hot: 0,
|
|
221
224
|
destroyed: false
|
|
222
225
|
});
|
|
223
226
|
entry.last = frame.seq;
|
|
224
227
|
if (event.kind === "destroy") entry.destroyed = true;
|
|
225
228
|
else if (event.kind === "call") entry.calls[event.key] = (entry.calls[event.key] || 0) + 1;
|
|
226
229
|
else if (event.kind === "caught") entry.caught++;
|
|
230
|
+
else if (event.kind === "hot") entry.hot++;
|
|
227
231
|
else {
|
|
228
232
|
const key = entry.keys[event.key] ||= { count: 0 };
|
|
229
233
|
key.count++;
|
|
@@ -232,6 +236,17 @@ const journal = {
|
|
|
232
236
|
}
|
|
233
237
|
return [...by.values()].sort((a, b) => b.last - a.last);
|
|
234
238
|
},
|
|
239
|
+
hot(key, value) {
|
|
240
|
+
if (config.level === "off") return;
|
|
241
|
+
const event = {
|
|
242
|
+
id: "",
|
|
243
|
+
type: "vite",
|
|
244
|
+
key,
|
|
245
|
+
kind: "hot"
|
|
246
|
+
};
|
|
247
|
+
if (value !== void 0) event.value = value;
|
|
248
|
+
push(event);
|
|
249
|
+
},
|
|
235
250
|
clear() {
|
|
236
251
|
frames.length = 0;
|
|
237
252
|
open = void 0;
|
|
@@ -298,13 +313,12 @@ function noteCall(state, key, args) {
|
|
|
298
313
|
if (config.level === "values") event.args = args.map((arg) => serialize(arg, 1));
|
|
299
314
|
push(event);
|
|
300
315
|
}
|
|
301
|
-
function noteCaught(error,
|
|
302
|
-
const { state, key } = error;
|
|
316
|
+
function noteCaught(state, error, kind, key) {
|
|
303
317
|
if (!wants(state, key)) return;
|
|
304
318
|
const value = {
|
|
305
|
-
case:
|
|
306
|
-
message: error.message,
|
|
307
|
-
stack: error.stack,
|
|
319
|
+
case: kind,
|
|
320
|
+
message: error instanceof Error ? error.message : String(error),
|
|
321
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
308
322
|
handled: true
|
|
309
323
|
};
|
|
310
324
|
push({
|
|
@@ -316,6 +330,14 @@ function noteCaught(error, name) {
|
|
|
316
330
|
});
|
|
317
331
|
return value;
|
|
318
332
|
}
|
|
333
|
+
function notePatch(state) {
|
|
334
|
+
if (wants(state)) push({
|
|
335
|
+
id: String(state),
|
|
336
|
+
type: labelOf(state.constructor),
|
|
337
|
+
key: "patch",
|
|
338
|
+
kind: "hot"
|
|
339
|
+
});
|
|
340
|
+
}
|
|
319
341
|
function noteDestroy(state) {
|
|
320
342
|
if (!wants(state)) return;
|
|
321
343
|
push({
|
|
@@ -356,15 +378,8 @@ const Reaper = typeof FinalizationRegistry === "function" ? FinalizationRegistry
|
|
|
356
378
|
const weak = (state) => typeof WeakRef === "function" ? new WeakRef(state) : { deref: () => state };
|
|
357
379
|
const live = /* @__PURE__ */ new Map();
|
|
358
380
|
const hooks = /* @__PURE__ */ new Map();
|
|
359
|
-
const CASES = [
|
|
360
|
-
"Destroyed",
|
|
361
|
-
"Inactive",
|
|
362
|
-
"Getter",
|
|
363
|
-
"Init",
|
|
364
|
-
"Effect"
|
|
365
|
-
];
|
|
366
381
|
const COPIES = Symbol.for("@expressive/mvc");
|
|
367
|
-
const
|
|
382
|
+
const REFRESH = Symbol.for("@expressive/mvc.refresh");
|
|
368
383
|
const wrappers = /* @__PURE__ */ new WeakMap();
|
|
369
384
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
370
385
|
const reaper = new Reaper(collected);
|
|
@@ -376,24 +391,27 @@ let copies = 1;
|
|
|
376
391
|
let unwatch;
|
|
377
392
|
function counts() {
|
|
378
393
|
return {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
394
|
+
dead: 0,
|
|
395
|
+
unused: 0,
|
|
396
|
+
getter: 0,
|
|
397
|
+
setup: 0,
|
|
398
|
+
effect: 0
|
|
384
399
|
};
|
|
385
400
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
401
|
+
/** The report `observe` last saw - the chain is synchronous, so `unhandled` checks it against its own. */
|
|
402
|
+
let last;
|
|
403
|
+
function observe(error, kind, key) {
|
|
404
|
+
tally[kind]++;
|
|
405
|
+
last = {
|
|
406
|
+
error,
|
|
407
|
+
event: noteCaught(this, error, kind, key)
|
|
408
|
+
};
|
|
391
409
|
return error;
|
|
392
410
|
}
|
|
393
|
-
function unhandled(error) {
|
|
394
|
-
if (
|
|
395
|
-
|
|
396
|
-
|
|
411
|
+
function unhandled(error, kind, key) {
|
|
412
|
+
if (last?.error !== error) observe.call(this, error, kind, key);
|
|
413
|
+
if (last.event) last.event.handled = false;
|
|
414
|
+
last = void 0;
|
|
397
415
|
return error;
|
|
398
416
|
}
|
|
399
417
|
function clearCaught() {
|
|
@@ -424,7 +442,7 @@ function registered() {
|
|
|
424
442
|
}
|
|
425
443
|
/** Instances on the mainline: claimed, or too young to judge, or every one when no host renders. */
|
|
426
444
|
function* mainline() {
|
|
427
|
-
const parents =
|
|
445
|
+
const parents = reach();
|
|
428
446
|
for (const state of registered()) if (!orphaned(state, parents)) yield state;
|
|
429
447
|
}
|
|
430
448
|
function orphaned(state, parents, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -496,7 +514,7 @@ var Instance = class Instance {
|
|
|
496
514
|
}
|
|
497
515
|
/** Reached by a host commit (`mount`), a claimed owner, or `static global`. Always true without a host. */
|
|
498
516
|
get claimed() {
|
|
499
|
-
return !orphaned(this.state,
|
|
517
|
+
return !orphaned(this.state, reach());
|
|
500
518
|
}
|
|
501
519
|
/** Registration time (ms). */
|
|
502
520
|
get since() {
|
|
@@ -557,7 +575,11 @@ function attach(Type = State) {
|
|
|
557
575
|
if (!hooks.has(Type)) {
|
|
558
576
|
const observed = /* @__PURE__ */ new Map();
|
|
559
577
|
const stopCatch = Type.on({ catch: unhandled });
|
|
560
|
-
const
|
|
578
|
+
const stopCall = Type.on({
|
|
579
|
+
type: trace,
|
|
580
|
+
method: retrace
|
|
581
|
+
});
|
|
582
|
+
const stopSetup = Type.on({ setup() {
|
|
561
583
|
const self = this.is;
|
|
562
584
|
const T = self.constructor;
|
|
563
585
|
const id = String(self);
|
|
@@ -575,8 +597,8 @@ function attach(Type = State) {
|
|
|
575
597
|
span.settled = true;
|
|
576
598
|
}, 0);
|
|
577
599
|
version++;
|
|
578
|
-
if (recordsCalls()) wrap(self);
|
|
579
600
|
mounts(self);
|
|
601
|
+
const unpatch = listener(self, () => notePatch(self), REFRESH);
|
|
580
602
|
const stop = self.set((key) => {
|
|
581
603
|
const store = entries(self);
|
|
582
604
|
if (typeof key === "string" && typeof store.get(key) === "object") version++;
|
|
@@ -584,16 +606,18 @@ function attach(Type = State) {
|
|
|
584
606
|
});
|
|
585
607
|
return () => {
|
|
586
608
|
stop();
|
|
609
|
+
unpatch();
|
|
587
610
|
live.delete(id);
|
|
588
611
|
reaper.unregister(self);
|
|
589
612
|
span.until = Date.now();
|
|
590
613
|
version++;
|
|
591
614
|
noteDestroy(self);
|
|
592
615
|
};
|
|
593
|
-
});
|
|
616
|
+
} });
|
|
594
617
|
hooks.set(Type, () => {
|
|
595
618
|
for (const stop of observed.values()) stop();
|
|
596
619
|
stopCatch();
|
|
620
|
+
stopCall();
|
|
597
621
|
stopSetup();
|
|
598
622
|
});
|
|
599
623
|
}
|
|
@@ -640,7 +664,7 @@ function orphans() {
|
|
|
640
664
|
return [...abandoned()].map(Instance.of);
|
|
641
665
|
}
|
|
642
666
|
function* abandoned() {
|
|
643
|
-
const parents =
|
|
667
|
+
const parents = reach();
|
|
644
668
|
for (const state of registered()) if (orphaned(state, parents)) yield state;
|
|
645
669
|
}
|
|
646
670
|
/** Counts worth a look before trusting what inspect shows. */
|
|
@@ -710,8 +734,36 @@ async function call(address, ...args) {
|
|
|
710
734
|
if (typeof method !== "function") throw new Error(`No method at ${address}.`);
|
|
711
735
|
return serialize(await method.apply(state, args));
|
|
712
736
|
}
|
|
713
|
-
|
|
714
|
-
|
|
737
|
+
const TRACED = /* @__PURE__ */ new WeakSet();
|
|
738
|
+
/** Wrap a class's own methods before they bind, so each call is recorded. */
|
|
739
|
+
function trace(type) {
|
|
740
|
+
const proto = type.prototype;
|
|
741
|
+
for (const [key, desc] of Object.entries(Object.getOwnPropertyDescriptors(proto))) if (key != "constructor" && key != "render" && typeof desc.value == "function" && desc.configurable) proto[key] = traced(key, desc.value);
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Rebind a method replaced through `set()` to a traced copy, so `unbind` still yields a function honoring `this`.
|
|
745
|
+
* A class bootstrapped before attach keeps its methods untraced - wrapped per instance, a hot patch would keep them.
|
|
746
|
+
*/
|
|
747
|
+
function retrace(key, fn) {
|
|
748
|
+
const source = unbind(fn);
|
|
749
|
+
let proto = Object.getPrototypeOf(this);
|
|
750
|
+
while (!Object.prototype.hasOwnProperty.call(proto, key)) proto = Object.getPrototypeOf(proto);
|
|
751
|
+
if (key == "render" || TRACED.has(source) || source === unbind(Object.getOwnPropertyDescriptor(proto, key).get)) return;
|
|
752
|
+
const self = this;
|
|
753
|
+
delete self[key];
|
|
754
|
+
self[key] = traced(key, source);
|
|
755
|
+
}
|
|
756
|
+
/** A `super` call reaches the base wrapper too; only the one `this[key]` resolves to records. */
|
|
757
|
+
function traced(key, fn) {
|
|
758
|
+
const wrapper = Object.defineProperties(function(...args) {
|
|
759
|
+
if (unbind(this[key]) === wrapper) noteCall(this, key, args);
|
|
760
|
+
return fn.apply(this, args);
|
|
761
|
+
}, {
|
|
762
|
+
name: { value: fn.name },
|
|
763
|
+
length: { value: fn.length }
|
|
764
|
+
});
|
|
765
|
+
TRACED.add(wrapper);
|
|
766
|
+
return wrapper;
|
|
715
767
|
}
|
|
716
768
|
/** Observe the host commit: adapters call `mount?.()` once an instance is placed. */
|
|
717
769
|
function mounts(state) {
|
|
@@ -739,41 +791,41 @@ function describe(state, parents) {
|
|
|
739
791
|
if (parent) model.parent = String(parent);
|
|
740
792
|
return model;
|
|
741
793
|
}
|
|
742
|
-
|
|
743
|
-
if (wrapped.has(state)) return;
|
|
744
|
-
wrapped.add(state);
|
|
745
|
-
const target = state;
|
|
746
|
-
const seenKeys = new Set(["render"]);
|
|
747
|
-
for (let proto = Object.getPrototypeOf(state); proto !== State.prototype; proto = Object.getPrototypeOf(proto)) for (const [key, desc] of Object.entries(Object.getOwnPropertyDescriptors(proto))) {
|
|
748
|
-
if (seenKeys.has(key) || typeof desc.get !== "function" || desc.get !== desc.set) continue;
|
|
749
|
-
seenKeys.add(key);
|
|
750
|
-
const original = target[key];
|
|
751
|
-
target[key] = function(...args) {
|
|
752
|
-
noteCall(state, key, args);
|
|
753
|
-
return original.apply(this, args);
|
|
754
|
-
};
|
|
755
|
-
}
|
|
756
|
-
}
|
|
794
|
+
/** Each instance's owner, from mvc. */
|
|
757
795
|
function ownership() {
|
|
796
|
+
return graph().owners;
|
|
797
|
+
}
|
|
798
|
+
/** Owner, else the first instance holding it - what keeps an instance from being abandoned. */
|
|
799
|
+
function reach() {
|
|
800
|
+
return graph().holders;
|
|
801
|
+
}
|
|
802
|
+
function graph() {
|
|
758
803
|
if (cached?.version !== version) {
|
|
759
|
-
const
|
|
760
|
-
|
|
804
|
+
const owners = /* @__PURE__ */ new Map();
|
|
805
|
+
const holders = /* @__PURE__ */ new Map();
|
|
806
|
+
for (const state of registered()) {
|
|
807
|
+
const owner = state.get(State, false);
|
|
808
|
+
if (owner) owners.set(state, owner);
|
|
809
|
+
for (const [key, value] of entries(state)) if (Object.getOwnPropertyDescriptor(state, key)?.enumerable || !(value instanceof State)) hold(holders, state, value);
|
|
810
|
+
}
|
|
811
|
+
for (const [state, owner] of owners) holders.set(state, owner);
|
|
761
812
|
cached = {
|
|
762
813
|
version,
|
|
763
|
-
|
|
814
|
+
owners,
|
|
815
|
+
holders
|
|
764
816
|
};
|
|
765
817
|
}
|
|
766
|
-
return cached
|
|
818
|
+
return cached;
|
|
767
819
|
}
|
|
768
|
-
function
|
|
820
|
+
function hold(holders, holder, value) {
|
|
769
821
|
if (value instanceof State) {
|
|
770
|
-
if (!
|
|
822
|
+
if (!holders.has(value) && value !== holder) holders.set(value, holder);
|
|
771
823
|
} else if (value && typeof value === "object" && Symbol.iterator in value) {
|
|
772
824
|
const items = value instanceof Map ? value.values() : value;
|
|
773
|
-
for (const item of items) if (item instanceof State)
|
|
825
|
+
for (const item of items) if (item instanceof State) hold(holders, holder, item);
|
|
774
826
|
}
|
|
775
827
|
}
|
|
776
828
|
|
|
777
829
|
//#endregion
|
|
778
|
-
export {
|
|
779
|
-
//# sourceMappingURL=inspect-
|
|
830
|
+
export { label as _, clearCaught as a, serialize as b, get as c, models as d, orphans as f, journal as g, tree as h, call as i, health as l, set as m, act as n, detach as o, roots as p, attach as r, find as s, Instance as t, instances as u, resolve as v, parsePath as y };
|
|
831
|
+
//# sourceMappingURL=inspect-Cj3S6CdL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-Cj3S6CdL.js","names":[],"sources":["../src/serialize.ts","../src/types.ts","../src/journal.ts","../src/inspect.ts"],"sourcesContent":["import { State } from '@expressive/mvc';\n\nconst MAX_STRING = 240;\nconst MAX_ARRAY = 24;\nconst MAX_KEYS = 40;\n\nexport type Address = { target: string; path?: string };\n\nexport function parsePath(raw: string): Address {\n const trimmed = raw.trim();\n const dot = trimmed.indexOf('.');\n if (dot <= 0) return { target: trimmed };\n return { target: trimmed.slice(0, dot), path: trimmed.slice(dot + 1) };\n}\n\n/** Raw stored entries of a State - never reads through accessors. */\nexport function entries(state: State): Map<string, unknown> {\n return new Map(state);\n}\n\n/** Walk `path` without triggering getters, factories, or suspense. */\nexport function walk(value: unknown, path?: string): unknown {\n if (!path) return value;\n let cur: unknown = value;\n for (const part of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined;\n if (cur instanceof State)\n cur = part[0] == '_' ? Object.getOwnPropertyDescriptor(cur, part)?.get?.() : entries(cur).get(part);\n else if (cur instanceof Map) cur = cur.get(part);\n else cur = (cur as Record<string, unknown>)[part];\n }\n return cur;\n}\n\nexport function ref(state: State) {\n return { $ref: String(state), $type: state.constructor.name };\n}\n\n/** `true` takes a value as `serialize` would; an object picks keys and descends, applying to each element of a list. */\nexport type Select = true | { [key: string]: Select };\n\n/** Only the selected keys, read in one synchronous pass - a consistent snapshot. States keep their `$ref`. */\nexport function project(value: unknown, select: Select): unknown {\n if (select === true || value == null || typeof value !== 'object') return serialize(value);\n\n const items = value instanceof State ? undefined : list(value);\n\n if (items) {\n const out = items.slice(0, MAX_ARRAY).map((row) => project(row, select));\n if (items.length > MAX_ARRAY) out.push(`…+${items.length - MAX_ARRAY}`);\n return out;\n }\n\n const out: Record<string, unknown> = value instanceof State ? ref(value) : {};\n for (const key in select) out[key] = project(walk(value, key), select[key]);\n return out;\n}\n\n/** JSON-safe, size-capped view. Nested States collapse to `$ref`. */\nexport function serialize(value: unknown, depth = 2): unknown {\n if (value instanceof State) {\n const out: Record<string, unknown> = ref(value);\n for (const [key, child] of [...entries(value)].slice(0, MAX_KEYS))\n out[key] = write(child, depth - 1);\n return out;\n }\n return write(value, depth);\n}\n\nfunction write(value: unknown, depth: number): unknown {\n if (value == null || typeof value === 'boolean') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value);\n if (typeof value === 'string')\n return value.length > MAX_STRING ? `${value.slice(0, MAX_STRING - 1)}…` : value;\n if (typeof value === 'bigint') return `${value}n`;\n if (typeof value !== 'object') return undefined;\n if (value instanceof State) return ref(value);\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Error) return { name: value.name, message: value.message };\n if (typeof (value as PromiseLike<unknown>).then === 'function') return '(pending)';\n\n const items = list(value);\n\n if (items) {\n if (depth <= 0) return `[${items.length}]`;\n const out = items.slice(0, MAX_ARRAY).map((row) => write(row, depth - 1));\n if (items.length > MAX_ARRAY) out.push(`…+${items.length - MAX_ARRAY}`);\n return out;\n }\n\n const pairs = value instanceof Map\n ? [...value].map(([k, v]) => [String(k), v] as const)\n : Object.entries(value);\n\n if (depth <= 0) return `{${pairs.length}}`;\n\n const out: Record<string, unknown> = {};\n for (const [key, child] of pairs.slice(0, MAX_KEYS)) {\n if (key === 'is') continue;\n const next = write(child, depth - 1);\n if (next !== undefined) out[key] = next;\n }\n if (pairs.length > MAX_KEYS) out['…'] = pairs.length - MAX_KEYS;\n return out;\n}\n\nfunction list(value: object): unknown[] | undefined {\n if (Array.isArray(value)) return value;\n if (value instanceof Map) return undefined;\n if (typeof (value as Iterable<unknown>)[Symbol.iterator] === 'function')\n return [...(value as Iterable<unknown>)];\n return undefined;\n}\n","import { State } from '@expressive/mvc';\n\nexport interface TypeInfo {\n /** Opaque, stable for the life of the process. */\n typeId: string;\n /** Resolved display name - see `label`. */\n type: string;\n /** Construction stack captured at first sight, for a source-map resolver. */\n site: string;\n}\n\nconst info = new Map<typeof State, TypeInfo>();\nconst labels = new Map<typeof State, string>();\nconst names = new Map<string, string>();\nlet count = 0;\n\nfunction register(Type: typeof State): TypeInfo {\n let row = info.get(Type);\n if (!row) {\n const site = String(new Error().stack).split('\\n').slice(1, 16).join('\\n');\n info.set(Type, (row = { typeId: `T${++count}`, type: '', site }));\n }\n return row;\n}\n\nexport function seen(Type: typeof State): TypeInfo {\n const row = register(Type);\n row.type = labelOf(Type);\n return { ...row };\n}\n\nexport function labelOf(Type: typeof State): string {\n const row = register(Type);\n const explicit = labels.get(Type) ?? (Type as { displayName?: string }).displayName;\n if (explicit) return explicit;\n const named = names.get(row.typeId) ?? names.get(row.site);\n if (named) return named;\n return Type.name.length > 2 ? Type.name : row.typeId;\n}\n\nexport function label(Type: typeof State, name: string): void {\n labels.set(Type, name);\n}\n\n/** Supply resolved names keyed by `typeId` or `site`, e.g. from a source-map pass. */\nexport function resolve(table: Record<string, string>): void {\n for (const [key, name] of Object.entries(table)) names.set(key, name);\n}\n\nexport function forget(): void {\n info.clear();\n labels.clear();\n names.clear();\n count = 0;\n}\n","import { State } from '@expressive/mvc';\n\nimport { parsePath, serialize } from './serialize';\nimport { labelOf, seen } from './types';\n\nexport type Level = 'off' | 'keys' | 'values';\n\nexport interface Options {\n level?: Level;\n /** Labels to record. */\n types?: string[];\n /** `Type.key` addresses to record - label, `typeId`, or instance id on the left, property on the right. */\n paths?: string[];\n /** Property names to record on any type. */\n keys?: string[];\n /** Also record method calls, except `render`. */\n calls?: boolean;\n}\n\nexport interface Event {\n id: string;\n type: string;\n key: string;\n kind: 'update' | 'event' | 'call' | 'destroy' | 'caught' | 'hot';\n value?: unknown;\n args?: unknown[];\n}\n\nexport interface Frame {\n seq: number;\n at: number;\n /** Frame whose flush scheduled the work that opened this one. */\n cause?: number;\n events: Event[];\n}\n\nexport interface Summary {\n id: string;\n type: string;\n /** Seq of the last frame touching this instance. */\n last: number;\n /** Updates and events per key, with the last recorded value at `values` level. */\n keys: Record<string, { count: number; value?: unknown }>;\n calls: Record<string, number>;\n /** `caught` reports. */\n caught: number;\n /** Hot patches applied to it. */\n hot: number;\n destroyed: boolean;\n}\n\nexport interface Query {\n since?: number;\n type?: string;\n id?: string;\n key?: string;\n cause?: number;\n}\n\nconst FRAME_CAP = 500;\n\nconst frames: Frame[] = [];\nconst config: Required<Options> = { level: 'off', types: [], paths: [], keys: [], calls: false };\nlet seq = 0;\nlet open: Frame | undefined;\nlet cause: number | undefined;\n\nexport const journal = {\n record(options: Options = {}): Required<Options> {\n Object.assign(config, options);\n if (!options.level && options.calls && config.level === 'off') config.level = 'keys';\n return { ...config, types: [...config.types], paths: [...config.paths], keys: [...config.keys] };\n },\n\n frames(query: Query = {}): Frame[] {\n const out: Frame[] = [];\n for (const frame of frames) {\n if (query.since !== undefined && frame.seq <= query.since) continue;\n if (query.cause !== undefined && frame.cause !== query.cause) continue;\n const events = frame.events.filter((e) => matches(e, query));\n if (events.length) out.push({ ...frame, events });\n }\n return out;\n },\n\n history(query: Query): Array<{ seq: number; at: number; event: Event }> {\n const out = [];\n for (const frame of journal.frames(query))\n for (const event of frame.events) out.push({ seq: frame.seq, at: frame.at, event });\n return out;\n },\n\n /** Frames reachable from `seq` through `cause` links, in order. */\n downstream(from: number): Frame[] {\n const roots = new Set([from]);\n return frames.filter((frame) => {\n if (frame.cause === undefined || !roots.has(frame.cause)) return false;\n roots.add(frame.seq);\n return true;\n });\n },\n\n /** Current sequence - pass as `since` to read only what follows. */\n seq(): number {\n return seq;\n },\n\n /** One event per line, for bulk export to a sidecar. */\n export(query: Query = {}): string {\n return journal\n .frames(query)\n .flatMap((frame) =>\n frame.events.map((event) =>\n JSON.stringify({ seq: frame.seq, at: frame.at, cause: frame.cause, ...event })\n )\n )\n .join('\\n');\n },\n\n /** Per-instance digest of recorded frames, most recently active first. */\n summary(query: Query = {}): Summary[] {\n const by = new Map<string, Summary>();\n\n for (const frame of journal.frames(query))\n for (const event of frame.events) {\n if (!event.id) continue;\n\n let entry = by.get(event.id);\n\n if (!entry) by.set(event.id, (entry = { id: event.id, type: event.type, last: 0, keys: {}, calls: {}, caught: 0, hot: 0, destroyed: false }));\n\n entry.last = frame.seq;\n\n if (event.kind === 'destroy') entry.destroyed = true;\n else if (event.kind === 'call') entry.calls[event.key] = (entry.calls[event.key] || 0) + 1;\n else if (event.kind === 'caught') entry.caught++;\n else if (event.kind === 'hot') entry.hot++;\n else {\n const key = (entry.keys[event.key] ||= { count: 0 });\n key.count++;\n if ('value' in event) key.value = event.value;\n }\n }\n\n return [...by.values()].sort((a, b) => b.last - a.last);\n },\n\n /**\n * Record a page-level hot update: `key` names it (`update`, `reload`), `value`\n * its detail. Recorded unfiltered while the journal is on.\n */\n hot(key: string, value?: unknown): void {\n if (config.level === 'off') return;\n\n const event: Event = { id: '', type: 'vite', key, kind: 'hot' };\n if (value !== undefined) event.value = value;\n push(event);\n },\n\n clear(): void {\n frames.length = 0;\n open = undefined;\n cause = undefined;\n seq = 0;\n },\n\n reset(): void {\n journal.clear();\n Object.assign(config, { level: 'off', types: [], paths: [], keys: [], calls: false });\n }\n};\n\nfunction matches(event: Event, query: Query) {\n return (\n (!query.type || event.type === query.type) &&\n (!query.id || event.id === query.id) &&\n (!query.key || event.key === query.key)\n );\n}\n\n/** Filters OR together; none set records everything. Without a key only type-level filters apply. */\nexport function wants(state: State, key?: string): boolean {\n if (config.level === 'off') return false;\n\n const { types, paths, keys } = config;\n if (!types.length && !paths.length && !keys.length) return true;\n\n const Type = state.constructor as typeof State;\n const label = labelOf(Type);\n if (types.includes(label)) return true;\n if (key !== undefined && keys.includes(key)) return true;\n\n const targets = [label, seen(Type).typeId, String(state)];\n for (const address of paths) {\n const { target, path } = parsePath(address);\n if (targets.includes(target) && (key === undefined || path === key)) return true;\n }\n return false;\n}\n\nexport function recordsCalls(): boolean {\n return config.calls && config.level !== 'off';\n}\n\n\nexport function note(state: State, key: unknown, store: Map<string, unknown>): void {\n const name = String(key);\n if (!wants(state, name)) return;\n\n const event: Event = {\n id: String(state),\n type: labelOf(state.constructor as typeof State),\n key: name,\n kind: typeof key === 'string' && store.has(key) ? 'update' : 'event'\n };\n\n if (config.level === 'values' && event.kind === 'update')\n event.value = serialize(store.get(name), 1);\n\n push(event);\n}\n\nexport function noteCall(state: State, key: string, args: unknown[]): void {\n if (!recordsCalls() || !wants(state, key)) return;\n\n const event: Event = { id: String(state), type: labelOf(state.constructor as typeof State), key, kind: 'call' };\n if (config.level === 'values') event.args = args.map((arg) => serialize(arg, 1));\n push(event);\n}\n\nexport function noteCaught(state: State, error: unknown, kind: string, key?: string): { handled: boolean } | undefined {\n if (!wants(state, key)) return;\n const value = {\n case: kind,\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n handled: true\n };\n push({ id: String(state), type: labelOf(state.constructor as typeof State), key: key ?? '', kind: 'caught', value });\n return value;\n}\n\nexport function notePatch(state: State): void {\n if (wants(state)) push({ id: String(state), type: labelOf(state.constructor as typeof State), key: 'patch', kind: 'hot' });\n}\n\nexport function noteDestroy(state: State): void {\n if (!wants(state)) return;\n push({ id: String(state), type: labelOf(state.constructor as typeof State), key: '', kind: 'destroy' });\n}\n\nfunction push(event: Event) {\n if (!open) {\n const frame: Frame = { seq: ++seq, at: Date.now(), events: [] };\n if (cause !== undefined) frame.cause = cause;\n open = frame;\n frames.push(frame);\n if (frames.length > FRAME_CAP) frames.splice(0, frames.length - FRAME_CAP);\n queueMicrotask(() => {\n open = undefined;\n cause = frame.seq;\n queueMicrotask(() => {\n if (seq === frame.seq) cause = undefined;\n });\n });\n }\n open.events.push(event);\n}\n","import { Context, State, unbind } from '@expressive/mvc';\nimport { listener } from '@expressive/mvc/observable';\nimport { isElement } from '@expressive/mvc/jsx-runtime';\n\nimport { journal, note, noteCall, noteCaught, noteDestroy, notePatch, type Frame, type Query } from './journal';\nimport { entries, parsePath, project, serialize, walk, type Select } from './serialize';\nimport { bracket } from './bracket';\nimport { tick, unreached, unsettled, type Act } from './settle';\nimport { forget, seen, type TypeInfo } from './types';\n\nexport interface Model extends TypeInfo {\n id: string;\n parent?: string;\n /** Keys with a stored value. */\n keys: string[];\n /** Declared keys with no stored value yet - lazy, pending, or uncomputed. */\n absent: string[];\n}\n\nexport interface Node {\n id: string;\n type: string;\n children: Node[];\n}\n\ninterface Span {\n since: number;\n until?: number;\n claimed: boolean;\n settled: boolean;\n}\n\ninterface Row {\n ref: { deref(): State | undefined };\n held?: State;\n}\n\nconst Reaper: typeof FinalizationRegistry =\n typeof FinalizationRegistry === 'function'\n ? FinalizationRegistry\n : (class {\n register() {}\n unregister() {}\n } as unknown as typeof FinalizationRegistry);\n\nconst weak = (state: State): Row['ref'] =>\n typeof WeakRef === 'function' ? new WeakRef(state) : { deref: () => state };\n\nconst live = new Map<string, Row>();\nconst hooks = new Map<typeof State, () => void>();\n\nconst COPIES = Symbol.for('@expressive/mvc');\n\nconst REFRESH = Symbol.for('@expressive/mvc.refresh');\nconst wrappers = new WeakMap<State, Instance>();\nconst spans = new WeakMap<State, Span>();\nconst reaper = new Reaper<string>(collected);\n\nlet version = 0;\nlet cached: { version: number; owners: Map<State, State>; holders: Map<State, State> } | undefined;\nlet lost = 0;\nlet tally = counts();\nlet copies = 1;\nlet unwatch: (() => void) | undefined;\n\nfunction counts(): Record<string, number> {\n return { dead: 0, unused: 0, getter: 0, setup: 0, effect: 0 };\n}\n\n/** The report `observe` last saw - the chain is synchronous, so `unhandled` checks it against its own. */\nlet last: { error: unknown; event?: { handled: boolean } } | undefined;\n\nfunction observe(this: State, error: unknown, kind: string, key?: string) {\n tally[kind]++;\n last = { error, event: noteCaught(this, error, kind, key) };\n return error;\n}\n\nfunction unhandled(this: State, error: unknown, kind: string, key?: string) {\n if (last?.error !== error) observe.call(this, error, kind, key);\n if (last!.event) last!.event.handled = false;\n last = undefined;\n return error;\n}\n\nexport function clearCaught(): void {\n tally = counts();\n}\n\n/** Count loaded copies of mvc from the list each one joins on first construction; warn once on a second. */\nfunction watchCopies() {\n const list = ((globalThis as { [COPIES]?: unknown[] })[COPIES] ||= []);\n const { push } = list;\n const check = () => {\n const was = copies;\n copies = new Set([State, ...list]).size;\n if (copies > 1 && was === 1)\n console.warn(`${copies} copies of @expressive/mvc are loaded - inspect sees only the one it imports.`);\n };\n\n list.push = (...items) => {\n const length = push.apply(list, items);\n check();\n return length;\n };\n\n check();\n unwatch = () => {\n list.push = push;\n };\n}\n\n/** Registered instances still reachable, claimed or not. */\nfunction registered(): State[] {\n return [...live.values()]\n .map((row) => row.held ?? row.ref.deref())\n .filter((state): state is State => !!state);\n}\n\n/** Instances on the mainline: claimed, or too young to judge, or every one when no host renders. */\nfunction* mainline(): Generator<State> {\n const parents = reach();\n for (const state of registered()) if (!orphaned(state, parents)) yield state;\n}\n\nfunction orphaned(state: State, parents: Map<State, State>, seen = new Set<State>()): boolean {\n const span = spans.get(state)!;\n if (span.claimed || !span.settled || !hosted()) return false;\n if (provided(state)) {\n claim(state);\n return false;\n }\n const owner = parents.get(state);\n if (!owner || seen.has(owner)) return true;\n seen.add(state);\n if (orphaned(owner, parents, seen)) return true;\n if (spans.get(owner)!.claimed) claim(state);\n return false;\n}\n\nfunction claim(state: State) {\n const span = spans.get(state)!;\n if (span.claimed) return;\n span.claimed = true;\n const row = live.get(String(state));\n if (row) {\n row.held = state;\n reaper.unregister(state);\n }\n version++;\n}\n\n/** A `static global` instance currently holding its slot in the root context. */\nfunction provided(state: State): boolean {\n const type = state.constructor as typeof State;\n const global = typeof type.global === 'function' ? type.global(state) : type.global;\n if (!global) return false;\n for (const set of Context.root.provide.values())\n if (set) for (const [member] of set) if (member === state) return true;\n return false;\n}\n\nfunction hosted(): boolean {\n try {\n isElement(null);\n return true;\n } catch {\n return false;\n }\n}\n\n/** A registered, unclaimed instance was garbage collected - it was abandoned. */\nexport function collected(id: string): void {\n if (!live.delete(id)) return;\n lost++;\n version++;\n}\n\n/** Navigable view of one instance - identity, ownership, reads, observation. One per state; outlives it. */\nexport class Instance {\n private constructor(readonly state: State) {}\n\n static of(state: State): Instance {\n let instance = wrappers.get(state);\n if (!instance) wrappers.set(state, (instance = new Instance(state)));\n return instance;\n }\n\n get id() {\n return String(this.state);\n }\n\n get type() {\n return seen(this.state.constructor as typeof State).type;\n }\n\n get alive() {\n return live.has(this.id);\n }\n\n /** Reached by a host commit (`mount`), a claimed owner, or `static global`. Always true without a host. */\n get claimed() {\n return !orphaned(this.state, reach());\n }\n\n /** Registration time (ms). */\n get since() {\n return spans.get(this.state)!.since;\n }\n\n /** Destruction time (ms), once destroyed. */\n get until() {\n return spans.get(this.state)!.until;\n }\n\n get parent(): Instance | undefined {\n const owner = ownership().get(this.state);\n return owner && Instance.of(owner);\n }\n\n get children(): Instance[] {\n const parents = ownership();\n return [...registered()]\n .filter((state) => parents.get(state) === this.state)\n .map(Instance.of);\n }\n\n /** First instance in this subtree, depth-first, matching `where` (a label or predicate). */\n find(where: string | ((instance: Instance) => boolean)): Instance | undefined {\n const test = typeof where === 'string' ? (h: Instance) => h.type === where : where;\n for (const child of this.children) {\n if (test(child)) return child;\n const deep = child.find(test);\n if (deep) return deep;\n }\n return undefined;\n }\n\n get(path?: string, select?: Select): unknown {\n const value = walk(this.state, path);\n return select ? project(value, select) : serialize(value);\n }\n\n model(): Model {\n return describe(this.state, ownership());\n }\n\n /** Run `work`, settle, and return the frames it produced. */\n act(work: (state: State) => unknown, options?: Act): Promise<Frame[]> {\n return act(() => work(this.state), options);\n }\n\n /** Call `fn` on each update, and with `null` on destroy; `keys` narrows updates. Returns unsubscribe. */\n watch(fn: (key: string | null) => void, keys?: string[]): () => void {\n const updates = this.state.set((key) => {\n if (typeof key === 'string' && (!keys || keys.includes(key))) fn(key);\n });\n const destroy = this.state.get(null, () => fn(null));\n return () => {\n updates();\n destroy();\n };\n }\n\n frames(query: Query = {}): Frame[] {\n return journal.frames({ ...query, id: this.id });\n }\n}\n\nexport function attach(Type: typeof State = State): () => void {\n if (!unwatch) watchCopies();\n\n if (!hooks.has(Type)) {\n const observed = new Map<typeof State, () => void>();\n const stopCatch = Type.on({ catch: unhandled });\n const stopCall = Type.on({ type: trace, method: retrace });\n const stopSetup = Type.on({\n setup(this: State) {\n const self = this.is;\n const T = self.constructor as typeof State;\n const id = String(self);\n const span: Span = { since: Date.now(), claimed: false, settled: false };\n if (!observed.has(T)) observed.set(T, T.on({ catch: observe }));\n seen(T);\n live.set(id, { ref: weak(self) });\n spans.set(self, span);\n reaper.register(self, id, self);\n setTimeout(() => {\n span.settled = true;\n }, 0);\n version++;\n mounts(self);\n const unpatch = listener(self, () => notePatch(self), REFRESH);\n const stop = self.set((key) => {\n const store = entries(self);\n if (typeof key === 'string' && typeof store.get(key) === 'object') version++;\n note(self, key, store);\n });\n return () => {\n stop();\n unpatch();\n live.delete(id);\n reaper.unregister(self);\n span.until = Date.now();\n version++;\n noteDestroy(self);\n };\n }\n });\n hooks.set(Type, () => {\n for (const stop of observed.values()) stop();\n stopCatch();\n stopCall();\n stopSetup();\n });\n }\n\n return () => {\n hooks.get(Type)?.();\n hooks.delete(Type);\n };\n}\n\nexport function detach(): void {\n for (const stop of hooks.values()) stop();\n hooks.clear();\n live.clear();\n cached = undefined;\n lost = 0;\n tally = counts();\n copies = 1;\n unwatch?.();\n unwatch = undefined;\n journal.reset();\n forget();\n}\n\n/** Resolve an id or label to an instance - mainline first, then orphans. */\nexport function find(target: string): Instance | undefined {\n const byId = live.get(target);\n const held = byId && (byId.held ?? byId.ref.deref());\n if (held) return Instance.of(held);\n\n const types = new Map<typeof State, string>();\n let first: State | undefined;\n\n for (const pool of [mainline(), abandoned()])\n for (const state of pool) {\n const Type = state.constructor as typeof State;\n const info = seen(Type);\n if (info.type !== target) continue;\n first ??= state;\n types.set(Type, info.typeId);\n }\n\n if (types.size > 1)\n throw new Error(\n `${target} matches ${types.size} classes (${[...types.values()].join(', ')}) - address by instance id or owner path, or label() one. models() lists their construction sites.`\n );\n\n return first && Instance.of(first);\n}\n\nexport function instances(): Instance[] {\n return [...mainline()].map(Instance.of);\n}\n\n/** Registered and settled, but never claimed by a host commit, an owner, or root context. */\nexport function orphans(): Instance[] {\n return [...abandoned()].map(Instance.of);\n}\n\nfunction* abandoned(): Generator<State> {\n const parents = reach();\n for (const state of registered()) if (orphaned(state, parents)) yield state;\n}\n\nexport interface Health {\n /** Live instances no host, owner, or root slot claimed. */\n orphans: number;\n /** Unclaimed instances the collector already reaped. */\n collected: number;\n /** Loaded copies of `@expressive/mvc` - more than 1 means inspect cannot see every State. */\n copies: number;\n /** Reports by kind, including ones an app handler went on to handle; zeroed by `journal.clear()`. */\n caught: Record<string, number>;\n}\n\n/** Counts worth a look before trusting what inspect shows. */\nexport function health(): Health {\n return { orphans: orphans().length, collected: lost, copies, caught: { ...tally } };\n}\n\nexport function roots(): Instance[] {\n const parents = ownership();\n return instances().filter((instance) => !parents.has(instance.state));\n}\n\nexport function models(): Model[] {\n const parents = ownership();\n return [...mainline()].map((state) => describe(state, parents));\n}\n\nexport function tree(): Node[] {\n const parents = ownership();\n const nodes = new Map<State, Node>();\n const out: Node[] = [];\n\n for (const state of mainline())\n nodes.set(state, { id: String(state), type: seen(state.constructor as typeof State).type, children: [] });\n\n for (const [state, node] of nodes) {\n const parent = parents.get(state);\n const owner = parent && nodes.get(parent);\n if (owner) owner.children.push(node);\n else out.push(node);\n }\n\n return out;\n}\n\n/** Run `work` recording values; returns the frames it produced once `until` holds and activity goes quiet. */\nexport async function act(work: () => unknown, options: Act = {}): Promise<Frame[]> {\n const { frames, settled, pending, missing, timeout } = await bracket({ ...journal, get }, work, tick, options, true);\n if (pending.length) throw unreached(timeout, pending, missing, frames);\n if (!settled) unsettled(timeout);\n return frames;\n}\n\nexport function get(address?: string, select?: Select): unknown {\n if (!address) return models();\n const { target, path } = parsePath(address);\n return find(target)?.get(path, select);\n}\n\nexport function set(address: string, value: unknown): void {\n const { target, path } = parsePath(address);\n const instance = find(target);\n if (!instance || !path) throw new Error(`No model at ${address}.`);\n\n const dot = path.lastIndexOf('.');\n const key = path.slice(dot + 1);\n const owner = dot < 0 ? instance.state : walk(instance.state, path.slice(0, dot));\n\n if (owner == null || typeof owner !== 'object') throw new Error(`No model at ${address}.`);\n\n if (owner instanceof Map) owner.set(key, value);\n else (owner as Record<string, unknown>)[key] = value;\n}\n\nexport async function call(address: string, ...args: unknown[]): Promise<unknown> {\n const { target, path } = parsePath(address);\n const state = find(target)?.state;\n const method = state && path && (state as unknown as Record<string, unknown>)[path];\n\n if (typeof method !== 'function') throw new Error(`No method at ${address}.`);\n\n return serialize(await method.apply(state, args));\n}\n\nconst TRACED = new WeakSet<Function>();\n\n/** Wrap a class's own methods before they bind, so each call is recorded. */\nfunction trace(type: typeof State) {\n const proto = type.prototype as unknown as Record<string, Function>;\n\n for (const [key, desc] of Object.entries(Object.getOwnPropertyDescriptors(proto)))\n if (key != 'constructor' && key != 'render' && typeof desc.value == 'function' && desc.configurable)\n proto[key] = traced(key, desc.value);\n}\n\n/**\n * Rebind a method replaced through `set()` to a traced copy, so `unbind` still yields a function honoring `this`.\n * A class bootstrapped before attach keeps its methods untraced - wrapped per instance, a hot patch would keep them.\n */\nfunction retrace(this: State, key: string, fn: Function) {\n const source = unbind(fn);\n let proto = Object.getPrototypeOf(this);\n\n while (!Object.prototype.hasOwnProperty.call(proto, key)) proto = Object.getPrototypeOf(proto);\n\n if (key == 'render' || TRACED.has(source) || source === unbind(Object.getOwnPropertyDescriptor(proto, key)!.get!)) return;\n\n const self = this as unknown as Record<string, Function>;\n\n delete self[key];\n self[key] = traced(key, source);\n}\n\n/** A `super` call reaches the base wrapper too; only the one `this[key]` resolves to records. */\nfunction traced(key: string, fn: Function) {\n const wrapper = Object.defineProperties(\n function (this: Record<string, Function>, ...args: unknown[]) {\n if (unbind(this[key]) === wrapper) noteCall(this as unknown as State, key, args);\n return fn.apply(this, args);\n },\n { name: { value: fn.name }, length: { value: fn.length } }\n );\n\n TRACED.add(wrapper);\n\n return wrapper;\n}\n\n/** Observe the host commit: adapters call `mount?.()` once an instance is placed. */\nfunction mounts(state: State) {\n const target = state as State & { mount?: (...args: unknown[]) => unknown };\n const original = target.mount;\n\n Object.defineProperty(target, 'mount', {\n configurable: true,\n writable: true,\n value(this: unknown, ...args: unknown[]) {\n claim(state);\n return typeof original === 'function' ? original.apply(this, args) : undefined;\n }\n });\n}\n\nfunction describe(state: State, parents: Map<State, State>): Model {\n const stored = entries(state);\n const declared = Object.entries(Object.getOwnPropertyDescriptors(state))\n .filter(([, desc]) => typeof desc.get === 'function')\n .map(([key]) => key);\n const model: Model = {\n id: String(state),\n ...seen(state.constructor as typeof State),\n keys: [...stored.keys()],\n absent: declared.filter((key) => !stored.has(key))\n };\n const parent = parents.get(state);\n if (parent) model.parent = String(parent);\n return model;\n}\n\n/** Each instance's owner, from mvc. */\nfunction ownership(): Map<State, State> {\n return graph().owners;\n}\n\n/** Owner, else the first instance holding it - what keeps an instance from being abandoned. */\nfunction reach(): Map<State, State> {\n return graph().holders;\n}\n\nfunction graph() {\n if (cached?.version !== version) {\n const owners = new Map<State, State>();\n const holders = new Map<State, State>();\n\n for (const state of registered()) {\n const owner = state.get(State, false);\n if (owner) owners.set(state, owner);\n\n for (const [key, value] of entries(state)) {\n const field = Object.getOwnPropertyDescriptor(state, key)?.enumerable;\n if (field || !(value instanceof State)) hold(holders, state, value);\n }\n }\n\n for (const [state, owner] of owners) holders.set(state, owner);\n\n cached = { version, owners, holders };\n }\n\n return cached;\n}\n\nfunction hold(holders: Map<State, State>, holder: State, value: unknown) {\n if (value instanceof State) {\n if (!holders.has(value) && value !== holder) holders.set(value, holder);\n } else if (value && typeof value === 'object' && Symbol.iterator in value) {\n const items = value instanceof Map ? value.values() : (value as Iterable<unknown>);\n for (const item of items) if (item instanceof State) hold(holders, holder, item);\n }\n}\n"],"mappings":";;;;;;AAEA,MAAM,aAAa;AACnB,MAAM,YAAY;AAClB,MAAM,WAAW;AAIjB,SAAgB,UAAU,KAAsB;CAC9C,MAAM,UAAU,IAAI,MAAM;CAC1B,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAChC,KAAI,OAAO,EAAG,QAAO,EAAE,QAAQ,SAAS;AACxC,QAAO;EAAE,QAAQ,QAAQ,MAAM,GAAG,IAAI;EAAE,MAAM,QAAQ,MAAM,MAAM,EAAE;EAAE;;;AAIxE,SAAgB,QAAQ,OAAoC;AAC1D,QAAO,IAAI,IAAI,MAAM;;;AAIvB,SAAgB,KAAK,OAAgB,MAAwB;AAC3D,KAAI,CAAC,KAAM,QAAO;CAClB,IAAI,MAAe;AACnB,MAAK,MAAM,QAAQ,KAAK,MAAM,IAAI,EAAE;AAClC,MAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACnD,MAAI,eAAe,MACjB,OAAM,KAAK,MAAM,MAAM,OAAO,yBAAyB,KAAK,KAAK,EAAE,OAAO,GAAG,QAAQ,IAAI,CAAC,IAAI,KAAK;WAC5F,eAAe,IAAK,OAAM,IAAI,IAAI,KAAK;MAC3C,OAAO,IAAgC;;AAE9C,QAAO;;AAGT,SAAgB,IAAI,OAAc;AAChC,QAAO;EAAE,MAAM,OAAO,MAAM;EAAE,OAAO,MAAM,YAAY;EAAM;;;AAO/D,SAAgB,QAAQ,OAAgB,QAAyB;AAC/D,KAAI,WAAW,QAAQ,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO,UAAU,MAAM;CAE1F,MAAM,QAAQ,iBAAiB,QAAQ,SAAY,KAAK,MAAM;AAE9D,KAAI,OAAO;EACT,MAAM,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACxE,MAAI,MAAM,SAAS,UAAW,KAAI,KAAK,KAAK,MAAM,SAAS,YAAY;AACvE,SAAO;;CAGT,MAAM,MAA+B,iBAAiB,QAAQ,IAAI,MAAM,GAAG,EAAE;AAC7E,MAAK,MAAM,OAAO,OAAQ,KAAI,OAAO,QAAQ,KAAK,OAAO,IAAI,EAAE,OAAO,KAAK;AAC3E,QAAO;;;AAIT,SAAgB,UAAU,OAAgB,QAAQ,GAAY;AAC5D,KAAI,iBAAiB,OAAO;EAC1B,MAAM,MAA+B,IAAI,MAAM;AAC/C,OAAK,MAAM,CAAC,KAAK,UAAU,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC,MAAM,GAAG,SAAS,CAC/D,KAAI,OAAO,MAAM,OAAO,QAAQ,EAAE;AACpC,SAAO;;AAET,QAAO,MAAM,OAAO,MAAM;;AAG5B,SAAS,MAAM,OAAgB,OAAwB;AACrD,KAAI,SAAS,QAAQ,OAAO,UAAU,UAAW,QAAO;AACxD,KAAI,OAAO,UAAU,SAAU,QAAO,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,MAAM;AACpF,KAAI,OAAO,UAAU,SACnB,QAAO,MAAM,SAAS,aAAa,GAAG,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC,KAAK;AAC5E,KAAI,OAAO,UAAU,SAAU,QAAO,GAAG,MAAM;AAC/C,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI,iBAAiB,MAAO,QAAO,IAAI,MAAM;AAC7C,KAAI,iBAAiB,KAAM,QAAO,MAAM,aAAa;AACrD,KAAI,iBAAiB,MAAO,QAAO;EAAE,MAAM,MAAM;EAAM,SAAS,MAAM;EAAS;AAC/E,KAAI,OAAQ,MAA+B,SAAS,WAAY,QAAO;CAEvE,MAAM,QAAQ,KAAK,MAAM;AAEzB,KAAI,OAAO;AACT,MAAI,SAAS,EAAG,QAAO,IAAI,MAAM,OAAO;EACxC,MAAM,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,QAAQ,MAAM,KAAK,QAAQ,EAAE,CAAC;AACzE,MAAI,MAAM,SAAS,UAAW,KAAI,KAAK,KAAK,MAAM,SAAS,YAAY;AACvE,SAAO;;CAGT,MAAM,QAAQ,iBAAiB,MAC3B,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,CAAU,GACnD,OAAO,QAAQ,MAAM;AAEzB,KAAI,SAAS,EAAG,QAAO,IAAI,MAAM,OAAO;CAExC,MAAM,MAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,KAAK,UAAU,MAAM,MAAM,GAAG,SAAS,EAAE;AACnD,MAAI,QAAQ,KAAM;EAClB,MAAM,OAAO,MAAM,OAAO,QAAQ,EAAE;AACpC,MAAI,SAAS,OAAW,KAAI,OAAO;;AAErC,KAAI,MAAM,SAAS,SAAU,KAAI,OAAO,MAAM,SAAS;AACvD,QAAO;;AAGT,SAAS,KAAK,OAAsC;AAClD,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO;AACjC,KAAI,iBAAiB,IAAK,QAAO;AACjC,KAAI,OAAQ,MAA4B,OAAO,cAAc,WAC3D,QAAO,CAAC,GAAI,MAA4B;;;;;ACnG5C,MAAM,uBAAO,IAAI,KAA6B;AAC9C,MAAM,yBAAS,IAAI,KAA2B;AAC9C,MAAM,wBAAQ,IAAI,KAAqB;AACvC,IAAI,QAAQ;AAEZ,SAAS,SAAS,MAA8B;CAC9C,IAAI,MAAM,KAAK,IAAI,KAAK;AACxB,KAAI,CAAC,KAAK;EACR,MAAM,OAAO,wBAAO,IAAI,OAAO,EAAC,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,KAAK;AAC1E,OAAK,IAAI,MAAO,MAAM;GAAE,QAAQ,IAAI,EAAE;GAAS,MAAM;GAAI;GAAM,CAAE;;AAEnE,QAAO;;AAGT,SAAgB,KAAK,MAA8B;CACjD,MAAM,MAAM,SAAS,KAAK;AAC1B,KAAI,OAAO,QAAQ,KAAK;AACxB,QAAO,EAAE,GAAG,KAAK;;AAGnB,SAAgB,QAAQ,MAA4B;CAClD,MAAM,MAAM,SAAS,KAAK;CAC1B,MAAM,WAAW,OAAO,IAAI,KAAK,IAAK,KAAkC;AACxE,KAAI,SAAU,QAAO;CACrB,MAAM,QAAQ,MAAM,IAAI,IAAI,OAAO,IAAI,MAAM,IAAI,IAAI,KAAK;AAC1D,KAAI,MAAO,QAAO;AAClB,QAAO,KAAK,KAAK,SAAS,IAAI,KAAK,OAAO,IAAI;;AAGhD,SAAgB,MAAM,MAAoB,MAAoB;AAC5D,QAAO,IAAI,MAAM,KAAK;;;AAIxB,SAAgB,QAAQ,OAAqC;AAC3D,MAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,MAAM,CAAE,OAAM,IAAI,KAAK,KAAK;;AAGvE,SAAgB,SAAe;AAC7B,MAAK,OAAO;AACZ,QAAO,OAAO;AACd,OAAM,OAAO;AACb,SAAQ;;;;;ACMV,MAAM,YAAY;AAElB,MAAM,SAAkB,EAAE;AAC1B,MAAM,SAA4B;CAAE,OAAO;CAAO,OAAO,EAAE;CAAE,OAAO,EAAE;CAAE,MAAM,EAAE;CAAE,OAAO;CAAO;AAChG,IAAI,MAAM;AACV,IAAI;AACJ,IAAI;AAEJ,MAAa,UAAU;CACrB,OAAO,UAAmB,EAAE,EAAqB;AAC/C,SAAO,OAAO,QAAQ,QAAQ;AAC9B,MAAI,CAAC,QAAQ,SAAS,QAAQ,SAAS,OAAO,UAAU,MAAO,QAAO,QAAQ;AAC9E,SAAO;GAAE,GAAG;GAAQ,OAAO,CAAC,GAAG,OAAO,MAAM;GAAE,OAAO,CAAC,GAAG,OAAO,MAAM;GAAE,MAAM,CAAC,GAAG,OAAO,KAAK;GAAE;;CAGlG,OAAO,QAAe,EAAE,EAAW;EACjC,MAAM,MAAe,EAAE;AACvB,OAAK,MAAM,SAAS,QAAQ;AAC1B,OAAI,MAAM,UAAU,UAAa,MAAM,OAAO,MAAM,MAAO;AAC3D,OAAI,MAAM,UAAU,UAAa,MAAM,UAAU,MAAM,MAAO;GAC9D,MAAM,SAAS,MAAM,OAAO,QAAQ,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC5D,OAAI,OAAO,OAAQ,KAAI,KAAK;IAAE,GAAG;IAAO;IAAQ,CAAC;;AAEnD,SAAO;;CAGT,QAAQ,OAAgE;EACtE,MAAM,MAAM,EAAE;AACd,OAAK,MAAM,SAAS,QAAQ,OAAO,MAAM,CACvC,MAAK,MAAM,SAAS,MAAM,OAAQ,KAAI,KAAK;GAAE,KAAK,MAAM;GAAK,IAAI,MAAM;GAAI;GAAO,CAAC;AACrF,SAAO;;CAIT,WAAW,MAAuB;EAChC,MAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC;AAC7B,SAAO,OAAO,QAAQ,UAAU;AAC9B,OAAI,MAAM,UAAU,UAAa,CAAC,MAAM,IAAI,MAAM,MAAM,CAAE,QAAO;AACjE,SAAM,IAAI,MAAM,IAAI;AACpB,UAAO;IACP;;CAIJ,MAAc;AACZ,SAAO;;CAIT,OAAO,QAAe,EAAE,EAAU;AAChC,SAAO,QACJ,OAAO,MAAM,CACb,SAAS,UACR,MAAM,OAAO,KAAK,UAChB,KAAK,UAAU;GAAE,KAAK,MAAM;GAAK,IAAI,MAAM;GAAI,OAAO,MAAM;GAAO,GAAG;GAAO,CAAC,CAC/E,CACF,CACA,KAAK,KAAK;;CAIf,QAAQ,QAAe,EAAE,EAAa;EACpC,MAAM,qBAAK,IAAI,KAAsB;AAErC,OAAK,MAAM,SAAS,QAAQ,OAAO,MAAM,CACvC,MAAK,MAAM,SAAS,MAAM,QAAQ;AAChC,OAAI,CAAC,MAAM,GAAI;GAEf,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG;AAE5B,OAAI,CAAC,MAAO,IAAG,IAAI,MAAM,IAAK,QAAQ;IAAE,IAAI,MAAM;IAAI,MAAM,MAAM;IAAM,MAAM;IAAG,MAAM,EAAE;IAAE,OAAO,EAAE;IAAE,QAAQ;IAAG,KAAK;IAAG,WAAW;IAAO,CAAE;AAE7I,SAAM,OAAO,MAAM;AAEnB,OAAI,MAAM,SAAS,UAAW,OAAM,YAAY;YACvC,MAAM,SAAS,OAAQ,OAAM,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM,QAAQ,KAAK;YAChF,MAAM,SAAS,SAAU,OAAM;YAC/B,MAAM,SAAS,MAAO,OAAM;QAChC;IACH,MAAM,MAAO,MAAM,KAAK,MAAM,SAAS,EAAE,OAAO,GAAG;AACnD,QAAI;AACJ,QAAI,WAAW,MAAO,KAAI,QAAQ,MAAM;;;AAI9C,SAAO,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK;;CAOzD,IAAI,KAAa,OAAuB;AACtC,MAAI,OAAO,UAAU,MAAO;EAE5B,MAAM,QAAe;GAAE,IAAI;GAAI,MAAM;GAAQ;GAAK,MAAM;GAAO;AAC/D,MAAI,UAAU,OAAW,OAAM,QAAQ;AACvC,OAAK,MAAM;;CAGb,QAAc;AACZ,SAAO,SAAS;AAChB,SAAO;AACP,UAAQ;AACR,QAAM;;CAGR,QAAc;AACZ,UAAQ,OAAO;AACf,SAAO,OAAO,QAAQ;GAAE,OAAO;GAAO,OAAO,EAAE;GAAE,OAAO,EAAE;GAAE,MAAM,EAAE;GAAE,OAAO;GAAO,CAAC;;CAExF;AAED,SAAS,QAAQ,OAAc,OAAc;AAC3C,SACG,CAAC,MAAM,QAAQ,MAAM,SAAS,MAAM,UACpC,CAAC,MAAM,MAAM,MAAM,OAAO,MAAM,QAChC,CAAC,MAAM,OAAO,MAAM,QAAQ,MAAM;;;AAKvC,SAAgB,MAAM,OAAc,KAAuB;AACzD,KAAI,OAAO,UAAU,MAAO,QAAO;CAEnC,MAAM,EAAE,OAAO,OAAO,SAAS;AAC/B,KAAI,CAAC,MAAM,UAAU,CAAC,MAAM,UAAU,CAAC,KAAK,OAAQ,QAAO;CAE3D,MAAM,OAAO,MAAM;CACnB,MAAM,QAAQ,QAAQ,KAAK;AAC3B,KAAI,MAAM,SAAS,MAAM,CAAE,QAAO;AAClC,KAAI,QAAQ,UAAa,KAAK,SAAS,IAAI,CAAE,QAAO;CAEpD,MAAM,UAAU;EAAC;EAAO,KAAK,KAAK,CAAC;EAAQ,OAAO,MAAM;EAAC;AACzD,MAAK,MAAM,WAAW,OAAO;EAC3B,MAAM,EAAE,QAAQ,SAAS,UAAU,QAAQ;AAC3C,MAAI,QAAQ,SAAS,OAAO,KAAK,QAAQ,UAAa,SAAS,KAAM,QAAO;;AAE9E,QAAO;;AAGT,SAAgB,eAAwB;AACtC,QAAO,OAAO,SAAS,OAAO,UAAU;;AAI1C,SAAgB,KAAK,OAAc,KAAc,OAAmC;CAClF,MAAM,OAAO,OAAO,IAAI;AACxB,KAAI,CAAC,MAAM,OAAO,KAAK,CAAE;CAEzB,MAAM,QAAe;EACnB,IAAI,OAAO,MAAM;EACjB,MAAM,QAAQ,MAAM,YAA4B;EAChD,KAAK;EACL,MAAM,OAAO,QAAQ,YAAY,MAAM,IAAI,IAAI,GAAG,WAAW;EAC9D;AAED,KAAI,OAAO,UAAU,YAAY,MAAM,SAAS,SAC9C,OAAM,QAAQ,UAAU,MAAM,IAAI,KAAK,EAAE,EAAE;AAE7C,MAAK,MAAM;;AAGb,SAAgB,SAAS,OAAc,KAAa,MAAuB;AACzE,KAAI,CAAC,cAAc,IAAI,CAAC,MAAM,OAAO,IAAI,CAAE;CAE3C,MAAM,QAAe;EAAE,IAAI,OAAO,MAAM;EAAE,MAAM,QAAQ,MAAM,YAA4B;EAAE;EAAK,MAAM;EAAQ;AAC/G,KAAI,OAAO,UAAU,SAAU,OAAM,OAAO,KAAK,KAAK,QAAQ,UAAU,KAAK,EAAE,CAAC;AAChF,MAAK,MAAM;;AAGb,SAAgB,WAAW,OAAc,OAAgB,MAAc,KAAgD;AACrH,KAAI,CAAC,MAAM,OAAO,IAAI,CAAE;CACxB,MAAM,QAAQ;EACZ,MAAM;EACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;EAC/D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;EAC9C,SAAS;EACV;AACD,MAAK;EAAE,IAAI,OAAO,MAAM;EAAE,MAAM,QAAQ,MAAM,YAA4B;EAAE,KAAK,OAAO;EAAI,MAAM;EAAU;EAAO,CAAC;AACpH,QAAO;;AAGT,SAAgB,UAAU,OAAoB;AAC5C,KAAI,MAAM,MAAM,CAAE,MAAK;EAAE,IAAI,OAAO,MAAM;EAAE,MAAM,QAAQ,MAAM,YAA4B;EAAE,KAAK;EAAS,MAAM;EAAO,CAAC;;AAG5H,SAAgB,YAAY,OAAoB;AAC9C,KAAI,CAAC,MAAM,MAAM,CAAE;AACnB,MAAK;EAAE,IAAI,OAAO,MAAM;EAAE,MAAM,QAAQ,MAAM,YAA4B;EAAE,KAAK;EAAI,MAAM;EAAW,CAAC;;AAGzG,SAAS,KAAK,OAAc;AAC1B,KAAI,CAAC,MAAM;EACT,MAAM,QAAe;GAAE,KAAK,EAAE;GAAK,IAAI,KAAK,KAAK;GAAE,QAAQ,EAAE;GAAE;AAC/D,MAAI,UAAU,OAAW,OAAM,QAAQ;AACvC,SAAO;AACP,SAAO,KAAK,MAAM;AAClB,MAAI,OAAO,SAAS,UAAW,QAAO,OAAO,GAAG,OAAO,SAAS,UAAU;AAC1E,uBAAqB;AACnB,UAAO;AACP,WAAQ,MAAM;AACd,wBAAqB;AACnB,QAAI,QAAQ,MAAM,IAAK,SAAQ;KAC/B;IACF;;AAEJ,MAAK,OAAO,KAAK,MAAM;;;;;ACrOzB,MAAM,SACJ,OAAO,yBAAyB,aAC5B,uBACC,MAAM;CACL,WAAW;CACX,aAAa;;AAGrB,MAAM,QAAQ,UACZ,OAAO,YAAY,aAAa,IAAI,QAAQ,MAAM,GAAG,EAAE,aAAa,OAAO;AAE7E,MAAM,uBAAO,IAAI,KAAkB;AACnC,MAAM,wBAAQ,IAAI,KAA+B;AAEjD,MAAM,SAAS,OAAO,IAAI,kBAAkB;AAE5C,MAAM,UAAU,OAAO,IAAI,0BAA0B;AACrD,MAAM,2BAAW,IAAI,SAA0B;AAC/C,MAAM,wBAAQ,IAAI,SAAsB;AACxC,MAAM,SAAS,IAAI,OAAe,UAAU;AAE5C,IAAI,UAAU;AACd,IAAI;AACJ,IAAI,OAAO;AACX,IAAI,QAAQ,QAAQ;AACpB,IAAI,SAAS;AACb,IAAI;AAEJ,SAAS,SAAiC;AACxC,QAAO;EAAE,MAAM;EAAG,QAAQ;EAAG,QAAQ;EAAG,OAAO;EAAG,QAAQ;EAAG;;;AAI/D,IAAI;AAEJ,SAAS,QAAqB,OAAgB,MAAc,KAAc;AACxE,OAAM;AACN,QAAO;EAAE;EAAO,OAAO,WAAW,MAAM,OAAO,MAAM,IAAI;EAAE;AAC3D,QAAO;;AAGT,SAAS,UAAuB,OAAgB,MAAc,KAAc;AAC1E,KAAI,MAAM,UAAU,MAAO,SAAQ,KAAK,MAAM,OAAO,MAAM,IAAI;AAC/D,KAAI,KAAM,MAAO,MAAM,MAAM,UAAU;AACvC,QAAO;AACP,QAAO;;AAGT,SAAgB,cAAoB;AAClC,SAAQ,QAAQ;;;AAIlB,SAAS,cAAc;CACrB,MAAM,OAAQ,AAAC,WAAwC,YAAY,EAAE;CACrE,MAAM,EAAE,SAAS;CACjB,MAAM,cAAc;EAClB,MAAM,MAAM;AACZ,WAAS,IAAI,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;AACnC,MAAI,SAAS,KAAK,QAAQ,EACxB,SAAQ,KAAK,GAAG,OAAO,+EAA+E;;AAG1G,MAAK,QAAQ,GAAG,UAAU;EACxB,MAAM,SAAS,KAAK,MAAM,MAAM,MAAM;AACtC,SAAO;AACP,SAAO;;AAGT,QAAO;AACP,iBAAgB;AACd,OAAK,OAAO;;;;AAKhB,SAAS,aAAsB;AAC7B,QAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CACtB,KAAK,QAAQ,IAAI,QAAQ,IAAI,IAAI,OAAO,CAAC,CACzC,QAAQ,UAA0B,CAAC,CAAC,MAAM;;;AAI/C,UAAU,WAA6B;CACrC,MAAM,UAAU,OAAO;AACvB,MAAK,MAAM,SAAS,YAAY,CAAE,KAAI,CAAC,SAAS,OAAO,QAAQ,CAAE,OAAM;;AAGzE,SAAS,SAAS,OAAc,SAA4B,uBAAO,IAAI,KAAY,EAAW;CAC5F,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,KAAI,KAAK,WAAW,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAE,QAAO;AACvD,KAAI,SAAS,MAAM,EAAE;AACnB,QAAM,MAAM;AACZ,SAAO;;CAET,MAAM,QAAQ,QAAQ,IAAI,MAAM;AAChC,KAAI,CAAC,SAAS,KAAK,IAAI,MAAM,CAAE,QAAO;AACtC,MAAK,IAAI,MAAM;AACf,KAAI,SAAS,OAAO,SAAS,KAAK,CAAE,QAAO;AAC3C,KAAI,MAAM,IAAI,MAAM,CAAE,QAAS,OAAM,MAAM;AAC3C,QAAO;;AAGT,SAAS,MAAM,OAAc;CAC3B,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,KAAI,KAAK,QAAS;AAClB,MAAK,UAAU;CACf,MAAM,MAAM,KAAK,IAAI,OAAO,MAAM,CAAC;AACnC,KAAI,KAAK;AACP,MAAI,OAAO;AACX,SAAO,WAAW,MAAM;;AAE1B;;;AAIF,SAAS,SAAS,OAAuB;CACvC,MAAM,OAAO,MAAM;AAEnB,KAAI,EADW,OAAO,KAAK,WAAW,aAAa,KAAK,OAAO,MAAM,GAAG,KAAK,QAChE,QAAO;AACpB,MAAK,MAAM,OAAO,QAAQ,KAAK,QAAQ,QAAQ,CAC7C,KAAI,KAAK;OAAK,MAAM,CAAC,WAAW,IAAK,KAAI,WAAW,MAAO,QAAO;;AACpE,QAAO;;AAGT,SAAS,SAAkB;AACzB,KAAI;AACF,YAAU,KAAK;AACf,SAAO;SACD;AACN,SAAO;;;;AAKX,SAAgB,UAAU,IAAkB;AAC1C,KAAI,CAAC,KAAK,OAAO,GAAG,CAAE;AACtB;AACA;;;AAIF,IAAa,WAAb,MAAa,SAAS;CACpB,AAAQ,YAAY,AAAS,OAAc;EAAd;;CAE7B,OAAO,GAAG,OAAwB;EAChC,IAAI,WAAW,SAAS,IAAI,MAAM;AAClC,MAAI,CAAC,SAAU,UAAS,IAAI,OAAQ,WAAW,IAAI,SAAS,MAAM,CAAE;AACpE,SAAO;;CAGT,IAAI,KAAK;AACP,SAAO,OAAO,KAAK,MAAM;;CAG3B,IAAI,OAAO;AACT,SAAO,KAAK,KAAK,MAAM,YAA4B,CAAC;;CAGtD,IAAI,QAAQ;AACV,SAAO,KAAK,IAAI,KAAK,GAAG;;;CAI1B,IAAI,UAAU;AACZ,SAAO,CAAC,SAAS,KAAK,OAAO,OAAO,CAAC;;;CAIvC,IAAI,QAAQ;AACV,SAAO,MAAM,IAAI,KAAK,MAAM,CAAE;;;CAIhC,IAAI,QAAQ;AACV,SAAO,MAAM,IAAI,KAAK,MAAM,CAAE;;CAGhC,IAAI,SAA+B;EACjC,MAAM,QAAQ,WAAW,CAAC,IAAI,KAAK,MAAM;AACzC,SAAO,SAAS,SAAS,GAAG,MAAM;;CAGpC,IAAI,WAAuB;EACzB,MAAM,UAAU,WAAW;AAC3B,SAAO,CAAC,GAAG,YAAY,CAAC,CACrB,QAAQ,UAAU,QAAQ,IAAI,MAAM,KAAK,KAAK,MAAM,CACpD,IAAI,SAAS,GAAG;;;CAIrB,KAAK,OAAyE;EAC5E,MAAM,OAAO,OAAO,UAAU,YAAY,MAAgB,EAAE,SAAS,QAAQ;AAC7E,OAAK,MAAM,SAAS,KAAK,UAAU;AACjC,OAAI,KAAK,MAAM,CAAE,QAAO;GACxB,MAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,OAAI,KAAM,QAAO;;;CAKrB,IAAI,MAAe,QAA0B;EAC3C,MAAM,QAAQ,KAAK,KAAK,OAAO,KAAK;AACpC,SAAO,SAAS,QAAQ,OAAO,OAAO,GAAG,UAAU,MAAM;;CAG3D,QAAe;AACb,SAAO,SAAS,KAAK,OAAO,WAAW,CAAC;;;CAI1C,IAAI,MAAiC,SAAiC;AACpE,SAAO,UAAU,KAAK,KAAK,MAAM,EAAE,QAAQ;;;CAI7C,MAAM,IAAkC,MAA6B;EACnE,MAAM,UAAU,KAAK,MAAM,KAAK,QAAQ;AACtC,OAAI,OAAO,QAAQ,aAAa,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAG,IAAG,IAAI;IACrE;EACF,MAAM,UAAU,KAAK,MAAM,IAAI,YAAY,GAAG,KAAK,CAAC;AACpD,eAAa;AACX,YAAS;AACT,YAAS;;;CAIb,OAAO,QAAe,EAAE,EAAW;AACjC,SAAO,QAAQ,OAAO;GAAE,GAAG;GAAO,IAAI,KAAK;GAAI,CAAC;;;AAIpD,SAAgB,OAAO,OAAqB,OAAmB;AAC7D,KAAI,CAAC,QAAS,cAAa;AAE3B,KAAI,CAAC,MAAM,IAAI,KAAK,EAAE;EACpB,MAAM,2BAAW,IAAI,KAA+B;EACpD,MAAM,YAAY,KAAK,GAAG,EAAE,OAAO,WAAW,CAAC;EAC/C,MAAM,WAAW,KAAK,GAAG;GAAE,MAAM;GAAO,QAAQ;GAAS,CAAC;EAC1D,MAAM,YAAY,KAAK,GAAG,EACxB,QAAmB;GACjB,MAAM,OAAO,KAAK;GAClB,MAAM,IAAI,KAAK;GACf,MAAM,KAAK,OAAO,KAAK;GACvB,MAAM,OAAa;IAAE,OAAO,KAAK,KAAK;IAAE,SAAS;IAAO,SAAS;IAAO;AACxE,OAAI,CAAC,SAAS,IAAI,EAAE,CAAE,UAAS,IAAI,GAAG,EAAE,GAAG,EAAE,OAAO,SAAS,CAAC,CAAC;AAC/D,QAAK,EAAE;AACP,QAAK,IAAI,IAAI,EAAE,KAAK,KAAK,KAAK,EAAE,CAAC;AACjC,SAAM,IAAI,MAAM,KAAK;AACrB,UAAO,SAAS,MAAM,IAAI,KAAK;AAC/B,oBAAiB;AACf,SAAK,UAAU;MACd,EAAE;AACL;AACA,UAAO,KAAK;GACZ,MAAM,UAAU,SAAS,YAAY,UAAU,KAAK,EAAE,QAAQ;GAC9D,MAAM,OAAO,KAAK,KAAK,QAAQ;IAC7B,MAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAI,OAAO,QAAQ,YAAY,OAAO,MAAM,IAAI,IAAI,KAAK,SAAU;AACnE,SAAK,MAAM,KAAK,MAAM;KACtB;AACF,gBAAa;AACX,UAAM;AACN,aAAS;AACT,SAAK,OAAO,GAAG;AACf,WAAO,WAAW,KAAK;AACvB,SAAK,QAAQ,KAAK,KAAK;AACvB;AACA,gBAAY,KAAK;;KAGtB,CAAC;AACF,QAAM,IAAI,YAAY;AACpB,QAAK,MAAM,QAAQ,SAAS,QAAQ,CAAE,OAAM;AAC5C,cAAW;AACX,aAAU;AACV,cAAW;IACX;;AAGJ,cAAa;AACX,QAAM,IAAI,KAAK,IAAI;AACnB,QAAM,OAAO,KAAK;;;AAItB,SAAgB,SAAe;AAC7B,MAAK,MAAM,QAAQ,MAAM,QAAQ,CAAE,OAAM;AACzC,OAAM,OAAO;AACb,MAAK,OAAO;AACZ,UAAS;AACT,QAAO;AACP,SAAQ,QAAQ;AAChB,UAAS;AACT,YAAW;AACX,WAAU;AACV,SAAQ,OAAO;AACf,SAAQ;;;AAIV,SAAgB,KAAK,QAAsC;CACzD,MAAM,OAAO,KAAK,IAAI,OAAO;CAC7B,MAAM,OAAO,SAAS,KAAK,QAAQ,KAAK,IAAI,OAAO;AACnD,KAAI,KAAM,QAAO,SAAS,GAAG,KAAK;CAElC,MAAM,wBAAQ,IAAI,KAA2B;CAC7C,IAAI;AAEJ,MAAK,MAAM,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAC1C,MAAK,MAAM,SAAS,MAAM;EACxB,MAAM,OAAO,MAAM;EACnB,MAAM,OAAO,KAAK,KAAK;AACvB,MAAI,KAAK,SAAS,OAAQ;AAC1B,YAAU;AACV,QAAM,IAAI,MAAM,KAAK,OAAO;;AAGhC,KAAI,MAAM,OAAO,EACf,OAAM,IAAI,MACR,GAAG,OAAO,WAAW,MAAM,KAAK,YAAY,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,KAAK,KAAK,CAAC,oGAC5E;AAEH,QAAO,SAAS,SAAS,GAAG,MAAM;;AAGpC,SAAgB,YAAwB;AACtC,QAAO,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,SAAS,GAAG;;;AAIzC,SAAgB,UAAsB;AACpC,QAAO,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,SAAS,GAAG;;AAG1C,UAAU,YAA8B;CACtC,MAAM,UAAU,OAAO;AACvB,MAAK,MAAM,SAAS,YAAY,CAAE,KAAI,SAAS,OAAO,QAAQ,CAAE,OAAM;;;AAexE,SAAgB,SAAiB;AAC/B,QAAO;EAAE,SAAS,SAAS,CAAC;EAAQ,WAAW;EAAM;EAAQ,QAAQ,EAAE,GAAG,OAAO;EAAE;;AAGrF,SAAgB,QAAoB;CAClC,MAAM,UAAU,WAAW;AAC3B,QAAO,WAAW,CAAC,QAAQ,aAAa,CAAC,QAAQ,IAAI,SAAS,MAAM,CAAC;;AAGvE,SAAgB,SAAkB;CAChC,MAAM,UAAU,WAAW;AAC3B,QAAO,CAAC,GAAG,UAAU,CAAC,CAAC,KAAK,UAAU,SAAS,OAAO,QAAQ,CAAC;;AAGjE,SAAgB,OAAe;CAC7B,MAAM,UAAU,WAAW;CAC3B,MAAM,wBAAQ,IAAI,KAAkB;CACpC,MAAM,MAAc,EAAE;AAEtB,MAAK,MAAM,SAAS,UAAU,CAC5B,OAAM,IAAI,OAAO;EAAE,IAAI,OAAO,MAAM;EAAE,MAAM,KAAK,MAAM,YAA4B,CAAC;EAAM,UAAU,EAAE;EAAE,CAAC;AAE3G,MAAK,MAAM,CAAC,OAAO,SAAS,OAAO;EACjC,MAAM,SAAS,QAAQ,IAAI,MAAM;EACjC,MAAM,QAAQ,UAAU,MAAM,IAAI,OAAO;AACzC,MAAI,MAAO,OAAM,SAAS,KAAK,KAAK;MAC/B,KAAI,KAAK,KAAK;;AAGrB,QAAO;;;AAIT,eAAsB,IAAI,MAAqB,UAAe,EAAE,EAAoB;CAClF,MAAM,EAAE,QAAQ,SAAS,SAAS,SAAS,YAAY,MAAM,QAAQ;EAAE,GAAG;EAAS;EAAK,EAAE,MAAM,MAAM,SAAS,KAAK;AACpH,KAAI,QAAQ,OAAQ,OAAM,UAAU,SAAS,SAAS,SAAS,OAAO;AACtE,KAAI,CAAC,QAAS,WAAU,QAAQ;AAChC,QAAO;;AAGT,SAAgB,IAAI,SAAkB,QAA0B;AAC9D,KAAI,CAAC,QAAS,QAAO,QAAQ;CAC7B,MAAM,EAAE,QAAQ,SAAS,UAAU,QAAQ;AAC3C,QAAO,KAAK,OAAO,EAAE,IAAI,MAAM,OAAO;;AAGxC,SAAgB,IAAI,SAAiB,OAAsB;CACzD,MAAM,EAAE,QAAQ,SAAS,UAAU,QAAQ;CAC3C,MAAM,WAAW,KAAK,OAAO;AAC7B,KAAI,CAAC,YAAY,CAAC,KAAM,OAAM,IAAI,MAAM,eAAe,QAAQ,GAAG;CAElE,MAAM,MAAM,KAAK,YAAY,IAAI;CACjC,MAAM,MAAM,KAAK,MAAM,MAAM,EAAE;CAC/B,MAAM,QAAQ,MAAM,IAAI,SAAS,QAAQ,KAAK,SAAS,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC;AAEjF,KAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,OAAM,IAAI,MAAM,eAAe,QAAQ,GAAG;AAE1F,KAAI,iBAAiB,IAAK,OAAM,IAAI,KAAK,MAAM;KAC1C,CAAC,MAAkC,OAAO;;AAGjD,eAAsB,KAAK,SAAiB,GAAG,MAAmC;CAChF,MAAM,EAAE,QAAQ,SAAS,UAAU,QAAQ;CAC3C,MAAM,QAAQ,KAAK,OAAO,EAAE;CAC5B,MAAM,SAAS,SAAS,QAAS,MAA6C;AAE9E,KAAI,OAAO,WAAW,WAAY,OAAM,IAAI,MAAM,gBAAgB,QAAQ,GAAG;AAE7E,QAAO,UAAU,MAAM,OAAO,MAAM,OAAO,KAAK,CAAC;;AAGnD,MAAM,yBAAS,IAAI,SAAmB;;AAGtC,SAAS,MAAM,MAAoB;CACjC,MAAM,QAAQ,KAAK;AAEnB,MAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,OAAO,0BAA0B,MAAM,CAAC,CAC/E,KAAI,OAAO,iBAAiB,OAAO,YAAY,OAAO,KAAK,SAAS,cAAc,KAAK,aACrF,OAAM,OAAO,OAAO,KAAK,KAAK,MAAM;;;;;;AAO1C,SAAS,QAAqB,KAAa,IAAc;CACvD,MAAM,SAAS,OAAO,GAAG;CACzB,IAAI,QAAQ,OAAO,eAAe,KAAK;AAEvC,QAAO,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,IAAI,CAAE,SAAQ,OAAO,eAAe,MAAM;AAE9F,KAAI,OAAO,YAAY,OAAO,IAAI,OAAO,IAAI,WAAW,OAAO,OAAO,yBAAyB,OAAO,IAAI,CAAE,IAAK,CAAE;CAEnH,MAAM,OAAO;AAEb,QAAO,KAAK;AACZ,MAAK,OAAO,OAAO,KAAK,OAAO;;;AAIjC,SAAS,OAAO,KAAa,IAAc;CACzC,MAAM,UAAU,OAAO,iBACrB,SAA0C,GAAG,MAAiB;AAC5D,MAAI,OAAO,KAAK,KAAK,KAAK,QAAS,UAAS,MAA0B,KAAK,KAAK;AAChF,SAAO,GAAG,MAAM,MAAM,KAAK;IAE7B;EAAE,MAAM,EAAE,OAAO,GAAG,MAAM;EAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ;EAAE,CAC3D;AAED,QAAO,IAAI,QAAQ;AAEnB,QAAO;;;AAIT,SAAS,OAAO,OAAc;CAC5B,MAAM,SAAS;CACf,MAAM,WAAW,OAAO;AAExB,QAAO,eAAe,QAAQ,SAAS;EACrC,cAAc;EACd,UAAU;EACV,MAAqB,GAAG,MAAiB;AACvC,SAAM,MAAM;AACZ,UAAO,OAAO,aAAa,aAAa,SAAS,MAAM,MAAM,KAAK,GAAG;;EAExE,CAAC;;AAGJ,SAAS,SAAS,OAAc,SAAmC;CACjE,MAAM,SAAS,QAAQ,MAAM;CAC7B,MAAM,WAAW,OAAO,QAAQ,OAAO,0BAA0B,MAAM,CAAC,CACrE,QAAQ,GAAG,UAAU,OAAO,KAAK,QAAQ,WAAW,CACpD,KAAK,CAAC,SAAS,IAAI;CACtB,MAAM,QAAe;EACnB,IAAI,OAAO,MAAM;EACjB,GAAG,KAAK,MAAM,YAA4B;EAC1C,MAAM,CAAC,GAAG,OAAO,MAAM,CAAC;EACxB,QAAQ,SAAS,QAAQ,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC;EACnD;CACD,MAAM,SAAS,QAAQ,IAAI,MAAM;AACjC,KAAI,OAAQ,OAAM,SAAS,OAAO,OAAO;AACzC,QAAO;;;AAIT,SAAS,YAA+B;AACtC,QAAO,OAAO,CAAC;;;AAIjB,SAAS,QAA2B;AAClC,QAAO,OAAO,CAAC;;AAGjB,SAAS,QAAQ;AACf,KAAI,QAAQ,YAAY,SAAS;EAC/B,MAAM,yBAAS,IAAI,KAAmB;EACtC,MAAM,0BAAU,IAAI,KAAmB;AAEvC,OAAK,MAAM,SAAS,YAAY,EAAE;GAChC,MAAM,QAAQ,MAAM,IAAI,OAAO,MAAM;AACrC,OAAI,MAAO,QAAO,IAAI,OAAO,MAAM;AAEnC,QAAK,MAAM,CAAC,KAAK,UAAU,QAAQ,MAAM,CAEvC,KADc,OAAO,yBAAyB,OAAO,IAAI,EAAE,cAC9C,EAAE,iBAAiB,OAAQ,MAAK,SAAS,OAAO,MAAM;;AAIvE,OAAK,MAAM,CAAC,OAAO,UAAU,OAAQ,SAAQ,IAAI,OAAO,MAAM;AAE9D,WAAS;GAAE;GAAS;GAAQ;GAAS;;AAGvC,QAAO;;AAGT,SAAS,KAAK,SAA4B,QAAe,OAAgB;AACvE,KAAI,iBAAiB,OACnB;MAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,UAAU,OAAQ,SAAQ,IAAI,OAAO,OAAO;YAC9D,SAAS,OAAO,UAAU,YAAY,OAAO,YAAY,OAAO;EACzE,MAAM,QAAQ,iBAAiB,MAAM,MAAM,QAAQ,GAAI;AACvD,OAAK,MAAM,QAAQ,MAAO,KAAI,gBAAgB,MAAO,MAAK,SAAS,QAAQ,KAAK"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { State } from "@expressive/mvc";
|
|
2
2
|
|
|
3
3
|
//#region src/journal.d.ts
|
|
4
4
|
type Level = 'off' | 'keys' | 'values';
|
|
@@ -10,14 +10,14 @@ interface Options {
|
|
|
10
10
|
paths?: string[];
|
|
11
11
|
/** Property names to record on any type. */
|
|
12
12
|
keys?: string[];
|
|
13
|
-
/** Also record method calls
|
|
13
|
+
/** Also record method calls, except `render`. */
|
|
14
14
|
calls?: boolean;
|
|
15
15
|
}
|
|
16
16
|
interface Event {
|
|
17
17
|
id: string;
|
|
18
18
|
type: string;
|
|
19
19
|
key: string;
|
|
20
|
-
kind: 'update' | 'event' | 'call' | 'destroy' | 'caught';
|
|
20
|
+
kind: 'update' | 'event' | 'call' | 'destroy' | 'caught' | 'hot';
|
|
21
21
|
value?: unknown;
|
|
22
22
|
args?: unknown[];
|
|
23
23
|
}
|
|
@@ -41,6 +41,8 @@ interface Summary {
|
|
|
41
41
|
calls: Record<string, number>;
|
|
42
42
|
/** `caught` reports. */
|
|
43
43
|
caught: number;
|
|
44
|
+
/** Hot patches applied to it. */
|
|
45
|
+
hot: number;
|
|
44
46
|
destroyed: boolean;
|
|
45
47
|
}
|
|
46
48
|
interface Query {
|
|
@@ -104,8 +106,6 @@ interface Node {
|
|
|
104
106
|
type: string;
|
|
105
107
|
children: Node[];
|
|
106
108
|
}
|
|
107
|
-
declare const CASES: readonly ["Destroyed", "Inactive", "Getter", "Init", "Effect"];
|
|
108
|
-
type Case = (typeof CASES)[number];
|
|
109
109
|
/** Navigable view of one instance - identity, ownership, reads, observation. One per state; outlives it. */
|
|
110
110
|
declare class Instance {
|
|
111
111
|
readonly state: State;
|
|
@@ -146,8 +146,8 @@ interface Health {
|
|
|
146
146
|
collected: number;
|
|
147
147
|
/** Loaded copies of `@expressive/mvc` - more than 1 means inspect cannot see every State. */
|
|
148
148
|
copies: number;
|
|
149
|
-
/**
|
|
150
|
-
caught: Record<
|
|
149
|
+
/** Reports by kind, including ones an app handler went on to handle; zeroed by `journal.clear()`. */
|
|
150
|
+
caught: Record<string, number>;
|
|
151
151
|
}
|
|
152
152
|
/** Counts worth a look before trusting what inspect shows. */
|
|
153
153
|
declare function health(): Health;
|
|
@@ -161,4 +161,4 @@ declare function set(address: string, value: unknown): void;
|
|
|
161
161
|
declare function call(address: string, ...args: unknown[]): Promise<unknown>;
|
|
162
162
|
//#endregion
|
|
163
163
|
export { Summary as A, parsePath as C, Level as D, Frame as E, Options as O, Select as S, Event as T, tree as _, act as a, resolve as b, detach as c, health as d, instances as f, set as g, roots as h, Node as i, Query as k, find as l, orphans as m, Instance as n, attach as o, models as p, Model as r, call as s, Health as t, get as u, TypeInfo as v, serialize as w, Act as x, label as y };
|
|
164
|
-
//# sourceMappingURL=inspect-
|
|
164
|
+
//# sourceMappingURL=inspect-UHBNq02g.d.ts.map
|
package/dist/install.js
CHANGED
package/dist/vite/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as tick, t as bracket } from "../bracket-
|
|
1
|
+
import { n as tick, t as bracket } from "../bracket-BYmLIpQH.js";
|
|
2
2
|
import { t as dispatch } from "../dispatch-Dnd88-J9.js";
|
|
3
3
|
|
|
4
4
|
//#region src/vite/client.ts
|
|
@@ -19,9 +19,36 @@ async function act(step, options) {
|
|
|
19
19
|
missing
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
+
const RELOAD = "@expressive/inspect.reload";
|
|
23
|
+
/** Keep a reload's reason past the reload, for the next page's journal. */
|
|
24
|
+
function remember(reason) {
|
|
25
|
+
try {
|
|
26
|
+
sessionStorage.setItem(RELOAD, JSON.stringify(reason));
|
|
27
|
+
} catch {}
|
|
28
|
+
}
|
|
29
|
+
function recall() {
|
|
30
|
+
try {
|
|
31
|
+
const reason = sessionStorage.getItem(RELOAD);
|
|
32
|
+
if (reason === null) return;
|
|
33
|
+
sessionStorage.removeItem(RELOAD);
|
|
34
|
+
return JSON.parse(reason);
|
|
35
|
+
} catch {}
|
|
36
|
+
}
|
|
22
37
|
function connect(hot) {
|
|
23
38
|
const id = Math.random().toString(36).slice(2, 8);
|
|
24
39
|
if (journal("record").level === "off") journal("record", { level: "keys" });
|
|
40
|
+
const reloaded = recall();
|
|
41
|
+
if (reloaded) journal("hot", "reload", reloaded);
|
|
42
|
+
hot.on("vite:beforeUpdate", ({ updates }) => {
|
|
43
|
+
journal("hot", "update", updates.map((update) => update.path));
|
|
44
|
+
});
|
|
45
|
+
hot.on("vite:beforeFullReload", ({ path, triggeredBy } = {}) => {
|
|
46
|
+
remember({
|
|
47
|
+
path,
|
|
48
|
+
triggeredBy
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
globalThis.addEventListener?.("expressive:reload", (event) => remember(event.detail));
|
|
25
52
|
hot.on("expressive-inspect:ask", async ({ rid, call }) => {
|
|
26
53
|
try {
|
|
27
54
|
const value = !call ? {
|
package/dist/vite/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../../src/vite/client.ts"],"sourcesContent":["import { dispatch, type Call } from '../dispatch';\nimport { bracket } from '../bracket';\nimport type { Options, Query } from '../journal';\nimport { tick, type Act } from '../settle';\n\nexport interface Hot {\n on(event: string, listener: (data: any) => unknown): void;\n send(event: string, data?: unknown): void;\n}\n\nexport interface Ask {\n rid: number;\n call?: Call;\n}\n\nconst journal = (method: string, ...args: unknown[]) => dispatch([['journal', method], args]) as any;\n\nasync function act(step: unknown, options?: Act) {\n if (!Array.isArray(step) || typeof step[0] != 'string')\n throw new Error('act takes one call: [\"act\", [method, ...args], options?].');\n\n const remote = {\n record: (...options: Options[]) => journal('record', ...options),\n seq: () => journal('seq'),\n frames: (query: Query) => journal('frames', query),\n get: (address: string) => dispatch([['get'], [address]])\n };\n\n const { value, frames, settled, pending, missing } = await bracket(remote, () => dispatch([step[0].split('.'), step.slice(1)]), tick, options, true);\n\n return { value: value ?? null, frames, settled, pending, missing };\n}\n\nexport function connect(hot: Hot) {\n const id = Math.random().toString(36).slice(2, 8);\n\n if (journal('record').level === 'off') journal('record', { level: 'keys' });\n\n hot.on('expressive-inspect:ask', async ({ rid, call }: Ask) => {\n try {\n const value = !call\n ? { id, url: location.href, title: document.title, top: window.self === window.top }\n : call[0].join('.') == 'act'\n ? await act(call[1][0], call[1][1] as Act)\n : await dispatch(call);\n\n hot.send('expressive-inspect:answer', { rid, value: JSON.parse(JSON.stringify(value) ?? 'null') });\n } catch (error) {\n hot.send('expressive-inspect:answer', { rid, error: error instanceof Error ? error.message : String(error) });\n }\n });\n\n hot.send('expressive-inspect:hello', { id });\n}\n"],"mappings":";;;;AAeA,MAAM,WAAW,QAAgB,GAAG,SAAoB,SAAS,CAAC,CAAC,WAAW,OAAO,EAAE,KAAK,CAAC;AAE7F,eAAe,IAAI,MAAe,SAAe;AAC/C,KAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,OAAO,KAAK,MAAM,SAC5C,OAAM,IAAI,MAAM,8DAA4D;CAS9E,MAAM,EAAE,OAAO,QAAQ,SAAS,SAAS,YAAY,MAAM,QAP5C;EACb,SAAS,GAAG,YAAuB,QAAQ,UAAU,GAAG,QAAQ;EAChE,WAAW,QAAQ,MAAM;EACzB,SAAS,UAAiB,QAAQ,UAAU,MAAM;EAClD,MAAM,YAAoB,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;EACzD,QAEgF,SAAS,CAAC,KAAK,GAAG,MAAM,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,SAAS,KAAK;AAEpJ,QAAO;EAAE,OAAO,SAAS;EAAM;EAAQ;EAAS;EAAS;EAAS;;AAGpE,SAAgB,QAAQ,KAAU;CAChC,MAAM,KAAK,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;AAEjD,KAAI,QAAQ,SAAS,CAAC,UAAU,MAAO,SAAQ,UAAU,EAAE,OAAO,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../src/vite/client.ts"],"sourcesContent":["import { dispatch, type Call } from '../dispatch';\nimport { bracket } from '../bracket';\nimport type { Options, Query } from '../journal';\nimport { tick, type Act } from '../settle';\n\nexport interface Hot {\n on(event: string, listener: (data: any) => unknown): void;\n send(event: string, data?: unknown): void;\n}\n\nexport interface Ask {\n rid: number;\n call?: Call;\n}\n\nconst journal = (method: string, ...args: unknown[]) => dispatch([['journal', method], args]) as any;\n\nasync function act(step: unknown, options?: Act) {\n if (!Array.isArray(step) || typeof step[0] != 'string')\n throw new Error('act takes one call: [\"act\", [method, ...args], options?].');\n\n const remote = {\n record: (...options: Options[]) => journal('record', ...options),\n seq: () => journal('seq'),\n frames: (query: Query) => journal('frames', query),\n get: (address: string) => dispatch([['get'], [address]])\n };\n\n const { value, frames, settled, pending, missing } = await bracket(remote, () => dispatch([step[0].split('.'), step.slice(1)]), tick, options, true);\n\n return { value: value ?? null, frames, settled, pending, missing };\n}\n\nconst RELOAD = '@expressive/inspect.reload';\n\n/** Keep a reload's reason past the reload, for the next page's journal. */\nfunction remember(reason: unknown) {\n try {\n sessionStorage.setItem(RELOAD, JSON.stringify(reason));\n } catch {}\n}\n\nfunction recall() {\n try {\n const reason = sessionStorage.getItem(RELOAD);\n\n if (reason === null) return;\n\n sessionStorage.removeItem(RELOAD);\n return JSON.parse(reason);\n } catch {}\n}\n\nexport function connect(hot: Hot) {\n const id = Math.random().toString(36).slice(2, 8);\n\n if (journal('record').level === 'off') journal('record', { level: 'keys' });\n\n const reloaded = recall();\n\n if (reloaded) journal('hot', 'reload', reloaded);\n\n hot.on('vite:beforeUpdate', ({ updates }: { updates: { path: string }[] }) => {\n journal('hot', 'update', updates.map((update) => update.path));\n });\n\n hot.on('vite:beforeFullReload', ({ path, triggeredBy }: { path?: string; triggeredBy?: string } = {}) => {\n remember({ path, triggeredBy });\n });\n\n globalThis.addEventListener?.('expressive:reload', (event) => remember((event as CustomEvent).detail));\n\n hot.on('expressive-inspect:ask', async ({ rid, call }: Ask) => {\n try {\n const value = !call\n ? { id, url: location.href, title: document.title, top: window.self === window.top }\n : call[0].join('.') == 'act'\n ? await act(call[1][0], call[1][1] as Act)\n : await dispatch(call);\n\n hot.send('expressive-inspect:answer', { rid, value: JSON.parse(JSON.stringify(value) ?? 'null') });\n } catch (error) {\n hot.send('expressive-inspect:answer', { rid, error: error instanceof Error ? error.message : String(error) });\n }\n });\n\n hot.send('expressive-inspect:hello', { id });\n}\n"],"mappings":";;;;AAeA,MAAM,WAAW,QAAgB,GAAG,SAAoB,SAAS,CAAC,CAAC,WAAW,OAAO,EAAE,KAAK,CAAC;AAE7F,eAAe,IAAI,MAAe,SAAe;AAC/C,KAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,OAAO,KAAK,MAAM,SAC5C,OAAM,IAAI,MAAM,8DAA4D;CAS9E,MAAM,EAAE,OAAO,QAAQ,SAAS,SAAS,YAAY,MAAM,QAP5C;EACb,SAAS,GAAG,YAAuB,QAAQ,UAAU,GAAG,QAAQ;EAChE,WAAW,QAAQ,MAAM;EACzB,SAAS,UAAiB,QAAQ,UAAU,MAAM;EAClD,MAAM,YAAoB,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;EACzD,QAEgF,SAAS,CAAC,KAAK,GAAG,MAAM,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,SAAS,KAAK;AAEpJ,QAAO;EAAE,OAAO,SAAS;EAAM;EAAQ;EAAS;EAAS;EAAS;;AAGpE,MAAM,SAAS;;AAGf,SAAS,SAAS,QAAiB;AACjC,KAAI;AACF,iBAAe,QAAQ,QAAQ,KAAK,UAAU,OAAO,CAAC;SAChD;;AAGV,SAAS,SAAS;AAChB,KAAI;EACF,MAAM,SAAS,eAAe,QAAQ,OAAO;AAE7C,MAAI,WAAW,KAAM;AAErB,iBAAe,WAAW,OAAO;AACjC,SAAO,KAAK,MAAM,OAAO;SACnB;;AAGV,SAAgB,QAAQ,KAAU;CAChC,MAAM,KAAK,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;AAEjD,KAAI,QAAQ,SAAS,CAAC,UAAU,MAAO,SAAQ,UAAU,EAAE,OAAO,QAAQ,CAAC;CAE3E,MAAM,WAAW,QAAQ;AAEzB,KAAI,SAAU,SAAQ,OAAO,UAAU,SAAS;AAEhD,KAAI,GAAG,sBAAsB,EAAE,cAA+C;AAC5E,UAAQ,OAAO,UAAU,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC;GAC9D;AAEF,KAAI,GAAG,0BAA0B,EAAE,MAAM,gBAAyD,EAAE,KAAK;AACvG,WAAS;GAAE;GAAM;GAAa,CAAC;GAC/B;AAEF,YAAW,mBAAmB,sBAAsB,UAAU,SAAU,MAAsB,OAAO,CAAC;AAEtG,KAAI,GAAG,0BAA0B,OAAO,EAAE,KAAK,WAAgB;AAC7D,MAAI;GACF,MAAM,QAAQ,CAAC,OACX;IAAE;IAAI,KAAK,SAAS;IAAM,OAAO,SAAS;IAAO,KAAK,OAAO,SAAS,OAAO;IAAK,GAClF,KAAK,GAAG,KAAK,IAAI,IAAI,QACnB,MAAM,IAAI,KAAK,GAAG,IAAI,KAAK,GAAG,GAAU,GACxC,MAAM,SAAS,KAAK;AAE1B,OAAI,KAAK,6BAA6B;IAAE;IAAK,OAAO,KAAK,MAAM,KAAK,UAAU,MAAM,IAAI,OAAO;IAAE,CAAC;WAC3F,OAAO;AACd,OAAI,KAAK,6BAA6B;IAAE;IAAK,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAAE,CAAC;;GAE/G;AAEF,KAAI,KAAK,4BAA4B,EAAE,IAAI,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expressive/inspect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "In-process inspector for Expressive MVC - registry, ownership tree, path queries, and a frame journal for agents, tests, and devtools.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"expressive",
|
|
@@ -59,10 +59,12 @@
|
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "tsdown",
|
|
62
|
-
"
|
|
62
|
+
"typecheck": "tsc --noEmit --incremental",
|
|
63
|
+
"coverage": "vitest run --coverage",
|
|
64
|
+
"test": "bun run typecheck && bun run coverage"
|
|
63
65
|
},
|
|
64
66
|
"peerDependencies": {
|
|
65
|
-
"@expressive/mvc": "^0.
|
|
67
|
+
"@expressive/mvc": "^0.88.0",
|
|
66
68
|
"vite": ">=5"
|
|
67
69
|
},
|
|
68
70
|
"peerDependenciesMeta": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bracket-CWa4p56P.js","names":[],"sources":["../src/settle.ts","../src/bracket.ts"],"sourcesContent":["import type { Frame, Options } from './journal';\n\nexport const SETTLE_TIMEOUT = 1000;\n\nexport interface Act {\n /**\n * What to wait for before settling: `Type.key` / `id.key` addresses that must each see a frame after the\n * step's synchronous writes, or `{ [address]: value }` pairs that must each hold that value.\n */\n until?: string | string[] | Record<string, unknown>;\n /** Longest to wait, in ms; default 1000. */\n timeout?: number;\n /** Recording filters for this window, instead of the journal's - `{ paths: [], types: [], keys: [] }` records everything. */\n record?: Omit<Options, 'level'>;\n}\n\nexport const tick = () => new Promise((resolve) => setTimeout(resolve, 0));\n\n/** Wait a macrotask at a time until one passes with no new frame. Resolves `false` if `timeout` passes first. */\nexport async function settle(seq: () => number | Promise<number>, wait: () => unknown = tick, timeout = SETTLE_TIMEOUT) {\n const end = Date.now() + timeout;\n\n for (let last = await seq(); ; ) {\n await wait();\n\n const next = await seq();\n\n if (next === last) return true;\n if (Date.now() >= end) return false;\n\n last = next;\n }\n}\n\nexport function unsettled(timeout = SETTLE_TIMEOUT) {\n console.warn(\n `Still active after ${timeout}ms - frames may be incomplete. Narrow the recording ({ record: { types, paths, keys } }) to exclude background work, or pass { timeout }.`\n );\n}\n\n/** `until` not met within `timeout` - carries the frames recorded so far and what never arrived. */\nexport function unreached(timeout: number, pending: string[], missing: string[], frames: Frame[], hint = '') {\n const list = pending.map((address) => (missing.includes(address) ? `${address} (names no instance)` : address));\n return Object.assign(new Error(`Not reached within ${timeout}ms: ${list.join(', ')}.${hint}`), { frames, pending });\n}\n","import type { Frame, Options, Query } from './journal';\nimport { SETTLE_TIMEOUT, settle, type Act } from './settle';\n\nexport interface Remote {\n record(options?: Options): Required<Options> | Promise<Required<Options>>;\n seq(): number | Promise<number>;\n frames(query: Query): Frame[] | Promise<Frame[]>;\n get(address: string): unknown;\n}\n\n/** Resolve `address.key` to the instance `address` names - label, id, or owner path - so frames match it alone. */\n/** Resolve `address.key` to the instance `address` names - label, id, or owner path - as the `id.key` its frames carry. */\nasync function locate(remote: Remote, target: string) {\n const dot = target.lastIndexOf('.');\n const found = (await remote.get(target.slice(0, dot))) as { $ref?: string } | undefined;\n\n if (!found?.$ref) throw new Error(`until ${target}: ${target.slice(0, dot)} names no State.`);\n\n return `${found.$ref}.${target.slice(dot + 1)}`;\n}\n\n/**\n * Run `step` recording values, wait for `until`, settle, and return what it produced; the prior recording is restored.\n * `local` steps run here, so activity for `until` counts once their synchronous writes flush, not once they resolve.\n */\nexport async function bracket(\n remote: Remote,\n step: () => unknown,\n wait: () => unknown,\n { until = [], timeout = SETTLE_TIMEOUT, record }: Act = {},\n local?: boolean\n) {\n const before = await remote.record();\n const since = await remote.seq();\n const window = { ...before, ...record };\n const filtered = window.types.length + window.paths.length + window.keys.length > 0;\n const values = typeof until == 'string' || Array.isArray(until) ? undefined : until;\n const addresses = values ? [] : ([] as string[]).concat(until as string | string[]);\n const paths = filtered ? [...window.paths, ...addresses.filter((address) => address.indexOf('.') === address.lastIndexOf('.'))] : [];\n\n await remote.record({ ...record, level: 'values', ...(filtered && { paths }) });\n\n try {\n const running = step();\n let from: number | undefined;\n\n if (local) {\n await undefined;\n from = await remote.seq();\n }\n\n const value = await running;\n\n from ??= await remote.seq();\n const end = Date.now() + timeout;\n const pending = new Set(values ? Object.keys(values) : addresses);\n const targets = new Map<string, string>();\n\n for (const address of addresses) targets.set(address, await locate(remote, address));\n\n if (filtered && addresses.some((address) => address.indexOf('.') !== address.lastIndexOf('.')))\n await remote.record({ paths: [...paths, ...targets.values()] });\n\n while (pending.size) {\n if (values) {\n for (const address of pending)\n if (JSON.stringify(await remote.get(address)) === JSON.stringify(values[address])) pending.delete(address);\n } else\n for (const frame of await remote.frames({ since: from }))\n for (const event of frame.events)\n for (const address of pending) if (targets.get(address) === `${event.id}.${event.key}`) pending.delete(address);\n\n if (!pending.size || Date.now() >= end) break;\n\n await wait();\n }\n\n const settled = !pending.size && (await settle(remote.seq, wait, Math.max(0, end - Date.now())));\n const missing: string[] = [];\n\n if (values)\n for (const address of pending)\n if ((await remote.get(address.slice(0, address.lastIndexOf('.')))) === undefined) missing.push(address);\n\n return { value, frames: await remote.frames({ since }), settled, pending: [...pending], missing, timeout };\n } finally {\n await remote.record(before);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inspect-FXOcmfKP.js","names":[],"sources":["../src/serialize.ts","../src/types.ts","../src/journal.ts","../src/inspect.ts"],"sourcesContent":["import { State } from '@expressive/mvc';\n\nconst MAX_STRING = 240;\nconst MAX_ARRAY = 24;\nconst MAX_KEYS = 40;\n\nexport type Address = { target: string; path?: string };\n\nexport function parsePath(raw: string): Address {\n const trimmed = raw.trim();\n const dot = trimmed.indexOf('.');\n if (dot <= 0) return { target: trimmed };\n return { target: trimmed.slice(0, dot), path: trimmed.slice(dot + 1) };\n}\n\n/** Raw stored entries of a State - never reads through accessors. */\nexport function entries(state: State): Map<string, unknown> {\n return new Map(state);\n}\n\n/** Walk `path` without triggering getters, factories, or suspense. */\nexport function walk(value: unknown, path?: string): unknown {\n if (!path) return value;\n let cur: unknown = value;\n for (const part of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined;\n if (cur instanceof State) cur = entries(cur).get(part);\n else if (cur instanceof Map) cur = cur.get(part);\n else cur = (cur as Record<string, unknown>)[part];\n }\n return cur;\n}\n\nexport function ref(state: State) {\n return { $ref: String(state), $type: state.constructor.name };\n}\n\n/** `true` takes a value as `serialize` would; an object picks keys and descends, applying to each element of a list. */\nexport type Select = true | { [key: string]: Select };\n\n/** Only the selected keys, read in one synchronous pass - a consistent snapshot. States keep their `$ref`. */\nexport function project(value: unknown, select: Select): unknown {\n if (select === true || value == null || typeof value !== 'object') return serialize(value);\n\n const items = value instanceof State ? undefined : list(value);\n\n if (items) {\n const out = items.slice(0, MAX_ARRAY).map((row) => project(row, select));\n if (items.length > MAX_ARRAY) out.push(`…+${items.length - MAX_ARRAY}`);\n return out;\n }\n\n const out: Record<string, unknown> = value instanceof State ? ref(value) : {};\n for (const key in select) out[key] = project(walk(value, key), select[key]);\n return out;\n}\n\n/** JSON-safe, size-capped view. Nested States collapse to `$ref`. */\nexport function serialize(value: unknown, depth = 2): unknown {\n if (value instanceof State) {\n const out: Record<string, unknown> = ref(value);\n for (const [key, child] of [...entries(value)].slice(0, MAX_KEYS))\n out[key] = write(child, depth - 1);\n return out;\n }\n return write(value, depth);\n}\n\nfunction write(value: unknown, depth: number): unknown {\n if (value == null || typeof value === 'boolean') return value;\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value);\n if (typeof value === 'string')\n return value.length > MAX_STRING ? `${value.slice(0, MAX_STRING - 1)}…` : value;\n if (typeof value === 'bigint') return `${value}n`;\n if (typeof value !== 'object') return undefined;\n if (value instanceof State) return ref(value);\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Error) return { name: value.name, message: value.message };\n if (typeof (value as PromiseLike<unknown>).then === 'function') return '(pending)';\n\n const items = list(value);\n\n if (items) {\n if (depth <= 0) return `[${items.length}]`;\n const out = items.slice(0, MAX_ARRAY).map((row) => write(row, depth - 1));\n if (items.length > MAX_ARRAY) out.push(`…+${items.length - MAX_ARRAY}`);\n return out;\n }\n\n const pairs = value instanceof Map\n ? [...value].map(([k, v]) => [String(k), v] as const)\n : Object.entries(value);\n\n if (depth <= 0) return `{${pairs.length}}`;\n\n const out: Record<string, unknown> = {};\n for (const [key, child] of pairs.slice(0, MAX_KEYS)) {\n if (key === 'is') continue;\n const next = write(child, depth - 1);\n if (next !== undefined) out[key] = next;\n }\n if (pairs.length > MAX_KEYS) out['…'] = pairs.length - MAX_KEYS;\n return out;\n}\n\nfunction list(value: object): unknown[] | undefined {\n if (Array.isArray(value)) return value;\n if (value instanceof Map) return undefined;\n if (typeof (value as Iterable<unknown>)[Symbol.iterator] === 'function')\n return [...(value as Iterable<unknown>)];\n return undefined;\n}\n","import { State } from '@expressive/mvc';\n\nexport interface TypeInfo {\n /** Opaque, stable for the life of the process. */\n typeId: string;\n /** Resolved display name - see `label`. */\n type: string;\n /** Construction stack captured at first sight, for a source-map resolver. */\n site: string;\n}\n\nconst info = new Map<typeof State, TypeInfo>();\nconst labels = new Map<typeof State, string>();\nconst names = new Map<string, string>();\nlet count = 0;\n\nfunction register(Type: typeof State): TypeInfo {\n let row = info.get(Type);\n if (!row) {\n const site = String(new Error().stack).split('\\n').slice(1, 16).join('\\n');\n info.set(Type, (row = { typeId: `T${++count}`, type: '', site }));\n }\n return row;\n}\n\nexport function seen(Type: typeof State): TypeInfo {\n const row = register(Type);\n row.type = labelOf(Type);\n return { ...row };\n}\n\nexport function labelOf(Type: typeof State): string {\n const row = register(Type);\n const explicit = labels.get(Type) ?? (Type as { displayName?: string }).displayName;\n if (explicit) return explicit;\n const named = names.get(row.typeId) ?? names.get(row.site);\n if (named) return named;\n return Type.name.length > 2 ? Type.name : row.typeId;\n}\n\nexport function label(Type: typeof State, name: string): void {\n labels.set(Type, name);\n}\n\n/** Supply resolved names keyed by `typeId` or `site`, e.g. from a source-map pass. */\nexport function resolve(table: Record<string, string>): void {\n for (const [key, name] of Object.entries(table)) names.set(key, name);\n}\n\nexport function forget(): void {\n info.clear();\n labels.clear();\n names.clear();\n count = 0;\n}\n","import { Caught, State } from '@expressive/mvc';\n\nimport { parsePath, serialize } from './serialize';\nimport { labelOf, seen } from './types';\n\nexport type Level = 'off' | 'keys' | 'values';\n\nexport interface Options {\n level?: Level;\n /** Labels to record. */\n types?: string[];\n /** `Type.key` addresses to record - label, `typeId`, or instance id on the left, property on the right. */\n paths?: string[];\n /** Property names to record on any type. */\n keys?: string[];\n /** Also record method calls (wraps instance methods except `render`). */\n calls?: boolean;\n}\n\nexport interface Event {\n id: string;\n type: string;\n key: string;\n kind: 'update' | 'event' | 'call' | 'destroy' | 'caught';\n value?: unknown;\n args?: unknown[];\n}\n\nexport interface Frame {\n seq: number;\n at: number;\n /** Frame whose flush scheduled the work that opened this one. */\n cause?: number;\n events: Event[];\n}\n\nexport interface Summary {\n id: string;\n type: string;\n /** Seq of the last frame touching this instance. */\n last: number;\n /** Updates and events per key, with the last recorded value at `values` level. */\n keys: Record<string, { count: number; value?: unknown }>;\n calls: Record<string, number>;\n /** `caught` reports. */\n caught: number;\n destroyed: boolean;\n}\n\nexport interface Query {\n since?: number;\n type?: string;\n id?: string;\n key?: string;\n cause?: number;\n}\n\nconst FRAME_CAP = 500;\n\nconst frames: Frame[] = [];\nconst config: Required<Options> = { level: 'off', types: [], paths: [], keys: [], calls: false };\nlet seq = 0;\nlet open: Frame | undefined;\nlet cause: number | undefined;\n\nexport const journal = {\n record(options: Options = {}): Required<Options> {\n Object.assign(config, options);\n if (!options.level && options.calls && config.level === 'off') config.level = 'keys';\n return { ...config, types: [...config.types], paths: [...config.paths], keys: [...config.keys] };\n },\n\n frames(query: Query = {}): Frame[] {\n const out: Frame[] = [];\n for (const frame of frames) {\n if (query.since !== undefined && frame.seq <= query.since) continue;\n if (query.cause !== undefined && frame.cause !== query.cause) continue;\n const events = frame.events.filter((e) => matches(e, query));\n if (events.length) out.push({ ...frame, events });\n }\n return out;\n },\n\n history(query: Query): Array<{ seq: number; at: number; event: Event }> {\n const out = [];\n for (const frame of journal.frames(query))\n for (const event of frame.events) out.push({ seq: frame.seq, at: frame.at, event });\n return out;\n },\n\n /** Frames reachable from `seq` through `cause` links, in order. */\n downstream(from: number): Frame[] {\n const roots = new Set([from]);\n return frames.filter((frame) => {\n if (frame.cause === undefined || !roots.has(frame.cause)) return false;\n roots.add(frame.seq);\n return true;\n });\n },\n\n /** Current sequence - pass as `since` to read only what follows. */\n seq(): number {\n return seq;\n },\n\n /** One event per line, for bulk export to a sidecar. */\n export(query: Query = {}): string {\n return journal\n .frames(query)\n .flatMap((frame) =>\n frame.events.map((event) =>\n JSON.stringify({ seq: frame.seq, at: frame.at, cause: frame.cause, ...event })\n )\n )\n .join('\\n');\n },\n\n /** Per-instance digest of recorded frames, most recently active first. */\n summary(query: Query = {}): Summary[] {\n const by = new Map<string, Summary>();\n\n for (const frame of journal.frames(query))\n for (const event of frame.events) {\n let entry = by.get(event.id);\n\n if (!entry) by.set(event.id, (entry = { id: event.id, type: event.type, last: 0, keys: {}, calls: {}, caught: 0, destroyed: false }));\n\n entry.last = frame.seq;\n\n if (event.kind === 'destroy') entry.destroyed = true;\n else if (event.kind === 'call') entry.calls[event.key] = (entry.calls[event.key] || 0) + 1;\n else if (event.kind === 'caught') entry.caught++;\n else {\n const key = (entry.keys[event.key] ||= { count: 0 });\n key.count++;\n if ('value' in event) key.value = event.value;\n }\n }\n\n return [...by.values()].sort((a, b) => b.last - a.last);\n },\n\n clear(): void {\n frames.length = 0;\n open = undefined;\n cause = undefined;\n seq = 0;\n },\n\n reset(): void {\n journal.clear();\n Object.assign(config, { level: 'off', types: [], paths: [], keys: [], calls: false });\n }\n};\n\nfunction matches(event: Event, query: Query) {\n return (\n (!query.type || event.type === query.type) &&\n (!query.id || event.id === query.id) &&\n (!query.key || event.key === query.key)\n );\n}\n\n/** Filters OR together; none set records everything. Without a key only type-level filters apply. */\nexport function wants(state: State, key?: string): boolean {\n if (config.level === 'off') return false;\n\n const { types, paths, keys } = config;\n if (!types.length && !paths.length && !keys.length) return true;\n\n const Type = state.constructor as typeof State;\n const label = labelOf(Type);\n if (types.includes(label)) return true;\n if (key !== undefined && keys.includes(key)) return true;\n\n const targets = [label, seen(Type).typeId, String(state)];\n for (const address of paths) {\n const { target, path } = parsePath(address);\n if (targets.includes(target) && (key === undefined || path === key)) return true;\n }\n return false;\n}\n\nexport function recordsCalls(): boolean {\n return config.calls && config.level !== 'off';\n}\n\n\nexport function note(state: State, key: unknown, store: Map<string, unknown>): void {\n const name = String(key);\n if (!wants(state, name)) return;\n\n const event: Event = {\n id: String(state),\n type: labelOf(state.constructor as typeof State),\n key: name,\n kind: typeof key === 'string' && store.has(key) ? 'update' : 'event'\n };\n\n if (config.level === 'values' && event.kind === 'update')\n event.value = serialize(store.get(name), 1);\n\n push(event);\n}\n\nexport function noteCall(state: State, key: string, args: unknown[]): void {\n if (!recordsCalls() || !wants(state, key)) return;\n\n const event: Event = { id: String(state), type: labelOf(state.constructor as typeof State), key, kind: 'call' };\n if (config.level === 'values') event.args = args.map((arg) => serialize(arg, 1));\n push(event);\n}\n\nexport function noteCaught(error: Caught, name: string): { handled: boolean } | undefined {\n const { state, key } = error;\n if (!wants(state, key)) return;\n const value = { case: name, message: error.message, stack: error.stack, handled: true };\n push({ id: String(state), type: labelOf(state.constructor as typeof State), key: key ?? '', kind: 'caught', value });\n return value;\n}\n\nexport function noteDestroy(state: State): void {\n if (!wants(state)) return;\n push({ id: String(state), type: labelOf(state.constructor as typeof State), key: '', kind: 'destroy' });\n}\n\nfunction push(event: Event) {\n if (!open) {\n const frame: Frame = { seq: ++seq, at: Date.now(), events: [] };\n if (cause !== undefined) frame.cause = cause;\n open = frame;\n frames.push(frame);\n if (frames.length > FRAME_CAP) frames.splice(0, frames.length - FRAME_CAP);\n queueMicrotask(() => {\n open = undefined;\n cause = frame.seq;\n queueMicrotask(() => {\n if (seq === frame.seq) cause = undefined;\n });\n });\n }\n open.events.push(event);\n}\n","import { Caught, Context, State } from '@expressive/mvc';\nimport { isElement } from '@expressive/mvc/runtime';\n\nimport { journal, note, noteCall, noteCaught, noteDestroy, recordsCalls, type Frame, type Query } from './journal';\nimport { entries, parsePath, project, serialize, walk, type Select } from './serialize';\nimport { bracket } from './bracket';\nimport { tick, unreached, unsettled, type Act } from './settle';\nimport { forget, seen, type TypeInfo } from './types';\n\nexport interface Model extends TypeInfo {\n id: string;\n parent?: string;\n /** Keys with a stored value. */\n keys: string[];\n /** Declared keys with no stored value yet - lazy, pending, or uncomputed. */\n absent: string[];\n}\n\nexport interface Node {\n id: string;\n type: string;\n children: Node[];\n}\n\ninterface Span {\n since: number;\n until?: number;\n claimed: boolean;\n settled: boolean;\n}\n\ninterface Row {\n ref: { deref(): State | undefined };\n held?: State;\n}\n\nconst Reaper: typeof FinalizationRegistry =\n typeof FinalizationRegistry === 'function'\n ? FinalizationRegistry\n : (class {\n register() {}\n unregister() {}\n } as unknown as typeof FinalizationRegistry);\n\nconst weak = (state: State): Row['ref'] =>\n typeof WeakRef === 'function' ? new WeakRef(state) : { deref: () => state };\n\nconst live = new Map<string, Row>();\nconst hooks = new Map<typeof State, () => void>();\n\nconst CASES = ['Destroyed', 'Inactive', 'Getter', 'Init', 'Effect'] as const;\nconst COPIES = Symbol.for('@expressive/mvc');\n\ntype Case = (typeof CASES)[number];\nconst wrapped = new WeakSet<State>();\nconst wrappers = new WeakMap<State, Instance>();\nconst spans = new WeakMap<State, Span>();\nconst reaper = new Reaper<string>(collected);\n\nlet version = 0;\nlet cached: { version: number; parents: Map<State, State> } | undefined;\nlet lost = 0;\nlet tally = counts();\nlet copies = 1;\nlet unwatch: (() => void) | undefined;\n\nfunction counts(): Record<Case, number> {\n return { Destroyed: 0, Inactive: 0, Getter: 0, Init: 0, Effect: 0 };\n}\n\nconst noted = new WeakMap<Caught, { handled: boolean } | undefined>();\n\nfunction observe(error: Caught) {\n const name = CASES.find((type) => error instanceof Caught[type]);\n if (name) tally[name]++;\n noted.set(error, noteCaught(error, name || 'Caught'));\n return error;\n}\n\nfunction unhandled(error: Caught) {\n if (!noted.has(error)) observe(error);\n const event = noted.get(error);\n if (event) event.handled = false;\n return error;\n}\n\nexport function clearCaught(): void {\n tally = counts();\n}\n\n/** Count loaded copies of mvc from the list each one joins on first construction; warn once on a second. */\nfunction watchCopies() {\n const list = ((globalThis as { [COPIES]?: unknown[] })[COPIES] ||= []);\n const { push } = list;\n const check = () => {\n const was = copies;\n copies = new Set([State, ...list]).size;\n if (copies > 1 && was === 1)\n console.warn(`${copies} copies of @expressive/mvc are loaded - inspect sees only the one it imports.`);\n };\n\n list.push = (...items) => {\n const length = push.apply(list, items);\n check();\n return length;\n };\n\n check();\n unwatch = () => {\n list.push = push;\n };\n}\n\n/** Registered instances still reachable, claimed or not. */\nfunction registered(): State[] {\n return [...live.values()]\n .map((row) => row.held ?? row.ref.deref())\n .filter((state): state is State => !!state);\n}\n\n/** Instances on the mainline: claimed, or too young to judge, or every one when no host renders. */\nfunction* mainline(): Generator<State> {\n const parents = ownership();\n for (const state of registered()) if (!orphaned(state, parents)) yield state;\n}\n\nfunction orphaned(state: State, parents: Map<State, State>, seen = new Set<State>()): boolean {\n const span = spans.get(state)!;\n if (span.claimed || !span.settled || !hosted()) return false;\n if (provided(state)) {\n claim(state);\n return false;\n }\n const owner = parents.get(state);\n if (!owner || seen.has(owner)) return true;\n seen.add(state);\n if (orphaned(owner, parents, seen)) return true;\n if (spans.get(owner)!.claimed) claim(state);\n return false;\n}\n\nfunction claim(state: State) {\n const span = spans.get(state)!;\n if (span.claimed) return;\n span.claimed = true;\n const row = live.get(String(state));\n if (row) {\n row.held = state;\n reaper.unregister(state);\n }\n version++;\n}\n\n/** A `static global` instance currently holding its slot in the root context. */\nfunction provided(state: State): boolean {\n const type = state.constructor as typeof State;\n const global = typeof type.global === 'function' ? type.global(state) : type.global;\n if (!global) return false;\n for (const set of Context.root.provide.values())\n if (set) for (const [member] of set) if (member === state) return true;\n return false;\n}\n\nfunction hosted(): boolean {\n try {\n isElement(null);\n return true;\n } catch {\n return false;\n }\n}\n\n/** A registered, unclaimed instance was garbage collected - it was abandoned. */\nexport function collected(id: string): void {\n if (!live.delete(id)) return;\n lost++;\n version++;\n}\n\n/** Navigable view of one instance - identity, ownership, reads, observation. One per state; outlives it. */\nexport class Instance {\n private constructor(readonly state: State) {}\n\n static of(state: State): Instance {\n let instance = wrappers.get(state);\n if (!instance) wrappers.set(state, (instance = new Instance(state)));\n return instance;\n }\n\n get id() {\n return String(this.state);\n }\n\n get type() {\n return seen(this.state.constructor as typeof State).type;\n }\n\n get alive() {\n return live.has(this.id);\n }\n\n /** Reached by a host commit (`mount`), a claimed owner, or `static global`. Always true without a host. */\n get claimed() {\n return !orphaned(this.state, ownership());\n }\n\n /** Registration time (ms). */\n get since() {\n return spans.get(this.state)!.since;\n }\n\n /** Destruction time (ms), once destroyed. */\n get until() {\n return spans.get(this.state)!.until;\n }\n\n get parent(): Instance | undefined {\n const owner = ownership().get(this.state);\n return owner && Instance.of(owner);\n }\n\n get children(): Instance[] {\n const parents = ownership();\n return [...registered()]\n .filter((state) => parents.get(state) === this.state)\n .map(Instance.of);\n }\n\n /** First instance in this subtree, depth-first, matching `where` (a label or predicate). */\n find(where: string | ((instance: Instance) => boolean)): Instance | undefined {\n const test = typeof where === 'string' ? (h: Instance) => h.type === where : where;\n for (const child of this.children) {\n if (test(child)) return child;\n const deep = child.find(test);\n if (deep) return deep;\n }\n return undefined;\n }\n\n get(path?: string, select?: Select): unknown {\n const value = walk(this.state, path);\n return select ? project(value, select) : serialize(value);\n }\n\n model(): Model {\n return describe(this.state, ownership());\n }\n\n /** Run `work`, settle, and return the frames it produced. */\n act(work: (state: State) => unknown, options?: Act): Promise<Frame[]> {\n return act(() => work(this.state), options);\n }\n\n /** Call `fn` on each update, and with `null` on destroy; `keys` narrows updates. Returns unsubscribe. */\n watch(fn: (key: string | null) => void, keys?: string[]): () => void {\n const updates = this.state.set((key) => {\n if (typeof key === 'string' && (!keys || keys.includes(key))) fn(key);\n });\n const destroy = this.state.get(null, () => fn(null));\n return () => {\n updates();\n destroy();\n };\n }\n\n frames(query: Query = {}): Frame[] {\n return journal.frames({ ...query, id: this.id });\n }\n}\n\nexport function attach(Type: typeof State = State): () => void {\n if (!unwatch) watchCopies();\n\n if (!hooks.has(Type)) {\n const observed = new Map<typeof State, () => void>();\n const stopCatch = Type.on({ catch: unhandled });\n const stopSetup = Type.on(function (this: State) {\n const self = this.is;\n const T = self.constructor as typeof State;\n const id = String(self);\n const span: Span = { since: Date.now(), claimed: false, settled: false };\n if (!observed.has(T)) observed.set(T, T.on({ catch: observe }));\n seen(T);\n live.set(id, { ref: weak(self) });\n spans.set(self, span);\n reaper.register(self, id, self);\n setTimeout(() => {\n span.settled = true;\n }, 0);\n version++;\n if (recordsCalls()) wrap(self);\n mounts(self);\n const stop = self.set((key) => {\n const store = entries(self);\n if (typeof key === 'string' && typeof store.get(key) === 'object') version++;\n note(self, key, store);\n });\n return () => {\n stop();\n live.delete(id);\n reaper.unregister(self);\n span.until = Date.now();\n version++;\n noteDestroy(self);\n };\n });\n\n hooks.set(Type, () => {\n for (const stop of observed.values()) stop();\n stopCatch();\n stopSetup();\n });\n }\n\n return () => {\n hooks.get(Type)?.();\n hooks.delete(Type);\n };\n}\n\nexport function detach(): void {\n for (const stop of hooks.values()) stop();\n hooks.clear();\n live.clear();\n cached = undefined;\n lost = 0;\n tally = counts();\n copies = 1;\n unwatch?.();\n unwatch = undefined;\n journal.reset();\n forget();\n}\n\n/** Resolve an id or label to an instance - mainline first, then orphans. */\nexport function find(target: string): Instance | undefined {\n const byId = live.get(target);\n const held = byId && (byId.held ?? byId.ref.deref());\n if (held) return Instance.of(held);\n\n const types = new Map<typeof State, string>();\n let first: State | undefined;\n\n for (const pool of [mainline(), abandoned()])\n for (const state of pool) {\n const Type = state.constructor as typeof State;\n const info = seen(Type);\n if (info.type !== target) continue;\n first ??= state;\n types.set(Type, info.typeId);\n }\n\n if (types.size > 1)\n throw new Error(\n `${target} matches ${types.size} classes (${[...types.values()].join(', ')}) - address by instance id or owner path, or label() one. models() lists their construction sites.`\n );\n\n return first && Instance.of(first);\n}\n\nexport function instances(): Instance[] {\n return [...mainline()].map(Instance.of);\n}\n\n/** Registered and settled, but never claimed by a host commit, an owner, or root context. */\nexport function orphans(): Instance[] {\n return [...abandoned()].map(Instance.of);\n}\n\nfunction* abandoned(): Generator<State> {\n const parents = ownership();\n for (const state of registered()) if (orphaned(state, parents)) yield state;\n}\n\nexport interface Health {\n /** Live instances no host, owner, or root slot claimed. */\n orphans: number;\n /** Unclaimed instances the collector already reaped. */\n collected: number;\n /** Loaded copies of `@expressive/mvc` - more than 1 means inspect cannot see every State. */\n copies: number;\n /** `Caught` reports by case, including ones an app handler went on to handle; zeroed by `journal.clear()`. */\n caught: Record<Case, number>;\n}\n\n/** Counts worth a look before trusting what inspect shows. */\nexport function health(): Health {\n return { orphans: orphans().length, collected: lost, copies, caught: { ...tally } };\n}\n\nexport function roots(): Instance[] {\n const parents = ownership();\n return instances().filter((instance) => !parents.has(instance.state));\n}\n\nexport function models(): Model[] {\n const parents = ownership();\n return [...mainline()].map((state) => describe(state, parents));\n}\n\nexport function tree(): Node[] {\n const parents = ownership();\n const nodes = new Map<State, Node>();\n const out: Node[] = [];\n\n for (const state of mainline())\n nodes.set(state, { id: String(state), type: seen(state.constructor as typeof State).type, children: [] });\n\n for (const [state, node] of nodes) {\n const parent = parents.get(state);\n const owner = parent && nodes.get(parent);\n if (owner) owner.children.push(node);\n else out.push(node);\n }\n\n return out;\n}\n\n/** Run `work` recording values; returns the frames it produced once `until` holds and activity goes quiet. */\nexport async function act(work: () => unknown, options: Act = {}): Promise<Frame[]> {\n const { frames, settled, pending, missing, timeout } = await bracket({ ...journal, get }, work, tick, options, true);\n if (pending.length) throw unreached(timeout, pending, missing, frames);\n if (!settled) unsettled(timeout);\n return frames;\n}\n\nexport function get(address?: string, select?: Select): unknown {\n if (!address) return models();\n const { target, path } = parsePath(address);\n return find(target)?.get(path, select);\n}\n\nexport function set(address: string, value: unknown): void {\n const { target, path } = parsePath(address);\n const instance = find(target);\n if (!instance || !path) throw new Error(`No model at ${address}.`);\n\n const dot = path.lastIndexOf('.');\n const key = path.slice(dot + 1);\n const owner = dot < 0 ? instance.state : walk(instance.state, path.slice(0, dot));\n\n if (owner == null || typeof owner !== 'object') throw new Error(`No model at ${address}.`);\n\n if (owner instanceof Map) owner.set(key, value);\n else (owner as Record<string, unknown>)[key] = value;\n}\n\nexport async function call(address: string, ...args: unknown[]): Promise<unknown> {\n const { target, path } = parsePath(address);\n const state = find(target)?.state;\n const method = state && path && (state as unknown as Record<string, unknown>)[path];\n\n if (typeof method !== 'function') throw new Error(`No method at ${address}.`);\n\n return serialize(await method.apply(state, args));\n}\n\nexport function wrapAll(): void {\n for (const state of registered()) wrap(state);\n}\n\n/** Observe the host commit: adapters call `mount?.()` once an instance is placed. */\nfunction mounts(state: State) {\n const target = state as State & { mount?: (...args: unknown[]) => unknown };\n const original = target.mount;\n\n Object.defineProperty(target, 'mount', {\n configurable: true,\n writable: true,\n value(this: unknown, ...args: unknown[]) {\n claim(state);\n return typeof original === 'function' ? original.apply(this, args) : undefined;\n }\n });\n}\n\nfunction describe(state: State, parents: Map<State, State>): Model {\n const stored = entries(state);\n const declared = Object.entries(Object.getOwnPropertyDescriptors(state))\n .filter(([, desc]) => typeof desc.get === 'function')\n .map(([key]) => key);\n const model: Model = {\n id: String(state),\n ...seen(state.constructor as typeof State),\n keys: [...stored.keys()],\n absent: declared.filter((key) => !stored.has(key))\n };\n const parent = parents.get(state);\n if (parent) model.parent = String(parent);\n return model;\n}\n\nfunction wrap(state: State) {\n if (wrapped.has(state)) return;\n wrapped.add(state);\n\n const target = state as unknown as Record<string, Function>;\n const seenKeys = new Set<string>(['render']);\n\n for (let proto = Object.getPrototypeOf(state); proto !== State.prototype; proto = Object.getPrototypeOf(proto))\n for (const [key, desc] of Object.entries(Object.getOwnPropertyDescriptors(proto))) {\n if (seenKeys.has(key) || typeof desc.get !== 'function' || desc.get !== desc.set) continue;\n\n seenKeys.add(key);\n\n const original = target[key];\n\n target[key] = function (this: unknown, ...args: unknown[]) {\n noteCall(state, key, args);\n return original.apply(this, args);\n };\n }\n}\n\nfunction ownership(): Map<State, State> {\n if (cached?.version !== version) {\n const parents = new Map<State, State>();\n\n for (const owner of registered())\n for (const [key, value] of entries(owner)) {\n const field = Object.getOwnPropertyDescriptor(owner, key)?.enumerable;\n if (field || !(value instanceof State)) own(parents, owner, value);\n }\n\n cached = { version, parents };\n }\n\n return cached.parents;\n}\n\nfunction own(parents: Map<State, State>, owner: State, value: unknown) {\n if (value instanceof State) {\n if (!parents.has(value) && value !== owner) parents.set(value, owner);\n } else if (value && typeof value === 'object' && Symbol.iterator in value) {\n const items = value instanceof Map ? value.values() : (value as Iterable<unknown>);\n for (const item of items) if (item instanceof State) own(parents, owner, item);\n }\n}\n"],"mappings":"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"}
|