@poe-platform/safe-js 0.1.123 → 0.1.125

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.
@@ -23880,6 +23880,44 @@ function hoistVarDeclarations(node, scope) {
23880
23880
  }
23881
23881
  }
23882
23882
 
23883
+ // packages/safe-js/src/interp/resources.ts
23884
+ import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
23885
+ var runResources = new AsyncLocalStorage5();
23886
+ async function withRunResources(signal, execute) {
23887
+ const controller = new AbortController();
23888
+ const cancel = () => controller.abort(signal?.reason);
23889
+ const cleanups = /* @__PURE__ */ new Set();
23890
+ const resources = {
23891
+ signal: controller.signal,
23892
+ referenceReleases: /* @__PURE__ */ new Set(),
23893
+ add(close) {
23894
+ cleanups.add(close);
23895
+ }
23896
+ };
23897
+ signal?.addEventListener("abort", cancel, { once: true });
23898
+ if (signal?.aborted) cancel();
23899
+ let result;
23900
+ let failure;
23901
+ let errors = [];
23902
+ try {
23903
+ result = await runResources.run(resources, execute);
23904
+ } catch (error) {
23905
+ failure = { reason: error };
23906
+ } finally {
23907
+ signal?.removeEventListener("abort", cancel);
23908
+ controller.abort(new Error("SafeJS run finished."));
23909
+ for (const release of resources.referenceReleases) release();
23910
+ resources.referenceReleases.clear();
23911
+ const outcomes = await Promise.allSettled(
23912
+ [...cleanups].map((close) => Promise.resolve().then(close))
23913
+ );
23914
+ errors = outcomes.flatMap((outcome) => outcome.status === "rejected" ? [outcome.reason] : []);
23915
+ }
23916
+ if (failure !== void 0) throw failure.reason;
23917
+ if (errors.length > 0) throw new AggregateError(errors, "SafeJS resource cleanup failed.");
23918
+ return result;
23919
+ }
23920
+
23883
23921
  // packages/safe-js/src/interp/methods/array.ts
23884
23922
  var arrayLikeSources = /* @__PURE__ */ new WeakMap();
23885
23923
  var activeArrayCallbacks = /* @__PURE__ */ new WeakMap();
@@ -26557,89 +26595,110 @@ async function evaluateEmptyStatement(_node, _context) {
26557
26595
  }
