poe-code 14.0.62 → 14.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/index.js +929 -504
  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-KMTTD3BL.js} +2 -2
  6. package/packages/safe-js/dist/chunks/{chunk-VKGWGZBH.js → chunk-RU2BCN4G.js} +898 -521
  7. package/packages/safe-js/dist/chunks/chunk-RU2BCN4G.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 +172 -120
  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/number.d.ts +1 -0
  27. package/packages/safe-js/dist/interp/methods/number.js +4 -1
  28. package/packages/safe-js/dist/interp/methods/string.d.ts +2 -0
  29. package/packages/safe-js/dist/interp/methods/string.js +2 -2
  30. package/packages/safe-js/dist/interp/object-model.d.ts +5 -0
  31. package/packages/safe-js/dist/interp/object-model.js +41 -3
  32. package/packages/safe-js/dist/interp/promise.js +68 -61
  33. package/packages/safe-js/dist/interp/string-coercion.js +4 -1
  34. package/packages/safe-js/dist/interp/values.d.ts +1 -0
  35. package/packages/safe-js/dist/interp/values.js +78 -3
  36. package/packages/safe-js/dist/migrate.d.ts +2 -2
  37. package/packages/safe-js/dist/migration-file.d.ts +4 -4
  38. package/packages/safe-js/dist/snapshot/boxed.d.ts +16 -0
  39. package/packages/safe-js/dist/snapshot/boxed.js +52 -0
  40. package/packages/safe-js/dist/snapshot/dump-format.js +18 -5
  41. package/packages/safe-js/dist/snapshot/replay-data.d.ts +5 -0
  42. package/packages/safe-js/dist/snapshot/replay-data.js +24 -0
  43. package/packages/safe-js/dist/snapshot/restore.js +8 -0
  44. package/packages/safe-js/dist/snapshot/serialize.d.ts +4 -2
  45. package/packages/safe-js/dist/snapshot/serialize.js +18 -10
  46. package/packages/safe-js/dist/snapshot/validation.js +22 -1
  47. package/packages/safe-js/dist/chunks/chunk-VKGWGZBH.js.map +0 -7
  48. /package/packages/safe-js/dist/chunks/{chunk-F7TJSPDZ.js.map → chunk-KMTTD3BL.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,11 +131725,34 @@ function getGuestFunctionProperty(closure, key3) {
131527
131725
  function installObjectPrototype(budget, prototype, constructor) {
131528
131726
  prototypes.set(prototype, null);
131529
131727
  intrinsicPrototypes.set(budget, prototype);
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);
131530
131751
  const records = [prototype, materializeFunctionProperties(constructor)].map((value) => ({
131531
131752
  value,
131532
131753
  descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(value)))
131533
131754
  }));
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;
131755
+ 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;
131535
131756
  intrinsicConstructors.set(constructor, () => records.every(({ value, descriptors }) => {
131536
131757
  const current = Object.getOwnPropertyDescriptors(value);
131537
131758
  return Object.keys(current).length === descriptors.size && Object.keys(current).every((key3) => unchanged(descriptors.get(key3), current[key3]));
@@ -131539,12 +131760,17 @@ function installObjectPrototype(budget, prototype, constructor) {
131539
131760
  budget.setRetainedValues(prototype, () => records.flatMap(({ value, descriptors }) => Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key3, descriptor]) => unchanged(descriptors.get(key3), descriptor) ? [] : [key3, descriptor.value])));
131540
131761
  }
131541
131762
  function releaseObjectPrototype(budget) {
131542
- const prototype = intrinsicPrototypes.get(budget);
131543
- if (prototype !== void 0) budget.setRetainedValues(prototype, void 0);
131763
+ for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
131764
+ intrinsicPrototypeRoots.delete(budget);
131765
+ boxedPrototypes.delete(budget);
131544
131766
  intrinsicPrototypes.delete(budget);
131545
131767
  }
131546
131768
  function getSandboxPrototype(value, budget) {
131547
131769
  if (prototypes.has(value)) return prototypes.get(value) ?? null;
131770
+ if (budget !== void 0 && isSandboxBox(value)) {
131771
+ const prototype = getBoxedPrototype(boxedValue(value), budget);
131772
+ if (prototype !== void 0 && prototype !== value) return prototype;
131773
+ }
131548
131774
  return budget !== void 0 && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
131549
131775
  }
131550
131776
  function hasExplicitSandboxPrototype(value) {
@@ -131610,22 +131836,27 @@ function hasGuestObjectState(value) {
131610
131836
  if (intrinsicUnchanged !== void 0) return !intrinsicUnchanged();
131611
131837
  if (isLiveCapability(value)) return true;
131612
131838
  if (functionProperties.has(value) || prototypes.has(value)) return true;
131839
+ if (isSandboxBox(value)) return false;
131613
131840
  return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
131614
131841
  (descriptor) => !descriptor.enumerable || !descriptor.configurable || !descriptor.writable
131615
131842
  );
131616
131843
  }
131617
- var guestClosures, functionProperties, prototypes, intrinsicPrototypes, intrinsicConstructors, descriptorObjects;
131844
+ var guestClosures, functionProperties, prototypes, intrinsicPrototypes, boxedPrototypes, intrinsicPrototypeRoots, intrinsicConstructors, initialBoxedMethods, descriptorObjects;
131618
131845
  var init_object_model = __esm({
131619
131846
  "packages/safe-js/src/interp/object-model.ts"() {
131620
131847
  "use strict";
131621
131848
  init_graph_depth();
131622
131849
  init_host_capabilities();
131850
+ init_boxed();
131623
131851
  init_values();
131624
131852
  guestClosures = /* @__PURE__ */ new WeakSet();
131625
131853
  functionProperties = /* @__PURE__ */ new WeakMap();
131626
131854
  prototypes = /* @__PURE__ */ new WeakMap();
131627
131855
  intrinsicPrototypes = /* @__PURE__ */ new WeakMap();
131856
+ boxedPrototypes = /* @__PURE__ */ new WeakMap();
131857
+ intrinsicPrototypeRoots = /* @__PURE__ */ new WeakMap();
131628
131858
  intrinsicConstructors = /* @__PURE__ */ new WeakMap();
131859
+ initialBoxedMethods = /* @__PURE__ */ new WeakMap();
131629
131860
  descriptorObjects = /* @__PURE__ */ new WeakSet();
131630
131861
  }
131631
131862
  });
