poe-code 14.0.5 → 14.0.6

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 (36) hide show
  1. package/dist/index.js +1176 -242
  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-B7H4ZL65.js → chunk-2M6MNQBY.js} +1937 -1008
  6. package/packages/safe-js/dist/chunks/chunk-2M6MNQBY.js.map +7 -0
  7. package/packages/safe-js/dist/chunks/{chunk-7B7BKWVF.js → chunk-QSSQJNKE.js} +2 -2
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.d.ts +3 -0
  10. package/packages/safe-js/dist/core.js +5 -1
  11. package/packages/safe-js/dist/extensions.d.ts +42 -0
  12. package/packages/safe-js/dist/extensions.js +83 -0
  13. package/packages/safe-js/dist/index.d.ts +4 -1
  14. package/packages/safe-js/dist/index.js +6 -2
  15. package/packages/safe-js/dist/index.js.map +2 -2
  16. package/packages/safe-js/dist/interp/async.d.ts +1 -0
  17. package/packages/safe-js/dist/interp/globals/object-array.js +5 -0
  18. package/packages/safe-js/dist/interp/globals.d.ts +31 -0
  19. package/packages/safe-js/dist/interp/globals.js +22 -0
  20. package/packages/safe-js/dist/interp/host-bridge.d.ts +14 -1
  21. package/packages/safe-js/dist/interp/host-bridge.js +19 -4
  22. package/packages/safe-js/dist/interp/host-capabilities.d.ts +43 -0
  23. package/packages/safe-js/dist/interp/host-capabilities.js +123 -0
  24. package/packages/safe-js/dist/interp/interpreter.d.ts +4 -0
  25. package/packages/safe-js/dist/interp/interpreter.js +22 -4
  26. package/packages/safe-js/dist/interp/object-model.js +7 -0
  27. package/packages/safe-js/dist/interp/values.d.ts +1 -0
  28. package/packages/safe-js/dist/interp/values.js +15 -0
  29. package/packages/safe-js/dist/modules/registry.d.ts +3 -1
  30. package/packages/safe-js/dist/modules/registry.js +2 -1
  31. package/packages/safe-js/dist/realm.d.ts +43 -0
  32. package/packages/safe-js/dist/realm.js +713 -0
  33. package/packages/safe-js/dist/run.d.ts +5 -1
  34. package/packages/safe-js/dist/run.js +6 -35
  35. package/packages/safe-js/dist/chunks/chunk-B7H4ZL65.js.map +0 -7
  36. /package/packages/safe-js/dist/chunks/{chunk-7B7BKWVF.js.map → chunk-QSSQJNKE.js.map} +0 -0
package/dist/index.js CHANGED
@@ -7179,24 +7179,24 @@ function renderReferencedFootnotes(context) {
7179
7179
  return items.length === 0 ? "" : `<section class="footnotes"><ol>${items}</ol></section>`;
7180
7180
  }
7181
7181
  function createFootnoteState(children2) {
7182
- const definitions = /* @__PURE__ */ new Map();
7182
+ const definitions2 = /* @__PURE__ */ new Map();
7183
7183
  for (const child of children2) {
7184
- collectFootnoteDefinitions(child, definitions);
7184
+ collectFootnoteDefinitions(child, definitions2);
7185
7185
  }
7186
7186
  return {
7187
- definitions,
7187
+ definitions: definitions2,
7188
7188
  labelsInOrder: [],
7189
7189
  numbers: /* @__PURE__ */ new Map()
7190
7190
  };
7191
7191
  }
