poe-code 14.0.51 → 14.0.53

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.
Files changed (57) hide show
  1. package/dist/index.js +451 -181
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-bash/dist/browser.js +35 -15
  6. package/packages/safe-bash/dist/browser.js.map +3 -3
  7. package/packages/safe-bash/dist/shell/arrays/state.d.ts +2 -1
  8. package/packages/safe-bash/dist/shell/arrays/state.d.ts.map +1 -1
  9. package/packages/safe-bash/dist/shell/arrays/state.js +23 -5
  10. package/packages/safe-bash/dist/shell/arrays/state.js.map +1 -1
  11. package/packages/safe-bash/dist/shell/cleanup.d.ts.map +1 -1
  12. package/packages/safe-bash/dist/shell/cleanup.js +11 -5
  13. package/packages/safe-bash/dist/shell/cleanup.js.map +1 -1
  14. package/packages/safe-bash/dist/shell/runtime.js +5 -5
  15. package/packages/safe-bash/dist/shell/runtime.js.map +1 -1
  16. package/packages/safe-js/dist/chunks/{chunk-MQU3AETK.js → chunk-4XYGVCOQ.js} +2 -2
  17. package/packages/safe-js/dist/chunks/{chunk-7AIY5C3F.js → chunk-VDFW3EKS.js} +368 -138
  18. package/packages/safe-js/dist/chunks/chunk-VDFW3EKS.js.map +7 -0
  19. package/packages/safe-js/dist/cli.js +2 -2
  20. package/packages/safe-js/dist/core.js +1 -1
  21. package/packages/safe-js/dist/graph-depth.js +10 -4
  22. package/packages/safe-js/dist/index.js +2 -2
  23. package/packages/safe-js/dist/interp/cancel.js +3 -0
  24. package/packages/safe-js/dist/interp/collection-brands.d.ts +5 -0
  25. package/packages/safe-js/dist/interp/collection-brands.js +8 -0
  26. package/packages/safe-js/dist/interp/collection-iterator.d.ts +27 -0
  27. package/packages/safe-js/dist/interp/collection-iterator.js +61 -0
  28. package/packages/safe-js/dist/interp/globals/collections.js +1 -1
  29. package/packages/safe-js/dist/interp/globals/misc.js +3 -2
  30. package/packages/safe-js/dist/interp/globals/object-array.js +2 -2
  31. package/packages/safe-js/dist/interp/globals/object.js +3 -0
  32. package/packages/safe-js/dist/interp/interpreter.js +20 -11
  33. package/packages/safe-js/dist/interp/iteration.d.ts +2 -1
  34. package/packages/safe-js/dist/interp/iteration.js +4 -1
  35. package/packages/safe-js/dist/interp/methods/array.d.ts +12 -3
  36. package/packages/safe-js/dist/interp/methods/array.js +164 -46
  37. package/packages/safe-js/dist/interp/methods/collection-iterator.d.ts +4 -0
  38. package/packages/safe-js/dist/interp/methods/collection-iterator.js +19 -0
  39. package/packages/safe-js/dist/interp/methods/map.js +3 -4
  40. package/packages/safe-js/dist/interp/methods/number.d.ts +2 -2
  41. package/packages/safe-js/dist/interp/methods/number.js +27 -46
  42. package/packages/safe-js/dist/interp/methods/set.js +3 -3
  43. package/packages/safe-js/dist/interp/patterns.d.ts +2 -0
  44. package/packages/safe-js/dist/interp/patterns.js +20 -2
  45. package/packages/safe-js/dist/interp/promise.js +1 -1
  46. package/packages/safe-js/dist/interp/string-coercion.js +4 -0
  47. package/packages/safe-js/dist/interp/values.d.ts +4 -5
  48. package/packages/safe-js/dist/interp/values.js +42 -10
  49. package/packages/safe-js/dist/snapshot/replay-data.d.ts +10 -0
  50. package/packages/safe-js/dist/snapshot/replay-data.js +32 -0
  51. package/packages/safe-js/dist/snapshot/replay-inputs.js +15 -0
  52. package/packages/safe-js/dist/snapshot/restore.js +16 -0
  53. package/packages/safe-js/dist/snapshot/serialize.d.ts +10 -1
  54. package/packages/safe-js/dist/snapshot/serialize.js +25 -9
  55. package/packages/safe-js/dist/snapshot/validation.js +14 -1
  56. package/packages/safe-js/dist/chunks/chunk-7AIY5C3F.js.map +0 -7
  57. /package/packages/safe-js/dist/chunks/{chunk-MQU3AETK.js.map → chunk-4XYGVCOQ.js.map} +0 -0
@@ -6337,6 +6337,72 @@ function serializedDateTime(value) {
6337
6337
  return Number.isNaN(time) ? null : time;
6338
6338
  }
6339
6339
 
6340
+ // packages/safe-js/src/interp/collection-brands.ts
6341
+ var sandboxMapBrand = /* @__PURE__ */ Symbol("SandboxMap");
6342
+ var sandboxSetBrand = /* @__PURE__ */ Symbol("SandboxSet");
6343
+ function isSandboxMap(value) {
6344
+ return typeof value === "object" && value !== null && sandboxMapBrand in value;
6345
+ }
6346
+ function isSandboxSet(value) {
6347
+ return typeof value === "object" && value !== null && sandboxSetBrand in value;
6348
+ }
6349
+
6350
+ // packages/safe-js/src/interp/collection-iterator.ts
6351
+ var states = /* @__PURE__ */ new WeakMap();
6352
+ function isSandboxCollectionIterator(value) {
6353
+ return typeof value === "object" && value !== null && states.has(value);
6354
+ }
6355
+ function createSandboxCollectionIterator(collection, method) {
6356
+ return restoreSandboxCollectionIterator({ collection, collectionKind: collection.kind, method, index: 0, exhausted: false });
6357
+ }
6358
+ function restoreSandboxCollectionIterator(snapshot, target = /* @__PURE__ */ Object.create(null)) {
6359
+ const { collection, collectionKind, method, index, exhausted } = snapshot;
6360
+ if (collection !== void 0 && collection.kind !== collectionKind)
6361
+ throw new TypeError("Collection iterator source has the wrong brand.");
6362
+ if (!exhausted && collection === void 0)
6363
+ throw new TypeError("Live collection iterator requires its source collection.");
6364
+ const iterator = exhausted ? void 0 : nativeIterator(collection, method);
6365
+ for (let skipped = 0; skipped < index; skipped += 1) {
6366
+ if (iterator === void 0 || iterator.next().done)
6367
+ throw new TypeError("Collection iterator cursor exceeds its source.");
6368
+ }
6369
+ states.set(target, { collection: exhausted ? void 0 : collection, collectionKind, method, exhausted, iterator });
6370
+ return target;
6371
+ }
6372
+ function collectionIteratorState(value) {
6373
+ const state = states.get(value);
6374
+ if (state === void 0) throw new TypeError("Expected a collection iterator.");
6375
+ return state;
6376
+ }
6377
+ function snapshotCollectionIterator(value) {
6378
+ const state = collectionIteratorState(value);
6379
+ if (state.exhausted) return { ...state, index: 0 };
6380
+ const collection = state.collection;
6381
+ const size = collection.kind === "map" ? collection.entries.size : collection.values.size;
6382
+ let remaining = 0;
6383
+ while (!state.iterator.next().done) remaining += 1;
6384
+ const snapshot = { ...state, index: size - remaining };
6385
+ restoreSandboxCollectionIterator(snapshot, value);
6386
+ return snapshot;
6387
+ }
6388
+ function nextCollectionIterator(value, budget) {
6389
+ const state = states.get(value);
6390
+ budget?.visitNode();
6391
+ if (state.exhausted) return { value: void 0, done: true };
6392
+ const result = state.iterator.next();
6393
+ if (result.done) {
6394
+ state.exhausted = true;
6395
+ state.collection = void 0;
6396
+ state.iterator = void 0;
6397
+ return { value: void 0, done: true };
6398
+ }
6399
+ if (state.method === "entries") budget?.allocateArrayLength(2);
6400
+ return { value: result.value, done: false };
6401
+ }
6402
+ function nativeIterator(collection, method) {
6403
+ return collection.kind === "map" ? collection.entries[method]() : collection.values[method]();
6404
+ }
6405
+
6340
6406
  // packages/safe-js/src/interp/host-capabilities.ts