26558
26596
  async function evaluateArrayExpression(node, context) {
26559
26597
  const values = [];
26560
- for (const element of node.elements) {
26561
- if (element.type === "UndefinedLiteral" && element.elision === true) {
26562
- values.length += 1;
26563
- context.budget.allocateArrayLength(values.length);
26564
- continue;
26565
- }
26566
- if (element.type === "SpreadElement") {
26567
- const spreadValues = await evaluateSpreadElement(element, context);
26568
- if (!spreadValues.ok) {
26569
- return spreadValues.result;
26598
+ const release = retainValues(context.budget, () => [values]);
26599
+ try {
26600
+ for (const element of node.elements) {
26601
+ if (element.type === "UndefinedLiteral" && element.elision === true) {
26602
+ values.length += 1;
26603
+ context.budget.allocateArrayLength(values.length);
26604
+ continue;
26570
26605
  }
26571
- appendArrayValues2(values, spreadValues.value);
26606
+ if (element.type === "SpreadElement") {
26607
+ const spreadValues = await evaluateSpreadElement(element, context);
26608
+ if (!spreadValues.ok) {
26609
+ return spreadValues.result;
26610
+ }
26611
+ appendArrayValues2(values, spreadValues.value);
26612
+ context.budget.allocateArrayLength(values.length);
26613
+ continue;
26614
+ }
26615
+ const result = await evaluateNode(element, context);
26616
+ if (result.kind !== "normal") {
26617
+ return result;
26618
+ }
26619
+ values.push(result.value);
26572
26620
  context.budget.allocateArrayLength(values.length);
26573
- continue;
26574
26621
  }
26575
- const result = await evaluateNode(element, context);
26576
- if (result.kind !== "normal") {
26577
- return result;
26578
- }
26579
- values.push(result.value);
26580
- context.budget.allocateArrayLength(values.length);
26622
+ return {
26623
+ kind: "normal",
26624
+ hasValue: true,
26625
+ value: values
26626
+ };
26627
+ } finally {
26628
+ release();
26581
26629
  }
26582
- return {
26583
- kind: "normal",
26584
- hasValue: true,
26585
- value: values
26586
- };
26587
26630
  }
26588
26631
  async function evaluateObjectExpression(node, context) {
26589
26632
  const object = /* @__PURE__ */ Object.create(null);
26590
- for (const property of node.properties) {
26591
- if (property.type === "SpreadElement") {
26592
- const spreadEntries = await evaluateObjectSpread(property, context);
26593
- if (!spreadEntries.ok) {
26594
- return spreadEntries.result;
26633
+ const release = retainValues(context.budget, () => [object]);
26634
+ try {
26635
+ for (const property of node.properties) {
26636
+ if (property.type === "SpreadElement") {
26637
+ const spreadEntries = await evaluateObjectSpread(property, context);
26638
+ if (!spreadEntries.ok) {
26639
+ return spreadEntries.result;
26640
+ }
26641
+ for (const [key2, value2] of spreadEntries.value) {
26642
+ defineSandboxProperty(object, key2, value2);
26643
+ }
26644
+ continue;
26595
26645
  }
26596
- for (const [key2, value2] of spreadEntries.value) {
26597
- defineSandboxProperty(object, key2, value2);
26646
+ const key = await evaluateObjectPropertyKey(property, context);
26647
+ if (!key.ok) {
26648
+ return key.result;
26598
26649
  }
26599
- continue;
26600
- }
26601
- const key = await evaluateObjectPropertyKey(property, context);
26602
- if (!key.ok) {
26603
- return key.result;
26604
- }
26605
- const value = await evaluateNode(property.value, context);
26606
- if (value.kind !== "normal") {
26607
- return value;
26608
- }
26609
- if (isObjectPrototypeSetterProperty(property, key.value)) {
26610
- if (value.value === null || typeof value.value === "object") {
26611
- setSandboxPrototype(object, value.value, context.budget);
26650
+ const releaseKey = retainValues(context.budget, () => [key.value]);
26651
+ let value;
26652
+ try {
26653
+ value = await evaluateNode(property.value, context);
26654
+ } finally {
26655
+ releaseKey();
26612
26656
  }
26613
- continue;
26657
+ if (value.kind !== "normal") {
26658
+ return value;
26659
+ }
26660
+ if (isObjectPrototypeSetterProperty(property, key.value)) {
26661
+ if (value.value === null || typeof value.value === "object") {
26662
+ setSandboxPrototype(object, value.value, context.budget);
26663
+ }
26664
+ continue;
26665
+ }
26666
+ defineSandboxProperty(object, String(key.value), value.value);
26614
26667
  }
26615
- defineSandboxProperty(object, String(key.value), value.value);
26668
+ return {
26669
+ kind: "normal",
26670
+ hasValue: true,
26671
+ value: object
26672
+ };
26673
+ } finally {
26674
+ release();
26616
26675
  }
26617
- return {
26618
- kind: "normal",
26619
- hasValue: true,
26620
- value: object
26621
- };
26622
26676
  }
26623
26677
  function isObjectPrototypeSetterProperty(property, key) {
26624
26678
  return !property.computed && !property.shorthand && key === "__proto__";
26625
26679
  }
26626
26680
  async function evaluateTemplateLiteral(node, context) {
26627
26681
  let value = context.budget.allocateString(node.quasis[0]?.value.cooked ?? "");
26628
- for (let index = 0; index < node.expressions.length; index += 1) {
26629
- const expression = await evaluateNode(node.expressions[index], context);
26630
- if (expression.kind !== "normal") {
26631
- return expression;
26682
+ const release = retainValues(context.budget, () => [value]);
26683
+ try {
26684
+ for (let index = 0; index < node.expressions.length; index += 1) {
26685
+ const expression = await evaluateNode(node.expressions[index], context);
26686
+ if (expression.kind !== "normal") {
26687
+ return expression;
26688
+ }
26689
+ const expressionText = context.budget.allocateString(String(expression.value));
26690
+ value = context.budget.allocateString(value + expressionText);
26691
+ const quasiText = context.budget.allocateString(node.quasis[index + 1]?.value.cooked ?? "");
26692
+ value = context.budget.allocateString(value + quasiText);
26632
26693
  }
26633
- const expressionText = context.budget.allocateString(String(expression.value));
26634
- value = context.budget.allocateString(value + expressionText);
26635
- const quasiText = context.budget.allocateString(node.quasis[index + 1]?.value.cooked ?? "");
26636
- value = context.budget.allocateString(value + quasiText);
26694
+ return {
26695
+ kind: "normal",
26696
+ hasValue: true,
26697
+ value
26698
+ };
26699
+ } finally {
26700
+ release();
26637
26701
  }
26638
- return {
26639
- kind: "normal",
26640
- hasValue: true,
26641
- value
26642
- };
26643
26702
  }
26644
26703
  async function evaluateTaggedTemplateExpression(node, context) {
26645
26704
  const tag = await evaluateNode(node.tag, context);
@@ -26666,20 +26725,25 @@ async function evaluateTaggedTemplateExpression(node, context) {
26666
26725
  }
26667
26726
  async function evaluateTemplateExpressionValues(node, context) {
26668
26727
  const values = [];
26669
- for (const expressionNode of node.expressions) {
26670
- const expression = await evaluateNode(expressionNode, context);
26671
- if (expression.kind !== "normal") {
26672
- return {
26673
- ok: false,
26674
- result: expression
26675
- };
26728
+ const release = retainValues(context.budget, () => values);
26729
+ try {
26730
+ for (const expressionNode of node.expressions) {
26731
+ const expression = await evaluateNode(expressionNode, context);
26732
+ if (expression.kind !== "normal") {
26733
+ return {
26734
+ ok: false,
26735
+ result: expression
26736
+ };
26737
+ }
26738
+ values.push(expression.value);
26676
26739
  }
26677
- values.push(expression.value);
26740
+ return {
26741
+ ok: true,
26742
+ value: values
26743
+ };
26744
+ } finally {
26745
+ release();
26678
26746
  }
26679
- return {
26680
- ok: true,
26681
- value: values
26682
- };
26683
26747
  }
26684
26748
  function createTaggedTemplateStrings(node, context) {
26685
26749
  context.budget.allocateArrayLength(node.quasis.length);
@@ -26727,23 +26791,30 @@ async function evaluateBinaryExpression(node, context) {
26727
26791
  if (left.kind !== "normal") {
26728
26792
  return left;
26729
26793
  }
26730
- const right = await evaluateNode(node.right, context);
26731
- if (right.kind !== "normal") {
26732
- return right;
26733
- }
26734
- let leftValue = left.value;
26735
- if (node.operator === "in") {
26736
- if (typeof right.value !== "object" || right.value === null) {
26737
- throw new TypeError("Right-hand side of 'in' must be an object.");
26794
+ let rightValue;
26795
+ const release = retainValues(context.budget, () => [left.value, rightValue]);
26796
+ try {
26797
+ const right = await evaluateNode(node.right, context);
26798
+ if (right.kind !== "normal") {
26799
+ return right;
26800
+ }
26801
+ rightValue = right.value;
26802
+ let leftValue = left.value;
26803
+ if (node.operator === "in") {
26804
+ if (typeof right.value !== "object" || right.value === null) {
26805
+ throw new TypeError("Right-hand side of 'in' must be an object.");
26806
+ }
26807
+ leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
26738
26808
  }
26739
- leftValue = await toPropertyKey(leftValue, context.budget, createCoercionContext(context));
26809
+ const value = applyBinaryOperator(node, leftValue, right.value, context);
26810
+ return {
26811
+ kind: "normal",
26812
+ hasValue: true,
26813
+ value
26814
+ };
26815
+ } finally {
26816
+ release();
26740
26817
  }
26741
- const value = applyBinaryOperator(node, leftValue, right.value, context);
26742
- return {
26743
- kind: "normal",
26744
- hasValue: true,
26745
- value
26746
- };
26747
26818
  }
26748
26819
  async function evaluateAssignmentExpression(node, context) {
26749
26820
  if (node.left.type === "ArrayPattern" || node.left.type === "ObjectPattern") {
@@ -26816,61 +26887,64 @@ async function evaluateMemberAssignmentExpression(node, context) {
26816
26887
  if (node.left.type !== "MemberExpression") {
26817
26888
  throw new TypeError("Expected member assignment target.");
26818
26889
  }
26819
- const member = await evaluateMemberAccess(node.left, context);
26820
- if (member.kind === "error") {
26821
- return member;
26822
- }
26823
- if (member.kind === "completion") {
26824
- return member.result;
26825
- }
26826
- if (member.kind === "nullish") {
26827
- throw new TypeError("Cannot assign properties of null or undefined.");
26828
- }
26829
- let property;
26830
- let current = void 0;
26831
- if (node.operator !== "=") {
26832
- if (member.object === null || member.object === void 0) {
26890
+ return evaluateMemberAccess(node.left, context, async (member) => {
26891
+ if (member.kind === "nullish") {
26833
26892
  throw new TypeError("Cannot assign properties of null or undefined.");
26834
26893
  }
26835
- property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
26836
- current = getPropertyValue(member.object, property, context);
26837
- }
26838
- if (node.operator === "&&=" && !isTruthy(current)) {
26839
- return {
26840
- kind: "normal",
26841
- hasValue: true,
26842
- value: current
26843
- };
26844
- }
26845
- if (node.operator === "||=" && isTruthy(current)) {
26846
- return {
26847
- kind: "normal",
26848
- hasValue: true,
26849
- value: current
26850
- };
26851
- }
26852
- if (node.operator === "??=" && current !== null && current !== void 0) {
26853
- return {
26854
- kind: "normal",
26855
- hasValue: true,
26856
- value: current
26857
- };
26858
- }
26859
- const right = await evaluateNode(node.right, context);
26860
- if (right.kind !== "normal") {
26861
- return right;
26862
- }
26863
- const value = node.operator === "=" || node.operator === "&&=" || node.operator === "||=" || node.operator === "??=" ? right.value : await applyCompoundAssignmentOperator(node.operator, current, right.value, context);
26864
- if (member.object === null || member.object === void 0) {
26865
- throw new TypeError("Cannot assign properties of null or undefined.");
26866
- }
26867
- property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
26868
- setSandboxProperty(member.object, property, value, context.budget);
26869
- return {
26870
- kind: "normal",
26871
- hasValue: true,
26872
- value
26873
- };
26894
+ let property;
26895
+ let current = void 0;
26896
+ if (node.operator !== "=") {
26897
+ if (member.object === null || member.object === void 0) {
26898
+ throw new TypeError("Cannot assign properties of null or undefined.");
26899
+ }
26900
+ property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
26901
+ current = getPropertyValue(member.object, property, context);
26902
+ }
26903
+ if (node.operator === "&&=" && !isTruthy(current)) {
26904
+ return {
26905
+ kind: "normal",
26906
+ hasValue: true,
26907
+ value: current
26908
+ };
26909
+ }
26910
+ if (node.operator === "||=" && isTruthy(current)) {
26911
+ return {
26912
+ kind: "normal",
26913
+ hasValue: true,
26914
+ value: current
26915
+ };
26916
+ }
26917
+ if (node.operator === "??=" && current !== null && current !== void 0) {
26918
+ return {
26919
+ kind: "normal",
26920
+ hasValue: true,
26921
+ value: current
26922
+ };
26923
+ }
26924
+ let operands = [current, property];
26925
+ const release = retainValues(context.budget, () => operands);
26926
+ try {
26927
+ const right = await evaluateNode(node.right, context);
26928
+ if (right.kind !== "normal") {
26929
+ return right;
26930
+ }
26931
+ operands.push(right.value);
26932
+ const value = node.operator === "=" || node.operator === "&&=" || node.operator === "||=" || node.operator === "??=" ? right.value : await applyCompoundAssignmentOperator(node.operator, current, right.value, context);
26933
+ if (member.object === null || member.object === void 0) {
26934
+ throw new TypeError("Cannot assign properties of null or undefined.");
26935
+ }
26936
+ operands = [value];
26937
+ property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
26938
+ setSandboxProperty(member.object, property, value, context.budget);
26939
+ return {
26940
+ kind: "normal",
26941
+ hasValue: true,
26942
+ value
26943
+ };
26944
+ } finally {
26945
+ release();
26946
+ }
26947
+ });
26874
26948
  }
26875
26949
  async function evaluateLogicalExpression(node, context) {
26876
26950
  const left = await evaluateNode(node.left, context);
@@ -27849,33 +27923,28 @@ async function evaluateDeleteExpression(node, context) {
27849
27923
  "Unary operator 'delete' requires a member target."
27850
27924
  );
27851
27925
  }
27852
- const member = await evaluateMemberAccess(node.argument, context);
27853
- if (member.kind === "error") {
27854
- return member;
27855
- }
27856
- if (member.kind === "completion") {
27857
- return member.result;
27858
- }
27859
- if (member.kind === "nullish" || member.object === null || member.object === void 0) {
27860
- if (member.kind === "nullish" && node.argument.optional) {
27861
- return {
27862
- kind: "normal",
27863
- hasValue: true,
27864
- value: true
27865
- };
27926
+ return evaluateMemberAccess(node.argument, context, async (member) => {
27927
+ if (member.kind === "nullish" || member.object === null || member.object === void 0) {
27928
+ if (member.kind === "nullish") {
27929
+ return {
27930
+ kind: "normal",
27931
+ hasValue: true,
27932
+ value: true
27933
+ };
27934
+ }
27935
+ throw new TypeError("Cannot delete properties of null or undefined.");
27866
27936
  }
27867
- throw new TypeError("Cannot delete properties of null or undefined.");
27868
- }
27869
- if (!isIndexableSandboxValue(member.object)) {
27870
- throw new TypeError("Unary operator 'delete' requires a sandbox object property.");
27871
- }
27872
- const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
27873
- const deleted = deleteSandboxProperty(member.object, property);
27874
- return {
27875
- kind: "normal",
27876
- hasValue: true,
27877
- value: deleted
27878
- };
27937
+ if (!isIndexableSandboxValue(member.object)) {
27938
+ throw new TypeError("Unary operator 'delete' requires a sandbox object property.");
27939
+ }
27940
+ const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
27941
+ const deleted = deleteSandboxProperty(member.object, property);
27942
+ return {
27943
+ kind: "normal",
27944
+ hasValue: true,
27945
+ value: deleted
27946
+ };
27947
+ });
27879
27948
  }
27880
27949
  async function evaluateUpdateExpression(node, context) {
27881
27950
  if (node.argument.type === "Identifier") {
@@ -27911,41 +27980,35 @@ async function evaluateMemberUpdateExpression(node, context) {
27911
27980
  if (node.argument.type !== "MemberExpression") {
27912
27981
  throw new TypeError("Expected member update target.");
27913
27982
  }
27914
- const member = await evaluateMemberAccess(node.argument, context);
27915
- if (member.kind === "error") {
27916
- return member;
27917
- }
27918
- if (member.kind === "completion") {
27919
- return member.result;
27920
- }
27921
- if (member.kind === "nullish" || member.object === null || member.object === void 0) {
27922
- throw new TypeError("Cannot update properties of null or undefined.");
27923
- }
27924
- const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
27925
- const current = toNumber(
27926
- await toNumericPrimitive(getPropertyValue(member.object, property, context), context)
27927
- );
27928
- const next = node.operator === "++" ? current + 1 : current - 1;
27929
- setSandboxProperty(member.object, property, next, context.budget);
27930
- return {
27931
- kind: "normal",
27932
- hasValue: true,
27933
- value: node.prefix ? next : current
27934
- };
27983
+ return evaluateMemberAccess(node.argument, context, async (member) => {
27984
+ if (member.kind === "nullish" || member.object === null || member.object === void 0) {
27985
+ throw new TypeError("Cannot update properties of null or undefined.");
27986
+ }
27987
+ const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
27988
+ const current = toNumber(
27989
+ await toNumericPrimitive(getPropertyValue(member.object, property, context), context)
27990
+ );
27991
+ const next = node.operator === "++" ? current + 1 : current - 1;
27992
+ setSandboxProperty(member.object, property, next, context.budget);
27993
+ return {
27994
+ kind: "normal",
27995
+ hasValue: true,
27996
+ value: node.prefix ? next : current
27997
+ };
27998
+ });
27935
27999
  }
27936
28000
  async function evaluateMemberExpression(node, context) {
27937
- const member = await evaluateMemberAccess(node, context);
27938
- if (member.kind === "error") return member;
27939
- if (member.kind === "completion") return member.result;
27940
- if (member.kind === "nullish" || member.object === null || member.object === void 0) {
27941
- if (member.kind === "nullish" && node.optional) return { kind: "normal", hasValue: true, value: void 0 };
27942
- throw new TypeError("Cannot read properties of null or undefined.");
27943
- }
27944
- return {
27945
- kind: "normal",
27946
- hasValue: true,
27947
- value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
27948
- };
28001
+ return evaluateMemberAccess(node, context, async (member) => {
28002
+ if (member.kind === "nullish" || member.object === null || member.object === void 0) {
28003
+ if (member.kind === "nullish") return { kind: "normal", hasValue: true, value: void 0 };
28004
+ throw new TypeError("Cannot read properties of null or undefined.");
28005
+ }
28006
+ return {
28007
+ kind: "normal",
28008
+ hasValue: true,
28009
+ value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
28010
+ };
28011
+ });
27949
28012
  }
27950
28013
  function getPropertyValue(target, property, context) {
27951
28014
  if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
@@ -28053,26 +28116,33 @@ function attachFatalSandboxErrorContext(error, node, stackFrames) {
28053
28116
  attachErrorSpan(error, node.span);
28054
28117
  replaceErrorStack(error, stackFrames);
28055
28118
  }
28056
- async function evaluateMemberAccess(node, context) {
28119
+ async function evaluateMemberAccess(node, context, consume) {
28057
28120
  const object = await evaluateNode(node.object, context);
28058
- if (object.kind !== "normal") {
28059
- return {
28060
- kind: "completion",
28061
- result: object
28062
- };
28063
- }
28121
+ if (object.kind !== "normal") return object;
28064
28122
  if ((object.value === null || object.value === void 0) && node.optional) {
28065
- return {
28066
- kind: "nullish"
28067
- };
28123
+ return consume({ kind: "nullish" });
28068
28124
  }
28069
- const property = node.computed ? await evaluateNode(node.property, context) : { kind: "normal", value: getStaticPropertyName2(node.property) };
28070
- if (property.kind !== "normal") return { kind: "completion", result: property };
28071
- return {
28072
- kind: "resolved",
28073
- object: object.value,
28074
- property: property.value
28125
+ let property;
28126
+ const release = retainValues(context.budget, () => [object.value, property]);
28127
+ try {
28128
+ const result = node.computed ? await evaluateNode(node.property, context) : { kind: "normal", value: getStaticPropertyName2(node.property) };
28129
+ if (result.kind !== "normal") return result;
28130
+ property = result.value;
28131
+ return await consume({ kind: "resolved", object: object.value, property });
28132
+ } finally {
28133
+ release();
28134
+ }
28135
+ }
28136
+ function retainValues(budget, values) {
28137
+ const retained = {};
28138
+ budget.setRetainedValues(retained, values);
28139
+ const pending = runResources.getStore()?.referenceReleases;
28140
+ const release = () => {
28141
+ budget.setRetainedValues(retained, void 0);
28142
+ pending?.delete(release);
28075
28143
  };
28144
+ pending?.add(release);
28145
+ return release;
28076
28146
  }
28077
28147
  async function evaluateMemberProperty(node, context) {
28078
28148
  const property = await evaluateNode(node, context);
@@ -28109,137 +28179,132 @@ async function evaluateMemberCallExpression(node, context) {
28109
28179
  if (node.callee.type !== "MemberExpression") {
28110
28180
  throw new TypeError("Expected member call expression.");
28111
28181
  }
28112
- const reference = await evaluateMemberAccess(node.callee, context);
28113
- if (reference.kind === "error") {
28114
- return reference;
28115
- }
28116
- if (reference.kind === "completion") {
28117
- return reference.result;
28118
- }
28119
- if (reference.kind === "nullish" || reference.object === null || reference.object === void 0) {
28120
- if (reference.kind === "nullish") {
28121
- return {
28122
- kind: "normal",
28123
- hasValue: true,
28124
- value: void 0
28125
- };
28182
+ return evaluateMemberAccess(node.callee, context, async (reference) => {
28183
+ if (reference.kind === "nullish" || reference.object === null || reference.object === void 0) {
28184
+ if (reference.kind === "nullish") {
28185
+ return {
28186
+ kind: "normal",
28187
+ hasValue: true,
28188
+ value: void 0
28189
+ };
28190
+ }
28191
+ throw new TypeError("Cannot read properties of null or undefined.");
28126
28192
  }
28127
- throw new TypeError("Cannot read properties of null or undefined.");
28128
- }
28129
- const member = {
28130
- ...reference,
28131
- property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
28132
- };
28133
- if (typeof member.object === "string" && isStringMethodName(member.property)) {
28134
- return evaluateStringMethodCall(node, member.object, member.property, context);
28135
- }
28136
- if (typeof member.object === "number" && isNumberMethodName(member.property)) {
28137
- return evaluateNumberMethodCall(node, member.object, member.property, context);
28138
- }
28139
- if (Array.isArray(member.object) && isArrayMethodName(member.property) && !Object.hasOwn(member.object, member.property)) {
28140
- return evaluateArrayMethodCall(node, member.object, member.property, context);
28141
- }
28142
- if (isSandboxMap(member.object) && isMapMethodName(member.property)) {
28143
- return evaluateMapMethodCall(node, member.object, member.property, context);
28144
- }
28145
- if (isSandboxSet(member.object) && isSetMethodName(member.property)) {
28146
- return evaluateSetMethodCall(node, member.object, member.property, context);
28147
- }
28148
- if (typeof member.object === "string") {
28149
- return evaluatePrimitiveMemberCall(
28150
- node,
28151
- "String",
28152
- member.property,
28153
- getStringMember(member.object, member.property, context.budget),
28154
- context
28155
- );
28156
- }
28157
- if (typeof member.object === "number") {
28158
- return evaluatePrimitiveMemberCall(
28159
- node,
28160
- "Number",
28161
- member.property,
28162
- getNumberMember(member.property, context.budget),
28163
- context
28164
- );
28165
- }
28166
- if (Array.isArray(member.object) && !Object.hasOwn(member.object, member.property)) {
28167
- return evaluatePrimitiveMemberCall(
28168
- node,
28169
- "Array",
28170
- member.property,
28171
- getArrayMemberValue(member.object, member.property, context),
28172
- context
28173
- );
28174
- }
28175
- if (isSandboxMap(member.object)) {
28176
- return evaluatePrimitiveMemberCall(
28177
- node,
28178
- "Map",
28179
- member.property,
28180
- getMapMember(member.object, member.property, createMapMethodOptions(context)),
28181
- context
28182
- );
28183
- }
28184
- if (isSandboxDate(member.object)) {
28185
- return evaluateResolvedCallExpression(node, getDateMember(member.property, context.budget, context.compilation?.owner), context, member.object);
28186
- }
28187
- if (isFloat32Array(member.object)) {
28188
- return evaluateResolvedCallExpression(
28189
- node,
28190
- getFloat32Member(member.object, member.property, context.budget),
28191
- context,
28192
- member.object
28193
- );
28194
- }
28195
- if (isSandboxSet(member.object)) {
28196
- return evaluatePrimitiveMemberCall(
28197
- node,
28198
- "Set",
28199
- member.property,
28200
- getSetMember(member.object, member.property, createSetMethodOptions(context)),
28201
- context
28202
- );
28203
- }
28204
- if (isSandboxGenerator(member.object)) {
28205
- const memberValue = getGeneratorMember(member.object, member.property, context.budget);
28206
- if (memberValue === void 0) {
28207
- throw new TypeError(`Generator#${String(member.property)} is not a supported method.`);
28193
+ const member = {
28194
+ ...reference,
28195
+ property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
28196
+ };
28197
+ if (typeof member.object === "string" && isStringMethodName(member.property)) {
28198
+ return evaluateStringMethodCall(node, member.object, member.property, context);
28208
28199
  }
28209
- return evaluateResolvedCallExpression(node, memberValue, context, member.object);
28210
- }
28211
- if (isSandboxClosure(member.object)) {
28212
- const memberValue = getClosureMemberValue(member.object, member.property, context);
28213
- if (memberValue === void 0) {
28214
- throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
28200
+ if (typeof member.object === "number" && isNumberMethodName(member.property)) {
28201
+ return evaluateNumberMethodCall(node, member.object, member.property, context);
28202
+ }
28203
+ if (Array.isArray(member.object) && isArrayMethodName(member.property) && !Object.hasOwn(member.object, member.property)) {
28204
+ return evaluateArrayMethodCall(node, member.object, member.property, context);
28205
+ }
28206
+ if (isSandboxMap(member.object) && isMapMethodName(member.property)) {
28207
+ return evaluateMapMethodCall(node, member.object, member.property, context);
28208
+ }
28209
+ if (isSandboxSet(member.object) && isSetMethodName(member.property)) {
28210
+ return evaluateSetMethodCall(node, member.object, member.property, context);
28211
+ }
28212
+ if (typeof member.object === "string") {
28213
+ return evaluatePrimitiveMemberCall(
28214
+ node,
28215
+ "String",
28216
+ member.property,
28217
+ getStringMember(member.object, member.property, context.budget),
28218
+ context
28219
+ );
28220
+ }
28221
+ if (typeof member.object === "number") {
28222
+ return evaluatePrimitiveMemberCall(
28223
+ node,
28224
+ "Number",
28225
+ member.property,
28226
+ getNumberMember(member.property, context.budget),
28227
+ context
28228
+ );
28229
+ }
28230
+ if (Array.isArray(member.object) && !Object.hasOwn(member.object, member.property)) {
28231
+ return evaluatePrimitiveMemberCall(
28232
+ node,
28233
+ "Array",
28234
+ member.property,
28235
+ getArrayMemberValue(member.object, member.property, context),
28236
+ context
28237
+ );
28238
+ }
28239
+ if (isSandboxMap(member.object)) {
28240
+ return evaluatePrimitiveMemberCall(
28241
+ node,
28242
+ "Map",
28243
+ member.property,
28244
+ getMapMember(member.object, member.property, createMapMethodOptions(context)),
28245
+ context
28246
+ );
28247
+ }
28248
+ if (isSandboxDate(member.object)) {
28249
+ return evaluateResolvedCallExpression(node, getDateMember(member.property, context.budget, context.compilation?.owner), context, member.object);
28250
+ }
28251
+ if (isFloat32Array(member.object)) {
28252
+ return evaluateResolvedCallExpression(
28253
+ node,
28254
+ getFloat32Member(member.object, member.property, context.budget),
28255
+ context,
28256
+ member.object
28257
+ );
28258
+ }
28259
+ if (isSandboxSet(member.object)) {
28260
+ return evaluatePrimitiveMemberCall(
28261
+ node,
28262
+ "Set",
28263
+ member.property,
28264
+ getSetMember(member.object, member.property, createSetMethodOptions(context)),
28265
+ context
28266
+ );
28267
+ }
28268
+ if (isSandboxGenerator(member.object)) {
28269
+ const memberValue = getGeneratorMember(member.object, member.property, context.budget);
28270
+ if (memberValue === void 0) {
28271
+ throw new TypeError(`Generator#${String(member.property)} is not a supported method.`);
28272
+ }
28273
+ return evaluateResolvedCallExpression(node, memberValue, context, member.object);
28274
+ }
28275
+ if (isSandboxClosure(member.object)) {
28276
+ const memberValue = getClosureMemberValue(member.object, member.property, context);
28277
+ if (memberValue === void 0) {
28278
+ throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
28279
+ }
28280
+ return evaluateResolvedCallExpression(node, memberValue, context, member.object);
28281
+ }
28282
+ if (isSandboxPromise(member.object)) {
28283
+ return evaluateResolvedCallExpression(
28284
+ node,
28285
+ getPromiseMember(member.property, context.budget),
28286
+ context,
28287
+ member.object
28288
+ );
28289
+ }
28290
+ if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
28291
+ return evaluateResolvedCallExpression(
28292
+ node,
28293
+ getRegexMember(member.object, member.property, context.budget),
28294
+ context,
28295
+ member.object
28296
+ );
28297
+ }
28298
+ if (!isIndexableSandboxValue(member.object)) {
28299
+ throw new TypeError("Attempted to read a property from a non-object value.");
28215
28300
  }
28216
- return evaluateResolvedCallExpression(node, memberValue, context, member.object);
28217
- }
28218
- if (isSandboxPromise(member.object)) {
28219
- return evaluateResolvedCallExpression(
28220
- node,
28221
- getPromiseMember(member.property, context.budget),
28222
- context,
28223
- member.object
28224
- );
28225
- }
28226
- if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
28227
28301
  return evaluateResolvedCallExpression(
28228
28302
  node,
28229
- getRegexMember(member.object, member.property, context.budget),
28303
+ getMemberValue(member.object, member.property, context),
28230
28304
  context,
28231
28305
  member.object
28232
28306
  );
28233
- }
28234
- if (!isIndexableSandboxValue(member.object)) {
28235
- throw new TypeError("Attempted to read a property from a non-object value.");
28236
- }
28237
- return evaluateResolvedCallExpression(
28238
- node,
28239
- getMemberValue(member.object, member.property, context),
28240
- context,
28241
- member.object
28242
- );
28307
+ });
28243
28308
  }
28244
28309
  function evaluatePrimitiveMemberCall(node, receiverType, property, value, context) {
28245
28310
  if (value === void 0) {
@@ -28874,30 +28939,35 @@ async function invokeSandboxClosure(callee, args, context, stack, span, thisValu
28874
28939
  }
28875
28940
  async function evaluateCallArguments(args, context) {
28876
28941
  const values = [];
28877
- for (const arg of args) {
28878
- if (arg.type === "SpreadElement") {
28879
- const spreadValues = await evaluateSpreadElement(arg, context);
28880
- if (!spreadValues.ok) {
28881
- return spreadValues;
28942
+ const release = retainValues(context.budget, () => values);
28943
+ try {
28944
+ for (const arg of args) {
28945
+ if (arg.type === "SpreadElement") {
28946
+ const spreadValues = await evaluateSpreadElement(arg, context);
28947
+ if (!spreadValues.ok) {
28948
+ return spreadValues;
28949
+ }
28950
+ appendArrayValues2(values, spreadValues.value);
28951
+ context.budget.allocateArrayLength(values.length);
28952
+ continue;
28953
+ }
28954
+ const result = await evaluateNode(arg, context);
28955
+ if (result.kind !== "normal") {
28956
+ return {
28957
+ ok: false,
28958
+ result
28959
+ };
28882
28960
  }
28883
- appendArrayValues2(values, spreadValues.value);
28961
+ values.push(result.value);
28884
28962
  context.budget.allocateArrayLength(values.length);
28885
- continue;
28886
- }
28887
- const result = await evaluateNode(arg, context);
28888
- if (result.kind !== "normal") {
28889
- return {
28890
- ok: false,
28891
- result
28892
- };
28893
28963
  }
28894
- values.push(result.value);
28895
- context.budget.allocateArrayLength(values.length);
28964
+ return {
28965
+ ok: true,
28966
+ value: values
28967
+ };
28968
+ } finally {
28969
+ release();
28896
28970
  }
28897
- return {
28898
- ok: true,
28899
- value: values
28900
- };
28901
28971
  }
28902
28972
  async function evaluateSpreadElement(node, context) {
28903
28973
  const value = await evaluateNode(node.argument, context);
@@ -28912,21 +28982,26 @@ async function evaluateSpreadElement(node, context) {
28912
28982
  throw new TypeError("Spread arguments must evaluate to an iterable.");
28913
28983
  }
28914
28984
  const spreadValues = [];
28915
- while (true) {
28916
- const next = await iterator.next();
28917
- if (typeof next !== "object" || next === null) {
28918
- throw new TypeError("Iterator result must be an object.");
28919
- }
28920
- if (next.done === true) {
28921
- break;
28985
+ const release = retainValues(context.budget, () => [value.value, ...spreadValues]);
28986
+ try {
28987
+ while (true) {
28988
+ const next = await iterator.next();
28989
+ if (typeof next !== "object" || next === null) {
28990
+ throw new TypeError("Iterator result must be an object.");
28991
+ }
28992
+ if (next.done === true) {
28993
+ break;
28994
+ }
28995
+ spreadValues.push(next.value);
28996
+ context.budget.allocateArrayLength(spreadValues.length);
28922
28997
  }
28923
- spreadValues.push(next.value);
28924
- context.budget.allocateArrayLength(spreadValues.length);
28998
+ return {
28999
+ ok: true,
29000
+ value: spreadValues
29001
+ };
29002
+ } finally {
29003
+ release();
28925
29004
  }
28926
- return {
28927
- ok: true,
28928
- value: spreadValues
28929
- };
28930
29005
  }
28931
29006
  async function evaluateObjectSpread(node, context) {
28932
29007
  const value = await evaluateNode(node.argument, context);
@@ -31301,41 +31376,6 @@ function createBuiltinBindings(options) {
31301
31376
  };
31302
31377
  }
31303
31378
 
31304
- // packages/safe-js/src/interp/resources.ts
31305
- import { AsyncLocalStorage as AsyncLocalStorage5 } from "node:async_hooks";
31306
- var runResources = new AsyncLocalStorage5();
31307
- async function withRunResources(signal, execute) {
31308
- const controller = new AbortController();
31309
- const cancel = () => controller.abort(signal?.reason);
31310
- const cleanups = /* @__PURE__ */ new Set();
31311
- const resources = {
31312
- signal: controller.signal,
31313
- add(close) {
31314
- cleanups.add(close);
31315
- }
31316
- };
31317
- signal?.addEventListener("abort", cancel, { once: true });
31318
- if (signal?.aborted) cancel();
31319
- let result;
31320
- let failure;
31321
- let errors = [];
31322
- try {
31323
- result = await runResources.run(resources, execute);
31324
- } catch (error) {
31325
- failure = { reason: error };
31326
- } finally {
31327
- signal?.removeEventListener("abort", cancel);
31328
- controller.abort(new Error("SafeJS run finished."));
31329
- const outcomes = await Promise.allSettled(
31330
- [...cleanups].map((close) => Promise.resolve().then(close))
31331
- );
31332
- errors = outcomes.flatMap((outcome) => outcome.status === "rejected" ? [outcome.reason] : []);
31333
- }
31334
- if (failure !== void 0) throw failure.reason;
31335
- if (errors.length > 0) throw new AggregateError(errors, "SafeJS resource cleanup failed.");
31336
- return result;
31337
- }
31338
-
31339
31379
  // packages/safe-js/src/modules/registry.ts
31340
31380
  function createUnknownModuleMessage2(moduleName, moduleNames) {
31341
31381
  if (moduleNames.length === 0) {
@@ -31577,6 +31617,7 @@ var RealmState = class {
31577
31617
  extensions;
31578
31618
  consoleExtension;
31579
31619
  cleanups = [];
31620
+ referenceReleases = /* @__PURE__ */ new Set();
31580
31621
  callbacks = /* @__PURE__ */ new Map();
31581
31622
  pendingCallbacks = /* @__PURE__ */ new Set();
31582
31623
  callbackCache = /* @__PURE__ */ new WeakMap();
@@ -31903,7 +31944,7 @@ var RealmState = class {
31903
31944
  const pending = withSandboxPromiseRejectionTracker(
31904
31945
  this.tracker,
31905
31946
  () => runResources.run(
31906
- { signal: this.controller.signal, add: this.onCleanup },
31947
+ { signal: this.controller.signal, referenceReleases: this.referenceReleases, add: this.onCleanup },
31907
31948
  () => withCancellationSignal(
31908
31949
  this.controller.signal,
31909
31950
  () => active && this.phase.getStore()?.active ? runAsyncPrefix(invoke) : this.queue.run(invoke)
@@ -32098,7 +32139,7 @@ var RealmState = class {
32098
32139
  () => withSandboxPromiseRejectionTracker(
32099
32140
  this.tracker,
32100
32141
  () => runResources.run(
32101
- { signal: this.controller.signal, add: this.onCleanup },
32142
+ { signal: this.controller.signal, referenceReleases: this.referenceReleases, add: this.onCleanup },
32102
32143
  () => withCancellationSignal(this.controller.signal, task)
32103
32144
  )
32104
32145
  )
@@ -32155,6 +32196,8 @@ var RealmState = class {
32155
32196
  this.hostObjects.clear();
32156
32197
  for (const reference of this.guestReferences.keys()) revokeGuestReference(reference, this);
32157
32198
  this.guestReferences.clear();
32199
+ for (const release of this.referenceReleases) release();
32200
+ this.referenceReleases.clear();
32158
32201
  this.budget.setRetainedValues(this, void 0);
32159
32202
  releaseObjectPrototype(this.budget);
32160
32203
  this.disposal = (async () => {
@@ -33408,9 +33451,9 @@ export {
33408
33451
  validateSnapshotMigration,
33409
33452
  restore,
33410
33453
  lint,
33454
+ runResources,
33411
33455
  declareHostOperation,
33412
33456
  createSeededRandom,
33413
- runResources,
33414
33457
  createReplayableRandom,
33415
33458
  createRealm,
33416
33459
  dump,
@@ -33420,4 +33463,4 @@ export {
33420
33463
  FileSnapshotBackend,
33421
33464
  run
33422
33465
  };
33423
- //# sourceMappingURL=chunk-N3CN2ACZ.js.map
33466
+ //# sourceMappingURL=chunk-D4YY44EF.js.map