@poe-platform/safe-js 0.1.406 → 0.1.408

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.
@@ -8812,6 +8812,9 @@ async function flushPromiseJobs() {
8812
8812
  var promiseStates = /* @__PURE__ */ new WeakMap();
8813
8813
 
8814
8814
  // packages/safe-js/src/interp/promise-continuations.ts
8815
+ var thenableContinuations = /* @__PURE__ */ new WeakMap();
8816
+ var thenableStates = /* @__PURE__ */ new WeakMap();
8817
+ var thenableResolvers = /* @__PURE__ */ new WeakMap();
8815
8818
  var promiseCapabilityExecutors = /* @__PURE__ */ new WeakMap();
8816
8819
  var promiseAggregateHandlers = /* @__PURE__ */ new WeakMap();
8817
8820
  var promiseAggregateStates = /* @__PURE__ */ new WeakMap();
@@ -21313,15 +21316,23 @@ function createPendingPromiseCapability(budget, context) {
21313
21316
  if (resolverState.settled) return void 0;
21314
21317
  resolverState.settled = true;
21315
21318
  continuation.resolution = { status, value };
21319
+ let prefix;
21316
21320
  try {
21317
21321
  if (status === "rejected") reject(budgetSandboxValue2(value, budget));
21318
21322
  else if (value === promise)
21319
21323
  reject(createSubsetErrorValue("TypeError", "Promise cannot resolve to itself.", context?.stack ?? [], budget));
21320
- else fulfill(resolveSandboxValue(value, { budget, self: promise, context }));
21324
+ else fulfill(resolveSandboxValue(value, {
21325
+ budget,
21326
+ self: promise,
21327
+ context,
21328
+ onSynchronousPrefix: (pending) => {
21329
+ prefix = pending;
21330
+ }
21331
+ }));
21321
21332
  } catch (error) {
21322
21333
  reject(error);
21323
21334
  }
21324
- return void 0;
21335
+ return prefix;
21325
21336
  }
21326
21337
  });
21327
21338
  promiseResolvingFunctions.set(resolver, resolverState);
@@ -21427,7 +21438,12 @@ function createPromiseGlobals(options) {
21427
21438
  }
21428
21439
  const finish = (actualConstructor2) => {
21429
21440
  if (isSandboxPromise(value) && actualConstructor2 === constructor) return value;
21430
- return isSandboxPromiseConstructor(constructor) ? createSandboxPromise(resolveSandboxValue(value, { budget: options.budget, context })) : settleConstructedPromise(constructor, value, "fulfilled", options.budget, context);
21441
+ if (isSandboxPromiseConstructor(constructor)) {
21442
+ const capability = createPendingPromiseCapability(options.budget, context);
21443
+ const prefix = capability.resolve.call([value], context);
21444
+ return prefix instanceof Promise ? prefix.then(() => capability.promise) : capability.promise;
21445
+ }
21446
+ return settleConstructedPromise(constructor, value, "fulfilled", options.budget, context);
21431
21447
  };
21432
21448
  if (!isSandboxPromise(value)) return finish(void 0);
21433
21449
  const descriptor = getSandboxPropertyDescriptor(value, "constructor", options.budget);
@@ -21993,10 +22009,27 @@ function resolveSandboxValueNow(value, options) {
21993
22009
  );
21994
22010
  }
21995
22011
  const then = getThenable(value, options.budget);
21996
- if (then instanceof Promise)
21997
- return then.then(
21998
- (method) => method === void 0 ? budgetIfNeeded(value, options.budget) : resolveThenable(value, method, options)
21999
- );
22012
+ if (then instanceof Promise) {
22013
+ let fulfill;
22014
+ let reject;
22015
+ const resolved = new Promise((resolve, fail2) => {
22016
+ fulfill = resolve;
22017
+ reject = fail2;
22018
+ });
22019
+ const prefix = then.then((method) => {
22020
+ try {
22021
+ fulfill(method === void 0 ? budgetIfNeeded(value, options.budget) : resolveThenable(value, method, options));
22022
+ } catch (error) {
22023
+ reject(error);
22024
+ }
22025
+ return void 0;
22026
+ }, (error) => {
22027
+ reject(error);
22028
+ return void 0;
22029
+ });
22030
+ options.onSynchronousPrefix?.(prefix);
22031
+ return resolved;
22032
+ }
22000
22033
  if (then !== void 0) {
22001
22034
  return resolveThenable(value, then, options);
22002
22035
  }
