flugrekorder 1.1.0 → 1.2.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 +354 -72
- package/dist/flugrekorder.d.mts +49 -24
- package/dist/flugrekorder.d.ts +49 -24
- package/dist/flugrekorder.global.js +422 -175
- package/dist/flugrekorder.global.js.map +1 -1
- package/dist/flugrekorder.js +425 -176
- package/dist/flugrekorder.js.map +1 -1
- package/dist/flugrekorder.mjs +421 -176
- package/dist/flugrekorder.mjs.map +1 -1
- package/package.json +13 -25
package/dist/flugrekorder.mjs
CHANGED
|
@@ -6,9 +6,14 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
6
6
|
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);
|
|
7
7
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
8
|
|
|
9
|
-
// source/
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// source/types.ts
|
|
10
|
+
function isProxiable(value) {
|
|
11
|
+
return value !== null && (typeof value === "object" || typeof value === "function");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// source/graph.ts
|
|
15
|
+
var _index, _all, _byId, _byProxy, _byTarget, _generator;
|
|
16
|
+
var _Graph = class _Graph {
|
|
12
17
|
constructor(id) {
|
|
13
18
|
__privateAdd(this, _byId, /* @__PURE__ */ new Map());
|
|
14
19
|
__privateAdd(this, _byProxy, /* @__PURE__ */ new WeakMap());
|
|
@@ -17,9 +22,26 @@ var Graph = class {
|
|
|
17
22
|
let counter = typeof id === "number" ? id : 0;
|
|
18
23
|
__privateSet(this, _generator, typeof id === "function" ? id : () => `#${++counter}`);
|
|
19
24
|
}
|
|
25
|
+
/** Returns the Graph that owns `pxy`, or `undefined` for non-proxies. */
|
|
26
|
+
static for(pxy) {
|
|
27
|
+
return __privateGet(_Graph, _index).get(pxy);
|
|
28
|
+
}
|
|
29
|
+
/** Returns `true` if `pxy` is a proxy created by this module. */
|
|
30
|
+
static isProxy(pxy) {
|
|
31
|
+
return __privateGet(_Graph, _all).has(pxy);
|
|
32
|
+
}
|
|
33
|
+
/** Marks `pxy` as a known proxy across all graphs (double-wrap guard). */
|
|
34
|
+
static track(pxy) {
|
|
35
|
+
__privateGet(_Graph, _all).add(pxy);
|
|
36
|
+
}
|
|
20
37
|
nextId() {
|
|
21
38
|
return __privateGet(this, _generator).call(this);
|
|
22
39
|
}
|
|
40
|
+
/** Returns the underlying target if `value` is a proxy known to this graph, otherwise `value` unchanged. */
|
|
41
|
+
unwrap(value) {
|
|
42
|
+
if (!isProxiable(value)) return value;
|
|
43
|
+
return __privateGet(this, _byProxy).get(value)?.target ?? value;
|
|
44
|
+
}
|
|
23
45
|
getByProxy(v) {
|
|
24
46
|
return __privateGet(this, _byProxy).get(v);
|
|
25
47
|
}
|
|
@@ -29,62 +51,89 @@ var Graph = class {
|
|
|
29
51
|
getById(id) {
|
|
30
52
|
return __privateGet(this, _byId).get(id);
|
|
31
53
|
}
|
|
32
|
-
register(proxy, target,
|
|
33
|
-
const node = { id, proxy, target, origin };
|
|
54
|
+
register(proxy, target, origin2, id) {
|
|
55
|
+
const node = { id, proxy, target, origin: origin2 };
|
|
34
56
|
__privateGet(this, _byId).set(id, node);
|
|
35
57
|
__privateGet(this, _byProxy).set(proxy, node);
|
|
36
58
|
__privateGet(this, _byTarget).set(target, node);
|
|
59
|
+
__privateGet(_Graph, _index).set(proxy, this);
|
|
37
60
|
return node;
|
|
38
61
|
}
|
|
39
62
|
};
|
|
63
|
+
_index = new WeakMap();
|
|
64
|
+
_all = new WeakMap();
|
|
40
65
|
_byId = new WeakMap();
|
|
41
66
|
_byProxy = new WeakMap();
|
|
42
67
|
_byTarget = new WeakMap();
|
|
43
68
|
_generator = new WeakMap();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
var
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
__privateAdd(_Graph, _index, /* @__PURE__ */ new WeakMap());
|
|
70
|
+
__privateAdd(_Graph, _all, /* @__PURE__ */ new WeakSet());
|
|
71
|
+
var Graph = _Graph;
|
|
72
|
+
|
|
73
|
+
// source/serialize.ts
|
|
74
|
+
var defaults = {
|
|
75
|
+
depth: Infinity,
|
|
76
|
+
redactors: [],
|
|
77
|
+
truncate: Infinity
|
|
78
|
+
};
|
|
79
|
+
function redact(redactors, key, value, target) {
|
|
80
|
+
for (const redactor of redactors) {
|
|
81
|
+
const result = redactor(key, value, target);
|
|
82
|
+
if (result === false) continue;
|
|
83
|
+
return result === true ? "[redacted]" : result;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
50
86
|
}
|
|
51
|
-
function
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
87
|
+
function proxiable(v, graph, seen, serial, depth) {
|
|
88
|
+
const proxyNode = graph.getByProxy(v);
|
|
89
|
+
if (proxyNode !== void 0) return { $proxy: proxyNode.id };
|
|
90
|
+
const targetNode = graph.getByTarget(v);
|
|
91
|
+
if (targetNode !== void 0) return { $unwrap: { $proxy: targetNode.id } };
|
|
92
|
+
if (depth >= serial.depth) return "[\u2026]";
|
|
93
|
+
if (Array.isArray(v)) {
|
|
94
|
+
return v.map(
|
|
95
|
+
(item) => serialize(item, graph, seen, serial, depth + 1)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
56
98
|
if (seen.has(v)) return { $proxy: "?" };
|
|
57
99
|
seen.add(v);
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
100
|
+
const entries = [];
|
|
101
|
+
for (const [k, val] of Object.entries(v)) {
|
|
102
|
+
if (serial.redactors.length > 0) {
|
|
103
|
+
const decision = redact(serial.redactors, k, val, v);
|
|
104
|
+
if (decision === null) continue;
|
|
105
|
+
if (decision !== false) {
|
|
106
|
+
entries.push([k, decision]);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
entries.push([k, serialize(val, graph, seen, serial, depth + 1)]);
|
|
111
|
+
}
|
|
64
112
|
seen.delete(v);
|
|
65
|
-
return
|
|
113
|
+
return Object.fromEntries(entries);
|
|
66
114
|
}
|
|
67
|
-
|
|
68
|
-
{ match: /number|boolean|bigint/, map: (v) => v },
|
|
69
|
-
{ match: /object|function/, map: serializeProxiable }
|
|
70
|
-
];
|
|
71
|
-
function serialize(v, graph, seen = /* @__PURE__ */ new Set()) {
|
|
115
|
+
function serialize(v, graph, seen = /* @__PURE__ */ new Set(), serial = defaults, depth = 0) {
|
|
72
116
|
if (v === null || v === void 0) return v;
|
|
73
|
-
|
|
74
|
-
return
|
|
117
|
+
if (isProxiable(v)) return proxiable(v, graph, seen, serial, depth);
|
|
118
|
+
return typeof v === "string" ? v.length > serial.truncate ? `${v.slice(0, serial.truncate)}\u2026` : v : v;
|
|
75
119
|
}
|
|
76
|
-
function
|
|
120
|
+
function origin(o) {
|
|
77
121
|
if (!o) return null;
|
|
78
122
|
if ("key" in o)
|
|
79
123
|
return { trap: o.trap, parent: o.parent, key: String(o.key) };
|
|
80
124
|
return o;
|
|
81
125
|
}
|
|
82
|
-
|
|
126
|
+
|
|
127
|
+
// source/slots.ts
|
|
128
|
+
var slotProtos = /* @__PURE__ */ new WeakMap();
|
|
129
|
+
var bindCache = /* @__PURE__ */ new WeakMap();
|
|
130
|
+
var slotError = /incompatible receiver|this is not|illegal invocation/i;
|
|
83
131
|
function hasInternalSlots(target) {
|
|
84
132
|
if (typeof target !== "object" || target === null) return false;
|
|
85
133
|
const direct = Object.getPrototypeOf(target);
|
|
86
134
|
if (!direct) return false;
|
|
87
|
-
|
|
135
|
+
const cached = slotProtos.get(direct);
|
|
136
|
+
if (cached !== void 0) return cached;
|
|
88
137
|
const probe = new Proxy(target, {
|
|
89
138
|
set: () => true,
|
|
90
139
|
defineProperty: () => true,
|
|
@@ -102,7 +151,8 @@ function hasInternalSlots(target) {
|
|
|
102
151
|
try {
|
|
103
152
|
fn.call(probe);
|
|
104
153
|
} catch (e) {
|
|
105
|
-
if (e instanceof TypeError && slotError.test(String(e)))
|
|
154
|
+
if (e instanceof TypeError && slotError.test(String(e)))
|
|
155
|
+
slots = true;
|
|
106
156
|
}
|
|
107
157
|
slotProtos.set(direct, slots);
|
|
108
158
|
return slots;
|
|
@@ -114,206 +164,401 @@ function hasInternalSlots(target) {
|
|
|
114
164
|
return false;
|
|
115
165
|
}
|
|
116
166
|
function boundMethod(target, key, fn) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
167
|
+
let cache = bindCache.get(target);
|
|
168
|
+
if (!cache) {
|
|
169
|
+
cache = /* @__PURE__ */ new Map();
|
|
170
|
+
bindCache.set(target, cache);
|
|
171
|
+
}
|
|
172
|
+
const existing = cache.get(key);
|
|
173
|
+
if (existing) return existing;
|
|
174
|
+
const bound = fn.bind(target);
|
|
175
|
+
cache.set(key, bound);
|
|
176
|
+
return bound;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// source/specs.ts
|
|
180
|
+
var TypedArray = Object.getPrototypeOf(Int8Array);
|
|
181
|
+
var ecmaBuiltins = [
|
|
182
|
+
Promise,
|
|
183
|
+
Map,
|
|
184
|
+
Set,
|
|
185
|
+
WeakMap,
|
|
186
|
+
WeakSet,
|
|
187
|
+
Date,
|
|
188
|
+
RegExp,
|
|
189
|
+
ArrayBuffer,
|
|
190
|
+
TypedArray,
|
|
191
|
+
DataView
|
|
192
|
+
];
|
|
193
|
+
function isECMABuiltin(v) {
|
|
194
|
+
return ecmaBuiltins.some((B) => v instanceof B);
|
|
195
|
+
}
|
|
196
|
+
function isUnsafeBinding(v) {
|
|
197
|
+
return isProxiable(v) && hasInternalSlots(v) && !isECMABuiltin(v);
|
|
121
198
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
key,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
199
|
+
function makeSpecs(bind) {
|
|
200
|
+
return {
|
|
201
|
+
get: {
|
|
202
|
+
// For targets with internal slots (Map, Set, WeakMap, WeakSet, Date …)
|
|
203
|
+
// or when bind is true, use the real target as the Reflect.get
|
|
204
|
+
// receiver so that getter-based slot checks and #private field reads
|
|
205
|
+
// (e.g. `get value() { return this.#count; }`) don't throw TypeError.
|
|
206
|
+
pre: ([target, key, receiver], _wrap, _known) => [
|
|
207
|
+
target,
|
|
208
|
+
key,
|
|
209
|
+
hasInternalSlots(target) || bind ? target : receiver
|
|
210
|
+
],
|
|
211
|
+
// For the same targets, bind method results to the real target before
|
|
212
|
+
// wrapping so that apply-level slot checks (e.g. Map.prototype.get)
|
|
213
|
+
// and #private field access inside methods also pass.
|
|
214
|
+
// The bind cache ensures proxy stability.
|
|
215
|
+
post: (result, [target, key], wrap) => {
|
|
216
|
+
if (key === "prototype") return result;
|
|
217
|
+
if (hasInternalSlots(target) || bind) {
|
|
218
|
+
if (typeof result === "function")
|
|
219
|
+
return wrap(
|
|
220
|
+
boundMethod(
|
|
221
|
+
target,
|
|
222
|
+
key,
|
|
223
|
+
result
|
|
224
|
+
)
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
if (isUnsafeBinding(result)) return result;
|
|
228
|
+
return wrap(result);
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
set: {
|
|
232
|
+
pre: ([target, key, value, receiver], wrap) => [
|
|
233
|
+
target,
|
|
234
|
+
key,
|
|
235
|
+
// Don't wrap when target has slots (Map/Set internals) or when the
|
|
236
|
+
// value is an unsafe C++ binding (TCP handles, etc.).
|
|
237
|
+
hasInternalSlots(target) || isUnsafeBinding(value) ? value : wrap(value),
|
|
238
|
+
receiver
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
apply: {
|
|
242
|
+
// thisArg is wrapped normally (it's always a graph node).
|
|
243
|
+
// Call arguments are wrapped with known — only existing graph nodes
|
|
244
|
+
// get proxied; plain data passes through and is inlined by serialize().
|
|
245
|
+
pre: ([target, thisArg, callArgs], wrap, known) => [
|
|
246
|
+
target,
|
|
247
|
+
wrap(thisArg),
|
|
248
|
+
callArgs.map(known)
|
|
249
|
+
],
|
|
250
|
+
post: (result, _args, wrap) => wrap(result)
|
|
251
|
+
},
|
|
252
|
+
construct: {
|
|
253
|
+
pre: ([target, callArgs, newTarget], wrap) => [
|
|
254
|
+
target,
|
|
255
|
+
callArgs.map(wrap),
|
|
256
|
+
newTarget
|
|
257
|
+
],
|
|
258
|
+
post: (result, _args, wrap) => wrap(result)
|
|
259
|
+
},
|
|
260
|
+
defineProperty: {
|
|
261
|
+
pre: (args, wrap) => {
|
|
262
|
+
const [target, key, descriptor] = args;
|
|
263
|
+
const patch = {};
|
|
264
|
+
if (descriptor.value != null && !isUnsafeBinding(descriptor.value))
|
|
265
|
+
patch.value = wrap(descriptor.value);
|
|
266
|
+
if (typeof descriptor.get === "function")
|
|
267
|
+
patch.get = wrap(descriptor.get);
|
|
268
|
+
if (typeof descriptor.set === "function")
|
|
269
|
+
patch.set = wrap(descriptor.set);
|
|
270
|
+
return Object.keys(patch).length > 0 ? [target, key, { ...descriptor, ...patch }] : args;
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
getOwnPropertyDescriptor: {
|
|
274
|
+
post: (result, _args, wrap) => {
|
|
275
|
+
const desc = result;
|
|
276
|
+
if (!desc) return result;
|
|
277
|
+
const patch = {};
|
|
278
|
+
if (desc.value != null && !isUnsafeBinding(desc.value))
|
|
279
|
+
patch.value = wrap(desc.value);
|
|
280
|
+
if (typeof desc.get === "function")
|
|
281
|
+
patch.get = wrap(desc.get);
|
|
282
|
+
if (typeof desc.set === "function")
|
|
283
|
+
patch.set = wrap(desc.set);
|
|
284
|
+
return Object.keys(patch).length > 0 ? { ...desc, ...patch } : result;
|
|
139
285
|
}
|
|
140
|
-
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// source/errors.ts
|
|
291
|
+
function isError(input) {
|
|
292
|
+
return input ? input instanceof Error : false;
|
|
293
|
+
}
|
|
294
|
+
function createErrorGuard(name, contains) {
|
|
295
|
+
const checks = [
|
|
296
|
+
isError,
|
|
297
|
+
(sub) => typeof sub === "object" && sub?.name === name
|
|
298
|
+
];
|
|
299
|
+
if (contains instanceof RegExp) {
|
|
300
|
+
checks.push((v) => contains.test(String(v)));
|
|
301
|
+
}
|
|
302
|
+
return (input) => checks.every((predicate) => predicate(input));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// source/retry.ts
|
|
306
|
+
function unwrap(graph, value) {
|
|
307
|
+
return graph?.unwrap(value) ?? value;
|
|
308
|
+
}
|
|
309
|
+
var isDataCloneDOMException = createErrorGuard("DataCloneError");
|
|
310
|
+
var isTypeErrorPrivateMember = createErrorGuard("TypeError", /private member/i);
|
|
311
|
+
var isTypeErrorIllegalInvocation = createErrorGuard("TypeError", /illegal invocation/i);
|
|
312
|
+
var retryFlows = [
|
|
313
|
+
{
|
|
314
|
+
// Native methods (console.log, DOM APIs, http.Server) check the internal
|
|
315
|
+
// [[Receiver]] slot and throw "Illegal invocation" when called through a
|
|
316
|
+
// proxy. Unwrap the real target from the graph and retry as the receiver.
|
|
317
|
+
is: (trap, error) => trap === "apply" && isTypeErrorIllegalInvocation(error),
|
|
318
|
+
trap: "apply:native",
|
|
319
|
+
handle: (graph, fn, thisArg, argList) => {
|
|
320
|
+
const realThis = unwrap(graph, thisArg);
|
|
321
|
+
return {
|
|
322
|
+
args: [fn, realThis, argList],
|
|
323
|
+
result: Reflect.apply(fn, realThis, argList)
|
|
324
|
+
};
|
|
141
325
|
}
|
|
142
326
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
pre: ([target, thisArg, callArgs], wrap, known) => [
|
|
156
|
-
target,
|
|
157
|
-
wrap(thisArg),
|
|
158
|
-
callArgs.map(known)
|
|
159
|
-
],
|
|
160
|
-
post: (result, _args, wrap) => wrap(result)
|
|
161
|
-
},
|
|
162
|
-
construct: {
|
|
163
|
-
pre: ([target, callArgs, newTarget], wrap) => [
|
|
164
|
-
target,
|
|
165
|
-
callArgs.map(wrap),
|
|
166
|
-
newTarget
|
|
167
|
-
],
|
|
168
|
-
post: (result, _args, wrap) => wrap(result)
|
|
327
|
+
{
|
|
328
|
+
// structuredClone and postMessage can't clone proxy objects — they throw a
|
|
329
|
+
// DataCloneError. Unwrap any proxy arguments to their real targets and retry.
|
|
330
|
+
is: (trap, error) => trap === "apply" && isDataCloneDOMException(error),
|
|
331
|
+
trap: "apply:structure",
|
|
332
|
+
handle: (graph, fn, thisArg, argList) => {
|
|
333
|
+
const unwrappedArgs = argList.map((arg) => unwrap(graph, arg));
|
|
334
|
+
return {
|
|
335
|
+
args: [fn, thisArg, unwrappedArgs],
|
|
336
|
+
result: Reflect.apply(fn, thisArg, unwrappedArgs)
|
|
337
|
+
};
|
|
338
|
+
}
|
|
169
339
|
},
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
340
|
+
{
|
|
341
|
+
// Private fields (#field) use brand checking — accessing #field on a proxy
|
|
342
|
+
// (rather than the original instance) throws "Cannot read private member".
|
|
343
|
+
// Unwrap the real instance from the graph and use it as the receiver.
|
|
344
|
+
is: (trap, error, bind) => bind !== false && trap === "apply" && isTypeErrorPrivateMember(error),
|
|
345
|
+
trap: "apply:private",
|
|
346
|
+
handle: (graph, fn, thisArg, argList) => {
|
|
347
|
+
const realThis = unwrap(graph, thisArg);
|
|
348
|
+
return {
|
|
349
|
+
args: [fn, realThis, argList],
|
|
350
|
+
result: Reflect.apply(fn, realThis, argList)
|
|
351
|
+
};
|
|
180
352
|
}
|
|
181
353
|
},
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
354
|
+
{
|
|
355
|
+
// A getter that reads a #private field hits the same brand check, but the
|
|
356
|
+
// apply retry doesn't apply here. Re-invoke Reflect.get with the real target
|
|
357
|
+
// as its own receiver so the brand check passes.
|
|
358
|
+
is: (trap, error, bind) => bind !== false && trap === "get" && isTypeErrorPrivateMember(error),
|
|
359
|
+
handle: (_graph, target, propertyKey) => ({
|
|
360
|
+
result: Reflect.get(target, propertyKey, target)
|
|
361
|
+
})
|
|
362
|
+
}
|
|
363
|
+
];
|
|
364
|
+
|
|
365
|
+
// source/inspection.ts
|
|
366
|
+
function getTarget(pxy) {
|
|
367
|
+
return Graph.for(pxy)?.getByProxy(pxy)?.target ?? null;
|
|
368
|
+
}
|
|
369
|
+
function getProxyById(id, pxy) {
|
|
370
|
+
return Graph.for(pxy)?.getById(id)?.proxy;
|
|
371
|
+
}
|
|
372
|
+
function getOrigin(pxy) {
|
|
373
|
+
return Graph.for(pxy)?.getByProxy(pxy)?.origin ?? null;
|
|
374
|
+
}
|
|
375
|
+
function getAncestors(pxy) {
|
|
376
|
+
const graph = Graph.for(pxy);
|
|
377
|
+
if (!graph) return [];
|
|
378
|
+
const result = [];
|
|
379
|
+
let node = graph.getByProxy(pxy);
|
|
380
|
+
while (node) {
|
|
381
|
+
result.unshift({ proxy: node.proxy, origin: node.origin });
|
|
382
|
+
if (!node.origin) break;
|
|
383
|
+
const parentId = "parent" in node.origin ? node.origin.parent : node.origin.source;
|
|
384
|
+
node = graph.getById(parentId);
|
|
385
|
+
}
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
388
|
+
function getPath(pxy) {
|
|
389
|
+
const ancestors = getAncestors(pxy);
|
|
390
|
+
const parts = [];
|
|
391
|
+
for (const { origin: o } of ancestors) {
|
|
392
|
+
if (!o) continue;
|
|
393
|
+
if ("key" in o) {
|
|
394
|
+
parts.push(String(o.key));
|
|
395
|
+
} else {
|
|
396
|
+
if (parts.length > 0) {
|
|
397
|
+
parts[parts.length - 1] += "()";
|
|
398
|
+
} else {
|
|
399
|
+
parts.push("()");
|
|
400
|
+
}
|
|
193
401
|
}
|
|
194
402
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
403
|
+
return parts.join(".");
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// source/format.ts
|
|
407
|
+
function resolve(id, proxy) {
|
|
408
|
+
if (!proxy) return id;
|
|
409
|
+
const p = getProxyById(id, proxy);
|
|
410
|
+
return p !== void 0 ? getPath(p) : id;
|
|
411
|
+
}
|
|
412
|
+
function display(v, proxy, limit = 80) {
|
|
413
|
+
if (v === null || v === void 0) return String(v);
|
|
414
|
+
if (typeof v !== "object") return String(v);
|
|
415
|
+
if (!Array.isArray(v) && "$proxy" in v)
|
|
416
|
+
return resolve(v.$proxy, proxy);
|
|
417
|
+
if (!Array.isArray(v) && "$unwrap" in v)
|
|
418
|
+
return `\u2193${resolve(v.$unwrap.$proxy, proxy)}`;
|
|
419
|
+
const raw = Array.isArray(v) ? `[${v.map((i) => display(i, proxy)).join(", ")}]` : JSON.stringify(v);
|
|
420
|
+
return raw.length > limit ? `${raw.slice(0, limit)}\u2026` : raw;
|
|
421
|
+
}
|
|
422
|
+
function format(rekording, proxy) {
|
|
423
|
+
const { id, trap, origin: origin2, args, result } = rekording;
|
|
424
|
+
if (origin2 && "parent" in origin2) {
|
|
425
|
+
const parent = resolve(origin2.parent, proxy);
|
|
426
|
+
const path = parent ? `${parent}.${origin2.key}` : String(origin2.key);
|
|
427
|
+
if (trap === "set") return `${path} = ${display(args[2], proxy)}`;
|
|
428
|
+
if (trap === "get") return `${path} \u2192 ${display(result, proxy)}`;
|
|
429
|
+
return `${trap} ${path}`;
|
|
430
|
+
}
|
|
431
|
+
if (origin2 && "source" in origin2) {
|
|
432
|
+
const path = resolve(origin2.source, proxy);
|
|
433
|
+
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})`;
|
|
436
|
+
if (trap === "construct" || trap === "construct:native")
|
|
437
|
+
return `new ${path}(${callArgs})`;
|
|
438
|
+
}
|
|
439
|
+
return `${trap} on ${id}`;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// source/flugrekorder.ts
|
|
443
|
+
function makeProxy(target, graph, config, origin2) {
|
|
444
|
+
if (Graph.isProxy(target)) return target;
|
|
198
445
|
const existing = graph.getByTarget(target);
|
|
199
446
|
if (existing) return existing.proxy;
|
|
200
447
|
if (target instanceof Promise) {
|
|
201
448
|
const chained = target.then(
|
|
202
|
-
(value) => isProxiable(value) ? makeProxy(value, graph, config,
|
|
449
|
+
(value) => isProxiable(value) ? makeProxy(value, graph, config, origin2) : value
|
|
203
450
|
);
|
|
204
451
|
const id = graph.nextId();
|
|
205
|
-
graph.register(chained, target,
|
|
206
|
-
graphOf.set(chained, graph);
|
|
452
|
+
graph.register(chained, target, origin2, id);
|
|
207
453
|
return chained;
|
|
208
454
|
}
|
|
209
455
|
const proxyId = graph.nextId();
|
|
210
|
-
let pxy;
|
|
211
456
|
const traps = Object.getOwnPropertyNames(Reflect).filter((trap) => config.only === null || config.only.has(trap));
|
|
212
457
|
const handler = Object.fromEntries(
|
|
213
458
|
traps.map((trap) => [
|
|
214
459
|
trap,
|
|
215
460
|
(...rawArgs) => {
|
|
216
|
-
const selfId = graph.
|
|
217
|
-
|
|
461
|
+
const selfId = graph.getByTarget(target).id;
|
|
462
|
+
let childOrigin = /get|set|defineProperty|getOwnPropertyDescriptor/.test(trap) ? {
|
|
218
463
|
trap,
|
|
219
464
|
parent: selfId,
|
|
220
465
|
key: rawArgs[1]
|
|
221
466
|
} : /apply|construct/.test(trap) ? { trap, source: selfId } : null;
|
|
222
467
|
const wrap = (v) => {
|
|
223
|
-
if (!isProxiable(v) ||
|
|
468
|
+
if (!isProxiable(v) || Graph.isProxy(v))
|
|
224
469
|
return v;
|
|
225
470
|
if (!config.recursive) return v;
|
|
226
471
|
return makeProxy(v, graph, config, childOrigin);
|
|
227
472
|
};
|
|
228
473
|
const known = (v) => {
|
|
229
474
|
if (!isProxiable(v)) return v;
|
|
230
|
-
if (
|
|
475
|
+
if (Graph.isProxy(v)) return v;
|
|
231
476
|
const existing2 = graph.getByTarget(v);
|
|
232
477
|
if (existing2) return existing2.proxy;
|
|
233
478
|
return v;
|
|
234
479
|
};
|
|
235
|
-
const spec = specs[trap] ?? {};
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
480
|
+
const spec = config.specs[trap] ?? {};
|
|
481
|
+
const preArgs = spec.pre ? spec.pre(rawArgs, wrap, known) : rawArgs;
|
|
482
|
+
let effectiveTrap = trap;
|
|
483
|
+
let effectiveArgs = preArgs;
|
|
484
|
+
let result;
|
|
485
|
+
try {
|
|
486
|
+
result = Reflect[trap](...preArgs);
|
|
487
|
+
} catch (e) {
|
|
488
|
+
const flow = retryFlows.find(
|
|
489
|
+
({ is }) => is(trap, e, config.bind)
|
|
490
|
+
);
|
|
491
|
+
if (flow) {
|
|
492
|
+
const invoke = flow.handle;
|
|
493
|
+
const output2 = invoke(graph, ...preArgs);
|
|
494
|
+
if (flow.trap) {
|
|
495
|
+
effectiveTrap = flow.trap;
|
|
496
|
+
childOrigin = {
|
|
497
|
+
trap: flow.trap,
|
|
498
|
+
source: selfId
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
if (output2?.args) effectiveArgs = output2.args;
|
|
502
|
+
result = output2.result;
|
|
503
|
+
} else {
|
|
504
|
+
throw e;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
const output = spec.post ? spec.post(result, effectiveArgs, wrap) : result;
|
|
508
|
+
const rekording = {
|
|
240
509
|
id: graph.nextId(),
|
|
241
|
-
trap,
|
|
242
|
-
origin:
|
|
243
|
-
args:
|
|
244
|
-
|
|
245
|
-
|
|
510
|
+
trap: effectiveTrap,
|
|
511
|
+
origin: origin(childOrigin),
|
|
512
|
+
args: effectiveArgs.map(
|
|
513
|
+
(arg) => serialize(arg, graph, /* @__PURE__ */ new Set(), config.serial)
|
|
514
|
+
),
|
|
515
|
+
result: serialize(output, graph, /* @__PURE__ */ new Set(), config.serial),
|
|
516
|
+
timestamp: Date.now()
|
|
517
|
+
};
|
|
518
|
+
if (!config.filter || config.filter(rekording))
|
|
519
|
+
config.write(rekording);
|
|
246
520
|
return output;
|
|
247
521
|
}
|
|
248
522
|
])
|
|
249
523
|
);
|
|
250
|
-
pxy = new Proxy(target, handler);
|
|
251
|
-
graph.register(pxy, target,
|
|
252
|
-
|
|
253
|
-
allProxies.add(pxy);
|
|
524
|
+
const pxy = new Proxy(target, handler);
|
|
525
|
+
graph.register(pxy, target, origin2, proxyId);
|
|
526
|
+
Graph.track(pxy);
|
|
254
527
|
return pxy;
|
|
255
528
|
}
|
|
256
529
|
function create(target, options) {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
`) : (
|
|
260
|
-
// biome-ignore lint/style/noNonNullAssertion: CreateOptions guarantees stream or callback is set — TypeScript cannot express this mutual exclusion
|
|
261
|
-
callback
|
|
262
|
-
);
|
|
530
|
+
const write = "stream" in options ? (r) => options.stream.write(`${JSON.stringify(r)}
|
|
531
|
+
`) : options.callback;
|
|
263
532
|
const recursive = options.recursive !== false;
|
|
264
533
|
const only = options.only ? new Set(options.only) : null;
|
|
534
|
+
const filter = options.filter ?? null;
|
|
535
|
+
const { redact: redact2 } = options;
|
|
536
|
+
const serial = {
|
|
537
|
+
depth: options.depth ?? Infinity,
|
|
538
|
+
redactors: redact2 ? Array.isArray(redact2) ? redact2 : [redact2] : [],
|
|
539
|
+
truncate: options.truncate ?? Infinity
|
|
540
|
+
};
|
|
265
541
|
const graph = new Graph(options.id ?? 0);
|
|
266
|
-
|
|
542
|
+
const specs = makeSpecs(options.bind);
|
|
543
|
+
return makeProxy(
|
|
544
|
+
target,
|
|
545
|
+
graph,
|
|
546
|
+
{ write, recursive, only, filter, serial, specs, bind: options.bind },
|
|
547
|
+
null
|
|
548
|
+
);
|
|
267
549
|
}
|
|
268
550
|
function isFlugrekorder(value) {
|
|
269
|
-
return isProxiable(value) &&
|
|
270
|
-
}
|
|
271
|
-
function getTarget(pxy) {
|
|
272
|
-
return graphOf.get(pxy)?.getByProxy(pxy)?.target ?? null;
|
|
273
|
-
}
|
|
274
|
-
function getProxyById(id, pxy) {
|
|
275
|
-
return graphOf.get(pxy)?.getById(id)?.proxy;
|
|
276
|
-
}
|
|
277
|
-
function getOrigin(pxy) {
|
|
278
|
-
return graphOf.get(pxy)?.getByProxy(pxy)?.origin ?? null;
|
|
279
|
-
}
|
|
280
|
-
function getAncestors(pxy) {
|
|
281
|
-
const graph = graphOf.get(pxy);
|
|
282
|
-
if (!graph) return [];
|
|
283
|
-
const result = [];
|
|
284
|
-
let node = graph.getByProxy(pxy);
|
|
285
|
-
while (node) {
|
|
286
|
-
result.unshift({ proxy: node.proxy, origin: node.origin });
|
|
287
|
-
if (!node.origin) break;
|
|
288
|
-
const parentId = "parent" in node.origin ? node.origin.parent : node.origin.source;
|
|
289
|
-
node = graph.getById(parentId);
|
|
290
|
-
}
|
|
291
|
-
return result;
|
|
292
|
-
}
|
|
293
|
-
function getPath(pxy) {
|
|
294
|
-
const ancestors = getAncestors(pxy);
|
|
295
|
-
const parts = [];
|
|
296
|
-
for (const { origin: o } of ancestors) {
|
|
297
|
-
if (!o) continue;
|
|
298
|
-
if ("key" in o) {
|
|
299
|
-
parts.push(String(o.key));
|
|
300
|
-
} else {
|
|
301
|
-
if (parts.length > 0) {
|
|
302
|
-
parts[parts.length - 1] += "()";
|
|
303
|
-
} else {
|
|
304
|
-
parts.push("()");
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return parts.join(".");
|
|
551
|
+
return isProxiable(value) && Graph.isProxy(value);
|
|
309
552
|
}
|
|
310
553
|
export {
|
|
311
554
|
create,
|
|
555
|
+
format,
|
|
312
556
|
getAncestors,
|
|
313
557
|
getOrigin,
|
|
314
558
|
getPath,
|
|
315
559
|
getProxyById,
|
|
316
560
|
getTarget,
|
|
317
|
-
isFlugrekorder
|
|
561
|
+
isFlugrekorder,
|
|
562
|
+
isProxiable
|
|
318
563
|
};
|
|
319
564
|
//# sourceMappingURL=flugrekorder.mjs.map
|