@@ -131722,7 +131953,7 @@ function serializeDumpValue(value, path193, state) {
131722
131953
  if (hasGuestObjectState(value)) {
131723
131954
  throw new TypeError("Guest function properties and prototype links cannot be serialized.");
131724
131955
  }
131725
- if (isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path193, state);
131956
+ if (isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value)) return serializeHeapReference(value, path193, state);
131726
131957
  if (Array.isArray(value)) {
131727
131958
  const reference2 = serializeHeapReference(value, path193, state);
131728
131959
  if (reference2 !== void 0) {
@@ -131746,7 +131977,13 @@ function serializeHeapReference(value, path193, state) {
131746
131977
  }
131747
131978
  if (!state.serializedHeapIds.has(id)) {
131748
131979
  state.serializedHeapIds.add(id);
131749
- if (isSandboxDate(value)) {
131980
+ if (isSandboxBox(value)) {
131981
+ state.heap[String(id)] = encodeBoxedData(value, (entry, key3) => {
131982
+ if (Object.is(entry, -0)) return { kind: "number", value: "-0" };
131983
+ const serialized = serializeDumpValue(entry, `${path193}.${key3}`, state);
131984
+ return serialized === SKIP_VALUE ? { kind: "undefined" } : serialized;
131985
+ });
131986
+ } else if (isSandboxDate(value)) {
131750
131987
  state.heap[String(id)] = { kind: "date", time: serializedDateTime(value) };
131751
131988
  } else if (isFloat32Array(value)) {
131752
131989
  const storage2 = encodeFloat32Storage(value, id, state.float32Buffers, (id2) => ({
@@ -131805,7 +132042,7 @@ function indexHeapContainers(snapshot2) {
131805
132042
  const heapIds = /* @__PURE__ */ new WeakMap();
131806
132043
  let nextId = 1;
131807
132044
  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)) {
132045
+ if (stat35.count > 1 || stat35.cyclic || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value) || Array.isArray(value) && requiresArrayEntries(value) || isSandboxArguments(value) || sandboxErrorTypes.has(value)) {
131809
132046
  heapIds.set(value, nextId);
131810
132047
  nextId += 1;
131811
132048
  }
@@ -131838,7 +132075,7 @@ function collectContainerStats(value, stats2, ancestors) {
131838
132075
  }
131839
132076
  stat35.expanded = true;
131840
132077
  ancestors.add(value);
131841
- const entries = isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
132078
+ const entries = isSandboxBox(value) ? boxedDataProperties(value).map(([, descriptor]) => descriptor.value) : isSandboxArguments(value) ? getSandboxArgumentEntries(value).map(([, entry]) => entry) : getEnumerableDataValues(value);
131842
132079
  for (const entry of entries) {
131843
132080
  collectContainerStats(entry, stats2, ancestors);
131844
132081
  }
@@ -131888,6 +132125,8 @@ var init_dump_format = __esm({
131888
132125
  init_float32();
131889
132126
  init_float32array();
131890
132127
  init_date();
132128
+ init_boxed();
132129
+ init_boxed2();
131891
132130
  DUMP_FORMAT_VERSION = 1;
131892
132131
  EXECUTION_SEMANTICS = "jobs-v8";
131893
132132
  SKIP_VALUE = /* @__PURE__ */ Symbol("SafeJS.skip-dump-value");
@@ -131895,7 +132134,7 @@ var init_dump_format = __esm({
131895
132134
  });
131896
132135
 
131897
132136
  // packages/safe-js/src/snapshot/validation.ts
131898
- import { types as types4 } from "node:util";
132137
+ import { types as types5 } from "node:util";
131899
132138
  function validateSnapshotData(value) {
131900
132139
  validateGenericValue(value, "$", 0, {
131901
132140
  allowFunctions: false,
@@ -131941,6 +132180,10 @@ function validateDumpHeap(root, state) {
131941
132180
  addUnique2(heapIds, id, path193);
131942
132181
  const entry = requireRecord3(value, path193);
131943
132182
  validateErrorType(entry, path193);
132183
+ if (entry.kind === "boxed") {
132184
+ validateBoxedRecord(entry, path193);
132185
+ continue;
132186
+ }
131944
132187
  if (entry.kind === "date") {
131945
132188
  validateDateRecord(entry, path193);
131946
132189
  continue;
@@ -132108,6 +132351,18 @@ function validateGeneratorShape(record2, path193, state) {
132108
132351
  }
132109
132352
  });
132110
132353
  }
132354
+ function validateBoxedRecord(record2, path193) {
132355
+ try {
132356
+ validateBoxedProperties(record2);
132357
+ } catch {
132358
+ fail2("invalidValue", path193, "invalid boxed primitive properties");
132359
+ }
132360
+ const value = record2.value;
132361
+ if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") return;
132362
+ const number = requireRecord3(value, `${path193}.value`);
132363
+ if (number.kind !== "number" || !["NaN", "Infinity", "-Infinity", "-0"].includes(String(number.value)))
132364
+ fail2("invalidValue", `${path193}.value`, "invalid boxed primitive payload");
132365
+ }
132111
132366
  function validateDateRecord(record2, path193) {
132112
132367
  if (Object.keys(record2).length !== 2) fail2("invalidValue", path193, "invalid Date fields");
132113
132368
  try {
@@ -132199,7 +132454,7 @@ function validateGenericValue(value, path193, depth, state) {
132199
132454
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
132200
132455
  fail2("invalidState", path193, "guest function properties, prototype links and custom descriptors cannot be restored");
132201
132456
  }
132202
- if (state.dataPropertiesOnly && types4.isProxy(value)) {
132457
+ if (state.dataPropertiesOnly && types5.isProxy(value)) {
132203
132458
  fail2("invalidType", path193, "proxy objects are not snapshot data");
132204
132459
  }
132205
132460
  if (depth > state.limits.maxDepth)
@@ -132334,6 +132589,7 @@ var init_validation = __esm({
132334
132589
  init_graph_depth();
132335
132590
  init_float32array();
132336
132591
  init_date();
132592
+ init_boxed2();
132337
132593
  init_object_model();
132338
132594
  DEFAULT_MAX_DEPTH = MAX_DATA_DEPTH;
132339
132595
  DEFAULT_MAX_ENTRIES = 1e5;
@@ -144275,7 +144531,10 @@ function isArrayMethodName(property) {
144275
144531
  }
144276
144532
  async function callArrayMethod(receiver, methodName, args, options, stack = []) {
144277
144533
  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.");
144534
+ if (typeof receiver !== "object") {
144535
+ receiver = createSandboxBox(receiver);
144536
+ options.budget.chargeDataUsage(measureSandboxData([receiver]));
144537
+ }
144279
144538
  const retainedReceiver = {};
144280
144539
  options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
144281
144540
  try {
@@ -144985,6 +145244,7 @@ var arrayLikeSources, activeArrayCallbacks, arrayMethodNames;
144985
145244
  var init_array = __esm({
144986
145245
  "packages/safe-js/src/interp/methods/array.ts"() {
144987
145246
  "use strict";
145247
+ init_boxed();
144988
145248
  init_values();
144989
145249
  init_running_state();
144990
145250
  init_object_model();
@@ -145111,254 +145371,6 @@ var init_function = __esm({
145111
145371
  }
145112
145372
  });
145113
145373
 
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
145374
  // packages/safe-js/src/interp/methods/string.ts
145363
145375
  function getStringMember(value, property, budget) {
145364
145376
  const index = getStringIndex(property);
@@ -145877,6 +145889,256 @@ var init_string = __esm({
145877
145889
  }
145878
145890
  });
145879
145891
 
145892
+ // packages/safe-js/src/interp/methods/collection-callback.ts
145893
+ function enterKeyedCollectionCallback(target, keys, budget) {
145894
+ let state = activeCallbacks.get(target);
145895
+ if (state === void 0) {
145896
+ state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
145897
+ activeCallbacks.set(target, state);
145898
+ }
145899
+ const cursor2 = { budget, pending: /* @__PURE__ */ new Set() };
145900
+ state.cursors.add(cursor2);
145901
+ const leave = () => {
145902
+ if (!state.cursors.delete(cursor2)) return;
145903
+ cursor2.pending.clear();
145904
+ budget.setRetainedDataUsage(cursor2, 0);
145905
+ budget.setRetainedValues(cursor2, void 0);
145906
+ if (state.cursors.size === 0) {
145907
+ activeCallbacks.delete(target);
145908
+ state.leaveRunning();
145909
+ }
145910
+ };
145911
+ try {
145912
+ budget.setRetainedDataUsage(cursor2, 1);
145913
+ budget.setRetainedValues(cursor2, () => cursor2.pending);
145914
+ for (const key3 of keys) updatePendingKeys(cursor2, "add", key3);
145915
+ } catch (error3) {
145916
+ leave();
145917
+ throw error3;
145918
+ }
145919
+ return {
145920
+ next: () => {
145921
+ budget.visitNode();
145922
+ for (const key3 of cursor2.pending) {
145923
+ cursor2.pending.delete(key3);
145924
+ budget.setRetainedDataUsage(cursor2, 1 + cursor2.pending.size);
145925
+ return { done: false, value: key3 };
145926
+ }
145927
+ return { done: true, value: void 0 };
145928
+ },
145929
+ leave
145930
+ };
145931
+ }
145932
+ function updateKeyedCollectionCallbacks(target, mutation, key3) {
145933
+ const state = activeCallbacks.get(target);
145934
+ if (state === void 0) return;
145935
+ for (const cursor2 of state.cursors) updatePendingKeys(cursor2, mutation, key3);
145936
+ }
145937
+ function updatePendingKeys(cursor2, mutation, key3) {
145938
+ const { budget, pending } = cursor2;
145939
+ budget.visitNode();
145940
+ if (mutation === "add") {
145941
+ const nextSize = pending.has(key3) ? pending.size : pending.size + 1;
145942
+ budget.allocateCollectionEntries(nextSize);
145943
+ budget.setRetainedDataUsage(cursor2, 1 + nextSize);
145944
+ pending.add(key3);
145945
+ } else {
145946
+ if (mutation === "delete") pending.delete(key3);
145947
+ else pending.clear();
145948
+ budget.setRetainedDataUsage(cursor2, 1 + pending.size);
145949
+ }
145950
+ }
145951
+ var activeCallbacks;
145952
+ var init_collection_callback = __esm({
145953
+ "packages/safe-js/src/interp/methods/collection-callback.ts"() {
145954
+ "use strict";
145955
+ init_running_state();
145956
+ activeCallbacks = /* @__PURE__ */ new WeakMap();
145957
+ }
145958
+ });
145959
+
145960
+ // packages/safe-js/src/interp/methods/map.ts
145961
+ function isMapMethodName(value) {
145962
+ return typeof value === "string" && mapMethodNames.has(value);
145963
+ }
145964
+ function getMapMember(target, property, options) {
145965
+ if (property === "size") {
145966
+ return target.entries.size;
145967
+ }
145968
+ if (!isMapMethodName(property)) {
145969
+ return void 0;
145970
+ }
145971
+ return createSandboxClosure({
145972
+ sandbox: true,
145973
+ call: (args, context) => {
145974
+ const receiver = context?.thisValue;
145975
+ if (!isSandboxMap(receiver)) throw new TypeError(`Map#${property} requires a Map receiver.`);
145976
+ return callMapMethod(receiver, property, args, options, context?.stack ?? []);
145977
+ },
145978
+ name: property
145979
+ });
145980
+ }
145981
+ async function callMapMethod(target, methodName, args, options, stack = []) {
145982
+ switch (methodName) {
145983
+ case "get":
145984
+ return target.entries.get(args[0]);
145985
+ case "set": {
145986
+ assertCollectionMutable(target);
145987
+ const exists4 = target.entries.has(args[0]);
145988
+ const nextSize = exists4 ? target.entries.size : target.entries.size + 1;
145989
+ options.budget.allocateCollectionEntries(nextSize);
145990
+ if (!exists4) updateKeyedCollectionCallbacks(target, "add", args[0]);
145991
+ target.entries.set(args[0], args[1]);
145992
+ return target;
145993
+ }
145994
+ case "has":
145995
+ return target.entries.has(args[0]);
145996
+ case "delete": {
145997
+ assertCollectionMutable(target);
145998
+ const deleted = target.entries.delete(args[0]);
145999
+ if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
146000
+ return deleted;
146001
+ }
146002
+ case "clear":
146003
+ assertCollectionMutable(target);
146004
+ target.entries.clear();
146005
+ updateKeyedCollectionCallbacks(target, "clear");
146006
+ return void 0;
146007
+ case "forEach": {
146008
+ const callback = args[0];
146009
+ if (!isSandboxClosure(callback)) {
146010
+ throw new TypeError("Map.prototype.forEach requires a callback function.");
146011
+ }
146012
+ const cursor2 = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
146013
+ try {
146014
+ for (let entry = cursor2.next(); !entry.done; entry = cursor2.next()) {
146015
+ const key3 = entry.value;
146016
+ const value = target.entries.get(key3);
146017
+ await options.callClosure(callback, [value, key3, target], stack, args[1]);
146018
+ }
146019
+ } finally {
146020
+ cursor2.leave();
146021
+ }
146022
+ return void 0;
146023
+ }
146024
+ case "keys":
146025
+ case "values":
146026
+ case "entries":
146027
+ return createSandboxCollectionIterator(target, methodName);
146028
+ }
146029
+ }
146030
+ var mapMethodNames;
146031
+ var init_map = __esm({
146032
+ "packages/safe-js/src/interp/methods/map.ts"() {
146033
+ "use strict";
146034
+ init_values();
146035
+ init_running_state();
146036
+ init_collection_callback();
146037
+ init_collection_iterator();
146038
+ mapMethodNames = /* @__PURE__ */ new Set([
146039
+ "get",
146040
+ "set",
146041
+ "has",
146042
+ "delete",
146043
+ "clear",
146044
+ "forEach",
146045
+ "keys",
146046
+ "values",
146047
+ "entries"
146048
+ ]);
146049
+ }
146050
+ });
146051
+
146052
+ // packages/safe-js/src/interp/methods/number.ts
146053
+ function getNumberMember(property, budget) {
146054
+ if (!isNumberMethodName(property)) {
146055
+ return void 0;
146056
+ }
146057
+ return createSandboxClosure({
146058
+ sandbox: true,
146059
+ name: `Number#${property}`,
146060
+ call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
146061
+ });
146062
+ }
146063
+ function isNumberMethodName(property) {
146064
+ return typeof property === "string" && numberMethodNames.has(property);
146065
+ }
146066
+ function callNumberMethod(value, methodName, args, budget, context) {
146067
+ if (isSandboxBox(value)) value = boxedValue(value);
146068
+ if (typeof value !== "number") {
146069
+ throw new TypeError(`Number#${methodName} requires a number receiver.`);
146070
+ }
146071
+ const argument = args[0];
146072
+ if (argument !== null && typeof argument === "object") {
146073
+ return formatObjectArgument(value, methodName, argument, budget, context);
146074
+ }
146075
+ return formatNumber3(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
146076
+ }
146077
+ async function formatObjectArgument(value, methodName, argument, budget, context) {
146078
+ const retainedArgument = {};
146079
+ budget.setRetainedValues(retainedArgument, () => [argument]);
146080
+ try {
146081
+ const number = await sandboxNumber(argument, budget, context);
146082
+ return formatNumber3(value, methodName, number, budget);
146083
+ } finally {
146084
+ budget.setRetainedValues(retainedArgument, void 0);
146085
+ }
146086
+ }
146087
+ function formatNumber3(value, methodName, argument, budget) {
146088
+ let result;
146089
+ try {
146090
+ result = value[methodName](argument);
146091
+ } catch (error3) {
146092
+ if (!(error3 instanceof RangeError)) throw error3;
146093
+ 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.";
146094
+ throw new RangeError(`Number#${methodName} ${detail}`);
146095
+ }
146096
+ return budget.allocateString(result);
146097
+ }
146098
+ var numberMethodNames;
146099
+ var init_number = __esm({
146100
+ "packages/safe-js/src/interp/methods/number.ts"() {
146101
+ "use strict";
146102
+ init_string_coercion();
146103
+ init_boxed();
146104
+ init_values();
146105
+ numberMethodNames = /* @__PURE__ */ new Set([
146106
+ "toExponential",
146107
+ "toFixed",
146108
+ "toPrecision",
146109
+ "toString"
146110
+ ]);
146111
+ }
146112
+ });
146113
+
146114
+ // packages/safe-js/src/interp/methods/generator.ts
146115
+ function getGeneratorMember(target, property, budget) {
146116
+ if (typeof property !== "string" || !generatorMethodNames.has(property)) {
146117
+ return void 0;
146118
+ }
146119
+ return createSandboxClosure({
146120
+ sandbox: true,
146121
+ name: property,
146122
+ call: async ([value]) => {
146123
+ const iterator = getSandboxIterator(target);
146124
+ const result = await iterator[property](value);
146125
+ return allocateProducedSandboxValue(
146126
+ { value: result.value, done: result.done === true },
146127
+ budget
146128
+ );
146129
+ }
146130
+ });
146131
+ }
146132
+ var generatorMethodNames;
146133
+ var init_generator2 = __esm({
146134
+ "packages/safe-js/src/interp/methods/generator.ts"() {
146135
+ "use strict";
146136
+ init_iteration();
146137
+ init_values();
146138
+ generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
146139
+ }
146140
+ });
146141
+
145880
146142
  // packages/safe-js/src/interp/methods/set.ts
145881
146143
  function isSetMethodName(value) {
145882
146144
  return typeof value === "string" && setMethodNames.has(value);
@@ -146029,7 +146291,11 @@ function createObjectGlobal(methods, budget) {
146029
146291
  budget.chargeDataUsage(1);
146030
146292
  return /* @__PURE__ */ Object.create(null);
146031
146293
  }
146032
- if (typeof value !== "object") throw new TypeError("Object primitive boxing is not supported.");
146294
+ if (typeof value !== "object") {
146295
+ const box = createSandboxBox(value);
146296
+ budget.chargeDataUsage(measureSandboxData([box]));
146297
+ return box;
146298
+ }
146033
146299
  return value;
146034
146300
  };
146035
146301
  const constructor = createSandboxClosure({
@@ -146059,9 +146325,7 @@ function createObjectGlobal(methods, budget) {
146059
146325
  length: 0,
146060
146326
  call: (_args, context) => {
146061
146327
  const value = requireReceiver(context?.thisValue);
146062
- if (typeof value !== "object")
146063
- throw new TypeError("Object primitive boxing is not supported.");
146064
- return value;
146328
+ return construct([value]);
146065
146329
  }
146066
146330
  }),
146067
146331
  hasOwnProperty: createSandboxClosure({
@@ -146129,6 +146393,7 @@ function hasOwnSandboxProperty(value, key3, enumerable) {
146129
146393
  return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
146130
146394
  }
146131
146395
  function typeTag(value) {
146396
+ if (isSandboxBox(value)) value = boxedValue(value);
146132
146397
  if (value === void 0) return "Undefined";
146133
146398
  if (value === null) return "Null";
146134
146399
  if (typeof value === "string") return "String";
@@ -146155,6 +146420,7 @@ var init_object2 = __esm({
146155
146420
  "use strict";
146156
146421
  init_graph_depth();
146157
146422
  init_date();
146423
+ init_boxed();
146158
146424
  init_exceptions();
146159
146425
  init_float32();
146160
146426
  init_host_capabilities();
@@ -146162,6 +146428,7 @@ var init_object2 = __esm({
146162
146428
  init_object_model();
146163
146429
  init_string_coercion();
146164
146430
  init_values();
146431
+ init_values();
146165
146432
  }
146166
146433
  });
146167
146434
 
@@ -146251,12 +146518,12 @@ function isSandboxSetConstructor(value) {
146251
146518
  function populateCollection(source, collection, { name, budget, context, append, retainedValues }) {
146252
146519
  budget.allocateCollectionEntries(0);
146253
146520
  if (source === void 0 || source === null) return collection;
146254
- const iterator = getSandboxIterator(source, budget);
146521
+ const iterator = getSandboxIterator(source, budget, context);
146255
146522
  if (iterator === void 0) throw new TypeError(`${name} constructor requires an iterable.`);
146256
146523
  let entry;
146257
146524
  let failure;
146258
146525
  const retained = {};
146259
- budget.setRetainedValues(retained, () => [source, collection, entry, failure, ...retainedValues?.() ?? []]);
146526
+ budget.setRetainedValues(retained, () => [source, iterator.retainedValue, collection, entry, failure, ...retainedValues?.() ?? []]);
146260
146527
  const checkData = createDataCheckpoint(budget, context);
146261
146528
  const closeOnThrow = (error3) => {
146262
146529
  failure = isCapturedException(error3) ? error3.reason : error3;
@@ -146266,7 +146533,7 @@ function populateCollection(source, collection, { name, budget, context, append,
146266
146533
  };
146267
146534
  try {
146268
146535
  const closing = iterator.return?.();
146269
- if (iterator.generator) return Promise.resolve(closing).then(() => {
146536
+ if (iterator.generator || iterator.asynchronous) return Promise.resolve(closing).then(() => {
146270
146537
  throw error3;
146271
146538
  }, rethrow);
146272
146539
  } catch (closeError) {
@@ -146288,7 +146555,7 @@ function populateCollection(source, collection, { name, budget, context, append,
146288
146555
  }
146289
146556
  return false;
146290
146557
  };
146291
- if (iterator.generator) {
146558
+ if (iterator.generator || iterator.asynchronous) {
146292
146559
  return (async () => {
146293
146560
  try {
146294
146561
  checkData(collection, 0, true);
@@ -147238,22 +147505,29 @@ async function evaluateBinaryExpression(node, context) {
147238
147505
  if (left.kind !== "normal") {
147239
147506
  return left;
147240
147507
  }
147508
+ let leftValue = left.value;
147241
147509
  let rightValue;
147242
- const release2 = retainValues(context.budget, () => [left.value, rightValue]);
147510
+ const release2 = retainValues(context.budget, () => [leftValue, rightValue]);
147243
147511
  try {
147244
147512
  const right = await evaluateNode2(node.right, context);
147245
147513
  if (right.kind !== "normal") {
147246
147514
  return right;
147247
147515
  }
147248
147516
  rightValue = right.value;
147249
- let leftValue = left.value;
147250
147517
  if (node.operator === "in") {
147251
147518
  if (typeof right.value !== "object" || right.value === null) {
147252
147519
  throw new TypeError("Right-hand side of 'in' must be an object.");
147253
147520
  }
147254
147521
  leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
147255
147522
  }
147256
- const value = applyBinaryOperator(node, leftValue, right.value, context);
147523
+ if (!["in", "instanceof", "===", "!=="].includes(node.operator)) {
147524
+ const equality = node.operator === "==" || node.operator === "!=";
147525
+ if (isSandboxBox(leftValue) && (!equality || rightValue !== null && rightValue !== void 0 && typeof rightValue !== "object"))
147526
+ leftValue = await toNumericPrimitive(leftValue, context);
147527
+ if (isSandboxBox(rightValue) && (!equality || left.value !== null && left.value !== void 0 && typeof left.value !== "object"))
147528
+ rightValue = await toNumericPrimitive(rightValue, context);
147529
+ }
147530
+ const value = applyBinaryOperator(node, leftValue, rightValue, context);
147257
147531
  return {
147258
147532
  kind: "normal",
147259
147533
  hasValue: true,
@@ -147841,63 +148115,68 @@ async function evaluateForOfStatement(node, context) {
147841
148115
  };
147842
148116
  }
147843
148117
  async function evaluateForOfIterator(node, value, context, restoredEntry) {
147844
- const iterator = getSandboxIterator(value, context.budget);
148118
+ const iterator = getSandboxIterator(value, context.budget, createCoercionContext(context));
147845
148119
  if (iterator === void 0) {
147846
148120
  throw new TypeError(`${String(value)} is not a supported iterable`);
147847
148121
  }
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]
148122
+ const releaseIterator = retainValues(context.budget, () => [value, iterator.retainedValue]);
148123
+ try {
148124
+ const nodeId = node.nodeId ?? -1;
148125
+ let index = consumeRestoredLoopIterationIndex(node, context);
148126
+ for (let skipped = 0; skipped < index; skipped += 1) {
148127
+ const skippedIteration = await iterator.next();
148128
+ if (typeof skippedIteration !== "object" || skippedIteration === null) {
148129
+ throw new TypeError("Iterator result must be an object.");
148130
+ }
148131
+ if (skippedIteration.done) {
148132
+ return normalEmptyResult();
147876
148133
  }
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
148134
  }
147891
- if (isMatchingContinue(result, loopLabels(node))) {
148135
+ while (true) {
148136
+ const iteration = restoredEntry ?? await iterator.next();
148137
+ restoredEntry = void 0;
148138
+ if (typeof iteration !== "object" || iteration === null) {
148139
+ throw new TypeError("Iterator result must be an object.");
148140
+ }
148141
+ if (iteration.done) {
148142
+ context.activeLoopIterations.delete(nodeId);
148143
+ return normalEmptyResult();
148144
+ }
148145
+ context.activeLoopIterations.set(
148146
+ nodeId,
148147
+ iterator.snapshotIndex === void 0 ? index : {
148148
+ get index() {
148149
+ return iterator.snapshotIndex();
148150
+ },
148151
+ values: [value, iteration.value]
148152
+ }
148153
+ );
148154
+ const scope = context.scope.child();
148155
+ const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
148156
+ if (!binding.ok) {
148157
+ return binding.result;
148158
+ }
148159
+ const iterationContext = createLoopIterationContext(context, scope);
148160
+ emitLoopIterationBreakpoint(node, iterationContext);
148161
+ const result = await evaluateNode2(node.body, iterationContext);
148162
+ if (isMatchingBreak(result, loopLabels(node))) {
148163
+ context.activeLoopIterations.delete(nodeId);
148164
+ await closeIterator(iterator);
148165
+ return normalEmptyResult();
148166
+ }
148167
+ if (isMatchingContinue(result, loopLabels(node))) {
148168
+ index += 1;
148169
+ continue;
148170
+ }
148171
+ if (result.kind !== "normal") {
148172
+ context.activeLoopIterations.delete(nodeId);
148173
+ await closeIterator(iterator);
148174
+ return result;
148175
+ }
147892
148176
  index += 1;
147893
- continue;
147894
- }
147895
- if (result.kind !== "normal") {
147896
- context.activeLoopIterations.delete(nodeId);
147897
- await closeIterator(iterator);
147898
- return result;
147899
148177
  }
147900
- index += 1;
148178
+ } finally {
148179
+ releaseIterator();
147901
148180
  }
147902
148181
  }
147903
148182
  async function evaluateForInStatement(node, context) {
@@ -148267,52 +148546,64 @@ async function evaluateYieldDelegate(node, context) {
148267
148546
  if (argument.kind !== "normal") {
148268
148547
  return argument;
148269
148548
  }
148270
- const iterator = getSandboxIterator(argument.value, context.budget);
148549
+ const iterator = getSandboxIterator(
148550
+ argument.value,
148551
+ context.budget,
148552
+ createCoercionContext(context)
148553
+ );
148271
148554
  if (iterator === void 0) {
148272
148555
  throw new TypeError(`${String(argument.value)} is not a supported iterable`);
148273
148556
  }
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;
148557
+ const releaseIterator = retainValues(context.budget, () => [
148558
+ argument.value,
148559
+ iterator.retainedValue
148560
+ ]);
148561
+ try {
148562
+ let completion = {
148563
+ type: "normal",
148564
+ value: void 0
148565
+ };
148566
+ const replay = context.generatorResume?.sent ?? [];
148567
+ let replayIndex = 0;
148568
+ while (true) {
148569
+ const method = completion.type === "normal" ? "next" : completion.type;
148570
+ const iteratorMethod = iterator[method];
148571
+ if (iteratorMethod === void 0) {
148572
+ if (completion.type === "throw") {
148573
+ throw completion.value;
148574
+ }
148575
+ return generatorCompletionResult(completion);
148286
148576
  }
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 });
148577
+ const result = await iteratorMethod(completion.value);
148578
+ if (result.done) {
148579
+ if (completion.type === "return") {
148580
+ return generatorCompletionResult({ type: "return", value: result.value });
148581
+ }
148582
+ return {
148583
+ kind: "normal",
148584
+ hasValue: true,
148585
+ value: result.value
148586
+ };
148293
148587
  }
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;
148588
+ if (replayIndex < replay.length - 1) {
148589
+ completion = replay[replayIndex + 1];
148590
+ replayIndex += 1;
148591
+ continue;
148592
+ }
148593
+ const completionPromise = context.generatorYield(
148594
+ allocateProducedSandboxValue(result.value, context.budget),
148595
+ node.nodeId
148596
+ );
148597
+ emitResumeBreakpoint(context, {
148598
+ kind: "generator-yield",
148599
+ nodeId: node.nodeId,
148600
+ span: node.span
148601
+ });
148602
+ completion = await completionPromise;
148603
+ context.generatorResume = void 0;
148304
148604
  }
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;
148605
+ } finally {
148606
+ releaseIterator();
148316
148607
  }
148317
148608
  }
148318
148609
  function generatorCompletionResult(completion) {
@@ -148459,6 +148750,14 @@ async function evaluateMemberExpression(node, context) {
148459
148750
  }
148460
148751
  function getPropertyValue(target, property, context) {
148461
148752
  if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
148753
+ if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
148754
+ const prototype = getBoxedPrototype(target, context.budget);
148755
+ if (prototype !== void 0) {
148756
+ if (typeof target === "string" && (property === "length" || getStringIndex(property) !== void 0))
148757
+ return getStringMember(target, property, context.budget);
148758
+ return getMemberValue(prototype, property, context);
148759
+ }
148760
+ }
148462
148761
  if (typeof target === "string") return getStringMember(target, property, context.budget);
148463
148762
  if (typeof target === "number") return getNumberMember(property, context.budget);
148464
148763
  if (typeof target === "boolean") return void 0;
@@ -148630,6 +148929,15 @@ async function evaluateMemberCallExpression(node, context) {
148630
148929
  ...reference,
148631
148930
  property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
148632
148931
  };
148932
+ if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") && getBoxedPrototype(member.object, context.budget) !== void 0) {
148933
+ if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
148934
+ if (typeof member.object === "string" && isStringMethodName(member.property))
148935
+ return evaluateStringMethodCall(node, member.object, member.property, context);
148936
+ if (typeof member.object === "number" && isNumberMethodName(member.property))
148937
+ return evaluateNumberMethodCall(node, member.object, member.property, context);
148938
+ }
148939
+ return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
148940
+ }
148633
148941
  if (typeof member.object === "string" && isStringMethodName(member.property)) {
148634
148942
  return evaluateStringMethodCall(node, member.object, member.property, context);
148635
148943
  }
@@ -148991,33 +149299,41 @@ function hasSandboxProperty(value, key3, context) {
148991
149299
  return false;
148992
149300
  }
148993
149301
  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);
149302
+ const convertingObject = typeof left === "object" && left !== null;
149303
+ let convertedLeft;
149304
+ const release2 = retainValues(context.budget, () => [convertedLeft]);
149305
+ try {
149306
+ left = await toNumericPrimitive(left, context);
149307
+ if (convertingObject) convertedLeft = left;
149308
+ right = await toNumericPrimitive(right, context);
149309
+ switch (operator) {
149310
+ case "+=":
149311
+ return applyAdditionOperator(left, right, context);
149312
+ case "-=":
149313
+ return toNumber(left) - toNumber(right);
149314
+ case "*=":
149315
+ return toNumber(left) * toNumber(right);
149316
+ case "/=":
149317
+ return toNumber(left) / toNumber(right);
149318
+ case "%=":
149319
+ return toNumber(left) % toNumber(right);
149320
+ case "**=":
149321
+ return toNumber(left) ** toNumber(right);
149322
+ case "&=":
149323
+ return toNumber(left) & toNumber(right);
149324
+ case "|=":
149325
+ return toNumber(left) | toNumber(right);
149326
+ case "^=":
149327
+ return toNumber(left) ^ toNumber(right);
149328
+ case "<<=":
149329
+ return toNumber(left) << toNumber(right);
149330
+ case ">>=":
149331
+ return toNumber(left) >> toNumber(right);
149332
+ case ">>>=":
149333
+ return toNumber(left) >>> toNumber(right);
149334
+ }
149335
+ } finally {
149336
+ release2();
149021
149337
  }
149022
149338
  }
149023
149339
  function applyAdditionOperator(left, right, context) {
@@ -149414,12 +149730,12 @@ async function evaluateSpreadElement(node, context) {
149414
149730
  result: value
149415
149731
  };
149416
149732
  }
149417
- const iterator = getSandboxIterator(value.value, context.budget);
149733
+ const iterator = getSandboxIterator(value.value, context.budget, createCoercionContext(context));
149418
149734
  if (iterator === void 0) {
149419
149735
  throw new TypeError("Spread arguments must evaluate to an iterable.");
149420
149736
  }
149421
149737
  const spreadValues = [];
149422
- const release2 = retainValues(context.budget, () => [value.value, ...spreadValues]);
149738
+ const release2 = retainValues(context.budget, () => [value.value, iterator.retainedValue, ...spreadValues]);
149423
149739
  try {
149424
149740
  while (true) {
149425
149741
  const next = await iterator.next();
@@ -149540,6 +149856,7 @@ var init_interpreter = __esm({
149540
149856
  init_array();
149541
149857
  init_function();
149542
149858
  init_object_model();
149859
+ init_string();
149543
149860
  init_graph_depth();
149544
149861
  init_map();
149545
149862
  init_number();
@@ -149559,6 +149876,7 @@ var init_interpreter = __esm({
149559
149876
  init_float32array2();
149560
149877
  init_float32();
149561
149878
  init_date();
149879
+ init_boxed();
149562
149880
  init_date2();
149563
149881
  init_values();
149564
149882
  init_scope();
@@ -150603,6 +150921,30 @@ function copyHostValueToSandbox(value, stackFrames, options, state, path193) {
150603
150921
  state
150604
150922
  );
150605
150923
  }
150924
+ const primitive = nativeBoxedValue(value);
150925
+ if (primitive !== void 0) {
150926
+ if (typeof primitive === "string") budget.allocateString(primitive);
150927
+ const original = value;
150928
+ const existing = state.seen.get(original);
150929
+ if (existing !== void 0) return existing;
150930
+ const copy = createSandboxBox(primitive);
150931
+ state.seen.set(original, copy);
150932
+ budget.chargeDataUsage(measureSandboxData([copy]));
150933
+ for (const [key3, descriptor] of boxedDataProperties(original)) {
150934
+ if (!("value" in descriptor)) throw new TypeError(`Unsupported sandbox value at ${joinPath2(path193, key3)}: accessor property`);
150935
+ Object.defineProperty(copy, budget.allocateString(key3), {
150936
+ ...descriptor,
150937
+ value: copyHostValueToSandbox(
150938
+ descriptor.value,
150939
+ stackFrames,
150940
+ { ...options, capabilityPath: [...options.capabilityPath ?? [], key3] },
150941
+ state,
150942
+ joinPath2(path193, key3)
150943
+ )
150944
+ });
150945
+ }
150946
+ return copy;
150947
+ }
150606
150948
  const date = copyNativeDate(value);
150607
150949
  if (date !== void 0) {
150608
150950
  const existing = state.seen.get(value);
@@ -150893,6 +151235,7 @@ var init_host_bridge = __esm({
150893
151235
  "use strict";
150894
151236
  init_async();
150895
151237
  init_date();
151238
+ init_boxed();
150896
151239
  init_host_capabilities();
150897
151240
  init_shape();
150898
151241
  init_budget2();
@@ -150927,12 +151270,18 @@ function createConsoleJsonGlobals(options) {
150927
151270
  JSON: {
150928
151271
  parse: createSandboxClosure({
150929
151272
  sandbox: true,
150930
- call: async ([text5]) => parseJson4(text5, options.budget),
151273
+ call: async ([text5], context) => {
151274
+ const converted = sandboxString(text5, options.budget, context);
151275
+ return copyJsonToSandbox(
151276
+ JSON.parse(converted instanceof Promise ? await converted : converted),
151277
+ options.budget
151278
+ );
151279
+ },
150931
151280
  name: "parse"
150932
151281
  }),
150933
151282
  stringify: createSandboxClosure({
150934
151283
  sandbox: true,
150935
- call: async ([value, replacer, indent]) => stringifyJson4(value, replacer, indent, options.budget),
151284
+ call: async ([value, replacer, indent], context) => stringifyJson4(value, replacer, indent, options.budget, context),
150936
151285
  name: "stringify"
150937
151286
  })
150938
151287
  },
@@ -150993,11 +151342,7 @@ function createConsoleJsonGlobals(options) {
150993
151342
  )
150994
151343
  };
150995
151344
  }
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) {
151345
+ async function stringifyJson4(value, replacer, indent, budget, context) {
151001
151346
  if (replacer !== void 0 && replacer !== null && !isSandboxClosure(replacer)) {
151002
151347
  throw new TypeError(
151003
151348
  "JSON.stringify(value, replacer, indent) only supports function, null, or undefined replacers."
@@ -151012,6 +151357,7 @@ async function stringifyJson4(value, replacer, indent, budget) {
151012
151357
  defineDataProperty8(holder, "", value);
151013
151358
  const output = await stringifyProperty("", holder, {
151014
151359
  budget,
151360
+ context,
151015
151361
  gap: normalizeStringifyGap(indent),
151016
151362
  replacer: isSandboxClosure(replacer) ? replacer : void 0,
151017
151363
  stack: []
@@ -151021,15 +151367,6 @@ async function stringifyJson4(value, replacer, indent, budget) {
151021
151367
  }
151022
151368
  return budget.allocateString(output);
151023
151369
  }
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
151370
  async function stringifyProperty(key3, holder, state, indent = "") {
151034
151371
  let value = getOwnDataValue(holder, key3);
151035
151372
  if (isSandboxDate(value)) {
@@ -151046,6 +151383,10 @@ async function stringifyProperty(key3, holder, state, indent = "") {
151046
151383
  return stringifyValue3(value, state, indent);
151047
151384
  }
151048
151385
  async function stringifyValue3(value, state, indent) {
151386
+ if (isSandboxBox(value)) {
151387
+ const primitive = boxedValue(value);
151388
+ value = typeof primitive === "number" ? await sandboxNumber(value, state.budget, state.context) : typeof primitive === "string" ? await sandboxString(value, state.budget, state.context) : primitive;
151389
+ }
151049
151390
  if (value === null) {
151050
151391
  return "null";
151051
151392
  }
@@ -151221,6 +151562,8 @@ var init_console_json = __esm({
151221
151562
  "packages/safe-js/src/interp/globals/console-json.ts"() {
151222
151563
  "use strict";
151223
151564
  init_date();
151565
+ init_boxed();
151566
+ init_string_coercion();
151224
151567
  init_compile_guard();
151225
151568
  init_host_bridge();
151226
151569
  init_values();
@@ -151468,7 +151811,7 @@ function structuredCloneSandboxValue(value, budget, parent) {
151468
151811
  const operation = budget.acquireCompileOwner(false, parent?.owner);
151469
151812
  const compilation = parent?.owner === operation.owner ? parent : new CompileScope(operation.owner);
151470
151813
  try {
151471
- const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true });
151814
+ const clone = cloneSandboxValue(value, { compilation, resetRegexLastIndex: true, structuredClone: true });
151472
151815
  assertSandboxGraphDepth(clone);
151473
151816
  assertStructuredCloneable(clone, /* @__PURE__ */ new WeakSet());
151474
151817
  allocateProducedSandboxValue(clone, budget);
@@ -151516,6 +151859,82 @@ var init_misc = __esm({
151516
151859
  }
151517
151860
  });
151518
151861
 
151862
+ // packages/safe-js/src/interp/globals/primitives.ts
151863
+ function createPrimitiveConstructor(options, budget) {
151864
+ const initial = { Number: 0, String: "", Boolean: false }[options.name];
151865
+ const kind = typeof initial;
151866
+ const prototype = createSandboxBox(initial);
151867
+ const allocate = (value) => {
151868
+ const box = createSandboxBox(value);
151869
+ budget.chargeDataUsage(measureSandboxData([box]));
151870
+ return box;
151871
+ };
151872
+ const constructor = createSandboxClosure({
151873
+ guest: true,
151874
+ sandbox: true,
151875
+ name: options.name,
151876
+ length: 1,
151877
+ call: options.call,
151878
+ construct: (args, context) => {
151879
+ const value = options.call(args, context);
151880
+ return value instanceof Promise ? value.then(allocate) : allocate(value);
151881
+ }
151882
+ });
151883
+ const properties = materializeFunctionProperties(constructor);
151884
+ Object.defineProperty(properties, "prototype", { value: prototype, writable: false });
151885
+ Object.defineProperty(prototype, "constructor", {
151886
+ value: constructor,
151887
+ writable: true,
151888
+ configurable: true
151889
+ });
151890
+ for (const [name, value] of Object.entries(options.properties ?? {}))
151891
+ Object.defineProperty(properties, name, {
151892
+ value,
151893
+ writable: isSandboxClosure(value),
151894
+ configurable: isSandboxClosure(value)
151895
+ });
151896
+ const methods = /* @__PURE__ */ new Map([
151897
+ [
151898
+ "valueOf",
151899
+ createSandboxClosure({
151900
+ sandbox: true,
151901
+ name: "valueOf",
151902
+ length: 0,
151903
+ call: (_args, context) => primitiveReceiver(context?.thisValue, kind)
151904
+ })
151905
+ ]
151906
+ ]);
151907
+ if (kind === "number") {
151908
+ for (const name of numberMethodNames) methods.set(name, getNumberMember(name, budget));
151909
+ } else {
151910
+ methods.set(
151911
+ "toString",
151912
+ createSandboxClosure({
151913
+ sandbox: true,
151914
+ name: "toString",
151915
+ length: 0,
151916
+ call: (_args, context) => budget.allocateString(String(primitiveReceiver(context?.thisValue, kind)))
151917
+ })
151918
+ );
151919
+ if (kind === "string")
151920
+ for (const name of stringMethodNames) methods.set(name, getStringMember("", name, budget));
151921
+ }
151922
+ for (const [name, value] of methods)
151923
+ Object.defineProperty(prototype, name, { value, writable: true, configurable: true });
151924
+ installBoxedPrototype(budget, prototype, constructor);
151925
+ return constructor;
151926
+ }
151927
+ var init_primitives = __esm({
151928
+ "packages/safe-js/src/interp/globals/primitives.ts"() {
151929
+ "use strict";
151930
+ init_boxed();
151931
+ init_object_model();
151932
+ init_number();
151933
+ init_string();
151934
+ init_values();
151935
+ }
151936
+ });
151937
+
151519
151938
  // packages/safe-js/src/interp/globals/object-array.ts
151520
151939
  function createObjectArrayGlobals(options) {
151521
151940
  return {
@@ -151581,6 +152000,7 @@ function createObjectArrayGlobals(options) {
151581
152000
  sandbox: true,
151582
152001
  call: ([value]) => {
151583
152002
  if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
152003
+ if (value !== null && value !== void 0 && typeof value !== "object") value = createSandboxBox(value);
151584
152004
  objectProperties(value);
151585
152005
  return getSandboxPrototype(value, options.budget);
151586
152006
  },
@@ -151620,11 +152040,11 @@ function createObjectArrayGlobals(options) {
151620
152040
  fromEntries: createSandboxClosure({
151621
152041
  sandbox: true,
151622
152042
  call: ([value], context) => {
151623
- const iterator = getSandboxIterator(value, options.budget);
152043
+ const iterator = getSandboxIterator(value, options.budget, context);
151624
152044
  if (iterator === void 0) {
151625
152045
  throw new TypeError("Object.fromEntries requires an iterable.");
151626
152046
  }
151627
- if (context === void 0 && !iterator.generator) {
152047
+ if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
151628
152048
  return allocateProducedSandboxValue(
151629
152049
  Object.setPrototypeOf(
151630
152050
  Reflect.apply(Object.fromEntries, Object, [{ [Symbol.iterator]: () => iterator }]),
@@ -151682,8 +152102,7 @@ function createObjectArrayGlobals(options) {
151682
152102
  })
151683
152103
  }
151684
152104
  }),
151685
- String: createSandboxClosure({
151686
- sandbox: true,
152105
+ String: createPrimitiveConstructor({
151687
152106
  call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
151688
152107
  name: "String",
151689
152108
  properties: {
@@ -151703,9 +152122,8 @@ function createObjectArrayGlobals(options) {
151703
152122
  name: "fromCodePoint"
151704
152123
  })
151705
152124
  }
151706
- }),
151707
- Number: createSandboxClosure({
151708
- sandbox: true,
152125
+ }, options.budget),
152126
+ Number: createPrimitiveConstructor({
151709
152127
  call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
151710
152128
  name: "Number",
151711
152129
  properties: {
@@ -151739,12 +152157,11 @@ function createObjectArrayGlobals(options) {
151739
152157
  NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
151740
152158
  POSITIVE_INFINITY: Number.POSITIVE_INFINITY
151741
152159
  }
151742
- }),
151743
- Boolean: createSandboxClosure({
151744
- sandbox: true,
152160
+ }, options.budget),
152161
+ Boolean: createPrimitiveConstructor({
151745
152162
  call: ([value]) => Boolean(value),
151746
152163
  name: "Boolean"
151747
- })
152164
+ }, options.budget)
151748
152165
  };
151749
152166
  }
151750
152167
  async function objectFromSandboxEntries(items, iterator, budget, context) {
@@ -151754,7 +152171,7 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
151754
152171
  let value;
151755
152172
  let failure;
151756
152173
  const retained = {};
151757
- budget.setRetainedValues(retained, () => [items, object, entry, key3, value, failure]);
152174
+ budget.setRetainedValues(retained, () => [items, iterator.retainedValue, object, entry, key3, value, failure]);
151758
152175
  const checkData = createDataCheckpoint(budget, context);
151759
152176
  const closeOnThrow = async (error3) => {
151760
152177
  failure = isCapturedException(error3) ? error3.reason : error3;
@@ -151805,6 +152222,10 @@ function assignSandboxValues(target, sources, budget) {
151805
152222
  if (target === null || target === void 0) {
151806
152223
  throw new TypeError("Object.assign(target, ...sources) requires a non-null target.");
151807
152224
  }
152225
+ if (typeof target !== "object") {
152226
+ target = createSandboxBox(target);
152227
+ budget.chargeDataUsage(measureSandboxData([target]));
152228
+ }
151808
152229
  if (!isGuestClosure(target) && !isAssignableSandboxTarget(target)) {
151809
152230
  throw new TypeError("Object.assign(target, ...sources) requires an object or array target.");
151810
152231
  }
@@ -151874,13 +152295,13 @@ async function arrayFromSandboxValues(args, budget, context) {
151874
152295
  throw new TypeError("Array.from requires a non-null input.");
151875
152296
  }
151876
152297
  const read = (property) => context?.getProperty !== void 0 ? context.getProperty(items, property) : getSandboxDataProperty(items, property, budget);
151877
- const iterator = getSandboxIterator(items, budget);
152298
+ const iterator = getSandboxIterator(items, budget, context);
151878
152299
  const constructor = context?.thisValue;
151879
152300
  let result;
151880
152301
  let currentValue;
151881
152302
  let failure;
151882
152303
  const retained = {};
151883
- budget.setRetainedValues(retained, () => [items, mapFn, constructor, result, currentValue, failure]);
152304
+ budget.setRetainedValues(retained, () => [items, iterator?.retainedValue, mapFn, constructor, result, currentValue, failure]);
151884
152305
  const checkData = createDataCheckpoint(budget, context);
151885
152306
  const closeOnThrow = async (error3) => {
151886
152307
  failure = isCapturedException(error3) ? error3.reason : error3;
@@ -151993,6 +152414,7 @@ var init_object_array = __esm({
151993
152414
  init_data_checkpoint();
151994
152415
  init_exceptions();
151995
152416
  init_date();
152417
+ init_boxed();
151996
152418
  init_date2();
151997
152419
  init_object2();
151998
152420
  init_host_capabilities();
@@ -152001,6 +152423,7 @@ var init_object_array = __esm({
152001
152423
  init_iteration();
152002
152424
  init_string_coercion();
152003
152425
  init_numeric_parsers();
152426
+ init_primitives();
152004
152427
  init_object_model();
152005
152428
  init_values();
152006
152429
  }
@@ -152188,10 +152611,10 @@ var init_random = __esm({
152188
152611
 
152189
152612
  // packages/safe-js/src/realm.ts
152190
152613
  import { AsyncLocalStorage as AsyncLocalStorage9 } from "node:async_hooks";
152191
- import { types as types5 } from "node:util";
152614
+ import { types as types6 } from "node:util";
152192
152615
  function readModules(input) {
152193
152616
  const entries = (value, label) => {
152194
- if (types5.isMap(value) && !types5.isProxy(value)) {
152617
+ if (types6.isMap(value) && !types6.isProxy(value)) {
152195
152618
  const result = [...Map.prototype.entries.call(value)];
152196
152619
  if (result.length > 4096 || result.some(([key3]) => typeof key3 !== "string" || key3.length === 0))
152197
152620
  throw new TypeError(`${label} requires bounded string keys.`);
@@ -152305,7 +152728,7 @@ var init_realm = __esm({
152305
152728
  throw new TypeError("Realm limits must be positive safe integers with supported names.");
152306
152729
  this.limits[name] = Number(value);
152307
152730
  }
152308
- if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types5.isProxy(options.extensions)))
152731
+ if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types6.isProxy(options.extensions)))
152309
152732
  throw new TypeError("Extensions must be a registration array.");
152310
152733
  const registrations = options.extensions ?? [];
152311
152734
  const extensions = [];
@@ -152540,7 +152963,7 @@ var init_realm = __esm({
152540
152963
  return this.phase.run(phase, () => {
152541
152964
  try {
152542
152965
  const result = call();
152543
- if (types5.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
152966
+ if (types6.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
152544
152967
  return Promise.resolve(result).then(
152545
152968
  async (value) => {
152546
152969
  await Promise.allSettled(phase.pending);
@@ -152609,7 +153032,7 @@ var init_realm = __esm({
152609
153032
  },
152610
153033
  read: (operation, validate2) => {
152611
153034
  const value = this.invokeHost(operation, operation);
152612
- if (types5.isPromise(value)) {
153035
+ if (types6.isPromise(value)) {
152613
153036
  void Promise.resolve(value).catch(() => void 0);
152614
153037
  throw new TypeError("Live property operations must be synchronous.");
152615
153038
  }
@@ -152617,7 +153040,7 @@ var init_realm = __esm({
152617
153040
  },
152618
153041
  write: (operation, value) => {
152619
153042
  const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
152620
- if (types5.isPromise(result)) {
153043
+ if (types6.isPromise(result)) {
152621
153044
  void Promise.resolve(result).catch(() => void 0);
152622
153045
  throw new TypeError("Live property setters must be synchronous.");
152623
153046
  }
@@ -152826,7 +153249,7 @@ var init_realm = __esm({
152826
153249
  }
152827
153250
  });
152828
153251
  const output = getExtensionSetup(extension)(context);
152829
- if (types5.isPromise(output)) {
153252
+ if (types6.isPromise(output)) {
152830
153253
  void Promise.resolve(output).catch(() => void 0);
152831
153254
  throw new TypeError("Extension setup must be synchronous.");
152832
153255
  }
@@ -153455,6 +153878,8 @@ var init_serialize = __esm({
153455
153878
  init_float32();
153456
153879
  init_float32array();
153457
153880
  init_date();
153881
+ init_boxed();
153882
+ init_boxed2();
153458
153883
  init_values();
153459
153884
  UnsnapshotableValueError = class extends Error {
153460
153885
  path;