poe-code 14.0.62 → 14.0.64

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 (49) hide show
  1. package/dist/index.js +977 -528
  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-F7TJSPDZ.js → chunk-3EXDJDQM.js} +2 -2
  6. package/packages/safe-js/dist/chunks/{chunk-VKGWGZBH.js → chunk-XO7B4P27.js} +945 -545
  7. package/packages/safe-js/dist/chunks/chunk-XO7B4P27.js.map +7 -0
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.js +1 -1
  10. package/packages/safe-js/dist/graph-depth.js +3 -0
  11. package/packages/safe-js/dist/index.js +2 -2
  12. package/packages/safe-js/dist/interp/boxed.d.ts +14 -0
  13. package/packages/safe-js/dist/interp/boxed.js +50 -0
  14. package/packages/safe-js/dist/interp/globals/collections.js +4 -4
  15. package/packages/safe-js/dist/interp/globals/console-json.js +15 -18
  16. package/packages/safe-js/dist/interp/globals/misc.js +1 -1
  17. package/packages/safe-js/dist/interp/globals/object-array.js +19 -14
  18. package/packages/safe-js/dist/interp/globals/object.js +10 -5
  19. package/packages/safe-js/dist/interp/globals/primitives.d.ts +8 -0
  20. package/packages/safe-js/dist/interp/globals/primitives.js +69 -0
  21. package/packages/safe-js/dist/interp/host-bridge.js +22 -0
  22. package/packages/safe-js/dist/interp/interpreter.js +175 -122
  23. package/packages/safe-js/dist/interp/iteration.d.ts +5 -3
  24. package/packages/safe-js/dist/interp/iteration.js +22 -1
  25. package/packages/safe-js/dist/interp/methods/array.js +6 -3
  26. package/packages/safe-js/dist/interp/methods/function.js +32 -15
  27. package/packages/safe-js/dist/interp/methods/number.d.ts +1 -0
  28. package/packages/safe-js/dist/interp/methods/number.js +4 -1
  29. package/packages/safe-js/dist/interp/methods/string.d.ts +2 -0
  30. package/packages/safe-js/dist/interp/methods/string.js +2 -2
  31. package/packages/safe-js/dist/interp/object-model.d.ts +5 -0
  32. package/packages/safe-js/dist/interp/object-model.js +66 -14
  33. package/packages/safe-js/dist/interp/promise.js +68 -61
  34. package/packages/safe-js/dist/interp/string-coercion.js +4 -1
  35. package/packages/safe-js/dist/interp/values.d.ts +1 -0
  36. package/packages/safe-js/dist/interp/values.js +78 -3
  37. package/packages/safe-js/dist/migrate.d.ts +2 -2
  38. package/packages/safe-js/dist/migration-file.d.ts +4 -4
  39. package/packages/safe-js/dist/snapshot/boxed.d.ts +16 -0
  40. package/packages/safe-js/dist/snapshot/boxed.js +52 -0
  41. package/packages/safe-js/dist/snapshot/dump-format.js +18 -5
  42. package/packages/safe-js/dist/snapshot/replay-data.d.ts +5 -0
  43. package/packages/safe-js/dist/snapshot/replay-data.js +24 -0
  44. package/packages/safe-js/dist/snapshot/restore.js +8 -0
  45. package/packages/safe-js/dist/snapshot/serialize.d.ts +4 -2
  46. package/packages/safe-js/dist/snapshot/serialize.js +18 -10
  47. package/packages/safe-js/dist/snapshot/validation.js +22 -1
  48. package/packages/safe-js/dist/chunks/chunk-VKGWGZBH.js.map +0 -7
  49. /package/packages/safe-js/dist/chunks/{chunk-F7TJSPDZ.js.map → chunk-3EXDJDQM.js.map} +0 -0
package/dist/index.js CHANGED
@@ -50271,8 +50271,8 @@ function assertNonNegativeInteger3(value, keyword) {
50271
50271
  }
