poe-code 14.0.61 → 14.0.63

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 (67) hide show
  1. package/dist/index.js +1147 -574
  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-js/dist/chunks/{chunk-VAYQP2VZ.js → chunk-KMTTD3BL.js} +7 -3
  6. package/packages/safe-js/dist/chunks/chunk-KMTTD3BL.js.map +7 -0
  7. package/packages/safe-js/dist/chunks/{chunk-ZTGKRKQH.js → chunk-RU2BCN4G.js} +1069 -577
  8. package/packages/safe-js/dist/chunks/chunk-RU2BCN4G.js.map +7 -0
  9. package/packages/safe-js/dist/cli.js +2 -2
  10. package/packages/safe-js/dist/core.js +1 -1
  11. package/packages/safe-js/dist/graph-depth.js +3 -0
  12. package/packages/safe-js/dist/index.js +2 -2
  13. package/packages/safe-js/dist/interp/async.js +3 -0
  14. package/packages/safe-js/dist/interp/boxed.d.ts +14 -0
  15. package/packages/safe-js/dist/interp/boxed.js +50 -0
  16. package/packages/safe-js/dist/interp/function-string.d.ts +2 -0
  17. package/packages/safe-js/dist/interp/function-string.js +21 -0
  18. package/packages/safe-js/dist/interp/globals/collections.js +4 -4
  19. package/packages/safe-js/dist/interp/globals/console-json.js +15 -18
  20. package/packages/safe-js/dist/interp/globals/misc.js +12 -13
  21. package/packages/safe-js/dist/interp/globals/numeric-parsers.d.ts +5 -0
  22. package/packages/safe-js/dist/interp/globals/numeric-parsers.js +47 -0
  23. package/packages/safe-js/dist/interp/globals/object-array.js +21 -24
  24. package/packages/safe-js/dist/interp/globals/object.js +10 -5
  25. package/packages/safe-js/dist/interp/globals/primitives.d.ts +8 -0
  26. package/packages/safe-js/dist/interp/globals/primitives.js +69 -0
  27. package/packages/safe-js/dist/interp/host-bridge.js +22 -0
  28. package/packages/safe-js/dist/interp/interpreter.js +173 -120
  29. package/packages/safe-js/dist/interp/iteration.d.ts +5 -3
  30. package/packages/safe-js/dist/interp/iteration.js +22 -1
  31. package/packages/safe-js/dist/interp/methods/array.js +6 -3
  32. package/packages/safe-js/dist/interp/methods/function.d.ts +2 -0
  33. package/packages/safe-js/dist/interp/methods/function.js +10 -1
  34. package/packages/safe-js/dist/interp/methods/number.d.ts +1 -0
  35. package/packages/safe-js/dist/interp/methods/number.js +4 -1
  36. package/packages/safe-js/dist/interp/methods/string.d.ts +2 -0
  37. package/packages/safe-js/dist/interp/methods/string.js +2 -2
  38. package/packages/safe-js/dist/interp/object-model.d.ts +5 -0
  39. package/packages/safe-js/dist/interp/object-model.js +41 -3
  40. package/packages/safe-js/dist/interp/promise.js +68 -61
  41. package/packages/safe-js/dist/interp/resources.d.ts +1 -0
  42. package/packages/safe-js/dist/interp/string-coercion.js +7 -1
  43. package/packages/safe-js/dist/interp/values.d.ts +4 -0
  44. package/packages/safe-js/dist/interp/values.js +81 -3
  45. package/packages/safe-js/dist/migrate.d.ts +2 -2
  46. package/packages/safe-js/dist/migrate.js +1 -1
  47. package/packages/safe-js/dist/migration-file.d.ts +4 -4
  48. package/packages/safe-js/dist/parse/function-source.d.ts +7 -0
  49. package/packages/safe-js/dist/parse/function-source.js +1 -0
  50. package/packages/safe-js/dist/parse/hash.d.ts +2 -2
  51. package/packages/safe-js/dist/parse/hash.js +23 -9
  52. package/packages/safe-js/dist/parse/parser.js +36 -23
  53. package/packages/safe-js/dist/restore.js +2 -1
  54. package/packages/safe-js/dist/run.js +16 -5
  55. package/packages/safe-js/dist/snapshot/boxed.d.ts +16 -0
  56. package/packages/safe-js/dist/snapshot/boxed.js +52 -0
  57. package/packages/safe-js/dist/snapshot/dump-format.d.ts +1 -1
  58. package/packages/safe-js/dist/snapshot/dump-format.js +19 -6
  59. package/packages/safe-js/dist/snapshot/migration.js +2 -2
  60. package/packages/safe-js/dist/snapshot/replay-data.d.ts +5 -0
  61. package/packages/safe-js/dist/snapshot/replay-data.js +24 -0
  62. package/packages/safe-js/dist/snapshot/restore.js +10 -0
  63. package/packages/safe-js/dist/snapshot/serialize.d.ts +4 -2
  64. package/packages/safe-js/dist/snapshot/serialize.js +18 -10
  65. package/packages/safe-js/dist/snapshot/validation.js +22 -1
  66. package/packages/safe-js/dist/chunks/chunk-VAYQP2VZ.js.map +0 -7
  67. package/packages/safe-js/dist/chunks/chunk-ZTGKRKQH.js.map +0 -7
@@ -1811,6 +1811,9 @@ function isAstNode(value) {
1811
1811
  return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string" && "span" in value && typeof value.span?.start.offset === "number" && typeof value.span?.end.offset === "number";
1812
1812
  }
1813
1813
 
1814
+ // packages/safe-js/src/parse/function-source.ts
1815
+ var functionSources = /* @__PURE__ */ new WeakMap();
1816
+
1814
1817
  // packages/safe-js/src/parse/format-error.ts
