@poe-platform/safe-js 0.1.419 → 0.1.420

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.
@@ -8690,6 +8690,9 @@ function nextStringIterator(value, budget) {
8690
8690
  // packages/safe-js/src/interp/iterator-wrapper.ts
8691
8691
  var iteratorWrapperStates = /* @__PURE__ */ new WeakMap();
8692
8692
 
8693
+ // packages/safe-js/src/interp/disposable-stack.ts
8694
+ var disposableStackStates = /* @__PURE__ */ new WeakMap();
8695
+
8693
8696
  // packages/safe-js/src/interp/iterator-helper.ts
8694
8697
  var iteratorHelperStates = /* @__PURE__ */ new WeakMap();
8695
8698
 
@@ -22514,6 +22517,16 @@ function serializeCollectionProperties(value, encode, dataOnly = false) {
22514
22517
 
22515
22518
  // packages/safe-js/src/snapshot/guest-heap.ts
22516
22519
  function captureGuestHeapNode(value, encode) {
22520
+ const disposable = disposableStackStates.get(value);
22521
+ if (disposable !== void 0) {
22522
+ if (disposable.active) throw new SnapshotNotReadyError("Cannot snapshot active synchronous resource cleanup.");
22523
+ return {
22524
+ kind: "disposable-stack",
22525
+ disposed: disposable.disposed,
22526
+ resources: disposable.resources.map((resource) => ({ method: encode(resource.method), receiver: encode(resource.receiver), args: resource.args.map(encode) })),
22527
+ state: captureObjectState(value, encode)
22528
+ };
22529
+ }
22517
22530
  const construction = constructionStates.get(value);
22518
22531
  if (construction !== void 0) {
22519
22532
  if (construction.activeCalls !== 0 || construction.thisScope === void 0)
@@ -27404,6 +27417,128 @@ function createIteratorGlobal(budget) {
27404
27417
  return constructor;
27405
27418
  }
27406
27419
 
27420
+ // packages/safe-js/src/interp/globals/disposable-stack.ts
27421
+ function createDisposableStackGlobal(budget) {
27422
+ const prototype = /* @__PURE__ */ Object.create(null);
27423
+ setSandboxPrototype(prototype, getSandboxPrototype(/* @__PURE__ */ Object.create(null), budget));
27424
+ const constructor = createSandboxClosure({
27425
+ guest: true,
27426
+ sandbox: true,
27427
+ name: "DisposableStack",
27428
+ length: 0,
27429
+ call: () => {
27430
+ throw new TypeError("DisposableStack requires new.");
27431
+ },
27432
+ construct: async (_args, context) => {
27433
+ const parent = await read(context?.newTarget ?? constructor, "prototype", context);
27434
+ const instance = /* @__PURE__ */ Object.create(null);
27435
+ disposableStackStates.set(instance, { disposed: false, active: false, resources: [] });
27436
+ setSandboxPrototype(instance, parent !== null && typeof parent === "object" ? parent : prototype, budget);
27437
+ createDataCheckpoint(budget, context)(instance, 0, true);
27438
+ return instance;
27439
+ }
27440
+ });
27441
+ Object.defineProperty(materializeFunctionProperties(constructor), "prototype", { value: prototype, writable: false });
27442
+ Object.defineProperties(prototype, {
27443
+ constructor: { value: constructor, writable: true, configurable: true },
27444
+ [Symbol.toStringTag]: { value: "DisposableStack", configurable: true },
27445
+ disposed: { get: accessorAdapter(createSandboxClosure({
27446
+ guest: true,
27447
+ sandbox: true,
27448
+ name: "get disposed",
27449
+ length: 0,
27450
+ call: (_args, context) => requireState(context?.thisValue).disposed
27451
+ }), "get"), configurable: true }
27452
+ });
27453
+ for (const name of ["use", "adopt", "defer", "move", "dispose"]) {
27454
+ const method = createSandboxClosure({
27455
+ guest: true,
27456
+ sandbox: true,
27457
+ name,
27458
+ length: name === "adopt" ? 2 : name === "move" || name === "dispose" ? 0 : 1,
27459
+ call: async (args, context) => {
27460
+ const receiver = context?.thisValue;
27461
+ const state = requireState(receiver);
27462
+ if (name === "dispose") {
27463
+ if (state.disposed) return void 0;
27464
+ state.disposed = true;
27465
+ state.active = true;
27466
+ let failed = false;
27467
+ let failure;
27468
+ let current;
27469
+ const release = retainValues(budget, () => [
27470
+ receiver,
27471
+ failure,
27472
+ ...current === void 0 ? [] : [current.method, current.receiver, ...current.args]
27473
+ ]);
27474
+ try {
27475
+ while ((current = state.resources.pop()) !== void 0) {
27476
+ budget.visitNode();
27477
+ try {
27478
+ await invokeBuiltinClosure(current.method, current.args, budget, context, current.receiver);
27479
+ } catch (error) {
27480
+ if (isFatalSandboxError(error)) throw error;
27481
+ const thrown = createThrowCompletion(error, budget, context?.stack ?? []).value;
27482
+ if (failed) {
27483
+ const combined = createSubsetErrorValue("SuppressedError", void 0, context?.stack ?? [], budget);
27484
+ Object.defineProperties(combined, {
27485
+ error: { value: thrown, writable: true, configurable: true },
27486
+ suppressed: { value: failure, writable: true, configurable: true }
27487
+ });
27488
+ failure = combined;
27489
+ } else {
27490
+ failed = true;
27491
+ failure = thrown;
27492
+ }
27493
+ }
27494
+ }
27495
+ if (failed) throw failure;
27496
+ return void 0;
27497
+ } finally {
27498
+ state.active = false;
27499
+ release();
27500
+ }
27501
+ }
27502
+ if (state.disposed) throw new ReferenceError("DisposableStack is already disposed.");
27503
+ if (name === "move") {
27504
+ const moved = /* @__PURE__ */ Object.create(null);
27505
+ disposableStackStates.set(moved, { disposed: false, active: false, resources: state.resources });
27506
+ setSandboxPrototype(moved, prototype, budget);
27507
+ state.resources = [];
27508
+ state.disposed = true;
27509
+ createDataCheckpoint(budget, context)(moved, 0, true);
27510
+ return moved;
27511
+ }
27512
+ const value = args[0];
27513
+ if (name === "use" && (value === null || value === void 0)) return value;
27514
+ if (name === "use" && typeof value !== "object") throw new TypeError("Disposable resource must be an object.");
27515
+ const resources = state.resources;
27516
+ const method2 = name === "use" ? await read(value, wellKnownSymbols.dispose, context) : args[name === "adopt" ? 1 : 0];
27517
+ if (!isSandboxClosure(method2)) throw new TypeError("Disposer must be callable.");
27518
+ resources.push({ method: method2, receiver: name === "use" ? value : void 0, args: name === "adopt" ? [value] : [] });
27519
+ createDataCheckpoint(budget, context)(receiver, 0, true);
27520
+ return name === "defer" ? void 0 : value;
27521
+ }
27522
+ });
27523
+ Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
27524
+ if (name === "dispose") Object.defineProperty(prototype, wellKnownSymbols.dispose, { value: method, writable: true, configurable: true });
27525
+ }
27526
+ registerBuiltinIdentities(budget, { DisposableStack: constructor });
27527
+ registerIntrinsicFunction(budget, constructor);
27528
+ registerIntrinsicObject(budget, prototype);
27529
+ return constructor;
27530
+ async function read(value, key, context) {
27531
+ if (context?.getProperty !== void 0) return context.getProperty(value, key);
27532
+ const descriptor = getSandboxPropertyDescriptor(value, key, budget);
27533
+ return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
27534
+ }
27535
+ }
27536
+ function requireState(receiver) {
27537
+ const state = receiver !== null && typeof receiver === "object" ? disposableStackStates.get(receiver) : void 0;
27538
+ if (state === void 0) throw new TypeError("DisposableStack method requires a branded receiver.");
27539
+ return state;
27540
+ }
27541
+
27407
27542
  // packages/safe-js/src/interp/globals/symbol.ts
27408
27543
  var registries = /* @__PURE__ */ new WeakMap();
27409
27544
  function createSymbolGlobal(budget) {
@@ -28031,6 +28166,7 @@ function createBuiltinBindings(options) {
28031
28166
  ...createMathGlobals({ random: options.random, budget: options.budget }),
28032
28167
  ...createObjectArrayGlobals(options),
28033
28168
  Iterator: createIteratorGlobal(options.budget),
28169
+ DisposableStack: createDisposableStackGlobal(options.budget),
28034
28170
  Reflect: createReflectGlobal(options.budget),
28035
28171
  ArrayBuffer: createArrayBufferGlobal(options.budget),
28036
28172
  DataView: createDataViewGlobal(options.budget),
@@ -28108,7 +28244,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
28108
28244
  createRawJson(node.text);
28109
28245
  return true;
28110
28246
  }
28111
- 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;
28247
+ 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", "disposable-stack", "iterator-wrapper", "iterator-helper", "guest-collection-iterator", "guest-regexp-iterator", "map", "set"].includes(String(node.kind))) return false;
28112
28248
  const reference = (value, kinds) => {
28113
28249
  const ref = record3(value);
28114
28250
  fields(ref, ["kind", "id"]);
@@ -28403,6 +28539,19 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
28403
28539
  const iterator = reference(node.iterator);
28404
28540
  if (iterator.kind === "symbol" || iterator.kind === "scope-frame") throw new TypeError("Invalid wrapped iterator.");
28405
28541
  state(node.state);
28542
+ } else if (node.kind === "disposable-stack") {
28543
+ fields(node, ["kind", "disposed", "resources", "state"]);
28544
+ const resources = array(node.resources);
28545
+ if (typeof node.disposed !== "boolean" || resources.length > maxArrayLength)
28546
+ throw new TypeError("Invalid disposable stack state.");
28547
+ for (const rawResource of resources) {
28548
+ const resource = record3(rawResource);
28549
+ fields(resource, ["method", "receiver", "args"]);
28550
+ if (absent(resource.method)) throw new TypeError("Missing disposer.");
28551
+ callable(resource.method);
28552
+ if (array(resource.args).length > 1) throw new TypeError("Invalid disposer arguments.");
28553
+ }
28554
+ state(node.state);
28406
28555
  } else if (node.kind === "intrinsic") {
28407
28556
  fields(node, ["kind", "id"], ["state", "symbolRegistry"]);
28408
28557
  if (typeof node.id !== "string" || !intrinsicCatalogue().has(node.id)) throw new TypeError("Unknown intrinsic identity.");
@@ -30330,6 +30479,8 @@ function* cloneStructuredGraph(value, state, budget, depth = 0) {
30330
30479
  if (typeof value !== "object" || value === null) return allocateProducedSandboxValue(value, budget);
30331
30480
  if (iteratorHelperStates.has(value) || iteratorWrapperStates.has(value))
30332
30481
  throw new DOMException("Iterator objects cannot be structured cloned.", "DataCloneError");
30482
+ if (disposableStackStates.has(value))
30483
+ throw new DOMException("Disposable stacks cannot be structured cloned.", "DataCloneError");
30333
30484
  if (isLiveCapability(value)) throw new DOMException("Capabilities cannot be structured cloned.", "DataCloneError");
30334
30485
  const existing = state.seen.get(value);
30335
30486
  if (existing !== void 0) return existing;
@@ -30429,6 +30580,7 @@ function measureSandboxData(values, options = {}) {
30429
30580
  assertSandboxDataDepth(depth);
30430
30581
  seen.add(value);
30431
30582
  usage += 1;
30583
+ const disposableResources = disposableStackStates.get(value)?.resources.map((resource) => [resource.method, resource.receiver, ...resource.args]);
30432
30584
  const arrayLength = Array.isArray(value) ? value.length : void 0;
30433
30585
  const managedArray = arrayLength !== void 0 && hasManagedDescriptors(value);
30434
30586
  let arrayDescriptors;
@@ -30494,6 +30646,10 @@ function measureSandboxData(values, options = {}) {
30494
30646
  return;
30495
30647
  }
30496
30648
  const wrapperState = iteratorWrapperStates.get(value);
30649
+ if (disposableResources !== void 0) {
30650
+ usage += disposableResources.length;
30651
+ for (const resource of disposableResources) for (const retained2 of resource) visit(retained2, depth + 1);
30652
+ }
30497
30653
  if (wrapperState !== void 0) {
30498
30654
  visit(wrapperState.iterator, depth + 1);
30499
30655
  visit(wrapperState.next, depth + 1);
@@ -33134,6 +33290,7 @@ var KNOWN_RUNTIME_GLOBALS = [
33134
33290
  "Boolean",
33135
33291
  "BigInt",
33136
33292
  "Date",
33293
+ "DisposableStack",
33137
33294
  "decodeURI",
33138
33295
  "decodeURIComponent",
33139
33296
  "encodeURI",
@@ -45652,4 +45809,4 @@ export {
45652
45809
  FileSnapshotBackend,
45653
45810
  run
45654
45811
  };
45655
- //# sourceMappingURL=chunk-SFIE326W.js.map
45812
+ //# sourceMappingURL=chunk-Q5EFE5BH.js.map