50272
50272
  function validateSchemaObject(schema, dialect) {
50273
50273
  if (schema.type !== void 0) {
50274
- const types6 = Array.isArray(schema.type) ? schema.type : [schema.type];
50275
- if (types6.length === 0 || !types6.every((type) => typeof type === "string" && draftTypeSet.has(type)) || new Set(types6).size !== types6.length) {
50274
+ const types7 = Array.isArray(schema.type) ? schema.type : [schema.type];
50275
+ if (types7.length === 0 || !types7.every((type) => typeof type === "string" && draftTypeSet.has(type)) || new Set(types7).size !== types7.length) {
50276
50276
  throw new Error("type must be a JSON Schema type or a unique array of JSON Schema types.");
50277
50277
  }
50278
50278
  }
@@ -50991,9 +50991,9 @@ function evaluateValidationKeywords(node, schema, value, path193) {
50991
50991
  if (schema.nullable === true && value === null) {
50992
50992
  return results;
50993
50993
  }
50994
- const types6 = typeof schema.type === "string" ? [schema.type] : Array.isArray(schema.type) ? schema.type : [];
50995
- if (types6.length > 0 && !types6.some((type) => typeof type === "string" && typeMatches(type, value))) {
50996
- results.push(invalidResult(issue(path193, types6.join(","), value, `must be ${types6.join(",")}`)));
50994
+ const types7 = typeof schema.type === "string" ? [schema.type] : Array.isArray(schema.type) ? schema.type : [];
50995
+ if (types7.length > 0 && !types7.some((type) => typeof type === "string" && typeMatches(type, value))) {
50996
+ results.push(invalidResult(issue(path193, types7.join(","), value, `must be ${types7.join(",")}`)));
50997
50997
  return results;
50998
50998
  }
50999
50999
  if (schema.const !== void 0 && !deepEqual(schema.const, value)) {
@@ -80409,18 +80409,18 @@ function readNumber3(value, fallback, field) {
80409
80409
  return value;
80410
80410
  }
80411
80411
  function readPositiveInteger(value, fallback, field) {
80412
- const numberValue2 = readNumber3(value, fallback, field);
80413
- if (!Number.isInteger(numberValue2) || numberValue2 <= 0) {
80412
+ const numberValue3 = readNumber3(value, fallback, field);
80413
+ if (!Number.isInteger(numberValue3) || numberValue3 <= 0) {
80414
80414
  throw new Error(`Expected "${field}" to be a positive integer.`);
80415
80415
  }
80416
- return numberValue2;
80416
+ return numberValue3;
80417
80417
  }
80418
80418
  function readNonNegativeInteger(value, fallback, field) {
80419
- const numberValue2 = readNumber3(value, fallback, field);
80420
- if (!Number.isInteger(numberValue2) || numberValue2 < 0) {
80419
+ const numberValue3 = readNumber3(value, fallback, field);
80420
+ if (!Number.isInteger(numberValue3) || numberValue3 < 0) {
80421
80421
  throw new Error(`Expected "${field}" to be a non-negative integer.`);
80422
80422
  }
80423
- return numberValue2;
80423
+ return numberValue3;
80424
80424
  }
80425
80425
  function readOptionalString3(value, field) {
80426
80426
  if (value === void 0) {
@@ -125901,6 +125901,54 @@ var init_collection_brands = __esm({
125901
125901
  }
125902
125902
  });
125903
125903
 
125904
+ // packages/safe-js/src/interp/boxed.ts
125905
+ import { types } from "node:util";
125906
+ function nativeBoxedValue(value) {
125907
+ if (types.isNumberObject(value)) return Reflect.apply(numberValue2, value, []);
125908
+ if (types.isStringObject(value)) return Reflect.apply(stringValue2, value, []);
125909
+ if (types.isBooleanObject(value)) return Reflect.apply(booleanValue, value, []);
125910
+ return void 0;
125911
+ }
125912
+ function createSandboxBox(value) {
125913
+ if (typeof value !== "number" && typeof value !== "string" && typeof value !== "boolean")
125914
+ throw new TypeError("Invalid boxed primitive payload.");
125915
+ const box = Object(value);
125916
+ Object.setPrototypeOf(box, null);
125917
+ boxes.add(box);
125918
+ return box;
125919
+ }
125920
+ function isSandboxBox(value) {
125921
+ return typeof value === "object" && value !== null && boxes.has(value);
125922
+ }
125923
+ function boxedValue(value) {
125924
+ if (!boxes.has(value)) throw new TypeError("Expected a sandbox boxed primitive.");
125925
+ return nativeBoxedValue(value);
125926
+ }
125927
+ function primitiveReceiver(value, kind) {
125928
+ const primitive = isSandboxBox(value) ? boxedValue(value) : value;
125929
+ if (typeof primitive !== kind) throw new TypeError(`${kind} method requires a ${kind} receiver.`);
125930
+ return primitive;
125931
+ }
125932
+ function boxedDataProperties(value) {
125933
+ const primitive = nativeBoxedValue(value);
125934
+ return Object.entries(Object.getOwnPropertyDescriptors(value)).filter(([key3]) => {
125935
+ if (typeof primitive !== "string") return true;
125936
+ if (key3 === "length") return false;
125937
+ const index = Number(key3);
125938
+ return !(Number.isInteger(index) && index >= 0 && index < primitive.length && String(index) === key3);
125939
+ });
125940
+ }
125941
+ var boxes, numberValue2, stringValue2, booleanValue;
125942
+ var init_boxed = __esm({
125943
+ "packages/safe-js/src/interp/boxed.ts"() {
125944
+ "use strict";
125945
+ boxes = /* @__PURE__ */ new WeakSet();
125946
+ numberValue2 = Number.prototype.valueOf;
125947
+ stringValue2 = String.prototype.valueOf;
125948
+ booleanValue = Boolean.prototype.valueOf;
125949
+ }
125950
+ });
125951
+
125904
125952
  // packages/safe-js/src/graph-depth.ts
125905
125953
  function assertSandboxDataDepth(depth) {
125906
125954
  if (depth > MAX_DATA_DEPTH) {
@@ -125943,6 +125991,7 @@ function walkGraphDepth(root, rootPath, assertDepth) {
125943
125991
  }
125944
125992
  }
125945
125993
  function graphEntries(value) {
125994
+ if (isSandboxBox(value)) return boxedDataProperties(value).map(([key3, descriptor]) => [`.${key3}`, descriptor.value]);
125946
125995
  if (isSandboxArguments(value)) {
125947
125996
  return getSandboxArgumentEntries(value).map(([key3, entry]) => [`.${key3}`, entry]);
125948
125997
  }
@@ -125975,6 +126024,7 @@ var init_graph_depth = __esm({
125975
126024
  init_arguments();
125976
126025
  init_collection_iterator();
125977
126026
  init_collection_brands();
126027
+ init_boxed();
125978
126028
  MAX_DATA_DEPTH = 1024;
125979
126029
  SnapshotBudgetError = class extends Error {
125980
126030
  code = "budgetExceeded";
@@ -125995,9 +126045,9 @@ var init_graph_depth = __esm({
125995
126045
  });
125996
126046
 
125997
126047
  // packages/safe-js/src/extensions.ts
125998
- import { types } from "node:util";
126048
+ import { types as types2 } from "node:util";
125999
126049
  function readDataRecord(value, label) {
126000
- if (typeof value !== "object" || value === null || types.isProxy(value)) {
126050
+ if (typeof value !== "object" || value === null || types2.isProxy(value)) {
126001
126051
  throw new TypeError(`${label} must be a plain data record.`);
126002
126052
  }
126003
126053
  const prototype = Object.getPrototypeOf(value);
@@ -126017,7 +126067,7 @@ function readDataRecord(value, label) {
126017
126067
  return result;
126018
126068
  }
126019
126069
  function readStringList(value, label) {
126020
- if (!Array.isArray(value) || types.isProxy(value) || value.length > 4096) {
126070
+ if (!Array.isArray(value) || types2.isProxy(value) || value.length > 4096) {
126021
126071
  throw new TypeError(`${label} must be a bounded string array.`);
126022
126072
  }
126023
126073
  const result = [];
@@ -126048,7 +126098,7 @@ var init_extensions = __esm({
126048
126098
  });
126049
126099
 
126050
126100
  // packages/safe-js/src/interp/host-capabilities.ts
126051
- import { types as types2 } from "node:util";
126101
+ import { types as types3 } from "node:util";
126052
126102
  function createGuestReference(root, owner, assertActive) {
126053
126103
  const reference = Object.freeze(/* @__PURE__ */ Object.create(null));
126054
126104
  guestReferences.set(reference, { root, owner, assertActive });
@@ -126096,7 +126146,7 @@ function createLiveHostObject(definition, controller) {
126096
126146
  for (const name of ["keys", "get", "set", "delete"]) {
126097
126147
  const operation = data[name];
126098
126148
  if (operation === void 0 && (name === "set" || name === "delete")) continue;
126099
- if (typeof operation !== "function" || types2.isProxy(operation) || types2.isAsyncFunction(operation) || types2.isGeneratorFunction(operation))
126149
+ if (typeof operation !== "function" || types3.isProxy(operation) || types3.isAsyncFunction(operation) || types3.isGeneratorFunction(operation))
126100
126150
  throw new TypeError(`Named ${name} must be a synchronous non-generator function, not a proxy.`);
126101
126151
  }
126102
126152
  if (typeof data.maxKeys !== "number" || !Number.isInteger(data.maxKeys) || data.maxKeys < 1 || data.maxKeys > MAX_NAMED_KEYS)
@@ -126351,7 +126401,7 @@ function namedMutationKeys(state, key3, create) {
126351
126401
  function namedKeys2(state) {
126352
126402
  const named = state.named;
126353
126403
  return state.controller.read(named.keys, (value) => {
126354
- if (!Array.isArray(value) || types2.isProxy(value))
126404
+ if (!Array.isArray(value) || types3.isProxy(value))
126355
126405
  throw new TypeError("Named keys must be a dense own-data array of strings, not a proxy.");
126356
126406
  const length = Object.getOwnPropertyDescriptor(value, "length").value;
126357
126407
  if (length > named.maxKeys) throw new RangeError("Named keys exceed maxKeys.");
@@ -126492,7 +126542,7 @@ var init_otel2 = __esm({
126492
126542
  });
126493
126543
 
126494
126544
  // packages/safe-js/src/interp/date.ts
126495
- import { types as types3 } from "node:util";
126545
+ import { types as types4 } from "node:util";
126496
126546
  function isSandboxDate(value) {
126497
126547
  return typeof value === "object" && value !== null && dates.has(value);
126498
126548
  }
@@ -126505,7 +126555,7 @@ function dateTime(value) {
126505
126555
  return Reflect.apply(readTime, value, []);
126506
126556
  }
126507
126557
  function copyNativeDate(value) {
126508
- if (!types3.isDate(value)) return void 0;
126558
+ if (!types4.isDate(value)) return void 0;
126509
126559
  if (Object.getPrototypeOf(value) !== NativeDate.prototype || Reflect.ownKeys(value).length > 0)
126510
126560
  throw new TypeError("Date subclasses and own properties are not supported.");
126511
126561
  return createSandboxDate(dateTime(value));
@@ -127203,6 +127253,40 @@ var init_float32array = __esm({
127203
127253
  }
127204
127254
  });
127205
127255
 
127256
+ // packages/safe-js/src/snapshot/boxed.ts
127257
+ function encodeBoxedData(value, encode) {
127258
+ const properties = /* @__PURE__ */ Object.create(null);
127259
+ for (const [key3, descriptor] of boxedDataProperties(value)) {
127260
+ if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
127261
+ properties[key3] = {
127262
+ value: encode(descriptor.value, key3),
127263
+ configurable: descriptor.configurable === true,
127264
+ enumerable: descriptor.enumerable === true,
127265
+ writable: descriptor.writable === true
127266
+ };
127267
+ }
127268
+ return {
127269
+ kind: "boxed",
127270
+ value: encode(boxedValue(value), "<payload>"),
127271
+ properties,
127272
+ extensible: Object.isExtensible(value)
127273
+ };
127274
+ }
127275
+ function validateBoxedProperties(data) {
127276
+ 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))
127277
+ throw new TypeError("Invalid boxed primitive properties.");
127278
+ for (const descriptor of Object.values(data.properties)) {
127279
+ 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)
127280
+ throw new TypeError("Invalid boxed primitive descriptor.");
127281
+ }
127282
+ }
127283
+ var init_boxed2 = __esm({
127284
+ "packages/safe-js/src/snapshot/boxed.ts"() {
127285
+ "use strict";
127286
+ init_boxed();
127287
+ }
127288
+ });
127289
+
127206
127290
  // packages/safe-js/src/snapshot/arguments.ts
127207
127291
  function serializeArguments(value, serializeValue) {
127208
127292
  const properties = /* @__PURE__ */ Object.create(null);
@@ -127289,6 +127373,13 @@ function encodeReplayData(value, options = {}) {
127289
127373
  id: capabilityId,
127290
127374
  properties: child(entry.properties, "properties")
127291
127375
  };
127376
+ } else if (nativeBoxedValue(entry) !== void 0) {
127377
+ const properties = /* @__PURE__ */ Object.create(null);
127378
+ nodes[id] = { kind: "boxed", value: child(nativeBoxedValue(entry), "<payload>"), properties, extensible: Object.isExtensible(entry) };
127379
+ for (const [key3, descriptor] of boxedDataProperties(entry)) {
127380
+ if (!("value" in descriptor)) throw new TypeError(`Cannot record replay data accessor '${key3}'.`);
127381
+ properties[key3] = { value: child(descriptor.value, JSON.stringify(["property", key3])), configurable: descriptor.configurable === true, enumerable: descriptor.enumerable === true, writable: descriptor.writable === true };
127382
+ }
127292
127383
  } else if (isSandboxDate(entry)) {
127293
127384
  nodes[id] = { kind: "date", time: serializedDateTime(entry) };
127294
127385
  } else if (isFloat32Array(entry)) {
@@ -127450,6 +127541,17 @@ function decodeReplayData(input, options = {}, parent) {
127450
127541
  options.onCapabilityRestored?.(capability, copy);
127451
127542
  return copy;
127452
127543
  }
127544
+ if (kind === "boxed") {
127545
+ validateBoxedProperties(node);
127546
+ const payload = own(node, "value");
127547
+ if (typeof payload !== "number" && typeof payload !== "string" && typeof payload !== "boolean" && (payload === null || typeof payload !== "object" || own(record(payload), "tag") !== "number"))
127548
+ throw new TypeError("Invalid boxed primitive payload.");
127549
+ const result3 = createSandboxBox(child(payload));
127550
+ restored.set(id, result3);
127551
+ defineProperties(result3, record(own(node, "properties")), child);
127552
+ if (!node.extensible) Object.preventExtensions(result3);
127553
+ return result3;
127554
+ }
127453
127555
  if (kind === "date") {
127454
127556
  if (Object.keys(node).length !== 2) throw new TypeError("Invalid serialized Date fields.");
127455
127557
  const result3 = restoreDateTime(own(node, "time"));
@@ -127588,6 +127690,8 @@ var init_replay_data = __esm({
127588
127690
  init_float32();
127589
127691
  init_float32array();
127590
127692
  init_date();
127693
+ init_boxed();
127694
+ init_boxed2();
127591
127695
  init_shape();
127592
127696
  init_values();
127593
127697
  init_arguments2();
@@ -128769,7 +128873,7 @@ async function objectToPrimitive(value, budget, context, joining, hint) {
128769
128873
  if (hook === defaultStringHook) {
128770
128874
  result = await defaultToString(value, budget, context, joining);
128771
128875
  } else if (hook === defaultValueHook) {
128772
- result = isSandboxDate(value) ? dateTime(value) : value;
128876
+ result = isSandboxDate(value) ? dateTime(value) : isSandboxBox(value) ? boxedValue(value) : value;
128773
128877
  } else {
128774
128878
  if (!isSandboxClosure(hook)) continue;
128775
128879
  result = await invokeBuiltinClosure(hook, [], budget, context, value);
@@ -128809,6 +128913,7 @@ function conversionHook(value, name, budget) {
128809
128913
  return void 0;
128810
128914
  }
128811
128915
  async function defaultToString(value, budget, context, joining) {
128916
+ if (isSandboxBox(value)) return budget.allocateString(String(boxedValue(value)));
128812
128917
  if (isSandboxClosure(value)) return budget.allocateString(functionString(value));
128813
128918
  if (isSandboxMap(value)) return "[object Map]";
128814
128919
  if (isSandboxSet(value)) return "[object Set]";
@@ -128881,6 +128986,7 @@ var init_string_coercion = __esm({
128881
128986
  init_regex();
128882
128987
  init_resources();
128883
128988
  init_function_string();
128989
+ init_boxed();
128884
128990
  init_values();
128885
128991
  defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
128886
128992
  defaultValueHook = /* @__PURE__ */ Symbol("defaultValueHook");
@@ -129411,7 +129517,27 @@ var init_running_state = __esm({
129411
129517
  });
129412
129518
 
129413
129519
  // packages/safe-js/src/interp/iteration.ts
129414
- function getSandboxIterator(value, budget) {
129520
+ function getSandboxIterator(value, budget, context) {
129521
+ if (isSandboxBox(value) && typeof boxedValue(value) === "string") {
129522
+ const primitive = boxedValue(value);
129523
+ let text5;
129524
+ let iterator;
129525
+ let initialized;
129526
+ return {
129527
+ asynchronous: true,
129528
+ get retainedValue() {
129529
+ return text5 === primitive ? void 0 : text5;
129530
+ },
129531
+ next: async () => {
129532
+ initialized ??= Promise.resolve(sandboxString(value, budget ?? new Budget(), context)).then((converted) => {
129533
+ text5 = converted;
129534
+ iterator = syncIterator(converted[Symbol.iterator]());
129535
+ });
129536
+ await initialized;
129537
+ return iterator.next();
129538
+ }
129539
+ };
129540
+ }
129415
129541
  if (isSandboxCollectionIterator(value)) return { next: () => nextCollectionIterator(value, budget), snapshotIndex: () => 0 };
129416
129542
  if (isGuestHostObject(value)) return getHostObjectIterator(value);
129417
129543
  if (isFloat32Array(value)) {
@@ -129515,8 +129641,11 @@ var init_iteration = __esm({
129515
129641
  init_values();
129516
129642
  init_running_state();
129517
129643
  init_float32();
129644
+ init_boxed();
129518
129645
  init_host_capabilities();
129519
129646
  init_collection_iterator();
129647
+ init_budget2();
129648
+ init_string_coercion();
129520
129649
  }
129521
129650
  });
129522
129651
 
@@ -129991,67 +130120,72 @@ async function settleIterable(iterable, method, budget, constructor, context) {
129991
130120
  const promiseResolve = readPromiseReceiverProperty(constructor, "resolve", prototype);
129992
130121
  if (!isSandboxClosure(promiseResolve))
129993
130122
  throw new TypeError("Promise constructor requires a callable resolve.");
129994
- const iterator = getSandboxIterator(iterable, budget);
130123
+ const iterator = getSandboxIterator(iterable, budget, context);
129995
130124
  if (iterator === void 0) throw new TypeError("Promise helpers require an iterable.");
129996
- let index = 0;
129997
- while (true) {
129998
- budget.visitNode();
129999
- const next = iterator.generator ? await iterator.next() : iterator.next();
130000
- if (typeof next !== "object" || next === null)
130001
- throw new TypeError("Iterator result must be an object.");
130002
- if (next.done) break;
130003
- const value = next.value;
130004
- try {
130005
- budget.allocateArrayLength(index + 1);
130006
- const entryIndex = index++;
130007
- if (method !== "race") values.push(void 0);
130008
- const entry = await callPromiseClosure(
130009
- promiseResolve,
130010
- [value],
130011
- constructor,
130012
- budget,
130013
- context
130014
- );
130015
- let called = false;
130016
- const handlers = ["fulfilled", "rejected"].map((state) => {
130017
- if (method === "race" || method === "any" && state === "fulfilled")
130018
- return state === "fulfilled" ? capability.resolve : capability.reject;
130019
- if (method === "all" && state === "rejected") return capability.reject;
130020
- return createSandboxClosure({
130021
- sandbox: true,
130022
- retainedValues: () => [
130023
- capability.promise,
130024
- capability.resolve,
130025
- capability.reject,
130026
- values
130027
- ],
130028
- call: async ([settlement]) => {
130029
- if (called) return void 0;
130030
- called = true;
130031
- values[entryIndex] = method === "allSettled" ? state === "fulfilled" ? { status: state, value: settlement } : { status: state, reason: settlement } : settlement;
130032
- remaining--;
130033
- await complete();
130034
- return void 0;
130035
- }
130036
- });
130037
- });
130038
- remaining++;
130039
- const then = readPromiseReceiverProperty(entry, "then", prototype);
130040
- if (!isSandboxClosure(then))
130041
- throw new TypeError("Promise resolver result requires a callable then.");
130042
- await callPromiseClosure(then, handlers, entry, budget, context);
130043
- } catch (error3) {
130125
+ const releaseIterator = retainValues(budget, () => [iterator.retainedValue]);
130126
+ try {
130127
+ let index = 0;
130128
+ while (true) {
130129
+ budget.visitNode();
130130
+ const next = iterator.generator || iterator.asynchronous ? await iterator.next() : iterator.next();
130131
+ if (typeof next !== "object" || next === null)
130132
+ throw new TypeError("Iterator result must be an object.");
130133
+ if (next.done) break;
130134
+ const value = next.value;
130044
130135
  try {
130045
- const closed = iterator.return?.();
130046
- if (iterator.generator) await closed;
130047
- } catch {
130136
+ budget.allocateArrayLength(index + 1);
130137
+ const entryIndex = index++;
130138
+ if (method !== "race") values.push(void 0);
130139
+ const entry = await callPromiseClosure(
130140
+ promiseResolve,
130141
+ [value],
130142
+ constructor,
130143
+ budget,
130144
+ context
130145
+ );
130146
+ let called = false;
130147
+ const handlers = ["fulfilled", "rejected"].map((state) => {
130148
+ if (method === "race" || method === "any" && state === "fulfilled")
130149
+ return state === "fulfilled" ? capability.resolve : capability.reject;
130150
+ if (method === "all" && state === "rejected") return capability.reject;
130151
+ return createSandboxClosure({
130152
+ sandbox: true,
130153
+ retainedValues: () => [
130154
+ capability.promise,
130155
+ capability.resolve,
130156
+ capability.reject,
130157
+ values
130158
+ ],
130159
+ call: async ([settlement]) => {
130160
+ if (called) return void 0;
130161
+ called = true;
130162
+ values[entryIndex] = method === "allSettled" ? state === "fulfilled" ? { status: state, value: settlement } : { status: state, reason: settlement } : settlement;
130163
+ remaining--;
130164
+ await complete();
130165
+ return void 0;
130166
+ }
130167
+ });
130168
+ });
130169
+ remaining++;
130170
+ const then = readPromiseReceiverProperty(entry, "then", prototype);
130171
+ if (!isSandboxClosure(then))
130172
+ throw new TypeError("Promise resolver result requires a callable then.");
130173
+ await callPromiseClosure(then, handlers, entry, budget, context);
130174
+ } catch (error3) {
130175
+ try {
130176
+ const closed = iterator.return?.();
130177
+ if (iterator.generator || iterator.asynchronous) await closed;
130178
+ } catch {
130179
+ throw error3;
130180
+ }
130048
130181
  throw error3;
130049
130182
  }
130050
- throw error3;
130051
130183
  }
130184
+ remaining--;
130185
+ await complete();
130186
+ } finally {
130187
+ releaseIterator();
130052
130188
  }
130053
- remaining--;
130054
- await complete();
130055
130189
  } catch (error3) {
130056
130190
  if (error3 instanceof SandboxError && (error3.code === "budgetExceeded" || error3.code === "reentry")) {
130057
130191
  if (isSandboxPromise(capability.promise)) observeSandboxPromise(capability.promise);
@@ -130359,6 +130493,7 @@ var init_promise = __esm({
130359
130493
  init_budget2();
130360
130494
  init_exceptions();
130361
130495
  init_iteration();
130496
+ init_resources();
130362
130497
  init_jobs4();
130363
130498
  init_promise_tracker();
130364
130499
  init_values();
@@ -130776,6 +130911,17 @@ function measureSandboxData(values, options = {}) {
130776
130911
  assertSandboxDataDepth(depth);
130777
130912
  seen.add(value);
130778
130913
  usage += 1;
130914
+ if (isSandboxBox(value)) {
130915
+ const primitive = boxedValue(value);
130916
+ usage += typeof primitive === "string" ? primitive.length : 8;
130917
+ const prototype2 = getSandboxPrototype(value);
130918
+ if (prototype2 !== null) visit(prototype2, depth + 1);
130919
+ for (const [key3, descriptor] of boxedDataProperties(value)) {
130920
+ usage += key3.length + 1;
130921
+ if ("value" in descriptor) visit(descriptor.value, depth + 1);
130922
+ }
130923
+ return;
130924
+ }
130779
130925
  if (isSandboxDate(value)) {
130780
130926
  usage += 8;
130781
130927
  return;
@@ -130837,7 +130983,15 @@ function measureSandboxData(values, options = {}) {
130837
130983
  }
130838
130984
  if (isSandboxClosure(value)) {
130839
130985
  if (options.ignoreClosures) return;
130840
- if (value.properties !== void 0) visit(value.properties, depth + 1);
130986
+ if (value.properties !== void 0) {
130987
+ if (isIntrinsicConstructor(value)) {
130988
+ for (const [key3, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(value.properties))) {
130989
+ if (key3 === "prototype" || key3 === "name" || key3 === "length") continue;
130990
+ usage += key3.length + 1;
130991
+ if ("value" in descriptor) visit(descriptor.value, depth + 1);
130992
+ }
130993
+ } else visit(value.properties, depth + 1);
130994
+ }
130841
130995
  if (!options.ignoreClosureCaptures)
130842
130996
  for (const retained of value[sandboxRetainedValues]?.() ?? []) visit(retained, depth + 1);
130843
130997
  return;
@@ -130969,6 +131123,24 @@ function copyToSandbox(value, state, path193 = "<root>", cloneSandboxCollections
130969
131123
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
130970
131124
  throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
130971
131125
  }
131126
+ const primitive = nativeBoxedValue(value);
131127
+ if (primitive !== void 0) {
131128
+ const original = value;
131129
+ const existing = state.seen.get(original);
131130
+ if (existing !== void 0) return existing;
131131
+ const copy = createSandboxBox(primitive);
131132
+ state.seen.set(original, copy);
131133
+ if (!state.structuredClone) {
131134
+ for (const [key3, descriptor] of boxedDataProperties(original)) {
131135
+ if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
131136
+ Object.defineProperty(copy, key3, {
131137
+ ...descriptor,
131138
+ value: copyToSandbox(descriptor.value, state, joinPath(path193, key3), cloneSandboxCollections, depth + 1)
131139
+ });
131140
+ }
131141
+ }
131142
+ return copy;
131143
+ }
130972
131144
  if (isSandboxMap(value)) {
130973
131145
  if (!cloneSandboxCollections) return value;
130974
131146
  const existing = state.seen.get(value);
@@ -131141,6 +131313,20 @@ function copyFromSandbox(value, state, path193 = "<root>", options, depth = 0) {
131141
131313
  if (!isSandboxClosure(value) && hasGuestObjectState(value)) {
131142
131314
  throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
131143
131315
  }
131316
+ if (isSandboxBox(value)) {
131317
+ const existing = state.seen.get(value);
131318
+ if (existing !== void 0) return existing;
131319
+ const copy = Object(boxedValue(value));
131320
+ state.seen.set(value, copy);
131321
+ for (const [key3, descriptor] of boxedDataProperties(value)) {
131322
+ if (!("value" in descriptor)) throw new TypeError("Boxed data cannot contain accessors.");
131323
+ Object.defineProperty(copy, key3, {
131324
+ ...descriptor,
131325
+ value: copyFromSandbox(descriptor.value, state, joinPath(path193, key3), options, depth + 1)
131326
+ });
131327
+ }
131328
+ return copy;
131329
+ }
131144
131330
  const regexBrand = Object.getOwnPropertyDescriptor(value, sandboxRegexBrand);
131145
131331
  if (regexBrand !== void 0) {
131146
131332
  if (!("value" in regexBrand) || regexBrand.value !== true) {
@@ -131311,6 +131497,17 @@ function allocateSandboxValue2(value, budget, seen) {
131311
131497
  budget.allocateString(value);
131312
131498
  return;
131313
131499
  }
131500
+ if (isSandboxBox(value)) {
131501
+ if (seen.has(value)) return;
131502
+ seen.add(value);
131503
+ const primitive = boxedValue(value);
131504
+ if (typeof primitive === "string") budget.allocateString(primitive);
131505
+ for (const [key3, descriptor] of boxedDataProperties(value)) {
131506
+ budget.allocateString(key3);
131507
+ if ("value" in descriptor) allocateSandboxValue2(descriptor.value, budget, seen);
131508
+ }
131509
+ return;
131510
+ }
131314
131511
  if (isFloat32Array(value)) {
131315
131512
  if (seen.has(value)) return;
131316
131513
  seen.add(value);
@@ -131457,6 +131654,7 @@ var init_values = __esm({
131457
131654
  init_collection_brands();
131458
131655
  init_collection_iterator();
131459
131656
  init_date();
131657
+ init_boxed();
131460
131658
  init_host_capabilities();
131461
131659
  init_compile_guard();
131462
131660
  init_float32();
@@ -131527,25 +131725,61 @@ function getGuestFunctionProperty(closure, key3) {
131527
131725
  function installObjectPrototype(budget, prototype, constructor) {
131528
131726
  prototypes.set(prototype, null);
131529
131727
  intrinsicPrototypes.set(budget, prototype);
131530
- const records = [prototype, materializeFunctionProperties(constructor)].map((value) => ({
131531
- value,
131532
- descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(value)))
131728
+ registerIntrinsicPrototype(budget, prototype, constructor);
131729
+ }
131730
+ function installBoxedPrototype(budget, prototype, constructor) {
131731
+ let state = boxedPrototypes.get(budget);
131732
+ if (state === void 0) boxedPrototypes.set(budget, state = /* @__PURE__ */ new Map());
131733
+ state.set(typeof boxedValue(prototype), prototype);
131734
+ initialBoxedMethods.set(prototype, new Map(Object.entries(Object.getOwnPropertyDescriptors(prototype)).map(([key3, descriptor]) => [key3, descriptor.value])));
131735
+ registerIntrinsicPrototype(budget, prototype, constructor);
131736
+ }
131737
+ function getBoxedPrototype(value, budget) {
131738
+ return boxedPrototypes.get(budget)?.get(typeof value);
131739
+ }
131740
+ function isDefaultBoxedMethod(value, key3, budget) {
131741
+ const prototype = getBoxedPrototype(value, budget);
131742
+ return prototype !== void 0 && initialBoxedMethods.get(prototype)?.has(key3) === true && Object.getOwnPropertyDescriptor(prototype, key3)?.value === initialBoxedMethods.get(prototype)?.get(key3);
131743
+ }
131744
+ function isIntrinsicConstructor(value) {
131745
+ return intrinsicConstructors.has(value);
131746
+ }
131747
+ function registerIntrinsicPrototype(budget, prototype, constructor) {
131748
+ let roots = intrinsicPrototypeRoots.get(budget);
131749
+ if (roots === void 0) intrinsicPrototypeRoots.set(budget, roots = /* @__PURE__ */ new Set());
131750
+ roots.add(prototype);
131751
+ const records = [prototype, constructor].map((target) => ({
131752
+ target,
131753
+ value: isGuestClosure(target) ? materializeFunctionProperties(target) : target,
131754
+ prototype: getSandboxPrototype(target),
131755
+ explicit: hasExplicitSandboxPrototype(target)
131756
+ })).map((record2) => ({
131757
+ ...record2,
131758
+ descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(record2.value)))
131533
131759
  }));
131534
- 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;
131535
- intrinsicConstructors.set(constructor, () => records.every(({ value, descriptors }) => {
131760
+ 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;
131761
+ intrinsicConstructors.set(constructor, () => records.every(({ target, value, descriptors, prototype: parent, explicit }) => {
131536
131762
  const current = Object.getOwnPropertyDescriptors(value);
131537
- return Object.keys(current).length === descriptors.size && Object.keys(current).every((key3) => unchanged(descriptors.get(key3), current[key3]));
131763
+ return getSandboxPrototype(target) === parent && hasExplicitSandboxPrototype(target) === explicit && Object.keys(current).length === descriptors.size && Object.keys(current).every((key3) => unchanged(descriptors.get(key3), current[key3]));
131538
131764
  }));
131539
- budget.setRetainedValues(prototype, () => records.flatMap(({ value, descriptors }) => Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key3, descriptor]) => unchanged(descriptors.get(key3), descriptor) ? [] : [key3, descriptor.value])));
131765
+ budget.setRetainedValues(prototype, () => records.flatMap(({ target, value, descriptors, prototype: parent }) => [
131766
+ ...getSandboxPrototype(target) === parent ? [] : [getSandboxPrototype(target)],
131767
+ ...Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key3, descriptor]) => unchanged(descriptors.get(key3), descriptor) ? [] : [key3, descriptor.value])
131768
+ ]));
131540
131769
  }
131541
131770
  function releaseObjectPrototype(budget) {
131542
- const prototype = intrinsicPrototypes.get(budget);
131543
- if (prototype !== void 0) budget.setRetainedValues(prototype, void 0);
131771
+ for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
131772
+ intrinsicPrototypeRoots.delete(budget);
131773
+ boxedPrototypes.delete(budget);
131544
131774
  intrinsicPrototypes.delete(budget);
131545
131775
  }
131546
131776
  function getSandboxPrototype(value, budget) {
131547
131777
  if (prototypes.has(value)) return prototypes.get(value) ?? null;
131548
- return budget !== void 0 && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
131778
+ if (budget !== void 0 && isSandboxBox(value)) {
131779
+ const prototype = getBoxedPrototype(boxedValue(value), budget);
131780
+ if (prototype !== void 0 && prototype !== value) return prototype;
131781
+ }
131782
+ return budget !== void 0 && !isSandboxClosure(value) && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
131549
131783
  }
131550
131784
  function hasExplicitSandboxPrototype(value) {
131551
131785
  return prototypes.has(value);
@@ -131555,14 +131789,16 @@ function getSandboxDataProperty(value, key3, budget) {
131555
131789
  let depth = 0;
131556
131790
  while (typeof current === "object" && current !== null) {
131557
131791
  if (isGuestHostObject(current)) return getHostObjectMember(current, String(key3));
131558
- if (isGuestClosure(current)) return getGuestFunctionProperty(current, String(key3));
131559
- if (isSandboxClosure(current)) {
131792
+ if (isGuestClosure(current)) {
131793
+ const entry = getGuestFunctionProperty(current, String(key3));
131794
+ if (entry !== void 0 || Object.hasOwn(current.properties ?? {}, String(key3))) return entry;
131795
+ } else if (isSandboxClosure(current)) {
131560
131796
  const properties = current.properties;
131561
131797
  return properties !== void 0 && Object.hasOwn(properties, String(key3)) ? properties[String(key3)] : void 0;
131562
131798
  }
131563
131799
  if (isSandboxMap(current) || isSandboxSet(current) || isSandboxPromise(current) || isSandboxRegex(current) || isSandboxGenerator(current))
131564
131800
  return void 0;
131565
- if (Object.hasOwn(current, String(key3))) return current[String(key3)];
131801
+ if (!isSandboxClosure(current) && Object.hasOwn(current, String(key3))) return current[String(key3)];
131566
131802
  current = getSandboxPrototype(current, budget);
131567
131803
  if (current !== null) {
131568
131804
  budget?.visitNode();
@@ -131577,7 +131813,7 @@ function setSandboxPrototype(value, prototype, budget) {
131577
131813
  }
131578
131814
  if (!isPrototypeRecord(value) || prototype !== null && !isPrototypeRecord(prototype)) {
131579
131815
  throw new TypeError(
131580
- "Prototype links require ordinary sandbox objects; callable and exotic prototype chains are not supported."
131816
+ "Prototype links require ordinary sandbox objects or guest functions."
131581
131817
  );
131582
131818
  }
131583
131819
  if (prototypes.has(value) && getSandboxPrototype(value, budget) === prototype) return;
@@ -131593,6 +131829,7 @@ function setSandboxPrototype(value, prototype, budget) {
131593
131829
  prototypes.set(value, prototype);
131594
131830
  }
131595
131831
  function isPrototypeRecord(value) {
131832
+ if (isGuestClosure(value)) return true;
131596
131833
  if (isGuestHostObject(value)) return false;
131597
131834
  if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxSet(value))
131598
131835
  return false;
@@ -131610,22 +131847,27 @@ function hasGuestObjectState(value) {
131610
131847
  if (intrinsicUnchanged !== void 0) return !intrinsicUnchanged();
131611
131848
  if (isLiveCapability(value)) return true;
131612
131849
  if (functionProperties.has(value) || prototypes.has(value)) return true;
131850
+ if (isSandboxBox(value)) return false;
131613
131851
  return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
131614
131852
  (descriptor) => !descriptor.enumerable || !descriptor.configurable || !descriptor.writable
131615
131853
  );
131616
131854
  }
131617
- var guestClosures, functionProperties, prototypes, intrinsicPrototypes, intrinsicConstructors, descriptorObjects;
131855
+ var guestClosures, functionProperties, prototypes, intrinsicPrototypes, boxedPrototypes, intrinsicPrototypeRoots, intrinsicConstructors, initialBoxedMethods, descriptorObjects;
131618
131856
  var init_object_model = __esm({
131619
131857
  "packages/safe-js/src/interp/object-model.ts"() {
131620
131858
  "use strict";
131621
131859
  init_graph_depth();
131622
131860
  init_host_capabilities();
131861
+ init_boxed();
131623
131862
  init_values();
131624
131863
  guestClosures = /* @__PURE__ */ new WeakSet();
131625
131864
  functionProperties = /* @__PURE__ */ new WeakMap();
131626
131865
  prototypes = /* @__PURE__ */ new WeakMap();
131627
131866
  intrinsicPrototypes = /* @__PURE__ */ new WeakMap();
131867
+ boxedPrototypes = /* @__PURE__ */ new WeakMap();
131868
+ intrinsicPrototypeRoots = /* @__PURE__ */ new WeakMap();
131628
131869
  intrinsicConstructors = /* @__PURE__ */ new WeakMap();
131870
+ initialBoxedMethods = /* @__PURE__ */ new WeakMap();
131629
131871
  descriptorObjects = /* @__PURE__ */ new WeakSet();
131630
131872
  }
131631
131873
  });
@@ -131722,7 +131964,7 @@ function serializeDumpValue(value, path193, state) {
131722
131964
  if (hasGuestObjectState(value)) {
131723
131965
  throw new TypeError("Guest function properties and prototype links cannot be serialized.");
131724
131966
  }
131725
- if (isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path193, state);
131967
+ if (isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path193, state);
131726
131968
  if (Array.isArray(value)) {
131727
131969
  const reference2 = serializeHeapReference(value, path193, state);
131728
131970
  if (reference2 !== void 0) {
@@ -131746,7 +131988,13 @@ function serializeHeapReference(value, path193, state) {
131746
131988
  }
131747
131989
  if (!state.serializedHeapIds.has(id)) {
131748
131990
  state.serializedHeapIds.add(id);
131749
- if (isSandboxDate(value)) {
131991
+ if (isSandboxBox(value)) {
131992
+ state.heap[String(id)] = encodeBoxedData(value, (entry, key3) => {
131993
+ if (Object.is(entry, -0)) return { kind: "number", value: "-0" };
131994
+ const serialized = serializeDumpValue(entry, `${path193}.${key3}`, state);
131995
+ return serialized === SKIP_VALUE ? { kind: "undefined" } : serialized;
131996
+ });
131997
+ } else if (isSandboxDate(value)) {
131750
131998
  state.heap[String(id)] = { kind: "date", time: serializedDateTime(value) };
131751
131999
  } else if (isFloat32Array(value)) {
131752
132000
  const storage2 = encodeFloat32Storage(value, id, state.float32Buffers, (id2) => ({
@@ -131805,7 +132053,7 @@ function indexHeapContainers(snapshot2) {
131805
132053
  const heapIds = /* @__PURE__ */ new WeakMap();
131806
132054
  let nextId = 1;
131807
132055
  for (const [value, stat35] of stats2.entries()) {
131808
- if (stat35.count > 1 || stat35.cyclic || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
132056
+ if (stat35.count > 1 || stat35.cyclic || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
131809
132057
  heapIds.set(value, nextId);
131810
132058
  nextId += 1;
131811
132059
  }
@@ -131838,7 +132086,7 @@ function collectContainerStats(value, stats2, ancestors) {
131838
132086
  }
131839
132087
  stat35.expanded = true;
131840
132088
  ancestors.add(value);
131841
- const entries = isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
132089
+ const entries = isSandboxBox(value) ? boxedDataProperties(value).map(([, descriptor]) => descriptor.value) : isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
131842
132090
  for (const entry of entries) {
131843
132091
  collectContainerStats(entry, stats2, ancestors);
131844
132092
  }
@@ -131888,6 +132136,8 @@ var init_dump_format = __esm({
131888
132136
  init_float32();
131889
132137
  init_float32array();
131890
132138
  init_date();
132139
+ init_boxed();
132140
+ init_boxed2();
131891
132141
  DUMP_FORMAT_VERSION = 1;
131892
132142
  EXECUTION_SEMANTICS = "jobs-v8";
131893
132143
  SKIP_VALUE = /* @__PURE__ */ Symbol("SafeJS.skip-dump-value");
@@ -131895,7 +132145,7 @@ var init_dump_format = __esm({
131895
132145
  });
131896
132146
 
131897
132147
  // packages/safe-js/src/snapshot/validation.ts
131898
- import { types as types4 } from "node:util";
132148
+ import { types as types5 } from "node:util";
131899
132149
  function validateSnapshotData(value) {
131900
132150
  validateGenericValue(value, "$", 0, {
131901
132151
  allowFunctions: false,
@@ -131941,6 +132191,10 @@ function validateDumpHeap(root, state) {
131941
132191
  addUnique2(heapIds, id, path193);
131942
132192
  const entry = requireRecord3(value, path193);
131943
132193
  validateErrorType(entry, path193);
132194
+ if (entry.kind === "boxed") {
132195
+ validateBoxedRecord(entry, path193);
132196
+ continue;
132197
+ }
131944
132198
  if (entry.kind === "date") {
131945
132199
  validateDateRecord(entry, path193);
131946
132200
  continue;
@@ -132108,6 +132362,18 @@ function validateGeneratorShape(record2, path193, state) {
132108
132362
  }
132109
132363
  });
132110
132364
  }
132365
+ function validateBoxedRecord(record2, path193) {
132366
+ try {
132367
+ validateBoxedProperties(record2);
132368
+ } catch {
132369
+ fail2("invalidValue", path193, "invalid boxed primitive properties");
132370
+ }
132371
+ const value = record2.value;
132372
+ if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") return;
132373
+ const number = requireRecord3(value, `${path193}.value`);
132374
+ if (number.kind !== "number" || !["NaN", "Infinity", "-Infinity", "-0"].includes(String(number.value)))
132375
+ fail2("invalidValue", `${path193}.value`, "invalid boxed primitive payload");
132376
+ }
132111
132377
  function validateDateRecord(record2, path193) {
132112
132378
  if (Object.keys(record2).length !== 2) fail2("invalidValue", path193, "invalid Date fields");
132113
132379
  try {
@@ -132199,7 +132465,7 @@ function validateGenericValue(value, path193, depth, state) {
132199
132465
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
132200
132466
  fail2("invalidState", path193, "guest function properties, prototype links and custom descriptors cannot be restored");
132201
132467
  }
132202
- if (state.dataPropertiesOnly && types4.isProxy(value)) {
132468
+ if (state.dataPropertiesOnly && types5.isProxy(value)) {
132203
132469
  fail2("invalidType", path193, "proxy objects are not snapshot data");
132204
132470
  }
132205
132471
  if (depth > state.limits.maxDepth)
@@ -132334,6 +132600,7 @@ var init_validation = __esm({
132334
132600
  init_graph_depth();
132335
132601
  init_float32array();
132336
132602
  init_date();
132603
+ init_boxed2();
132337
132604
  init_object_model();
132338
132605
  DEFAULT_MAX_DEPTH = MAX_DATA_DEPTH;
132339
132606
  DEFAULT_MAX_ENTRIES = 1e5;
@@ -144275,7 +144542,10 @@ function isArrayMethodName(property) {
144275
144542
  }
144276
144543
  async function callArrayMethod(receiver, methodName, args, options, stack = []) {
144277
144544
  if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
144278
- if (typeof receiver !== "object") throw new TypeError("Object primitive boxing is not supported.");
144545
+ if (typeof receiver !== "object") {
144546
+ receiver = createSandboxBox(receiver);
144547
+ options.budget.chargeDataUsage(measureSandboxData([receiver]));
144548
+ }
144279
144549
  const retainedReceiver = {};
144280
144550
  options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
144281
144551
  try {
@@ -144985,6 +145255,7 @@ var arrayLikeSources, activeArrayCallbacks, arrayMethodNames;
144985
145255
  var init_array = __esm({
144986
145256
  "packages/safe-js/src/interp/methods/array.ts"() {
144987
145257
  "use strict";
145258
+ init_boxed();
144988
145259
  init_values();
144989
145260
  init_running_state();
144990
145261
  init_object_model();
@@ -145031,18 +145302,27 @@ var init_array = __esm({
145031
145302
 
145032
145303
  // packages/safe-js/src/interp/methods/function.ts
145033
145304
  function getFunctionMember(target, property, options) {
145034
- if (isGuestClosure(target)) {
145035
- const value = getGuestFunctionProperty(target, String(property));
145036
- if (value !== void 0 || Object.hasOwn(target.properties ?? {}, String(property))) return value;
145037
- if (!isFunctionMethodName(property)) return void 0;
145038
- }
145039
- const properties = target.properties;
145040
- if (properties !== void 0 && Object.hasOwn(properties, String(property))) {
145041
- return properties[String(property)];
145042
- }
145043
- if (property === "length") {
145044
- return target.length;
145305
+ let current = target;
145306
+ let depth = 0;
145307
+ while (current !== null) {
145308
+ if (isGuestClosure(current)) {
145309
+ const value = getGuestFunctionProperty(current, String(property));
145310
+ if (value !== void 0 || Object.hasOwn(current.properties ?? {}, String(property))) return value;
145311
+ } else if (isSandboxClosure(current)) {
145312
+ if (current.properties !== void 0 && Object.hasOwn(current.properties, String(property)))
145313
+ return current.properties[String(property)];
145314
+ if (property === "length") return current.length;
145315
+ } else if (Object.hasOwn(current, String(property))) {
145316
+ return current[String(property)];
145317
+ }
145318
+ if (isSandboxClosure(current) && !hasExplicitSandboxPrototype(current)) break;
145319
+ current = getSandboxPrototype(current, options.budget);
145320
+ if (current !== null) {
145321
+ options.budget?.visitNode();
145322
+ assertSandboxDataDepth(++depth);
145323
+ }
145045
145324
  }
145325
+ if (current === null) return void 0;
145046
145326
  if (property === "toString" && runResources.getStore()?.functionSourceText === false) return void 0;
145047
145327
  if (!isFunctionMethodName(property)) {
145048
145328
  return void 0;
@@ -145068,7 +145348,7 @@ function callFunctionMethod(target, methodName, args, options, stack) {
145068
145348
  const thisValue = args[0];
145069
145349
  if (methodName === "bind") {
145070
145350
  const boundArgs = args.slice(1);
145071
- return createSandboxClosure({
145351
+ const bound = createSandboxClosure({
145072
145352
  guest: true,
145073
145353
  sandbox: true,
145074
145354
  name: `bound ${target.name ?? ""}`,
@@ -145086,6 +145366,9 @@ function callFunctionMethod(target, methodName, args, options, stack) {
145086
145366
  )
145087
145367
  }
145088
145368
  });
145369
+ if (hasExplicitSandboxPrototype(target))
145370
+ setSandboxPrototype(bound, getSandboxPrototype(target, options.budget), options.budget);
145371
+ return bound;
145089
145372
  }
145090
145373
  if (methodName === "call") {
145091
145374
  return options.callClosure(target, args.slice(1), stack, thisValue);
@@ -145105,260 +145388,13 @@ var init_function = __esm({
145105
145388
  "use strict";
145106
145389
  init_values();
145107
145390
  init_object_model();
145391
+ init_graph_depth();
145108
145392
  init_function_string();
145109
145393
  init_resources();
145110
145394
  functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call", "toString"]);
145111
145395
  }
145112
145396
  });
145113
145397
 
145114
- // packages/safe-js/src/interp/methods/collection-callback.ts
145115
- function enterKeyedCollectionCallback(target, keys, budget) {
145116
- let state = activeCallbacks.get(target);
145117
- if (state === void 0) {
145118
- state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
145119
- activeCallbacks.set(target, state);
145120
- }
145121
- const cursor2 = { budget, pending: /* @__PURE__ */ new Set() };
145122
- state.cursors.add(cursor2);
145123
- const leave = () => {
145124
- if (!state.cursors.delete(cursor2)) return;
145125
- cursor2.pending.clear();
145126
- budget.setRetainedDataUsage(cursor2, 0);
145127
- budget.setRetainedValues(cursor2, void 0);
145128
- if (state.cursors.size === 0) {
145129
- activeCallbacks.delete(target);
145130
- state.leaveRunning();
145131
- }
145132
- };
145133
- try {
145134
- budget.setRetainedDataUsage(cursor2, 1);
145135
- budget.setRetainedValues(cursor2, () => cursor2.pending);
145136
- for (const key3 of keys) updatePendingKeys(cursor2, "add", key3);
145137
- } catch (error3) {
145138
- leave();
145139
- throw error3;
145140
- }
145141
- return {
145142
- next: () => {
145143
- budget.visitNode();
145144
- for (const key3 of cursor2.pending) {
145145
- cursor2.pending.delete(key3);
145146
- budget.setRetainedDataUsage(cursor2, 1 + cursor2.pending.size);
145147
- return { done: false, value: key3 };
145148
- }
145149
- return { done: true, value: void 0 };
145150
- },
145151
- leave
145152
- };
145153
- }
145154
- function updateKeyedCollectionCallbacks(target, mutation, key3) {
145155
- const state = activeCallbacks.get(target);
145156
- if (state === void 0) return;
145157
- for (const cursor2 of state.cursors) updatePendingKeys(cursor2, mutation, key3);
145158
- }
145159
- function updatePendingKeys(cursor2, mutation, key3) {
145160
- const { budget, pending } = cursor2;
145161
- budget.visitNode();
145162
- if (mutation === "add") {
145163
- const nextSize = pending.has(key3) ? pending.size : pending.size + 1;
145164
- budget.allocateCollectionEntries(nextSize);
145165
- budget.setRetainedDataUsage(cursor2, 1 + nextSize);
145166
- pending.add(key3);
145167
- } else {
145168
- if (mutation === "delete") pending.delete(key3);
145169
- else pending.clear();
145170
- budget.setRetainedDataUsage(cursor2, 1 + pending.size);
145171
- }
145172
- }
145173
- var activeCallbacks;
145174
- var init_collection_callback = __esm({
145175
- "packages/safe-js/src/interp/methods/collection-callback.ts"() {
145176
- "use strict";
145177
- init_running_state();
145178
- activeCallbacks = /* @__PURE__ */ new WeakMap();
145179
- }
145180
- });
145181
-
145182
- // packages/safe-js/src/interp/methods/map.ts
145183
- function isMapMethodName(value) {
145184
- return typeof value === "string" && mapMethodNames.has(value);
145185
- }
145186
- function getMapMember(target, property, options) {
145187
- if (property === "size") {
145188
- return target.entries.size;
145189
- }
145190
- if (!isMapMethodName(property)) {
145191
- return void 0;
145192
- }
145193
- return createSandboxClosure({
145194
- sandbox: true,
145195
- call: (args, context) => {
145196
- const receiver = context?.thisValue;
145197
- if (!isSandboxMap(receiver)) throw new TypeError(`Map#${property} requires a Map receiver.`);
145198
- return callMapMethod(receiver, property, args, options, context?.stack ?? []);
145199
- },
145200
- name: property
145201
- });
145202
- }
145203
- async function callMapMethod(target, methodName, args, options, stack = []) {
145204
- switch (methodName) {
145205
- case "get":
145206
- return target.entries.get(args[0]);
145207
- case "set": {
145208
- assertCollectionMutable(target);
145209
- const exists4 = target.entries.has(args[0]);
145210
- const nextSize = exists4 ? target.entries.size : target.entries.size + 1;
145211
- options.budget.allocateCollectionEntries(nextSize);
145212
- if (!exists4) updateKeyedCollectionCallbacks(target, "add", args[0]);
145213
- target.entries.set(args[0], args[1]);
145214
- return target;
145215
- }
145216
- case "has":
145217
- return target.entries.has(args[0]);
145218
- case "delete": {
145219
- assertCollectionMutable(target);
145220
- const deleted = target.entries.delete(args[0]);
145221
- if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
145222
- return deleted;
145223
- }
145224
- case "clear":
145225
- assertCollectionMutable(target);
145226
- target.entries.clear();
145227
- updateKeyedCollectionCallbacks(target, "clear");
145228
- return void 0;
145229
- case "forEach": {
145230
- const callback = args[0];
145231
- if (!isSandboxClosure(callback)) {
145232
- throw new TypeError("Map.prototype.forEach requires a callback function.");
145233
- }
145234
- const cursor2 = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
145235
- try {
145236
- for (let entry = cursor2.next(); !entry.done; entry = cursor2.next()) {
145237
- const key3 = entry.value;
145238
- const value = target.entries.get(key3);
145239
- await options.callClosure(callback, [value, key3, target], stack, args[1]);
145240
- }
145241
- } finally {
145242
- cursor2.leave();
145243
- }
145244
- return void 0;
145245
- }
145246
- case "keys":
145247
- case "values":
145248
- case "entries":
145249
- return createSandboxCollectionIterator(target, methodName);
145250
- }
145251
- }
145252
- var mapMethodNames;
145253
- var init_map = __esm({
145254
- "packages/safe-js/src/interp/methods/map.ts"() {
145255
- "use strict";
145256
- init_values();
145257
- init_running_state();
145258
- init_collection_callback();
145259
- init_collection_iterator();
145260
- mapMethodNames = /* @__PURE__ */ new Set([
145261
- "get",
145262
- "set",
145263
- "has",
145264
- "delete",
145265
- "clear",
145266
- "forEach",
145267
- "keys",
145268
- "values",
145269
- "entries"
145270
- ]);
145271
- }
145272
- });
145273
-
145274
- // packages/safe-js/src/interp/methods/number.ts
145275
- function getNumberMember(property, budget) {
145276
- if (!isNumberMethodName(property)) {
145277
- return void 0;
145278
- }
145279
- return createSandboxClosure({
145280
- sandbox: true,
145281
- name: `Number#${property}`,
145282
- call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
145283
- });
145284
- }
145285
- function isNumberMethodName(property) {
145286
- return typeof property === "string" && numberMethodNames.has(property);
145287
- }
145288
- function callNumberMethod(value, methodName, args, budget, context) {
145289
- if (typeof value !== "number") {
145290
- throw new TypeError(`Number#${methodName} requires a number receiver.`);
145291
- }
145292
- const argument = args[0];
145293
- if (argument !== null && typeof argument === "object") {
145294
- return formatObjectArgument(value, methodName, argument, budget, context);
145295
- }
145296
- return formatNumber3(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
145297
- }
145298
- async function formatObjectArgument(value, methodName, argument, budget, context) {
145299
- const retainedArgument = {};
145300
- budget.setRetainedValues(retainedArgument, () => [argument]);
145301
- try {
145302
- const number = await sandboxNumber(argument, budget, context);
145303
- return formatNumber3(value, methodName, number, budget);
145304
- } finally {
145305
- budget.setRetainedValues(retainedArgument, void 0);
145306
- }
145307
- }
145308
- function formatNumber3(value, methodName, argument, budget) {
145309
- let result;
145310
- try {
145311
- result = value[methodName](argument);
145312
- } catch (error3) {
145313
- if (!(error3 instanceof RangeError)) throw error3;
145314
- 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.";
145315
- throw new RangeError(`Number#${methodName} ${detail}`);
145316
- }
145317
- return budget.allocateString(result);
145318
- }
145319
- var numberMethodNames;
145320
- var init_number = __esm({
145321
- "packages/safe-js/src/interp/methods/number.ts"() {
145322
- "use strict";
145323
- init_string_coercion();
145324
- init_values();
145325
- numberMethodNames = /* @__PURE__ */ new Set([
145326
- "toExponential",
145327
- "toFixed",
145328
- "toPrecision",
145329
- "toString"
145330
- ]);
145331
- }
145332
- });
145333
-
145334
- // packages/safe-js/src/interp/methods/generator.ts
145335
- function getGeneratorMember(target, property, budget) {
145336
- if (typeof property !== "string" || !generatorMethodNames.has(property)) {
145337
- return void 0;
145338
- }
145339
- return createSandboxClosure({
145340
- sandbox: true,
145341
- name: property,
145342
- call: async ([value]) => {
145343
- const iterator = getSandboxIterator(target);
145344
- const result = await iterator[property](value);
145345
- return allocateProducedSandboxValue(
145346
- { value: result.value, done: result.done === true },
145347
- budget
145348
- );
145349
- }
145350
- });
145351
- }
145352
- var generatorMethodNames;
145353
- var init_generator2 = __esm({
145354
- "packages/safe-js/src/interp/methods/generator.ts"() {
145355
- "use strict";
145356
- init_iteration();
145357
- init_values();
145358
- generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
145359
- }
145360
- });
145361
-
145362
145398
  // packages/safe-js/src/interp/methods/string.ts
145363
145399
  function getStringMember(value, property, budget) {
145364
145400
  const index = getStringIndex(property);
@@ -145877,6 +145913,256 @@ var init_string = __esm({
145877
145913
  }
145878
145914
  });
145879
145915
 
145916
+ // packages/safe-js/src/interp/methods/collection-callback.ts
145917
+ function enterKeyedCollectionCallback(target, keys, budget) {
145918
+ let state = activeCallbacks.get(target);
145919
+ if (state === void 0) {
145920
+ state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
145921
+ activeCallbacks.set(target, state);
145922
+ }
145923
+ const cursor2 = { budget, pending: /* @__PURE__ */ new Set() };
145924
+ state.cursors.add(cursor2);
145925
+ const leave = () => {
145926
+ if (!state.cursors.delete(cursor2)) return;
145927
+ cursor2.pending.clear();
145928
+ budget.setRetainedDataUsage(cursor2, 0);
145929
+ budget.setRetainedValues(cursor2, void 0);
145930
+ if (state.cursors.size === 0) {
145931
+ activeCallbacks.delete(target);
145932
+ state.leaveRunning();
145933
+ }
145934
+ };
145935
+ try {
145936
+ budget.setRetainedDataUsage(cursor2, 1);
145937
+ budget.setRetainedValues(cursor2, () => cursor2.pending);
145938
+ for (const key3 of keys) updatePendingKeys(cursor2, "add", key3);
145939
+ } catch (error3) {
145940
+ leave();
145941
+ throw error3;
145942
+ }
145943
+ return {
145944
+ next: () => {
145945
+ budget.visitNode();
145946
+ for (const key3 of cursor2.pending) {
145947
+ cursor2.pending.delete(key3);
145948
+ budget.setRetainedDataUsage(cursor2, 1 + cursor2.pending.size);
145949
+ return { done: false, value: key3 };
145950
+ }
145951
+ return { done: true, value: void 0 };
145952
+ },
145953
+ leave
145954
+ };
145955
+ }
145956
+ function updateKeyedCollectionCallbacks(target, mutation, key3) {
145957
+ const state = activeCallbacks.get(target);
145958
+ if (state === void 0) return;
145959
+ for (const cursor2 of state.cursors) updatePendingKeys(cursor2, mutation, key3);
145960
+ }
145961
+ function updatePendingKeys(cursor2, mutation, key3) {
145962
+ const { budget, pending } = cursor2;
145963
+ budget.visitNode();
145964
+ if (mutation === "add") {
145965
+ const nextSize = pending.has(key3) ? pending.size : pending.size + 1;
145966
+ budget.allocateCollectionEntries(nextSize);
145967
+ budget.setRetainedDataUsage(cursor2, 1 + nextSize);
145968
+ pending.add(key3);
145969
+ } else {
145970
+ if (mutation === "delete") pending.delete(key3);
145971
+ else pending.clear();
145972
+ budget.setRetainedDataUsage(cursor2, 1 + pending.size);
145973
+ }
145974
+ }
145975
+ var activeCallbacks;
145976
+ var init_collection_callback = __esm({
145977
+ "packages/safe-js/src/interp/methods/collection-callback.ts"() {
145978
+ "use strict";
145979
+ init_running_state();
145980
+ activeCallbacks = /* @__PURE__ */ new WeakMap();
145981
+ }
145982
+ });
145983
+
145984
+ // packages/safe-js/src/interp/methods/map.ts
145985
+ function isMapMethodName(value) {
145986
+ return typeof value === "string" && mapMethodNames.has(value);
145987
+ }
145988
+ function getMapMember(target, property, options) {
145989
+ if (property === "size") {
145990
+ return target.entries.size;
145991
+ }
145992
+ if (!isMapMethodName(property)) {
145993
+ return void 0;
145994
+ }
145995
+ return createSandboxClosure({
145996
+ sandbox: true,
145997
+ call: (args, context) => {
145998
+ const receiver = context?.thisValue;
145999
+ if (!isSandboxMap(receiver)) throw new TypeError(`Map#${property} requires a Map receiver.`);
146000
+ return callMapMethod(receiver, property, args, options, context?.stack ?? []);
146001
+ },
146002
+ name: property
146003
+ });
146004
+ }
146005
+ async function callMapMethod(target, methodName, args, options, stack = []) {
146006
+ switch (methodName) {
146007
+ case "get":
146008
+ return target.entries.get(args[0]);
146009
+ case "set": {
146010
+ assertCollectionMutable(target);
146011
+ const exists4 = target.entries.has(args[0]);
146012
+ const nextSize = exists4 ? target.entries.size : target.entries.size + 1;
146013
+ options.budget.allocateCollectionEntries(nextSize);
146014
+ if (!exists4) updateKeyedCollectionCallbacks(target, "add", args[0]);
146015
+ target.entries.set(args[0], args[1]);
146016
+ return target;
146017
+ }
146018
+ case "has":
146019
+ return target.entries.has(args[0]);
146020
+ case "delete": {
146021
+ assertCollectionMutable(target);
146022
+ const deleted = target.entries.delete(args[0]);
146023
+ if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
146024
+ return deleted;
146025
+ }
146026
+ case "clear":
146027
+ assertCollectionMutable(target);
146028
+ target.entries.clear();
146029
+ updateKeyedCollectionCallbacks(target, "clear");
146030
+ return void 0;
146031
+ case "forEach": {
146032
+ const callback = args[0];
146033
+ if (!isSandboxClosure(callback)) {
146034
+ throw new TypeError("Map.prototype.forEach requires a callback function.");
146035
+ }
146036
+ const cursor2 = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
146037
+ try {
146038
+ for (let entry = cursor2.next(); !entry.done; entry = cursor2.next()) {
146039
+ const key3 = entry.value;
146040
+ const value = target.entries.get(key3);
146041
+ await options.callClosure(callback, [value, key3, target], stack, args[1]);
146042
+ }
146043
+ } finally {
146044
+ cursor2.leave();
146045
+ }
146046
+ return void 0;
146047
+ }
146048
+ case "keys":
146049
+ case "values":
146050
+ case "entries":
146051
+ return createSandboxCollectionIterator(target, methodName);
146052
+ }
146053
+ }
146054
+ var mapMethodNames;
146055
+ var init_map = __esm({
146056
+ "packages/safe-js/src/interp/methods/map.ts"() {
146057
+ "use strict";
146058
+ init_values();
146059
+ init_running_state();
146060
+ init_collection_callback();
146061
+ init_collection_iterator();
146062
+ mapMethodNames = /* @__PURE__ */ new Set([
146063
+ "get",
146064
+ "set",
146065
+ "has",
146066
+ "delete",
146067
+ "clear",
146068
+ "forEach",
146069
+ "keys",
146070
+ "values",
146071
+ "entries"
146072
+ ]);
146073
+ }
146074
+ });
146075
+
146076
+ // packages/safe-js/src/interp/methods/number.ts
146077
+ function getNumberMember(property, budget) {
146078
+ if (!isNumberMethodName(property)) {
146079
+ return void 0;
146080
+ }
146081
+ return createSandboxClosure({
146082
+ sandbox: true,
146083
+ name: `Number#${property}`,
146084
+ call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
146085
+ });
146086
+ }
146087
+ function isNumberMethodName(property) {
146088
+ return typeof property === "string" && numberMethodNames.has(property);
146089
+ }
146090
+ function callNumberMethod(value, methodName, args, budget, context) {
146091
+ if (isSandboxBox(value)) value = boxedValue(value);
146092
+ if (typeof value !== "number") {
146093
+ throw new TypeError(`Number#${methodName} requires a number receiver.`);
146094
+ }
146095
+ const argument = args[0];
146096
+ if (argument !== null && typeof argument === "object") {
146097
+ return formatObjectArgument(value, methodName, argument, budget, context);
146098
+ }
146099
+ return formatNumber3(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
146100
+ }
146101
+ async function formatObjectArgument(value, methodName, argument, budget, context) {
146102
+ const retainedArgument = {};
146103
+ budget.setRetainedValues(retainedArgument, () => [argument]);
146104
+ try {
146105
+ const number = await sandboxNumber(argument, budget, context);
146106
+ return formatNumber3(value, methodName, number, budget);
146107
+ } finally {
146108
+ budget.setRetainedValues(retainedArgument, void 0);
146109
+ }
146110
+ }
146111
+ function formatNumber3(value, methodName, argument, budget) {
146112
+ let result;
146113
+ try {
146114
+ result = value[methodName](argument);
146115
+ } catch (error3) {
146116
+ if (!(error3 instanceof RangeError)) throw error3;
146117
+ 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.";
146118
+ throw new RangeError(`Number#${methodName} ${detail}`);
146119
+ }
146120
+ return budget.allocateString(result);
146121
+ }
146122
+ var numberMethodNames;
146123
+ var init_number = __esm({
146124
+ "packages/safe-js/src/interp/methods/number.ts"() {
146125
+ "use strict";
146126
+ init_string_coercion();
146127
+ init_boxed();
146128
+ init_values();
146129
+ numberMethodNames = /* @__PURE__ */ new Set([
146130
+ "toExponential",
146131
+ "toFixed",
146132
+ "toPrecision",
146133
+ "toString"
146134
+ ]);
146135
+ }
146136
+ });
146137
+
146138
+ // packages/safe-js/src/interp/methods/generator.ts
146139
+ function getGeneratorMember(target, property, budget) {
146140
+ if (typeof property !== "string" || !generatorMethodNames.has(property)) {
146141
+ return void 0;
146142
+ }
146143
+ return createSandboxClosure({
146144
+ sandbox: true,
146145
+ name: property,
146146
+ call: async ([value]) => {
146147
+ const iterator = getSandboxIterator(target);
146148
+ const result = await iterator[property](value);
146149
+ return allocateProducedSandboxValue(
146150
+ { value: result.value, done: result.done === true },
146151
+ budget
146152
+ );
146153
+ }
146154
+ });
146155
+ }
146156
+ var generatorMethodNames;
146157
+ var init_generator2 = __esm({
146158
+ "packages/safe-js/src/interp/methods/generator.ts"() {
146159
+ "use strict";
146160
+ init_iteration();
146161
+ init_values();
146162
+ generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
146163
+ }
146164
+ });
146165
+
145880
146166
  // packages/safe-js/src/interp/methods/set.ts
145881
146167
  function isSetMethodName(value) {
145882
146168
  return typeof value === "string" && setMethodNames.has(value);
@@ -146029,7 +146315,11 @@ function createObjectGlobal(methods, budget) {
146029
146315
  budget.chargeDataUsage(1);
146030
146316
  return /* @__PURE__ */ Object.create(null);
146031
146317
  }
146032
- if (typeof value !== "object") throw new TypeError("Object primitive boxing is not supported.");
146318
+ if (typeof value !== "object") {
146319
+ const box = createSandboxBox(value);
146320
+ budget.chargeDataUsage(measureSandboxData([box]));
146321
+ return box;
146322
+ }
146033
146323
  return value;
146034
146324
  };
146035
146325
  const constructor = createSandboxClosure({
@@ -146059,9 +146349,7 @@ function createObjectGlobal(methods, budget) {
146059
146349
  length: 0,
146060
146350
  call: (_args, context) => {
146061
146351
  const value = requireReceiver(context?.thisValue);
146062
- if (typeof value !== "object")
146063
- throw new TypeError("Object primitive boxing is not supported.");
146064
- return value;
146352
+ return construct([value]);
146065
146353
  }
146066
146354
  }),
146067
146355
  hasOwnProperty: createSandboxClosure({
@@ -146129,6 +146417,7 @@ function hasOwnSandboxProperty(value, key3, enumerable) {
146129
146417
  return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
146130
146418
  }
146131
146419
  function typeTag(value) {
146420
+ if (isSandboxBox(value)) value = boxedValue(value);
146132
146421
  if (value === void 0) return "Undefined";
146133
146422
  if (value === null) return "Null";
146134
146423
  if (typeof value === "string") return "String";
@@ -146155,6 +146444,7 @@ var init_object2 = __esm({
146155
146444
  "use strict";
146156
146445
  init_graph_depth();
146157
146446
  init_date();
146447
+ init_boxed();
146158
146448
  init_exceptions();
146159
146449
  init_float32();
146160
146450
  init_host_capabilities();
@@ -146162,6 +146452,7 @@ var init_object2 = __esm({
146162
146452
  init_object_model();
146163
146453
  init_string_coercion();
146164
146454
  init_values();
146455
+ init_values();
146165
146456
  }
146166
146457
  });
146167
146458
 
@@ -146251,12 +146542,12 @@ function isSandboxSetConstructor(value) {
146251
146542
  function populateCollection(source, collection, { name, budget, context, append, retainedValues }) {
146252
146543
  budget.allocateCollectionEntries(0);
146253
146544
  if (source === void 0 || source === null) return collection;
146254
- const iterator = getSandboxIterator(source, budget);
146545
+ const iterator = getSandboxIterator(source, budget, context);
146255
146546
  if (iterator === void 0) throw new TypeError(`${name} constructor requires an iterable.`);
146256
146547
  let entry;
146257
146548
  let failure;
146258
146549
  const retained = {};
146259
- budget.setRetainedValues(retained, () => [source, collection, entry, failure, ...retainedValues?.() ?? []]);
146550
+ budget.setRetainedValues(retained, () => [source, iterator.retainedValue, collection, entry, failure, ...retainedValues?.() ?? []]);
146260
146551
  const checkData = createDataCheckpoint(budget, context);
146261
146552
  const closeOnThrow = (error3) => {
146262
146553
  failure = isCapturedException(error3) ? error3.reason : error3;
@@ -146266,7 +146557,7 @@ function populateCollection(source, collection, { name, budget, context, append,
146266
146557
  };
146267
146558
  try {
146268
146559
  const closing = iterator.return?.();
146269
- if (iterator.generator) return Promise.resolve(closing).then(() => {
146560
+ if (iterator.generator || iterator.asynchronous) return Promise.resolve(closing).then(() => {
146270
146561
  throw error3;
146271
146562
  }, rethrow);
146272
146563
  } catch (closeError) {
@@ -146288,7 +146579,7 @@ function populateCollection(source, collection, { name, budget, context, append,
146288
146579
  }
146289
146580
  return false;
146290
146581
  };
146291
- if (iterator.generator) {
146582
+ if (iterator.generator || iterator.asynchronous) {
146292
146583
  return (async () => {
146293
146584
  try {
146294
146585
  checkData(collection, 0, true);
@@ -147238,22 +147529,29 @@ async function evaluateBinaryExpression(node, context) {
147238
147529
  if (left.kind !== "normal") {
147239
147530
  return left;
147240
147531
  }
147532
+ let leftValue = left.value;
147241
147533
  let rightValue;
147242
- const release2 = retainValues(context.budget, () => [left.value, rightValue]);
147534
+ const release2 = retainValues(context.budget, () => [leftValue, rightValue]);
147243
147535
  try {
147244
147536
  const right = await evaluateNode2(node.right, context);
147245
147537
  if (right.kind !== "normal") {
147246
147538
  return right;
147247
147539
  }
147248
147540
  rightValue = right.value;
147249
- let leftValue = left.value;
147250
147541
  if (node.operator === "in") {
147251
147542
  if (typeof right.value !== "object" || right.value === null) {
147252
147543
  throw new TypeError("Right-hand side of 'in' must be an object.");
147253
147544
  }
147254
147545
  leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
147255
147546
  }
147256
- const value = applyBinaryOperator(node, leftValue, right.value, context);
147547
+ if (!["in", "instanceof", "===", "!=="].includes(node.operator)) {
147548
+ const equality = node.operator === "==" || node.operator === "!=";
147549
+ if (isSandboxBox(leftValue) && (!equality || rightValue !== null && rightValue !== void 0 && typeof rightValue !== "object"))
147550
+ leftValue = await toNumericPrimitive(leftValue, context);
147551
+ if (isSandboxBox(rightValue) && (!equality || left.value !== null && left.value !== void 0 && typeof left.value !== "object"))
147552
+ rightValue = await toNumericPrimitive(rightValue, context);
147553
+ }
147554
+ const value = applyBinaryOperator(node, leftValue, rightValue, context);
147257
147555
  return {
147258
147556
  kind: "normal",
147259
147557
  hasValue: true,
@@ -147841,63 +148139,68 @@ async function evaluateForOfStatement(node, context) {
147841
148139
  };
147842
148140
  }
147843
148141
  async function evaluateForOfIterator(node, value, context, restoredEntry) {
147844
- const iterator = getSandboxIterator(value, context.budget);
148142
+ const iterator = getSandboxIterator(value, context.budget, createCoercionContext(context));
147845
148143
  if (iterator === void 0) {
147846
148144
  throw new TypeError(`${String(value)} is not a supported iterable`);
147847
148145
  }
147848
- const nodeId = node.nodeId ?? -1;
147849
- let index = consumeRestoredLoopIterationIndex(node, context);
147850
- for (let skipped = 0; skipped < index; skipped += 1) {
147851
- const skippedIteration = await iterator.next();
147852
- if (typeof skippedIteration !== "object" || skippedIteration === null) {
147853
- throw new TypeError("Iterator result must be an object.");
147854
- }
147855
- if (skippedIteration.done) {
147856
- return normalEmptyResult();
147857
- }
147858
- }
147859
- while (true) {
147860
- const iteration = restoredEntry ?? await iterator.next();
147861
- restoredEntry = void 0;
147862
- if (typeof iteration !== "object" || iteration === null) {
147863
- throw new TypeError("Iterator result must be an object.");
147864
- }
147865
- if (iteration.done) {
147866
- context.activeLoopIterations.delete(nodeId);
147867
- return normalEmptyResult();
147868
- }
147869
- context.activeLoopIterations.set(
147870
- nodeId,
147871
- iterator.snapshotIndex === void 0 ? index : {
147872
- get index() {
147873
- return iterator.snapshotIndex();
147874
- },
147875
- values: [value, iteration.value]
148146
+ const releaseIterator = retainValues(context.budget, () => [value, iterator.retainedValue]);
148147
+ try {
148148
+ const nodeId = node.nodeId ?? -1;
148149
+ let index = consumeRestoredLoopIterationIndex(node, context);
148150
+ for (let skipped = 0; skipped < index; skipped += 1) {
148151
+ const skippedIteration = await iterator.next();
148152
+ if (typeof skippedIteration !== "object" || skippedIteration === null) {
148153
+ throw new TypeError("Iterator result must be an object.");
148154
+ }
148155
+ if (skippedIteration.done) {
148156
+ return normalEmptyResult();
147876
148157
  }
147877
- );
147878
- const scope = context.scope.child();
147879
- const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
147880
- if (!binding.ok) {
147881
- return binding.result;
147882
- }
147883
- const iterationContext = createLoopIterationContext(context, scope);
147884
- emitLoopIterationBreakpoint(node, iterationContext);
147885
- const result = await evaluateNode2(node.body, iterationContext);
147886
- if (isMatchingBreak(result, loopLabels(node))) {
147887
- context.activeLoopIterations.delete(nodeId);
147888
- await closeIterator(iterator);
147889
- return normalEmptyResult();
147890
148158
  }
147891
- if (isMatchingContinue(result, loopLabels(node))) {
148159
+ while (true) {
148160
+ const iteration = restoredEntry ?? await iterator.next();
148161
+ restoredEntry = void 0;
148162
+ if (typeof iteration !== "object" || iteration === null) {
148163
+ throw new TypeError("Iterator result must be an object.");
148164
+ }
148165
+ if (iteration.done) {
148166
+ context.activeLoopIterations.delete(nodeId);
148167
+ return normalEmptyResult();
148168
+ }
148169
+ context.activeLoopIterations.set(
148170
+ nodeId,
148171
+ iterator.snapshotIndex === void 0 ? index : {
148172
+ get index() {
148173
+ return iterator.snapshotIndex();
148174
+ },
148175
+ values: [value, iteration.value]
148176
+ }
148177
+ );
148178
+ const scope = context.scope.child();
148179
+ const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
148180
+ if (!binding.ok) {
148181
+ return binding.result;
148182
+ }
148183
+ const iterationContext = createLoopIterationContext(context, scope);
148184
+ emitLoopIterationBreakpoint(node, iterationContext);
148185
+ const result = await evaluateNode2(node.body, iterationContext);
148186
+ if (isMatchingBreak(result, loopLabels(node))) {
148187
+ context.activeLoopIterations.delete(nodeId);
148188
+ await closeIterator(iterator);
148189
+ return normalEmptyResult();
148190
+ }
148191
+ if (isMatchingContinue(result, loopLabels(node))) {
148192
+ index += 1;
148193
+ continue;
148194
+ }
148195
+ if (result.kind !== "normal") {
148196
+ context.activeLoopIterations.delete(nodeId);
148197
+ await closeIterator(iterator);
148198
+ return result;
148199
+ }
147892
148200
  index += 1;
147893
- continue;
147894
- }
147895
- if (result.kind !== "normal") {
147896
- context.activeLoopIterations.delete(nodeId);
147897
- await closeIterator(iterator);
147898
- return result;
147899
148201
  }
147900
- index += 1;
148202
+ } finally {
148203
+ releaseIterator();
147901
148204
  }
147902
148205
  }
147903
148206
  async function evaluateForInStatement(node, context) {
@@ -148267,52 +148570,64 @@ async function evaluateYieldDelegate(node, context) {
148267
148570
  if (argument.kind !== "normal") {
148268
148571
  return argument;
148269
148572
  }
148270
- const iterator = getSandboxIterator(argument.value, context.budget);
148573
+ const iterator = getSandboxIterator(
148574
+ argument.value,
148575
+ context.budget,
148576
+ createCoercionContext(context)
148577
+ );
148271
148578
  if (iterator === void 0) {
148272
148579
  throw new TypeError(`${String(argument.value)} is not a supported iterable`);
148273
148580
  }
148274
- let completion = {
148275
- type: "normal",
148276
- value: void 0
148277
- };
148278
- const replay = context.generatorResume?.sent ?? [];
148279
- let replayIndex = 0;
148280
- while (true) {
148281
- const method = completion.type === "normal" ? "next" : completion.type;
148282
- const iteratorMethod = iterator[method];
148283
- if (iteratorMethod === void 0) {
148284
- if (completion.type === "throw") {
148285
- throw completion.value;
148581
+ const releaseIterator = retainValues(context.budget, () => [
148582
+ argument.value,
148583
+ iterator.retainedValue
148584
+ ]);
148585
+ try {
148586
+ let completion = {
148587
+ type: "normal",
148588
+ value: void 0
148589
+ };
148590
+ const replay = context.generatorResume?.sent ?? [];
148591
+ let replayIndex = 0;
148592
+ while (true) {
148593
+ const method = completion.type === "normal" ? "next" : completion.type;
148594
+ const iteratorMethod = iterator[method];
148595
+ if (iteratorMethod === void 0) {
148596
+ if (completion.type === "throw") {
148597
+ throw completion.value;
148598
+ }
148599
+ return generatorCompletionResult(completion);
148286
148600
  }
148287
- return generatorCompletionResult(completion);
148288
- }
148289
- const result = await iteratorMethod(completion.value);
148290
- if (result.done) {
148291
- if (completion.type === "return") {
148292
- return generatorCompletionResult({ type: "return", value: result.value });
148601
+ const result = await iteratorMethod(completion.value);
148602
+ if (result.done) {
148603
+ if (completion.type === "return") {
148604
+ return generatorCompletionResult({ type: "return", value: result.value });
148605
+ }
148606
+ return {
148607
+ kind: "normal",
148608
+ hasValue: true,
148609
+ value: result.value
148610
+ };
148293
148611
  }
148294
- return {
148295
- kind: "normal",
148296
- hasValue: true,
148297
- value: result.value
148298
- };
148299
- }
148300
- if (replayIndex < replay.length - 1) {
148301
- completion = replay[replayIndex + 1];
148302
- replayIndex += 1;
148303
- continue;
148612
+ if (replayIndex < replay.length - 1) {
148613
+ completion = replay[replayIndex + 1];
148614
+ replayIndex += 1;
148615
+ continue;
148616
+ }
148617
+ const completionPromise = context.generatorYield(
148618
+ allocateProducedSandboxValue(result.value, context.budget),
148619
+ node.nodeId
148620
+ );
148621
+ emitResumeBreakpoint(context, {
148622
+ kind: "generator-yield",
148623
+ nodeId: node.nodeId,
148624
+ span: node.span
148625
+ });
148626
+ completion = await completionPromise;
148627
+ context.generatorResume = void 0;
148304
148628
  }
148305
- const completionPromise = context.generatorYield(
148306
- allocateProducedSandboxValue(result.value, context.budget),
148307
- node.nodeId
148308
- );
148309
- emitResumeBreakpoint(context, {
148310
- kind: "generator-yield",
148311
- nodeId: node.nodeId,
148312
- span: node.span
148313
- });
148314
- completion = await completionPromise;
148315
- context.generatorResume = void 0;
148629
+ } finally {
148630
+ releaseIterator();
148316
148631
  }
148317
148632
  }
148318
148633
  function generatorCompletionResult(completion) {
@@ -148459,6 +148774,14 @@ async function evaluateMemberExpression(node, context) {
148459
148774
  }
148460
148775
  function getPropertyValue(target, property, context) {
148461
148776
  if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
148777
+ if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
148778
+ const prototype = getBoxedPrototype(target, context.budget);
148779
+ if (prototype !== void 0) {
148780
+ if (typeof target === "string" && (property === "length" || getStringIndex(property) !== void 0))
148781
+ return getStringMember(target, property, context.budget);
148782
+ return getMemberValue(prototype, property, context);
148783
+ }
148784
+ }
148462
148785
  if (typeof target === "string") return getStringMember(target, property, context.budget);
148463
148786
  if (typeof target === "number") return getNumberMember(property, context.budget);
148464
148787
  if (typeof target === "boolean") return void 0;
@@ -148630,6 +148953,15 @@ async function evaluateMemberCallExpression(node, context) {
148630
148953
  ...reference,
148631
148954
  property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
148632
148955
  };
148956
+ if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") && getBoxedPrototype(member.object, context.budget) !== void 0) {
148957
+ if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
148958
+ if (typeof member.object === "string" && isStringMethodName(member.property))
148959
+ return evaluateStringMethodCall(node, member.object, member.property, context);
148960
+ if (typeof member.object === "number" && isNumberMethodName(member.property))
148961
+ return evaluateNumberMethodCall(node, member.object, member.property, context);
148962
+ }
148963
+ return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
148964
+ }
148633
148965
  if (typeof member.object === "string" && isStringMethodName(member.property)) {
148634
148966
  return evaluateStringMethodCall(node, member.object, member.property, context);
148635
148967
  }
@@ -148979,7 +149311,7 @@ function hasSandboxProperty(value, key3, context) {
148979
149311
  while (typeof current === "object" && current !== null) {
148980
149312
  if (isGuestHostObject(current)) return hasHostObjectMember(current, key3);
148981
149313
  if (hasOwnSandboxProperty(current, key3, false)) return true;
148982
- if (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current)) {
149314
+ if (!(isGuestClosure(current) && hasExplicitSandboxPrototype(current)) && (Array.isArray(current) || !isPlainSandboxObject(current) || isSandboxDate(current) || isFloat32Array(current) || isSandboxGenerator(current) || isSandboxCollectionIterator(current))) {
148983
149315
  return getPropertyValue(current, key3, context) !== void 0;
148984
149316
  }
148985
149317
  current = getSandboxPrototype(current, context.budget);
@@ -148991,33 +149323,41 @@ function hasSandboxProperty(value, key3, context) {
148991
149323
  return false;
148992
149324
  }
148993
149325
  async function applyCompoundAssignmentOperator(operator, left, right, context) {
148994
- left = await toNumericPrimitive(left, context);
148995
- right = await toNumericPrimitive(right, context);
148996
- switch (operator) {
148997
- case "+=":
148998
- return applyAdditionOperator(left, right, context);
148999
- case "-=":
149000
- return toNumber(left) - toNumber(right);
149001
- case "*=":
149002
- return toNumber(left) * toNumber(right);
149003
- case "/=":
149004
- return toNumber(left) / toNumber(right);
149005
- case "%=":
149006
- return toNumber(left) % toNumber(right);
149007
- case "**=":
149008
- return toNumber(left) ** toNumber(right);
149009
- case "&=":
149010
- return toNumber(left) & toNumber(right);
149011
- case "|=":
149012
- return toNumber(left) | toNumber(right);
149013
- case "^=":
149014
- return toNumber(left) ^ toNumber(right);
149015
- case "<<=":
149016
- return toNumber(left) << toNumber(right);
149017
- case ">>=":
149018
- return toNumber(left) >> toNumber(right);
149019
- case ">>>=":
149020
- return toNumber(left) >>> toNumber(right);
149326
+ const convertingObject = typeof left === "object" && left !== null;
149327
+ let convertedLeft;
149328
+ const release2 = retainValues(context.budget, () => [convertedLeft]);
149329
+ try {
149330
+ left = await toNumericPrimitive(left, context);
149331
+ if (convertingObject) convertedLeft = left;
149332
+ right = await toNumericPrimitive(right, context);
149333
+ switch (operator) {
149334
+ case "+=":
149335
+ return applyAdditionOperator(left, right, context);
149336
+ case "-=":
149337
+ return toNumber(left) - toNumber(right);
149338
+ case "*=":
149339
+ return toNumber(left) * toNumber(right);
149340
+ case "/=":
149341
+ return toNumber(left) / toNumber(right);
149342
+ case "%=":
149343
+ return toNumber(left) % toNumber(right);
149344
+ case "**=":
149345
+ return toNumber(left) ** toNumber(right);
149346
+ case "&=":
149347
+ return toNumber(left) & toNumber(right);
149348
+ case "|=":
149349
+ return toNumber(left) | toNumber(right);
149350
+ case "^=":
149351
+ return toNumber(left) ^ toNumber(right);
149352
+ case "<<=":
149353
+ return toNumber(left) << toNumber(right);
149354
+ case ">>=":
149355
+ return toNumber(left) >> toNumber(right);
149356
+ case ">>>=":
149357
+ return toNumber(left) >>> toNumber(right);
149358
+ }
149359
+ } finally {
149360
+ release2();
149021
149361
  }
149022
149362
  }
149023
149363
  function applyAdditionOperator(left, right, context) {
@@ -149414,12 +149754,12 @@ async function evaluateSpreadElement(node, context) {
149414
149754
  result: value
149415
149755
  };
149416
149756
  }
149417
- const iterator = getSandboxIterator(value.value, context.budget);
149757
+ const iterator = getSandboxIterator(value.value, context.budget, createCoercionContext(context));
149418
149758
  if (iterator === void 0) {
149419
149759
  throw new TypeError("Spread arguments must evaluate to an iterable.");
149420
149760
  }
149421
149761
  const spreadValues = [];
149422
- const release2 = retainValues(context.budget, () => [value.value, ...spreadValues]);
149762
+ const release2 = retainValues(context.budget, () => [value.value, iterator.retainedValue, ...spreadValues]);
149423
149763
  try {
149424
149764
  while (true) {
149425
149765
  const next = await iterator.next();
@@ -149540,6 +149880,7 @@ var init_interpreter = __esm({
149540
149880
  init_array();
149541
149881
  init_function();
149542
149882
  init_object_model();
149883
+ init_string();
149543
149884
  init_graph_depth();
149544
149885
  init_map();
149545
149886
  init_number();
@@ -149559,6 +149900,7 @@ var init_interpreter = __esm({
149559
149900
  init_float32array2();
149560
149901
  init_float32();
149561
149902
  init_date();
149903
+ init_boxed();
149562
149904
  init_date2();
149563
149905
  init_values();
149564
149906
  init_scope();
@@ -150603,6 +150945,30 @@ function copyHostValueToSandbox(value, stackFrames, options, state, path193) {
150603
150945
  state
150604
150946
  );
150605
150947
  }
150948
+ const primitive = nativeBoxedValue(value);
150949
+ if (primitive !== void 0) {
150950
+ if (typeof primitive === "string") budget.allocateString(primitive);
150951
+ const original = value;
150952
+ const existing = state.seen.get(original);
150953
+ if (existing !== void 0) return existing;
150954
+ const copy = createSandboxBox(primitive);
150955
+ state.seen.set(original, copy);
150956
+ budget.chargeDataUsage(measureSandboxData([copy]));
150957
+ for (const [key3, descriptor] of boxedDataProperties(original)) {
150958
+ if (!("value" in descriptor)) throw new TypeError(`Unsupported sandbox value at ${joinPath2(path193, key3)}: accessor property`);
150959
+ Object.defineProperty(copy, budget.allocateString(key3), {
150960
+ ...descriptor,
150961
+ value: copyHostValueToSandbox(
150962
+ descriptor.value,
150963
+ stackFrames,
150964
+ { ...options, capabilityPath: [...options.capabilityPath ?? [], key3] },
150965
+ state,
150966
+ joinPath2(path193, key3)
150967
+ )
150968
+ });
150969
+ }
150970
+ return copy;
150971
+ }
150606
150972
  const date = copyNativeDate(value);
150607
150973
  if (date !== void 0) {
150608
150974
  const existing = state.seen.get(value);
@@ -150893,6 +151259,7 @@ var init_host_bridge = __esm({
150893
151259
  "use strict";
150894
151260
  init_async();
150895
151261
  init_date();
151262
+ init_boxed();
150896
151263
  init_host_capabilities();
150897
151264
  init_shape();
150898
151265
  init_budget2();
@@ -150927,12 +151294,18 @@ function createConsoleJsonGlobals(options) {
150927
151294
  JSON: {
150928
151295
  parse: createSandboxClosure({
150929
151296
  sandbox: true,
150930
- call: async ([text5]) => parseJson4(text5, options.budget),
151297
+ call: async ([text5], context) => {
151298
+ const converted = sandboxString(text5, options.budget, context);
151299
+ return copyJsonToSandbox(
151300
+ JSON.parse(converted instanceof Promise ? await converted : converted),
151301
+ options.budget
151302
+ );
151303
+ },
150931
151304
  name: "parse"
150932
151305
  }),
150933
151306
  stringify: createSandboxClosure({
150934
151307
  sandbox: true,
150935
- call: async ([value, replacer, indent]) => stringifyJson4(value, replacer, indent, options.budget),
151308
+ call: async ([value, replacer, indent], context) => stringifyJson4(value, replacer, indent, options.budget, context),
150936
151309
  name: "stringify"
150937
151310
  })
150938
151311
  },
@@ -150993,11 +151366,7 @@ function createConsoleJsonGlobals(options) {
150993
151366
  )
150994
151367
  };
150995
151368
  }
150996
- function parseJson4(input, budget) {
150997
- const text5 = budget.allocateString(toJsonParseText(input));
150998
- return copyJsonToSandbox(JSON.parse(text5), budget);
150999
- }
151000
- async function stringifyJson4(value, replacer, indent, budget) {
151369
+ async function stringifyJson4(value, replacer, indent, budget, context) {
151001
151370
  if (replacer !== void 0 && replacer !== null && !isSandboxClosure(replacer)) {
151002
151371
  throw new TypeError(
151003
151372
  "JSON.stringify(value, replacer, indent) only supports function, null, or undefined replacers."
@@ -151012,6 +151381,7 @@ async function stringifyJson4(value, replacer, indent, budget) {
151012
151381
  defineDataProperty8(holder, "", value);
151013
151382
  const output = await stringifyProperty("", holder, {
151014
151383
  budget,
151384
+ context,
151015
151385
  gap: normalizeStringifyGap(indent),
151016
151386
  replacer: isSandboxClosure(replacer) ? replacer : void 0,
151017
151387
  stack: []
@@ -151021,15 +151391,6 @@ async function stringifyJson4(value, replacer, indent, budget) {
151021
151391
  }
151022
151392
  return budget.allocateString(output);
151023
151393
  }
151024
- function toJsonParseText(input) {
151025
- if (Array.isArray(input)) {
151026
- return input.map((entry) => entry === null || entry === void 0 ? "" : toJsonParseText(entry)).join(",");
151027
- }
151028
- if (typeof input === "object" && input !== null) {
151029
- return "[object Object]";
151030
- }
151031
- return String(input);
151032
- }
151033
151394
  async function stringifyProperty(key3, holder, state, indent = "") {
151034
151395
  let value = getOwnDataValue(holder, key3);
151035
151396
  if (isSandboxDate(value)) {
@@ -151046,6 +151407,10 @@ async function stringifyProperty(key3, holder, state, indent = "") {
151046
151407
  return stringifyValue3(value, state, indent);
151047
151408
  }
151048
151409
  async function stringifyValue3(value, state, indent) {
151410
+ if (isSandboxBox(value)) {
151411
+ const primitive = boxedValue(value);
151412
+ value = typeof primitive === "number" ? await sandboxNumber(value, state.budget, state.context) : typeof primitive === "string" ? await sandboxString(value, state.budget, state.context) : primitive;
151413
+ }
151049
151414
  if (value === null) {
151050
151415
  return "null";
151051
151416
  }
@@ -151221,6 +151586,8 @@ var init_console_json = __esm({
151221
151586
  "packages/safe-js/src/interp/globals/console-json.ts"() {
151222
151587
  "use strict";
151223
151588
  init_date();
151589
+ init_boxed();
151590
+ init_string_coercion();
151224
151591
  init_compile_guard();
151225
151592
  init_host_bridge();
151226
151593
  init_values();
@@ -151468,7 +151835,7 @@ function structuredCloneSandboxValue(value, budget, parent) {
151468
151835
  const operation = budget.acquireCompileOwner(false, parent?.owner);
151469
151836
  const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
151470
151837
  try {
151471
- const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
151838
+ const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true, structuredClone: true });
151472
151839
  assertSandboxGraphDepth(clone);
151473
151840
  assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
151474
151841
  allocateProducedSandboxValue(clone, budget);
@@ -151516,6 +151883,82 @@ var init_misc = __esm({
151516
151883
  }
151517
151884
  });
151518
151885
 
151886
+ // packages/safe-js/src/interp/globals/primitives.ts
151887
+ function createPrimitiveConstructor(options, budget) {
151888
+ const initial = { Number: 0, String: "", Boolean: false }[options.name];
151889
+ const kind = typeof initial;
151890
+ const prototype = createSandboxBox(initial);
151891
+ const allocate = (value) => {
151892
+ const box = createSandboxBox(value);
151893
+ budget.chargeDataUsage(measureSandboxData([box]));
151894
+ return box;
151895
+ };
151896
+ const constructor = createSandboxClosure({
151897
+ guest: true,
151898
+ sandbox: true,
151899
+ name: options.name,
151900
+ length: 1,
151901
+ call: options.call,
151902
+ construct: (args, context) => {
151903
+ const value = options.call(args, context);
151904
+ return value instanceof Promise ? value.then(allocate) : allocate(value);
151905
+ }
151906
+ });
151907
+ const properties = materializeFunctionProperties(constructor);
151908
+ Object.defineProperty(properties, "prototype", { value: prototype, writable: false });
151909
+ Object.defineProperty(prototype, "constructor", {
151910
+ value: constructor,
151911
+ writable: true,
151912
+ configurable: true
151913
+ });
151914
+ for (const [name, value] of Object.entries(options.properties ?? {}))
151915
+ Object.defineProperty(properties, name, {
151916
+ value,
151917
+ writable: isSandboxClosure(value),
151918
+ configurable: isSandboxClosure(value)
151919
+ });
151920
+ const methods = /* @__PURE__ */ new Map([
151921
+ [
151922
+ "valueOf",
151923
+ createSandboxClosure({
151924
+ sandbox: true,
151925
+ name: "valueOf",
151926
+ length: 0,
151927
+ call: (_args, context) => primitiveReceiver(context?.thisValue, kind)
151928
+ })
151929
+ ]
151930
+ ]);
151931
+ if (kind === "number") {
151932
+ for (const name of numberMethodNames) methods.set(name, getNumberMember(name, budget));
151933
+ } else {
151934
+ methods.set(
151935
+ "toString",
151936
+ createSandboxClosure({
151937
+ sandbox: true,
151938
+ name: "toString",
151939
+ length: 0,
151940
+ call: (_args, context) => budget.allocateString(String(primitiveReceiver(context?.thisValue, kind)))
151941
+ })
151942
+ );
151943
+ if (kind === "string")
151944
+ for (const name of stringMethodNames) methods.set(name, getStringMember("", name, budget));
151945
+ }
151946
+ for (const [name, value] of methods)
151947
+ Object.defineProperty(prototype, name, { value, writable: true, configurable: true });
151948
+ installBoxedPrototype(budget, prototype, constructor);
151949
+ return constructor;
151950
+ }
151951
+ var init_primitives = __esm({
151952
+ "packages/safe-js/src/interp/globals/primitives.ts"() {
151953
+ "use strict";
151954
+ init_boxed();
151955
+ init_object_model();
151956
+ init_number();
151957
+ init_string();
151958
+ init_values();
151959
+ }
151960
+ });
151961
+
151519
151962
  // packages/safe-js/src/interp/globals/object-array.ts
151520
151963
  function createObjectArrayGlobals(options) {
151521
151964
  return {
@@ -151581,6 +152024,7 @@ function createObjectArrayGlobals(options) {
151581
152024
  sandbox: true,
151582
152025
  call: ([value]) => {
151583
152026
  if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
152027
+ if (value !== null && value !== void 0 && typeof value !== "object") value = createSandboxBox(value);
151584
152028
  objectProperties(value);
151585
152029
  return getSandboxPrototype(value, options.budget);
151586
152030
  },
@@ -151620,11 +152064,11 @@ function createObjectArrayGlobals(options) {
151620
152064
  fromEntries: createSandboxClosure({
151621
152065
  sandbox: true,
151622
152066
  call: ([value], context) => {
151623
- const iterator = getSandboxIterator(value, options.budget);
152067
+ const iterator = getSandboxIterator(value, options.budget, context);
151624
152068
  if (iterator === void 0) {
151625
152069
  throw new TypeError("Object.fromEntries requires an iterable.");
151626
152070
  }
151627
- if (context === void 0 && !iterator.generator) {
152071
+ if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
151628
152072
  return allocateProducedSandboxValue(
151629
152073
  Object.setPrototypeOf(
151630
152074
  Reflect.apply(Object.fromEntries, Object, [{ [Symbol.iterator]: () => iterator }]),
@@ -151682,8 +152126,7 @@ function createObjectArrayGlobals(options) {
151682
152126
  })
151683
152127
  }
151684
152128
  }),
151685
- String: createSandboxClosure({
151686
- sandbox: true,
152129
+ String: createPrimitiveConstructor({
151687
152130
  call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
151688
152131
  name: "String",
151689
152132
  properties: {
@@ -151703,9 +152146,8 @@ function createObjectArrayGlobals(options) {
151703
152146
  name: "fromCodePoint"
151704
152147
  })
151705
152148
  }
151706
- }),
151707
- Number: createSandboxClosure({
151708
- sandbox: true,
152149
+ }, options.budget),
152150
+ Number: createPrimitiveConstructor({
151709
152151
  call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
151710
152152
  name: "Number",
151711
152153
  properties: {
@@ -151739,12 +152181,11 @@ function createObjectArrayGlobals(options) {
151739
152181
  NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
151740
152182
  POSITIVE_INFINITY: Number.POSITIVE_INFINITY
151741
152183
  }
151742
- }),
151743
- Boolean: createSandboxClosure({
151744
- sandbox: true,
152184
+ }, options.budget),
152185
+ Boolean: createPrimitiveConstructor({
151745
152186
  call: ([value]) => Boolean(value),
151746
152187
  name: "Boolean"
151747
- })
152188
+ }, options.budget)
151748
152189
  };
151749
152190
  }
151750
152191
  async function objectFromSandboxEntries(items, iterator, budget, context) {
@@ -151754,7 +152195,7 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
151754
152195
  let value;
151755
152196
  let failure;
151756
152197
  const retained = {};
151757
- budget.setRetainedValues(retained, () => [items, object, entry, key3, value, failure]);
152198
+ budget.setRetainedValues(retained, () => [items, iterator.retainedValue, object, entry, key3, value, failure]);
151758
152199
  const checkData = createDataCheckpoint(budget, context);
151759
152200
  const closeOnThrow = async (error3) => {
151760
152201
  failure = isCapturedException(error3) ? error3.reason : error3;
@@ -151805,6 +152246,10 @@ function assignSandboxValues(target, sources, budget) {
151805
152246
  if (target === null || target === void 0) {
151806
152247
  throw new TypeError("Object.assign(target, ...sources) requires a non-null target.");
151807
152248
  }
152249
+ if (typeof target !== "object") {
152250
+ target = createSandboxBox(target);
152251
+ budget.chargeDataUsage(measureSandboxData([target]));
152252
+ }
151808
152253
  if (!isGuestClosure(target) && !isAssignableSandboxTarget(target)) {
151809
152254
  throw new TypeError("Object.assign(target, ...sources) requires an object or array target.");
151810
152255
  }
@@ -151874,13 +152319,13 @@ async function arrayFromSandboxValues(args, budget, context) {
151874
152319
  throw new TypeError("Array.from requires a non-null input.");
151875
152320
  }
151876
152321
  const read = (property) => context?.getProperty !== void 0 ? context.getProperty(items, property) : getSandboxDataProperty(items, property, budget);
151877
- const iterator = getSandboxIterator(items, budget);
152322
+ const iterator = getSandboxIterator(items, budget, context);
151878
152323
  const constructor = context?.thisValue;
151879
152324
  let result;
151880
152325
  let currentValue;
151881
152326
  let failure;
151882
152327
  const retained = {};
151883
- budget.setRetainedValues(retained, () => [items, mapFn, constructor, result, currentValue, failure]);
152328
+ budget.setRetainedValues(retained, () => [items, iterator?.retainedValue, mapFn, constructor, result, currentValue, failure]);
151884
152329
  const checkData = createDataCheckpoint(budget, context);
151885
152330
  const closeOnThrow = async (error3) => {
151886
152331
  failure = isCapturedException(error3) ? error3.reason : error3;
@@ -151993,6 +152438,7 @@ var init_object_array = __esm({
151993
152438
  init_data_checkpoint();
151994
152439
  init_exceptions();
151995
152440
  init_date();
152441
+ init_boxed();
151996
152442
  init_date2();
151997
152443
  init_object2();
151998
152444
  init_host_capabilities();
@@ -152001,6 +152447,7 @@ var init_object_array = __esm({
152001
152447
  init_iteration();
152002
152448
  init_string_coercion();
152003
152449
  init_numeric_parsers();
152450
+ init_primitives();
152004
152451
  init_object_model();
152005
152452
  init_values();
152006
152453
  }
@@ -152188,10 +152635,10 @@ var init_random = __esm({
152188
152635
 
152189
152636
  // packages/safe-js/src/realm.ts
152190
152637
  import { AsyncLocalStorage as AsyncLocalStorage9 } from "node:async_hooks";
152191
- import { types as types5 } from "node:util";
152638
+ import { types as types6 } from "node:util";
152192
152639
  function readModules(input) {
152193
152640
  const entries = (value, label) => {
152194
- if (types5.isMap(value) && !types5.isProxy(value)) {
152641
+ if (types6.isMap(value) && !types6.isProxy(value)) {
152195
152642
  const result = [...Map.prototype.entries.call(value)];
152196
152643
  if (result.length > 4096 || result.some(([key3]) => typeof key3 !== "string" || key3.length === 0))
152197
152644
  throw new TypeError(`${label} requires bounded string keys.`);
@@ -152305,7 +152752,7 @@ var init_realm = __esm({
152305
152752
  throw new TypeError("Realm limits must be positive safe integers with supported names.");
152306
152753
  this.limits[name] = Number(value);
152307
152754
  }
152308
- if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types5.isProxy(options.extensions)))
152755
+ if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types6.isProxy(options.extensions)))
152309
152756
  throw new TypeError("Extensions must be a registration array.");
152310
152757
  const registrations = options.extensions ?? [];
152311
152758
  const extensions = [];
@@ -152540,7 +152987,7 @@ var init_realm = __esm({
152540
152987
  return this.phase.run(phase, () => {
152541
152988
  try {
152542
152989
  const result = call();
152543
- if (types5.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
152990
+ if (types6.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
152544
152991
  return Promise.resolve(result).then(
152545
152992
  async (value) => {
152546
152993
  await Promise.allSettled(phase.pending);
@@ -152609,7 +153056,7 @@ var init_realm = __esm({
152609
153056
  },
152610
153057
  read: (operation, validate2) => {
152611
153058
  const value = this.invokeHost(operation, operation);
152612
- if (types5.isPromise(value)) {
153059
+ if (types6.isPromise(value)) {
152613
153060
  void Promise.resolve(value).catch(() => void 0);
152614
153061
  throw new TypeError("Live property operations must be synchronous.");
152615
153062
  }
@@ -152617,7 +153064,7 @@ var init_realm = __esm({
152617
153064
  },
152618
153065
  write: (operation, value) => {
152619
153066
  const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
152620
- if (types5.isPromise(result)) {
153067
+ if (types6.isPromise(result)) {
152621
153068
  void Promise.resolve(result).catch(() => void 0);
152622
153069
  throw new TypeError("Live property setters must be synchronous.");
152623
153070
  }
@@ -152826,7 +153273,7 @@ var init_realm = __esm({
152826
153273
  }
152827
153274
  });
152828
153275
  const output = getExtensionSetup(extension)(context);
152829
- if (types5.isPromise(output)) {
153276
+ if (types6.isPromise(output)) {
152830
153277
  void Promise.resolve(output).catch(() => void 0);
152831
153278
  throw new TypeError("Extension setup must be synchronous.");
152832
153279
  }
@@ -153455,6 +153902,8 @@ var init_serialize = __esm({
153455
153902
  init_float32();
153456
153903
  init_float32array();
153457
153904
  init_date();
153905
+ init_boxed();
153906
+ init_boxed2();
153458
153907
  init_values();
153459
153908
  UnsnapshotableValueError = class extends Error {
153460
153909
  path;