flugrekorder 1.2.0 → 2.0.0-beta.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/README.md +59 -0
- package/dist/{flugrekorder.mjs → flugrekorder.cjs} +66 -43
- package/dist/flugrekorder.cjs.map +1 -0
- package/dist/{flugrekorder.d.mts → flugrekorder.d.cts} +2 -1
- package/dist/flugrekorder.d.ts +2 -1
- package/dist/flugrekorder.global.js +30 -41
- package/dist/flugrekorder.global.js.map +1 -1
- package/dist/flugrekorder.js +32 -78
- package/dist/flugrekorder.js.map +1 -1
- package/package.json +25 -18
- package/dist/flugrekorder.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -279,6 +279,62 @@ Certainly not the average request log, but a full picture of what happened when,
|
|
|
279
279
|
|
|
280
280
|
---
|
|
281
281
|
|
|
282
|
+
### Find the call behind a memory spike
|
|
283
|
+
|
|
284
|
+
flugrekorder knows nothing about memory — but the callback runs synchronously after every trap, so it can take a sample itself. A record fires only once a trap *returns*, though, and the call that runs a process out of memory never does. The `get` that looks a method up fires *before* the call, so it doubles as an entry marker.
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
import { openSync, writeSync } from 'node:fs';
|
|
288
|
+
import { create } from 'flugrekorder';
|
|
289
|
+
|
|
290
|
+
const log = openSync('memory.ndjson', 'w');
|
|
291
|
+
const write = (line: object) => writeSync(log, `${JSON.stringify(line)}\n`);
|
|
292
|
+
let peak = process.resourceUsage().maxRSS;
|
|
293
|
+
let seq = 0;
|
|
294
|
+
const id = () => `#${++seq}`;
|
|
295
|
+
|
|
296
|
+
// exit: every method becomes its own non-recursive proxy
|
|
297
|
+
for (const [key, fn] of Object.entries(processor)) {
|
|
298
|
+
processor[key] = create(fn, {
|
|
299
|
+
id,
|
|
300
|
+
only: ['apply'],
|
|
301
|
+
recursive: false,
|
|
302
|
+
depth: 0,
|
|
303
|
+
callback(r) {
|
|
304
|
+
const { maxRSS } = process.resourceUsage();
|
|
305
|
+
write({ id: r.id, exit: key, growth: Math.round((maxRSS - peak) / 1024) });
|
|
306
|
+
peak = maxRSS;
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// enter: looking up `p.method` fires just before calling it
|
|
312
|
+
const p = create(processor, {
|
|
313
|
+
id,
|
|
314
|
+
only: ['get'],
|
|
315
|
+
recursive: false,
|
|
316
|
+
callback: (r) => write({ id: r.id, enter: r.origin && 'key' in r.origin ? r.origin.key : '?' }),
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
`memory.ndjson` after a crash ends with a call that was entered but never exited:
|
|
321
|
+
|
|
322
|
+
```json
|
|
323
|
+
{"id":"#13","exit":"parse","growth":85}
|
|
324
|
+
{"id":"#14","enter":"normalise"}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Without the memory limit, the same run reports `{"exit":"normalise","growth":213}`, while `heapUsed` *dropped* by 66MB across that call. Some details matter more than they look:
|
|
328
|
+
|
|
329
|
+
- **`maxRSS`, not `heapUsed`.** Garbage collection can run between the spike and the sample, so the heap may look fine afterwards. `maxRSS` is a high-water mark: its growth per call is what each call cost at its worst. `Buffer` contents count towards `external`, not the heap.
|
|
330
|
+
- **`writeSync`, not `stream`.** A Writable buffers in memory, adding to the spike, and whatever is still buffered when the process dies is lost.
|
|
331
|
+
- **`recursive: false`.** Proxying the payload records every element read and keeps every one of them alive in the graph. The recorder becomes the leak.
|
|
332
|
+
- **`depth: 0`.** The default `depth: Infinity` serializes plain-object arguments by value, so a `Buffer` argument is serialized byte by byte. Here it also stops the `apply` record from serializing `this`, which is the `enter` proxy: reading its keys would fire its `get` trap and log entries that never happened.
|
|
333
|
+
|
|
334
|
+
The record names the call, not the line. Wrap the internals of the call it points at and run again, or take a heap snapshot at the limit (`node --heapsnapshot-near-heap-limit=1`) to see what filled it. The runnable version is [`examples/07-memory-spike.ts`](examples/07-memory-spike.ts).
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
282
338
|
## API
|
|
283
339
|
|
|
284
340
|
### `create(target, options)`
|
|
@@ -301,6 +357,7 @@ const p = create(target, { callback: (r) => records.push(r) });
|
|
|
301
357
|
| `id` | `number \| (() => string)` | `0` | Starting integer for the auto-incrementing ID sequence, or a custom generator. IDs take the form `#1`, `#2`, … unless overridden. |
|
|
302
358
|
| `recursive` | `boolean` | `true` | When `false`, only the root target is proxied. Values returned from traps are passed through as-is. |
|
|
303
359
|
| `only` | `Array<string>` | all traps | Allowlist of Reflect trap names to record. Traps not listed pass straight through to `Reflect` without emitting a record. |
|
|
360
|
+
| `filter` | `(r: Rekording) => boolean` | — | Called with each record before it is emitted; return `false` to drop it. Unlike `only`, the trap is still handled and its result still proxied — so the graph keeps growing — and the record is already serialized when `filter` sees it. |
|
|
304
361
|
| `depth` | `number` | `Infinity` | Maximum depth for nested object serialization. Deeper values are replaced with `[…]`. |
|
|
305
362
|
| `redact` | `Redactor \| Array<Redactor>` | — | Function(s) to redact sensitive values. Return `true` to replace with `"[redacted]"`, `false` to keep as-is, or a string for custom replacement. |
|
|
306
363
|
| `truncate` | `number` | `Infinity` | Maximum string length before truncation. Longer strings are truncated with `…`. |
|
|
@@ -483,6 +540,8 @@ Note the `let p!: typeof …` pattern: the callback closes over `p` before it is
|
|
|
483
540
|
|
|
484
541
|
Every `create()` call produces an isolated `Graph` — a session-scoped registry that maps proxies, targets, and IDs to each other. Once all references to a proxied tree are dropped, the graph is eligible for garbage collection. There are no module-level leaks between independent recordings.
|
|
485
542
|
|
|
543
|
+
While a session is alive, though, it holds on to everything it has touched: the graph indexes every proxy by ID so `getProxyById` can resolve it, which keeps each proxy — and its target — reachable for as long as any proxy in the graph is. A recursive recording that walks a large data structure retains all of it. When memory is what you are investigating, wrap code boundaries with `recursive: false` rather than the data flowing through them (see [Find the call behind a memory spike](#find-the-call-behind-a-memory-spike)).
|
|
544
|
+
|
|
486
545
|
### Structured origin
|
|
487
546
|
|
|
488
547
|
Each proxy carries an `Origin` that describes exactly how it was created: which trap fired, on which parent proxy, and under which key (for property traps) or from which function proxy (for call traps). This makes the recording self-describing — you can reconstruct a full call graph from the records alone, without keeping any external state.
|
|
@@ -1,10 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
3
9
|
};
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// source/flugrekorder.ts
|
|
21
|
+
var flugrekorder_exports = {};
|
|
22
|
+
__export(flugrekorder_exports, {
|
|
23
|
+
create: () => create,
|
|
24
|
+
format: () => format,
|
|
25
|
+
getAncestors: () => getAncestors,
|
|
26
|
+
getOrigin: () => getOrigin,
|
|
27
|
+
getPath: () => getPath,
|
|
28
|
+
getProxyById: () => getProxyById,
|
|
29
|
+
getTarget: () => getTarget,
|
|
30
|
+
isFlugrekorder: () => isFlugrekorder,
|
|
31
|
+
isProxiable: () => isProxiable
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(flugrekorder_exports);
|
|
8
34
|
|
|
9
35
|
// source/types.ts
|
|
10
36
|
function isProxiable(value) {
|
|
@@ -12,63 +38,55 @@ function isProxiable(value) {
|
|
|
12
38
|
}
|
|
13
39
|
|
|
14
40
|
// source/graph.ts
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
__privateAdd(this, _byId, /* @__PURE__ */ new Map());
|
|
19
|
-
__privateAdd(this, _byProxy, /* @__PURE__ */ new WeakMap());
|
|
20
|
-
__privateAdd(this, _byTarget, /* @__PURE__ */ new WeakMap());
|
|
21
|
-
__privateAdd(this, _generator);
|
|
22
|
-
let counter = typeof id === "number" ? id : 0;
|
|
23
|
-
__privateSet(this, _generator, typeof id === "function" ? id : () => `#${++counter}`);
|
|
24
|
-
}
|
|
41
|
+
var Graph = class _Graph {
|
|
42
|
+
static #index = /* @__PURE__ */ new WeakMap();
|
|
43
|
+
static #all = /* @__PURE__ */ new WeakSet();
|
|
25
44
|
/** Returns the Graph that owns `pxy`, or `undefined` for non-proxies. */
|
|
26
45
|
static for(pxy) {
|
|
27
|
-
return
|
|
46
|
+
return _Graph.#index.get(pxy);
|
|
28
47
|
}
|
|
29
48
|
/** Returns `true` if `pxy` is a proxy created by this module. */
|
|
30
49
|
static isProxy(pxy) {
|
|
31
|
-
return
|
|
50
|
+
return _Graph.#all.has(pxy);
|
|
32
51
|
}
|
|
33
52
|
/** Marks `pxy` as a known proxy across all graphs (double-wrap guard). */
|
|
34
53
|
static track(pxy) {
|
|
35
|
-
|
|
54
|
+
_Graph.#all.add(pxy);
|
|
55
|
+
}
|
|
56
|
+
#byId = /* @__PURE__ */ new Map();
|
|
57
|
+
#byProxy = /* @__PURE__ */ new WeakMap();
|
|
58
|
+
#byTarget = /* @__PURE__ */ new WeakMap();
|
|
59
|
+
#generator;
|
|
60
|
+
constructor(id) {
|
|
61
|
+
let counter = typeof id === "number" ? id : 0;
|
|
62
|
+
this.#generator = typeof id === "function" ? id : () => `#${++counter}`;
|
|
36
63
|
}
|
|
37
64
|
nextId() {
|
|
38
|
-
return
|
|
65
|
+
return this.#generator();
|
|
39
66
|
}
|
|
40
67
|
/** Returns the underlying target if `value` is a proxy known to this graph, otherwise `value` unchanged. */
|
|
41
68
|
unwrap(value) {
|
|
42
69
|
if (!isProxiable(value)) return value;
|
|
43
|
-
return
|
|
70
|
+
return this.#byProxy.get(value)?.target ?? value;
|
|
44
71
|
}
|
|
45
72
|
getByProxy(v) {
|
|
46
|
-
return
|
|
73
|
+
return this.#byProxy.get(v);
|
|
47
74
|
}
|
|
48
75
|
getByTarget(v) {
|
|
49
|
-
return
|
|
76
|
+
return this.#byTarget.get(v);
|
|
50
77
|
}
|
|
51
78
|
getById(id) {
|
|
52
|
-
return
|
|
79
|
+
return this.#byId.get(id);
|
|
53
80
|
}
|
|
54
81
|
register(proxy, target, origin2, id) {
|
|
55
82
|
const node = { id, proxy, target, origin: origin2 };
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
83
|
+
this.#byId.set(id, node);
|
|
84
|
+
this.#byProxy.set(proxy, node);
|
|
85
|
+
this.#byTarget.set(target, node);
|
|
86
|
+
_Graph.#index.set(proxy, this);
|
|
60
87
|
return node;
|
|
61
88
|
}
|
|
62
89
|
};
|
|
63
|
-
_index = new WeakMap();
|
|
64
|
-
_all = new WeakMap();
|
|
65
|
-
_byId = new WeakMap();
|
|
66
|
-
_byProxy = new WeakMap();
|
|
67
|
-
_byTarget = new WeakMap();
|
|
68
|
-
_generator = new WeakMap();
|
|
69
|
-
__privateAdd(_Graph, _index, /* @__PURE__ */ new WeakMap());
|
|
70
|
-
__privateAdd(_Graph, _all, /* @__PURE__ */ new WeakSet());
|
|
71
|
-
var Graph = _Graph;
|
|
72
90
|
|
|
73
91
|
// source/serialize.ts
|
|
74
92
|
var defaults = {
|
|
@@ -431,8 +449,7 @@ function format(rekording, proxy) {
|
|
|
431
449
|
if (origin2 && "source" in origin2) {
|
|
432
450
|
const path = resolve(origin2.source, proxy);
|
|
433
451
|
const callArgs = (Array.isArray(trap === "construct" ? args[1] : args[2]) ? trap === "construct" ? args[1] : args[2] : []).map((a) => display(a, proxy)).join(", ");
|
|
434
|
-
if (/^apply(:|$)/.test(trap))
|
|
435
|
-
return `${path}(${callArgs})`;
|
|
452
|
+
if (/^apply(:|$)/.test(trap)) return `${path}(${callArgs})`;
|
|
436
453
|
if (trap === "construct" || trap === "construct:native")
|
|
437
454
|
return `new ${path}(${callArgs})`;
|
|
438
455
|
}
|
|
@@ -468,7 +485,12 @@ function makeProxy(target, graph, config, origin2) {
|
|
|
468
485
|
if (!isProxiable(v) || Graph.isProxy(v))
|
|
469
486
|
return v;
|
|
470
487
|
if (!config.recursive) return v;
|
|
471
|
-
return makeProxy(
|
|
488
|
+
return makeProxy(
|
|
489
|
+
v,
|
|
490
|
+
graph,
|
|
491
|
+
config,
|
|
492
|
+
childOrigin
|
|
493
|
+
);
|
|
472
494
|
};
|
|
473
495
|
const known = (v) => {
|
|
474
496
|
if (!isProxiable(v)) return v;
|
|
@@ -550,7 +572,8 @@ function create(target, options) {
|
|
|
550
572
|
function isFlugrekorder(value) {
|
|
551
573
|
return isProxiable(value) && Graph.isProxy(value);
|
|
552
574
|
}
|
|
553
|
-
export
|
|
575
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
576
|
+
0 && (module.exports = {
|
|
554
577
|
create,
|
|
555
578
|
format,
|
|
556
579
|
getAncestors,
|
|
@@ -560,5 +583,5 @@ export {
|
|
|
560
583
|
getTarget,
|
|
561
584
|
isFlugrekorder,
|
|
562
585
|
isProxiable
|
|
563
|
-
};
|
|
564
|
-
//# sourceMappingURL=flugrekorder.
|
|
586
|
+
});
|
|
587
|
+
//# sourceMappingURL=flugrekorder.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../source/flugrekorder.ts","../source/types.ts","../source/graph.ts","../source/serialize.ts","../source/slots.ts","../source/specs.ts","../source/errors.ts","../source/retry.ts","../source/inspection.ts","../source/format.ts"],"sourcesContent":["import type { Writable } from 'node:stream';\nimport type { GraphNode } from './graph.ts';\nimport { Graph } from './graph.ts';\nimport type { SerialConfig } from './serialize.ts';\nimport { serialize, origin as serializeOrigin } from './serialize.ts';\nimport type { Spec, Wrapper } from './specs.ts';\nimport { makeSpecs } from './specs.ts';\nimport type {\n\tCallTrap,\n\tOrigin,\n\tPropertyTrap,\n\tProxiable,\n\tRedactor,\n\tRekording,\n} from './types.ts';\nimport { isProxiable } from './types.ts';\nimport { retryFlows } from './retry.ts';\n\nexport { format } from './format.ts';\nexport {\n\tgetAncestors,\n\tgetOrigin,\n\tgetPath,\n\tgetProxyById,\n\tgetTarget,\n} from './inspection.ts';\nexport type {\n\tCallTrap,\n\tOrigin,\n\tPropertyTrap,\n\tProxiable,\n\tRedactor,\n\tRekording,\n\tSerialized,\n} from './types.ts';\nexport { isProxiable } from './types.ts';\n\n/** Resolved runtime configuration — derived from CreateOptions and passed through the proxy factory. */\ntype Config = {\n\twrite: (r: Rekording) => void;\n\trecursive: boolean;\n\tonly: Set<string> | null;\n\tfilter: ((r: Rekording) => boolean) | null;\n\tserial: SerialConfig;\n\tspecs: Partial<Record<string, Spec>>;\n\tbind: boolean | undefined;\n};\n\ntype CommonCreateOptions = {\n\tid?: number | (() => string);\n\trecursive?: boolean;\n\tonly?: Array<string>;\n\tfilter?: (rekording: Rekording) => boolean;\n\tdepth?: number;\n\tredact?: Redactor | Array<Redactor>;\n\ttruncate?: number;\n\tbind?: boolean;\n};\n\ntype StreamCreateOptions = CommonCreateOptions & { stream: Writable };\ntype CallbackCreateOptions = CommonCreateOptions & {\n\tcallback: (record: Rekording) => void;\n};\ntype CreateOptions = StreamCreateOptions | CallbackCreateOptions;\n\n/**\n * Creates a recording proxy for `target` within `graph`.\n * Reuses existing proxies for stability, handles Promises specially,\n * and registers every new proxy in both the graph and the module-level index.\n */\nfunction makeProxy<T extends Proxiable>(\n\ttarget: T,\n\tgraph: Graph,\n\tconfig: Config,\n\torigin: Origin,\n): T {\n\t// Already a proxy (in any graph) — return unchanged, preventing double-wrapping.\n\tif (Graph.isProxy(target as Proxiable)) return target;\n\n\t// Already have a proxy for this original — reuse it (stability guarantee).\n\tconst existing = graph.getByTarget(target as Proxiable);\n\n\tif (existing) return existing.proxy as T;\n\n\t// Promises cannot be proxied directly: native methods like .then() check for\n\t// the [[PromiseState]] internal slot and throw if `this` is a Proxy. Instead,\n\t// return a new Promise that resolves to a proxy of the settled value.\n\tif (target instanceof Promise) {\n\t\tconst chained = target.then((value) =>\n\t\t\tisProxiable(value)\n\t\t\t\t? makeProxy(value as Proxiable, graph, config, origin)\n\t\t\t\t: value,\n\t\t) as unknown as T;\n\t\t// Register with a placeholder node so stability lookups work.\n\t\tconst id = graph.nextId();\n\n\t\tgraph.register(chained as Proxiable, target as Proxiable, origin, id);\n\n\t\treturn chained;\n\t}\n\n\tconst proxyId = graph.nextId();\n\n\tconst traps = (\n\t\tObject.getOwnPropertyNames(Reflect) as Array<keyof typeof Reflect>\n\t).filter((trap) => config.only === null || config.only.has(trap));\n\n\tconst handler: ProxyHandler<Proxiable> = Object.fromEntries(\n\t\ttraps.map((trap) => [\n\t\t\ttrap,\n\t\t\t(...rawArgs: Array<unknown>) => {\n\t\t\t\tconst selfId = (graph.getByTarget(target) as GraphNode).id;\n\n\t\t\t\tlet childOrigin: Origin =\n\t\t\t\t\t/get|set|defineProperty|getOwnPropertyDescriptor/.test(trap)\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\ttrap: trap as PropertyTrap,\n\t\t\t\t\t\t\t\tparent: selfId,\n\t\t\t\t\t\t\t\tkey: rawArgs[1] as string | symbol,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: /apply|construct/.test(trap)\n\t\t\t\t\t\t\t? { trap: trap as CallTrap, source: selfId }\n\t\t\t\t\t\t\t: null;\n\n\t\t\t\tconst wrap: Wrapper = (v) => {\n\t\t\t\t\tif (!isProxiable(v) || Graph.isProxy(v as Proxiable))\n\t\t\t\t\t\treturn v;\n\t\t\t\t\tif (!config.recursive) return v;\n\n\t\t\t\t\treturn makeProxy(\n\t\t\t\t\t\tv as Proxiable,\n\t\t\t\t\t\tgraph,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tchildOrigin,\n\t\t\t\t\t);\n\t\t\t\t};\n\n\t\t\t\t// Only wraps values already in the graph — new plain data passes through.\n\t\t\t\tconst known: Wrapper = (v) => {\n\t\t\t\t\tif (!isProxiable(v)) return v;\n\t\t\t\t\tif (Graph.isProxy(v as Proxiable)) return v;\n\n\t\t\t\t\tconst existing = graph.getByTarget(v as Proxiable);\n\n\t\t\t\t\tif (existing) return existing.proxy;\n\n\t\t\t\t\treturn v;\n\t\t\t\t};\n\n\t\t\t\tconst spec = config.specs[trap] ?? {};\n\t\t\t\tconst preArgs = spec.pre\n\t\t\t\t\t? spec.pre(rawArgs, wrap, known)\n\t\t\t\t\t: rawArgs;\n\n\t\t\t\tlet effectiveTrap: string = trap;\n\t\t\t\tlet effectiveArgs = preArgs;\n\t\t\t\tlet result: unknown;\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = (\n\t\t\t\t\t\tReflect[trap] as (...args: Array<unknown>) => unknown\n\t\t\t\t\t)(...preArgs);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconst flow = retryFlows.find(({ is }) =>\n\t\t\t\t\t\tis(trap, e, config.bind),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (flow) {\n\t\t\t\t\t\t// is() matched preArgs to this flow's parameter shape at runtime;\n\t\t\t\t\t\t// the union can't express that statically.\n\t\t\t\t\t\tconst invoke = flow.handle as (\n\t\t\t\t\t\t\tg: Graph | undefined,\n\t\t\t\t\t\t\t...a: Array<unknown>\n\t\t\t\t\t\t) => { args?: Array<unknown>; result: unknown };\n\t\t\t\t\t\tconst output = invoke(graph, ...preArgs);\n\t\t\t\t\t\tif (flow.trap) {\n\t\t\t\t\t\t\teffectiveTrap = flow.trap;\n\t\t\t\t\t\t\tchildOrigin = {\n\t\t\t\t\t\t\t\ttrap: flow.trap as CallTrap,\n\t\t\t\t\t\t\t\tsource: selfId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (output?.args) effectiveArgs = output.args;\n\t\t\t\t\t\tresult = output.result;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst output = spec.post\n\t\t\t\t\t? spec.post(result, effectiveArgs, wrap)\n\t\t\t\t\t: result;\n\n\t\t\t\tconst rekording: Rekording = {\n\t\t\t\t\tid: graph.nextId(),\n\t\t\t\t\ttrap: effectiveTrap,\n\t\t\t\t\torigin: serializeOrigin(childOrigin),\n\t\t\t\t\targs: effectiveArgs.map((arg) =>\n\t\t\t\t\t\tserialize(arg, graph, new Set(), config.serial),\n\t\t\t\t\t),\n\t\t\t\t\tresult: serialize(output, graph, new Set(), config.serial),\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t};\n\t\t\t\tif (!config.filter || config.filter(rekording))\n\t\t\t\t\tconfig.write(rekording);\n\n\t\t\t\treturn output;\n\t\t\t},\n\t\t]),\n\t);\n\n\tconst pxy = new Proxy(target as Proxiable, handler) as unknown as T;\n\n\tgraph.register(pxy as Proxiable, target as Proxiable, origin, proxyId);\n\tGraph.track(pxy as Proxiable);\n\n\treturn pxy;\n}\n\n/**\n * Wraps `target` in a transparent recording proxy.\n * Every Reflect trap that fires emits a `Rekording` to `callback` or `stream`.\n */\nexport function create<T extends Proxiable>(\n\ttarget: T,\n\toptions: CreateOptions,\n): T {\n\tconst write: (r: Rekording) => void =\n\t\t'stream' in options\n\t\t\t? (r) => options.stream.write(`${JSON.stringify(r)}\\n`)\n\t\t\t: options.callback;\n\tconst recursive = options.recursive !== false;\n\tconst only = options.only ? new Set(options.only) : null;\n\tconst filter = options.filter ?? null;\n\tconst { redact } = options;\n\tconst serial: SerialConfig = {\n\t\tdepth: options.depth ?? Infinity,\n\t\tredactors: redact ? (Array.isArray(redact) ? redact : [redact]) : [],\n\t\ttruncate: options.truncate ?? Infinity,\n\t};\n\tconst graph = new Graph(options.id ?? 0);\n\tconst specs = makeSpecs(options.bind);\n\n\treturn makeProxy(\n\t\ttarget,\n\t\tgraph,\n\t\t{ write, recursive, only, filter, serial, specs, bind: options.bind },\n\t\tnull,\n\t);\n}\n\n/** Returns `true` if `value` is a proxy created by this module. */\nexport function isFlugrekorder(value: unknown): value is Proxiable {\n\treturn isProxiable(value) && Graph.isProxy(value as Proxiable);\n}\n","import type { Graph } from './graph.ts';\nexport type Proxiable = object;\n\n/** Reflect traps that operate on a property — carry a parent ID and key in their origin. */\nexport type PropertyTrap =\n\t| 'get'\n\t| 'set'\n\t| 'defineProperty'\n\t| 'getOwnPropertyDescriptor';\n\n/** Reflect traps that invoke a callable — carry a source ID in their origin. Includes synthetic variants for native boundary crossings. */\nexport type CallTrap =\n\t| 'apply'\n\t| 'construct'\n\t| 'apply:native'\n\t| 'construct:native'\n\t| 'apply:structure'\n\t| 'apply:private';\n\n/** Describes how a proxy was created — which trap fired, on which parent, and under which key or source. Null for root proxies. */\nexport type Origin =\n\t| { trap: PropertyTrap; parent: string; key: string | symbol }\n\t| { trap: CallTrap; source: string }\n\t| null;\n\n/** Origin with symbol keys coerced to strings — safe to include in a Rekording. */\nexport type SerializedOrigin =\n\t| { trap: PropertyTrap; parent: string; key: string }\n\t| { trap: CallTrap; source: string }\n\t| null;\n\n/** A JSON-safe representation of any value. Proxiable values are replaced with `{ $proxy: id }` tags. Raw targets (proxiable values known to the graph but passed unwrapped) are tagged `{ $unwrap: { $proxy: id } }`. */\nexport type Serialized =\n\t| string\n\t| number\n\t| boolean\n\t| bigint\n\t| null\n\t| undefined\n\t| { readonly $proxy: string }\n\t| { readonly $unwrap: { readonly $proxy: string } }\n\t| Array<Serialized>\n\t| { [key: string]: Serialized };\n\n/** Returns true for any value that can meaningfully be wrapped in a Proxy. */\nexport function isProxiable(value: unknown): value is Proxiable {\n\treturn (\n\t\tvalue !== null &&\n\t\t(typeof value === 'object' || typeof value === 'function')\n\t);\n}\n\n/**\n * Determines whether and how a key/value pair should be redacted during serialization.\n * Return `false` to keep as-is, `true` to replace with `\"[redacted]\"`,\n * a string to use as a custom replacement, or `null` to drop the key entirely.\n */\nexport type Redactor = (\n\tkey: string | symbol,\n\tvalue: unknown,\n\ttarget: object,\n) => string | boolean | null;\n\n/** A single recorded interaction — one Reflect trap firing on one proxy. */\nexport type Rekording = {\n\tid: string;\n\ttrap: string;\n\torigin: SerializedOrigin;\n\targs: Array<Serialized>;\n\tresult: Serialized;\n\ttimestamp: number;\n};\n\ntype Fn = (...args: Array<unknown>) => unknown;\n\n/** Describes a retry handler for an apply trap boundary crossing. */\ntype ApplyRetryFlow = {\n\tis: (trap: string, error: unknown, bind?: boolean) => boolean;\n\ttrap?: string;\n\thandle: (\n\t\tgraph: Graph | undefined,\n\t\tfn: Fn,\n\t\tthisArg: unknown,\n\t\targList: Array<unknown>,\n\t) => { args: [Fn, unknown, Array<unknown>]; result: unknown };\n};\n\n/** Describes a retry handler for a get trap boundary crossing. */\ntype GetRetryFlow = {\n\tis: (trap: string, error: unknown, bind?: boolean) => boolean;\n\ttrap?: never;\n\thandle: (\n\t\tgraph: Graph | undefined,\n\t\ttarget: object,\n\t\tpropertyKey: PropertyKey,\n\t\treceiver: unknown,\n\t) => { result: unknown };\n};\n\n/** Describes a native boundary crossing retry handler. */\nexport type RetryFlow = ApplyRetryFlow | GetRetryFlow;\n","import { isProxiable } from './types.ts';\nimport type { Origin, Proxiable } from './types.ts';\n\n/** A node in the proxy graph — links a proxy to its original target, its origin, and its ID. */\nexport type GraphNode = {\n\treadonly id: string;\n\treadonly proxy: Proxiable;\n\treadonly target: Proxiable;\n\treadonly origin: Origin;\n};\n\n/**\n * Session-scoped proxy registry.\n * Each `create()` call produces its own Graph so proxied trees are\n * independent and GC-eligible once no longer referenced.\n */\nexport class Graph {\n\tstatic #index = new WeakMap<Proxiable, Graph>();\n\tstatic #all = new WeakSet<Proxiable>();\n\n\t/** Returns the Graph that owns `pxy`, or `undefined` for non-proxies. */\n\tstatic for(pxy: Proxiable): Graph | undefined {\n\t\treturn Graph.#index.get(pxy);\n\t}\n\n\t/** Returns `true` if `pxy` is a proxy created by this module. */\n\tstatic isProxy(pxy: Proxiable): boolean {\n\t\treturn Graph.#all.has(pxy);\n\t}\n\n\t/** Marks `pxy` as a known proxy across all graphs (double-wrap guard). */\n\tstatic track(pxy: Proxiable): void {\n\t\tGraph.#all.add(pxy);\n\t}\n\n\t#byId = new Map<string, GraphNode>();\n\t#byProxy = new WeakMap<Proxiable, GraphNode>();\n\t#byTarget = new WeakMap<Proxiable, GraphNode>();\n\t#generator: () => string;\n\n\tconstructor(id: number | (() => string)) {\n\t\tlet counter = typeof id === 'number' ? id : 0;\n\n\t\tthis.#generator = typeof id === 'function' ? id : () => `#${++counter}`;\n\t}\n\n\tnextId(): string {\n\t\treturn this.#generator();\n\t}\n\n\t/** Returns the underlying target if `value` is a proxy known to this graph, otherwise `value` unchanged. */\n\tunwrap(value: unknown): unknown {\n\t\tif (!isProxiable(value)) return value;\n\t\treturn this.#byProxy.get(value)?.target ?? value;\n\t}\n\n\tgetByProxy(v: Proxiable): GraphNode | undefined {\n\t\treturn this.#byProxy.get(v);\n\t}\n\tgetByTarget(v: Proxiable): GraphNode | undefined {\n\t\treturn this.#byTarget.get(v);\n\t}\n\tgetById(id: string): GraphNode | undefined {\n\t\treturn this.#byId.get(id);\n\t}\n\n\tregister(\n\t\tproxy: Proxiable,\n\t\ttarget: Proxiable,\n\t\torigin: Origin,\n\t\tid: string,\n\t): GraphNode {\n\t\tconst node: GraphNode = { id, proxy, target, origin };\n\n\t\tthis.#byId.set(id, node);\n\t\tthis.#byProxy.set(proxy, node);\n\t\tthis.#byTarget.set(target, node);\n\t\tGraph.#index.set(proxy, this);\n\n\t\treturn node;\n\t}\n}\n","import type { Graph } from './graph.ts';\nimport {\n\tisProxiable,\n\ttype Origin,\n\ttype Proxiable,\n\ttype Redactor,\n\ttype Serialized,\n\ttype SerializedOrigin,\n} from './types.ts';\n\nexport type SerialConfig = {\n\tdepth: number;\n\tredactors: Array<Redactor>;\n\ttruncate: number;\n};\n\nexport const defaults: SerialConfig = {\n\tdepth: Infinity,\n\tredactors: [],\n\ttruncate: Infinity,\n};\n\n/** Find and apply any redaction for the given key/value/target context */\nfunction redact(\n\tredactors: Array<Redactor>,\n\tkey: string | symbol,\n\tvalue: unknown,\n\ttarget: object,\n): string | null | false {\n\tfor (const redactor of redactors) {\n\t\tconst result = redactor(key, value, target);\n\t\tif (result === false) continue;\n\n\t\treturn result === true ? '[redacted]' : result;\n\t}\n\n\treturn false;\n}\n\n/** Serializes an object or function value — tags known proxies by ID, inlines arrays and plain objects. */\nfunction proxiable(\n\tv: unknown,\n\tgraph: Graph,\n\tseen: Set<unknown>,\n\tserial: SerialConfig,\n\tdepth: number,\n): Serialized {\n\t// Check for a known proxy BEFORE Array.isArray: iterating a proxied\n\t// array via its proxy triggers get traps which call serialize again,\n\t// causing infinite recursion. A proxy is always tagged by ID.\n\tconst proxyNode = graph.getByProxy(v as Proxiable);\n\tif (proxyNode !== undefined) return { $proxy: proxyNode.id };\n\n\tconst targetNode = graph.getByTarget(v as Proxiable);\n\tif (targetNode !== undefined) return { $unwrap: { $proxy: targetNode.id } };\n\tif (depth >= serial.depth) return '[…]';\n\n\t// Plain (unproxied) arrays are safe to iterate directly.\n\tif (Array.isArray(v)) {\n\t\treturn (v as Array<unknown>).map((item) =>\n\t\t\tserialize(item, graph, seen, serial, depth + 1),\n\t\t);\n\t}\n\n\t// Plain (unproxied) objects: serialize by value with a circular-reference guard.\n\tif (seen.has(v)) return { $proxy: '?' };\n\n\tseen.add(v);\n\n\tconst entries: Array<[string, Serialized]> = [];\n\n\tfor (const [k, val] of Object.entries(v as object)) {\n\t\tif (serial.redactors.length > 0) {\n\t\t\tconst decision = redact(serial.redactors, k, val, v as object);\n\t\t\tif (decision === null) continue;\n\t\t\tif (decision !== false) {\n\t\t\t\tentries.push([k, decision]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tentries.push([k, serialize(val, graph, seen, serial, depth + 1)]);\n\t}\n\n\tseen.delete(v);\n\n\treturn Object.fromEntries(entries);\n}\n\n/** Converts any value to a JSON-safe Serialized form, tagging graph members by ID. */\nexport function serialize(\n\tv: unknown,\n\tgraph: Graph,\n\tseen = new Set<unknown>(),\n\tserial = defaults,\n\tdepth = 0,\n): Serialized {\n\tif (v === null || v === undefined) return v;\n\tif (isProxiable(v)) return proxiable(v, graph, seen, serial, depth);\n\n\treturn typeof v === 'string'\n\t\t? (v as string).length > serial.truncate\n\t\t\t? `${(v as string).slice(0, serial.truncate)}…`\n\t\t\t: (v as string)\n\t\t: (v as Serialized);\n}\n\n/** Converts an Origin to its serialized form — coerces symbol keys to strings. */\nexport function origin(o: Origin): SerializedOrigin {\n\tif (!o) return null;\n\tif ('key' in o)\n\t\treturn { trap: o.trap, parent: o.parent, key: String(o.key) };\n\n\treturn o;\n}\n","import type { Proxiable } from './types.ts';\n\ntype AnyFn = (...args: Array<unknown>) => unknown;\n\n// Per-prototype cache: true if any getter on this prototype (or its chain)\n// throws TypeError when called through a blank Proxy — the signature of an\n// internal slot check. Keyed by the direct prototype of the proxied target\n// so all instances of the same type share one probe result.\nconst slotProtos = new WeakMap<object, boolean>();\n\n// Stable bound-method cache: (target, key) → fn.bind(target).\n// Ensures the same proxied bound function is returned every time the same\n// method is accessed on the same target — required for graph proxy stability.\nconst bindCache = new WeakMap<object, Map<PropertyKey, AnyFn>>();\n\n// Slot-check TypeErrors have specific messages; filter by them to avoid\n// misclassifying TypeErrors thrown for other reasons (e.g. wrong arg count).\nconst slotError = /incompatible receiver|this is not|illegal invocation/i;\n\n/**\n * Returns true if `target`'s prototype chain contains a getter that throws\n * TypeError when called through a Proxy — the JS-observable signature of an\n * ECMAScript internal slot check (e.g. Map, Set, WeakMap, WeakSet, Date).\n * Result is cached per prototype so the probe runs at most once per type.\n */\nexport function hasInternalSlots(target: Proxiable): boolean {\n\tif (typeof target !== 'object' || target === null) return false;\n\n\tconst direct = Object.getPrototypeOf(target as object) as object | null;\n\tif (!direct) return false;\n\tconst cached = slotProtos.get(direct);\n\tif (cached !== undefined) return cached;\n\n\tconst probe = new Proxy(target as object, {\n\t\tset: () => true,\n\t\tdefineProperty: () => true,\n\t\tdeleteProperty: () => true,\n\t\tsetPrototypeOf: () => true,\n\t});\n\tlet proto: object | null = direct;\n\n\twhile (proto && proto !== Object.prototype) {\n\t\tfor (const key of Object.getOwnPropertyNames(proto)) {\n\t\t\tif (key === 'constructor') continue;\n\t\t\tconst desc = Object.getOwnPropertyDescriptor(proto, key);\n\t\t\tconst fn =\n\t\t\t\tdesc?.get ??\n\t\t\t\t(typeof desc?.value === 'function'\n\t\t\t\t\t? (desc.value as AnyFn)\n\t\t\t\t\t: null);\n\t\t\tif (fn) {\n\t\t\t\tlet slots = false;\n\t\t\t\ttry {\n\t\t\t\t\tfn.call(probe);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof TypeError && slotError.test(String(e)))\n\t\t\t\t\t\tslots = true;\n\t\t\t\t}\n\t\t\t\tslotProtos.set(direct, slots);\n\t\t\t\treturn slots;\n\t\t\t}\n\t\t}\n\t\tproto = Object.getPrototypeOf(proto) as object | null;\n\t}\n\n\tslotProtos.set(direct, false);\n\treturn false;\n}\n\n/** Returns a stable bound version of `fn` for `(target, key)` — created once, reused on every access. */\nexport function boundMethod(\n\ttarget: object,\n\tkey: PropertyKey,\n\tfn: AnyFn,\n): AnyFn {\n\tlet cache = bindCache.get(target);\n\tif (!cache) {\n\t\tcache = new Map();\n\t\tbindCache.set(target, cache);\n\t}\n\tconst existing = cache.get(key);\n\tif (existing) return existing;\n\tconst bound = fn.bind(target);\n\tcache.set(key, bound);\n\treturn bound;\n}\n","import { boundMethod, hasInternalSlots } from './slots.ts';\nimport { isProxiable, type Proxiable } from './types.ts';\n\n/** A function that conditionally wraps a value in a proxy. */\nexport type Wrapper = (v: unknown) => unknown;\n\n// %TypedArray% — the abstract base class shared by all TypedArray constructors.\n// Not exposed as a global; reached via the prototype chain of any TypedArray.\nconst TypedArray = Object.getPrototypeOf(Int8Array);\n\nconst ecmaBuiltins = [\n\tPromise,\n\tMap,\n\tSet,\n\tWeakMap,\n\tWeakSet,\n\tDate,\n\tRegExp,\n\tArrayBuffer,\n\tTypedArray,\n\tDataView,\n];\n\n/**\n * Returns true for standard ECMAScript built-ins whose C++ implementations\n * perform a JavaScript-level type check before touching internal fields —\n * so they throw a catchable TypeError when called through a Proxy rather\n * than crashing the process. Distinguishes them from Node.js C++ bindings\n * (TCP handles, ConnectionsList, HTTPParser, …) that crash fatally.\n *\n * Uses instanceof to cover subclasses — a JS subclass of Map has the same\n * internal-slot behaviour as Map itself and is equally safe to proxy.\n */\nfunction isECMABuiltin(v: unknown): boolean {\n\treturn ecmaBuiltins.some((B) => v instanceof B);\n}\n\n/** Returns true when v is a C++ binding object that would crash Node.js if proxied. */\nfunction isUnsafeBinding(v: unknown): boolean {\n\treturn isProxiable(v) && hasInternalSlots(v) && !isECMABuiltin(v);\n}\n\n// Exported for testing only.\nexport { isECMABuiltin, isUnsafeBinding };\n\n/** Pre/post hooks for a Reflect trap — transform args before dispatch and/or wrap the result. */\nexport type Spec = {\n\tpre?: (\n\t\targs: Array<unknown>,\n\t\twrap: Wrapper,\n\t\tknown: Wrapper,\n\t) => Array<unknown>;\n\tpost?: (result: unknown, args: Array<unknown>, wrap: Wrapper) => unknown;\n};\n\n/**\n * Builds per-trap hooks for a proxy session.\n * When `bind` is true, all method results and getter receivers are\n * bound to the real target — the same strategy used for ECMAScript built-ins\n * with internal slots, extended to user-defined classes with `#` private fields.\n */\nexport function makeSpecs(\n\tbind: boolean | undefined,\n): Partial<Record<string, Spec>> {\n\treturn {\n\t\tget: {\n\t\t\t// For targets with internal slots (Map, Set, WeakMap, WeakSet, Date …)\n\t\t\t// or when bind is true, use the real target as the Reflect.get\n\t\t\t// receiver so that getter-based slot checks and #private field reads\n\t\t\t// (e.g. `get value() { return this.#count; }`) don't throw TypeError.\n\t\t\tpre: ([target, key, receiver], _wrap, _known) => [\n\t\t\t\ttarget,\n\t\t\t\tkey,\n\t\t\t\thasInternalSlots(target as Proxiable) || bind\n\t\t\t\t\t? target\n\t\t\t\t\t: receiver,\n\t\t\t],\n\t\t\t// For the same targets, bind method results to the real target before\n\t\t\t// wrapping so that apply-level slot checks (e.g. Map.prototype.get)\n\t\t\t// and #private field access inside methods also pass.\n\t\t\t// The bind cache ensures proxy stability.\n\t\t\tpost: (result, [target, key], wrap) => {\n\t\t\t\tif (key === 'prototype') return result;\n\t\t\t\tif (hasInternalSlots(target as Proxiable) || bind) {\n\t\t\t\t\tif (typeof result === 'function')\n\t\t\t\t\t\treturn wrap(\n\t\t\t\t\t\t\tboundMethod(\n\t\t\t\t\t\t\t\ttarget as object,\n\t\t\t\t\t\t\t\tkey as PropertyKey,\n\t\t\t\t\t\t\t\tresult as (...args: Array<unknown>) => unknown,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Don't proxy C++ binding objects — they crash native code when\n\t\t\t\t// used as Proxies (e.g. ConnectionsList, TCP handles). ECMAScript\n\t\t\t\t// built-ins (Map, Set, Promise, Date …) are excluded: they have\n\t\t\t\t// proper JS-level type checks and can be safely proxied.\n\t\t\t\tif (isUnsafeBinding(result)) return result;\n\t\t\t\treturn wrap(result);\n\t\t\t},\n\t\t},\n\t\tset: {\n\t\t\tpre: ([target, key, value, receiver], wrap) => [\n\t\t\t\ttarget,\n\t\t\t\tkey,\n\t\t\t\t// Don't wrap when target has slots (Map/Set internals) or when the\n\t\t\t\t// value is an unsafe C++ binding (TCP handles, etc.).\n\t\t\t\thasInternalSlots(target as Proxiable) || isUnsafeBinding(value)\n\t\t\t\t\t? value\n\t\t\t\t\t: wrap(value),\n\t\t\t\treceiver,\n\t\t\t],\n\t\t},\n\t\tapply: {\n\t\t\t// thisArg is wrapped normally (it's always a graph node).\n\t\t\t// Call arguments are wrapped with known — only existing graph nodes\n\t\t\t// get proxied; plain data passes through and is inlined by serialize().\n\t\t\tpre: ([target, thisArg, callArgs], wrap, known) => [\n\t\t\t\ttarget,\n\t\t\t\twrap(thisArg),\n\t\t\t\t(callArgs as Array<unknown>).map(known),\n\t\t\t],\n\t\t\tpost: (result, _args, wrap) => wrap(result),\n\t\t},\n\t\tconstruct: {\n\t\t\tpre: ([target, callArgs, newTarget], wrap) => [\n\t\t\t\ttarget,\n\t\t\t\t(callArgs as Array<unknown>).map(wrap),\n\t\t\t\tnewTarget,\n\t\t\t],\n\t\t\tpost: (result, _args, wrap) => wrap(result),\n\t\t},\n\t\tdefineProperty: {\n\t\t\tpre: (args, wrap) => {\n\t\t\t\tconst [target, key, descriptor] = args as [\n\t\t\t\t\tunknown,\n\t\t\t\t\tunknown,\n\t\t\t\t\tPropertyDescriptor,\n\t\t\t\t];\n\t\t\t\tconst patch: PropertyDescriptor = {};\n\n\t\t\t\tif (\n\t\t\t\t\tdescriptor.value != null &&\n\t\t\t\t\t!isUnsafeBinding(descriptor.value)\n\t\t\t\t)\n\t\t\t\t\tpatch.value = wrap(descriptor.value);\n\t\t\t\tif (typeof descriptor.get === 'function')\n\t\t\t\t\tpatch.get = wrap(descriptor.get) as () => unknown;\n\t\t\t\tif (typeof descriptor.set === 'function')\n\t\t\t\t\tpatch.set = wrap(descriptor.set) as (v: unknown) => void;\n\n\t\t\t\treturn Object.keys(patch).length > 0\n\t\t\t\t\t? [target, key, { ...descriptor, ...patch }]\n\t\t\t\t\t: args;\n\t\t\t},\n\t\t},\n\t\tgetOwnPropertyDescriptor: {\n\t\t\tpost: (result, _args, wrap) => {\n\t\t\t\tconst desc = result as PropertyDescriptor | undefined;\n\n\t\t\t\tif (!desc) return result;\n\n\t\t\t\tconst patch: PropertyDescriptor = {};\n\n\t\t\t\tif (desc.value != null && !isUnsafeBinding(desc.value))\n\t\t\t\t\tpatch.value = wrap(desc.value);\n\t\t\t\tif (typeof desc.get === 'function')\n\t\t\t\t\tpatch.get = wrap(desc.get) as () => unknown;\n\t\t\t\tif (typeof desc.set === 'function')\n\t\t\t\t\tpatch.set = wrap(desc.set) as (v: unknown) => void;\n\n\t\t\t\treturn Object.keys(patch).length > 0\n\t\t\t\t\t? { ...desc, ...patch }\n\t\t\t\t\t: result;\n\t\t\t},\n\t\t},\n\t};\n}\n","export function isError(input: unknown): input is Error {\n\treturn input ? input instanceof Error : false;\n}\n\nexport function createErrorGuard(\n\tname: string,\n\tcontains?: RegExp,\n): (input: unknown) => input is Error {\n\tconst checks: Array<(input: unknown) => boolean> = [\n\t\tisError,\n\t\t(sub: unknown) =>\n\t\t\ttypeof sub === 'object' &&\n\t\t\t(sub as Record<string, unknown>)?.name === name,\n\t];\n\n\tif (contains instanceof RegExp) {\n\t\tchecks.push((v) => contains.test(String(v)));\n\t}\n\n\treturn (input: unknown): input is Error =>\n\t\tchecks.every((predicate) => predicate(input));\n}\n","import { createErrorGuard } from './errors.ts';\nimport type { Graph } from './graph.ts';\nimport type { RetryFlow } from './types.ts';\n\n/** Returns the underlying target if `value` is a proxy known to `graph`, otherwise `value` unchanged. */\nexport function unwrap(graph: Graph | undefined, value: unknown): unknown {\n\treturn graph?.unwrap(value) ?? value;\n}\n\nconst isDataCloneDOMException = createErrorGuard('DataCloneError');\nconst isTypeErrorPrivateMember = createErrorGuard('TypeError', /private member/i);\nconst isTypeErrorIllegalInvocation = createErrorGuard('TypeError', /illegal invocation/i);\n\n/** Retry handlers for native boundary crossings — defined once at module level. */\nexport const retryFlows: Array<RetryFlow> = [\n\t{\n\t\t// Native methods (console.log, DOM APIs, http.Server) check the internal\n\t\t// [[Receiver]] slot and throw \"Illegal invocation\" when called through a\n\t\t// proxy. Unwrap the real target from the graph and retry as the receiver.\n\t\tis: (trap, error) =>\n\t\t\ttrap === 'apply' && isTypeErrorIllegalInvocation(error),\n\t\ttrap: 'apply:native',\n\t\thandle: (graph, fn, thisArg, argList) => {\n\t\t\tconst realThis = unwrap(graph, thisArg);\n\t\t\treturn {\n\t\t\t\targs: [fn, realThis, argList],\n\t\t\t\tresult: Reflect.apply(fn, realThis, argList),\n\t\t\t};\n\t\t},\n\t},\n\t{\n\t\t// structuredClone and postMessage can't clone proxy objects — they throw a\n\t\t// DataCloneError. Unwrap any proxy arguments to their real targets and retry.\n\t\tis: (trap, error) => trap === 'apply' && isDataCloneDOMException(error),\n\t\ttrap: 'apply:structure',\n\t\thandle: (graph, fn, thisArg, argList) => {\n\t\t\tconst unwrappedArgs = argList.map((arg) => unwrap(graph, arg));\n\t\t\treturn {\n\t\t\t\targs: [fn, thisArg, unwrappedArgs],\n\t\t\t\tresult: Reflect.apply(fn, thisArg, unwrappedArgs),\n\t\t\t};\n\t\t},\n\t},\n\t{\n\t\t// Private fields (#field) use brand checking — accessing #field on a proxy\n\t\t// (rather than the original instance) throws \"Cannot read private member\".\n\t\t// Unwrap the real instance from the graph and use it as the receiver.\n\t\tis: (trap, error, bind) =>\n\t\t\tbind !== false &&\n\t\t\ttrap === 'apply' &&\n\t\t\tisTypeErrorPrivateMember(error),\n\t\ttrap: 'apply:private',\n\t\thandle: (graph, fn, thisArg, argList) => {\n\t\t\tconst realThis = unwrap(graph, thisArg);\n\t\t\treturn {\n\t\t\t\targs: [fn, realThis, argList],\n\t\t\t\tresult: Reflect.apply(fn, realThis, argList),\n\t\t\t};\n\t\t},\n\t},\n\t{\n\t\t// A getter that reads a #private field hits the same brand check, but the\n\t\t// apply retry doesn't apply here. Re-invoke Reflect.get with the real target\n\t\t// as its own receiver so the brand check passes.\n\t\tis: (trap, error, bind) =>\n\t\t\tbind !== false && trap === 'get' && isTypeErrorPrivateMember(error),\n\t\thandle: (_graph, target, propertyKey) => ({\n\t\t\tresult: Reflect.get(target, propertyKey, target),\n\t\t}),\n\t},\n];\n","import { Graph } from './graph.ts';\nimport type { Origin, Proxiable } from './types.ts';\n\n/** Returns the original unwrapped target of a proxy, or `null` for non-proxies. */\nexport function getTarget(pxy: Proxiable): Proxiable | null {\n\treturn Graph.for(pxy)?.getByProxy(pxy)?.target ?? null;\n}\n\n/**\n * Looks up a proxy by its recorded ID within the same graph as `pxy`.\n * Use this to resolve `{ $proxy: id }` references in recorded args and results back to live proxies.\n */\nexport function getProxyById(\n\tid: string,\n\tpxy: Proxiable,\n): Proxiable | undefined {\n\treturn Graph.for(pxy)?.getById(id)?.proxy;\n}\n\n/** Returns the `Origin` of a proxy — how and from where it was created. Returns `null` for root proxies and non-proxies. */\nexport function getOrigin(pxy: Proxiable): Origin {\n\treturn Graph.for(pxy)?.getByProxy(pxy)?.origin ?? null;\n}\n\n/**\n * Walks the origin chain from the root proxy down to `pxy`.\n * Returns an ordered array of `{ proxy, origin }` pairs, root first.\n * Returns an empty array for non-proxies.\n */\nexport function getAncestors(\n\tpxy: Proxiable,\n): Array<{ proxy: Proxiable; origin: Origin }> {\n\tconst graph = Graph.for(pxy);\n\n\tif (!graph) return [];\n\n\tconst result: Array<{ proxy: Proxiable; origin: Origin }> = [];\n\tlet node = graph.getByProxy(pxy);\n\n\twhile (node) {\n\t\tresult.unshift({ proxy: node.proxy, origin: node.origin });\n\t\tif (!node.origin) break;\n\n\t\tconst parentId =\n\t\t\t'parent' in node.origin ? node.origin.parent : node.origin.source;\n\n\t\tnode = graph.getById(parentId);\n\t}\n\n\treturn result;\n}\n\n/**\n * Returns a human-readable dotted path string for a proxy.\n * Function and constructor calls are annotated with `()`.\n * Returns an empty string for the root proxy and for non-proxies.\n */\nexport function getPath(pxy: Proxiable): string {\n\tconst ancestors = getAncestors(pxy);\n\tconst parts: Array<string> = [];\n\n\tfor (const { origin: o } of ancestors) {\n\t\tif (!o) continue;\n\t\tif ('key' in o) {\n\t\t\tparts.push(String(o.key));\n\t\t} else {\n\t\t\tif (parts.length > 0) {\n\t\t\t\tparts[parts.length - 1] += '()';\n\t\t\t} else {\n\t\t\t\tparts.push('()');\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parts.join('.');\n}\n","import { getPath, getProxyById } from './inspection.ts';\nimport type { Proxiable, Rekording, Serialized } from './types.ts';\n\nfunction resolve(id: string, proxy?: Proxiable): string {\n\tif (!proxy) return id;\n\tconst p = getProxyById(id, proxy);\n\treturn p !== undefined ? getPath(p) : id;\n}\n\nfunction display(v: Serialized, proxy?: Proxiable, limit = 80): string {\n\tif (v === null || v === undefined) return String(v);\n\tif (typeof v !== 'object') return String(v);\n\tif (!Array.isArray(v) && '$proxy' in v)\n\t\treturn resolve(v.$proxy as string, proxy);\n\tif (!Array.isArray(v) && '$unwrap' in v)\n\t\treturn `↓${resolve((v as { $unwrap: { $proxy: string } }).$unwrap.$proxy, proxy)}`;\n\tconst raw = Array.isArray(v)\n\t\t? `[${v.map((i) => display(i, proxy)).join(', ')}]`\n\t\t: JSON.stringify(v);\n\treturn raw.length > limit ? `${raw.slice(0, limit)}…` : raw;\n}\n\n/** Converts a `Rekording` to a human-readable string.\n * When `proxy` is supplied, `{ $proxy: id }` tags in args and results resolve to dotted paths.\n * When omitted, raw IDs are shown instead. */\nexport function format(rekording: Rekording, proxy?: Proxiable): string {\n\tconst { id, trap, origin, args, result } = rekording;\n\n\tif (origin && 'parent' in origin) {\n\t\tconst parent = resolve(origin.parent, proxy);\n\t\tconst path = parent ? `${parent}.${origin.key}` : String(origin.key);\n\t\tif (trap === 'set') return `${path} = ${display(args[2], proxy)}`;\n\t\tif (trap === 'get') return `${path} → ${display(result, proxy)}`;\n\t\treturn `${trap} ${path}`;\n\t}\n\n\tif (origin && 'source' in origin) {\n\t\tconst path = resolve(origin.source, proxy);\n\t\tconst callArgs = (\n\t\t\tArray.isArray(trap === 'construct' ? args[1] : args[2])\n\t\t\t\t? ((trap === 'construct'\n\t\t\t\t\t\t? args[1]\n\t\t\t\t\t\t: args[2]) as Array<Serialized>)\n\t\t\t\t: []\n\t\t)\n\t\t\t.map((a) => display(a, proxy))\n\t\t\t.join(', ');\n\t\tif (/^apply(:|$)/.test(trap)) return `${path}(${callArgs})`;\n\t\tif (trap === 'construct' || trap === 'construct:native')\n\t\t\treturn `new ${path}(${callArgs})`;\n\t}\n\n\treturn `${trap} on ${id}`;\n}\n"],"mappings":"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","names":["origin","origin","origin","existing","output","redact"]}
|
|
@@ -106,4 +106,5 @@ declare function create<T extends Proxiable>(target: T, options: CreateOptions):
|
|
|
106
106
|
/** Returns `true` if `value` is a proxy created by this module. */
|
|
107
107
|
declare function isFlugrekorder(value: unknown): value is Proxiable;
|
|
108
108
|
|
|
109
|
-
export {
|
|
109
|
+
export { create, format, getAncestors, getOrigin, getPath, getProxyById, getTarget, isFlugrekorder, isProxiable };
|
|
110
|
+
export type { CallTrap, Origin, PropertyTrap, Proxiable, Redactor, Rekording, Serialized };
|
package/dist/flugrekorder.d.ts
CHANGED
|
@@ -106,4 +106,5 @@ declare function create<T extends Proxiable>(target: T, options: CreateOptions):
|
|
|
106
106
|
/** Returns `true` if `value` is a proxy created by this module. */
|
|
107
107
|
declare function isFlugrekorder(value: unknown): value is Proxiable;
|
|
108
108
|
|
|
109
|
-
export {
|
|
109
|
+
export { create, format, getAncestors, getOrigin, getPath, getProxyById, getTarget, isFlugrekorder, isProxiable };
|
|
110
|
+
export type { CallTrap, Origin, PropertyTrap, Proxiable, Redactor, Rekording, Serialized };
|
|
@@ -4,9 +4,6 @@ var Flugrekorder = (() => {
|
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __typeError = (msg) => {
|
|
8
|
-
throw TypeError(msg);
|
|
9
|
-
};
|
|
10
7
|
var __export = (target, all) => {
|
|
11
8
|
for (var name in all)
|
|
12
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -20,10 +17,6 @@ var Flugrekorder = (() => {
|
|
|
20
17
|
return to;
|
|
21
18
|
};
|
|
22
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
24
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
25
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
26
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
27
20
|
|
|
28
21
|
// source/flugrekorder.ts
|
|
29
22
|
var flugrekorder_exports = {};
|
|
@@ -45,63 +38,55 @@ var Flugrekorder = (() => {
|
|
|
45
38
|
}
|
|
46
39
|
|
|
47
40
|
// source/graph.ts
|
|
48
|
-
var
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
__privateAdd(this, _byId, /* @__PURE__ */ new Map());
|
|
52
|
-
__privateAdd(this, _byProxy, /* @__PURE__ */ new WeakMap());
|
|
53
|
-
__privateAdd(this, _byTarget, /* @__PURE__ */ new WeakMap());
|
|
54
|
-
__privateAdd(this, _generator);
|
|
55
|
-
let counter = typeof id === "number" ? id : 0;
|
|
56
|
-
__privateSet(this, _generator, typeof id === "function" ? id : () => `#${++counter}`);
|
|
57
|
-
}
|
|
41
|
+
var Graph = class _Graph {
|
|
42
|
+
static #index = /* @__PURE__ */ new WeakMap();
|
|
43
|
+
static #all = /* @__PURE__ */ new WeakSet();
|
|
58
44
|
/** Returns the Graph that owns `pxy`, or `undefined` for non-proxies. */
|
|
59
45
|
static for(pxy) {
|
|
60
|
-
return
|
|
46
|
+
return _Graph.#index.get(pxy);
|
|
61
47
|
}
|
|
62
48
|
/** Returns `true` if `pxy` is a proxy created by this module. */
|
|
63
49
|
static isProxy(pxy) {
|
|
64
|
-
return
|
|
50
|
+
return _Graph.#all.has(pxy);
|
|
65
51
|
}
|
|
66
52
|
/** Marks `pxy` as a known proxy across all graphs (double-wrap guard). */
|
|
67
53
|
static track(pxy) {
|
|
68
|
-
|
|
54
|
+
_Graph.#all.add(pxy);
|
|
55
|
+
}
|
|
56
|
+
#byId = /* @__PURE__ */ new Map();
|
|
57
|
+
#byProxy = /* @__PURE__ */ new WeakMap();
|
|
58
|
+
#byTarget = /* @__PURE__ */ new WeakMap();
|
|
59
|
+
#generator;
|
|
60
|
+
constructor(id) {
|
|
61
|
+
let counter = typeof id === "number" ? id : 0;
|
|
62
|
+
this.#generator = typeof id === "function" ? id : () => `#${++counter}`;
|
|
69
63
|
}
|
|
70
64
|
nextId() {
|
|
71
|
-
return
|
|
65
|
+
return this.#generator();
|
|
72
66
|
}
|
|
73
67
|
/** Returns the underlying target if `value` is a proxy known to this graph, otherwise `value` unchanged. */
|
|
74
68
|
unwrap(value) {
|
|
75
69
|
if (!isProxiable(value)) return value;
|
|
76
|
-
return
|
|
70
|
+
return this.#byProxy.get(value)?.target ?? value;
|
|
77
71
|
}
|
|
78
72
|
getByProxy(v) {
|
|
79
|
-
return
|
|
73
|
+
return this.#byProxy.get(v);
|
|
80
74
|
}
|
|
81
75
|
getByTarget(v) {
|
|
82
|
-
return
|
|
76
|
+
return this.#byTarget.get(v);
|
|
83
77
|
}
|
|
84
78
|
getById(id) {
|
|
85
|
-
return
|
|
79
|
+
return this.#byId.get(id);
|
|
86
80
|
}
|
|
87
81
|
register(proxy, target, origin2, id) {
|
|
88
82
|
const node = { id, proxy, target, origin: origin2 };
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
this.#byId.set(id, node);
|
|
84
|
+
this.#byProxy.set(proxy, node);
|
|
85
|
+
this.#byTarget.set(target, node);
|
|
86
|
+
_Graph.#index.set(proxy, this);
|
|
93
87
|
return node;
|
|
94
88
|
}
|
|
95
89
|
};
|
|
96
|
-
_index = new WeakMap();
|
|
97
|
-
_all = new WeakMap();
|
|
98
|
-
_byId = new WeakMap();
|
|
99
|
-
_byProxy = new WeakMap();
|
|
100
|
-
_byTarget = new WeakMap();
|
|
101
|
-
_generator = new WeakMap();
|
|
102
|
-
__privateAdd(_Graph, _index, /* @__PURE__ */ new WeakMap());
|
|
103
|
-
__privateAdd(_Graph, _all, /* @__PURE__ */ new WeakSet());
|
|
104
|
-
var Graph = _Graph;
|
|
105
90
|
|
|
106
91
|
// source/serialize.ts
|
|
107
92
|
var defaults = {
|
|
@@ -464,8 +449,7 @@ var Flugrekorder = (() => {
|
|
|
464
449
|
if (origin2 && "source" in origin2) {
|
|
465
450
|
const path = resolve(origin2.source, proxy);
|
|
466
451
|
const callArgs = (Array.isArray(trap === "construct" ? args[1] : args[2]) ? trap === "construct" ? args[1] : args[2] : []).map((a) => display(a, proxy)).join(", ");
|
|
467
|
-
if (/^apply(:|$)/.test(trap))
|
|
468
|
-
return `${path}(${callArgs})`;
|
|
452
|
+
if (/^apply(:|$)/.test(trap)) return `${path}(${callArgs})`;
|
|
469
453
|
if (trap === "construct" || trap === "construct:native")
|
|
470
454
|
return `new ${path}(${callArgs})`;
|
|
471
455
|
}
|
|
@@ -501,7 +485,12 @@ var Flugrekorder = (() => {
|
|
|
501
485
|
if (!isProxiable(v) || Graph.isProxy(v))
|
|
502
486
|
return v;
|
|
503
487
|
if (!config.recursive) return v;
|
|
504
|
-
return makeProxy(
|
|
488
|
+
return makeProxy(
|
|
489
|
+
v,
|
|
490
|
+
graph,
|
|
491
|
+
config,
|
|
492
|
+
childOrigin
|
|
493
|
+
);
|
|
505
494
|
};
|
|
506
495
|
const known = (v) => {
|
|
507
496
|
if (!isProxiable(v)) return v;
|