@@ -22006,72 +22039,85 @@ function resolveThenable(value, then, options) {
22006
22039
  if (typeof value !== "object" || value === null) {
22007
22040
  return Promise.resolve(budgetIfNeeded(value, options.budget));
22008
22041
  }
22009
- return new Promise((resolve, reject) => {
22010
- let settlement;
22011
- let completed = false;
22012
- let invocationPending = true;
22013
- const complete2 = () => {
22014
- if (completed || invocationPending || settlement === void 0) return;
22015
- completed = true;
22016
- try {
22017
- if (settlement.state === "fulfilled") {
22018
- resolve(
22019
- requiresPromiseResolution(settlement.value, options.budget) ? resolveSandboxValueNow(settlement.value, options) : budgetIfNeeded(settlement.value, options.budget)
22020
- );
22021
- } else {
22022
- reject(budgetIfNeeded(settlement.value, options.budget));
22023
- }
22024
- } catch (error) {
22025
- reject(error);
22042
+ const state = {
22043
+ source: value,
22044
+ owner: options.self,
22045
+ settlement: void 0,
22046
+ completed: false,
22047
+ invocationPending: true
22048
+ };
22049
+ const bridge = createThenableBridge(state, options);
22050
+ callInPromiseJob(then, bridge.resolvers, value, bridge.invocation, options.context).catch(bridge.rejectNative);
22051
+ return bridge.promise;
22052
+ }
22053
+ function createThenableBridge(state, options) {
22054
+ thenableStates.set(state, state);
22055
+ let resolve;
22056
+ let reject;
22057
+ const promise = new Promise((fulfill, fail2) => {
22058
+ resolve = fulfill;
22059
+ reject = fail2;
22060
+ });
22061
+ if (state.owner !== void 0 && !state.completed) thenableContinuations.set(state.owner, state);
22062
+ const complete2 = () => {
22063
+ if (state.completed || state.invocationPending || state.settlement === void 0) return;
22064
+ state.completed = true;
22065
+ try {
22066
+ if (state.settlement.state === "fulfilled") {
22067
+ resolve(
22068
+ requiresPromiseResolution(state.settlement.value, options.budget) ? resolveSandboxValueNow(state.settlement.value, { ...options, self: state.owner }) : budgetIfNeeded(state.settlement.value, options.budget)
22069
+ );
22070
+ } else {
22071
+ reject(budgetIfNeeded(state.settlement.value, options.budget));
22026
22072
  }
22027
- };
22028
- const recordSettlement = (state, settledValue) => {
22029
- if (settlement !== void 0) {
22030
- return;
22073
+ } catch (error) {
22074
+ reject(error);
22075
+ }
22076
+ };
22077
+ const recordSettlement = (status, settledValue) => {
22078
+ if (state.settlement !== void 0) {
22079
+ return;
22080
+ }
22081
+ state.settlement = { state: status, value: settledValue };
22082
+ queueMicrotask(complete2);
22083
+ };
22084
+ const resolvers = ["fulfilled", "rejected"].map((action) => {
22085
+ const resolver = createSandboxClosure({
22086
+ sandbox: true,
22087
+ guest: true,
22088
+ name: "",
22089
+ length: 1,
22090
+ retainedValues: () => [state.source, state.owner, state.settlement?.value],
22091
+ call: ([settledValue]) => {
22092
+ recordSettlement(action, settledValue);
22093
+ return void 0;
22031
22094
  }
22032
- settlement = { state, value: settledValue };
22033
- queueMicrotask(complete2);
22034
- };
22035
- callInPromiseJob(
22036
- then,
22037
- [
22038
- createSandboxClosure({
22039
- sandbox: true,
22040
- call: ([resolved]) => {
22041
- recordSettlement("fulfilled", resolved);
22042
- return void 0;
22043
- },
22044
- name: "resolve"
22045
- }),
22046
- createSandboxClosure({
22047
- sandbox: true,
22048
- call: ([reason]) => {
22049
- recordSettlement("rejected", reason);
22050
- return void 0;
22051
- },
22052
- name: "reject"
22053
- })
22054
- ],
22055
- value,
22056
- {
22057
- fulfilled: () => {
22058
- invocationPending = false;
22059
- complete2();
22060
- },
22061
- rejected: (error) => {
22062
- invocationPending = false;
22063
- if (error instanceof SandboxError && (error.code === "budgetExceeded" || error.code === "reentry")) {
22064
- completed = true;
22065
- reject(error);
22066
- return;
22067
- }
22068
- recordSettlement("rejected", error);
22069
- complete2();
22070
- }
22071
- },
22072
- options.context
22073
- ).catch(reject);
22095
+ });
22096
+ thenableResolvers.set(resolver, { continuation: state, action });
22097
+ return resolver;
22074
22098
  });
22099
+ const invocation = {
22100
+ fulfilled: () => {
22101
+ state.invocationPending = false;
22102
+ complete2();
22103
+ },
22104
+ rejected: (error) => {
22105
+ state.invocationPending = false;
22106
+ if (error instanceof SandboxError && (error.code === "budgetExceeded" || error.code === "reentry")) {
22107
+ state.completed = true;
22108
+ reject(error);
22109
+ return;
22110
+ }
22111
+ recordSettlement("rejected", error);
22112
+ complete2();
22113
+ }
22114
+ };
22115
+ const release = () => {
22116
+ if (state.owner !== void 0 && thenableContinuations.get(state.owner) === state)
22117
+ thenableContinuations.delete(state.owner);
22118
+ };
22119
+ promise.then(release, release);
22120
+ return { state, promise, resolvers, invocation, rejectNative: reject };
22075
22121
  }
22076
22122
  function runCapabilityReaction(handler, value, state, capability, budget, context) {
22077
22123
  return runPromiseJob(async () => {
@@ -22300,6 +22346,10 @@ function isPromiseLike2(value) {
22300
22346
  return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function" && !isSandboxClosure(value) && !isSandboxPromise(value);
22301
22347
  }
22302
22348
 
22349
+ // packages/safe-js/src/snapshot/not-ready.ts
22350
+ var SnapshotNotReadyError = class extends TypeError {
22351
+ };
22352
+
22303
22353
  // packages/safe-js/src/interp/symbol-registry.ts
22304
22354
  var symbolRegistryOrigins = /* @__PURE__ */ new WeakMap();
22305
22355
 
@@ -22442,6 +22492,25 @@ function captureGuestHeapNode(value, encode) {
22442
22492
  const aggregateHandler = isSandboxClosure(value) ? promiseAggregateHandlers.get(value) : void 0;
22443
22493
  if (aggregateHandler !== void 0)
22444
22494
  return { kind: "aggregate-handler", entry: encode(aggregateHandler.entry), action: aggregateHandler.action, state: captureObjectState(value, encode) };
22495
+ const thenable = thenableStates.get(value);
22496
+ if (thenable !== void 0) {
22497
+ if (thenable.invocationPending || !thenable.completed && thenable.settlement !== void 0)
22498
+ throw new SnapshotNotReadyError("Cannot serialize an active thenable invocation or settlement.");
22499
+ return {
22500
+ kind: "thenable-state",
22501
+ source: encode(thenable.source),
22502
+ owner: encode(thenable.owner),
22503
+ completed: thenable.completed,
22504
+ ...thenable.settlement === void 0 ? {} : { settlement: { state: thenable.settlement.state, value: encode(thenable.settlement.value) } }
22505
+ };
22506
+ }
22507
+ const thenableResolver = isSandboxClosure(value) ? thenableResolvers.get(value) : void 0;
22508
+ if (thenableResolver !== void 0) return {
22509
+ kind: "thenable-resolver",
22510
+ continuation: encode(thenableResolver.continuation),
22511
+ action: thenableResolver.action,
22512
+ state: captureObjectState(value, encode)
22513
+ };
22445
22514
  const bridge = promiseAdoptionBridges.get(value);
22446
22515
  if (bridge !== void 0) {
22447
22516
  if (bridge.settled || bridge.owner === void 0) return void 0;
@@ -22477,6 +22546,15 @@ function captureGuestHeapNode(value, encode) {
22477
22546
  if (unrepresentedPromiseContinuations.has(value))
22478
22547
  throw new TypeError("Cannot serialize host reference: unrepresented promise continuation.");
22479
22548
  if (continuation?.kind === "capability") {
22549
+ const thenable2 = thenableContinuations.get(value);
22550
+ if (continuation.state.settled && thenable2 !== void 0 && !thenable2.completed && thenable2.owner === value)
22551
+ return {
22552
+ kind: "pending-promise",
22553
+ thenable: encode(thenable2),
22554
+ ...producerState,
22555
+ reactions: [...promiseReactionResults.get(value) ?? []].map(encode),
22556
+ state: captureObjectState(value, encode)
22557
+ };
22480
22558
  const adoption = promiseAdoptions.get(value);
22481
22559
  const bridge2 = adoption === void 0 ? void 0 : promiseAdoptionBridges.get(adoption);
22482
22560
  if (continuation.state.settled && (bridge2 === void 0 || bridge2.settled || bridge2.owner !== value || continuation.resolution?.status !== "fulfilled" || continuation.resolution.value !== bridge2.source)) return void 0;
@@ -27960,7 +28038,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27960
28038
  createRawJson(node.text);
27961
28039
  return true;
27962
28040
  }
27963
- if (!["construction-environment", "capability-executor", "promise-aggregate", "aggregate-entry", "aggregate-handler", "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;
28041
+ if (!["thenable-state", "thenable-resolver", "construction-environment", "capability-executor", "promise-aggregate", "aggregate-entry", "aggregate-handler", "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;
27964
28042
  const reference = (value, kinds) => {
27965
28043
  const ref = record3(value);
27966
28044
  fields(ref, ["kind", "id"]);
@@ -27971,7 +28049,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27971
28049
  };
27972
28050
  const callable = (value) => {
27973
28051
  if (absent(value)) return;
27974
- const target = reference(value, ["aggregate-handler", "capability-executor", "intrinsic", "bound-function", "promise-resolver", "guest-function", "guest-class"]);
28052
+ const target = reference(value, ["thenable-resolver", "aggregate-handler", "capability-executor", "intrinsic", "bound-function", "promise-resolver", "guest-function", "guest-class"]);
27975
28053
  if (target.kind === "intrinsic" && intrinsicCatalogue().get(String(target.id)) !== true)
27976
28054
  throw new TypeError("Guest accessor reference is not callable.");
27977
28055
  };
@@ -28052,7 +28130,26 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
28052
28130
  });
28053
28131
  return false;
28054
28132
  }
28055
- if (node.kind === "construction-environment") {
28133
+ if (node.kind === "thenable-state") {
28134
+ fields(node, ["kind", "source", "owner", "completed"], ["settlement"]);
28135
+ reference(node.source);
28136
+ if (!absent(node.owner)) {
28137
+ const owner = reference(node.owner, ["pending-promise", "promise-reaction", "guest-promise"]);
28138
+ if (node.completed === false && (owner.kind !== "pending-promise" || owner.thenable === void 0 || reference(owner.thenable, ["thenable-state"]) !== node)) throw new TypeError("Invalid thenable owner linkage.");
28139
+ }
28140
+ if (typeof node.completed !== "boolean" || node.completed !== Object.hasOwn(node, "settlement"))
28141
+ throw new TypeError("Invalid thenable settlement phase.");
28142
+ if (node.settlement !== void 0) {
28143
+ const settlement = record3(node.settlement);
28144
+ fields(settlement, ["state", "value"]);
28145
+ if (settlement.state !== "fulfilled" && settlement.state !== "rejected") throw new TypeError("Invalid thenable settlement status.");
28146
+ }
28147
+ } else if (node.kind === "thenable-resolver") {
28148
+ fields(node, ["kind", "continuation", "action", "state"]);
28149
+ reference(node.continuation, ["thenable-state"]);
28150
+ if (node.action !== "fulfilled" && node.action !== "rejected") throw new TypeError("Invalid thenable resolver action.");
28151
+ state(node.state);
28152
+ } else if (node.kind === "construction-environment") {
28056
28153
  fields(node, ["kind", "constructor", "newTarget", "prototype", "thisValue", "thisScope", "initialized"]);
28057
28154
  const owner = reference(node.constructor, ["guest-class"]);
28058
28155
  callable(node.newTarget);
@@ -28128,7 +28225,12 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
28128
28225
  throw new TypeError("Invalid promise resolver action.");
28129
28226
  state(node.state);
28130
28227
  } else if (node.kind === "pending-promise" || node.kind === "promise-reaction") {
28131
- fields(node, node.kind === "pending-promise" ? ["kind", "reactions", "state"] : ["kind", "source", "onFulfilled", "onRejected", "reactions", "state"], node.kind === "pending-promise" ? ["adoption", "producers"] : ["capability", "aggregate", "producers"]);
28228
+ fields(node, node.kind === "pending-promise" ? ["kind", "reactions", "state"] : ["kind", "source", "onFulfilled", "onRejected", "reactions", "state"], node.kind === "pending-promise" ? ["adoption", "thenable", "producers"] : ["capability", "aggregate", "producers"]);
28229
+ if (node.kind === "pending-promise" && Object.hasOwn(node, "thenable")) {
28230
+ const continuation = reference(node.thenable, ["thenable-state"]);
28231
+ if (Object.hasOwn(node, "adoption") || continuation.completed !== false || reference(continuation.owner) !== node)
28232
+ throw new TypeError("Invalid thenable promise owner.");
28233
+ }
28132
28234
  if (node.kind === "pending-promise" && Object.hasOwn(node, "adoption")) {
28133
28235
  const bridge = reference(node.adoption, ["promise-adoption"]);
28134
28236
  if (reference(bridge.owner, ["pending-promise"]) !== node) throw new TypeError("Invalid promise adoption owner.");
@@ -28984,7 +29086,7 @@ function validateDumpHeap(root, state) {
28984
29086
  fail("invalidCycle", "$.heap", error instanceof Error ? error.message : "invalid guest scope parent graph");
28985
29087
  }
28986
29088
  }
28987
- function validateDumpReferences(value, path, depth, state, heapIds, heap, role = "data", allowScopeReference = false, allowConstructionReference = false) {
29089
+ function validateDumpReferences(value, path, depth, state, heapIds, heap, role = "data", allowScopeReference = false, allowConstructionReference = false, allowThenableReference = false) {
28988
29090
  if (value === null || typeof value !== "object") return;
28989
29091
  if (depth > state.limits.maxDepth)
28990
29092
  fail("budgetExceeded", path, `exceeds nesting limit ${state.limits.maxDepth}`);
@@ -29002,6 +29104,8 @@ function validateDumpReferences(value, path, depth, state, heapIds, heap, role =
29002
29104
  fail("invalidValue", path, "Internal scopes cannot be guest data");
29003
29105
  if (heap[String(id)].kind === "construction-environment" && !allowConstructionReference)
29004
29106
  fail("invalidValue", path, "Internal construction environments cannot be guest data");
29107
+ if (heap[String(id)].kind === "thenable-state" && !allowThenableReference)
29108
+ fail("invalidValue", path, "Internal thenable states cannot be guest data");
29005
29109
  }
29006
29110
  for (const [key, entry] of Object.entries(record4)) {
29007
29111
  const childRole = role === "root" && key === "heap" ? "heap" : role === "heap" ? "heap-node" : role === "heap-node" && (record4.kind === "guest-function" || record4.kind === "guest-generator") && key === "environment" ? "function-environment" : role === "heap-node" && record4.kind === "guest-generator" && key === "blockScopes" ? "scope-map" : role === "heap-node" && record4.kind === "guest-generator" && key === "expressionStates" ? "expressions" : role === "expressions" ? "expression" : "data";
@@ -29015,7 +29119,8 @@ function validateDumpReferences(value, path, depth, state, heapIds, heap, role =
29015
29119
  heap,
29016
29120
  childRole,
29017
29121
  scopeField,
29018
- role === "function-environment" && key === "construction"
29122
+ role === "function-environment" && key === "construction",
29123
+ role === "heap-node" && (record4.kind === "thenable-resolver" && key === "continuation" || record4.kind === "pending-promise" && key === "thenable")
29019
29124
  );
29020
29125
  }
29021
29126
  }
@@ -30338,10 +30443,20 @@ function measureSandboxData(values, options = {}) {
30338
30443
  }
30339
30444
  return;
30340
30445
  }
30341
- for (let index = 0; index < value.length; index += 1) {
30342
- const descriptor = Object.getOwnPropertyDescriptor(value, index);
30343
- if (descriptor !== void 0 && "value" in descriptor) visit(descriptor.value, depth + 1);
30446
+ const elements = [];
30447
+ if (nodeTypes.isProxy(value)) {
30448
+ for (let index = 0; index < value.length; index += 1) {
30449
+ const descriptor = Object.getOwnPropertyDescriptor(value, index);
30450
+ if (descriptor !== void 0 && "value" in descriptor) elements.push(descriptor.value);
30451
+ }
30452
+ } else {
30453
+ for (const key of Object.getOwnPropertyNames(value)) {
30454
+ if (!isArrayIndexKey2(key)) continue;
30455
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
30456
+ if (descriptor !== void 0 && "value" in descriptor) elements.push(descriptor.value);
30457
+ }
30344
30458
  }
30459
+ for (const element of elements) visit(element, depth + 1);
30345
30460
  return;
30346
30461
  }
30347
30462
  if (isSandboxMap(value) || isSandboxSet(value)) {
@@ -44382,6 +44497,7 @@ function createDumpController(lifecycle) {
44382
44497
  try {
44383
44498
  settlePendingRequest(serializeRunSnapshot(snapshot));
44384
44499
  } catch (error) {
44500
+ if (!finished && error instanceof SnapshotNotReadyError) return;
44385
44501
  pendingRequest?.reject(error);
44386
44502
  pendingRequest = void 0;
44387
44503
  }
@@ -45452,4 +45568,4 @@ export {
45452
45568
  FileSnapshotBackend,
45453
45569
  run
45454
45570
  };
45455
- //# sourceMappingURL=chunk-XY5ZPK3G.js.map
45571
+ //# sourceMappingURL=chunk-6GFX7QAK.js.map