@poe-platform/safe-js 0.1.397 → 0.1.399

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.
@@ -8695,6 +8695,7 @@ import { types as nodeTypes } from "node:util";
8695
8695
 
8696
8696
  // packages/safe-js/src/interp/promise-tracker.ts
8697
8697
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
8698
+ var unrepresentedPromiseContinuations = /* @__PURE__ */ new WeakSet();
8698
8699
  var SandboxPromiseRejectionTracker = class {
8699
8700
  records = /* @__PURE__ */ new Set();
8700
8701
  recordsByPromise = /* @__PURE__ */ new WeakMap();
@@ -8791,7 +8792,8 @@ function withFatalPromiseCleanup(callback) {
8791
8792
  function createSandboxPromiseRejectionTracker() {
8792
8793
  return new SandboxPromiseRejectionTracker();
8793
8794
  }
8794
- function observeSandboxPromise(promise) {
8795
+ function observeSandboxPromise(promise, represented = false) {
8796
+ if (!represented) unrepresentedPromiseContinuations.add(promise);
8795
8797
  activePromiseTracker.getStore()?.observe(promise);
8796
8798
  }
8797
8799
  function trackSandboxPromise(promise, outcome) {
@@ -8809,6 +8811,31 @@ async function flushPromiseJobs() {
8809
8811
  // packages/safe-js/src/interp/promise-state.ts
8810
8812
  var promiseStates = /* @__PURE__ */ new WeakMap();
8811
8813
 
8814
+ // packages/safe-js/src/interp/promise-continuations.ts
8815
+ var promiseAdoptions = /* @__PURE__ */ new WeakMap();
8816
+ var promiseAdoptionBridges = /* @__PURE__ */ new WeakMap();
8817
+ var promiseAdoptionResolvers = /* @__PURE__ */ new WeakMap();
8818
+ var promiseContinuations = /* @__PURE__ */ new WeakMap();
8819
+ var promiseReactionResults = /* @__PURE__ */ new WeakMap();
8820
+ function trackPromiseContinuation(promise, continuation) {
8821
+ promiseContinuations.set(promise, continuation);
8822
+ if (continuation.kind === "reaction") {
8823
+ let results = promiseReactionResults.get(continuation.source);
8824
+ if (results === void 0) promiseReactionResults.set(continuation.source, results = /* @__PURE__ */ new Set());
8825
+ results.add(promise);
8826
+ }
8827
+ const release = () => {
8828
+ promiseContinuations.delete(promise);
8829
+ if (continuation.kind === "capability") delete continuation.resolution;
8830
+ else {
8831
+ const results = promiseReactionResults.get(continuation.source);
8832
+ results?.delete(promise);
8833
+ if (results?.size === 0) promiseReactionResults.delete(continuation.source);
8834
+ }
8835
+ };
8836
+ promise.promise.then(release, release);
8837
+ }
8838
+
8812
8839
  // packages/safe-js/src/interp/promise-replay.ts
8813
8840
  import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
8814
8841
 
@@ -9409,6 +9436,9 @@ var SandboxJobQueue = class {
9409
9436
  ready = [];
9410
9437
  idle = [];
9411
9438
  generation = 0;
9439
+ bind(task) {
9440
+ return activeJob.run({ queue: this, ownsExecution: false }, task);
9441
+ }
9412
9442
  acquire(job) {
9413
9443
  return new Promise((resolve) => {
9414
9444
  this.pending.push(() => {
@@ -21187,6 +21217,7 @@ async function copyObjectRest(value, excludedKeys, context) {
21187
21217
 
21188
21218
  // packages/safe-js/src/interp/promise-resolvers.ts
21189
21219
  var promiseResolvingFunctions = /* @__PURE__ */ new WeakMap();
21220
+ var promiseResolverActions = /* @__PURE__ */ new WeakMap();
21190
21221
 
21191
21222
  // packages/safe-js/src/interp/promise.ts
21192
21223
  var promiseConstructors = /* @__PURE__ */ new WeakSet();
@@ -21199,6 +21230,44 @@ function isSandboxPromiseConstructor(value) {
21199
21230
  function isPromiseResolvingFunction(value) {
21200
21231
  return isSandboxClosure(value) && promiseResolvingFunctions.has(value);
21201
21232
  }
21233
+ function createPendingPromiseCapability(budget, context) {
21234
+ let fulfill;
21235
+ let reject;
21236
+ const promise = createSandboxPromise(new Promise((resolve, rejectPromise) => {
21237
+ fulfill = resolve;
21238
+ reject = rejectPromise;
21239
+ }), { span: context?.span });
21240
+ const resolverState = { promise, settled: false };
21241
+ const continuation = { kind: "capability", state: resolverState };
21242
+ trackPromiseContinuation(promise, continuation);
21243
+ const resolvers = ["fulfilled", "rejected"].map((status) => {
21244
+ const resolver = createSandboxClosure({
21245
+ sandbox: true,
21246
+ guest: true,
21247
+ name: "",
21248
+ length: 1,
21249
+ retainedValues: () => [promise],
21250
+ call: ([value]) => {
21251
+ if (resolverState.settled) return void 0;
21252
+ resolverState.settled = true;
21253
+ continuation.resolution = { status, value };
21254
+ try {
21255
+ if (status === "rejected") reject(budgetSandboxValue2(value, budget));
21256
+ else if (value === promise)
21257
+ reject(createSubsetErrorValue("TypeError", "Promise cannot resolve to itself.", context?.stack ?? [], budget));
21258
+ else fulfill(resolveSandboxValue(value, { budget, self: promise, context }));
21259
+ } catch (error) {
21260
+ reject(error);
21261
+ }
21262
+ return void 0;
21263
+ }
21264
+ });
21265
+ promiseResolvingFunctions.set(resolver, resolverState);
21266
+ promiseResolverActions.set(resolver, status);
21267
+ return resolver;
21268
+ });
21269
+ return { promise, resolve: resolvers[0], reject: resolvers[1], fulfill, rejectNative: reject };
21270
+ }
21202
21271
  function createPromiseGlobals(options) {
21203
21272
  promisePrototypes2.delete(options.budget);
21204
21273
  const prototype = getPromisePrototype(options.budget);
@@ -21206,56 +21275,12 @@ function createPromiseGlobals(options) {
21206
21275
  if (!isSandboxClosure(executor)) throw new TypeError("Promise executor must be a function.");
21207
21276
  const prototypeValue = context?.newTarget === void 0 ? prototype : context.getProperty === void 0 ? getSandboxDataProperty(context.newTarget, "prototype", options.budget) : context.getProperty(context.newTarget, "prototype");
21208
21277
  const targetPrototype = prototypeValue instanceof Promise ? await prototypeValue : prototypeValue;
21209
- let fulfill;
21210
- let reject;
21211
- const pending = createSandboxPromise(
21212
- new Promise((resolve, rejectPromise) => {
21213
- fulfill = resolve;
21214
- reject = rejectPromise;
21215
- }),
21216
- { span: context?.span }
21217
- );
21278
+ const capability = createPendingPromiseCapability(options.budget, context);
21279
+ const pending = capability.promise;
21218
21280
  if (typeof targetPrototype === "object" && targetPrototype !== null && targetPrototype !== prototype)
21219
21281
  setSandboxPrototype(pending, targetPrototype, options.budget);
21220
- const resolverState = { promise: pending, settled: false };
21221
- const settle = (state, value) => {
21222
- if (resolverState.settled) return;
21223
- resolverState.settled = true;
21224
- try {
21225
- if (state === "rejected") {
21226
- reject(budgetSandboxValue2(value, options.budget));
21227
- } else if (value === pending) {
21228
- reject(
21229
- createSubsetErrorValue(
21230
- "TypeError",
21231
- "Promise cannot resolve to itself.",
21232
- context?.stack ?? [],
21233
- options.budget
21234
- )
21235
- );
21236
- } else {
21237
- fulfill(resolveSandboxValue(value, { budget: options.budget, self: pending, context }));
21238
- }
21239
- } catch (error) {
21240
- reject(error);
21241
- }
21242
- };
21243
21282
  try {
21244
- const resolvers = ["fulfilled", "rejected"].map((state) => {
21245
- const resolver = createSandboxClosure({
21246
- sandbox: true,
21247
- guest: true,
21248
- name: "",
21249
- length: 1,
21250
- retainedValues: () => [pending],
21251
- call: ([value]) => {
21252
- settle(state, value);
21253
- return void 0;
21254
- }
21255
- });
21256
- promiseResolvingFunctions.set(resolver, resolverState);
21257
- return resolver;
21258
- });
21283
+ const resolvers = [capability.resolve, capability.reject];
21259
21284
  const result = executor.call(resolvers, { stack: context?.stack ?? [], thisValue: void 0 });
21260
21285
  if (executor.async !== true) await result;
21261
21286
  else if (isSandboxPromise(result) && result.synchronousPrefix !== void 0)
@@ -21266,7 +21291,7 @@ function createPromiseGlobals(options) {
21266
21291
  observeSandboxPromise(pending);
21267
21292
  throw error;
21268
21293
  }
21269
- settle("rejected", error);
21294
+ capability.reject.call([error]);
21270
21295
  }
21271
21296
  return pending;
21272
21297
  };
@@ -21524,6 +21549,7 @@ function getPromisePrototype(budget) {
21524
21549
  const finish = (constructor2) => {
21525
21550
  if (!isSandboxPromiseConstructor(constructor2)) {
21526
21551
  return createPromiseCapability(constructor2, budget, context).then((capability) => {
21552
+ if (isSandboxPromise(capability.promise)) unrepresentedPromiseContinuations.add(capability.promise);
21527
21553
  observeSandboxPromise(target);
21528
21554
  createSandboxPromise(target.promise.then(
21529
21555
  (value) => {
@@ -21538,19 +21564,29 @@ function getPromisePrototype(budget) {
21538
21564
  return capability.promise;
21539
21565
  });
21540
21566
  }
21541
- observeSandboxPromise(target);
21567
+ observeSandboxPromise(target, true);
21568
+ const continuation = {
21569
+ kind: "reaction",
21570
+ phase: "waiting",
21571
+ source: target,
21572
+ onFulfilled,
21573
+ onRejected
21574
+ };
21542
21575
  const chained = createSandboxPromise(
21543
21576
  target.promise.then(
21544
21577
  (value) => {
21578
+ continuation.phase = "running";
21545
21579
  consumeSettledHostCall(target);
21546
21580
  return runPromiseReaction(onFulfilled, value, "fulfilled", budget, chained, context);
21547
21581
  },
21548
21582
  (reason) => {
21583
+ continuation.phase = "running";
21549
21584
  consumeSettledHostCall(target);
21550
21585
  return runPromiseReaction(onRejected, reason, "rejected", budget, chained, context);
21551
21586
  }
21552
21587
  )
21553
21588
  );
21589
+ trackPromiseContinuation(chained, continuation);
21554
21590
  return chained;
21555
21591
  };
21556
21592
  const constructor = getPromiseSpeciesConstructor(target, prototype, budget, context);
@@ -21698,6 +21734,7 @@ function readPromiseProperty(receiver, property, prototype, budget, context) {
21698
21734
  async function settleIterable(iterable, method, budget, constructor, context) {
21699
21735
  const capability = await createPromiseCapability(constructor, budget, context);
21700
21736
  const prototype = getPromisePrototype(budget);
21737
+ if (isSandboxPromise(capability.promise)) unrepresentedPromiseContinuations.add(capability.promise);
21701
21738
  const values = [];
21702
21739
  let remaining = 1;
21703
21740
  const complete2 = async () => {
@@ -22031,6 +22068,57 @@ function callInPromiseJob(handler, args, thisValue = void 0, completion, context
22031
22068
  }
22032
22069
  });
22033
22070
  }
22071
+ function createPromiseAdoptionBridge(source, budget, owner, context) {
22072
+ let fulfill;
22073
+ let rejectNative;
22074
+ const promise = new Promise((resolve, reject) => {
22075
+ fulfill = resolve;
22076
+ rejectNative = reject;
22077
+ });
22078
+ const token = /* @__PURE__ */ Object.create(null);
22079
+ const settle = (status, value) => {
22080
+ if (bridge.settled) return;
22081
+ bridge.settled = true;
22082
+ try {
22083
+ if (status === "rejected") rejectNative(budgetSandboxValue2(value, budget));
22084
+ else if (requiresPromiseResolution(value, budget)) {
22085
+ fulfill(resolvePromiseResult(value, budget, owner, context));
22086
+ } else fulfill(budgetSandboxValue2(value, budget));
22087
+ } catch (error) {
22088
+ rejectNative(error);
22089
+ }
22090
+ };
22091
+ const resolvers = ["fulfilled", "rejected"].map((action) => {
22092
+ const resolver = createSandboxClosure({
22093
+ sandbox: true,
22094
+ retainedValues: () => [source, owner],
22095
+ call: ([value]) => {
22096
+ settle(action, value);
22097
+ return void 0;
22098
+ }
22099
+ });
22100
+ promiseAdoptionResolvers.set(resolver, { bridge: token, action });
22101
+ return resolver;
22102
+ });
22103
+ const bridge = {
22104
+ source,
22105
+ owner,
22106
+ settled: false,
22107
+ promise,
22108
+ resolve: resolvers[0],
22109
+ reject: resolvers[1],
22110
+ rejectNative
22111
+ };
22112
+ promiseAdoptionBridges.set(token, bridge);
22113
+ if (owner !== void 0) promiseAdoptions.set(owner, token);
22114
+ const release = () => {
22115
+ if (owner !== void 0 && promiseAdoptions.get(owner) === token) promiseAdoptions.delete(owner);
22116
+ promiseAdoptionBridges.delete(token);
22117
+ for (const resolver of resolvers) promiseAdoptionResolvers.delete(resolver);
22118
+ };
22119
+ promise.then(release, release);
22120
+ return { token, bridge };
22121
+ }
22034
22122
  function resolvePromiseResult(result, budget, self, context) {
22035
22123
  if (isPromiseLike2(result)) {
22036
22124
  return Promise.resolve(result).then((resolved) => resolvePromiseResult(resolved, budget, self, context));
@@ -22045,58 +22133,28 @@ function resolvePromiseResult(result, budget, self, context) {
22045
22133
  }
22046
22134
  const then = getSandboxPropertyDescriptor(result, "then", budget)?.value ?? getPromiseMember("then", budget);
22047
22135
  if (!isSandboxClosure(then)) return Promise.resolve(result);
22048
- return new Promise((resolve, reject) => {
22049
- let settled = false;
22050
- const settle = (state, value) => {
22051
- if (settled) return;
22052
- settled = true;
22053
- try {
22054
- if (state === "rejected") reject(budgetSandboxValue2(value, budget));
22055
- else if (requiresPromiseResolution(value, budget)) {
22056
- resolve(resolvePromiseResult(value, budget, self, context));
22057
- } else {
22058
- resolve(budgetSandboxValue2(value, budget));
22059
- }
22060
- } catch (error) {
22061
- reject(error);
22062
- }
22063
- };
22064
- runPromiseJob(async () => {
22065
- try {
22066
- const completion = await callPromiseClosure(
22067
- then,
22068
- [
22069
- createSandboxClosure({
22070
- sandbox: true,
22071
- call: ([value]) => {
22072
- settle("fulfilled", value);
22073
- return void 0;
22074
- }
22075
- }),
22076
- createSandboxClosure({
22077
- sandbox: true,
22078
- call: ([reason]) => {
22079
- settle("rejected", reason);
22080
- return void 0;
22081
- }
22082
- })
22083
- ],
22084
- result,
22085
- budget,
22086
- context
22087
- );
22088
- if (isSandboxPromise(completion)) {
22089
- completion.promise.catch((reason) => {
22090
- if (reason instanceof SandboxError && (reason.code === "budgetExceeded" || reason.code === "reentry")) {
22091
- reject(reason);
22092
- }
22093
- });
22094
- }
22095
- } catch (error) {
22096
- settle("rejected", error);
22136
+ const { bridge } = createPromiseAdoptionBridge(result, budget, self, context);
22137
+ runPromiseJob(async () => {
22138
+ try {
22139
+ const completion = await callPromiseClosure(
22140
+ then,
22141
+ [bridge.resolve, bridge.reject],
22142
+ result,
22143
+ budget,
22144
+ context
22145
+ );
22146
+ if (isSandboxPromise(completion)) {
22147
+ completion.promise.catch((reason) => {
22148
+ if (reason instanceof SandboxError && (reason.code === "budgetExceeded" || reason.code === "reentry")) {
22149
+ bridge.rejectNative(reason);
22150
+ }
22151
+ });
22097
22152
  }
22098
- }).catch(reject);
22099
- });
22153
+ } catch (error) {
22154
+ bridge.reject.call([error]);
22155
+ }
22156
+ }).catch(bridge.rejectNative);
22157
+ return bridge.promise;
22100
22158
  }
22101
22159
  function isSelfResolution(result, self) {
22102
22160
  return self !== void 0 && (result === self || isSandboxPromise(result) && result.promise === self.promise);
@@ -22261,16 +22319,58 @@ function serializeCollectionProperties(value, encode, dataOnly = false) {
22261
22319
 
22262
22320
  // packages/safe-js/src/snapshot/guest-heap.ts
22263
22321
  function captureGuestHeapNode(value, encode) {
22322
+ const bridge = promiseAdoptionBridges.get(value);
22323
+ if (bridge !== void 0) {
22324
+ if (bridge.settled || bridge.owner === void 0) return void 0;
22325
+ return { kind: "promise-adoption", owner: encode(bridge.owner), source: encode(bridge.source) };
22326
+ }
22327
+ const adoptionResolver = isSandboxClosure(value) ? promiseAdoptionResolvers.get(value) : void 0;
22328
+ if (adoptionResolver !== void 0)
22329
+ return { kind: "adoption-resolver", bridge: encode(adoptionResolver.bridge), action: adoptionResolver.action };
22264
22330
  const resolver = isSandboxClosure(value) ? promiseResolvingFunctions.get(value) : void 0;
22265
22331
  if (resolver !== void 0) {
22266
22332
  const settlement = promiseStates.get(resolver.promise);
22267
- if (!resolver.settled || settlement === void 0 || settlement.status === "pending") return void 0;
22333
+ if (settlement?.status === "pending") {
22334
+ const action = isSandboxClosure(value) ? promiseResolverActions.get(value) : void 0;
22335
+ if (action === void 0) return void 0;
22336
+ return { kind: "promise-resolver", promise: encode(resolver.promise), action, state: captureObjectState(value, encode) };
22337
+ }
22338
+ if (!resolver.settled || settlement === void 0) return void 0;
22268
22339
  return { kind: "promise-resolver", promise: encode(resolver.promise), state: captureObjectState(value, encode) };
22269
22340
  }
22270
22341
  if (isSandboxPromise(value)) {
22271
22342
  const settlement = promiseStates.get(value);
22272
22343
  if (settlement !== void 0 && settlement.status !== "pending")
22273
- return { kind: "guest-promise", status: settlement.status, value: encode(settlement.value), state: captureObjectState(value, encode) };
22344
+ return {
22345
+ kind: "guest-promise",
22346
+ status: settlement.status,
22347
+ value: encode(settlement.value),
22348
+ ...promiseReactionResults.has(value) ? { reactions: [...promiseReactionResults.get(value)].map(encode) } : {},
22349
+ state: captureObjectState(value, encode)
22350
+ };
22351
+ const continuation = promiseContinuations.get(value);
22352
+ if (unrepresentedPromiseContinuations.has(value))
22353
+ throw new TypeError("Cannot serialize host reference: unrepresented promise continuation.");
22354
+ if (continuation?.kind === "capability") {
22355
+ const adoption = promiseAdoptions.get(value);
22356
+ const bridge2 = adoption === void 0 ? void 0 : promiseAdoptionBridges.get(adoption);
22357
+ if (continuation.state.settled && (bridge2 === void 0 || bridge2.settled || bridge2.owner !== value || continuation.resolution?.status !== "fulfilled" || continuation.resolution.value !== bridge2.source)) return void 0;
22358
+ return {
22359
+ kind: "pending-promise",
22360
+ ...continuation.state.settled ? { adoption: encode(adoption) } : {},
22361
+ reactions: [...promiseReactionResults.get(value) ?? []].map(encode),
22362
+ state: captureObjectState(value, encode)
22363
+ };
22364
+ }
22365
+ if (continuation?.kind === "reaction" && continuation.phase === "waiting")
22366
+ return {
22367
+ kind: "promise-reaction",
22368
+ source: encode(continuation.source),
22369
+ onFulfilled: encode(continuation.onFulfilled),
22370
+ onRejected: encode(continuation.onRejected),
22371
+ reactions: [...promiseReactionResults.get(value) ?? []].map(encode),
22372
+ state: captureObjectState(value, encode)
22373
+ };
22274
22374
  return void 0;
22275
22375
  }
22276
22376
  if (hasGuestObjectState(value) || privateElements.has(value)) {
@@ -23065,7 +23165,7 @@ function indexHeapContainers(snapshot) {
23065
23165
  if (key === "version" || key === "sourceHash" || key === "heap") {
23066
23166
  continue;
23067
23167
  }
23068
- collectContainerStats(value, stats, ancestors, guestValues);
23168
+ collectContainerStats(value, stats, ancestors, guestValues, inMemoryRunSnapshots.has(snapshot));
23069
23169
  }
23070
23170
  const heapIds = /* @__PURE__ */ new Map();
23071
23171
  let nextId = 1;
@@ -23077,7 +23177,7 @@ function indexHeapContainers(snapshot) {
23077
23177
  }
23078
23178
  return { heapIds, guestValues };
23079
23179
  }
23080
- function collectContainerStats(value, stats, ancestors, guestValues, depth = 0) {
23180
+ function collectContainerStats(value, stats, ancestors, guestValues, trustedRunReplay, depth = 0) {
23081
23181
  if (value === null || typeof value !== "object") {
23082
23182
  return;
23083
23183
  }
@@ -23113,20 +23213,20 @@ function collectContainerStats(value, stats, ancestors, guestValues, depth = 0)
23113
23213
  }) } : isSandboxArrayBuffer(value) ? { kind: "arraybuffer", state: captureArrayBufferState(value, (entry) => {
23114
23214
  guestEntries.push(entry);
23115
23215
  return null;
23116
- }) } : captureGuestHeapNode(value, (entry) => {
23216
+ }) } : trustedRunReplay && isSandboxPromise(value) && unrepresentedPromiseContinuations.has(value) ? void 0 : captureGuestHeapNode(value, (entry) => {
23117
23217
  guestEntries.push(entry);
23118
23218
  return null;
23119
23219
  });
23120
23220
  if (guest !== void 0) {
23121
23221
  if (!isSandboxArrayBuffer(value) && !isSandboxDataView(value) && !isNumericTypedArray(value)) guestValues.add(value);
23122
23222
  for (const entry of guestEntries) {
23123
- collectContainerStats(entry, stats, ancestors, guestValues, depth + 1);
23223
+ collectContainerStats(entry, stats, ancestors, guestValues, trustedRunReplay, depth + 1);
23124
23224
  if (entry !== null && typeof entry === "object") stats.get(entry).forceHeap = true;
23125
23225
  }
23126
23226
  ancestors.delete(value);
23127
23227
  return;
23128
23228
  }
23129
- for (const entry of guestEntries) collectContainerStats(entry, stats, ancestors, guestValues, depth + 1);
23229
+ for (const entry of guestEntries) collectContainerStats(entry, stats, ancestors, guestValues, trustedRunReplay, depth + 1);
23130
23230
  if (!Array.isArray(value) && !isPlainObject(value) && !isNumericTypedArray(value) && !isSandboxDate(value)) {
23131
23231
  ancestors.delete(value);
23132
23232
  return;
@@ -23136,12 +23236,12 @@ function collectContainerStats(value, stats, ancestors, guestValues, depth = 0)
23136
23236
  return "value" in descriptor ? [descriptor.value] : [];
23137
23237
  }) : isSandboxDate(value) ? dateDataProperties(value).flatMap(([key, descriptor]) => typeof key === "string" ? [descriptor.value] : []) : isSandboxBox(value) ? boxedDataProperties(value).map(([, descriptor]) => descriptor.value) : isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
23138
23238
  for (const entry of entries) {
23139
- collectContainerStats(entry, stats, ancestors, guestValues, depth + 1);
23239
+ collectContainerStats(entry, stats, ancestors, guestValues, trustedRunReplay, depth + 1);
23140
23240
  }
23141
23241
  for (const key of ownSerializableSymbolKeys(value)) {
23142
23242
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
23143
23243
  if ("value" in descriptor)
23144
- collectContainerStats(descriptor.value, stats, ancestors, guestValues, depth + 1);
23244
+ collectContainerStats(descriptor.value, stats, ancestors, guestValues, trustedRunReplay, depth + 1);
23145
23245
  }
23146
23246
  ancestors.delete(value);
23147
23247
  }
@@ -27726,7 +27826,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27726
27826
  createRawJson(node.text);
27727
27827
  return true;
27728
27828
  }
27729
- if (!["intrinsic", "bound-function", "promise-resolver", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "guest-boxed", "guest-date", "guest-regex", "guest-promise", "array-iterator", "string-iterator", "iterator-wrapper", "iterator-helper", "guest-collection-iterator", "guest-regexp-iterator", "map", "set"].includes(String(node.kind))) return false;
27829
+ if (!["intrinsic", "bound-function", "promise-resolver", "pending-promise", "promise-reaction", "promise-adoption", "adoption-resolver", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "guest-boxed", "guest-date", "guest-regex", "guest-promise", "array-iterator", "string-iterator", "iterator-wrapper", "iterator-helper", "guest-collection-iterator", "guest-regexp-iterator", "map", "set"].includes(String(node.kind))) return false;
27730
27830
  const reference = (value, kinds) => {
27731
27831
  const ref = record3(value);
27732
27832
  fields(ref, ["kind", "id"]);
@@ -27807,12 +27907,68 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27807
27907
  });
27808
27908
  return false;
27809
27909
  }
27810
- if (node.kind === "promise-resolver") {
27811
- fields(node, ["kind", "promise", "state"]);
27812
- reference(node.promise, ["guest-promise"]);
27910
+ if (node.kind === "promise-adoption") {
27911
+ fields(node, ["kind", "owner", "source"]);
27912
+ const owner = reference(node.owner, ["pending-promise"]);
27913
+ if (reference(owner.adoption, ["promise-adoption"]) !== node) throw new TypeError("Invalid promise adoption owner.");
27914
+ const source = reference(node.source, ["pending-promise", "promise-reaction", "guest-promise"]);
27915
+ if (source === owner)
27916
+ throw new TypeError("A promise cannot adopt itself.");
27917
+ let matchingCallbacks = 0;
27918
+ for (const entry of array(source.reactions)) {
27919
+ const reaction = reference(entry, ["promise-reaction"]);
27920
+ const handlers = [reaction.onFulfilled, reaction.onRejected].map((value) => {
27921
+ if (value === null || typeof value !== "object" || record3(value).kind !== "ref") return void 0;
27922
+ const handler = reference(value);
27923
+ return handler.kind === "adoption-resolver" && reference(handler.bridge, ["promise-adoption"]) === node ? handler : void 0;
27924
+ });
27925
+ if (handlers.every((handler) => handler === void 0)) continue;
27926
+ if (handlers[0]?.action !== "fulfilled" || handlers[1]?.action !== "rejected")
27927
+ throw new TypeError("Invalid promise adoption callbacks.");
27928
+ matchingCallbacks++;
27929
+ }
27930
+ if (matchingCallbacks !== 1) throw new TypeError("Invalid promise adoption callbacks.");
27931
+ } else if (node.kind === "adoption-resolver") {
27932
+ fields(node, ["kind", "bridge", "action"]);
27933
+ reference(node.bridge, ["promise-adoption"]);
27934
+ if (node.action !== "fulfilled" && node.action !== "rejected") throw new TypeError("Invalid adoption resolver action.");
27935
+ } else if (node.kind === "promise-resolver") {
27936
+ fields(node, ["kind", "promise", "state"], ["action"]);
27937
+ const target = reference(node.promise, ["guest-promise", "pending-promise"]);
27938
+ if ((target.kind === "pending-promise" || Object.hasOwn(node, "action")) && node.action !== "fulfilled" && node.action !== "rejected")
27939
+ throw new TypeError("Invalid promise resolver action.");
27940
+ state(node.state);
27941
+ } else if (node.kind === "pending-promise" || node.kind === "promise-reaction") {
27942
+ fields(node, node.kind === "pending-promise" ? ["kind", "reactions", "state"] : ["kind", "source", "onFulfilled", "onRejected", "reactions", "state"], node.kind === "pending-promise" ? ["adoption"] : []);
27943
+ if (node.kind === "pending-promise" && Object.hasOwn(node, "adoption")) {
27944
+ const bridge = reference(node.adoption, ["promise-adoption"]);
27945
+ if (reference(bridge.owner, ["pending-promise"]) !== node) throw new TypeError("Invalid promise adoption owner.");
27946
+ }
27947
+ if (node.kind === "promise-reaction") {
27948
+ const source = reference(node.source, ["pending-promise", "promise-reaction", "guest-promise"]);
27949
+ if (!Array.isArray(source.reactions) || !source.reactions.some((entry) => reference(entry, ["promise-reaction"]) === node))
27950
+ throw new TypeError("Unlisted promise reaction.");
27951
+ }
27952
+ if (!Array.isArray(node.reactions)) throw new TypeError("Invalid promise reactions.");
27953
+ const reactions = /* @__PURE__ */ new Set();
27954
+ for (const entry of node.reactions) {
27955
+ const reaction = reference(entry, ["promise-reaction"]);
27956
+ if (reactions.has(reaction)) throw new TypeError("Duplicate promise reaction.");
27957
+ if (reference(reaction.source) !== node) throw new TypeError("Invalid promise reaction source.");
27958
+ reactions.add(reaction);
27959
+ }
27813
27960
  state(node.state);
27814
27961
  } else if (node.kind === "guest-promise") {
27815
- fields(node, ["kind", "status", "value", "state"]);
27962
+ fields(node, ["kind", "status", "value", "state"], ["reactions"]);
27963
+ if (Object.hasOwn(node, "reactions")) {
27964
+ if (!Array.isArray(node.reactions)) throw new TypeError("Invalid promise reactions.");
27965
+ const reactions = /* @__PURE__ */ new Set();
27966
+ for (const entry of node.reactions) {
27967
+ const reaction = reference(entry, ["promise-reaction"]);
27968
+ if (reactions.has(reaction) || reference(reaction.source) !== node) throw new TypeError("Invalid promise reaction source.");
27969
+ reactions.add(reaction);
27970
+ }
27971
+ }
27816
27972
  if (node.status !== "fulfilled" && node.status !== "rejected") throw new TypeError("Invalid guest promise settlement.");
27817
27973
  if (node.status === "fulfilled" && node.value !== null && typeof node.value === "object" && record3(node.value).kind === "ref" && reference(node.value) === node)
27818
27974
  throw new TypeError("A promise cannot fulfill with itself.");
@@ -28201,19 +28357,26 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
28201
28357
  }
28202
28358
  return true;
28203
28359
  }
28204
- function validateGuestScopeParents(heap) {
28205
- const finished = /* @__PURE__ */ new Set();
28206
- for (const [id, raw] of Object.entries(heap)) {
28207
- if (record3(raw).kind !== "scope-frame" || finished.has(id)) continue;
28208
- const path = /* @__PURE__ */ new Set();
28209
- let current = id;
28210
- while (current !== void 0 && !finished.has(current)) {
28211
- if (path.has(current)) throw new TypeError("Cyclic guest scope parent graph.");
28212
- path.add(current);
28213
- const parent = record3(heap[current]).parent;
28214
- current = absent(parent) ? void 0 : String(record3(parent).id);
28360
+ function validateGuestHeapGraphs(heap) {
28361
+ for (const [kind, edge, message] of [
28362
+ ["scope-frame", "parent", "Cyclic guest scope parent graph."],
28363
+ ["promise-reaction", "source", "Cyclic promise reaction source graph."]
28364
+ ]) {
28365
+ const finished = /* @__PURE__ */ new Set();
28366
+ for (const [id, raw] of Object.entries(heap)) {
28367
+ if (record3(raw).kind !== kind || finished.has(id)) continue;
28368
+ const path = /* @__PURE__ */ new Set();
28369
+ let current = id;
28370
+ while (current !== void 0 && !finished.has(current)) {
28371
+ if (path.has(current)) throw new TypeError(message);
28372
+ const node = record3(heap[current]);
28373
+ if (node.kind !== kind) break;
28374
+ path.add(current);
28375
+ const parent = node[edge];
28376
+ current = absent(parent) ? void 0 : String(record3(parent).id);
28377
+ }
28378
+ for (const visited of path) finished.add(visited);
28215
28379
  }
28216
- for (const visited of path) finished.add(visited);
28217
28380
  }
28218
28381
  }
28219
28382
 
@@ -28597,7 +28760,7 @@ function validateDumpHeap(root, state) {
28597
28760
  }
28598
28761
  validateDumpReferences(root, "$", 0, state, heapIds, heap, "root");
28599
28762
  try {
28600
- validateGuestScopeParents(heap);
28763
+ validateGuestHeapGraphs(heap);
28601
28764
  } catch (error) {
28602
28765
  fail("invalidCycle", "$.heap", error instanceof Error ? error.message : "invalid guest scope parent graph");
28603
28766
  }
@@ -30028,6 +30191,15 @@ function measureSandboxData(values, options = {}) {
30028
30191
  if (isSandboxPromise(value)) {
30029
30192
  const settlement = promiseStates.get(value);
30030
30193
  if (settlement !== void 0 && settlement.status !== "pending") visit(settlement.value, depth + 1);
30194
+ const continuation = promiseContinuations.get(value);
30195
+ if (continuation?.kind === "capability" && continuation.resolution !== void 0)
30196
+ visit(continuation.resolution.value, depth + 1);
30197
+ else if (continuation?.kind === "reaction") {
30198
+ visit(continuation.source, depth + 1);
30199
+ visit(continuation.onFulfilled, depth + 1);
30200
+ visit(continuation.onRejected, depth + 1);
30201
+ }
30202
+ for (const reaction of promiseReactionResults.get(value) ?? []) visit(reaction, depth + 1);
30031
30203
  for (const key of Reflect.ownKeys(getPromiseProperties(value))) {
30032
30204
  const descriptor = Object.getOwnPropertyDescriptor(getPromiseProperties(value), key);
30033
30205
  usage += typeof key === "string" ? key.length + 1 : 1;
@@ -45043,4 +45215,4 @@ export {
45043
45215
  FileSnapshotBackend,
45044
45216
  run
45045
45217
  };
45046
- //# sourceMappingURL=chunk-6HQSVAXP.js.map
45218
+ //# sourceMappingURL=chunk-L4AQGNFP.js.map