7192
- function collectFootnoteDefinitions(node, definitions) {
7192
+ function collectFootnoteDefinitions(node, definitions2) {
7193
7193
  if (node.type === "footnoteDefinition") {
7194
- definitions.set(node.label, node);
7194
+ definitions2.set(node.label, node);
7195
7195
  return;
7196
7196
  }
7197
7197
  if ("children" in node) {
7198
7198
  for (const child of node.children) {
7199
- collectFootnoteDefinitions(child, definitions);
7199
+ collectFootnoteDefinitions(child, definitions2);
7200
7200
  }
7201
7201
  }
7202
7202
  }
@@ -12159,19 +12159,19 @@ function selectedRows(state, fallback) {
12159
12159
  return source.filter((row) => state.selected.has(row.id));
12160
12160
  }
12161
12161
  function runtimePanes(state) {
12162
- const definitions = state.paneDefinitions;
12162
+ const definitions2 = state.paneDefinitions;
12163
12163
  return [
12164
12164
  {
12165
- id: definitions[0]?.id ?? "list",
12166
- title: definitions[0]?.title ?? state.title,
12165
+ id: definitions2[0]?.id ?? "list",
12166
+ title: definitions2[0]?.title ?? state.title,
12167
12167
  rows: state.rows,
12168
12168
  cursor: state.cursor,
12169
12169
  selected: state.selected,
12170
12170
  filter: state.filter
12171
12171
  },
12172
12172
  {
12173
- id: definitions[1]?.id ?? "detail",
12174
- title: definitions[1]?.title ?? "Preview",
12173
+ id: definitions2[1]?.id ?? "detail",
12174
+ title: definitions2[1]?.title ?? "Preview",
12175
12175
  rows: (state.detail.items ?? []).map((item) => ({
12176
12176
  id: item.id,
12177
12177
  title: item.title ?? item.id,
@@ -49222,9 +49222,9 @@ function buildSkillGuidance(activeDefinitions, activeTools) {
49222
49222
  ];
49223
49223
  return lines.join("\n");
49224
49224
  }
49225
- function normalizeDefinitions(definitions) {
49225
+ function normalizeDefinitions(definitions2) {
49226
49226
  const normalized = /* @__PURE__ */ new Map();
49227
- for (const [rawName, rawDefinition] of Object.entries(definitions)) {
49227
+ for (const [rawName, rawDefinition] of Object.entries(definitions2)) {
49228
49228
  const name = rawName.trim();
49229
49229
  if (name.length === 0 || normalized.has(name)) {
49230
49230
  continue;
@@ -49259,14 +49259,14 @@ var init_poe_agent_plugin_skills = __esm({
49259
49259
  "packages/poe-agent/src/plugins/poe-agent-plugin-skills.ts"() {
49260
49260
  "use strict";
49261
49261
  skills = (options) => {
49262
- const definitions = normalizeDefinitions(options.definitions);
49262
+ const definitions2 = normalizeDefinitions(options.definitions);
49263
49263
  return {
49264
49264
  name: "skills",
49265
49265
  prompt(ctx) {
49266
49266
  const activeSkills = normalizeStringList(
49267
49267
  typeof options.skills === "function" ? options.skills() : options.skills
49268
49268
  );
49269
- const activeDefinitions = activeSkills.map((skillName) => definitions.get(skillName)).filter((definition) => definition !== void 0);
49269
+ const activeDefinitions = activeSkills.map((skillName) => definitions2.get(skillName)).filter((definition) => definition !== void 0);
49270
49270
  const activeTools = options.toolRegistry?.getActiveTools(activeSkills).map((tool) => tool.name) ?? [];
49271
49271
  const guidance = buildSkillGuidance(activeDefinitions, activeTools);
49272
49272
  return {
@@ -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 types2 = Array.isArray(schema.type) ? schema.type : [schema.type];
50275
- if (types2.length === 0 || !types2.every((type) => typeof type === "string" && draftTypeSet.has(type)) || new Set(types2).size !== types2.length) {
50274
+ const types4 = Array.isArray(schema.type) ? schema.type : [schema.type];
50275
+ if (types4.length === 0 || !types4.every((type) => typeof type === "string" && draftTypeSet.has(type)) || new Set(types4).size !== types4.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 types2 = typeof schema.type === "string" ? [schema.type] : Array.isArray(schema.type) ? schema.type : [];
50995
- if (types2.length > 0 && !types2.some((type) => typeof type === "string" && typeMatches(type, value))) {
50996
- results.push(invalidResult(issue(path193, types2.join(","), value, `must be ${types2.join(",")}`)));
50994
+ const types4 = typeof schema.type === "string" ? [schema.type] : Array.isArray(schema.type) ? schema.type : [];
50995
+ if (types4.length > 0 && !types4.some((type) => typeof type === "string" && typeMatches(type, value))) {
50996
+ results.push(invalidResult(issue(path193, types4.join(","), value, `must be ${types4.join(",")}`)));
50997
50997
  return results;
50998
50998
  }
50999
50999
  if (schema.const !== void 0 && !deepEqual(schema.const, value)) {
@@ -125538,6 +125538,184 @@ var init_graph_depth = __esm({
125538
125538
  }
125539
125539
  });
125540
125540
 
125541
+ // packages/safe-js/src/extensions.ts
125542
+ import { types } from "node:util";
125543
+ function readDataRecord(value, label) {
125544
+ if (typeof value !== "object" || value === null || types.isProxy(value)) {
125545
+ throw new TypeError(`${label} must be a plain data record.`);
125546
+ }
125547
+ const prototype = Object.getPrototypeOf(value);
125548
+ if (prototype !== null && prototype !== Object.prototype) {
125549
+ throw new TypeError(`${label} must be a plain data record.`);
125550
+ }
125551
+ const keys = Reflect.ownKeys(value);
125552
+ if (keys.length > 4096) throw new RangeError(`${label} has too many fields.`);
125553
+ const result = /* @__PURE__ */ Object.create(null);
125554
+ for (const key3 of keys) {
125555
+ const descriptor = Object.getOwnPropertyDescriptor(value, key3);
125556
+ if (typeof key3 !== "string" || !("value" in descriptor)) {
125557
+ throw new TypeError(`${label} requires string-keyed data properties, not accessors.`);
125558
+ }
125559
+ result[key3] = descriptor.value;
125560
+ }
125561
+ return result;
125562
+ }
125563
+ function readStringList(value, label) {
125564
+ if (!Array.isArray(value) || types.isProxy(value) || value.length > 4096) {
125565
+ throw new TypeError(`${label} must be a bounded string array.`);
125566
+ }
125567
+ const result = [];
125568
+ for (let index = 0; index < value.length; index++) {
125569
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
125570
+ if (descriptor === void 0 || !("value" in descriptor) || typeof descriptor.value !== "string" || descriptor.value.length === 0) {
125571
+ throw new TypeError(`${label} requires nonempty string data properties.`);
125572
+ }
125573
+ if (result.includes(descriptor.value))
125574
+ throw new TypeError(`${label} contains a duplicate name.`);
125575
+ result.push(descriptor.value);
125576
+ }
125577
+ if (Reflect.ownKeys(value).length !== result.length + 1)
125578
+ throw new TypeError(`${label} has unexpected fields.`);
125579
+ return Object.freeze(result);
125580
+ }
125581
+ function getExtensionSetup(extension) {
125582
+ const setup = definitions.get(extension);
125583
+ if (setup === void 0) throw new TypeError("Extensions must be created by defineExtension.");
125584
+ return setup;
125585
+ }
125586
+ var definitions;
125587
+ var init_extensions = __esm({
125588
+ "packages/safe-js/src/extensions.ts"() {
125589
+ "use strict";
125590
+ definitions = /* @__PURE__ */ new WeakMap();
125591
+ }
125592
+ });
125593
+
125594
+ // packages/safe-js/src/interp/host-capabilities.ts
125595
+ function createLiveHostObject(definition, controller) {
125596
+ const input = readDataRecord(definition, "Host object definition");
125597
+ if (Object.keys(input).some((key3) => key3 !== "properties" && key3 !== "methods"))
125598
+ throw new TypeError("Unknown host object definition field.");
125599
+ const properties = /* @__PURE__ */ new Map();
125600
+ for (const [name, inputProperty] of Object.entries(
125601
+ readDataRecord(input.properties ?? {}, "Host properties")
125602
+ )) {
125603
+ const property = readDataRecord(inputProperty, `Host property '${name}'`);
125604
+ if (Object.keys(property).some((key3) => key3 !== "get" && key3 !== "set"))
125605
+ throw new TypeError("Unknown host property field.");
125606
+ if (property.get !== void 0 && typeof property.get !== "function" || property.set !== void 0 && typeof property.set !== "function")
125607
+ throw new TypeError("Host property operations must be functions.");
125608
+ properties.set(name, property);
125609
+ }
125610
+ const operations = readDataRecord(input.methods ?? {}, "Host methods");
125611
+ for (const [name, operation] of Object.entries(operations)) {
125612
+ if (typeof operation !== "function") throw new TypeError("Host methods must be functions.");
125613
+ if (properties.has(name)) throw new TypeError(`Conflicting host member '${name}'.`);
125614
+ }
125615
+ for (const name of [...properties.keys(), ...Object.keys(operations)]) {
125616
+ if (["constructor", "prototype", "__proto__"].includes(name))
125617
+ throw new TypeError(`Reserved host member '${name}'.`);
125618
+ }
125619
+ controller.assertActive();
125620
+ controller.chargeWork(properties.size + Object.keys(operations).length + 1);
125621
+ const host = Object.freeze(/* @__PURE__ */ Object.create(null));
125622
+ const guest = Object.freeze(/* @__PURE__ */ Object.create(null));
125623
+ const methods = new Map(
125624
+ Object.entries(operations).map(([name, operation]) => [
125625
+ name,
125626
+ controller.method(operation)
125627
+ ])
125628
+ );
125629
+ const state = { host, guest, controller, properties, methods };
125630
+ hostObjects.set(host, state);
125631
+ guestObjects.set(guest, state);
125632
+ return host;
125633
+ }
125634
+ function isGuestHostObject(value) {
125635
+ return typeof value === "object" && value !== null && guestObjects.has(value);
125636
+ }
125637
+ function isLiveCapability(value) {
125638
+ return (typeof value === "object" && value !== null || typeof value === "function") && (hostObjects.has(value) || guestObjects.has(value) || guestCallbacks.has(value));
125639
+ }
125640
+ function importHostCapability(value, owner) {
125641
+ const object = hostObjects.get(value);
125642
+ if (object !== void 0) {
125643
+ if (object.controller.owner !== owner) throw new TypeError("Foreign realm host capability.");
125644
+ object.controller.assertActive();
125645
+ return object.guest;
125646
+ }
125647
+ const callback = guestCallbacks.get(value);
125648
+ if (callback !== void 0) {
125649
+ if (callback.owner !== owner) throw new TypeError("Foreign realm guest callback.");
125650
+ callback.assertActive();
125651
+ if (callback.closure === void 0) throw new TypeError("Guest callback is revoked.");
125652
+ return callback.closure;
125653
+ }
125654
+ throw new TypeError("Unsupported live capability conversion.");
125655
+ }
125656
+ function exportHostCapability(value, owner) {
125657
+ const state = guestObjects.get(value);
125658
+ if (state === void 0 || state.controller.owner !== owner)
125659
+ throw new TypeError("Foreign realm host capability.");
125660
+ state.controller.assertActive();
125661
+ return state.host;
125662
+ }
125663
+ function registerGuestCallback(callback, state) {
125664
+ guestCallbacks.set(callback, state);
125665
+ }
125666
+ function readGuestCallback(callback, owner) {
125667
+ const state = typeof callback === "function" ? guestCallbacks.get(callback) : void 0;
125668
+ if (state === void 0 || state.owner !== owner)
125669
+ throw new TypeError("Foreign or invalid guest callback.");
125670
+ state.assertActive();
125671
+ if (state.closure === void 0) throw new TypeError("Guest callback is revoked.");
125672
+ return state.closure;
125673
+ }
125674
+ function revokeGuestCallback(callback, owner) {
125675
+ const state = guestCallbacks.get(callback);
125676
+ if (state === void 0 || state.owner !== owner) throw new TypeError("Foreign guest callback.");
125677
+ state.closure = void 0;
125678
+ }
125679
+ function revokeHostObject(value, owner) {
125680
+ const state = hostObjects.get(value);
125681
+ if (state === void 0 || state.controller.owner !== owner)
125682
+ throw new TypeError("Foreign host object.");
125683
+ state.properties.clear();
125684
+ state.methods.clear();
125685
+ }
125686
+ function getHostObjectMember(value, key3) {
125687
+ const state = guestObjects.get(value);
125688
+ state.controller.assertActive();
125689
+ state.controller.chargeWork();
125690
+ const property = state.properties.get(key3);
125691
+ if (property !== void 0)
125692
+ return property.get === void 0 ? void 0 : state.controller.read(property.get);
125693
+ return state.methods.get(key3);
125694
+ }
125695
+ function setHostObjectMember(value, key3, entry) {
125696
+ const state = guestObjects.get(value);
125697
+ state.controller.assertActive();
125698
+ state.controller.chargeWork();
125699
+ const property = state.properties.get(key3);
125700
+ if (property?.set === void 0) throw new TypeError(`Host property '${key3}' is not writable.`);
125701
+ state.controller.write(property.set, entry);
125702
+ }
125703
+ function getHostObjectKeys(value) {
125704
+ const state = guestObjects.get(value);
125705
+ state.controller.assertActive();
125706
+ return [...state.properties.keys(), ...state.methods.keys()];
125707
+ }
125708
+ var hostObjects, guestObjects, guestCallbacks;
125709
+ var init_host_capabilities = __esm({
125710
+ "packages/safe-js/src/interp/host-capabilities.ts"() {
125711
+ "use strict";
125712
+ init_extensions();
125713
+ hostObjects = /* @__PURE__ */ new WeakMap();
125714
+ guestObjects = /* @__PURE__ */ new WeakMap();
125715
+ guestCallbacks = /* @__PURE__ */ new WeakMap();
125716
+ }
125717
+ });
125718
+
125541
125719
  // packages/safe-js/src/observability/otel.ts
125542
125720
  function bindOtelSpan(value, span) {
125543
125721
  spanByAsyncValue.set(value, span);
@@ -128921,6 +129099,7 @@ function createSandboxClosure(input) {
128921
129099
  return Object.freeze(closure);
128922
129100
  }
128923
129101
  function ownEnumerableSandboxEntries(value) {
129102
+ if (isGuestHostObject(value)) return getHostObjectKeys(value).map((key3) => [key3, getHostObjectMember(value, key3)]);
128924
129103
  if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
128925
129104
  if (isGuestClosure(value)) return Object.entries(value.properties ?? {});
128926
129105
  if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
@@ -129073,6 +129252,10 @@ function measureSandboxData(values, options = {}) {
129073
129252
  assertSandboxDataDepth(depth);
129074
129253
  seen.add(value);
129075
129254
  usage += 1;
129255
+ if (isGuestHostObject(value)) {
129256
+ for (const key3 of getHostObjectKeys(value)) usage += key3.length + 1;
129257
+ return;
129258
+ }
129076
129259
  const prototype = getSandboxPrototype(value);
129077
129260
  if (prototype !== null) visit(prototype, depth + 1);
129078
129261
  if (isFloat32Array(value)) {
@@ -129215,6 +129398,7 @@ function copyToSandbox(value, state, path193 = "<root>", cloneSandboxCollections
129215
129398
  if (isSandboxPrimitive(value)) {
129216
129399
  return value;
129217
129400
  }
129401
+ if (isLiveCapability(value)) throw new TypeError("Live capabilities require their owning realm bridge.");
129218
129402
  if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxRegex(value) || isSandboxPromise(value)) {
129219
129403
  return value;
129220
129404
  }
@@ -129378,6 +129562,10 @@ function copyFromSandbox(value, state, path193 = "<root>", options, depth = 0) {
129378
129562
  if (isSandboxPrimitive(value)) {
129379
129563
  return value;
129380
129564
  }
129565
+ if (isGuestHostObject(value)) {
129566
+ if (options.unwrapHostObject === void 0) throw new TypeError("Live capabilities require their owning realm bridge.");
129567
+ return options.unwrapHostObject(value);
129568
+ }
129381
129569
  if (nodeTypes.isProxy(value)) throw new TypeError("Unsupported proxy sandbox value.");
129382
129570
  if (!isSandboxClosure(value) && hasGuestObjectState(value)) {
129383
129571
  throw new TypeError("Guest prototype links and custom descriptors cannot be copied as data.");
@@ -129685,6 +129873,7 @@ var init_values = __esm({
129685
129873
  "packages/safe-js/src/interp/values.ts"() {
129686
129874
  "use strict";
129687
129875
  init_otel2();
129876
+ init_host_capabilities();
129688
129877
  init_compile_guard();
129689
129878
  init_float32();
129690
129879
  init_budget2();
@@ -129775,6 +129964,7 @@ function setSandboxPrototype(value, prototype, budget) {
129775
129964
  else prototypes.set(value, prototype);
129776
129965
  }
129777
129966
  function isPrototypeRecord(value) {
129967
+ if (isGuestHostObject(value)) return false;
129778
129968
  if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxSet(value))
129779
129969
  return false;
129780
129970
  const prototype = Object.getPrototypeOf(value);
@@ -129787,6 +129977,7 @@ function hasManagedDescriptors(value) {
129787
129977
  return descriptorObjects.has(value);
129788
129978
  }
129789
129979
  function hasGuestObjectState(value) {
129980
+ if (isLiveCapability(value)) return true;
129790
129981
  if (functionProperties.has(value) || prototypes.has(value)) return true;
129791
129982
  return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
129792
129983
  (descriptor) => !descriptor.enumerable || !descriptor.configurable || !descriptor.writable
@@ -129797,6 +129988,7 @@ var init_object_model = __esm({
129797
129988
  "packages/safe-js/src/interp/object-model.ts"() {
129798
129989
  "use strict";
129799
129990
  init_graph_depth();
129991
+ init_host_capabilities();
129800
129992
  init_values();
129801
129993
  guestClosures = /* @__PURE__ */ new WeakSet();
129802
129994
  functionProperties = /* @__PURE__ */ new WeakMap();
@@ -130067,7 +130259,7 @@ var init_dump_format = __esm({
130067
130259
  });
130068
130260
 
130069
130261
  // packages/safe-js/src/snapshot/validation.ts
130070
- import { types } from "node:util";
130262
+ import { types as types2 } from "node:util";
130071
130263
  function validateSnapshotData(value) {
130072
130264
  validateGenericValue(value, "$", 0, {
130073
130265
  allowFunctions: false,
@@ -130353,7 +130545,7 @@ function validateGenericValue(value, path193, depth, state) {
130353
130545
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
130354
130546
  fail2("invalidState", path193, "guest function properties, prototype links and custom descriptors cannot be restored");
130355
130547
  }
130356
- if (state.dataPropertiesOnly && types.isProxy(value)) {
130548
+ if (state.dataPropertiesOnly && types2.isProxy(value)) {
130357
130549
  fail2("invalidType", path193, "proxy objects are not snapshot data");
130358
130550
  }
130359
130551
  if (depth > state.limits.maxDepth)
@@ -142064,180 +142256,6 @@ var init_lint4 = __esm({
142064
142256
  }
142065
142257
  });
142066
142258
 
142067
- // packages/safe-js/src/interp/resources.ts
142068
- import { AsyncLocalStorage as AsyncLocalStorage8 } from "node:async_hooks";
142069
- async function withRunResources(signal, execute2) {
142070
- const controller = new AbortController();
142071
- const cancel2 = () => controller.abort(signal?.reason);
142072
- const cleanups = /* @__PURE__ */ new Set();
142073
- const resources = {
142074
- signal: controller.signal,
142075
- add(close) {
142076
- cleanups.add(close);
142077
- }
142078
- };
142079
- signal?.addEventListener("abort", cancel2, { once: true });
142080
- if (signal?.aborted) cancel2();
142081
- let result;
142082
- let failure;
142083
- let errors2 = [];
142084
- try {
142085
- result = await runResources.run(resources, execute2);
142086
- } catch (error3) {
142087
- failure = { reason: error3 };
142088
- } finally {
142089
- signal?.removeEventListener("abort", cancel2);
142090
- controller.abort(new Error("SafeJS run finished."));
142091
- const outcomes = await Promise.allSettled(
142092
- [...cleanups].map((close) => Promise.resolve().then(close))
142093
- );
142094
- errors2 = outcomes.flatMap((outcome) => outcome.status === "rejected" ? [outcome.reason] : []);
142095
- }
142096
- if (failure !== void 0) throw failure.reason;
142097
- if (errors2.length > 0) throw new AggregateError(errors2, "SafeJS resource cleanup failed.");
142098
- return result;
142099
- }
142100
- var runResources;
142101
- var init_resources = __esm({
142102
- "packages/safe-js/src/interp/resources.ts"() {
142103
- "use strict";
142104
- runResources = new AsyncLocalStorage8();
142105
- }
142106
- });
142107
-
142108
- // packages/safe-js/src/interp/globals/math.ts
142109
- function f16round(value) {
142110
- const number = +value;
142111
- if (!Number.isFinite(number) || number === 0) {
142112
- return number;
142113
- }
142114
- const magnitude = Math.abs(number);
142115
- if (magnitude >= 65520) {
142116
- return number < 0 ? -Infinity : Infinity;
142117
- }
142118
- let quantum = 2 ** -24;
142119
- let boundary = 2 ** -13;
142120
- for (let exponent = -13; exponent <= 15 && magnitude >= boundary; exponent += 1) {
142121
- quantum *= 2;
142122
- boundary *= 2;
142123
- }
142124
- const scaled = magnitude / quantum;
142125
- const lower = Math.floor(scaled);
142126
- const remainder = scaled - lower;
142127
- const rounded = (remainder > 0.5 || remainder === 0.5 && lower % 2 !== 0 ? lower + 1 : lower) * quantum;
142128
- return number < 0 ? -rounded : rounded;
142129
- }
142130
- function createMathGlobals(options = {}) {
142131
- const random = options.random ?? Math.random;
142132
- const mathObject = {
142133
- E: Math.E,
142134
- LN2: Math.LN2,
142135
- LN10: Math.LN10,
142136
- LOG2E: Math.LOG2E,
142137
- LOG10E: Math.LOG10E,
142138
- PI: Math.PI,
142139
- SQRT1_2: Math.SQRT1_2,
142140
- SQRT2: Math.SQRT2,
142141
- random: createSandboxClosure({ sandbox: true, call: () => random(), name: "random" })
142142
- };
142143
- for (const [name, method] of Object.entries(mathMethods)) {
142144
- mathObject[name] = createSandboxClosure({
142145
- sandbox: true,
142146
- call: (args) => Reflect.apply(method, Math, args),
142147
- name
142148
- });
142149
- }
142150
- return {
142151
- Infinity: Infinity,
142152
- Math: mathObject,
142153
- NaN: Number.NaN
142154
- };
142155
- }
142156
- function createSeededRandom(seed) {
142157
- let state = normalizeSeed(seed);
142158
- return {
142159
- next: () => {
142160
- state = Math.imul(state, 1664525) + 1013904223 >>> 0;
142161
- return state / 4294967296;
142162
- },
142163
- snapshot: () => state,
142164
- restore: (nextState) => {
142165
- state = normalizeSeed(nextState);
142166
- }
142167
- };
142168
- }
142169
- function normalizeSeed(seed) {
142170
- if (!Number.isFinite(seed)) {
142171
- throw new TypeError("Seeded random requires a finite numeric seed.");
142172
- }
142173
- return Math.trunc(seed) >>> 0;
142174
- }
142175
- var mathMethods;
142176
- var init_math = __esm({
142177
- "packages/safe-js/src/interp/globals/math.ts"() {
142178
- "use strict";
142179
- init_values();
142180
- mathMethods = {
142181
- abs: Math.abs,
142182
- acos: Math.acos,
142183
- acosh: Math.acosh,
142184
- asin: Math.asin,
142185
- asinh: Math.asinh,
142186
- atan: Math.atan,
142187
- atan2: Math.atan2,
142188
- atanh: Math.atanh,
142189
- ceil: Math.ceil,
142190
- cbrt: Math.cbrt,
142191
- clz32: Math.clz32,
142192
- cos: Math.cos,
142193
- cosh: Math.cosh,
142194
- exp: Math.exp,
142195
- expm1: Math.expm1,
142196
- floor: Math.floor,
142197
- f16round,
142198
- fround: Math.fround,
142199
- hypot: Math.hypot,
142200
- imul: Math.imul,
142201
- log: Math.log,
142202
- log1p: Math.log1p,
142203
- log10: Math.log10,
142204
- log2: Math.log2,
142205
- max: Math.max,
142206
- min: Math.min,
142207
- pow: Math.pow,
142208
- round: Math.round,
142209
- sign: Math.sign,
142210
- sin: Math.sin,
142211
- sinh: Math.sinh,
142212
- sqrt: Math.sqrt,
142213
- tan: Math.tan,
142214
- tanh: Math.tanh,
142215
- trunc: Math.trunc
142216
- };
142217
- }
142218
- });
142219
-
142220
- // packages/safe-js/src/random.ts
142221
- import { randomInt } from "node:crypto";
142222
- function createReplayableRandom(options = {}) {
142223
- const snapshot2 = options.snapshot;
142224
- const saved = snapshot2?.random;
142225
- let initialState = options.seed;
142226
- if (saved !== void 0) {
142227
- const hasLoopState = typeof snapshot2?.loopIterations === "object" && snapshot2.loopIterations !== null && Object.keys(snapshot2.loopIterations).length > 0;
142228
- const replaysFromStart = snapshot2?.replay !== void 0 || Array.isArray(snapshot2?.pendingAwaits) && snapshot2.pendingAwaits.length > 0 && !hasLoopState;
142229
- initialState = replaysFromStart ? saved.initialState ?? saved.seed : saved.resumeState ?? saved.state;
142230
- }
142231
- const generator = createSeededRandom(initialState ?? randomInt(4294967296));
142232
- return { seed: saved?.seed ?? generator.snapshot(), ...generator };
142233
- }
142234
- var init_random = __esm({
142235
- "packages/safe-js/src/random.ts"() {
142236
- "use strict";
142237
- init_math();
142238
- }
142239
- });
142240
-
142241
142259
  // packages/safe-js/src/interp/generator.ts
142242
142260
  function createGeneratorChannel(body) {
142243
142261
  let state = "unstarted";
@@ -144957,9 +144975,10 @@ async function interpret(node, options = {}) {
144957
144975
  peakDataSize: { enumerable: false, value: 0, writable: true }
144958
144976
  });
144959
144977
  const activeLoopIterations = /* @__PURE__ */ new Map();
144960
- const jobs = new SandboxJobQueue();
144978
+ const jobs = options.jobs ?? new SandboxJobQueue();
144961
144979
  hoistVarDeclarations(node, scope);
144962
144980
  const context = {
144981
+ assertActive: options.assertActive,
144963
144982
  compilation,
144964
144983
  budget,
144965
144984
  callStack: [],
@@ -144982,9 +145001,9 @@ async function interpret(node, options = {}) {
144982
145001
  };
144983
145002
  const evaluation = await withCancellationSignal(
144984
145003
  options.signal,
144985
- () => jobs.run(() => evaluateNode2(node, context))
145004
+ () => options.nested ? runAsyncPrefix(() => evaluateNode2(node, context)) : jobs.run(() => evaluateNode2(node, context))
144986
145005
  );
144987
- await jobs.drain();
145006
+ if (!options.nested) await jobs.drain();
144988
145007
  const snapshot2 = scope.snapshot();
144989
145008
  reconcileDataBudget(
144990
145009
  budget,
@@ -145039,6 +145058,7 @@ async function interpret(node, options = {}) {
145039
145058
  }
145040
145059
  }
145041
145060
  async function evaluateNode2(node, context) {
145061
+ context.assertActive?.();
145042
145062
  const replayWait = promiseReplayContext.getStore()?.beforeNode(node.nodeId);
145043
145063
  if (replayWait !== void 0) await suspendJob(replayWait);
145044
145064
  assertPromiseExecutionAllowed();
@@ -146010,6 +146030,7 @@ function forInObject(value) {
146010
146030
  return void 0;
146011
146031
  }
146012
146032
  function forInKeys(object, budget) {
146033
+ if (isGuestHostObject(object)) return getHostObjectKeys(object);
146013
146034
  const keys = [];
146014
146035
  const seen = /* @__PURE__ */ new Set();
146015
146036
  let depth = 0;
@@ -146027,6 +146048,7 @@ function forInKeys(object, budget) {
146027
146048
  return keys;
146028
146049
  }
146029
146050
  function hasForInProperty(object, key3, budget) {
146051
+ if (isGuestHostObject(object)) return getHostObjectKeys(object).includes(key3);
146030
146052
  let depth = 0;
146031
146053
  for (let current = object; current !== null; current = getSandboxPrototype(current)) {
146032
146054
  if (depth > 0) budget.visitNode();
@@ -146518,6 +146540,7 @@ async function evaluateMemberExpression(node, context) {
146518
146540
  };
146519
146541
  }
146520
146542
  function getPropertyValue(target, property, context) {
146543
+ if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
146521
146544
  if (typeof target === "string") return getStringMember(target, property, context.budget);
146522
146545
  if (typeof target === "number") return getNumberMember(target, property, context.budget);
146523
146546
  if (typeof target === "boolean") return void 0;
@@ -147224,6 +147247,7 @@ function isPlainSandboxObject(value) {
147224
147247
  return typeof value === "object" && value !== null && !Array.isArray(value) && !isSandboxClosure(value) && !isSandboxMap(value) && !isSandboxSet(value) && !isSandboxPromise(value) && !isSandboxRegex(value);
147225
147248
  }
147226
147249
  function getMemberValue(target, property, context) {
147250
+ if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
147227
147251
  let current = target;
147228
147252
  let depth = 0;
147229
147253
  while (typeof current === "object" && current !== null) {
@@ -147248,6 +147272,10 @@ function getArrayMemberValue(target, property, context) {
147248
147272
  return getArrayMember(target, property, createArrayMethodOptions(context));
147249
147273
  }
147250
147274
  function setSandboxProperty(target, property, value, budget) {
147275
+ if (isGuestHostObject(target)) {
147276
+ setHostObjectMember(target, String(property), value);
147277
+ return;
147278
+ }
147251
147279
  const prototypeOwner = target;
147252
147280
  if (isGuestClosure(target)) target = materializeFunctionProperties(target);
147253
147281
  if (isFloat32Array(target)) {
@@ -147292,6 +147320,7 @@ function setSandboxProperty(target, property, value, budget) {
147292
147320
  }
147293
147321
  }
147294
147322
  function deleteSandboxProperty(target, property) {
147323
+ if (isGuestHostObject(target)) throw new TypeError("Live host properties cannot be deleted.");
147295
147324
  if (isGuestClosure(target)) target = materializeFunctionProperties(target);
147296
147325
  if (Array.isArray(target)) {
147297
147326
  assertCollectionMutable(target);
@@ -147546,6 +147575,7 @@ var init_interpreter = __esm({
147546
147575
  "packages/safe-js/src/interp/interpreter.ts"() {
147547
147576
  "use strict";
147548
147577
  init_promise_replay();
147578
+ init_host_capabilities();
147549
147579
  init_promise_tracker();
147550
147580
  init_jobs4();
147551
147581
  init_cancel2();
@@ -147951,7 +147981,7 @@ function wrapCallerInjectedBindings(bindings, options) {
147951
147981
  const copied = Object.fromEntries(
147952
147982
  Object.entries(bindings).map(([name, value]) => [
147953
147983
  name,
147954
- typeof value === "function" ? wrapCallerInjectedFunction(name, value, { ...options, capabilityPath: [name] }, state) : copyHostValueToSandbox(
147984
+ typeof value === "function" && !isLiveCapability(value) ? wrapCallerInjectedFunction(name, value, { ...options, capabilityPath: [name] }, state) : copyHostValueToSandbox(
147955
147985
  value,
147956
147986
  [],
147957
147987
  { ...options, operation: name, capabilityPath: [name] },
@@ -147972,9 +148002,10 @@ function wrapCallerInjectedFunction(name, value, options, state) {
147972
148002
  const bindingName = name === "default" && value.name.length > 0 ? value.name : name;
147973
148003
  const callable = value;
147974
148004
  return createSandboxClosure({
147975
- ...isAsyncFunction(callable) ? { async: true } : {},
148005
+ ...isAsyncFunction(callable) && !options.realm?.awaitResult(callable) ? { async: true } : {},
147976
148006
  cancellationSignal: options.signal,
147977
148007
  call: (args, context) => {
148008
+ options.realm?.assertActive();
147978
148009
  const operationLease = options.budget.acquireCompileOwner(false, options.compileOwner);
147979
148010
  const compilation = new CompileScope(operationLease.owner);
147980
148011
  try {
@@ -147992,7 +148023,8 @@ function wrapCallerInjectedFunction(name, value, options, state) {
147992
148023
  };
147993
148024
  const hostArgs = deepCopyFromSandbox([...args], {
147994
148025
  compilation,
147995
- wrapClosure: (closure) => wrapSandboxClosureForHost(
148026
+ unwrapHostObject: options.realm === void 0 ? void 0 : (object) => exportHostCapability(object, options.realm.owner),
148027
+ wrapClosure: (closure) => options.realm?.wrapCallback(closure) ?? wrapSandboxClosureForHost(
147996
148028
  closure,
147997
148029
  stackFrames,
147998
148030
  options.budget,
@@ -148005,6 +148037,13 @@ function wrapCallerInjectedFunction(name, value, options, state) {
148005
148037
  const moduleId = options.moduleId ?? "<bindings>";
148006
148038
  const policy = readHostOperationPolicy(value) ?? readRegisteredPendingHostCallPolicy(moduleId, operation) ?? "re-issue";
148007
148039
  if (hostCalls === void 0) {
148040
+ if (options.realm !== void 0) {
148041
+ const result = options.realm.invoke(callable, () => Reflect.apply(callable, void 0, hostArgs));
148042
+ if (options.realm.awaitResult(callable)) {
148043
+ return Promise.resolve(result).then((value2) => copyHostResultToSandbox(value2, stackFrames, options));
148044
+ }
148045
+ return copyHostResultToSandbox(result, stackFrames, options);
148046
+ }
148008
148047
  return copyHostResultToSandbox(
148009
148048
  invokeHostCallback(() => Reflect.apply(callable, void 0, hostArgs), options),
148010
148049
  stackFrames,
@@ -148542,6 +148581,10 @@ function wrapHostPromiseWithSignal(promise, signal) {
148542
148581
  }
148543
148582
  function copyHostValueToSandbox(value, stackFrames, options, state, path193) {
148544
148583
  const { budget } = options;
148584
+ if (isLiveCapability(value)) {
148585
+ if (options.realm === void 0 || options.errorData || options.hostCalls !== void 0) throw new TypeError("Live capabilities are not portable replay or error data.");
148586
+ return importHostCapability(value, options.realm.owner);
148587
+ }
148545
148588
  if (value === null || value === void 0 || typeof value === "number" || typeof value === "boolean") {
148546
148589
  return value;
148547
148590
  }
@@ -148864,6 +148907,7 @@ var init_host_bridge = __esm({
148864
148907
  "packages/safe-js/src/interp/host-bridge.ts"() {
148865
148908
  "use strict";
148866
148909
  init_async();
148910
+ init_host_capabilities();
148867
148911
  init_shape();
148868
148912
  init_budget2();
148869
148913
  init_compile_guard();
@@ -149194,6 +149238,118 @@ var init_console_json = __esm({
149194
149238
  }
149195
149239
  });
149196
149240
 
149241
+ // packages/safe-js/src/interp/globals/math.ts
149242
+ function f16round(value) {
149243
+ const number = +value;
149244
+ if (!Number.isFinite(number) || number === 0) {
149245
+ return number;
149246
+ }
149247
+ const magnitude = Math.abs(number);
149248
+ if (magnitude >= 65520) {
149249
+ return number < 0 ? -Infinity : Infinity;
149250
+ }
149251
+ let quantum = 2 ** -24;
149252
+ let boundary = 2 ** -13;
149253
+ for (let exponent = -13; exponent <= 15 && magnitude >= boundary; exponent += 1) {
149254
+ quantum *= 2;
149255
+ boundary *= 2;
149256
+ }
149257
+ const scaled = magnitude / quantum;
149258
+ const lower = Math.floor(scaled);
149259
+ const remainder = scaled - lower;
149260
+ const rounded = (remainder > 0.5 || remainder === 0.5 && lower % 2 !== 0 ? lower + 1 : lower) * quantum;
149261
+ return number < 0 ? -rounded : rounded;
149262
+ }
149263
+ function createMathGlobals(options = {}) {
149264
+ const random = options.random ?? Math.random;
149265
+ const mathObject = {
149266
+ E: Math.E,
149267
+ LN2: Math.LN2,
149268
+ LN10: Math.LN10,
149269
+ LOG2E: Math.LOG2E,
149270
+ LOG10E: Math.LOG10E,
149271
+ PI: Math.PI,
149272
+ SQRT1_2: Math.SQRT1_2,
149273
+ SQRT2: Math.SQRT2,
149274
+ random: createSandboxClosure({ sandbox: true, call: () => random(), name: "random" })
149275
+ };
149276
+ for (const [name, method] of Object.entries(mathMethods)) {
149277
+ mathObject[name] = createSandboxClosure({
149278
+ sandbox: true,
149279
+ call: (args) => Reflect.apply(method, Math, args),
149280
+ name
149281
+ });
149282
+ }
149283
+ return {
149284
+ Infinity: Infinity,
149285
+ Math: mathObject,
149286
+ NaN: Number.NaN
149287
+ };
149288
+ }
149289
+ function createSeededRandom(seed) {
149290
+ let state = normalizeSeed(seed);
149291
+ return {
149292
+ next: () => {
149293
+ state = Math.imul(state, 1664525) + 1013904223 >>> 0;
149294
+ return state / 4294967296;
149295
+ },
149296
+ snapshot: () => state,
149297
+ restore: (nextState) => {
149298
+ state = normalizeSeed(nextState);
149299
+ }
149300
+ };
149301
+ }
149302
+ function normalizeSeed(seed) {
149303
+ if (!Number.isFinite(seed)) {
149304
+ throw new TypeError("Seeded random requires a finite numeric seed.");
149305
+ }
149306
+ return Math.trunc(seed) >>> 0;
149307
+ }
149308
+ var mathMethods;
149309
+ var init_math = __esm({
149310
+ "packages/safe-js/src/interp/globals/math.ts"() {
149311
+ "use strict";
149312
+ init_values();
149313
+ mathMethods = {
149314
+ abs: Math.abs,
149315
+ acos: Math.acos,
149316
+ acosh: Math.acosh,
149317
+ asin: Math.asin,
149318
+ asinh: Math.asinh,
149319
+ atan: Math.atan,
149320
+ atan2: Math.atan2,
149321
+ atanh: Math.atanh,
149322
+ ceil: Math.ceil,
149323
+ cbrt: Math.cbrt,
149324
+ clz32: Math.clz32,
149325
+ cos: Math.cos,
149326
+ cosh: Math.cosh,
149327
+ exp: Math.exp,
149328
+ expm1: Math.expm1,
149329
+ floor: Math.floor,
149330
+ f16round,
149331
+ fround: Math.fround,
149332
+ hypot: Math.hypot,
149333
+ imul: Math.imul,
149334
+ log: Math.log,
149335
+ log1p: Math.log1p,
149336
+ log10: Math.log10,
149337
+ log2: Math.log2,
149338
+ max: Math.max,
149339
+ min: Math.min,
149340
+ pow: Math.pow,
149341
+ round: Math.round,
149342
+ sign: Math.sign,
149343
+ sin: Math.sin,
149344
+ sinh: Math.sinh,
149345
+ sqrt: Math.sqrt,
149346
+ tan: Math.tan,
149347
+ tanh: Math.tanh,
149348
+ trunc: Math.trunc
149349
+ };
149350
+ }
149351
+ });
149352
+
149197
149353
  // packages/safe-js/src/interp/globals/regex.ts
149198
149354
  function createRegexGlobals(owner) {
149199
149355
  const construct = (args, context) => {
@@ -149672,6 +149828,7 @@ function assignSandboxValues(target, sources, budget) {
149672
149828
  return target;
149673
149829
  }
149674
149830
  function objectProperties(value, mutable = false) {
149831
+ if (isGuestHostObject(value)) throw new TypeError("Live host object descriptors are not supported.");
149675
149832
  if (isGuestClosure(value)) return materializeFunctionProperties(value);
149676
149833
  if (isSandboxClosure(value)) {
149677
149834
  if (mutable) throw new TypeError("Host function properties are read only.");
@@ -149756,6 +149913,7 @@ async function collectIteratorValues(iterator) {
149756
149913
  }
149757
149914
  }
149758
149915
  function getOwnEnumerableKeys(value) {
149916
+ if (isGuestHostObject(value)) return getHostObjectKeys(value);
149759
149917
  return ownEnumerableSandboxEntries(value).map(([key3]) => key3);
149760
149918
  }
149761
149919
  function getOwnEnumerableValues(value) {
@@ -149787,6 +149945,7 @@ function getTemplateRawParts(template2) {
149787
149945
  var init_object_array = __esm({
149788
149946
  "packages/safe-js/src/interp/globals/object-array.ts"() {
149789
149947
  "use strict";
149948
+ init_host_capabilities();
149790
149949
  init_float32();
149791
149950
  init_interpreter();
149792
149951
  init_iteration();
@@ -149796,6 +149955,76 @@ var init_object_array = __esm({
149796
149955
  }
149797
149956
  });
149798
149957
 
149958
+ // packages/safe-js/src/interp/globals.ts
149959
+ function createBuiltinBindings(options) {
149960
+ return {
149961
+ ...createConsoleJsonGlobals(options),
149962
+ ...createCollectionGlobals(options),
149963
+ Float32Array: createFloat32ArrayGlobal(options.budget),
149964
+ ...createErrorGlobals(options),
149965
+ ...createMathGlobals({ random: options.random }),
149966
+ ...createObjectArrayGlobals(options),
149967
+ ...createMiscGlobals(options),
149968
+ ...createPromiseGlobals(options),
149969
+ ...createRegexGlobals(options.compileOwner)
149970
+ };
149971
+ }
149972
+ var init_globals = __esm({
149973
+ "packages/safe-js/src/interp/globals.ts"() {
149974
+ "use strict";
149975
+ init_console_json();
149976
+ init_collections();
149977
+ init_float32array2();
149978
+ init_error();
149979
+ init_math();
149980
+ init_regex2();
149981
+ init_misc();
149982
+ init_object_array();
149983
+ init_promise();
149984
+ }
149985
+ });
149986
+
149987
+ // packages/safe-js/src/interp/resources.ts
149988
+ import { AsyncLocalStorage as AsyncLocalStorage8 } from "node:async_hooks";
149989
+ async function withRunResources(signal, execute2) {
149990
+ const controller = new AbortController();
149991
+ const cancel2 = () => controller.abort(signal?.reason);
149992
+ const cleanups = /* @__PURE__ */ new Set();
149993
+ const resources = {
149994
+ signal: controller.signal,
149995
+ add(close) {
149996
+ cleanups.add(close);
149997
+ }
149998
+ };
149999
+ signal?.addEventListener("abort", cancel2, { once: true });
150000
+ if (signal?.aborted) cancel2();
150001
+ let result;
150002
+ let failure;
150003
+ let errors2 = [];
150004
+ try {
150005
+ result = await runResources.run(resources, execute2);
150006
+ } catch (error3) {
150007
+ failure = { reason: error3 };
150008
+ } finally {
150009
+ signal?.removeEventListener("abort", cancel2);
150010
+ controller.abort(new Error("SafeJS run finished."));
150011
+ const outcomes = await Promise.allSettled(
150012
+ [...cleanups].map((close) => Promise.resolve().then(close))
150013
+ );
150014
+ errors2 = outcomes.flatMap((outcome) => outcome.status === "rejected" ? [outcome.reason] : []);
150015
+ }
150016
+ if (failure !== void 0) throw failure.reason;
150017
+ if (errors2.length > 0) throw new AggregateError(errors2, "SafeJS resource cleanup failed.");
150018
+ return result;
150019
+ }
150020
+ var runResources;
150021
+ var init_resources = __esm({
150022
+ "packages/safe-js/src/interp/resources.ts"() {
150023
+ "use strict";
150024
+ runResources = new AsyncLocalStorage8();
150025
+ }
150026
+ });
150027
+
149799
150028
  // packages/safe-js/src/modules/registry.ts
149800
150029
  function createUnknownModuleMessage2(moduleName, moduleNames) {
149801
150030
  if (moduleNames.length === 0) {
@@ -149812,7 +150041,7 @@ function createUnknownExportMessage2(moduleName, exportName, availableExports) {
149812
150041
  function resolveModuleImports(module, modules, options) {
149813
150042
  const registry = normalizeModuleRegistry(modules);
149814
150043
  const bindings = createBindingRecord();
149815
- const wrappedModules = /* @__PURE__ */ new Map();
150044
+ const wrappedModules = options.wrappedModules ?? /* @__PURE__ */ new Map();
149816
150045
  for (const statement of module.body) {
149817
150046
  if (statement.type !== "ImportDeclaration") {
149818
150047
  continue;
@@ -149834,6 +150063,7 @@ function bindImportDeclaration(declaration, registry, wrappedModules, bindings,
149834
150063
  const wrappedExports = wrappedModules.get(moduleName) ?? createBindingRecord(
149835
150064
  wrapCancelableBindings(
149836
150065
  wrapCallerInjectedBindings(Object.fromEntries(moduleExports), {
150066
+ realm: options.realm,
149837
150067
  budget: options.budget,
149838
150068
  compileOwner: options.compileOwner,
149839
150069
  hostCalls: options.hostCalls,
@@ -149923,6 +150153,738 @@ var init_registry7 = __esm({
149923
150153
  }
149924
150154
  });
149925
150155
 
150156
+ // packages/safe-js/src/random.ts
150157
+ import { randomInt } from "node:crypto";
150158
+ function createReplayableRandom(options = {}) {
150159
+ const snapshot2 = options.snapshot;
150160
+ const saved = snapshot2?.random;
150161
+ let initialState = options.seed;
150162
+ if (saved !== void 0) {
150163
+ const hasLoopState = typeof snapshot2?.loopIterations === "object" && snapshot2.loopIterations !== null && Object.keys(snapshot2.loopIterations).length > 0;
150164
+ const replaysFromStart = snapshot2?.replay !== void 0 || Array.isArray(snapshot2?.pendingAwaits) && snapshot2.pendingAwaits.length > 0 && !hasLoopState;
150165
+ initialState = replaysFromStart ? saved.initialState ?? saved.seed : saved.resumeState ?? saved.state;
150166
+ }
150167
+ const generator = createSeededRandom(initialState ?? randomInt(4294967296));
150168
+ return { seed: saved?.seed ?? generator.snapshot(), ...generator };
150169
+ }
150170
+ var init_random = __esm({
150171
+ "packages/safe-js/src/random.ts"() {
150172
+ "use strict";
150173
+ init_math();
150174
+ }
150175
+ });
150176
+
150177
+ // packages/safe-js/src/realm.ts
150178
+ import { AsyncLocalStorage as AsyncLocalStorage9 } from "node:async_hooks";
150179
+ import { types as types3 } from "node:util";
150180
+ function readModules(input) {
150181
+ const entries = (value, label) => {
150182
+ if (types3.isMap(value) && !types3.isProxy(value)) {
150183
+ const result = [...Map.prototype.entries.call(value)];
150184
+ if (result.length > 4096 || result.some(([key3]) => typeof key3 !== "string" || key3.length === 0))
150185
+ throw new TypeError(`${label} requires bounded string keys.`);
150186
+ return result;
150187
+ }
150188
+ return Object.entries(readDataRecord(value, label));
150189
+ };
150190
+ const modules = /* @__PURE__ */ Object.create(null);
150191
+ for (const [name, exports] of entries(input ?? {}, "Module registry")) {
150192
+ const exported = /* @__PURE__ */ Object.create(null);
150193
+ for (const [key3, value] of entries(exports, "Module exports"))
150194
+ exported[key3] = value;
150195
+ modules[name] = exported;
150196
+ }
150197
+ return modules;
150198
+ }
150199
+ function assertNames(actual, expected, label) {
150200
+ if (actual.length !== expected.length || actual.some((name) => !expected.includes(name)))
150201
+ throw new TypeError(`Extension ${label} names do not match its manifest.`);
150202
+ }
150203
+ async function runWithExtensions(source, options) {
150204
+ if (options.snapshot !== void 0 || options.snapshotBackend !== void 0 || options.snapshotPath !== void 0 || options.entryPointArgs !== void 0)
150205
+ throw new TypeError(
150206
+ "Live extension runs do not support snapshots or entryPointArgs; use a persistent realm."
150207
+ );
150208
+ const state = new RealmState(readRealmOptions(options, true));
150209
+ try {
150210
+ const result = await state.perform(() => state.evaluateRaw(source, options.filename));
150211
+ if (result.ok) encodeReplayData(result.returnValue);
150212
+ return {
150213
+ ...result,
150214
+ snapshot: {
150215
+ version: 1,
150216
+ sourceHash: hashSource(source),
150217
+ bindings: {},
150218
+ replayError: "Live realm state cannot be serialized or replayed."
150219
+ }
150220
+ };
150221
+ } catch (error3) {
150222
+ if (state.disposal === void 0) {
150223
+ try {
150224
+ await state.close();
150225
+ } catch (cleanupError) {
150226
+ throw new AggregateError([error3, cleanupError], "Realm execution and cleanup failed.");
150227
+ }
150228
+ }
150229
+ throw error3;
150230
+ } finally {
150231
+ if (state.disposal === void 0) await state.close();
150232
+ }
150233
+ }
150234
+ function readRealmOptions(value, oneShot = false) {
150235
+ const options = readDataRecord(value, "Realm options");
150236
+ const supported = /* @__PURE__ */ new Set([
150237
+ "bindings",
150238
+ "modules",
150239
+ "extensions",
150240
+ "grants",
150241
+ "budget",
150242
+ "signal",
150243
+ "sink",
150244
+ "randomSeed",
150245
+ "limits"
150246
+ ]);
150247
+ for (const [key3, entry] of Object.entries(options)) {
150248
+ if (supported.has(key3) || oneShot && (key3 === "filename" || entry === void 0)) continue;
150249
+ throw new TypeError(`Unsupported ${oneShot ? "extension-run" : "realm"} option '${key3}'.`);
150250
+ }
150251
+ return options;
150252
+ }
150253
+ var RealmState;
150254
+ var init_realm = __esm({
150255
+ "packages/safe-js/src/realm.ts"() {
150256
+ "use strict";
150257
+ init_budget2();
150258
+ init_compile_guard();
150259
+ init_globals();
150260
+ init_interpreter();
150261
+ init_jobs4();
150262
+ init_cancel2();
150263
+ init_running_state();
150264
+ init_resources();
150265
+ init_promise_tracker();
150266
+ init_host_bridge();
150267
+ init_host_capabilities();
150268
+ init_values();
150269
+ init_extensions();
150270
+ init_registry7();
150271
+ init_parser3();
150272
+ init_random();
150273
+ init_hash();
150274
+ init_shape();
150275
+ init_replay_data();
150276
+ RealmState = class {
150277
+ constructor(options) {
150278
+ this.options = options;
150279
+ const limitInput = readDataRecord(options.limits ?? {}, "Realm limits");
150280
+ this.limits = {
150281
+ extensions: 32,
150282
+ hostObjects: 1024,
150283
+ callbacks: 1024,
150284
+ cleanups: 1024,
150285
+ nestedEvaluations: 16
150286
+ };
150287
+ for (const [name, value] of Object.entries(limitInput)) {
150288
+ if (!Object.hasOwn(this.limits, name) || !Number.isSafeInteger(value) || Number(value) < 1)
150289
+ throw new TypeError("Realm limits must be positive safe integers with supported names.");
150290
+ this.limits[name] = Number(value);
150291
+ }
150292
+ if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types3.isProxy(options.extensions)))
150293
+ throw new TypeError("Extensions must be a registration array.");
150294
+ const registrations = options.extensions ?? [];
150295
+ const extensions = [];
150296
+ if (registrations.length > this.limits.extensions)
150297
+ throw new RangeError("Realm extension limit exceeded.");
150298
+ for (let index = 0; index < registrations.length; index++) {
150299
+ const descriptor = Object.getOwnPropertyDescriptor(registrations, String(index));
150300
+ if (descriptor === void 0 || !("value" in descriptor))
150301
+ throw new TypeError("Extension registrations require data properties, not accessors.");
150302
+ extensions.push(descriptor.value);
150303
+ }
150304
+ if (Reflect.ownKeys(registrations).length !== extensions.length + 1)
150305
+ throw new TypeError("Extension registrations have unsupported fields.");
150306
+ this.extensions = Object.freeze(extensions);
150307
+ if (this.extensions.length > this.limits.extensions)
150308
+ throw new RangeError("Realm extension limit exceeded.");
150309
+ this.globals = readDataRecord(options.bindings ?? {}, "Realm bindings");
150310
+ this.modules = readModules(options.modules);
150311
+ const grants = new Set(readStringList(options.grants ?? [], "Realm grants"));
150312
+ for (const extension of this.extensions) getExtensionSetup(extension);
150313
+ this.budget = options.budget ?? new Budget({ maxCallDepth: 1e3 });
150314
+ this.lease = this.budget.acquireCompileOwner(true);
150315
+ this.compilation = new CompileScope(this.lease.owner);
150316
+ this.bridge = {
150317
+ owner: this,
150318
+ assertActive: this.assertOpen,
150319
+ wrapCallback: this.wrapCallback,
150320
+ invoke: this.invokeHost,
150321
+ awaitResult: (operation) => this.nestedOperations.has(operation)
150322
+ };
150323
+ try {
150324
+ this.builtinBindings = createBuiltinBindings({
150325
+ budget: this.budget,
150326
+ compileOwner: this.lease.owner,
150327
+ sink: options.sink,
150328
+ random: createReplayableRandom({ seed: options.randomSeed }).next
150329
+ });
150330
+ const names = /* @__PURE__ */ new Set();
150331
+ const globals = /* @__PURE__ */ new Set([...Object.keys(this.builtinBindings), ...Object.keys(this.globals)]);
150332
+ const modules = new Map(
150333
+ Object.entries(this.modules).map(([name, exports]) => [name, new Set(Object.keys(exports))])
150334
+ );
150335
+ for (const extension of this.extensions) {
150336
+ const manifest = extension.manifest;
150337
+ if (names.has(manifest.name))
150338
+ throw new TypeError(`Duplicate extension '${manifest.name}'.`);
150339
+ names.add(manifest.name);
150340
+ for (const capability of manifest.capabilities ?? []) {
150341
+ if (!grants.has(capability))
150342
+ throw new TypeError(`Missing grant '${capability}' for extension '${manifest.name}'.`);
150343
+ }
150344
+ for (const name of manifest.globals ?? []) {
150345
+ if (globals.has(name)) throw new TypeError(`Conflicting global '${name}'.`);
150346
+ globals.add(name);
150347
+ }
150348
+ for (const [name, exports] of Object.entries(manifest.modules ?? {})) {
150349
+ const occupied = modules.get(name) ?? /* @__PURE__ */ new Set();
150350
+ for (const key3 of exports) {
150351
+ if (occupied.has(key3)) throw new TypeError(`Conflicting export '${name}.${key3}'.`);
150352
+ occupied.add(key3);
150353
+ }
150354
+ modules.set(name, occupied);
150355
+ }
150356
+ }
150357
+ options.signal?.addEventListener("abort", this.abort, { once: true });
150358
+ if (options.signal?.aborted) this.abort();
150359
+ this.budget.setRetainedValues(this, this.retainedCallbacks);
150360
+ this.tracker.onFatalRejection((error3) => this.poison(error3));
150361
+ } catch (error3) {
150362
+ this.compilation.dispose();
150363
+ this.lease.release();
150364
+ throw error3;
150365
+ }
150366
+ }
150367
+ options;
150368
+ budget;
150369
+ lease;
150370
+ compilation;
150371
+ controller = new AbortController();
150372
+ phase = new AsyncLocalStorage9();
150373
+ queue = new SandboxJobQueue();
150374
+ tracker = createSandboxPromiseRejectionTracker();
150375
+ bridge;
150376
+ limits;
150377
+ extensions;
150378
+ cleanups = [];
150379
+ callbacks = /* @__PURE__ */ new Map();
150380
+ pendingCallbacks = /* @__PURE__ */ new Set();
150381
+ callbackCache = /* @__PURE__ */ new WeakMap();
150382
+ hostObjects = /* @__PURE__ */ new Set();
150383
+ nestedOperations = /* @__PURE__ */ new WeakMap();
150384
+ convertedModules = /* @__PURE__ */ new Map();
150385
+ nativeConversions = { seen: /* @__PURE__ */ new WeakMap() };
150386
+ modules;
150387
+ globals;
150388
+ builtinBindings;
150389
+ scope;
150390
+ active;
150391
+ disposal;
150392
+ closed = false;
150393
+ initialized = false;
150394
+ nestedDepth = 0;
150395
+ failure;
150396
+ bridgeOptions = () => ({
150397
+ budget: this.budget,
150398
+ compileOwner: this.lease.owner,
150399
+ signal: this.controller.signal,
150400
+ realm: this.bridge
150401
+ });
150402
+ retainedCallbacks = () => [
150403
+ ...this.callbacks.values(),
150404
+ ...Array.from(this.pendingCallbacks, (pending) => pending.closure)
150405
+ ];
150406
+ assertOpen = () => {
150407
+ if (this.failure !== void 0) throw this.failure.reason;
150408
+ if (this.closed) throw new Error("SafeJS realm is closed; capabilities are revoked.");
150409
+ this.controller.signal.throwIfAborted();
150410
+ };
150411
+ abort = () => {
150412
+ this.poison(this.options.signal?.reason ?? new SandboxError("aborted"));
150413
+ void this.close().catch(() => void 0);
150414
+ };
150415
+ poison(reason) {
150416
+ this.failure ??= { reason };
150417
+ this.controller.abort(reason);
150418
+ if (this.active === void 0)
150419
+ queueMicrotask(() => {
150420
+ void this.dispose().catch(() => void 0);
150421
+ });
150422
+ }
150423
+ chargeWork = (units = 1) => {
150424
+ this.assertOpen();
150425
+ if (!Number.isSafeInteger(units) || units < 0)
150426
+ throw new TypeError("Work charges must be non-negative safe integers.");
150427
+ try {
150428
+ for (let index = 0; index < units; index++) this.budget.visitNode();
150429
+ } catch (error3) {
150430
+ this.poison(error3);
150431
+ throw error3;
150432
+ }
150433
+ };
150434
+ onCleanup = (cleanup) => {
150435
+ this.assertOpen();
150436
+ if (typeof cleanup !== "function") throw new TypeError("Cleanup must be a function.");
150437
+ this.checkCollection(this.cleanups.length + 1, this.limits.cleanups, "cleanup");
150438
+ this.cleanups.push(cleanup);
150439
+ };
150440
+ checkCollection(count, limit, name) {
150441
+ this.assertOpen();
150442
+ try {
150443
+ this.budget.allocateCollectionEntries(count);
150444
+ } catch (error3) {
150445
+ this.poison(error3);
150446
+ throw error3;
150447
+ }
150448
+ if (count > limit) throw new RangeError(`Realm ${name} limit exceeded.`);
150449
+ }
150450
+ invokeHost = (operation, call) => {
150451
+ this.assertOpen();
150452
+ const phase = {
150453
+ active: true,
150454
+ extension: this.nestedOperations.get(operation),
150455
+ evaluating: false,
150456
+ pending: /* @__PURE__ */ new Set()
150457
+ };
150458
+ return this.phase.run(phase, () => {
150459
+ try {
150460
+ const result = call();
150461
+ if (types3.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
150462
+ return Promise.resolve(result).then(
150463
+ async (value) => {
150464
+ await Promise.allSettled(phase.pending);
150465
+ if (phase.failure !== void 0) throw phase.failure.reason;
150466
+ this.assertOpen();
150467
+ return value;
150468
+ },
150469
+ async (error3) => {
150470
+ if (error3 instanceof SandboxError || phase.pending.size > 0) this.poison(error3);
150471
+ await Promise.allSettled(phase.pending);
150472
+ throw error3;
150473
+ }
150474
+ ).finally(() => {
150475
+ phase.active = false;
150476
+ });
150477
+ }
150478
+ this.assertOpen();
150479
+ phase.active = false;
150480
+ return result;
150481
+ } catch (error3) {
150482
+ phase.active = false;
150483
+ if (error3 instanceof SandboxError) this.poison(error3);
150484
+ if (phase.pending.size > 0) {
150485
+ this.poison(error3);
150486
+ return Promise.allSettled(phase.pending).then(() => {
150487
+ throw error3;
150488
+ });
150489
+ }
150490
+ throw error3;
150491
+ }
150492
+ });
150493
+ };
150494
+ importValue(value) {
150495
+ return copyHostValueToSandbox(
150496
+ value,
150497
+ [],
150498
+ this.bridgeOptions(),
150499
+ { seen: /* @__PURE__ */ new WeakMap() },
150500
+ "<realm>"
150501
+ );
150502
+ }
150503
+ exportValue(value) {
150504
+ return deepCopyFromSandbox(value, {
150505
+ compilation: this.compilation,
150506
+ wrapClosure: this.wrapCallback,
150507
+ unwrapHostObject: (object) => exportHostCapability(object, this)
150508
+ });
150509
+ }
150510
+ createHostObject = (definition) => {
150511
+ this.checkCollection(this.hostObjects.size + 1, this.limits.hostObjects, "host object");
150512
+ const object = createLiveHostObject(definition, {
150513
+ owner: this,
150514
+ assertActive: this.assertOpen,
150515
+ chargeWork: this.chargeWork,
150516
+ read: (operation) => {
150517
+ const value = this.invokeHost(operation, operation);
150518
+ if (types3.isPromise(value)) {
150519
+ void Promise.resolve(value).catch(() => void 0);
150520
+ throw new TypeError("Live property getters must be synchronous.");
150521
+ }
150522
+ return this.importValue(value);
150523
+ },
150524
+ write: (operation, value) => {
150525
+ const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
150526
+ if (types3.isPromise(result)) {
150527
+ void Promise.resolve(result).catch(() => void 0);
150528
+ throw new TypeError("Live property setters must be synchronous.");
150529
+ }
150530
+ },
150531
+ method: (operation) => {
150532
+ const value = copyHostValueToSandbox(
150533
+ operation,
150534
+ [],
150535
+ this.bridgeOptions(),
150536
+ this.nativeConversions,
150537
+ "<host-method>"
150538
+ );
150539
+ if (!isSandboxClosure(value)) throw new TypeError("Invalid host method.");
150540
+ return value;
150541
+ }
150542
+ });
150543
+ this.hostObjects.add(object);
150544
+ try {
150545
+ this.budget.chargeDataUsage(1);
150546
+ } catch (error3) {
150547
+ this.poison(error3);
150548
+ throw error3;
150549
+ }
150550
+ return object;
150551
+ };
150552
+ wrapCallback = (closure) => {
150553
+ this.assertOpen();
150554
+ const existing = this.callbackCache.get(closure);
150555
+ if (existing !== void 0 && this.callbacks.has(existing)) return existing;
150556
+ this.checkCollection(this.callbacks.size + 1, this.limits.callbacks, "callback");
150557
+ const invokeCallback = this.invokeCallback;
150558
+ const callback = function(...args) {
150559
+ return invokeCallback(callback, { args, thisValue: this });
150560
+ };
150561
+ this.callbacks.set(callback, closure);
150562
+ this.callbackCache.set(closure, callback);
150563
+ registerGuestCallback(callback, {
150564
+ owner: this,
150565
+ closure,
150566
+ assertActive: () => {
150567
+ this.assertOpen();
150568
+ if (!this.callbacks.has(callback)) throw new TypeError("Guest callback is revoked.");
150569
+ }
150570
+ });
150571
+ try {
150572
+ this.budget.reconcileDataUsage(
150573
+ measureSandboxData([...this.scope?.retainedValues() ?? [], ...this.retainedCallbacks()])
150574
+ );
150575
+ } catch (error3) {
150576
+ this.poison(error3);
150577
+ throw error3;
150578
+ }
150579
+ return callback;
150580
+ };
150581
+ releaseCallback = (callback) => {
150582
+ readGuestCallback(callback, this);
150583
+ revokeGuestCallback(callback, this);
150584
+ this.callbacks.delete(callback);
150585
+ if (this.active === void 0)
150586
+ reconcileCompiledValues(
150587
+ this.budget,
150588
+ [...this.scope?.retainedValues() ?? [], ...this.retainedCallbacks()],
150589
+ this.compilation
150590
+ );
150591
+ };
150592
+ invokeCallback = async (callback, options = {}) => {
150593
+ if (this.closed || this.failure !== void 0) await this.dispose();
150594
+ this.assertOpen();
150595
+ const closure = readGuestCallback(callback, this);
150596
+ this.checkCollection(this.pendingCallbacks.size + 1, this.limits.callbacks, "pending callback");
150597
+ const record2 = { closure };
150598
+ this.pendingCallbacks.add(record2);
150599
+ const invoke2 = async () => {
150600
+ this.assertOpen();
150601
+ readGuestCallback(callback, this);
150602
+ const leave = enterRunningState(closure);
150603
+ const leaveCall = this.budget.enterCall();
150604
+ try {
150605
+ const values = this.importValue([
150606
+ options.thisValue,
150607
+ [...options.args ?? []]
150608
+ ]);
150609
+ const value = await closure.call(values[1], {
150610
+ thisValue: values[0],
150611
+ compilation: this.compilation,
150612
+ stack: []
150613
+ });
150614
+ const settled = await suspendJob(
150615
+ awaitSandboxValue(value, this.controller.signal, this.budget)
150616
+ );
150617
+ return this.exportValue(settled);
150618
+ } finally {
150619
+ leaveCall();
150620
+ leave();
150621
+ }
150622
+ };
150623
+ try {
150624
+ if (this.active !== void 0) {
150625
+ record2.promise = withSandboxPromiseRejectionTracker(
150626
+ this.tracker,
150627
+ () => runResources.run(
150628
+ { signal: this.controller.signal, add: this.onCleanup },
150629
+ () => withCancellationSignal(
150630
+ this.controller.signal,
150631
+ () => this.phase.getStore()?.active ? runAsyncPrefix(invoke2) : this.queue.run(invoke2)
150632
+ )
150633
+ )
150634
+ );
150635
+ } else {
150636
+ record2.promise = this.perform(() => this.queue.run(invoke2));
150637
+ }
150638
+ return await record2.promise;
150639
+ } catch (error3) {
150640
+ if (error3 instanceof SandboxError) this.poison(error3);
150641
+ throw error3;
150642
+ } finally {
150643
+ this.pendingCallbacks.delete(record2);
150644
+ if (!this.closed && this.active === void 0)
150645
+ reconcileCompiledValues(
150646
+ this.budget,
150647
+ [...this.scope?.retainedValues() ?? [], ...this.retainedCallbacks()],
150648
+ this.compilation
150649
+ );
150650
+ }
150651
+ };
150652
+ initialize() {
150653
+ if (this.initialized) return;
150654
+ this.assertOpen();
150655
+ this.initialized = true;
150656
+ for (const extension of this.extensions) {
150657
+ const context = Object.freeze({
150658
+ signal: this.controller.signal,
150659
+ onCleanup: this.onCleanup,
150660
+ chargeWork: this.chargeWork,
150661
+ createHostObject: this.createHostObject,
150662
+ invokeCallback: this.invokeCallback,
150663
+ releaseCallback: this.releaseCallback,
150664
+ nestedOperation: (operation) => {
150665
+ this.assertOpen();
150666
+ if (!extension.manifest.capabilities?.includes("source:nested"))
150667
+ throw new TypeError("Nested source requires the source:nested grant.");
150668
+ if (typeof operation !== "function")
150669
+ throw new TypeError("Nested operation must be a function.");
150670
+ if (this.scope !== void 0)
150671
+ throw new TypeError("Nested operations must be registered during setup.");
150672
+ const owner = this.nestedOperations.get(operation);
150673
+ if (owner !== void 0 && owner !== extension)
150674
+ throw new TypeError("Nested operation already belongs to another extension.");
150675
+ this.nestedOperations.set(operation, extension);
150676
+ return operation;
150677
+ },
150678
+ evaluateNested: (source) => {
150679
+ const phase = this.phase.getStore();
150680
+ if (!extension.manifest.capabilities?.includes("source:nested") || !phase?.active || phase.extension !== extension || phase.evaluating) {
150681
+ const error3 = new SandboxError("reentry");
150682
+ this.poison(error3);
150683
+ const rejected = Promise.reject(error3);
150684
+ void rejected.catch(() => void 0);
150685
+ return rejected;
150686
+ }
150687
+ const pending = this.evaluateNested(source, extension);
150688
+ phase.pending.add(pending);
150689
+ void pending.then(
150690
+ () => {
150691
+ phase.pending.delete(pending);
150692
+ },
150693
+ (reason) => {
150694
+ phase.pending.delete(pending);
150695
+ phase.failure ??= { reason };
150696
+ }
150697
+ );
150698
+ return pending;
150699
+ }
150700
+ });
150701
+ const output = getExtensionSetup(extension)(context);
150702
+ if (types3.isPromise(output)) {
150703
+ void Promise.resolve(output).catch(() => void 0);
150704
+ throw new TypeError("Extension setup must be synchronous.");
150705
+ }
150706
+ const exports = readDataRecord(output, "Extension exports");
150707
+ if (Object.keys(exports).some((key3) => key3 !== "globals" && key3 !== "modules"))
150708
+ throw new TypeError("Unknown extension export field.");
150709
+ const globals = readDataRecord(
150710
+ exports.globals ?? {},
150711
+ "Extension globals"
150712
+ );
150713
+ const modules = readModules(exports.modules);
150714
+ assertNames(Object.keys(globals), extension.manifest.globals ?? [], "global");
150715
+ assertNames(Object.keys(modules), Object.keys(extension.manifest.modules ?? {}), "module");
150716
+ for (const [name, values] of Object.entries(modules)) {
150717
+ assertNames(Object.keys(values), extension.manifest.modules?.[name] ?? [], "module export");
150718
+ this.modules[name] ??= /* @__PURE__ */ Object.create(null);
150719
+ Object.assign(this.modules[name], values);
150720
+ }
150721
+ Object.assign(this.globals, globals);
150722
+ }
150723
+ const bindings = wrapCallerInjectedBindings(this.globals, this.bridgeOptions());
150724
+ this.scope = new Scope(this.builtinBindings, void 0, void 0, { chargeData: false }).child(
150725
+ bindings,
150726
+ { functionBoundary: true }
150727
+ );
150728
+ }
150729
+ async evaluateRaw(source, filename = "<realm>", nested = false) {
150730
+ this.assertOpen();
150731
+ if (typeof source !== "string") throw new TypeError("Realm source must be a string.");
150732
+ const module = parseExecutableModule(source, filename, this.lease.owner);
150733
+ this.initialize();
150734
+ const imports = resolveModuleImports(module, this.modules, {
150735
+ ...this.bridgeOptions(),
150736
+ wrappedModules: this.convertedModules
150737
+ });
150738
+ for (const [name, value] of Object.entries(imports)) {
150739
+ const binding = this.scope.lookup(name);
150740
+ if (!binding.found) this.scope.declare(name, "const", value);
150741
+ else if (binding.value !== value) throw new TypeError(`Conflicting import '${name}'.`);
150742
+ }
150743
+ const result = await interpret(
150744
+ {
150745
+ type: "BlockStatement",
150746
+ body: module.body.filter((statement) => statement.type !== "ImportDeclaration"),
150747
+ span: module.span
150748
+ },
150749
+ {
150750
+ scope: this.scope,
150751
+ useScopeDirectly: true,
150752
+ budget: this.budget,
150753
+ compilation: this.compilation,
150754
+ signal: this.controller.signal,
150755
+ surfaceUnhandledThrows: true,
150756
+ jobs: this.queue,
150757
+ nested,
150758
+ assertActive: this.assertOpen
150759
+ }
150760
+ );
150761
+ this.assertOpen();
150762
+ return result;
150763
+ }
150764
+ evaluateNested = async (source, extension) => {
150765
+ this.assertOpen();
150766
+ const phase = this.phase.getStore();
150767
+ if (!phase?.active || phase.extension !== extension || phase.evaluating || this.active === void 0)
150768
+ throw new SandboxError("reentry");
150769
+ const leave = this.budget.enterCall();
150770
+ phase.evaluating = true;
150771
+ try {
150772
+ if (++this.nestedDepth > this.limits.nestedEvaluations) {
150773
+ const error3 = new SandboxError({
150774
+ budget: "callDepth",
150775
+ current: this.nestedDepth,
150776
+ limit: this.limits.nestedEvaluations
150777
+ });
150778
+ this.poison(error3);
150779
+ throw error3;
150780
+ }
150781
+ const result = await this.evaluateRaw(source, "<nested>", true);
150782
+ if (!result.ok) throw new Error(result.error.message);
150783
+ } finally {
150784
+ this.nestedDepth--;
150785
+ phase.evaluating = false;
150786
+ leave();
150787
+ }
150788
+ };
150789
+ evaluate = async (source, options = {}) => this.perform(async () => {
150790
+ const result = await this.evaluateRaw(source, options.filename);
150791
+ if (!result.ok) {
150792
+ await this.dispose();
150793
+ return { ok: false, error: result.error, stats: result.stats };
150794
+ }
150795
+ return { ok: true, returnValue: this.exportValue(result.returnValue), stats: result.stats };
150796
+ });
150797
+ async perform(task) {
150798
+ if (this.closed || this.failure !== void 0) await this.dispose();
150799
+ this.assertOpen();
150800
+ if (this.active !== void 0) throw new SandboxError("reentry");
150801
+ const pending = Promise.resolve().then(
150802
+ () => withSandboxPromiseRejectionTracker(
150803
+ this.tracker,
150804
+ () => runResources.run(
150805
+ { signal: this.controller.signal, add: this.onCleanup },
150806
+ () => withCancellationSignal(this.controller.signal, task)
150807
+ )
150808
+ )
150809
+ );
150810
+ this.active = pending;
150811
+ try {
150812
+ const result = await pending;
150813
+ await this.queue.drain();
150814
+ const unhandled = await this.tracker.findUnhandledRejection();
150815
+ if (unhandled !== void 0) {
150816
+ const error3 = new Error(
150817
+ `Unhandled guest promise rejection: ${describeThrownValue(unhandled.reason)}`
150818
+ );
150819
+ error3.name = "UnhandledRejectionError";
150820
+ throw error3;
150821
+ }
150822
+ if (this.failure !== void 0) throw this.failure.reason;
150823
+ if (!this.closed)
150824
+ reconcileCompiledValues(
150825
+ this.budget,
150826
+ [...this.scope?.retainedValues() ?? [], ...this.retainedCallbacks()],
150827
+ this.compilation
150828
+ );
150829
+ return result;
150830
+ } catch (error3) {
150831
+ this.poison(error3);
150832
+ try {
150833
+ await this.dispose();
150834
+ } catch (cleanup) {
150835
+ throw new AggregateError([error3, cleanup], "Realm execution and cleanup failed.");
150836
+ }
150837
+ throw error3;
150838
+ } finally {
150839
+ this.active = void 0;
150840
+ }
150841
+ }
150842
+ close = () => {
150843
+ this.closed = true;
150844
+ this.controller.abort(new Error("SafeJS realm is closed."));
150845
+ if (this.phase.getStore()?.active) return this.dispose();
150846
+ return Promise.allSettled([
150847
+ this.active,
150848
+ ...Array.from(this.pendingCallbacks, (pending) => pending.promise)
150849
+ ]).then(() => this.dispose());
150850
+ };
150851
+ dispose() {
150852
+ if (this.disposal !== void 0) return this.disposal;
150853
+ this.closed = true;
150854
+ this.controller.abort(new Error("SafeJS realm is closed."));
150855
+ this.options.signal?.removeEventListener("abort", this.abort);
150856
+ for (const callback of this.callbacks.keys()) revokeGuestCallback(callback, this);
150857
+ this.callbacks.clear();
150858
+ for (const object of this.hostObjects) revokeHostObject(object, this);
150859
+ this.hostObjects.clear();
150860
+ this.budget.setRetainedValues(this, void 0);
150861
+ this.disposal = (async () => {
150862
+ const errors2 = [];
150863
+ for (const cleanup of this.cleanups.splice(0).reverse()) {
150864
+ try {
150865
+ await cleanup();
150866
+ } catch (error3) {
150867
+ errors2.push(error3);
150868
+ }
150869
+ }
150870
+ this.scope = void 0;
150871
+ this.convertedModules.clear();
150872
+ for (const key3 of Object.keys(this.globals)) delete this.globals[key3];
150873
+ for (const key3 of Object.keys(this.modules)) delete this.modules[key3];
150874
+ for (const key3 of Object.keys(this.builtinBindings))
150875
+ Reflect.deleteProperty(this.builtinBindings, key3);
150876
+ this.nativeConversions.seen = /* @__PURE__ */ new WeakMap();
150877
+ reconcileCompiledValues(this.budget, [], this.compilation);
150878
+ this.compilation.dispose();
150879
+ this.lease.release();
150880
+ if (errors2.length > 0) throw new AggregateError(errors2, "Realm cleanup failed.");
150881
+ })();
150882
+ return this.disposal;
150883
+ }
150884
+ };
150885
+ }
150886
+ });
150887
+
149926
150888
  // packages/safe-js/src/snapshot/dump.ts
149927
150889
  function attachDumpController(result, controller) {
149928
150890
  Object.defineProperty(result, RUN_DUMP_CONTROLLER, {
@@ -150493,11 +151455,12 @@ var init_replay_inputs = __esm({
150493
151455
  });
150494
151456
 
150495
151457
  // packages/safe-js/src/run.ts
150496
- import { AsyncLocalStorage as AsyncLocalStorage9 } from "node:async_hooks";
151458
+ import { AsyncLocalStorage as AsyncLocalStorage10 } from "node:async_hooks";
150497
151459
  function run(source, options = {}) {
151460
+ if (options.extensions !== void 0) return runWithExtensions(source, options);
150498
151461
  const lifecycle = {
150499
151462
  hostCallbackDepth: 0,
150500
- hostCallbackContext: new AsyncLocalStorage9()
151463
+ hostCallbackContext: new AsyncLocalStorage10()
150501
151464
  };
150502
151465
  const dumpController = createDumpController(lifecycle);
150503
151466
  const promiseTracker = createSandboxPromiseRejectionTracker();
@@ -150563,32 +151526,7 @@ function run(source, options = {}) {
150563
151526
  lifecycle
150564
151527
  })
150565
151528
  );
150566
- const builtinBindings = {
150567
- ...createConsoleJsonGlobals({
150568
- compileOwner: operation.owner,
150569
- budget,
150570
- hostCalls,
150571
- sink: options.sink
150572
- }),
150573
- ...createCollectionGlobals({ budget }),
150574
- Float32Array: createFloat32ArrayGlobal(budget),
150575
- ...createErrorGlobals({
150576
- budget
150577
- }),
150578
- ...createMathGlobals({
150579
- random: random?.generator.next
150580
- }),
150581
- ...createObjectArrayGlobals({
150582
- budget
150583
- }),
150584
- ...createMiscGlobals({
150585
- budget
150586
- }),
150587
- ...createPromiseGlobals({
150588
- budget
150589
- }),
150590
- ...createRegexGlobals(operation.owner)
150591
- };
151529
+ const builtinBindings = createBuiltinBindings({ compileOwner: operation.owner, budget, hostCalls, sink: options.sink, random: random?.generator.next });
150592
151530
  const importMeta = convertInitialInput(
150593
151531
  () => deepCopyToSandbox(options.importMeta ?? {})
150594
151532
  );
@@ -151045,6 +151983,7 @@ var UnhandledRejectionError, DEFAULT_MAX_CALL_DEPTH;
151045
151983
  var init_run7 = __esm({
151046
151984
  "packages/safe-js/src/run.ts"() {
151047
151985
  "use strict";
151986
+ init_realm();
151048
151987
  init_hash();
151049
151988
  init_resources();
151050
151989
  init_random();
@@ -151058,14 +151997,7 @@ var init_run7 = __esm({
151058
151997
  init_running_state();
151059
151998
  init_promise_tracker();
151060
151999
  init_host_call();
151061
- init_console_json();
151062
- init_collections();
151063
- init_float32array2();
151064
- init_error();
151065
- init_math();
151066
- init_regex2();
151067
- init_misc();
151068
- init_object_array();
152000
+ init_globals();
151069
152001
  init_host_bridge();
151070
152002
  init_interpreter();
151071
152003
  init_promise();
@@ -151414,7 +152346,7 @@ var init_find_exported = __esm({
151414
152346
  });
151415
152347
 
151416
152348
  // packages/safe-js/src/modules/agent.ts
151417
- import { AsyncLocalStorage as AsyncLocalStorage10 } from "node:async_hooks";
152349
+ import { AsyncLocalStorage as AsyncLocalStorage11 } from "node:async_hooks";
151418
152350
  function createSpawnUsageAccumulator() {
151419
152351
  let inputTokens = 0;
151420
152352
  let outputTokens = 0;
@@ -152317,7 +153249,7 @@ var init_agent3 = __esm({
152317
153249
  hostErrorData.set(this, { result });
152318
153250
  }
152319
153251
  };
152320
- activeUsageAccumulator = new AsyncLocalStorage10();
153252
+ activeUsageAccumulator = new AsyncLocalStorage11();
152321
153253
  oneAttemptRetryOptions = {
152322
153254
  maxAttempts: 1,
152323
153255
  backoffMs: 0,
@@ -154176,6 +155108,8 @@ var init_src48 = __esm({
154176
155108
  init_parse6();
154177
155109
  init_lint4();
154178
155110
  init_run7();
155111
+ init_realm();
155112
+ init_extensions();
154179
155113
  init_random();
154180
155114
  init_otel2();
154181
155115
  init_backend();
@@ -157943,7 +158877,7 @@ var init_package2 = __esm({
157943
158877
  "package.json"() {
157944
158878
  package_default2 = {
157945
158879
  name: "poe-code",
157946
- version: "14.0.5",
158880
+ version: "14.0.6",
157947
158881
  description: "CLI tool to configure Poe API for developer workflows.",
157948
158882
  license: "MIT",
157949
158883
  type: "module",