1815
1818
  var ParseError = class extends Error {
1816
1819
  constructor(filename, message, line, column, excerpt, caret, span) {
@@ -2459,7 +2462,11 @@ function parse(source, filename = "<input>", owner) {
2459
2462
  const compilation = new CompileScope(owner);
2460
2463
  try {
2461
2464
  const result = assignIds(
2462
- parseTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation)
2465
+ new Parser(
2466
+ tokenize(source, { allowRegexLiterals: true, compilation }),
2467
+ source,
2468
+ compilation
2469
+ ).parseTopLevel()
2463
2470
  );
2464
2471
  const regexLiteral = findRegexLiteral(result);
2465
2472
  if (regexLiteral !== void 0) {
@@ -2485,7 +2492,11 @@ function parseModule(source, filename = "<input>", owner) {
2485
2492
  const compilation = new CompileScope(owner);
2486
2493
  try {
2487
2494
  return assignIds(
2488
- parseModuleTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation)
2495
+ new Parser(
2496
+ tokenize(source, { allowRegexLiterals: true, compilation }),
2497
+ source,
2498
+ compilation
2499
+ ).parseModule()
2489
2500
  );
2490
2501
  } catch (error) {
2491
2502
  if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
@@ -2503,7 +2514,11 @@ function parseExecutableModule(source, filename = "<input>", owner) {
2503
2514
  const compilation = new CompileScope(owner);
2504
2515
  try {
2505
2516
  const result = assignIds(
2506
- parseModuleTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation)
2517
+ new Parser(
2518
+ tokenize(source, { allowRegexLiterals: true, compilation }),
2519
+ source,
2520
+ compilation
2521
+ ).parseModule()
2507
2522
  );
2508
2523
  throwIfImportMetaAssignment(result);
2509
2524
  return result;
@@ -2519,20 +2534,16 @@ function parseExecutableModule(source, filename = "<input>", owner) {
2519
2534
  compilation.dispose();
2520
2535
  }
2521
2536
  }
2522
- function parseTokens(tokens, compilation) {
2523
- return new Parser(tokens, compilation).parseTopLevel();
2524
- }
2525
- function parseModuleTokens(tokens, compilation) {
2526
- return new Parser(tokens, compilation).parseModule();
2527
- }
2528
2537
  var Parser = class {
2529
- constructor(tokens, compilation, functionContext = "normal") {
2538
+ constructor(tokens, source, compilation, functionContext = "normal") {
2530
2539
  this.tokens = tokens;
2540
+ this.source = source;
2531
2541
  this.compilation = compilation;
2532
2542
  this.functionContext = functionContext;
2533
2543
  this.functionScopes.add(this.scopes[0]);
2534
2544
  }
2535
2545
  tokens;
2546
+ source;
2536
2547
  compilation;
2537
2548
  functionContext;
2538
2549
  index = 0;
@@ -2543,6 +2554,14 @@ var Parser = class {
2543
2554
  scopes = [/* @__PURE__ */ new Map()];
2544
2555
  functionScopes = /* @__PURE__ */ new WeakSet();
2545
2556
  varNames = /* @__PURE__ */ new WeakMap();
2557
+ withFunctionSource(node) {
2558
+ functionSources.set(node, {
2559
+ text: this.source,
2560
+ start: node.span.start.offset,
2561
+ end: node.span.end.offset
2562
+ });
2563
+ return node;
2564
+ }
2546
2565
  parseTopLevel() {
2547
2566
  if (this.isExportToken(this.currentToken())) {
2548
2567
  throw new DisallowedSyntaxError("export", this.currentToken().start);
@@ -2684,14 +2703,14 @@ var Parser = class {
2684
2703
  });
2685
2704
  this.expectPunctuator("=>");
2686
2705
  const body = this.parseArrowFunctionBody(params);
2687
- return {
2706
+ return this.withFunctionSource({
2688
2707
  type: "ArrowFunctionExpression",
2689
2708
  async: isAsync,
2690
2709
  body,
2691
2710
  expression: body.type !== "BlockStatement",
2692
2711
  params,
2693
2712
  span: createSpan2(start, body.span.end)
2694
- };
2713
+ });
2695
2714
  }
2696
2715
  parseConditionalExpression() {
2697
2716
  if (this.conditionalExpressionDepth >= MAX_CONDITIONAL_EXPRESSION_DEPTH) {
@@ -3331,8 +3350,11 @@ var Parser = class {
3331
3350
  return parsedParams;
3332
3351
  });
3333
3352
  const generator = generatorToken !== void 0;
3334
- const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
3335
- return {
3353
+ const body = this.withFunctionContext(
3354
+ generator ? "generator" : "normal",
3355
+ () => this.parseBlockStatement(params)
3356
+ );
3357
+ return this.withFunctionSource({
3336
3358
  type: "FunctionDeclaration",
3337
3359
  async: asyncToken !== void 0,
3338
3360
  body,
@@ -3340,7 +3362,7 @@ var Parser = class {
3340
3362
  id,
3341
3363
  params,
3342
3364
  span: createSpan2(asyncToken?.start ?? functionToken.start, body.span.end)
3343
- };
3365
+ });
3344
3366
  }
3345
3367
  parseVariableDeclarator(kind) {
3346
3368
  const id = this.parseBindingTarget();
@@ -4108,7 +4130,11 @@ var Parser = class {
4108
4130
  if (this.currentToken().type === "template") {
4109
4131
  const quasi = createTemplateLiteral(
4110
4132
  this.currentToken(),
4111
- { allowMalformedEscapes: true, functionContext: this.functionContext },
4133
+ {
4134
+ allowMalformedEscapes: true,
4135
+ functionContext: this.functionContext,
4136
+ source: this.source
4137
+ },
4112
4138
  this.compilation
4113
4139
  );
4114
4140
  this.index += 1;
@@ -4197,7 +4223,11 @@ var Parser = class {
4197
4223
  return {
4198
4224
  node: createTemplateLiteral(
4199
4225
  token,
4200
- { allowMalformedEscapes: false, functionContext: this.functionContext },
4226
+ {
4227
+ allowMalformedEscapes: false,
4228
+ functionContext: this.functionContext,
4229
+ source: this.source
4230
+ },
4201
4231
  this.compilation
4202
4232
  ),
4203
4233
  parenthesized: false
@@ -4282,7 +4312,8 @@ var Parser = class {
4282
4312
  break;
4283
4313
  }
4284
4314
  const optional = this.consumePunctuator("?.");
4285
- if (optional !== void 0) throw new DisallowedSyntaxError("new optional chain", optional.start);
4315
+ if (optional !== void 0)
4316
+ throw new DisallowedSyntaxError("new optional chain", optional.start);
4286
4317
  const args = this.consumePunctuator("(") === void 0 ? [] : this.parseArguments();
4287
4318
  const end = this.previousToken();
4288
4319
  return {
@@ -4315,8 +4346,11 @@ var Parser = class {
4315
4346
  return parsedParams;
4316
4347
  });
4317
4348
  const generator = generatorToken !== void 0;
4318
- const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
4319
- return {
4349
+ const body = this.withFunctionContext(
4350
+ generator ? "generator" : "normal",
4351
+ () => this.parseBlockStatement(params)
4352
+ );
4353
+ return this.withFunctionSource({
4320
4354
  type: "FunctionExpression",
4321
4355
  async: asyncToken !== void 0,
4322
4356
  body,
@@ -4324,7 +4358,7 @@ var Parser = class {
4324
4358
  id,
4325
4359
  params,
4326
4360
  span: createSpan2(asyncToken?.start ?? functionToken.start, body.span.end)
4327
- };
4361
+ });
4328
4362
  }
4329
4363
  parseArrayExpression() {
4330
4364
  const start = this.expectPunctuator("[");
@@ -4560,7 +4594,7 @@ var Parser = class {
4560
4594
  return parsedParams;
4561
4595
  });
4562
4596
  const body = this.withFunctionContext("normal", () => this.parseBlockStatement(params));
4563
- return {
4597
+ return this.withFunctionSource({
4564
4598
  type: "FunctionExpression",
4565
4599
  async: asyncToken !== void 0,
4566
4600
  body,
@@ -4569,7 +4603,7 @@ var Parser = class {
4569
4603
  method: true,
4570
4604
  params,
4571
4605
  span: createSpan2(asyncToken?.start ?? methodStart, body.span.end)
4572
- };
4606
+ });
4573
4607
  }
4574
4608
  parseIdentifierName() {
4575
4609
  const token = this.currentToken();
@@ -5432,6 +5466,7 @@ function createTemplateLiteral(token, options, compilation) {
5432
5466
  raw.slice(expressionStart, expressionEnd),
5433
5467
  positionWithinRaw(token.start, raw, expressionStart),
5434
5468
  options.functionContext,
5469
+ options.source,
5435
5470
  compilation
5436
5471
  )
5437
5472
  );
@@ -5794,13 +5829,13 @@ function decodeHexEscape(value, start) {
5794
5829
  end: index + 2
5795
5830
  };
5796
5831
  }
5797
- function parseEmbeddedExpression(source, base, functionContext, compilation) {
5832
+ function parseEmbeddedExpression(source, base, functionContext, fullSource, compilation) {
5798
5833
  const tokens = tokenize(source, { allowRegexLiterals: true, compilation }).map((token) => ({
5799
5834
  ...token,
5800
5835
  start: rebasePosition(token.start, base),
5801
5836
  end: rebasePosition(token.end, base)
5802
5837
  }));
5803
- return new Parser(tokens, compilation, functionContext).parseExpressionOnly();
5838
+ return new Parser(tokens, fullSource, compilation, functionContext).parseExpressionOnly();
5804
5839
  }
5805
5840
  function findRegexLiteral(node) {
5806
5841
  if (node === null || node === void 0) {
@@ -6413,8 +6448,50 @@ function nativeIterator(collection, method) {
6413
6448
  return collection.kind === "map" ? collection.entries[method]() : collection.values[method]();
6414
6449
  }
6415
6450
 
6416
- // packages/safe-js/src/interp/host-capabilities.ts
6451
+ // packages/safe-js/src/interp/boxed.ts
6417
6452
  import { types as types3 } from "node:util";
6453
+ var boxes = /* @__PURE__ */ new WeakSet();
6454
+ var numberValue = Number.prototype.valueOf;
6455
+ var stringValue = String.prototype.valueOf;
6456
+ var booleanValue = Boolean.prototype.valueOf;
6457
+ function nativeBoxedValue(value) {
6458
+ if (types3.isNumberObject(value)) return Reflect.apply(numberValue, value, []);
6459
+ if (types3.isStringObject(value)) return Reflect.apply(stringValue, value, []);
6460
+ if (types3.isBooleanObject(value)) return Reflect.apply(booleanValue, value, []);
6461
+ return void 0;
6462
+ }
6463
+ function createSandboxBox(value) {
6464
+ if (typeof value !== "number" && typeof value !== "string" && typeof value !== "boolean")
6465
+ throw new TypeError("Invalid boxed primitive payload.");
6466
+ const box = Object(value);
6467
+ Object.setPrototypeOf(box, null);
6468
+ boxes.add(box);
6469
+ return box;
6470
+ }
6471
+ function isSandboxBox(value) {
6472
+ return typeof value === "object" && value !== null && boxes.has(value);
6473
+ }
6474
+ function boxedValue(value) {
6475
+ if (!boxes.has(value)) throw new TypeError("Expected a sandbox boxed primitive.");
6476
+ return nativeBoxedValue(value);
6477
+ }
6478
+ function primitiveReceiver(value, kind) {
6479
+ const primitive = isSandboxBox(value) ? boxedValue(value) : value;
6480
+ if (typeof primitive !== kind) throw new TypeError(`${kind} method requires a ${kind} receiver.`);
6481
+ return primitive;
6482
+ }
6483
+ function boxedDataProperties(value) {
6484
+ const primitive = nativeBoxedValue(value);
6485
+ return Object.entries(Object.getOwnPropertyDescriptors(value)).filter(([key]) => {
6486
+ if (typeof primitive !== "string") return true;
6487
+ if (key === "length") return false;
6488
+ const index = Number(key);
6489
+ return !(Number.isInteger(index) && index >= 0 && index < primitive.length && String(index) === key);
6490
+ });
6491
+ }
6492
+
6493
+ // packages/safe-js/src/interp/host-capabilities.ts
6494
+ import { types as types4 } from "node:util";
6418
6495
  var MAX_INDEXED_LENGTH = 65536;
6419
6496
  var MAX_NAMED_KEYS = 65536;
6420
6497
  var MAX_NAMED_KEY_CODE_UNITS = 1048576;
@@ -6469,7 +6546,7 @@ function createLiveHostObject(definition, controller) {
6469
6546
  for (const name of ["keys", "get", "set", "delete"]) {
6470
6547
  const operation = data[name];
6471
6548
  if (operation === void 0 && (name === "set" || name === "delete")) continue;
6472
- if (typeof operation !== "function" || types3.isProxy(operation) || types3.isAsyncFunction(operation) || types3.isGeneratorFunction(operation))
6549
+ if (typeof operation !== "function" || types4.isProxy(operation) || types4.isAsyncFunction(operation) || types4.isGeneratorFunction(operation))
6473
6550
  throw new TypeError(`Named ${name} must be a synchronous non-generator function, not a proxy.`);
6474
6551
  }
6475
6552
  if (typeof data.maxKeys !== "number" || !Number.isInteger(data.maxKeys) || data.maxKeys < 1 || data.maxKeys > MAX_NAMED_KEYS)
@@ -6724,7 +6801,7 @@ function namedMutationKeys(state, key, create) {
6724
6801
  function namedKeys(state) {
6725
6802
  const named = state.named;
6726
6803
  return state.controller.read(named.keys, (value) => {
6727
- if (!Array.isArray(value) || types3.isProxy(value))
6804
+ if (!Array.isArray(value) || types4.isProxy(value))
6728
6805
  throw new TypeError("Named keys must be a dense own-data array of strings, not a proxy.");
6729
6806
  const length = Object.getOwnPropertyDescriptor(value, "length").value;
6730
6807
  if (length > named.maxKeys) throw new RangeError("Named keys exceed maxKeys.");
@@ -6877,7 +6954,7 @@ async function flushPromiseJobs() {
6877
6954
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
6878
6955
 
6879
6956
  // packages/safe-js/src/snapshot/validation.ts
6880
- import { types as types4 } from "node:util";
6957
+ import { types as types5 } from "node:util";
6881
6958
 
6882
6959
  // packages/safe-js/src/interp/arguments.ts
6883
6960
  var sandboxArgumentsBrand = /* @__PURE__ */ Symbol("SandboxArguments");
@@ -6982,6 +7059,7 @@ function walkGraphDepth(root, rootPath, assertDepth) {
6982
7059
  }
6983
7060
  }
6984
7061
  function graphEntries(value) {
7062
+ if (isSandboxBox(value)) return boxedDataProperties(value).map(([key, descriptor]) => [`.${key}`, descriptor.value]);
6985
7063
  if (isSandboxArguments(value)) {
6986
7064
  return getSandboxArgumentEntries(value).map(([key, entry]) => [`.${key}`, entry]);
6987
7065
  }
@@ -7011,7 +7089,10 @@ var guestClosures = /* @__PURE__ */ new WeakSet();
7011
7089
  var functionProperties = /* @__PURE__ */ new WeakMap();
7012
7090
  var prototypes = /* @__PURE__ */ new WeakMap();
7013
7091
  var intrinsicPrototypes = /* @__PURE__ */ new WeakMap();
7092
+ var boxedPrototypes = /* @__PURE__ */ new WeakMap();
7093
+ var intrinsicPrototypeRoots = /* @__PURE__ */ new WeakMap();
7014
7094
  var intrinsicConstructors = /* @__PURE__ */ new WeakMap();
7095
+ var initialBoxedMethods = /* @__PURE__ */ new WeakMap();
7015
7096
  var descriptorObjects = /* @__PURE__ */ new WeakSet();
7016
7097
  function registerGuestClosure(closure) {
7017
7098
  guestClosures.add(closure);
@@ -7059,11 +7140,34 @@ function getGuestFunctionProperty(closure, key) {
7059
7140
  function installObjectPrototype(budget, prototype, constructor) {
7060
7141
  prototypes.set(prototype, null);
7061
7142
  intrinsicPrototypes.set(budget, prototype);
7143
+ registerIntrinsicPrototype(budget, prototype, constructor);
7144
+ }
7145
+ function installBoxedPrototype(budget, prototype, constructor) {
7146
+ let state = boxedPrototypes.get(budget);
7147
+ if (state === void 0) boxedPrototypes.set(budget, state = /* @__PURE__ */ new Map());
7148
+ state.set(typeof boxedValue(prototype), prototype);
7149
+ initialBoxedMethods.set(prototype, new Map(Object.entries(Object.getOwnPropertyDescriptors(prototype)).map(([key, descriptor]) => [key, descriptor.value])));
7150
+ registerIntrinsicPrototype(budget, prototype, constructor);
7151
+ }
7152
+ function getBoxedPrototype(value, budget) {
7153
+ return boxedPrototypes.get(budget)?.get(typeof value);
7154
+ }
7155
+ function isDefaultBoxedMethod(value, key, budget) {
7156
+ const prototype = getBoxedPrototype(value, budget);
7157
+ return prototype !== void 0 && initialBoxedMethods.get(prototype)?.has(key) === true && Object.getOwnPropertyDescriptor(prototype, key)?.value === initialBoxedMethods.get(prototype)?.get(key);
7158
+ }
7159
+ function isIntrinsicConstructor(value) {
7160
+ return intrinsicConstructors.has(value);
7161
+ }
7162
+ function registerIntrinsicPrototype(budget, prototype, constructor) {
7163
+ let roots = intrinsicPrototypeRoots.get(budget);
7164
+ if (roots === void 0) intrinsicPrototypeRoots.set(budget, roots = /* @__PURE__ */ new Set());
7165
+ roots.add(prototype);
7062
7166
  const records = [prototype, materializeFunctionProperties(constructor)].map((value) => ({
7063
7167
  value,
7064
7168
  descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(value)))
7065
7169
  }));
7066
- const unchanged = (before, after) => before !== void 0 && after !== void 0 && before.value === after.value && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
7170
+ const unchanged = (before, after) => before !== void 0 && after !== void 0 && Object.is(before.value, after.value) && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
7067
7171
  intrinsicConstructors.set(constructor, () => records.every(({ value, descriptors }) => {
7068
7172
  const current = Object.getOwnPropertyDescriptors(value);
7069
7173
  return Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
@@ -7071,12 +7175,17 @@ function installObjectPrototype(budget, prototype, constructor) {
7071
7175
  budget.setRetainedValues(prototype, () => records.flatMap(({ value, descriptors }) => Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key, descriptor]) => unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value])));
7072
7176
  }
7073
7177
  function releaseObjectPrototype(budget) {
7074
- const prototype = intrinsicPrototypes.get(budget);
7075
- if (prototype !== void 0) budget.setRetainedValues(prototype, void 0);
7178
+ for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
7179
+ intrinsicPrototypeRoots.delete(budget);
7180
+ boxedPrototypes.delete(budget);
7076
7181
  intrinsicPrototypes.delete(budget);
7077
7182
  }
7078
7183
  function getSandboxPrototype(value, budget) {
7079
7184
  if (prototypes.has(value)) return prototypes.get(value) ?? null;
7185
+ if (budget !== void 0 && isSandboxBox(value)) {
7186
+ const prototype = getBoxedPrototype(boxedValue(value), budget);
7187
+ if (prototype !== void 0 && prototype !== value) return prototype;
7188
+ }
7080
7189
  return budget !== void 0 && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
7081
7190
  }
7082
7191
  function hasExplicitSandboxPrototype(value) {
@@ -7142,6 +7251,7 @@ function hasGuestObjectState(value) {
7142
7251
  if (intrinsicUnchanged !== void 0) return !intrinsicUnchanged();
7143
7252
  if (isLiveCapability(value)) return true;
7144
7253
  if (functionProperties.has(value) || prototypes.has(value)) return true;
7254
+ if (isSandboxBox(value)) return false;
7145
7255
  return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
7146
7256
  (descriptor) => !descriptor.enumerable || !descriptor.configurable || !descriptor.writable
7147
7257
  );
@@ -7245,9 +7355,37 @@ function decodeFloat32Storage(value, resolve) {
7245
7355
  return new Float32Array(buffer, Number(value.byteOffset), Number(value.length));
7246
7356
  }
7247
7357
 
7358
+ // packages/safe-js/src/snapshot/boxed.ts
7359
+ function encodeBoxedData(value, encode) {
7360
+ const properties = /* @__PURE__ */ Object.create(null);
7361
+ for (const [key, descriptor] of boxedDataProperties(value)) {
7362
+ if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
7363
+ properties[key] = {
7364
+ value: encode(descriptor.value, key),
7365
+ configurable: descriptor.configurable === true,
7366
+ enumerable: descriptor.enumerable === true,
7367
+ writable: descriptor.writable === true
7368
+ };
7369
+ }
7370
+ return {
7371
+ kind: "boxed",
7372
+ value: encode(boxedValue(value), "<payload>"),
7373
+ properties,
7374
+ extensible: Object.isExtensible(value)
7375
+ };
7376
+ }
7377
+ function validateBoxedProperties(data) {
7378
+ if (!Object.hasOwn(data, "kind") || data.kind !== "boxed" || !Object.hasOwn(data, "value") || !Object.hasOwn(data, "extensible") || !Object.hasOwn(data, "properties") || Object.keys(data).length !== 4 || typeof data.extensible !== "boolean" || typeof data.properties !== "object" || data.properties === null || Array.isArray(data.properties))
7379
+ throw new TypeError("Invalid boxed primitive properties.");
7380
+ for (const descriptor of Object.values(data.properties)) {
7381
+ if (typeof descriptor !== "object" || descriptor === null || !Object.hasOwn(descriptor, "value") || !Object.hasOwn(descriptor, "writable") || !Object.hasOwn(descriptor, "enumerable") || !Object.hasOwn(descriptor, "configurable") || typeof descriptor.writable !== "boolean" || typeof descriptor.enumerable !== "boolean" || typeof descriptor.configurable !== "boolean" || Object.keys(descriptor).length !== 4)
7382
+ throw new TypeError("Invalid boxed primitive descriptor.");
7383
+ }
7384
+ }
7385
+
7248
7386
  // packages/safe-js/src/snapshot/dump-format.ts
7249
7387
  var DUMP_FORMAT_VERSION = 1;
7250
- var EXECUTION_SEMANTICS = "jobs-v7";
7388
+ var EXECUTION_SEMANTICS = "jobs-v8";
7251
7389
  var SKIP_VALUE = /* @__PURE__ */ Symbol("SafeJS.skip-dump-value");
7252
7390
  function serializeSafeJSSnapshot(snapshot) {
7253
7391
  const replayError = Object.getOwnPropertyDescriptor(snapshot, "replayError");
@@ -7306,7 +7444,7 @@ function serializeDumpValue(value, path, state) {
7306
7444
  if (hasGuestObjectState(value)) {
7307
7445
  throw new TypeError("Guest function properties and prototype links cannot be serialized.");
7308
7446
  }
7309
- if (isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path, state);
7447
+ if (isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path, state);
7310
7448
  if (Array.isArray(value)) {
7311
7449
  const reference2 = serializeHeapReference(value, path, state);
7312
7450
  if (reference2 !== void 0) {
@@ -7330,7 +7468,13 @@ function serializeHeapReference(value, path, state) {
7330
7468
  }
7331
7469
  if (!state.serializedHeapIds.has(id)) {
7332
7470
  state.serializedHeapIds.add(id);
7333
- if (isSandboxDate(value)) {
7471
+ if (isSandboxBox(value)) {
7472
+ state.heap[String(id)] = encodeBoxedData(value, (entry, key) => {
7473
+ if (Object.is(entry, -0)) return { kind: "number", value: "-0" };
7474
+ const serialized = serializeDumpValue(entry, `${path}.${key}`, state);
7475
+ return serialized === SKIP_VALUE ? { kind: "undefined" } : serialized;
7476
+ });
7477
+ } else if (isSandboxDate(value)) {
7334
7478
  state.heap[String(id)] = { kind: "date", time: serializedDateTime(value) };
7335
7479
  } else if (isFloat32Array(value)) {
7336
7480
  const storage = encodeFloat32Storage(value, id, state.float32Buffers, (id2) => ({
@@ -7389,7 +7533,7 @@ function indexHeapContainers(snapshot) {
7389
7533
  const heapIds = /* @__PURE__ */ new WeakMap();
7390
7534
  let nextId = 1;
7391
7535
  for (const [value, stat2] of stats.entries()) {
7392
- if (stat2.count > 1 || stat2.cyclic || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
7536
+ if (stat2.count > 1 || stat2.cyclic || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
7393
7537
  heapIds.set(value, nextId);
7394
7538
  nextId += 1;
7395
7539
  }
@@ -7422,7 +7566,7 @@ function collectContainerStats(value, stats, ancestors) {
7422
7566
  }
7423
7567
  stat2.expanded = true;
7424
7568
  ancestors.add(value);
7425
- const entries = isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
7569
+ const entries = isSandboxBox(value) ? boxedDataProperties(value).map(([, descriptor]) => descriptor.value) : isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
7426
7570
  for (const entry of entries) {
7427
7571
  collectContainerStats(entry, stats, ancestors);
7428
7572
  }
@@ -7536,6 +7680,10 @@ function validateDumpHeap(root, state) {
7536
7680
  addUnique(heapIds, id, path);
7537
7681
  const entry = requireRecord(value, path);
7538
7682
  validateErrorType(entry, path);
7683
+ if (entry.kind === "boxed") {
7684
+ validateBoxedRecord(entry, path);
7685
+ continue;
7686
+ }
7539
7687
  if (entry.kind === "date") {
7540
7688
  validateDateRecord(entry, path);
7541
7689
  continue;
@@ -7703,6 +7851,18 @@ function validateGeneratorShape(record2, path, state) {
7703
7851
  }
7704
7852
  });
7705
7853
  }
7854
+ function validateBoxedRecord(record2, path) {
7855
+ try {
7856
+ validateBoxedProperties(record2);
7857
+ } catch {
7858
+ fail("invalidValue", path, "invalid boxed primitive properties");
7859
+ }
7860
+ const value = record2.value;
7861
+ if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") return;
7862
+ const number = requireRecord(value, `${path}.value`);
7863
+ if (number.kind !== "number" || !["NaN", "Infinity", "-Infinity", "-0"].includes(String(number.value)))
7864
+ fail("invalidValue", `${path}.value`, "invalid boxed primitive payload");
7865
+ }
7706
7866
  function validateDateRecord(record2, path) {
7707
7867
  if (Object.keys(record2).length !== 2) fail("invalidValue", path, "invalid Date fields");
7708
7868
  try {
@@ -7794,7 +7954,7 @@ function validateGenericValue(value, path, depth, state) {
7794
7954
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
7795
7955
  fail("invalidState", path, "guest function properties, prototype links and custom descriptors cannot be restored");
7796
7956
  }
7797
- if (state.dataPropertiesOnly && types4.isProxy(value)) {
7957
+ if (state.dataPropertiesOnly && types5.isProxy(value)) {
7798
7958
  fail("invalidType", path, "proxy objects are not snapshot data");
7799
7959
  }
7800
7960
  if (depth > state.limits.maxDepth)
@@ -8676,6 +8836,22 @@ async function withRunResources(signal, execute) {
8676
8836
  return result;
8677
8837
  }
8678
8838
 
8839
+ // packages/safe-js/src/interp/function-string.ts
8840
+ function functionString(value) {
8841
+ if (runResources.getStore()?.functionSourceText === false) return "[object Object]";
8842
+ const source = value.sourceRange;
8843
+ if (source !== void 0) return source.text.slice(source.start, source.end);
8844
+ let name = value.boundTarget === void 0 ? value.name?.split("#").at(-1) ?? "" : "";
8845
+ for (let index = 0; index < name.length; index++) {
8846
+ const code = name.charCodeAt(index);
8847
+ if (!(code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 36 || code === 95 || index > 0 && code >= 48 && code <= 57)) {
8848
+ name = "";
8849
+ break;
8850
+ }
8851
+ }
8852
+ return `function ${name}() { [native code] }`;
8853
+ }
8854
+
8679
8855
  // packages/safe-js/src/interp/string-coercion.ts
8680
8856
  var defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
8681
8857
  var defaultValueHook = /* @__PURE__ */ Symbol("defaultValueHook");
@@ -8703,7 +8879,7 @@ async function objectToPrimitive(value, budget, context, joining, hint) {
8703
8879
  if (hook === defaultStringHook) {
8704
8880
  result = await defaultToString(value, budget, context, joining);
8705
8881
  } else if (hook === defaultValueHook) {
8706
- result = isSandboxDate(value) ? dateTime(value) : value;
8882
+ result = isSandboxDate(value) ? dateTime(value) : isSandboxBox(value) ? boxedValue(value) : value;
8707
8883
  } else {
8708
8884
  if (!isSandboxClosure(hook)) continue;
8709
8885
  result = await invokeBuiltinClosure(hook, [], budget, context, value);
@@ -8743,6 +8919,8 @@ function conversionHook(value, name, budget) {
8743
8919
  return void 0;
8744
8920
  }
8745
8921
  async function defaultToString(value, budget, context, joining) {
8922
+ if (isSandboxBox(value)) return budget.allocateString(String(boxedValue(value)));
8923
+ if (isSandboxClosure(value)) return budget.allocateString(functionString(value));
8746
8924
  if (isSandboxMap(value)) return "[object Map]";
8747
8925
  if (isSandboxSet(value)) return "[object Set]";
8748
8926
  if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "[object Map Iterator]" : "[object Set Iterator]";
@@ -9298,7 +9476,27 @@ function assertSnapshotInactive(snapshot) {
9298
9476
  }
9299
9477
 
9300
9478
  // packages/safe-js/src/interp/iteration.ts
9301
- function getSandboxIterator(value, budget) {
9479
+ function getSandboxIterator(value, budget, context) {
9480
+ if (isSandboxBox(value) && typeof boxedValue(value) === "string") {
9481
+ const primitive = boxedValue(value);
9482
+ let text;
9483
+ let iterator;
9484
+ let initialized;
9485
+ return {
9486
+ asynchronous: true,
9487
+ get retainedValue() {
9488
+ return text === primitive ? void 0 : text;
9489
+ },
9490
+ next: async () => {
9491
+ initialized ??= Promise.resolve(sandboxString(value, budget ?? new Budget(), context)).then((converted) => {
9492
+ text = converted;
9493
+ iterator = syncIterator(converted[Symbol.iterator]());
9494
+ });
9495
+ await initialized;
9496
+ return iterator.next();
9497
+ }
9498
+ };
9499
+ }
9302
9500
  if (isSandboxCollectionIterator(value)) return { next: () => nextCollectionIterator(value, budget), snapshotIndex: () => 0 };
9303
9501
  if (isGuestHostObject(value)) return getHostObjectIterator(value);
9304
9502
  if (isFloat32Array(value)) {
@@ -9865,67 +10063,72 @@ async function settleIterable(iterable, method, budget, constructor, context) {
9865
10063
  const promiseResolve = readPromiseReceiverProperty(constructor, "resolve", prototype);
9866
10064
  if (!isSandboxClosure(promiseResolve))
9867
10065
  throw new TypeError("Promise constructor requires a callable resolve.");
9868
- const iterator = getSandboxIterator(iterable, budget);
10066
+ const iterator = getSandboxIterator(iterable, budget, context);
9869
10067
  if (iterator === void 0) throw new TypeError("Promise helpers require an iterable.");
9870
- let index = 0;
9871
- while (true) {
9872
- budget.visitNode();
9873
- const next = iterator.generator ? await iterator.next() : iterator.next();
9874
- if (typeof next !== "object" || next === null)
9875
- throw new TypeError("Iterator result must be an object.");
9876
- if (next.done) break;
9877
- const value = next.value;
9878
- try {
9879
- budget.allocateArrayLength(index + 1);
9880
- const entryIndex = index++;
9881
- if (method !== "race") values.push(void 0);
9882
- const entry = await callPromiseClosure(
9883
- promiseResolve,
9884
- [value],
9885
- constructor,
9886
- budget,
9887
- context
9888
- );
9889
- let called = false;
9890
- const handlers = ["fulfilled", "rejected"].map((state) => {
9891
- if (method === "race" || method === "any" && state === "fulfilled")
9892
- return state === "fulfilled" ? capability.resolve : capability.reject;
9893
- if (method === "all" && state === "rejected") return capability.reject;
9894
- return createSandboxClosure({
9895
- sandbox: true,
9896
- retainedValues: () => [
9897
- capability.promise,
9898
- capability.resolve,
9899
- capability.reject,
9900
- values
9901
- ],
9902
- call: async ([settlement]) => {
9903
- if (called) return void 0;
9904
- called = true;
9905
- values[entryIndex] = method === "allSettled" ? state === "fulfilled" ? { status: state, value: settlement } : { status: state, reason: settlement } : settlement;
9906
- remaining--;
9907
- await complete();
9908
- return void 0;
9909
- }
9910
- });
9911
- });
9912
- remaining++;
9913
- const then = readPromiseReceiverProperty(entry, "then", prototype);
9914
- if (!isSandboxClosure(then))
9915
- throw new TypeError("Promise resolver result requires a callable then.");
9916
- await callPromiseClosure(then, handlers, entry, budget, context);
9917
- } catch (error) {
10068
+ const releaseIterator = retainValues(budget, () => [iterator.retainedValue]);
10069
+ try {
10070
+ let index = 0;
10071
+ while (true) {
10072
+ budget.visitNode();
10073
+ const next = iterator.generator || iterator.asynchronous ? await iterator.next() : iterator.next();
10074
+ if (typeof next !== "object" || next === null)
10075
+ throw new TypeError("Iterator result must be an object.");
10076
+ if (next.done) break;
10077
+ const value = next.value;
9918
10078
  try {
9919
- const closed = iterator.return?.();
9920
- if (iterator.generator) await closed;
9921
- } catch {
10079
+ budget.allocateArrayLength(index + 1);
10080
+ const entryIndex = index++;
10081
+ if (method !== "race") values.push(void 0);
10082
+ const entry = await callPromiseClosure(
10083
+ promiseResolve,
10084
+ [value],
10085
+ constructor,
10086
+ budget,
10087
+ context
10088
+ );
10089
+ let called = false;
10090
+ const handlers = ["fulfilled", "rejected"].map((state) => {
10091
+ if (method === "race" || method === "any" && state === "fulfilled")
10092
+ return state === "fulfilled" ? capability.resolve : capability.reject;
10093
+ if (method === "all" && state === "rejected") return capability.reject;
10094
+ return createSandboxClosure({
10095
+ sandbox: true,
10096
+ retainedValues: () => [
10097
+ capability.promise,
10098
+ capability.resolve,
10099
+ capability.reject,
10100
+ values
10101
+ ],
10102
+ call: async ([settlement]) => {
10103
+ if (called) return void 0;
10104
+ called = true;
10105
+ values[entryIndex] = method === "allSettled" ? state === "fulfilled" ? { status: state, value: settlement } : { status: state, reason: settlement } : settlement;
10106
+ remaining--;
10107
+ await complete();
10108
+ return void 0;
10109
+ }
10110
+ });
10111
+ });
10112
+ remaining++;
10113
+ const then = readPromiseReceiverProperty(entry, "then", prototype);
10114
+ if (!isSandboxClosure(then))
10115
+ throw new TypeError("Promise resolver result requires a callable then.");
10116
+ await callPromiseClosure(then, handlers, entry, budget, context);
10117
+ } catch (error) {
10118
+ try {
10119
+ const closed = iterator.return?.();
10120
+ if (iterator.generator || iterator.asynchronous) await closed;
10121
+ } catch {
10122
+ throw error;
10123
+ }
9922
10124
  throw error;
9923
10125
  }
9924
- throw error;
9925
10126
  }
10127
+ remaining--;
10128
+ await complete();
10129
+ } finally {
10130
+ releaseIterator();
9926
10131
  }
9927
- remaining--;
9928
- await complete();
9929
10132
  } catch (error) {
9930
10133
  if (error instanceof SandboxError && (error.code === "budgetExceeded" || error.code === "reentry")) {
9931
10134
  if (isSandboxPromise(capability.promise)) observeSandboxPromise(capability.promise);
@@ -10427,6 +10630,9 @@ function createSandboxClosure(input) {
10427
10630
  enumerable: false,
10428
10631
  value: true
10429
10632
  });
10633
+ if (input.sourceRange !== void 0) {
10634
+ Object.defineProperty(closure, "sourceRange", { value: input.sourceRange });
10635
+ }
10430
10636
  if (input.sandbox === true) {
10431
10637
  Object.defineProperty(closure, "sandbox", { value: true });
10432
10638
  }
@@ -10624,6 +10830,17 @@ function measureSandboxData(values, options = {}) {
10624
10830
  assertSandboxDataDepth(depth);
10625
10831
  seen.add(value);
10626
10832
  usage += 1;
10833
+ if (isSandboxBox(value)) {
10834
+ const primitive = boxedValue(value);
10835
+ usage += typeof primitive === "string" ? primitive.length : 8;
10836
+ const prototype2 = getSandboxPrototype(value);
10837
+ if (prototype2 !== null) visit(prototype2, depth + 1);
10838
+ for (const [key, descriptor] of boxedDataProperties(value)) {
10839
+ usage += key.length + 1;
10840
+ if ("value" in descriptor) visit(descriptor.value, depth + 1);
10841
+ }
10842
+ return;
10843
+ }
10627
10844
  if (isSandboxDate(value)) {
10628
10845
  usage += 8;
10629
10846
  return;
@@ -10685,7 +10902,15 @@ function measureSandboxData(values, options = {}) {
10685
10902
  }
10686
10903
  if (isSandboxClosure(value)) {
10687
10904
  if (options.ignoreClosures) return;
10688
- if (value.properties !== void 0) visit(value.properties, depth + 1);
10905
+ if (value.properties !== void 0) {
10906
+ if (isIntrinsicConstructor(value)) {
10907
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value.properties))) {
10908
+ if (key === "prototype" || key === "name" || key === "length") continue;
10909
+ usage += key.length + 1;
10910
+ if ("value" in descriptor) visit(descriptor.value, depth + 1);
10911
+ }
10912
+ } else visit(value.properties, depth + 1);
10913
+ }
10689
10914
  if (!options.ignoreClosureCaptures)
10690
10915
  for (const retained of value[sandboxRetainedValues]?.() ?? []) visit(retained, depth + 1);
10691
10916
  return;
@@ -10817,6 +11042,24 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
10817
11042
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
10818
11043
  throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
10819
11044
  }
11045
+ const primitive = nativeBoxedValue(value);
11046
+ if (primitive !== void 0) {
11047
+ const original = value;
11048
+ const existing = state.seen.get(original);
11049
+ if (existing !== void 0) return existing;
11050
+ const copy = createSandboxBox(primitive);
11051
+ state.seen.set(original, copy);
11052
+ if (!state.structuredClone) {
11053
+ for (const [key, descriptor] of boxedDataProperties(original)) {
11054
+ if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
11055
+ Object.defineProperty(copy, key, {
11056
+ ...descriptor,
11057
+ value: copyToSandbox(descriptor.value, state, joinPath(path, key), cloneSandboxCollections, depth + 1)
11058
+ });
11059
+ }
11060
+ }
11061
+ return copy;
11062
+ }
10820
11063
  if (isSandboxMap(value)) {
10821
11064
  if (!cloneSandboxCollections) return value;
10822
11065
  const existing = state.seen.get(value);
@@ -10989,6 +11232,20 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
10989
11232
  if (!isSandboxClosure(value) && hasGuestObjectState(value)) {
10990
11233
  throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
10991
11234
  }
11235
+ if (isSandboxBox(value)) {
11236
+ const existing = state.seen.get(value);
11237
+ if (existing !== void 0) return existing;
11238
+ const copy = Object(boxedValue(value));
11239
+ state.seen.set(value, copy);
11240
+ for (const [key, descriptor] of boxedDataProperties(value)) {
11241
+ if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
11242
+ Object.defineProperty(copy, key, {
11243
+ ...descriptor,
11244
+ value: copyFromSandbox(descriptor.value, state, joinPath(path, key), options, depth + 1)
11245
+ });
11246
+ }
11247
+ return copy;
11248
+ }
10992
11249
  const regexBrand = Object.getOwnPropertyDescriptor(value, sandboxRegexBrand);
10993
11250
  if (regexBrand !== void 0) {
10994
11251
  if (!("value" in regexBrand) || regexBrand.value !== true) {
@@ -11159,6 +11416,17 @@ function allocateSandboxValue2(value, budget, seen) {
11159
11416
  budget.allocateString(value);
11160
11417
  return;
11161
11418
  }
11419
+ if (isSandboxBox(value)) {
11420
+ if (seen.has(value)) return;
11421
+ seen.add(value);
11422
+ const primitive = boxedValue(value);
11423
+ if (typeof primitive === "string") budget.allocateString(primitive);
11424
+ for (const [key, descriptor] of boxedDataProperties(value)) {
11425
+ budget.allocateString(key);
11426
+ if ("value" in descriptor) allocateSandboxValue2(descriptor.value, budget, seen);
11427
+ }
11428
+ return;
11429
+ }
11162
11430
  if (isFloat32Array(value)) {
11163
11431
  if (seen.has(value)) return;
11164
11432
  seen.add(value);
@@ -11348,6 +11616,13 @@ function encodeReplayData(value, options = {}) {
11348
11616
  id: capabilityId,
11349
11617
  properties: child(entry.properties, "properties")
11350
11618
  };
11619
+ } else if (nativeBoxedValue(entry) !== void 0) {
11620
+ const properties = /* @__PURE__ */ Object.create(null);
11621
+ nodes[id] = { kind: "boxed", value: child(nativeBoxedValue(entry), "<payload>"), properties, extensible: Object.isExtensible(entry) };
11622
+ for (const [key, descriptor] of boxedDataProperties(entry)) {
11623
+ if (!("value" in descriptor)) throw new TypeError(`Cannot record replay data accessor '${key}'.`);
11624
+ properties[key] = { value: child(descriptor.value, JSON.stringify(["property", key])), configurable: descriptor.configurable === true, enumerable: descriptor.enumerable === true, writable: descriptor.writable === true };
11625
+ }
11351
11626
  } else if (isSandboxDate(entry)) {
11352
11627
  nodes[id] = { kind: "date", time: serializedDateTime(entry) };
11353
11628
  } else if (isFloat32Array(entry)) {
@@ -11509,6 +11784,17 @@ function decodeReplayData(input, options = {}, parent) {
11509
11784
  options.onCapabilityRestored?.(capability, copy);
11510
11785
  return copy;
11511
11786
  }
11787
+ if (kind === "boxed") {
11788
+ validateBoxedProperties(node);
11789
+ const payload = own(node, "value");
11790
+ if (typeof payload !== "number" && typeof payload !== "string" && typeof payload !== "boolean" && (payload === null || typeof payload !== "object" || own(record(payload), "tag") !== "number"))
11791
+ throw new TypeError("Invalid boxed primitive payload.");
11792
+ const result3 = createSandboxBox(child(payload));
11793
+ restored.set(id, result3);
11794
+ defineProperties(result3, record(own(node, "properties")), child);
11795
+ if (!node.extensible) Object.preventExtensions(result3);
11796
+ return result3;
11797
+ }
11512
11798
  if (kind === "date") {
11513
11799
  if (Object.keys(node).length !== 2) throw new TypeError("Invalid serialized Date fields.");
11514
11800
  const result3 = restoreDateTime(own(node, "time"));
@@ -12274,19 +12560,19 @@ function normalize(value, seen) {
12274
12560
  var FNV_OFFSET_BASIS = 2166136261;
12275
12561
  var FNV_PRIME = 16777619;
12276
12562
  var IGNORED_KEYS = /* @__PURE__ */ new Set(["nodeId", "raw", "span"]);
12277
- function hashSource(source, owner) {
12563
+ function hashSource(source, owner, includeFunctionSource = true) {
12278
12564
  try {
12279
- return hashParsedAst(parse(source, "<input>", owner));
12565
+ return hashParsedAst(parse(source, "<input>", owner), includeFunctionSource);
12280
12566
  } catch (error) {
12281
12567
  if (error instanceof SandboxError) throw error;
12282
- return hashParsedAst(parseModule(source, "<input>", owner));
12568
+ return hashParsedAst(parseModule(source, "<input>", owner), includeFunctionSource);
12283
12569
  }
12284
12570
  }
12285
- function hashParsedAst(ast) {
12571
+ function hashParsedAst(ast, includeFunctionSource = true) {
12286
12572
  let hash = FNV_OFFSET_BASIS;
12287
12573
  visit(ast);
12288
12574
  return hash.toString(16).padStart(8, "0");
12289
- function visit(value, includeTemplateRaw = false) {
12575
+ function visit(value, includeTemplateRaw = false, enclosingSource) {
12290
12576
  if (value === null) {
12291
12577
  write("null");
12292
12578
  return;
@@ -12298,7 +12584,7 @@ function hashParsedAst(ast) {
12298
12584
  if (Array.isArray(value)) {
12299
12585
  write("[");
12300
12586
  for (const entry of value) {
12301
- visit(entry, includeTemplateRaw);
12587
+ visit(entry, includeTemplateRaw, enclosingSource);
12302
12588
  write(",");
12303
12589
  }
12304
12590
  write("]");
@@ -12316,12 +12602,23 @@ function hashParsedAst(ast) {
12316
12602
  return;
12317
12603
  case "object": {
12318
12604
  const record2 = value;
12605
+ const source = includeFunctionSource ? functionSources.get(value) : void 0;
12606
+ if (source !== void 0 && !(enclosingSource !== void 0 && source.text === enclosingSource.text && source.start >= enclosingSource.start && source.end <= enclosingSource.end)) {
12607
+ write("function-source:");
12608
+ write(String(source.end - source.start));
12609
+ write(":");
12610
+ write(source.text, source.start, source.end);
12611
+ }
12319
12612
  const keys = Object.keys(value).filter((key) => shouldHashKey(record2, key, includeTemplateRaw)).sort();
12320
12613
  write("{");
12321
12614
  for (const key of keys) {
12322
12615
  write(JSON.stringify(key));
12323
12616
  write(":");
12324
- visit(record2[key], shouldIncludeTemplateRaw(record2, key, includeTemplateRaw));
12617
+ visit(
12618
+ record2[key],
12619
+ shouldIncludeTemplateRaw(record2, key, includeTemplateRaw),
12620
+ source ?? enclosingSource
12621
+ );
12325
12622
  write(",");
12326
12623
  }
12327
12624
  write("}");
@@ -12331,8 +12628,8 @@ function hashParsedAst(ast) {
12331
12628
  throw new TypeError(`Unsupported AST value type: ${typeof value}`);
12332
12629
  }
12333
12630
  }
12334
- function write(chunk) {
12335
- for (let index = 0; index < chunk.length; index += 1) {
12631
+ function write(chunk, start = 0, end = chunk.length) {
12632
+ for (let index = start; index < end; index += 1) {
12336
12633
  hash ^= chunk.charCodeAt(index);
12337
12634
  hash = Math.imul(hash, FNV_PRIME) >>> 0;
12338
12635
  }
@@ -12359,11 +12656,11 @@ function shouldIncludeTemplateRaw(record2, key, includeTemplateRaw) {
12359
12656
 
12360
12657
  // packages/safe-js/src/snapshot/migration.ts
12361
12658
  function validateMigrationSemantics(value) {
12362
- if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7"].includes(
12659
+ if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7", "jobs-v8"].includes(
12363
12660
  value
12364
12661
  ))
12365
12662
  throw new TypeError(
12366
- "Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v7)."
12663
+ "Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v8)."
12367
12664
  );
12368
12665
  }
12369
12666
  function validateMigrationJournal(sourceHash, replay, hostCalls = [], owner) {
@@ -12472,14 +12769,18 @@ function restore(snapshot, options, owner) {
12472
12769
  assertSnapshotInactive(snapshot);
12473
12770
  validateDumpEnvelope(snapshot);
12474
12771
  validateSnapshotMigration(snapshot.migration, snapshot.sourceHash, owner);
12475
- if (snapshot.executionSemantics !== EXECUTION_SEMANTICS && snapshot.executionSemantics !== "jobs-v6" && (snapshot.executionSemantics !== void 0 || snapshot.promiseReplay !== void 0 || snapshot.replay !== void 0 || snapshot.initialInputs !== void 0)) {
12772
+ if (snapshot.executionSemantics !== EXECUTION_SEMANTICS && snapshot.executionSemantics !== "jobs-v6" && snapshot.executionSemantics !== "jobs-v7" && (snapshot.executionSemantics !== void 0 || snapshot.promiseReplay !== void 0 || snapshot.replay !== void 0 || snapshot.initialInputs !== void 0)) {
12476
12773
  throw new SnapshotValidationError(
12477
12774
  "unsupportedVersion",
12478
12775
  "$.executionSemantics",
12479
12776
  "incompatible execution semantics; resume with the SafeJS version that created this snapshot. Migration requires explicit reconciliation, not changing its version marker."
12480
12777
  );
12481
12778
  }
12482
- const currentSourceHash = hashSource(options.source, owner);
12779
+ const currentSourceHash = hashSource(
12780
+ options.source,
12781
+ owner,
12782
+ snapshot.executionSemantics !== "jobs-v6" && snapshot.executionSemantics !== "jobs-v7"
12783
+ );
12483
12784
  if (snapshot.sourceHash !== currentSourceHash) {
12484
12785
  throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
12485
12786
  }
@@ -24016,7 +24317,10 @@ function isArrayMethodName(property) {
24016
24317
  }
24017
24318
  async function callArrayMethod(receiver, methodName, args, options, stack = []) {
24018
24319
  if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
24019
- if (typeof receiver !== "object") throw new TypeError("Object primitive boxing is not supported.");
24320
+ if (typeof receiver !== "object") {
24321
+ receiver = createSandboxBox(receiver);
24322
+ options.budget.chargeDataUsage(measureSandboxData([receiver]));
24323
+ }
24020
24324
  const retainedReceiver = {};
24021
24325
  options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
24022
24326
  try {
@@ -24724,7 +25028,7 @@ function toIntegerOrInfinity(value) {
24724
25028
  }
24725
25029
 
24726
25030
  // packages/safe-js/src/interp/methods/function.ts
24727
- var functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call"]);
25031
+ var functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call", "toString"]);
24728
25032
  function getFunctionMember(target, property, options) {
24729
25033
  if (isGuestClosure(target)) {
24730
25034
  const value = getGuestFunctionProperty(target, String(property));
@@ -24738,12 +25042,14 @@ function getFunctionMember(target, property, options) {
24738
25042
  if (property === "length") {
24739
25043
  return target.length;
24740
25044
  }
25045
+ if (property === "toString" && runResources.getStore()?.functionSourceText === false) return void 0;
24741
25046
  if (!isFunctionMethodName(property)) {
24742
25047
  return void 0;
24743
25048
  }
24744
25049
  return createSandboxClosure({
24745
25050
  sandbox: true,
24746
25051
  name: `Function#${property}`,
25052
+ ...property === "toString" ? { length: 0 } : {},
24747
25053
  call: (args, context) => callFunctionMethod(context?.thisValue, property, args, options, context?.stack ?? [])
24748
25054
  });
24749
25055
  }
@@ -24754,6 +25060,10 @@ function callFunctionMethod(target, methodName, args, options, stack) {
24754
25060
  if (!isSandboxClosure(target)) {
24755
25061
  throw new TypeError(`Function#${methodName} requires a callable receiver.`);
24756
25062
  }
25063
+ if (methodName === "toString") {
25064
+ const text = functionString(target);
25065
+ return options.budget?.allocateString(text) ?? text;
25066
+ }
24757
25067
  const thisValue = args[0];
24758
25068
  if (methodName === "bind") {
24759
25069
  const boundArgs = args.slice(1);
@@ -24789,276 +25099,61 @@ function callFunctionMethod(target, methodName, args, options, stack) {
24789
25099
  return options.callClosure(target, applyArgs, stack, thisValue);
24790
25100
  }
24791
25101
 
24792
- // packages/safe-js/src/interp/methods/collection-callback.ts
24793
- var activeCallbacks = /* @__PURE__ */ new WeakMap();
24794
- function enterKeyedCollectionCallback(target, keys, budget) {
24795
- let state = activeCallbacks.get(target);
24796
- if (state === void 0) {
24797
- state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
24798
- activeCallbacks.set(target, state);
25102
+ // packages/safe-js/src/interp/methods/string.ts
25103
+ var SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
25104
+ var stringMethodNames = /* @__PURE__ */ new Set([
25105
+ "at",
25106
+ "charAt",
25107
+ "charCodeAt",
25108
+ "codePointAt",
25109
+ "concat",
25110
+ "endsWith",
25111
+ "includes",
25112
+ "indexOf",
25113
+ "isWellFormed",
25114
+ "lastIndexOf",
25115
+ "localeCompare",
25116
+ "match",
25117
+ "matchAll",
25118
+ "normalize",
25119
+ "padEnd",
25120
+ "padStart",
25121
+ "repeat",
25122
+ "replace",
25123
+ "replaceAll",
25124
+ "slice",
25125
+ "search",
25126
+ "split",
25127
+ "startsWith",
25128
+ "substr",
25129
+ "substring",
25130
+ "toLowerCase",
25131
+ "toUpperCase",
25132
+ "toWellFormed",
25133
+ "trim",
25134
+ "trimEnd",
25135
+ "trimStart"
25136
+ ]);
25137
+ function getStringMember(value, property, budget) {
25138
+ const index = getStringIndex(property);
25139
+ if (index !== void 0) {
25140
+ return value[index];
24799
25141
  }
24800
- const cursor = { budget, pending: /* @__PURE__ */ new Set() };
24801
- state.cursors.add(cursor);
24802
- const leave = () => {
24803
- if (!state.cursors.delete(cursor)) return;
24804
- cursor.pending.clear();
24805
- budget.setRetainedDataUsage(cursor, 0);
24806
- budget.setRetainedValues(cursor, void 0);
24807
- if (state.cursors.size === 0) {
24808
- activeCallbacks.delete(target);
24809
- state.leaveRunning();
24810
- }
24811
- };
24812
- try {
24813
- budget.setRetainedDataUsage(cursor, 1);
24814
- budget.setRetainedValues(cursor, () => cursor.pending);
24815
- for (const key of keys) updatePendingKeys(cursor, "add", key);
24816
- } catch (error) {
24817
- leave();
24818
- throw error;
25142
+ if (property === "length") {
25143
+ return value.length;
24819
25144
  }
24820
- return {
24821
- next: () => {
24822
- budget.visitNode();
24823
- for (const key of cursor.pending) {
24824
- cursor.pending.delete(key);
24825
- budget.setRetainedDataUsage(cursor, 1 + cursor.pending.size);
24826
- return { done: false, value: key };
24827
- }
24828
- return { done: true, value: void 0 };
24829
- },
24830
- leave
24831
- };
24832
- }
24833
- function updateKeyedCollectionCallbacks(target, mutation, key) {
24834
- const state = activeCallbacks.get(target);
24835
- if (state === void 0) return;
24836
- for (const cursor of state.cursors) updatePendingKeys(cursor, mutation, key);
24837
- }
24838
- function updatePendingKeys(cursor, mutation, key) {
24839
- const { budget, pending } = cursor;
24840
- budget.visitNode();
24841
- if (mutation === "add") {
24842
- const nextSize = pending.has(key) ? pending.size : pending.size + 1;
24843
- budget.allocateCollectionEntries(nextSize);
24844
- budget.setRetainedDataUsage(cursor, 1 + nextSize);
24845
- pending.add(key);
24846
- } else {
24847
- if (mutation === "delete") pending.delete(key);
24848
- else pending.clear();
24849
- budget.setRetainedDataUsage(cursor, 1 + pending.size);
24850
- }
24851
- }
24852
-
24853
- // packages/safe-js/src/interp/methods/map.ts
24854
- var mapMethodNames = /* @__PURE__ */ new Set([
24855
- "get",
24856
- "set",
24857
- "has",
24858
- "delete",
24859
- "clear",
24860
- "forEach",
24861
- "keys",
24862
- "values",
24863
- "entries"
24864
- ]);
24865
- function isMapMethodName(value) {
24866
- return typeof value === "string" && mapMethodNames.has(value);
24867
- }
24868
- function getMapMember(target, property, options) {
24869
- if (property === "size") {
24870
- return target.entries.size;
24871
- }
24872
- if (!isMapMethodName(property)) {
24873
- return void 0;
24874
- }
24875
- return createSandboxClosure({
24876
- sandbox: true,
24877
- call: (args, context) => {
24878
- const receiver = context?.thisValue;
24879
- if (!isSandboxMap(receiver)) throw new TypeError(`Map#${property} requires a Map receiver.`);
24880
- return callMapMethod(receiver, property, args, options, context?.stack ?? []);
24881
- },
24882
- name: property
24883
- });
24884
- }
24885
- async function callMapMethod(target, methodName, args, options, stack = []) {
24886
- switch (methodName) {
24887
- case "get":
24888
- return target.entries.get(args[0]);
24889
- case "set": {
24890
- assertCollectionMutable(target);
24891
- const exists = target.entries.has(args[0]);
24892
- const nextSize = exists ? target.entries.size : target.entries.size + 1;
24893
- options.budget.allocateCollectionEntries(nextSize);
24894
- if (!exists) updateKeyedCollectionCallbacks(target, "add", args[0]);
24895
- target.entries.set(args[0], args[1]);
24896
- return target;
24897
- }
24898
- case "has":
24899
- return target.entries.has(args[0]);
24900
- case "delete": {
24901
- assertCollectionMutable(target);
24902
- const deleted = target.entries.delete(args[0]);
24903
- if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
24904
- return deleted;
24905
- }
24906
- case "clear":
24907
- assertCollectionMutable(target);
24908
- target.entries.clear();
24909
- updateKeyedCollectionCallbacks(target, "clear");
24910
- return void 0;
24911
- case "forEach": {
24912
- const callback = args[0];
24913
- if (!isSandboxClosure(callback)) {
24914
- throw new TypeError("Map.prototype.forEach requires a callback function.");
24915
- }
24916
- const cursor = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
24917
- try {
24918
- for (let entry = cursor.next(); !entry.done; entry = cursor.next()) {
24919
- const key = entry.value;
24920
- const value = target.entries.get(key);
24921
- await options.callClosure(callback, [value, key, target], stack, args[1]);
24922
- }
24923
- } finally {
24924
- cursor.leave();
24925
- }
24926
- return void 0;
24927
- }
24928
- case "keys":
24929
- case "values":
24930
- case "entries":
24931
- return createSandboxCollectionIterator(target, methodName);
24932
- }
24933
- }
24934
-
24935
- // packages/safe-js/src/interp/methods/number.ts
24936
- var numberMethodNames = /* @__PURE__ */ new Set([
24937
- "toExponential",
24938
- "toFixed",
24939
- "toPrecision",
24940
- "toString"
24941
- ]);
24942
- function getNumberMember(property, budget) {
24943
- if (!isNumberMethodName(property)) {
24944
- return void 0;
24945
- }
24946
- return createSandboxClosure({
24947
- sandbox: true,
24948
- name: `Number#${property}`,
24949
- call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
24950
- });
24951
- }
24952
- function isNumberMethodName(property) {
24953
- return typeof property === "string" && numberMethodNames.has(property);
24954
- }
24955
- function callNumberMethod(value, methodName, args, budget, context) {
24956
- if (typeof value !== "number") {
24957
- throw new TypeError(`Number#${methodName} requires a number receiver.`);
24958
- }
24959
- const argument = args[0];
24960
- if (argument !== null && typeof argument === "object") {
24961
- return formatObjectArgument(value, methodName, argument, budget, context);
24962
- }
24963
- return formatNumber(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
24964
- }
24965
- async function formatObjectArgument(value, methodName, argument, budget, context) {
24966
- const retainedArgument = {};
24967
- budget.setRetainedValues(retainedArgument, () => [argument]);
24968
- try {
24969
- const number = await sandboxNumber(argument, budget, context);
24970
- return formatNumber(value, methodName, number, budget);
24971
- } finally {
24972
- budget.setRetainedValues(retainedArgument, void 0);
24973
- }
24974
- }
24975
- function formatNumber(value, methodName, argument, budget) {
24976
- let result;
24977
- try {
24978
- result = value[methodName](argument);
24979
- } catch (error) {
24980
- if (!(error instanceof RangeError)) throw error;
24981
- 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.";
24982
- throw new RangeError(`Number#${methodName} ${detail}`);
24983
- }
24984
- return budget.allocateString(result);
24985
- }
24986
-
24987
- // packages/safe-js/src/interp/methods/generator.ts
24988
- var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
24989
- function getGeneratorMember(target, property, budget) {
24990
- if (typeof property !== "string" || !generatorMethodNames.has(property)) {
24991
- return void 0;
24992
- }
24993
- return createSandboxClosure({
24994
- sandbox: true,
24995
- name: property,
24996
- call: async ([value]) => {
24997
- const iterator = getSandboxIterator(target);
24998
- const result = await iterator[property](value);
24999
- return allocateProducedSandboxValue(
25000
- { value: result.value, done: result.done === true },
25001
- budget
25002
- );
25003
- }
25004
- });
25005
- }
25006
-
25007
- // packages/safe-js/src/interp/methods/string.ts
25008
- var SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
25009
- var stringMethodNames = /* @__PURE__ */ new Set([
25010
- "at",
25011
- "charAt",
25012
- "charCodeAt",
25013
- "codePointAt",
25014
- "concat",
25015
- "endsWith",
25016
- "includes",
25017
- "indexOf",
25018
- "isWellFormed",
25019
- "lastIndexOf",
25020
- "localeCompare",
25021
- "match",
25022
- "matchAll",
25023
- "normalize",
25024
- "padEnd",
25025
- "padStart",
25026
- "repeat",
25027
- "replace",
25028
- "replaceAll",
25029
- "slice",
25030
- "search",
25031
- "split",
25032
- "startsWith",
25033
- "substr",
25034
- "substring",
25035
- "toLowerCase",
25036
- "toUpperCase",
25037
- "toWellFormed",
25038
- "trim",
25039
- "trimEnd",
25040
- "trimStart"
25041
- ]);
25042
- function getStringMember(value, property, budget) {
25043
- const index = getStringIndex(property);
25044
- if (index !== void 0) {
25045
- return value[index];
25046
- }
25047
- if (property === "length") {
25048
- return value.length;
25049
- }
25050
- if (!isStringMethodName(property)) {
25051
- return void 0;
25052
- }
25053
- return createSandboxClosure({
25054
- sandbox: true,
25055
- name: `String#${property}`,
25056
- ...property === "localeCompare" ? { length: 1 } : {},
25057
- ...property === "isWellFormed" || property === "toWellFormed" ? { length: 0 } : {},
25058
- call: async (args, context) => {
25059
- const receiver = context?.thisValue;
25060
- if (receiver === null || receiver === void 0) {
25061
- throw new TypeError(`String#${property} requires a non-null receiver.`);
25145
+ if (!isStringMethodName(property)) {
25146
+ return void 0;
25147
+ }
25148
+ return createSandboxClosure({
25149
+ sandbox: true,
25150
+ name: `String#${property}`,
25151
+ ...property === "localeCompare" ? { length: 1 } : {},
25152
+ ...property === "isWellFormed" || property === "toWellFormed" ? { length: 0 } : {},
25153
+ call: async (args, context) => {
25154
+ const receiver = context?.thisValue;
25155
+ if (receiver === null || receiver === void 0) {
25156
+ throw new TypeError(`String#${property} requires a non-null receiver.`);
25062
25157
  }
25063
25158
  const retainedReceiver = {};
25064
25159
  budget.setRetainedValues(retainedReceiver, () => [receiver]);
@@ -25502,11 +25597,227 @@ function splitString(value, separator, limit) {
25502
25597
  function asNumber(value) {
25503
25598
  return Number(value);
25504
25599
  }
25505
- function asNumberOrUndefined(value) {
25506
- return value === void 0 ? void 0 : Number(value);
25600
+ function asNumberOrUndefined(value) {
25601
+ return value === void 0 ? void 0 : Number(value);
25602
+ }
25603
+ function asStringOrUndefined(value) {
25604
+ return value === void 0 ? void 0 : String(value);
25605
+ }
25606
+
25607
+ // packages/safe-js/src/interp/methods/collection-callback.ts
25608
+ var activeCallbacks = /* @__PURE__ */ new WeakMap();
25609
+ function enterKeyedCollectionCallback(target, keys, budget) {
25610
+ let state = activeCallbacks.get(target);
25611
+ if (state === void 0) {
25612
+ state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
25613
+ activeCallbacks.set(target, state);
25614
+ }
25615
+ const cursor = { budget, pending: /* @__PURE__ */ new Set() };
25616
+ state.cursors.add(cursor);
25617
+ const leave = () => {
25618
+ if (!state.cursors.delete(cursor)) return;
25619
+ cursor.pending.clear();
25620
+ budget.setRetainedDataUsage(cursor, 0);
25621
+ budget.setRetainedValues(cursor, void 0);
25622
+ if (state.cursors.size === 0) {
25623
+ activeCallbacks.delete(target);
25624
+ state.leaveRunning();
25625
+ }
25626
+ };
25627
+ try {
25628
+ budget.setRetainedDataUsage(cursor, 1);
25629
+ budget.setRetainedValues(cursor, () => cursor.pending);
25630
+ for (const key of keys) updatePendingKeys(cursor, "add", key);
25631
+ } catch (error) {
25632
+ leave();
25633
+ throw error;
25634
+ }
25635
+ return {
25636
+ next: () => {
25637
+ budget.visitNode();
25638
+ for (const key of cursor.pending) {
25639
+ cursor.pending.delete(key);
25640
+ budget.setRetainedDataUsage(cursor, 1 + cursor.pending.size);
25641
+ return { done: false, value: key };
25642
+ }
25643
+ return { done: true, value: void 0 };
25644
+ },
25645
+ leave
25646
+ };
25647
+ }
25648
+ function updateKeyedCollectionCallbacks(target, mutation, key) {
25649
+ const state = activeCallbacks.get(target);
25650
+ if (state === void 0) return;
25651
+ for (const cursor of state.cursors) updatePendingKeys(cursor, mutation, key);
25652
+ }
25653
+ function updatePendingKeys(cursor, mutation, key) {
25654
+ const { budget, pending } = cursor;
25655
+ budget.visitNode();
25656
+ if (mutation === "add") {
25657
+ const nextSize = pending.has(key) ? pending.size : pending.size + 1;
25658
+ budget.allocateCollectionEntries(nextSize);
25659
+ budget.setRetainedDataUsage(cursor, 1 + nextSize);
25660
+ pending.add(key);
25661
+ } else {
25662
+ if (mutation === "delete") pending.delete(key);
25663
+ else pending.clear();
25664
+ budget.setRetainedDataUsage(cursor, 1 + pending.size);
25665
+ }
25666
+ }
25667
+
25668
+ // packages/safe-js/src/interp/methods/map.ts
25669
+ var mapMethodNames = /* @__PURE__ */ new Set([
25670
+ "get",
25671
+ "set",
25672
+ "has",
25673
+ "delete",
25674
+ "clear",
25675
+ "forEach",
25676
+ "keys",
25677
+ "values",
25678
+ "entries"
25679
+ ]);
25680
+ function isMapMethodName(value) {
25681
+ return typeof value === "string" && mapMethodNames.has(value);
25682
+ }
25683
+ function getMapMember(target, property, options) {
25684
+ if (property === "size") {
25685
+ return target.entries.size;
25686
+ }
25687
+ if (!isMapMethodName(property)) {
25688
+ return void 0;
25689
+ }
25690
+ return createSandboxClosure({
25691
+ sandbox: true,
25692
+ call: (args, context) => {
25693
+ const receiver = context?.thisValue;
25694
+ if (!isSandboxMap(receiver)) throw new TypeError(`Map#${property} requires a Map receiver.`);
25695
+ return callMapMethod(receiver, property, args, options, context?.stack ?? []);
25696
+ },
25697
+ name: property
25698
+ });
25699
+ }
25700
+ async function callMapMethod(target, methodName, args, options, stack = []) {
25701
+ switch (methodName) {
25702
+ case "get":
25703
+ return target.entries.get(args[0]);
25704
+ case "set": {
25705
+ assertCollectionMutable(target);
25706
+ const exists = target.entries.has(args[0]);
25707
+ const nextSize = exists ? target.entries.size : target.entries.size + 1;
25708
+ options.budget.allocateCollectionEntries(nextSize);
25709
+ if (!exists) updateKeyedCollectionCallbacks(target, "add", args[0]);
25710
+ target.entries.set(args[0], args[1]);
25711
+ return target;
25712
+ }
25713
+ case "has":
25714
+ return target.entries.has(args[0]);
25715
+ case "delete": {
25716
+ assertCollectionMutable(target);
25717
+ const deleted = target.entries.delete(args[0]);
25718
+ if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
25719
+ return deleted;
25720
+ }
25721
+ case "clear":
25722
+ assertCollectionMutable(target);
25723
+ target.entries.clear();
25724
+ updateKeyedCollectionCallbacks(target, "clear");
25725
+ return void 0;
25726
+ case "forEach": {
25727
+ const callback = args[0];
25728
+ if (!isSandboxClosure(callback)) {
25729
+ throw new TypeError("Map.prototype.forEach requires a callback function.");
25730
+ }
25731
+ const cursor = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
25732
+ try {
25733
+ for (let entry = cursor.next(); !entry.done; entry = cursor.next()) {
25734
+ const key = entry.value;
25735
+ const value = target.entries.get(key);
25736
+ await options.callClosure(callback, [value, key, target], stack, args[1]);
25737
+ }
25738
+ } finally {
25739
+ cursor.leave();
25740
+ }
25741
+ return void 0;
25742
+ }
25743
+ case "keys":
25744
+ case "values":
25745
+ case "entries":
25746
+ return createSandboxCollectionIterator(target, methodName);
25747
+ }
25748
+ }
25749
+
25750
+ // packages/safe-js/src/interp/methods/number.ts
25751
+ var numberMethodNames = /* @__PURE__ */ new Set([
25752
+ "toExponential",
25753
+ "toFixed",
25754
+ "toPrecision",
25755
+ "toString"
25756
+ ]);
25757
+ function getNumberMember(property, budget) {
25758
+ if (!isNumberMethodName(property)) {
25759
+ return void 0;
25760
+ }
25761
+ return createSandboxClosure({
25762
+ sandbox: true,
25763
+ name: `Number#${property}`,
25764
+ call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
25765
+ });
25766
+ }
25767
+ function isNumberMethodName(property) {
25768
+ return typeof property === "string" && numberMethodNames.has(property);
25769
+ }
25770
+ function callNumberMethod(value, methodName, args, budget, context) {
25771
+ if (isSandboxBox(value)) value = boxedValue(value);
25772
+ if (typeof value !== "number") {
25773
+ throw new TypeError(`Number#${methodName} requires a number receiver.`);
25774
+ }
25775
+ const argument = args[0];
25776
+ if (argument !== null && typeof argument === "object") {
25777
+ return formatObjectArgument(value, methodName, argument, budget, context);
25778
+ }
25779
+ return formatNumber(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
25780
+ }
25781
+ async function formatObjectArgument(value, methodName, argument, budget, context) {
25782
+ const retainedArgument = {};
25783
+ budget.setRetainedValues(retainedArgument, () => [argument]);
25784
+ try {
25785
+ const number = await sandboxNumber(argument, budget, context);
25786
+ return formatNumber(value, methodName, number, budget);
25787
+ } finally {
25788
+ budget.setRetainedValues(retainedArgument, void 0);
25789
+ }
25790
+ }
25791
+ function formatNumber(value, methodName, argument, budget) {
25792
+ let result;
25793
+ try {
25794
+ result = value[methodName](argument);
25795
+ } catch (error) {
25796
+ if (!(error instanceof RangeError)) throw error;
25797
+ 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.";
25798
+ throw new RangeError(`Number#${methodName} ${detail}`);
25799
+ }
25800
+ return budget.allocateString(result);
25507
25801
  }
25508
- function asStringOrUndefined(value) {
25509
- return value === void 0 ? void 0 : String(value);
25802
+
25803
+ // packages/safe-js/src/interp/methods/generator.ts
25804
+ var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
25805
+ function getGeneratorMember(target, property, budget) {
25806
+ if (typeof property !== "string" || !generatorMethodNames.has(property)) {
25807
+ return void 0;
25808
+ }
25809
+ return createSandboxClosure({
25810
+ sandbox: true,
25811
+ name: property,
25812
+ call: async ([value]) => {
25813
+ const iterator = getSandboxIterator(target);
25814
+ const result = await iterator[property](value);
25815
+ return allocateProducedSandboxValue(
25816
+ { value: result.value, done: result.done === true },
25817
+ budget
25818
+ );
25819
+ }
25820
+ });
25510
25821
  }
25511
25822
 
25512
25823
  // packages/safe-js/src/interp/methods/set.ts
@@ -25643,7 +25954,11 @@ function createObjectGlobal(methods, budget) {
25643
25954
  budget.chargeDataUsage(1);
25644
25955
  return /* @__PURE__ */ Object.create(null);
25645
25956
  }
25646
- if (typeof value !== "object") throw new TypeError("Object primitive boxing is not supported.");
25957
+ if (typeof value !== "object") {
25958
+ const box = createSandboxBox(value);
25959
+ budget.chargeDataUsage(measureSandboxData([box]));
25960
+ return box;
25961
+ }
25647
25962
  return value;
25648
25963
  };
25649
25964
  const constructor = createSandboxClosure({
@@ -25673,9 +25988,7 @@ function createObjectGlobal(methods, budget) {
25673
25988
  length: 0,
25674
25989
  call: (_args, context) => {
25675
25990
  const value = requireReceiver(context?.thisValue);
25676
- if (typeof value !== "object")
25677
- throw new TypeError("Object primitive boxing is not supported.");
25678
- return value;
25991
+ return construct([value]);
25679
25992
  }
25680
25993
  }),
25681
25994
  hasOwnProperty: createSandboxClosure({
@@ -25743,6 +26056,7 @@ function hasOwnSandboxProperty(value, key, enumerable) {
25743
26056
  return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
25744
26057
  }
25745
26058
  function typeTag(value) {
26059
+ if (isSandboxBox(value)) value = boxedValue(value);
25746
26060
  if (value === void 0) return "Undefined";
25747
26061
  if (value === null) return "Null";
25748
26062
  if (typeof value === "string") return "String";
@@ -25847,12 +26161,12 @@ function isSandboxSetConstructor(value) {
25847
26161
  function populateCollection(source, collection, { name, budget, context, append, retainedValues }) {
25848
26162
  budget.allocateCollectionEntries(0);
25849
26163
  if (source === void 0 || source === null) return collection;
25850
- const iterator = getSandboxIterator(source, budget);
26164
+ const iterator = getSandboxIterator(source, budget, context);
25851
26165
  if (iterator === void 0) throw new TypeError(`${name} constructor requires an iterable.`);
25852
26166
  let entry;
25853
26167
  let failure;
25854
26168
  const retained = {};
25855
- budget.setRetainedValues(retained, () => [source, collection, entry, failure, ...retainedValues?.() ?? []]);
26169
+ budget.setRetainedValues(retained, () => [source, iterator.retainedValue, collection, entry, failure, ...retainedValues?.() ?? []]);
25856
26170
  const checkData = createDataCheckpoint(budget, context);
25857
26171
  const closeOnThrow = (error) => {
25858
26172
  failure = isCapturedException(error) ? error.reason : error;
@@ -25862,7 +26176,7 @@ function populateCollection(source, collection, { name, budget, context, append,
25862
26176
  };
25863
26177
  try {
25864
26178
  const closing = iterator.return?.();
25865
- if (iterator.generator) return Promise.resolve(closing).then(() => {
26179
+ if (iterator.generator || iterator.asynchronous) return Promise.resolve(closing).then(() => {
25866
26180
  throw error;
25867
26181
  }, rethrow);
25868
26182
  } catch (closeError) {
@@ -25884,7 +26198,7 @@ function populateCollection(source, collection, { name, budget, context, append,
25884
26198
  }
25885
26199
  return false;
25886
26200
  };
25887
- if (iterator.generator) {
26201
+ if (iterator.generator || iterator.asynchronous) {
25888
26202
  return (async () => {
25889
26203
  try {
25890
26204
  checkData(collection, 0, true);
@@ -26839,22 +27153,29 @@ async function evaluateBinaryExpression(node, context) {
26839
27153
  if (left.kind !== "normal") {
26840
27154
  return left;
26841
27155
  }
27156
+ let leftValue = left.value;
26842
27157
  let rightValue;
26843
- const release = retainValues(context.budget, () => [left.value, rightValue]);
27158
+ const release = retainValues(context.budget, () => [leftValue, rightValue]);
26844
27159
  try {
26845
27160
  const right = await evaluateNode(node.right, context);
26846
27161
  if (right.kind !== "normal") {
26847
27162
  return right;
26848
27163
  }
26849
27164
  rightValue = right.value;
26850
- let leftValue = left.value;
26851
27165
  if (node.operator === "in") {
26852
27166
  if (typeof right.value !== "object" || right.value === null) {
26853
27167
  throw new TypeError("Right-hand side of 'in' must be an object.");
26854
27168
  }
26855
27169
  leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
26856
27170
  }
26857
- const value = applyBinaryOperator(node, leftValue, right.value, context);
27171
+ if (!["in", "instanceof", "===", "!=="].includes(node.operator)) {
27172
+ const equality = node.operator === "==" || node.operator === "!=";
27173
+ if (isSandboxBox(leftValue) && (!equality || rightValue !== null && rightValue !== void 0 && typeof rightValue !== "object"))
27174
+ leftValue = await toNumericPrimitive(leftValue, context);
27175
+ if (isSandboxBox(rightValue) && (!equality || left.value !== null && left.value !== void 0 && typeof left.value !== "object"))
27176
+ rightValue = await toNumericPrimitive(rightValue, context);
27177
+ }
27178
+ const value = applyBinaryOperator(node, leftValue, rightValue, context);
26858
27179
  return {
26859
27180
  kind: "normal",
26860
27181
  hasValue: true,
@@ -27442,63 +27763,68 @@ async function evaluateForOfStatement(node, context) {
27442
27763
  };
27443
27764
  }
27444
27765
  async function evaluateForOfIterator(node, value, context, restoredEntry) {
27445
- const iterator = getSandboxIterator(value, context.budget);
27766
+ const iterator = getSandboxIterator(value, context.budget, createCoercionContext(context));
27446
27767
  if (iterator === void 0) {
27447
27768
  throw new TypeError(`${String(value)} is not a supported iterable`);
27448
27769
  }
27449
- const nodeId = node.nodeId ?? -1;
27450
- let index = consumeRestoredLoopIterationIndex(node, context);
27451
- for (let skipped = 0; skipped < index; skipped += 1) {
27452
- const skippedIteration = await iterator.next();
27453
- if (typeof skippedIteration !== "object" || skippedIteration === null) {
27454
- throw new TypeError("Iterator result must be an object.");
27455
- }
27456
- if (skippedIteration.done) {
27457
- return normalEmptyResult();
27458
- }
27459
- }
27460
- while (true) {
27461
- const iteration = restoredEntry ?? await iterator.next();
27462
- restoredEntry = void 0;
27463
- if (typeof iteration !== "object" || iteration === null) {
27464
- throw new TypeError("Iterator result must be an object.");
27465
- }
27466
- if (iteration.done) {
27467
- context.activeLoopIterations.delete(nodeId);
27468
- return normalEmptyResult();
27469
- }
27470
- context.activeLoopIterations.set(
27471
- nodeId,
27472
- iterator.snapshotIndex === void 0 ? index : {
27473
- get index() {
27474
- return iterator.snapshotIndex();
27475
- },
27476
- values: [value, iteration.value]
27770
+ const releaseIterator = retainValues(context.budget, () => [value, iterator.retainedValue]);
27771
+ try {
27772
+ const nodeId = node.nodeId ?? -1;
27773
+ let index = consumeRestoredLoopIterationIndex(node, context);
27774
+ for (let skipped = 0; skipped < index; skipped += 1) {
27775
+ const skippedIteration = await iterator.next();
27776
+ if (typeof skippedIteration !== "object" || skippedIteration === null) {
27777
+ throw new TypeError("Iterator result must be an object.");
27778
+ }
27779
+ if (skippedIteration.done) {
27780
+ return normalEmptyResult();
27477
27781
  }
27478
- );
27479
- const scope = context.scope.child();
27480
- const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
27481
- if (!binding.ok) {
27482
- return binding.result;
27483
- }
27484
- const iterationContext = createLoopIterationContext(context, scope);
27485
- emitLoopIterationBreakpoint(node, iterationContext);
27486
- const result = await evaluateNode(node.body, iterationContext);
27487
- if (isMatchingBreak(result, loopLabels(node))) {
27488
- context.activeLoopIterations.delete(nodeId);
27489
- await closeIterator(iterator);
27490
- return normalEmptyResult();
27491
27782
  }
27492
- if (isMatchingContinue(result, loopLabels(node))) {
27783
+ while (true) {
27784
+ const iteration = restoredEntry ?? await iterator.next();
27785
+ restoredEntry = void 0;
27786
+ if (typeof iteration !== "object" || iteration === null) {
27787
+ throw new TypeError("Iterator result must be an object.");
27788
+ }
27789
+ if (iteration.done) {
27790
+ context.activeLoopIterations.delete(nodeId);
27791
+ return normalEmptyResult();
27792
+ }
27793
+ context.activeLoopIterations.set(
27794
+ nodeId,
27795
+ iterator.snapshotIndex === void 0 ? index : {
27796
+ get index() {
27797
+ return iterator.snapshotIndex();
27798
+ },
27799
+ values: [value, iteration.value]
27800
+ }
27801
+ );
27802
+ const scope = context.scope.child();
27803
+ const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
27804
+ if (!binding.ok) {
27805
+ return binding.result;
27806
+ }
27807
+ const iterationContext = createLoopIterationContext(context, scope);
27808
+ emitLoopIterationBreakpoint(node, iterationContext);
27809
+ const result = await evaluateNode(node.body, iterationContext);
27810
+ if (isMatchingBreak(result, loopLabels(node))) {
27811
+ context.activeLoopIterations.delete(nodeId);
27812
+ await closeIterator(iterator);
27813
+ return normalEmptyResult();
27814
+ }
27815
+ if (isMatchingContinue(result, loopLabels(node))) {
27816
+ index += 1;
27817
+ continue;
27818
+ }
27819
+ if (result.kind !== "normal") {
27820
+ context.activeLoopIterations.delete(nodeId);
27821
+ await closeIterator(iterator);
27822
+ return result;
27823
+ }
27493
27824
  index += 1;
27494
- continue;
27495
27825
  }
27496
- if (result.kind !== "normal") {
27497
- context.activeLoopIterations.delete(nodeId);
27498
- await closeIterator(iterator);
27499
- return result;
27500
- }
27501
- index += 1;
27826
+ } finally {
27827
+ releaseIterator();
27502
27828
  }
27503
27829
  }
27504
27830
  async function evaluateForInStatement(node, context) {
@@ -27868,52 +28194,64 @@ async function evaluateYieldDelegate(node, context) {
27868
28194
  if (argument.kind !== "normal") {
27869
28195
  return argument;
27870
28196
  }
27871
- const iterator = getSandboxIterator(argument.value, context.budget);
28197
+ const iterator = getSandboxIterator(
28198
+ argument.value,
28199
+ context.budget,
28200
+ createCoercionContext(context)
28201
+ );
27872
28202
  if (iterator === void 0) {
27873
28203
  throw new TypeError(`${String(argument.value)} is not a supported iterable`);
27874
28204
  }
27875
- let completion = {
27876
- type: "normal",
27877
- value: void 0
27878
- };
27879
- const replay = context.generatorResume?.sent ?? [];
27880
- let replayIndex = 0;
27881
- while (true) {
27882
- const method = completion.type === "normal" ? "next" : completion.type;
27883
- const iteratorMethod = iterator[method];
27884
- if (iteratorMethod === void 0) {
27885
- if (completion.type === "throw") {
27886
- throw completion.value;
28205
+ const releaseIterator = retainValues(context.budget, () => [
28206
+ argument.value,
28207
+ iterator.retainedValue
28208
+ ]);
28209
+ try {
28210
+ let completion = {
28211
+ type: "normal",
28212
+ value: void 0
28213
+ };
28214
+ const replay = context.generatorResume?.sent ?? [];
28215
+ let replayIndex = 0;
28216
+ while (true) {
28217
+ const method = completion.type === "normal" ? "next" : completion.type;
28218
+ const iteratorMethod = iterator[method];
28219
+ if (iteratorMethod === void 0) {
28220
+ if (completion.type === "throw") {
28221
+ throw completion.value;
28222
+ }
28223
+ return generatorCompletionResult(completion);
27887
28224
  }
27888
- return generatorCompletionResult(completion);
27889
- }
27890
- const result = await iteratorMethod(completion.value);
27891
- if (result.done) {
27892
- if (completion.type === "return") {
27893
- return generatorCompletionResult({ type: "return", value: result.value });
28225
+ const result = await iteratorMethod(completion.value);
28226
+ if (result.done) {
28227
+ if (completion.type === "return") {
28228
+ return generatorCompletionResult({ type: "return", value: result.value });
28229
+ }
28230
+ return {
28231
+ kind: "normal",
28232
+ hasValue: true,
28233
+ value: result.value
28234
+ };
27894
28235
  }
27895
- return {
27896
- kind: "normal",
27897
- hasValue: true,
27898
- value: result.value
27899
- };
27900
- }
27901
- if (replayIndex < replay.length - 1) {
27902
- completion = replay[replayIndex + 1];
27903
- replayIndex += 1;
27904
- continue;
28236
+ if (replayIndex < replay.length - 1) {
28237
+ completion = replay[replayIndex + 1];
28238
+ replayIndex += 1;
28239
+ continue;
28240
+ }
28241
+ const completionPromise = context.generatorYield(
28242
+ allocateProducedSandboxValue(result.value, context.budget),
28243
+ node.nodeId
28244
+ );
28245
+ emitResumeBreakpoint(context, {
28246
+ kind: "generator-yield",
28247
+ nodeId: node.nodeId,
28248
+ span: node.span
28249
+ });
28250
+ completion = await completionPromise;
28251
+ context.generatorResume = void 0;
27905
28252
  }
27906
- const completionPromise = context.generatorYield(
27907
- allocateProducedSandboxValue(result.value, context.budget),
27908
- node.nodeId
27909
- );
27910
- emitResumeBreakpoint(context, {
27911
- kind: "generator-yield",
27912
- nodeId: node.nodeId,
27913
- span: node.span
27914
- });
27915
- completion = await completionPromise;
27916
- context.generatorResume = void 0;
28253
+ } finally {
28254
+ releaseIterator();
27917
28255
  }
27918
28256
  }
27919
28257
  function generatorCompletionResult(completion) {
@@ -28060,6 +28398,14 @@ async function evaluateMemberExpression(node, context) {
28060
28398
  }
28061
28399
  function getPropertyValue(target, property, context) {
28062
28400
  if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
28401
+ if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
28402
+ const prototype = getBoxedPrototype(target, context.budget);
28403
+ if (prototype !== void 0) {
28404
+ if (typeof target === "string" && (property === "length" || getStringIndex(property) !== void 0))
28405
+ return getStringMember(target, property, context.budget);
28406
+ return getMemberValue(prototype, property, context);
28407
+ }
28408
+ }
28063
28409
  if (typeof target === "string") return getStringMember(target, property, context.budget);
28064
28410
  if (typeof target === "number") return getNumberMember(property, context.budget);
28065
28411
  if (typeof target === "boolean") return void 0;
@@ -28231,6 +28577,15 @@ async function evaluateMemberCallExpression(node, context) {
28231
28577
  ...reference,
28232
28578
  property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
28233
28579
  };
28580
+ if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") && getBoxedPrototype(member.object, context.budget) !== void 0) {
28581
+ if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
28582
+ if (typeof member.object === "string" && isStringMethodName(member.property))
28583
+ return evaluateStringMethodCall(node, member.object, member.property, context);
28584
+ if (typeof member.object === "number" && isNumberMethodName(member.property))
28585
+ return evaluateNumberMethodCall(node, member.object, member.property, context);
28586
+ }
28587
+ return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
28588
+ }
28234
28589
  if (typeof member.object === "string" && isStringMethodName(member.property)) {
28235
28590
  return evaluateStringMethodCall(node, member.object, member.property, context);
28236
28591
  }
@@ -28592,33 +28947,41 @@ function hasSandboxProperty(value, key, context) {
28592
28947
  return false;
28593
28948
  }
28594
28949
  async function applyCompoundAssignmentOperator(operator, left, right, context) {
28595
- left = await toNumericPrimitive(left, context);
28596
- right = await toNumericPrimitive(right, context);
28597
- switch (operator) {
28598
- case "+=":
28599
- return applyAdditionOperator(left, right, context);
28600
- case "-=":
28601
- return toNumber(left) - toNumber(right);
28602
- case "*=":
28603
- return toNumber(left) * toNumber(right);
28604
- case "/=":
28605
- return toNumber(left) / toNumber(right);
28606
- case "%=":
28607
- return toNumber(left) % toNumber(right);
28608
- case "**=":
28609
- return toNumber(left) ** toNumber(right);
28610
- case "&=":
28611
- return toNumber(left) & toNumber(right);
28612
- case "|=":
28613
- return toNumber(left) | toNumber(right);
28614
- case "^=":
28615
- return toNumber(left) ^ toNumber(right);
28616
- case "<<=":
28617
- return toNumber(left) << toNumber(right);
28618
- case ">>=":
28619
- return toNumber(left) >> toNumber(right);
28620
- case ">>>=":
28621
- return toNumber(left) >>> toNumber(right);
28950
+ const convertingObject = typeof left === "object" && left !== null;
28951
+ let convertedLeft;
28952
+ const release = retainValues(context.budget, () => [convertedLeft]);
28953
+ try {
28954
+ left = await toNumericPrimitive(left, context);
28955
+ if (convertingObject) convertedLeft = left;
28956
+ right = await toNumericPrimitive(right, context);
28957
+ switch (operator) {
28958
+ case "+=":
28959
+ return applyAdditionOperator(left, right, context);
28960
+ case "-=":
28961
+ return toNumber(left) - toNumber(right);
28962
+ case "*=":
28963
+ return toNumber(left) * toNumber(right);
28964
+ case "/=":
28965
+ return toNumber(left) / toNumber(right);
28966
+ case "%=":
28967
+ return toNumber(left) % toNumber(right);
28968
+ case "**=":
28969
+ return toNumber(left) ** toNumber(right);
28970
+ case "&=":
28971
+ return toNumber(left) & toNumber(right);
28972
+ case "|=":
28973
+ return toNumber(left) | toNumber(right);
28974
+ case "^=":
28975
+ return toNumber(left) ^ toNumber(right);
28976
+ case "<<=":
28977
+ return toNumber(left) << toNumber(right);
28978
+ case ">>=":
28979
+ return toNumber(left) >> toNumber(right);
28980
+ case ">>>=":
28981
+ return toNumber(left) >>> toNumber(right);
28982
+ }
28983
+ } finally {
28984
+ release();
28622
28985
  }
28623
28986
  }
28624
28987
  function applyAdditionOperator(left, right, context) {
@@ -28938,6 +29301,7 @@ function createSetMethodOptions(context) {
28938
29301
  }
28939
29302
  function createFunctionMethodOptions(context) {
28940
29303
  return {
29304
+ budget: context.budget,
28941
29305
  callClosure: (closure, args, stack, thisValue, construct) => invokeSandboxClosure(closure, args, context, stack, void 0, thisValue, construct)
28942
29306
  };
28943
29307
  }
@@ -29014,12 +29378,12 @@ async function evaluateSpreadElement(node, context) {
29014
29378
  result: value
29015
29379
  };
29016
29380
  }
29017
- const iterator = getSandboxIterator(value.value, context.budget);
29381
+ const iterator = getSandboxIterator(value.value, context.budget, createCoercionContext(context));
29018
29382
  if (iterator === void 0) {
29019
29383
  throw new TypeError("Spread arguments must evaluate to an iterable.");
29020
29384
  }
29021
29385
  const spreadValues = [];
29022
- const release = retainValues(context.budget, () => [value.value, ...spreadValues]);
29386
+ const release = retainValues(context.budget, () => [value.value, iterator.retainedValue, ...spreadValues]);
29023
29387
  try {
29024
29388
  while (true) {
29025
29389
  const next = await iterator.next();
@@ -29175,6 +29539,7 @@ function createInterpretedClosure(node, context, evaluateNode2) {
29175
29539
  return isConstructResult(result) ? result : thisValue;
29176
29540
  } : void 0;
29177
29541
  const closure = createSandboxClosure({
29542
+ sourceRange: functionSources.get(node),
29178
29543
  guest: true,
29179
29544
  sandbox: true,
29180
29545
  length: getFunctionLength(node.params),
@@ -29237,6 +29602,7 @@ function executeAsyncFunction(execute, budget, signal) {
29237
29602
  }
29238
29603
  function createGeneratorClosure(node, context, evaluateNode2) {
29239
29604
  return createSandboxClosure({
29605
+ sourceRange: functionSources.get(node),
29240
29606
  guest: true,
29241
29607
  generator: true,
29242
29608
  sandbox: true,
@@ -30097,6 +30463,30 @@ function copyHostValueToSandbox(value, stackFrames, options, state, path) {
30097
30463
  state
30098
30464
  );
30099
30465
  }
30466
+ const primitive = nativeBoxedValue(value);
30467
+ if (primitive !== void 0) {
30468
+ if (typeof primitive === "string") budget.allocateString(primitive);
30469
+ const original = value;
30470
+ const existing = state.seen.get(original);
30471
+ if (existing !== void 0) return existing;
30472
+ const copy = createSandboxBox(primitive);
30473
+ state.seen.set(original, copy);
30474
+ budget.chargeDataUsage(measureSandboxData([copy]));
30475
+ for (const [key, descriptor] of boxedDataProperties(original)) {
30476
+ if (!("value" in descriptor)) throw new TypeError(`Unsupported sandbox value at ${joinPath2(path, key)}: accessor property`);
30477
+ Object.defineProperty(copy, budget.allocateString(key), {
30478
+ ...descriptor,
30479
+ value: copyHostValueToSandbox(
30480
+ descriptor.value,
30481
+ stackFrames,
30482
+ { ...options, capabilityPath: [...options.capabilityPath ?? [], key] },
30483
+ state,
30484
+ joinPath2(path, key)
30485
+ )
30486
+ });
30487
+ }
30488
+ return copy;
30489
+ }
30100
30490
  const date = copyNativeDate(value);
30101
30491
  if (date !== void 0) {
30102
30492
  const existing = state.seen.get(value);
@@ -30506,7 +30896,7 @@ function createReplayableRandom(options = {}) {
30506
30896
 
30507
30897
  // packages/safe-js/src/realm.ts
30508
30898
  import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
30509
- import { types as types5 } from "node:util";
30899
+ import { types as types6 } from "node:util";
30510
30900
 
30511
30901
  // packages/safe-js/src/interp/globals/console-json.ts
30512
30902
  function createConsoleJsonGlobals(options) {
@@ -30515,12 +30905,18 @@ function createConsoleJsonGlobals(options) {
30515
30905
  JSON: {
30516
30906
  parse: createSandboxClosure({
30517
30907
  sandbox: true,
30518
- call: async ([text]) => parseJson(text, options.budget),
30908
+ call: async ([text], context) => {
30909
+ const converted = sandboxString(text, options.budget, context);
30910
+ return copyJsonToSandbox(
30911
+ JSON.parse(converted instanceof Promise ? await converted : converted),
30912
+ options.budget
30913
+ );
30914
+ },
30519
30915
  name: "parse"
30520
30916
  }),
30521
30917
  stringify: createSandboxClosure({
30522
30918
  sandbox: true,
30523
- call: async ([value, replacer, indent]) => stringifyJson(value, replacer, indent, options.budget),
30919
+ call: async ([value, replacer, indent], context) => stringifyJson(value, replacer, indent, options.budget, context),
30524
30920
  name: "stringify"
30525
30921
  })
30526
30922
  },
@@ -30581,11 +30977,7 @@ function createConsoleJsonGlobals(options) {
30581
30977
  )
30582
30978
  };
30583
30979
  }
30584
- function parseJson(input, budget) {
30585
- const text = budget.allocateString(toJsonParseText(input));
30586
- return copyJsonToSandbox(JSON.parse(text), budget);
30587
- }
30588
- async function stringifyJson(value, replacer, indent, budget) {
30980
+ async function stringifyJson(value, replacer, indent, budget, context) {
30589
30981
  if (replacer !== void 0 && replacer !== null && !isSandboxClosure(replacer)) {
30590
30982
  throw new TypeError(
30591
30983
  "JSON.stringify(value, replacer, indent) only supports function, null, or undefined replacers."
@@ -30600,6 +30992,7 @@ async function stringifyJson(value, replacer, indent, budget) {
30600
30992
  defineDataProperty(holder, "", value);
30601
30993
  const output = await stringifyProperty("", holder, {
30602
30994
  budget,
30995
+ context,
30603
30996
  gap: normalizeStringifyGap(indent),
30604
30997
  replacer: isSandboxClosure(replacer) ? replacer : void 0,
30605
30998
  stack: []
@@ -30609,15 +31002,6 @@ async function stringifyJson(value, replacer, indent, budget) {
30609
31002
  }
30610
31003
  return budget.allocateString(output);
30611
31004
  }
30612
- function toJsonParseText(input) {
30613
- if (Array.isArray(input)) {
30614
- return input.map((entry) => entry === null || entry === void 0 ? "" : toJsonParseText(entry)).join(",");
30615
- }
30616
- if (typeof input === "object" && input !== null) {
30617
- return "[object Object]";
30618
- }
30619
- return String(input);
30620
- }
30621
31005
  async function stringifyProperty(key, holder, state, indent = "") {
30622
31006
  let value = getOwnDataValue(holder, key);
30623
31007
  if (isSandboxDate(value)) {
@@ -30634,6 +31018,10 @@ async function stringifyProperty(key, holder, state, indent = "") {
30634
31018
  return stringifyValue(value, state, indent);
30635
31019
  }
30636
31020
  async function stringifyValue(value, state, indent) {
31021
+ if (isSandboxBox(value)) {
31022
+ const primitive = boxedValue(value);
31023
+ value = typeof primitive === "number" ? await sandboxNumber(value, state.budget, state.context) : typeof primitive === "string" ? await sandboxString(value, state.budget, state.context) : primitive;
31024
+ }
30637
31025
  if (value === null) {
30638
31026
  return "null";
30639
31027
  }
@@ -30847,6 +31235,46 @@ function createRegexGlobals(options) {
30847
31235
  };
30848
31236
  }
30849
31237
 
31238
+ // packages/safe-js/src/interp/globals/numeric-parsers.ts
31239
+ function createNumericParsers(budget) {
31240
+ return {
31241
+ parseInt: createSandboxClosure({
31242
+ sandbox: true,
31243
+ name: "parseInt",
31244
+ call: ([value, radix], context) => {
31245
+ const parse2 = (text2) => {
31246
+ const release = retainValues(budget, () => [text2]);
31247
+ let convertedRadix;
31248
+ try {
31249
+ convertedRadix = sandboxNumber(radix, budget, context);
31250
+ } catch (error) {
31251
+ release();
31252
+ throw error;
31253
+ }
31254
+ if (typeof convertedRadix === "number") {
31255
+ try {
31256
+ return globalThis.parseInt(text2, convertedRadix);
31257
+ } finally {
31258
+ release();
31259
+ }
31260
+ }
31261
+ return convertedRadix.then((number) => globalThis.parseInt(text2, number)).finally(release);
31262
+ };
31263
+ const text = sandboxString(value, budget, context);
31264
+ return typeof text === "string" ? parse2(text) : text.then(parse2);
31265
+ }
31266
+ }),
31267
+ parseFloat: createSandboxClosure({
31268
+ sandbox: true,
31269
+ name: "parseFloat",
31270
+ call: ([value], context) => {
31271
+ const text = sandboxString(value, budget, context);
31272
+ return typeof text === "string" ? globalThis.parseFloat(text) : text.then(globalThis.parseFloat);
31273
+ }
31274
+ })
31275
+ };
31276
+ }
31277
+
30850
31278
  // packages/safe-js/src/interp/globals/misc.ts
30851
31279
  function createMiscGlobals(options) {
30852
31280
  return {
@@ -30855,24 +31283,21 @@ function createMiscGlobals(options) {
30855
31283
  call: ([value], context) => structuredCloneSandboxValue(value, options.budget, context?.compilation),
30856
31284
  name: "structuredClone"
30857
31285
  }),
30858
- parseInt: createSandboxClosure({
30859
- sandbox: true,
30860
- call: (args) => Reflect.apply(globalThis.parseInt, globalThis, [...args]),
30861
- name: "parseInt"
30862
- }),
30863
- parseFloat: createSandboxClosure({
30864
- sandbox: true,
30865
- call: (args) => Reflect.apply(globalThis.parseFloat, globalThis, [...args]),
30866
- name: "parseFloat"
30867
- }),
31286
+ ...createNumericParsers(options.budget),
30868
31287
  isNaN: createSandboxClosure({
30869
31288
  sandbox: true,
30870
- call: ([value]) => globalThis.isNaN(value),
31289
+ call: ([value], context) => {
31290
+ const number = sandboxNumber(value, options.budget, context);
31291
+ return typeof number === "number" ? Number.isNaN(number) : number.then(Number.isNaN);
31292
+ },
30871
31293
  name: "isNaN"
30872
31294
  }),
30873
31295
  isFinite: createSandboxClosure({
30874
31296
  sandbox: true,
30875
- call: ([value]) => globalThis.isFinite(value),
31297
+ call: ([value], context) => {
31298
+ const number = sandboxNumber(value, options.budget, context);
31299
+ return typeof number === "number" ? Number.isFinite(number) : number.then(Number.isFinite);
31300
+ },
30876
31301
  name: "isFinite"
30877
31302
  })
30878
31303
  };
@@ -30881,7 +31306,7 @@ function structuredCloneSandboxValue(value, budget, parent) {
30881
31306
  const operation = budget.acquireCompileOwner(false, parent?.owner);
30882
31307
  const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
30883
31308
  try {
30884
- const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
31309
+ const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true, structuredClone: true });
30885
31310
  assertSandboxGraphDepth(clone);
30886
31311
  assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
30887
31312
  allocateProducedSandboxValue(clone, budget);
@@ -30918,6 +31343,72 @@ function assertStructuredCloneable(value, seen) {
30918
31343
  }
30919
31344
  }
30920
31345
 
31346
+ // packages/safe-js/src/interp/globals/primitives.ts
31347
+ function createPrimitiveConstructor(options, budget) {
31348
+ const initial = { Number: 0, String: "", Boolean: false }[options.name];
31349
+ const kind = typeof initial;
31350
+ const prototype = createSandboxBox(initial);
31351
+ const allocate = (value) => {
31352
+ const box = createSandboxBox(value);
31353
+ budget.chargeDataUsage(measureSandboxData([box]));
31354
+ return box;
31355
+ };
31356
+ const constructor = createSandboxClosure({
31357
+ guest: true,
31358
+ sandbox: true,
31359
+ name: options.name,
31360
+ length: 1,
31361
+ call: options.call,
31362
+ construct: (args, context) => {
31363
+ const value = options.call(args, context);
31364
+ return value instanceof Promise ? value.then(allocate) : allocate(value);
31365
+ }
31366
+ });
31367
+ const properties = materializeFunctionProperties(constructor);
31368
+ Object.defineProperty(properties, "prototype", { value: prototype, writable: false });
31369
+ Object.defineProperty(prototype, "constructor", {
31370
+ value: constructor,
31371
+ writable: true,
31372
+ configurable: true
31373
+ });
31374
+ for (const [name, value] of Object.entries(options.properties ?? {}))
31375
+ Object.defineProperty(properties, name, {
31376
+ value,
31377
+ writable: isSandboxClosure(value),
31378
+ configurable: isSandboxClosure(value)
31379
+ });
31380
+ const methods = /* @__PURE__ */ new Map([
31381
+ [
31382
+ "valueOf",
31383
+ createSandboxClosure({
31384
+ sandbox: true,
31385
+ name: "valueOf",
31386
+ length: 0,
31387
+ call: (_args, context) => primitiveReceiver(context?.thisValue, kind)
31388
+ })
31389
+ ]
31390
+ ]);
31391
+ if (kind === "number") {
31392
+ for (const name of numberMethodNames) methods.set(name, getNumberMember(name, budget));
31393
+ } else {
31394
+ methods.set(
31395
+ "toString",
31396
+ createSandboxClosure({
31397
+ sandbox: true,
31398
+ name: "toString",
31399
+ length: 0,
31400
+ call: (_args, context) => budget.allocateString(String(primitiveReceiver(context?.thisValue, kind)))
31401
+ })
31402
+ );
31403
+ if (kind === "string")
31404
+ for (const name of stringMethodNames) methods.set(name, getStringMember("", name, budget));
31405
+ }
31406
+ for (const [name, value] of methods)
31407
+ Object.defineProperty(prototype, name, { value, writable: true, configurable: true });
31408
+ installBoxedPrototype(budget, prototype, constructor);
31409
+ return constructor;
31410
+ }
31411
+
30921
31412
  // packages/safe-js/src/interp/globals/object-array.ts
30922
31413
  function createObjectArrayGlobals(options) {
30923
31414
  return {
@@ -30983,6 +31474,7 @@ function createObjectArrayGlobals(options) {
30983
31474
  sandbox: true,
30984
31475
  call: ([value]) => {
30985
31476
  if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
31477
+ if (value !== null && value !== void 0 && typeof value !== "object") value = createSandboxBox(value);
30986
31478
  objectProperties(value);
30987
31479
  return getSandboxPrototype(value, options.budget);
30988
31480
  },
@@ -31022,11 +31514,11 @@ function createObjectArrayGlobals(options) {
31022
31514
  fromEntries: createSandboxClosure({
31023
31515
  sandbox: true,
31024
31516
  call: ([value], context) => {
31025
- const iterator = getSandboxIterator(value, options.budget);
31517
+ const iterator = getSandboxIterator(value, options.budget, context);
31026
31518
  if (iterator === void 0) {
31027
31519
  throw new TypeError("Object.fromEntries requires an iterable.");
31028
31520
  }
31029
- if (context === void 0 && !iterator.generator) {
31521
+ if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
31030
31522
  return allocateProducedSandboxValue(
31031
31523
  Object.setPrototypeOf(
31032
31524
  Reflect.apply(Object.fromEntries, Object, [{ [Symbol.iterator]: () => iterator }]),
@@ -31084,8 +31576,7 @@ function createObjectArrayGlobals(options) {
31084
31576
  })
31085
31577
  }
31086
31578
  }),
31087
- String: createSandboxClosure({
31088
- sandbox: true,
31579
+ String: createPrimitiveConstructor({
31089
31580
  call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
31090
31581
  name: "String",
31091
31582
  properties: {
@@ -31105,9 +31596,8 @@ function createObjectArrayGlobals(options) {
31105
31596
  name: "fromCodePoint"
31106
31597
  })
31107
31598
  }
31108
- }),
31109
- Number: createSandboxClosure({
31110
- sandbox: true,
31599
+ }, options.budget),
31600
+ Number: createPrimitiveConstructor({
31111
31601
  call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
31112
31602
  name: "Number",
31113
31603
  properties: {
@@ -31126,16 +31616,7 @@ function createObjectArrayGlobals(options) {
31126
31616
  call: ([value]) => typeof value === "number" && Number.isInteger(value),
31127
31617
  name: "isInteger"
31128
31618
  }),
31129
- parseInt: createSandboxClosure({
31130
- sandbox: true,
31131
- call: (args) => Reflect.apply(Number.parseInt, Number, [...args]),
31132
- name: "parseInt"
31133
- }),
31134
- parseFloat: createSandboxClosure({
31135
- sandbox: true,
31136
- call: (args) => Reflect.apply(Number.parseFloat, Number, [...args]),
31137
- name: "parseFloat"
31138
- }),
31619
+ ...createNumericParsers(options.budget),
31139
31620
  isSafeInteger: createSandboxClosure({
31140
31621
  sandbox: true,
31141
31622
  call: ([value]) => typeof value === "number" && Number.isSafeInteger(value),
@@ -31150,12 +31631,11 @@ function createObjectArrayGlobals(options) {
31150
31631
  NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
31151
31632
  POSITIVE_INFINITY: Number.POSITIVE_INFINITY
31152
31633
  }
31153
- }),
31154
- Boolean: createSandboxClosure({
31155
- sandbox: true,
31634
+ }, options.budget),
31635
+ Boolean: createPrimitiveConstructor({
31156
31636
  call: ([value]) => Boolean(value),
31157
31637
  name: "Boolean"
31158
- })
31638
+ }, options.budget)
31159
31639
  };
31160
31640
  }
31161
31641
  async function objectFromSandboxEntries(items, iterator, budget, context) {
@@ -31165,7 +31645,7 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
31165
31645
  let value;
31166
31646
  let failure;
31167
31647
  const retained = {};
31168
- budget.setRetainedValues(retained, () => [items, object, entry, key, value, failure]);
31648
+ budget.setRetainedValues(retained, () => [items, iterator.retainedValue, object, entry, key, value, failure]);
31169
31649
  const checkData = createDataCheckpoint(budget, context);
31170
31650
  const closeOnThrow = async (error) => {
31171
31651
  failure = isCapturedException(error) ? error.reason : error;
@@ -31216,6 +31696,10 @@ function assignSandboxValues(target, sources, budget) {
31216
31696
  if (target === null || target === void 0) {
31217
31697
  throw new TypeError("Object.assign(target, ...sources) requires a non-null target.");
31218
31698
  }
31699
+ if (typeof target !== "object") {
31700
+ target = createSandboxBox(target);
31701
+ budget.chargeDataUsage(measureSandboxData([target]));
31702
+ }
31219
31703
  if (!isGuestClosure(target) && !isAssignableSandboxTarget(target)) {
31220
31704
  throw new TypeError("Object.assign(target, ...sources) requires an object or array target.");
31221
31705
  }
@@ -31285,13 +31769,13 @@ async function arrayFromSandboxValues(args, budget, context) {
31285
31769
  throw new TypeError("Array.from requires a non-null input.");
31286
31770
  }
31287
31771
  const read = (property) => context?.getProperty !== void 0 ? context.getProperty(items, property) : getSandboxDataProperty(items, property, budget);
31288
- const iterator = getSandboxIterator(items, budget);
31772
+ const iterator = getSandboxIterator(items, budget, context);
31289
31773
  const constructor = context?.thisValue;
31290
31774
  let result;
31291
31775
  let currentValue;
31292
31776
  let failure;
31293
31777
  const retained = {};
31294
- budget.setRetainedValues(retained, () => [items, mapFn, constructor, result, currentValue, failure]);
31778
+ budget.setRetainedValues(retained, () => [items, iterator?.retainedValue, mapFn, constructor, result, currentValue, failure]);
31295
31779
  const checkData = createDataCheckpoint(budget, context);
31296
31780
  const closeOnThrow = async (error) => {
31297
31781
  failure = isCapturedException(error) ? error.reason : error;
@@ -31550,7 +32034,7 @@ var RealmState = class {
31550
32034
  throw new TypeError("Realm limits must be positive safe integers with supported names.");
31551
32035
  this.limits[name] = Number(value);
31552
32036
  }
31553
- if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types5.isProxy(options.extensions)))
32037
+ if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types6.isProxy(options.extensions)))
31554
32038
  throw new TypeError("Extensions must be a registration array.");
31555
32039
  const registrations = options.extensions ?? [];
31556
32040
  const extensions = [];
@@ -31785,7 +32269,7 @@ var RealmState = class {
31785
32269
  return this.phase.run(phase, () => {
31786
32270
  try {
31787
32271
  const result = call();
31788
- if (types5.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
32272
+ if (types6.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
31789
32273
  return Promise.resolve(result).then(
31790
32274
  async (value) => {
31791
32275
  await Promise.allSettled(phase.pending);
@@ -31854,7 +32338,7 @@ var RealmState = class {
31854
32338
  },
31855
32339
  read: (operation, validate) => {
31856
32340
  const value = this.invokeHost(operation, operation);
31857
- if (types5.isPromise(value)) {
32341
+ if (types6.isPromise(value)) {
31858
32342
  void Promise.resolve(value).catch(() => void 0);
31859
32343
  throw new TypeError("Live property operations must be synchronous.");
31860
32344
  }
@@ -31862,7 +32346,7 @@ var RealmState = class {
31862
32346
  },
31863
32347
  write: (operation, value) => {
31864
32348
  const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
31865
- if (types5.isPromise(result)) {
32349
+ if (types6.isPromise(result)) {
31866
32350
  void Promise.resolve(result).catch(() => void 0);
31867
32351
  throw new TypeError("Live property setters must be synchronous.");
31868
32352
  }
@@ -32071,7 +32555,7 @@ var RealmState = class {
32071
32555
  }
32072
32556
  });
32073
32557
  const output = getExtensionSetup(extension)(context);
32074
- if (types5.isPromise(output)) {
32558
+ if (types6.isPromise(output)) {
32075
32559
  void Promise.resolve(output).catch(() => void 0);
32076
32560
  throw new TypeError("Extension setup must be synchronous.");
32077
32561
  }
@@ -32263,7 +32747,7 @@ var RealmState = class {
32263
32747
  };
32264
32748
  function readModules(input) {
32265
32749
  const entries = (value, label) => {
32266
- if (types5.isMap(value) && !types5.isProxy(value)) {
32750
+ if (types6.isMap(value) && !types6.isProxy(value)) {
32267
32751
  const result = [...Map.prototype.entries.call(value)];
32268
32752
  if (result.length > 4096 || result.some(([key]) => typeof key !== "string" || key.length === 0))
32269
32753
  throw new TypeError(`${label} requires bounded string keys.`);
@@ -32961,7 +33445,8 @@ function run(source, options = {}) {
32961
33445
  options.signal?.addEventListener("abort", captureCancellationSnapshot, { once: true });
32962
33446
  try {
32963
33447
  const restoredSnapshot = options.snapshot === void 0 ? void 0 : restore(options.snapshot, { source }, operation.owner);
32964
- const executionSemantics = restoredSnapshot?.executionSemantics === "jobs-v6" ? "jobs-v6" : EXECUTION_SEMANTICS;
33448
+ const executionSemantics = restoredSnapshot?.executionSemantics === "jobs-v6" || restoredSnapshot?.executionSemantics === "jobs-v7" ? restoredSnapshot.executionSemantics : EXECUTION_SEMANTICS;
33449
+ runResources.getStore().functionSourceText = executionSemantics === EXECUTION_SEMANTICS;
32965
33450
  const convertInitialInput = (convert) => executionSemantics === "jobs-v6" ? convert() : promiseReplayContext.exit(convert);
32966
33451
  if (restoredSnapshot !== void 0) {
32967
33452
  leaveSnapshotRun = enterSnapshotRun(restoredSnapshot);
@@ -32970,7 +33455,7 @@ function run(source, options = {}) {
32970
33455
  const filename = options.filename ?? "<input>";
32971
33456
  const module = parseExecutableModule(source, filename, operation.owner);
32972
33457
  promiseReplay.validateNodes(module);
32973
- const sourceHash = findRegexLiteral(module) === void 0 ? hashSource(source, operation.owner) : hashParsedAst(module);
33458
+ const sourceHash = findRegexLiteral(module) === void 0 ? hashSource(source, operation.owner, executionSemantics === EXECUTION_SEMANTICS) : hashParsedAst(module, executionSemantics === EXECUTION_SEMANTICS);
32974
33459
  const hostCalls = new HostCallJournal(
32975
33460
  sourceHash,
32976
33461
  readHostCallSnapshot(restoredSnapshot),
@@ -32997,7 +33482,14 @@ function run(source, options = {}) {
32997
33482
  lifecycle
32998
33483
  })
32999
33484
  );
33000
- const builtinBindings = createBuiltinBindings({ compileOwner: operation.owner, budget, hostCalls, sink: options.sink, random: random?.generator.next, clock: options.clock });
33485
+ const builtinBindings = createBuiltinBindings({
33486
+ compileOwner: operation.owner,
33487
+ budget,
33488
+ hostCalls,
33489
+ sink: options.sink,
33490
+ random: random?.generator.next,
33491
+ clock: options.clock
33492
+ });
33001
33493
  const importMeta = convertInitialInput(
33002
33494
  () => deepCopyToSandbox(options.importMeta ?? {})
33003
33495
  );
@@ -33500,4 +33992,4 @@ export {
33500
33992
  FileSnapshotBackend,
33501
33993
  run
33502
33994
  };
33503
- //# sourceMappingURL=chunk-ZTGKRKQH.js.map
33995
+ //# sourceMappingURL=chunk-RU2BCN4G.js.map