6341
6407
  import { types as types3 } from "node:util";
6342
6408
  var MAX_INDEXED_LENGTH = 65536;
@@ -6909,16 +6975,19 @@ function graphEntries(value) {
6909
6975
  if (isSandboxArguments(value)) {
6910
6976
  return getSandboxArgumentEntries(value).map(([key, entry]) => [`.${key}`, entry]);
6911
6977
  }
6912
- if (value instanceof Map) {
6913
- return [...value.entries()].flatMap(([key, entry], index) => [
6978
+ const map = isSandboxMap(value) ? value.entries : value instanceof Map ? value : void 0;
6979
+ if (map !== void 0) {
6980
+ return [...map.entries()].flatMap(([key, entry], index) => [
6914
6981
  [`.<map>[${index}].key`, key],
6915
6982
  [`.<map>[${index}].value`, entry]
6916
6983
  ]);
6917
6984
  }
6918
- if (value instanceof Set) {
6919
- return [...value.values()].map((entry, index) => [`.<set>[${index}]`, entry]);
6985
+ const set = isSandboxSet(value) ? value.values : value instanceof Set ? value : void 0;
6986
+ if (set !== void 0) {
6987
+ return [...set.values()].map((entry, index) => [`.<set>[${index}]`, entry]);
6920
6988
  }
6921
6989
  const entries = [];
6990
+ if (isSandboxCollectionIterator(value)) entries.push([".<collection>", collectionIteratorState(value).collection]);
6922
6991
  for (const key of Object.keys(value)) {
6923
6992
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
6924
6993
  if (descriptor !== void 0 && "value" in descriptor)
@@ -7581,6 +7650,7 @@ function validateTaggedValue(record2, path, state) {
7581
7650
  case "object":
7582
7651
  case "map":
7583
7652
  case "set":
7653
+ case "collection-iterator":
7584
7654
  return;
7585
7655
  }
7586
7656
  }
@@ -8548,7 +8618,7 @@ async function objectToPrimitive(value, budget, context, joining, hint) {
8548
8618
  }
8549
8619
  }
8550
8620
  function conversionHook(value, name, budget) {
8551
- const implicitBuiltin = !hasExplicitSandboxPrototype(value) && (Array.isArray(value) || isSandboxDate(value) || isFloat32Array(value) || sandboxErrorTypes.has(value) || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxGenerator(value) || isGuestHostObject(value));
8621
+ const implicitBuiltin = !hasExplicitSandboxPrototype(value) && (Array.isArray(value) || isSandboxDate(value) || isFloat32Array(value) || sandboxErrorTypes.has(value) || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxCollectionIterator(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxGenerator(value) || isGuestHostObject(value));
8552
8622
  let current = value;
8553
8623
  let depth = 0;
8554
8624
  while (current !== null) {
@@ -8574,6 +8644,7 @@ function conversionHook(value, name, budget) {
8574
8644
  async function defaultToString(value, budget, context, joining) {
8575
8645
  if (isSandboxMap(value)) return "[object Map]";
8576
8646
  if (isSandboxSet(value)) return "[object Set]";
8647
+ if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "[object Map Iterator]" : "[object Set Iterator]";
8577
8648
  if (isSandboxGenerator(value)) return "[object Generator]";
8578
8649
  if (isSandboxRegex(value)) {
8579
8650
  return budget.allocateString(
@@ -9119,7 +9190,8 @@ function assertSnapshotInactive(snapshot) {
9119
9190
  }
9120
9191
 
9121
9192
  // packages/safe-js/src/interp/iteration.ts
9122
- function getSandboxIterator(value) {
9193
+ function getSandboxIterator(value, budget) {
9194
+ if (isSandboxCollectionIterator(value)) return { next: () => nextCollectionIterator(value, budget), snapshotIndex: () => 0 };
9123
9195
  if (isGuestHostObject(value)) return getHostObjectIterator(value);
9124
9196
  if (isFloat32Array(value)) {
9125
9197
  return syncIterator(Float32Array.prototype.values.call(value));
@@ -9685,7 +9757,7 @@ async function settleIterable(iterable, method, budget, constructor, context) {
9685
9757
  const promiseResolve = readPromiseReceiverProperty(constructor, "resolve", prototype);
9686
9758
  if (!isSandboxClosure(promiseResolve))
9687
9759
  throw new TypeError("Promise constructor requires a callable resolve.");
9688
- const iterator = getSandboxIterator(iterable);
9760
+ const iterator = getSandboxIterator(iterable, budget);
9689
9761
  if (iterator === void 0) throw new TypeError("Promise helpers require an iterable.");
9690
9762
  let index = 0;
9691
9763
  while (true) {
@@ -10127,6 +10199,7 @@ function registerCancelablePromises(value, signal) {
10127
10199
  } else if (isSandboxSet(current)) {
10128
10200
  for (const entry of current.values) pending.push(entry);
10129
10201
  } else {
10202
+ if (isSandboxCollectionIterator(current)) pending.push(collectionIteratorState(current).collection);
10130
10203
  for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(current))) {
10131
10204
  if ("value" in descriptor) pending.push(descriptor.value);
10132
10205
  }
@@ -10228,11 +10301,9 @@ function isPromiseLike2(value) {
10228
10301
  // packages/safe-js/src/interp/values.ts
10229
10302
  var sandboxClosureBrand = /* @__PURE__ */ Symbol("SandboxClosure");
10230
10303
  var sandboxGeneratorBrand = /* @__PURE__ */ Symbol("SandboxGenerator");
10231
- var sandboxMapBrand = /* @__PURE__ */ Symbol("SandboxMap");
10232
10304
  var sandboxPromiseBrand = /* @__PURE__ */ Symbol("SandboxPromise");
10233
10305
  var sandboxRegexBrand = /* @__PURE__ */ Symbol("SandboxRegex");
10234
10306
  var sandboxRegexPattern = /* @__PURE__ */ Symbol("SandboxRegexPattern");
10235
- var sandboxSetBrand = /* @__PURE__ */ Symbol("SandboxSet");
10236
10307
  var sandboxRetainedValues = /* @__PURE__ */ Symbol("SandboxRetainedValues");
10237
10308
  function createSandboxClosure(input) {
10238
10309
  const closure = {
@@ -10399,15 +10470,9 @@ function getSandboxRegexPattern(regex) {
10399
10470
  function isSandboxClosure(value) {
10400
10471
  return typeof value === "object" && value !== null && sandboxClosureBrand in value;
10401
10472
  }
10402
- function isSandboxMap(value) {
10403
- return typeof value === "object" && value !== null && sandboxMapBrand in value;
10404
- }
10405
10473
  function isSandboxPromise(value) {
10406
10474
  return typeof value === "object" && value !== null && sandboxPromiseBrand in value;
10407
10475
  }
10408
- function isSandboxSet(value) {
10409
- return typeof value === "object" && value !== null && sandboxSetBrand in value;
10410
- }
10411
10476
  function isSandboxGenerator(value) {
10412
10477
  return typeof value === "object" && value !== null && sandboxGeneratorBrand in value;
10413
10478
  }
@@ -10420,14 +10485,18 @@ function deepCopyToSandbox(value) {
10420
10485
  });
10421
10486
  }
10422
10487
  function cloneSandboxValue(value) {
10423
- return copyToSandbox(
10488
+ const initializeIterators = [];
10489
+ const copy = copyToSandbox(
10424
10490
  value,
10425
10491
  {
10426
- seen: /* @__PURE__ */ new WeakMap()
10492
+ seen: /* @__PURE__ */ new WeakMap(),
10493
+ initializeIterators
10427
10494
  },
10428
10495
  "<root>",
10429
10496
  true
10430
10497
  );
10498
+ for (const initialize of initializeIterators) initialize();
10499
+ return copy;
10431
10500
  }
10432
10501
  function allocateProducedSandboxValue(value, budget) {
10433
10502
  allocateSandboxValue2(value, budget, /* @__PURE__ */ new WeakSet());
@@ -10492,6 +10561,14 @@ function measureSandboxData(values, options = {}) {
10492
10561
  }
10493
10562
  return;
10494
10563
  }
10564
+ if (isSandboxCollectionIterator(value)) {
10565
+ visit(collectionIteratorState(value).collection, depth + 1);
10566
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
10567
+ usage += key.length + 1;
10568
+ if ("value" in descriptor) visit(descriptor.value, depth + 1);
10569
+ }
10570
+ return;
10571
+ }
10495
10572
  if (isSandboxSet(value)) {
10496
10573
  usage += value.values.size;
10497
10574
  for (const entry of value.values) visit(entry, depth + 1);
@@ -10600,6 +10677,24 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
10600
10677
  if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxRegex(value) || isSandboxPromise(value)) {
10601
10678
  return value;
10602
10679
  }
10680
+ if (isSandboxCollectionIterator(value)) {
10681
+ if (hasGuestObjectState(value)) throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
10682
+ if (!cloneSandboxCollections) return value;
10683
+ const existing = state.seen.get(value);
10684
+ if (existing !== void 0) return existing;
10685
+ const snapshot = snapshotCollectionIterator(value);
10686
+ const copy = restoreSandboxCollectionIterator({ ...snapshot, collection: void 0, index: 0, exhausted: true });
10687
+ state.seen.set(value, copy);
10688
+ const collection = copyToSandbox(snapshot.collection, state, `${path}.<collection>`, true, depth + 1);
10689
+ if (collection !== void 0 && !isSandboxMap(collection) && !isSandboxSet(collection)) throw new TypeError("Invalid cloned collection iterator source.");
10690
+ state.initializeIterators.push(() => {
10691
+ restoreSandboxCollectionIterator({ ...snapshot, collection }, copy);
10692
+ });
10693
+ for (const entry of getEnumerableObjectEntries(value, path)) {
10694
+ defineOwnDataProperty(copy, entry.key, copyToSandbox(entry.value, state, joinPath(path, entry.key), true, depth + 1));
10695
+ }
10696
+ return copy;
10697
+ }
10603
10698
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
10604
10699
  throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
10605
10700
  }
@@ -10855,6 +10950,9 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
10855
10950
  if (isSandboxGenerator(value)) {
10856
10951
  throw new TypeError("Sandbox generators cannot cross into host values.");
10857
10952
  }
10953
+ if (isSandboxCollectionIterator(value)) {
10954
+ throw new TypeError("Sandbox collection iterators cannot cross into host values.");
10955
+ }
10858
10956
  if (isSandboxRegex(value)) {
10859
10957
  throw new TypeError("Invalid sandbox RegExp brand.");
10860
10958
  }
@@ -11148,6 +11246,14 @@ function encodeReplayData(value, options = {}) {
11148
11246
  };
11149
11247
  }
11150
11248
  nodes[id] = { ...storage, properties, extensible: Object.isExtensible(entry) };
11249
+ } else if (isSandboxCollectionIterator(entry)) {
11250
+ const snapshot = snapshotCollectionIterator(entry);
11251
+ const properties = /* @__PURE__ */ Object.create(null);
11252
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(entry))) {
11253
+ if (!("value" in descriptor)) throw new TypeError(`Cannot record replay data accessor '${key}'.`);
11254
+ properties[key] = { value: child(descriptor.value, JSON.stringify(["property", key])), configurable: descriptor.configurable === true, enumerable: descriptor.enumerable === true, writable: descriptor.writable === true };
11255
+ }
11256
+ nodes[id] = { kind: "collection-iterator", collectionKind: snapshot.collectionKind, method: snapshot.method, collection: child(snapshot.collection, "<collection>"), index: snapshot.index, exhausted: snapshot.exhausted, properties, extensible: Object.isExtensible(entry) };
11151
11257
  } else if (isSandboxMap(entry)) {
11152
11258
  nodes[id] = {
11153
11259
  kind: "map",
@@ -11206,6 +11312,7 @@ function decodeReplayData(input, options = {}, parent) {
11206
11312
  const graph = record(input);
11207
11313
  const nodes = list(own(graph, "nodes"));
11208
11314
  const restored = /* @__PURE__ */ new Map();
11315
+ const initializeIterators = [];
11209
11316
  const decode = (entry, depth = 0) => {
11210
11317
  if (depth > MAX_DATA_DEPTH) throw new TypeError("Replay data exceeds the nesting limit.");
11211
11318
  if (entry === null || typeof entry === "boolean" || typeof entry === "string") return entry;
@@ -11298,6 +11405,23 @@ function decodeReplayData(input, options = {}, parent) {
11298
11405
  if (!node.extensible) Object.preventExtensions(result3);
11299
11406
  return result3;
11300
11407
  }
11408
+ if (kind === "collection-iterator") {
11409
+ const collectionKind = own(node, "collectionKind");
11410
+ const method = own(node, "method");
11411
+ const index = own(node, "index");
11412
+ const exhausted = own(node, "exhausted");
11413
+ if (collectionKind !== "map" && collectionKind !== "set" || method !== "keys" && method !== "values" && method !== "entries" || typeof index !== "number" || !Number.isSafeInteger(index) || index < 0 || typeof exhausted !== "boolean" || typeof node.extensible !== "boolean") throw new TypeError("Invalid replay collection iterator.");
11414
+ const result3 = restoreSandboxCollectionIterator({ collection: void 0, collectionKind, method, index: 0, exhausted: true });
11415
+ restored.set(id, result3);
11416
+ const collection = child(own(node, "collection"));
11417
+ if (collection !== void 0 && !isSandboxMap(collection) && !isSandboxSet(collection)) throw new TypeError("Invalid replay collection iterator source.");
11418
+ initializeIterators.push(() => {
11419
+ restoreSandboxCollectionIterator({ collection, collectionKind, method, index, exhausted }, result3);
11420
+ });
11421
+ defineProperties(result3, record(own(node, "properties")), child);
11422
+ if (!node.extensible) Object.preventExtensions(result3);
11423
+ return result3;
11424
+ }
11301
11425
  if (kind === "map") {
11302
11426
  const result3 = createSandboxMap();
11303
11427
  restored.set(id, result3);
@@ -11354,6 +11478,7 @@ function decodeReplayData(input, options = {}, parent) {
11354
11478
  return result2;
11355
11479
  };
11356
11480
  const result = decode(own(graph, "root"));
11481
+ for (const initialize of initializeIterators) initialize();
11357
11482
  if (parent !== void 0) compilation.forward(compilation.tickets, parent);
11358
11483
  return result;
11359
11484
  } finally {
@@ -23540,13 +23665,27 @@ async function bindAssignmentPattern2(pattern, value, target, scope, context) {
23540
23665
  return bindPattern2(pattern.left, defaultValue.value, target, scope, context);
23541
23666
  }
23542
23667
  async function bindArrayPattern2(pattern, value, target, scope, context) {
23543
- const values = getArrayPatternValues(value);
23668
+ const iterator = isSandboxCollectionIterator(value) ? value : void 0;
23669
+ const values = iterator === void 0 ? getArrayPatternValues(value) : void 0;
23544
23670
  for (let index = 0; index < pattern.elements.length; index += 1) {
23545
23671
  const element = pattern.elements[index];
23546
23672
  if (element === null) {
23673
+ if (iterator !== void 0) nextCollectionIterator(iterator, context.budget);
23547
23674
  continue;
23548
23675
  }
23549
- const elementValue = element.type === "RestElement" ? values.slice(index) : values[index];
23676
+ let elementValue;
23677
+ if (iterator === void 0) {
23678
+ elementValue = element.type === "RestElement" ? values.slice(index) : values[index];
23679
+ } else if (element.type === "RestElement") {
23680
+ const rest = [];
23681
+ for (let entry = nextCollectionIterator(iterator, context.budget); !entry.done; entry = nextCollectionIterator(iterator, context.budget)) {
23682
+ context.budget?.allocateArrayLength(rest.length + 1);
23683
+ rest.push(entry.value);
23684
+ }
23685
+ elementValue = rest;
23686
+ } else {
23687
+ elementValue = nextCollectionIterator(iterator, context.budget).value;
23688
+ }
23550
23689
  const binding = await bindPattern2(element, elementValue, target, scope, context);
23551
23690
  if (!binding.ok) {
23552
23691
  return binding;
@@ -23688,6 +23827,7 @@ function hoistVarDeclarations(node, scope) {
23688
23827
  }
23689
23828
 
23690
23829
  // packages/safe-js/src/interp/methods/array.ts
23830
+ var arrayLikeSources = /* @__PURE__ */ new WeakMap();
23691
23831
  var activeArrayCallbacks = /* @__PURE__ */ new WeakMap();
23692
23832
  var arrayMethodNames = /* @__PURE__ */ new Set([
23693
23833
  "map",
@@ -23739,7 +23879,7 @@ function getArrayMember(value, property, options) {
23739
23879
  return createSandboxClosure({
23740
23880
  sandbox: true,
23741
23881
  name: `Array#${property}`,
23742
- call: (args, context) => callArrayMethod(value, property, args, options, context?.stack ?? [])
23882
+ call: (args, context) => callArrayMethod(context?.thisValue, property, args, { ...options, context }, context?.stack ?? [])
23743
23883
  });
23744
23884
  }
23745
23885
  return void 0;
@@ -23754,28 +23894,75 @@ function getArrayIndex(property) {
23754
23894
  function isArrayMethodName(property) {
23755
23895
  return typeof property === "string" && arrayMethodNames.has(property);
23756
23896
  }
23757
- async function callArrayMethod(value, methodName, args, options, stack = []) {
23758
- if (isMutatingArrayMethod(methodName)) {
23759
- assertCollectionMutable(value);
23760
- }
23761
- if (isCallbackArrayMethod(methodName)) {
23762
- let callbackState = activeArrayCallbacks.get(value);
23763
- if (callbackState === void 0) {
23764
- callbackState = { depth: 0, leave: enterRunningState(value) };
23765
- activeArrayCallbacks.set(value, callbackState);
23897
+ async function callArrayMethod(receiver, methodName, args, options, stack = []) {
23898
+ if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
23899
+ if (typeof receiver !== "object") throw new TypeError("Object primitive boxing is not supported.");
23900
+ const retainedReceiver = {};
23901
+ options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
23902
+ try {
23903
+ const value = Array.isArray(receiver) || methodName === "concat" ? receiver : await arrayLikeView(receiver, options);
23904
+ if (isMutatingArrayMethod(methodName)) {
23905
+ assertCollectionMutable(receiver);
23766
23906
  }
23767
- callbackState.depth += 1;
23768
- try {
23769
- return await callArrayMethodUnlocked(value, methodName, args, options, stack);
23770
- } finally {
23771
- callbackState.depth -= 1;
23772
- if (callbackState.depth === 0) {
23773
- activeArrayCallbacks.delete(value);
23774
- callbackState.leave();
23907
+ if (isCallbackArrayMethod(methodName)) {
23908
+ let callbackState = activeArrayCallbacks.get(receiver);
23909
+ if (callbackState === void 0) {
23910
+ callbackState = { depth: 0, leave: enterRunningState(receiver) };
23911
+ activeArrayCallbacks.set(receiver, callbackState);
23912
+ }
23913
+ callbackState.depth += 1;
23914
+ try {
23915
+ const result2 = await callArrayMethodUnlocked(value, methodName, args, options, stack);
23916
+ return result2 === value ? receiver : result2;
23917
+ } finally {
23918
+ callbackState.depth -= 1;
23919
+ if (callbackState.depth === 0) {
23920
+ activeArrayCallbacks.delete(receiver);
23921
+ callbackState.leave();
23922
+ }
23775
23923
  }
23776
23924
  }
23925
+ const result = await callArrayMethodUnlocked(value, methodName, args, options, stack);
23926
+ return result === value ? receiver : result;
23927
+ } finally {
23928
+ options.budget.setRetainedValues(retainedReceiver, void 0);
23777
23929
  }
23778
- return callArrayMethodUnlocked(value, methodName, args, options, stack);
23930
+ }
23931
+ async function arrayLikeView(receiver, options) {
23932
+ const rawLength = options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
23933
+ const number = await sandboxNumber(rawLength, options.budget, options.context);
23934
+ const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
23935
+ const view = new Proxy(/* @__PURE__ */ Object.create(null), {
23936
+ get: (_target, key) => {
23937
+ options.budget.visitNode();
23938
+ if (key === "length") return length;
23939
+ if (typeof key !== "string") return void 0;
23940
+ return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, key) : getSandboxDataProperty(receiver, key, options.budget);
23941
+ },
23942
+ has: (_target, key) => {
23943
+ options.budget.visitNode();
23944
+ if (typeof key === "string" && options.hasProperty !== void 0) return options.hasProperty(receiver, key);
23945
+ for (let current = receiver; current !== null; current = getSandboxPrototype(current, options.budget)) {
23946
+ options.budget.visitNode();
23947
+ if (Object.hasOwn(current, key)) return true;
23948
+ }
23949
+ return false;
23950
+ },
23951
+ set: (_target, key, entry) => {
23952
+ options.budget.visitNode();
23953
+ if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
23954
+ if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
23955
+ else if (!Reflect.set(receiver, key, entry)) throw new TypeError(`Cannot assign property '${key}'.`);
23956
+ return true;
23957
+ },
23958
+ deleteProperty: (_target, key) => {
23959
+ options.budget.visitNode();
23960
+ if (typeof key === "string" && options.deleteProperty !== void 0) return options.deleteProperty(receiver, key);
23961
+ return Reflect.deleteProperty(receiver, key);
23962
+ }
23963
+ });
23964
+ arrayLikeSources.set(view, receiver);
23965
+ return view;
23779
23966
  }
23780
23967
  async function callArrayMethodUnlocked(value, methodName, args, options, stack) {
23781
23968
  switch (methodName) {
@@ -23888,11 +24075,21 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
23888
24075
  return Reflect.apply(Array.prototype.lastIndexOf, value, [...args]);
23889
24076
  case "join":
23890
24077
  return options.budget.allocateString(Reflect.apply(Array.prototype.join, value, [...args]));
23891
- case "slice":
23892
- return budgetProducedValue(
23893
- Reflect.apply(Array.prototype.slice, value, [...args]),
23894
- options.budget
23895
- );
24078
+ case "slice": {
24079
+ const length = value.length;
24080
+ const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
24081
+ const end = args[1] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
24082
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
24083
+ const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
24084
+ const count = Math.max(final - first, 0);
24085
+ options.budget.allocateArrayLength(count);
24086
+ const result = new Array(count);
24087
+ for (let index = 0; index < count; index += 1) {
24088
+ options.budget.visitNode();
24089
+ if (first + index in value) result[index] = value[first + index];
24090
+ }
24091
+ return budgetProducedValue(result, options.budget);
24092
+ }
23896
24093
  case "concat":
23897
24094
  return budgetProducedValue(
23898
24095
  Reflect.apply(Array.prototype.concat, value, [...args]),
@@ -23919,7 +24116,7 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
23919
24116
  );
23920
24117
  case "sort":
23921
24118
  if (args[0] === void 0) {
23922
- value.sort();
24119
+ Reflect.apply(Array.prototype.sort, value, []);
23923
24120
  budgetProducedValue(value, options.budget);
23924
24121
  return value;
23925
24122
  }
@@ -23927,11 +24124,17 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
23927
24124
  budgetProducedValue(value, options.budget);
23928
24125
  return value;
23929
24126
  case "reverse":
23930
- value.reverse();
24127
+ Reflect.apply(Array.prototype.reverse, value, []);
23931
24128
  budgetProducedValue(value, options.budget);
23932
24129
  return value;
23933
24130
  case "toSorted": {
23934
- const result = Array.from(value);
24131
+ const length = value.length;
24132
+ options.budget.allocateArrayLength(length);
24133
+ const result = new Array(length);
24134
+ for (let index = 0; index < length; index += 1) {
24135
+ options.budget.visitNode();
24136
+ result[index] = value[index];
24137
+ }
23935
24138
  if (args[0] === void 0) {
23936
24139
  result.sort();
23937
24140
  } else {
@@ -23940,13 +24143,29 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
23940
24143
  return budgetProducedValue(result, options.budget);
23941
24144
  }
23942
24145
  case "toReversed": {
23943
- const result = Array.from(value);
23944
- result.reverse();
24146
+ const length = value.length;
24147
+ options.budget.allocateArrayLength(length);
24148
+ const result = new Array(length);
24149
+ for (let index = 0; index < length; index += 1) {
24150
+ options.budget.visitNode();
24151
+ result[index] = value[length - index - 1];
24152
+ }
23945
24153
  return budgetProducedValue(result, options.budget);
23946
24154
  }
23947
24155
  case "toSpliced": {
23948
- const result = Array.from(value);
23949
- Reflect.apply(Array.prototype.splice, result, [...args]);
24156
+ const length = value.length;
24157
+ const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
24158
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
24159
+ const inserted = Math.max(args.length - 2, 0);
24160
+ const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(Math.max(toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context)), 0), length - first);
24161
+ const resultLength = length + inserted - deleted;
24162
+ if (resultLength > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24163
+ options.budget.allocateArrayLength(resultLength);
24164
+ const result = new Array(resultLength);
24165
+ for (let index = 0; index < resultLength; index += 1) {
24166
+ options.budget.visitNode();
24167
+ result[index] = index < first ? value[index] : index < first + inserted ? args[index - first + 2] : value[index - inserted + deleted];
24168
+ }
23950
24169
  return budgetProducedValue(result, options.budget);
23951
24170
  }
23952
24171
  case "with": {
@@ -23960,39 +24179,42 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
23960
24179
  const result = [];
23961
24180
  for (let position = 0; position < length; position += 1) {
23962
24181
  options.budget.visitNode();
23963
- result[position] = position === actualIndex ? args[1] : Object.hasOwn(value, position) ? value[position] : void 0;
24182
+ result[position] = position === actualIndex ? args[1] : Array.isArray(value) && !Object.hasOwn(value, position) ? void 0 : value[position];
23964
24183
  }
23965
24184
  return budgetProducedValue(result, options.budget);
23966
24185
  }
23967
24186
  case "push": {
23968
- appendArrayValues(value, args);
23969
- const nextLength = value.length;
24187
+ const nextLength = appendArrayValues(value, args);
23970
24188
  budgetProducedValue(value, options.budget);
23971
24189
  return nextLength;
23972
24190
  }
23973
24191
  case "pop":
23974
- return budgetProducedValue(value.pop(), options.budget);
24192
+ return budgetProducedValue(Reflect.apply(Array.prototype.pop, value, []), options.budget);
23975
24193
  case "shift":
23976
- return budgetProducedValue(value.shift(), options.budget);
24194
+ return budgetProducedValue(Reflect.apply(Array.prototype.shift, value, []), options.budget);
23977
24195
  case "unshift": {
23978
- prependArrayValues(value, args);
23979
- const nextLength = value.length;
24196
+ const nextLength = prependArrayValues(value, args);
23980
24197
  budgetProducedValue(value, options.budget);
23981
24198
  return nextLength;
23982
24199
  }
23983
24200
  }
23984
24201
  }
23985
24202
  function appendArrayValues(target, values) {
24203
+ let length = target.length;
24204
+ if (length + values.length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
23986
24205
  for (const value of values) {
23987
- target.push(value);
24206
+ target[length++] = value;
23988
24207
  }
24208
+ target.length = length;
24209
+ return length;
23989
24210
  }
23990
24211
  function prependArrayValues(target, values) {
23991
24212
  const originalLength = target.length;
23992
- target.length = originalLength + values.length;
23993
- for (let index = originalLength - 1; index >= 0; index -= 1) {
24213
+ const length = originalLength + values.length;
24214
+ if (length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24215
+ for (let index = values.length === 0 ? -1 : originalLength - 1; index >= 0; index -= 1) {
23994
24216
  const targetIndex = index + values.length;
23995
- if (Object.hasOwn(target, index)) {
24217
+ if (index in target) {
23996
24218
  target[targetIndex] = target[index];
23997
24219
  } else {
23998
24220
  delete target[targetIndex];
@@ -24001,6 +24223,8 @@ function prependArrayValues(target, values) {
24001
24223
  for (let index = 0; index < values.length; index += 1) {
24002
24224
  target[index] = values[index];
24003
24225
  }
24226
+ target.length = length;
24227
+ return length;
24004
24228
  }
24005
24229
  function isCallbackArrayMethod(methodName) {
24006
24230
  return methodName === "map" || methodName === "filter" || methodName === "find" || methodName === "findIndex" || methodName === "findLast" || methodName === "findLastIndex" || methodName === "some" || methodName === "every" || methodName === "reduce" || methodName === "reduceRight" || methodName === "forEach" || methodName === "flatMap" || methodName === "sort";
@@ -24016,6 +24240,7 @@ function getRequiredCallback(methodName, value) {
24016
24240
  }
24017
24241
  async function mapArray(value, callback, options, stack, thisValue) {
24018
24242
  const length = value.length;
24243
+ options.budget.allocateArrayLength(length);
24019
24244
  const result = new Array(length);
24020
24245
  options.budget.setRetainedValues(result, () => [result]);
24021
24246
  try {
@@ -24161,7 +24386,7 @@ async function reduceFromLeft(value, callback, accumulator, startIndex, length,
24161
24386
  if (!(index in value)) {
24162
24387
  continue;
24163
24388
  }
24164
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
24389
+ current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
24165
24390
  }
24166
24391
  return current;
24167
24392
  } finally {
@@ -24178,7 +24403,7 @@ async function reduceFromRight(value, callback, accumulator, startIndex, length,
24178
24403
  if (!(index in value)) {
24179
24404
  continue;
24180
24405
  }
24181
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
24406
+ current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
24182
24407
  }
24183
24408
  return current;
24184
24409
  } finally {
@@ -24301,7 +24526,7 @@ async function compareEntries(left, right, comparator, options, stack) {
24301
24526
  return Number.isNaN(result) ? 0 : result;
24302
24527
  }
24303
24528
  async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
24304
- return options.callClosure(callback, [value, index, array], stack, thisValue);
24529
+ return options.callClosure(callback, [value, index, arrayLikeSources.get(array) ?? array], stack, thisValue);
24305
24530
  }
24306
24531
  function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24307
24532
  for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
@@ -24313,6 +24538,7 @@ function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24313
24538
  return -1;
24314
24539
  }
24315
24540
  function budgetProducedValue(value, budget) {
24541
+ if (typeof value === "object" && value !== null) value = arrayLikeSources.get(value) ?? value;
24316
24542
  allocateProducedValue(value, budget, /* @__PURE__ */ new WeakSet());
24317
24543
  return value;
24318
24544
  }
@@ -24580,14 +24806,9 @@ async function callMapMethod(target, methodName, args, options, stack = []) {
24580
24806
  return void 0;
24581
24807
  }
24582
24808
  case "keys":
24583
- return allocateProducedSandboxValue([...target.entries.keys()], options.budget);
24584
24809
  case "values":
24585
- return allocateProducedSandboxValue([...target.entries.values()], options.budget);
24586
24810
  case "entries":
24587
- return allocateProducedSandboxValue(
24588
- [...target.entries].map(([key, value]) => [key, value]),
24589
- options.budget
24590
- );
24811
+ return createSandboxCollectionIterator(target, methodName);
24591
24812
  }
24592
24813
  }
24593
24814
 
@@ -24605,63 +24826,42 @@ function getNumberMember(property, budget) {
24605
24826
  return createSandboxClosure({
24606
24827
  sandbox: true,
24607
24828
  name: `Number#${property}`,
24608
- call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget)
24829
+ call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
24609
24830
  });
24610
24831
  }
24611
24832
  function isNumberMethodName(property) {
24612
24833
  return typeof property === "string" && numberMethodNames.has(property);
24613
24834
  }
24614
- function callNumberMethod(value, methodName, args, budget) {
24835
+ function callNumberMethod(value, methodName, args, budget, context) {
24615
24836
  if (typeof value !== "number") {
24616
24837
  throw new TypeError(`Number#${methodName} requires a number receiver.`);
24617
24838
  }
24618
- return budget.allocateString(callNativeNumberMethod(value, methodName, args));
24619
- }
24620
- function callNativeNumberMethod(value, methodName, args) {
24621
- switch (methodName) {
24622
- case "toString":
24623
- return value.toString(asValidatedRadix(args[0]));
24624
- case "toExponential":
24625
- return args[0] === void 0 ? value.toExponential() : value.toExponential(asValidatedFractionDigits(args[0], methodName));
24626
- case "toFixed":
24627
- return value.toFixed(asValidatedFractionDigits(args[0], methodName));
24628
- case "toPrecision":
24629
- return args[0] === void 0 ? value.toPrecision() : value.toPrecision(asValidatedPrecision(args[0]));
24630
- }
24631
- }
24632
- function asValidatedRadix(value) {
24633
- if (value === void 0) {
24634
- return void 0;
24839
+ const argument = args[0];
24840
+ if (argument !== null && typeof argument === "object") {
24841
+ return formatObjectArgument(value, methodName, argument, budget, context);
24635
24842
  }
24636
- const radix = toIntegerOrInfinity2(value);
24637
- if (radix < 2 || radix > 36) {
24638
- throw new RangeError("Number#toString radix must be between 2 and 36.");
24639
- }
24640
- return radix;
24843
+ return formatNumber(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
24641
24844
  }
24642
- function asValidatedFractionDigits(value, methodName) {
24643
- const digits = toIntegerOrInfinity2(value);
24644
- if (digits < 0 || digits > 100) {
24645
- throw new RangeError(`Number#${methodName} digits must be between 0 and 100.`);
24646
- }
24647
- return digits;
24648
- }
24649
- function asValidatedPrecision(value) {
24650
- const precision = toIntegerOrInfinity2(value);
24651
- if (precision < 1 || precision > 100) {
24652
- throw new RangeError("Number#toPrecision precision must be between 1 and 100.");
24845
+ async function formatObjectArgument(value, methodName, argument, budget, context) {
24846
+ const retainedArgument = {};
24847
+ budget.setRetainedValues(retainedArgument, () => [argument]);
24848
+ try {
24849
+ const number = await sandboxNumber(argument, budget, context);
24850
+ return formatNumber(value, methodName, number, budget);
24851
+ } finally {
24852
+ budget.setRetainedValues(retainedArgument, void 0);
24653
24853
  }
24654
- return precision;
24655
24854
  }
24656
- function toIntegerOrInfinity2(value) {
24657
- const number = Number(value);
24658
- if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
24659
- return 0;
24660
- }
24661
- if (!Number.isFinite(number)) {
24662
- return number;
24855
+ function formatNumber(value, methodName, argument, budget) {
24856
+ let result;
24857
+ try {
24858
+ result = value[methodName](argument);
24859
+ } catch (error) {
24860
+ if (!(error instanceof RangeError)) throw error;
24861
+ const detail = methodName === "toString" ? "radix must be between 2 and 36." : methodName === "toPrecision" ? "precision must be between 1 and 100." : "digits must be between 0 and 100.";
24862
+ throw new RangeError(`Number#${methodName} ${detail}`);
24663
24863
  }
24664
- return Math.trunc(number);
24864
+ return budget.allocateString(result);
24665
24865
  }
24666
24866
 
24667
24867
  // packages/safe-js/src/interp/methods/generator.ts
@@ -25184,12 +25384,8 @@ async function callSetMethod(target, methodName, args, options, stack = []) {
25184
25384
  }
25185
25385
  case "keys":
25186
25386
  case "values":
25187
- return allocateProducedSandboxValue([...target.values], options.budget);
25188
25387
  case "entries":
25189
- return allocateProducedSandboxValue(
25190
- [...target.values].map((value) => [value, value]),
25191
- options.budget
25192
- );
25388
+ return createSandboxCollectionIterator(target, methodName);
25193
25389
  }
25194
25390
  }
25195
25391
 
@@ -25364,6 +25560,7 @@ function typeTag(value) {
25364
25560
  if (isSandboxRegex(value)) return "RegExp";
25365
25561
  if (isSandboxMap(value)) return "Map";
25366
25562
  if (isSandboxSet(value)) return "Set";
25563
+ if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "Map Iterator" : "Set Iterator";
25367
25564
  if (isSandboxPromise(value)) return "Promise";
25368
25565
  if (isSandboxGenerator(value)) return "Generator";
25369
25566
  if (isFloat32Array(value)) return "Float32Array";
@@ -25452,7 +25649,7 @@ function isSandboxSetConstructor(value) {
25452
25649
  function populateCollection(source, collection, { name, budget, context, append, retainedValues }) {
25453
25650
  budget.allocateCollectionEntries(0);
25454
25651
  if (source === void 0 || source === null) return collection;
25455
- const iterator = getSandboxIterator(source);
25652
+ const iterator = getSandboxIterator(source, budget);
25456
25653
  if (iterator === void 0) throw new TypeError(`${name} constructor requires an iterable.`);
25457
25654
  let entry;
25458
25655
  let failure;
@@ -25513,6 +25710,23 @@ function populateCollection(source, collection, { name, budget, context, append,
25513
25710
  }
25514
25711
  }
25515
25712
 
25713
+ // packages/safe-js/src/interp/methods/collection-iterator.ts
25714
+ function getCollectionIteratorMember(target, property, budget) {
25715
+ if (Object.hasOwn(target, property)) return target[property];
25716
+ if (property !== "next") return void 0;
25717
+ const { collectionKind } = collectionIteratorState(target);
25718
+ return createSandboxClosure({
25719
+ sandbox: true,
25720
+ name: "next",
25721
+ call: (_args, context) => {
25722
+ const receiver = context?.thisValue;
25723
+ if (!isSandboxCollectionIterator(receiver) || collectionIteratorState(receiver).collectionKind !== collectionKind)
25724
+ throw new TypeError("Iterator next requires a matching collection iterator receiver.");
25725
+ return nextCollectionIterator(receiver, budget);
25726
+ }
25727
+ });
25728
+ }
25729
+
25516
25730
  // packages/safe-js/src/interp/globals/float32array.ts
25517
25731
  var constructors = /* @__PURE__ */ new WeakSet();
25518
25732
  function createFloat32ArrayGlobal(budget) {
@@ -26697,6 +26911,9 @@ function isRestorableBindingValue(value, seen = /* @__PURE__ */ new WeakSet()) {
26697
26911
  }
26698
26912
  if (seen.has(value)) return true;
26699
26913
  seen.add(value);
26914
+ if (isSandboxCollectionIterator(value)) {
26915
+ return isRestorableBindingValue(collectionIteratorState(value).collection, seen);
26916
+ }
26700
26917
  if (isSandboxMap(value)) {
26701
26918
  for (const [key, entry] of value.entries) {
26702
26919
  if (!isRestorableBindingValue(key, seen) || !isRestorableBindingValue(entry, seen)) {
@@ -26939,7 +27156,7 @@ async function evaluateForOfStatement(node, context) {
26939
27156
  const restored = context.scope.consumeRestoredBinding(restoredIteration.values[0]);
26940
27157
  if (restored.found && Array.isArray(restored.value)) {
26941
27158
  restoredEntry = { done: false, value: restored.value[1] };
26942
- if (isSandboxMap(restored.value[0]) || isSandboxSet(restored.value[0])) {
27159
+ if (isSandboxMap(restored.value[0]) || isSandboxSet(restored.value[0]) || isSandboxCollectionIterator(restored.value[0])) {
26943
27160
  return evaluateForOfIterator(node, restored.value[0], context, restoredEntry);
26944
27161
  }
26945
27162
  }
@@ -26987,7 +27204,7 @@ async function evaluateForOfStatement(node, context) {
26987
27204
  };
26988
27205
  }
26989
27206
  async function evaluateForOfIterator(node, value, context, restoredEntry) {
26990
- const iterator = getSandboxIterator(value);
27207
+ const iterator = getSandboxIterator(value, context.budget);
26991
27208
  if (iterator === void 0) {
26992
27209
  throw new TypeError(`${String(value)} is not a supported iterable`);
26993
27210
  }
@@ -27286,7 +27503,7 @@ function createLoopIterationContext(context, scope) {
27286
27503
  if (context.activeLoopIterations.size === 0) return snapshot;
27287
27504
  snapshot.loopIterations = {};
27288
27505
  for (const [nodeId, iteration] of context.activeLoopIterations) {
27289
- if (typeof iteration !== "number" && (isSandboxMap(iteration.values[0]) || isSandboxSet(iteration.values[0]))) {
27506
+ if (typeof iteration !== "number" && (isSandboxMap(iteration.values[0]) || isSandboxSet(iteration.values[0]) || isSandboxCollectionIterator(iteration.values[0]))) {
27290
27507
  const bindingName = `#for-of:${nodeId}`;
27291
27508
  snapshot.bindings[bindingName] = iteration.values;
27292
27509
  snapshot.loopIterations[nodeId] = { index: iteration.index, values: [bindingName] };
@@ -27413,7 +27630,7 @@ async function evaluateYieldDelegate(node, context) {
27413
27630
  if (argument.kind !== "normal") {
27414
27631
  return argument;
27415
27632
  }
27416
- const iterator = getSandboxIterator(argument.value);
27633
+ const iterator = getSandboxIterator(argument.value, context.budget);
27417
27634
  if (iterator === void 0) {
27418
27635
  throw new TypeError(`${String(argument.value)} is not a supported iterable`);
27419
27636
  }
@@ -27623,6 +27840,7 @@ function getPropertyValue(target, property, context) {
27623
27840
  if (isSandboxDate(target)) return getDateMember(property, context.budget, context.compilation?.owner);
27624
27841
  if (isSandboxMap(target)) return getMapMember(target, property, createMapMethodOptions(context));
27625
27842
  if (isSandboxSet(target)) return getSetMember(target, property, createSetMethodOptions(context));
27843
+ if (isSandboxCollectionIterator(target)) return getCollectionIteratorMember(target, property, context.budget);
27626
27844
  if (isSandboxGenerator(target)) return getGeneratorMember(target, property, context.budget);
27627
27845
  if (isSandboxClosure(target)) return getClosureMemberValue(target, property, context);
27628
27846
  if (isSandboxPromise(target)) return getPromiseMember(property, context.budget);
@@ -27635,6 +27853,7 @@ function getPropertyValue(target, property, context) {
27635
27853
  function createPatternContext(context, scope = context.scope, evaluate = evaluateNode) {
27636
27854
  const evaluationContext = { ...context, scope };
27637
27855
  return {
27856
+ budget: context.budget,
27638
27857
  evaluate: (node) => evaluate(node, evaluationContext),
27639
27858
  toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
27640
27859
  getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
@@ -28142,7 +28361,7 @@ function hasSandboxProperty(value, key, context) {
28142
28361
  while (typeof current === "object" && current !== null) {
28143
28362
  if (isGuestHostObject(current)) return hasHostObjectMember(current, key);
28144
28363
  if (hasOwnSandboxProperty(current, key, false)) return true;
28145
- if (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current)) {
28364
+ if (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current)) {
28146
28365
  return getPropertyValue(current, key, context) !== void 0;
28147
28366
  }
28148
28367
  current = getSandboxPrototype(current, context.budget);
@@ -28352,7 +28571,7 @@ function getMemberValue(target, property, context) {
28352
28571
  while (typeof current === "object" && current !== null) {
28353
28572
  if (isSandboxClosure(current)) return getClosureMemberValue(current, property, context);
28354
28573
  if (Array.isArray(current)) return getArrayMemberValue(current, property, context);
28355
- if (!isPlainSandboxObject(current) || isSandboxGenerator(current) || isFloat32Array(current)) {
28574
+ if (!isPlainSandboxObject(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current) || isFloat32Array(current)) {
28356
28575
  return getPropertyValue(current, property, context);
28357
28576
  }
28358
28577
  if (Object.hasOwn(current, String(property))) return current[String(property)];
@@ -28467,7 +28686,7 @@ async function evaluateNumberMethodCall(node, target, methodName, context) {
28467
28686
  return {
28468
28687
  kind: "normal",
28469
28688
  hasValue: true,
28470
- value: callNumberMethod(target, methodName, args.value, context.budget)
28689
+ value: await callNumberMethod(target, methodName, args.value, context.budget, createCoercionContext(context))
28471
28690
  };
28472
28691
  } catch (error) {
28473
28692
  if (isFatalSandboxError(error)) {
@@ -28479,6 +28698,10 @@ async function evaluateNumberMethodCall(node, target, methodName, context) {
28479
28698
  function createArrayMethodOptions(context) {
28480
28699
  return {
28481
28700
  budget: context.budget,
28701
+ context: createCoercionContext(context),
28702
+ hasProperty: (value, property) => hasSandboxProperty(value, property, context),
28703
+ setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
28704
+ deleteProperty: deleteSandboxProperty,
28482
28705
  callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, void 0, thisValue)
28483
28706
  };
28484
28707
  }
@@ -28567,7 +28790,7 @@ async function evaluateSpreadElement(node, context) {
28567
28790
  result: value
28568
28791
  };
28569
28792
  }
28570
- const iterator = getSpreadIterator(value.value);
28793
+ const iterator = getSandboxIterator(value.value, context.budget);
28571
28794
  if (iterator === void 0) {
28572
28795
  throw new TypeError("Spread arguments must evaluate to an iterable.");
28573
28796
  }
@@ -28637,9 +28860,6 @@ function describeObjectSpreadValue(value) {
28637
28860
  }
28638
28861
  return typeof value;
28639
28862
  }
28640
- function getSpreadIterator(value) {
28641
- return getSandboxIterator(value);
28642
- }
28643
28863
  async function closeIterator(iterator) {
28644
28864
  if (iterator.generator && iterator.return !== void 0) {
28645
28865
  await iterator.return();
@@ -30424,8 +30644,8 @@ function structuredCloneSandboxValue(value, budget) {
30424
30644
  return allocateProducedSandboxValue(clone, budget);
30425
30645
  }
30426
30646
  function assertStructuredCloneable(value, seen) {
30427
- if (isSandboxClosure(value) || isSandboxPromise(value)) {
30428
- throw new TypeError("structuredClone() cannot clone closures or promises.");
30647
+ if (isSandboxClosure(value) || isSandboxPromise(value) || isSandboxCollectionIterator(value)) {
30648
+ throw new TypeError("structuredClone() cannot clone closures, promises, or collection iterators.");
30429
30649
  }
30430
30650
  if (typeof value !== "object" || value === null || seen.has(value)) {
30431
30651
  return;
@@ -30553,7 +30773,7 @@ function createObjectArrayGlobals(options) {
30553
30773
  fromEntries: createSandboxClosure({
30554
30774
  sandbox: true,
30555
30775
  call: ([value], context) => {
30556
- const iterator = getSandboxIterator(value);
30776
+ const iterator = getSandboxIterator(value, options.budget);
30557
30777
  if (iterator === void 0) {
30558
30778
  throw new TypeError("Object.fromEntries requires an iterable.");
30559
30779
  }
@@ -30816,7 +31036,7 @@ async function arrayFromSandboxValues(args, budget, context) {
30816
31036
  throw new TypeError("Array.from requires a non-null input.");
30817
31037
  }
30818
31038
  const read = (property) => context?.getProperty !== void 0 ? context.getProperty(items, property) : getSandboxDataProperty(items, property, budget);
30819
- const iterator = getSandboxIterator(items);
31039
+ const iterator = getSandboxIterator(items, budget);
30820
31040
  const constructor = context?.thisValue;
30821
31041
  let result;
30822
31042
  let currentValue;
@@ -32396,6 +32616,16 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
32396
32616
  throw new TypeError("Invalid replay input capability path.");
32397
32617
  let value = current;
32398
32618
  for (const key of path) {
32619
+ if (isSandboxCollectionIterator(value)) {
32620
+ if (key === "<collection>") value = collectionIteratorState(value).collection;
32621
+ else {
32622
+ const property = JSON.parse(key);
32623
+ if (!Array.isArray(property) || property.length !== 2 || property[0] !== "property" || typeof property[1] !== "string") throw new TypeError("Invalid replay input iterator capability path.");
32624
+ const descriptor2 = Object.getOwnPropertyDescriptor(value, property[1]);
32625
+ value = descriptor2 !== void 0 && "value" in descriptor2 ? descriptor2.value : void 0;
32626
+ }
32627
+ continue;
32628
+ }
32399
32629
  if (isSandboxMap(value)) {
32400
32630
  const [kind, ordinal] = key.split(":");
32401
32631
  const index = Number(ordinal);
@@ -32456,11 +32686,11 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
32456
32686
  return { values: restored, snapshot: structuredClone(saved) };
32457
32687
  }
32458
32688
  function assertReplayInputShape(restored) {
32459
- if (restored === null || typeof restored !== "object" || Array.isArray(restored) || isSandboxClosure(restored) || isSandboxPromise(restored) || isSandboxMap(restored) || isSandboxSet(restored))
32689
+ if (restored === null || typeof restored !== "object" || Array.isArray(restored) || isSandboxClosure(restored) || isSandboxPromise(restored) || isSandboxCollectionIterator(restored) || isSandboxMap(restored) || isSandboxSet(restored))
32460
32690
  throw new TypeError("Invalid replay inputs.");
32461
32691
  const values = restored;
32462
32692
  for (const key of ["bindings", "imports"]) {
32463
- if (values[key] === null || typeof values[key] !== "object" || Array.isArray(values[key]) || isSandboxClosure(values[key]) || isSandboxPromise(values[key]) || isSandboxMap(values[key]) || isSandboxSet(values[key]))
32693
+ if (values[key] === null || typeof values[key] !== "object" || Array.isArray(values[key]) || isSandboxClosure(values[key]) || isSandboxPromise(values[key]) || isSandboxCollectionIterator(values[key]) || isSandboxMap(values[key]) || isSandboxSet(values[key]))
32464
32694
  throw new TypeError(`Invalid replay input ${key}.`);
32465
32695
  }
32466
32696
  if (values.entryPointArgs !== void 0 && !Array.isArray(values.entryPointArgs))
@@ -33053,4 +33283,4 @@ export {
33053
33283
  FileSnapshotBackend,
33054
33284
  run
33055
33285
  };
33056
- //# sourceMappingURL=chunk-7AIY5C3F.js.map
33286
+ //# sourceMappingURL=chunk-VDFW3EKS.js.map