@poe-platform/safe-js 0.1.391 → 0.1.392

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.
@@ -647,6 +647,64 @@ function* hoistedVarDeclarations(nodes) {
647
647
  }
648
648
  }
649
649
 
650
+ // packages/safe-js/src/parse/private-names.ts
651
+ function validatePrivateNames(root) {
652
+ const pending = [{ value: root }];
653
+ while (pending.length > 0) {
654
+ const { value, scope, declaration } = pending.pop();
655
+ if (value === null || typeof value !== "object") continue;
656
+ if (Array.isArray(value)) {
657
+ for (const entry of value) pending.push({ value: entry, scope });
658
+ continue;
659
+ }
660
+ const node = value;
661
+ if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
662
+ const klass = value;
663
+ pending.push({ value: klass.superClass, scope });
664
+ const inner = { names: /* @__PURE__ */ new Set(), parent: scope };
665
+ const declarations = /* @__PURE__ */ new Map();
666
+ for (const element of klass.body.body) {
667
+ if (element.type === "StaticBlock" || element.key.type !== "PrivateIdentifier") continue;
668
+ const name = element.key.name;
669
+ if (name === "constructor") throw new Error("Private name #constructor is forbidden.");
670
+ const kind = element.type === "MethodDefinition" ? element.kind : "field";
671
+ const previous = declarations.get(name);
672
+ if (previous !== void 0 && !(previous.static === element.static && (previous.kind === "get" && kind === "set" || previous.kind === "set" && kind === "get")))
673
+ throw new Error(`Duplicate private name #${name}.`);
674
+ declarations.set(name, { kind: previous === void 0 ? kind : "pair", static: element.static });
675
+ inner.names.add(name);
676
+ }
677
+ pending.push({ value: klass.body, scope: inner });
678
+ continue;
679
+ }
680
+ if (node.type === "PrivateIdentifier") {
681
+ if (declaration) continue;
682
+ let owner = scope;
683
+ while (owner !== void 0 && !owner.names.has(String(node.name))) owner = owner.parent;
684
+ if (owner === void 0) throw new Error(`Undeclared private name #${String(node.name)}.`);
685
+ continue;
686
+ }
687
+ if (node.type === "MemberExpression") {
688
+ const property = node.property;
689
+ if (property.type === "PrivateIdentifier" && node.object.type === "Super")
690
+ throw new Error("super cannot access a private name.");
691
+ }
692
+ if (node.type === "UnaryExpression" && node.operator === "delete") {
693
+ const argument = node.argument;
694
+ if (argument.type === "MemberExpression" && argument.property.type === "PrivateIdentifier")
695
+ throw new Error("Private elements cannot be deleted.");
696
+ }
697
+ for (const [key, child] of Object.entries(node)) {
698
+ if (key === "span") continue;
699
+ pending.push({
700
+ value: child,
701
+ scope,
702
+ declaration: key === "key" && (node.type === "MethodDefinition" || node.type === "PropertyDefinition")
703
+ });
704
+ }
705
+ }
706
+ }
707
+
650
708
  // packages/safe-js/src/interp/regex/compile-guard.ts
651
709
  var compiledData = /* @__PURE__ */ new WeakMap();
652
710
  var CompileScope = class {
@@ -962,6 +1020,11 @@ var Lexer = class {
962
1020
  if (char === "*" && this.peekChar(1) === "/") {
963
1021
  this.syntaxError("Unexpected block comment terminator", start);
964
1022
  }
1023
+ if (char === "#") {
1024
+ this.advance();
1025
+ this.readIdentifierOrKeyword(start, true);
1026
+ continue;
1027
+ }
965
1028
  if (isIdentifierStart(codePointChar) || this.startsUnicodeEscape()) {
966
1029
  this.readIdentifierOrKeyword(start);
967
1030
  continue;
@@ -1018,7 +1081,7 @@ var Lexer = class {
1018
1081
  break;
1019
1082
  }
1020
1083
  }
1021
- readIdentifierOrKeyword(start) {
1084
+ readIdentifierOrKeyword(start, privateName = false) {
1022
1085
  let value = "";
1023
1086
  let isStart = true;
1024
1087
  while (!this.isAtEnd()) {
@@ -1042,7 +1105,8 @@ var Lexer = class {
1042
1105
  value += char;
1043
1106
  isStart = false;
1044
1107
  }
1045
- this.pushToken(KEYWORDS.has(value) ? "keyword" : "identifier", start, value);
1108
+ if (privateName && isStart) this.syntaxError("Expected private identifier", start);
1109
+ this.pushToken(privateName ? "private-identifier" : KEYWORDS.has(value) ? "keyword" : "identifier", start, value);
1046
1110
  }
1047
1111
  readString(start, quote) {
1048
1112
  this.advance();
@@ -1732,7 +1796,7 @@ function shouldRejectRegexLiteral(previousToken, lastClosedControlParenthesis, t
1732
1796
  if (previousToken === void 0) {
1733
1797
  return true;
1734
1798
  }
1735
- if (previousToken.type === "identifier" || previousToken.type === "numeric" || previousToken.type === "string" || previousToken.type === "template") {
1799
+ if (previousToken.type === "identifier" || previousToken.type === "private-identifier" || previousToken.type === "numeric" || previousToken.type === "string" || previousToken.type === "template") {
1736
1800
  return false;
1737
1801
  }
1738
1802
  if (previousToken.type === "keyword") {
@@ -2917,6 +2981,7 @@ function parse(source, filename = "<input>", owner) {
2917
2981
  );
2918
2982
  }
2919
2983
  throwIfImportMetaAssignment(result);
2984
+ if (source.includes("#")) validatePrivateNames(result);
2920
2985
  return result;
2921
2986
  } catch (error) {
2922
2987
  if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
@@ -2933,13 +2998,15 @@ function parse(source, filename = "<input>", owner) {
2933
2998
  function parseModule(source, filename = "<input>", owner) {
2934
2999
  const compilation = new CompileScope(owner);
2935
3000
  try {
2936
- return assignIds(
3001
+ const result = assignIds(
2937
3002
  new Parser(
2938
3003
  tokenize(source, { allowRegexLiterals: true, compilation }),
2939
3004
  source,
2940
3005
  compilation
2941
3006
  ).parseModule()
2942
3007
  );
3008
+ if (source.includes("#")) validatePrivateNames(result);
3009
+ return result;
2943
3010
  } catch (error) {
2944
3011
  if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
2945
3012
  throw error;
@@ -2963,6 +3030,7 @@ function parseExecutableModule(source, filename = "<input>", owner) {
2963
3030
  ).parseModule()
2964
3031
  );
2965
3032
  throwIfImportMetaAssignment(result);
3033
+ if (source.includes("#")) validatePrivateNames(result);
2966
3034
  return result;
2967
3035
  } catch (error) {
2968
3036
  if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
@@ -3889,7 +3957,7 @@ var Parser = class {
3889
3957
  parseClassElement(derived) {
3890
3958
  const start = this.currentToken();
3891
3959
  let isStatic = false;
3892
- if (start.value === "static" && !["(", "=", ";", "}"].includes(this.peekToken(1).value)) {
3960
+ if (start.type !== "private-identifier" && start.value === "static" && !["(", "=", ";", "}"].includes(this.peekToken(1).value)) {
3893
3961
  this.index++;
3894
3962
  isStatic = true;
3895
3963
  if (this.currentToken().value === "{") {
@@ -3907,21 +3975,21 @@ var Parser = class {
3907
3975
  }
3908
3976
  const methodStart = this.currentToken();
3909
3977
  let async = false;
3910
- if (methodStart.value === "async" && !hasLineBreakBetween(methodStart, this.peekToken(1)) && (this.peekToken(1).value === "*" || this.isObjectMethodStart())) {
3978
+ if (methodStart.type !== "private-identifier" && methodStart.value === "async" && !hasLineBreakBetween(methodStart, this.peekToken(1)) && (this.peekToken(1).value === "*" || this.isObjectMethodStart())) {
3911
3979
  this.index++;
3912
3980
  async = true;
3913
3981
  }
3914
3982
  const generator = this.consumePunctuator("*") !== void 0;
3915
3983
  let accessor;
3916
3984
  const modifier = this.currentToken();
3917
- if ((modifier.value === "get" || modifier.value === "set") && this.isObjectMethodStart()) {
3985
+ if (modifier.type !== "private-identifier" && (modifier.value === "get" || modifier.value === "set") && this.isObjectMethodStart()) {
3918
3986
  if (async || generator || modifier.end.offset - modifier.start.offset !== modifier.value.length)
3919
3987
  throw unexpectedTokenError(modifier);
3920
3988
  accessor = modifier.value;
3921
3989
  this.index++;
3922
3990
  }
3923
3991
  const computed = this.consumePunctuator("[") !== void 0;
3924
- const key = computed ? this.parseExpression({ allowSequence: true }).node : this.currentToken().type === "string" ? createStringLiteral(this.tokens[this.index++]) : this.currentToken().type === "numeric" ? createNumericLiteral(this.tokens[this.index++]) : this.parseIdentifierName();
3992
+ const key = computed ? this.parseExpression({ allowSequence: true }).node : this.currentToken().type === "string" ? createStringLiteral(this.tokens[this.index++]) : this.currentToken().type === "numeric" ? createNumericLiteral(this.tokens[this.index++]) : this.currentToken().type === "private-identifier" ? this.parsePrivateIdentifier() : this.parseIdentifierName();
3925
3993
  if (computed) this.expectPunctuator("]");
3926
3994
  const name = computed ? void 0 : key.type === "Identifier" ? key.name : key.type === "StringLiteral" || key.type === "NumericLiteral" ? String(key.value) : void 0;
3927
3995
  if (isStatic && name === "prototype") throw new Error("A static class element cannot be named prototype.");
@@ -4518,6 +4586,22 @@ var Parser = class {
4518
4586
  return this.parseBinaryExpression(() => this.parseRelationalExpression(), EQUALITY_OPERATORS);
4519
4587
  }
4520
4588
  parseRelationalExpression() {
4589
+ if (this.currentToken().type === "private-identifier") {
4590
+ const left = this.parsePrivateIdentifier();
4591
+ this.expectKeyword("in");
4592
+ const right = this.parseShiftExpression();
4593
+ return this.parseBinaryExpression(
4594
+ () => this.parseShiftExpression(),
4595
+ RELATIONAL_OPERATORS,
4596
+ { node: {
4597
+ type: "BinaryExpression",
4598
+ operator: "in",
4599
+ left,
4600
+ right: right.node,
4601
+ span: createSpan2(left.span.start, right.node.span.end)
4602
+ }, parenthesized: false }
4603
+ );
4604
+ }
4521
4605
  return this.parseBinaryExpression(() => this.parseShiftExpression(), RELATIONAL_OPERATORS);
4522
4606
  }
4523
4607
  parseShiftExpression() {
@@ -4683,7 +4767,7 @@ var Parser = class {
4683
4767
  };
4684
4768
  continue;
4685
4769
  }
4686
- const property = this.parseIdentifierName();
4770
+ const property = this.currentToken().type === "private-identifier" ? this.parsePrivateIdentifier() : this.parseIdentifierName();
4687
4771
  expression = {
4688
4772
  node: {
4689
4773
  type: "MemberExpression",
@@ -4698,7 +4782,7 @@ var Parser = class {
4698
4782
  continue;
4699
4783
  }
4700
4784
  if (this.consumePunctuator(".") !== void 0) {
4701
- const property = this.parseIdentifierName();
4785
+ const property = this.currentToken().type === "private-identifier" ? this.parsePrivateIdentifier() : this.parseIdentifierName();
4702
4786
  expression = {
4703
4787
  node: {
4704
4788
  type: "MemberExpression",
@@ -4904,7 +4988,7 @@ var Parser = class {
4904
4988
  let callee = this.parsePrimaryExpression();
4905
4989
  while (true) {
4906
4990
  if (this.consumePunctuator(".") !== void 0) {
4907
- const property = this.parseIdentifierName();
4991
+ const property = this.currentToken().type === "private-identifier" ? this.parsePrivateIdentifier() : this.parseIdentifierName();
4908
4992
  callee = {
4909
4993
  node: {
4910
4994
  type: "MemberExpression",
@@ -5201,7 +5285,7 @@ var Parser = class {
5201
5285
  offset += 1;
5202
5286
  }
5203
5287
  }
5204
- return (propertyToken.type === "identifier" || propertyToken.type === "keyword" || propertyToken.type === "numeric" || propertyToken.type === "string") && this.peekToken(2).type === "punctuator" && this.peekToken(2).value === "(";
5288
+ return (propertyToken.type === "identifier" || propertyToken.type === "private-identifier" || propertyToken.type === "keyword" || propertyToken.type === "numeric" || propertyToken.type === "string") && this.peekToken(2).type === "punctuator" && this.peekToken(2).value === "(";
5205
5289
  }
5206
5290
  parseObjectMethod(asyncToken, methodStart, accessor, generatorToken) {
5207
5291
  const { params, body } = this.parseFunctionParts(generatorToken !== void 0, {
@@ -5228,6 +5312,12 @@ var Parser = class {
5228
5312
  this.index += 1;
5229
5313
  return createIdentifierName(token);
5230
5314
  }
5315
+ parsePrivateIdentifier() {
5316
+ const token = this.currentToken();
5317
+ if (token.type !== "private-identifier") throw unexpectedTokenError(token);
5318
+ this.index++;
5319
+ return { type: "PrivateIdentifier", name: token.value, span: createSpan2(token.start, token.end) };
5320
+ }
5231
5321
  parseArguments() {
5232
5322
  const args = [];
5233
5323
  const emptyEnd = this.consumePunctuator(")");
@@ -5288,8 +5378,8 @@ var Parser = class {
5288
5378
  }
5289
5379
  return left;
5290
5380
  }
5291
- parseBinaryExpression(parseOperand, operators) {
5292
- let left = parseOperand();
5381
+ parseBinaryExpression(parseOperand, operators, initial) {
5382
+ let left = initial ?? parseOperand();
5293
5383
  while (true) {
5294
5384
  const token = this.currentToken();
5295
5385
  if (!operators.has(token.value)) {
@@ -8552,6 +8642,23 @@ var iteratorWrapperStates = /* @__PURE__ */ new WeakMap();
8552
8642
  // packages/safe-js/src/interp/iterator-helper.ts
8553
8643
  var iteratorHelperStates = /* @__PURE__ */ new WeakMap();
8554
8644
 
8645
+ // packages/safe-js/src/interp/private-state.ts
8646
+ var privateElements = /* @__PURE__ */ new WeakMap();
8647
+ function findPrivateElement(receiver, name) {
8648
+ if (receiver === null || typeof receiver !== "object") throw new TypeError("Private elements require an object receiver.");
8649
+ return privateElements.get(receiver)?.get(name);
8650
+ }
8651
+ function addPrivateElement(receiver, name, element) {
8652
+ if (receiver === null || typeof receiver !== "object") throw new TypeError("Private elements require an object receiver.");
8653
+ let slots = privateElements.get(receiver);
8654
+ if (slots === void 0) {
8655
+ slots = /* @__PURE__ */ new Map();
8656
+ privateElements.set(receiver, slots);
8657
+ }
8658
+ if (slots.has(name)) throw new TypeError(`Private element #${name.description} is already installed.`);
8659
+ slots.set(name, element);
8660
+ }
8661
+
8555
8662
  // packages/safe-js/src/interp/raw-json.ts
8556
8663
  var rawJsonValues = /* @__PURE__ */ new WeakSet();
8557
8664
  function createRawJson(text) {
@@ -10366,7 +10473,7 @@ async function bindArrayPattern(pattern, value, target, scope, context) {
10366
10473
  target,
10367
10474
  scope,
10368
10475
  elementContext,
10369
- Object.hasOwn(saved, "referenceObject") ? { object: saved.referenceObject, key: saved.referenceKey } : void 0
10476
+ Object.hasOwn(saved, "referenceObject") ? { object: saved.referenceObject, key: saved.referenceKey, privateName: saved.privateName } : void 0
10370
10477
  ) : await bindPatternValue(
10371
10478
  element,
10372
10479
  async () => {
@@ -10389,6 +10496,7 @@ async function bindArrayPattern(pattern, value, target, scope, context) {
10389
10496
  if (reference !== void 0) {
10390
10497
  state.referenceObject = reference.object;
10391
10498
  state.referenceKey = reference.key;
10499
+ if (reference.privateName !== void 0) state.privateName = reference.privateName;
10392
10500
  }
10393
10501
  }
10394
10502
  );
@@ -10453,7 +10561,7 @@ async function bindObjectPattern(pattern, value, target, scope, context) {
10453
10561
  target,
10454
10562
  scope,
10455
10563
  propertyContext,
10456
- Object.hasOwn(state, "referenceObject") ? { object: state.referenceObject, key: state.referenceKey } : void 0
10564
+ Object.hasOwn(state, "referenceObject") ? { object: state.referenceObject, key: state.referenceKey, privateName: state.privateName } : void 0
10457
10565
  ) : await bindPatternValue(
10458
10566
  element,
10459
10567
  async () => ({ value: property.type === "RestElement" ? await copyObjectRestValue(value, excludedKeys, propertyContext) : await propertyContext.getProperty(value, currentState.key) }),
@@ -10466,6 +10574,7 @@ async function bindObjectPattern(pattern, value, target, scope, context) {
10466
10574
  if (reference !== void 0) {
10467
10575
  currentState.referenceObject = reference.object;
10468
10576
  currentState.referenceKey = reference.key;
10577
+ if (reference.privateName !== void 0) currentState.privateName = reference.privateName;
10469
10578
  }
10470
10579
  }
10471
10580
  );
@@ -10488,7 +10597,10 @@ async function bindMemberExpression(pattern, value, context, reference) {
10488
10597
  if (!isIndexableValue(reference.object)) {
10489
10598
  throw new TypeError("Assignment expressions require a sandbox object property.");
10490
10599
  }
10491
- await context.setProperty(reference.object, reference.key, value);
10600
+ if (reference.privateName !== void 0) {
10601
+ if (context.setPrivateProperty === void 0) throw new TypeError("Private assignment context is unavailable.");
10602
+ await context.setPrivateProperty(reference.object, reference.privateName, value);
10603
+ } else await context.setProperty(reference.object, reference.key, value);
10492
10604
  return { ok: true };
10493
10605
  }
10494
10606
  async function prepareMemberReference(pattern, context) {
@@ -15618,7 +15730,11 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
15618
15730
  throw new TypeError("Class extends value has an invalid prototype.");
15619
15731
  }
15620
15732
  const derived = node.superClass !== void 0;
15733
+ for (const element of node.body.body)
15734
+ if (element.type !== "StaticBlock" && element.key.type === "PrivateIdentifier") scope.declarePrivateName(element.key.name);
15621
15735
  constructor = createClassConstructor(node, { ...classContext, inferredName: context.inferredName }, evaluateNode2, fields2);
15736
+ const instancePrivate = classOrigins.get(constructor).privateMethods;
15737
+ const staticPrivate = /* @__PURE__ */ new Map();
15622
15738
  const properties = materializeFunctionProperties(constructor);
15623
15739
  const prototype = properties.prototype;
15624
15740
  Object.defineProperty(properties, "prototype", { writable: false });
@@ -15633,16 +15749,17 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
15633
15749
  }
15634
15750
  if (element.type === "MethodDefinition" && element.kind === "constructor") continue;
15635
15751
  let key;
15752
+ const privateName = element.key.type === "PrivateIdentifier" ? scope.resolvePrivateName(element.key.name) : void 0;
15636
15753
  if (element.computed) {
15637
15754
  const result = await evaluateNode2(element.key, classContext);
15638
15755
  if (result.kind !== "normal") return result;
15639
15756
  key = await pattern.toPropertyKey(result.value);
15640
15757
  } else {
15641
- key = element.key.type === "Identifier" ? element.key.name : String(element.key.value);
15758
+ key = privateName !== void 0 ? `#${privateName.description}` : element.key.type === "Identifier" ? element.key.name : String(element.key.value);
15642
15759
  }
15643
15760
  if (typeof key === "string") context.budget.allocateString(key);
15644
15761
  if (element.type === "PropertyDefinition") {
15645
- (element.static ? statics : fields2).push({ element, key });
15762
+ (element.static ? statics : fields2).push({ element, key, ...privateName === void 0 ? {} : { privateName } });
15646
15763
  } else {
15647
15764
  const home = element.static ? constructor : prototype;
15648
15765
  const method = createInterpretedClosure(element.value, classContext, evaluateNode2, home);
@@ -15650,6 +15767,20 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
15650
15767
  Object.defineProperty(materializeFunctionProperties(method), "name", {
15651
15768
  value: accessor === void 0 ? propertyFunctionName(key) : `${accessor} ${propertyFunctionName(key)}`
15652
15769
  });
15770
+ if (privateName !== void 0) {
15771
+ const entries = element.static ? staticPrivate : instancePrivate;
15772
+ if (accessor === void 0) entries.set(privateName, { kind: "method", value: method });
15773
+ else {
15774
+ let entry = entries.get(privateName);
15775
+ if (entry === void 0) {
15776
+ entry = { kind: "accessor" };
15777
+ entries.set(privateName, entry);
15778
+ }
15779
+ if (entry.kind !== "accessor") throw new TypeError("Invalid private accessor declaration.");
15780
+ entry[accessor] = method;
15781
+ }
15782
+ continue;
15783
+ }
15653
15784
  Object.defineProperty(
15654
15785
  element.static ? properties : prototype,
15655
15786
  key,
@@ -15658,6 +15789,7 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
15658
15789
  }
15659
15790
  }
15660
15791
  if (node.id !== void 0) scope.declare(node.id.name, "const", constructor);
15792
+ for (const [name, element] of staticPrivate) addPrivateElement(constructor, name, element);
15661
15793
  for (const element of statics) await initializeElement(element, constructor, constructor, classContext, evaluateNode2);
15662
15794
  classOrigins.get(constructor).initialized = true;
15663
15795
  if (node.type === "ClassDeclaration") {
@@ -15681,7 +15813,15 @@ function createClassConstructor(node, context, evaluateNode2, fields2) {
15681
15813
  name: node.id?.name ?? context.inferredName ?? "",
15682
15814
  length: constructorElement === void 0 ? 0 : getFunctionLength(constructorElement.value.params),
15683
15815
  sourceRange: functionSources.get(node),
15684
- retainedValues: () => [...scope.retainedValues(), ...fields2.map((field) => field.key)],
15816
+ retainedValues: () => {
15817
+ const values = [...scope.retainedValues(), ...fields2.flatMap((field) => field.privateName === void 0 ? [field.key] : [field.key, field.privateName])];
15818
+ for (const [name, element] of classOrigins.get(constructor)?.privateMethods ?? []) {
15819
+ values.push(name);
15820
+ if (element.kind === "accessor") values.push(element.get, element.set);
15821
+ else values.push(element.value);
15822
+ }
15823
+ return values;
15824
+ },
15685
15825
  call: () => {
15686
15826
  throw new TypeError("Class constructor cannot be invoked without 'new'.");
15687
15827
  },
@@ -15692,6 +15832,7 @@ function createClassConstructor(node, context, evaluateNode2, fields2) {
15692
15832
  let thisScope;
15693
15833
  let initialized = !derived;
15694
15834
  const initializeFields = async (receiver) => {
15835
+ for (const [name, element] of classOrigins.get(constructor).privateMethods) addPrivateElement(receiver, name, element);
15695
15836
  for (const field of fields2) {
15696
15837
  await initializeElement(field, receiver, prototype, classContext, evaluateNode2);
15697
15838
  }
@@ -15742,7 +15883,7 @@ function createClassConstructor(node, context, evaluateNode2, fields2) {
15742
15883
  return thisValue;
15743
15884
  }
15744
15885
  });
15745
- classOrigins.set(constructor, { node, scope, fields: fields2, initialized: false });
15886
+ classOrigins.set(constructor, { node, scope, fields: fields2, initialized: false, privateMethods: /* @__PURE__ */ new Map() });
15746
15887
  return constructor;
15747
15888
  }
15748
15889
  async function initializeElement(definition, receiver, homeObject, context, evaluateNode2) {
@@ -15759,7 +15900,8 @@ async function initializeElement(definition, receiver, homeObject, context, eval
15759
15900
  value = result.hasValue ? result.value : void 0;
15760
15901
  }
15761
15902
  if ("key" in definition) {
15762
- await defineDataProperty(receiver, definition.key, { value, configurable: true, writable: true, enumerable: true }, context.budget, createCoercionContext(context));
15903
+ if (definition.privateName !== void 0) addPrivateElement(receiver, definition.privateName, { kind: "field", value });
15904
+ else await defineDataProperty(receiver, definition.key, { value, configurable: true, writable: true, enumerable: true }, context.budget, createCoercionContext(context));
15763
15905
  }
15764
15906
  }
15765
15907
 
@@ -16433,6 +16575,7 @@ var Scope = class _Scope {
16433
16575
  parent;
16434
16576
  importMeta;
16435
16577
  options;
16578
+ privateNames;
16436
16579
  #bindings = /* @__PURE__ */ new Map();
16437
16580
  #restoredBindings;
16438
16581
  #frameHydrated = false;
@@ -16442,6 +16585,25 @@ var Scope = class _Scope {
16442
16585
  ...options
16443
16586
  });
16444
16587
  }
16588
+ declarePrivateName(description) {
16589
+ const names = this.privateNames ??= /* @__PURE__ */ new Map();
16590
+ const existing = names.get(description);
16591
+ if (existing !== void 0) return existing;
16592
+ const name = { description };
16593
+ names.set(description, name);
16594
+ return name;
16595
+ }
16596
+ resolvePrivateName(description) {
16597
+ const ownName = this.privateNames?.get(description);
16598
+ if (ownName !== void 0) return ownName;
16599
+ let scope = this.parent;
16600
+ while (scope !== void 0) {
16601
+ const name = scope.privateNames?.get(description);
16602
+ if (name !== void 0) return name;
16603
+ scope = scope.parent;
16604
+ }
16605
+ throw new SyntaxError(`Undeclared private name #${description}.`);
16606
+ }
16445
16607
  consumeRestoredBinding(name) {
16446
16608
  if (!this.#restoredBindings.has(name)) {
16447
16609
  return { found: false };
@@ -16483,6 +16645,7 @@ var Scope = class _Scope {
16483
16645
  const values = this.parent?.retainedValues() ?? [];
16484
16646
  if (this.options.chargeData !== false) {
16485
16647
  if (this.importMeta !== void 0) values.push(this.importMeta);
16648
+ if (this.privateNames !== void 0) values.push(...this.privateNames.values());
16486
16649
  for (const binding of this.#bindings.values()) {
16487
16650
  if (binding.value !== uninitialized) values.push(binding.value);
16488
16651
  }
@@ -16610,6 +16773,7 @@ var Scope = class _Scope {
16610
16773
  chargeData: this.options.chargeData !== false,
16611
16774
  bindings,
16612
16775
  cells,
16776
+ ...this.privateNames === void 0 ? {} : { privateNames: [...this.privateNames] },
16613
16777
  ...this.parent === void 0 ? { restoredBindings: [...this.#restoredBindings] } : {}
16614
16778
  };
16615
16779
  }
@@ -16636,6 +16800,7 @@ var Scope = class _Scope {
16636
16800
  const restored = new Map(frame.restoredBindings ?? []);
16637
16801
  if (restored.size !== (frame.restoredBindings?.length ?? 0)) throw new TypeError("Duplicate restored binding.");
16638
16802
  this.importMeta = frame.importMeta;
16803
+ if (frame.privateNames !== void 0) this.privateNames = new Map(frame.privateNames);
16639
16804
  for (const [name, binding] of bindings) this.#bindings.set(name, binding);
16640
16805
  if (this.parent === void 0)
16641
16806
  for (const [name, value] of restored) this.#restoredBindings.set(name, value);
@@ -17179,6 +17344,7 @@ async function evaluateTaggedTemplateExpression(node, context) {
17179
17344
  }
17180
17345
  if (node.tag.type === "MemberExpression") return evaluateMemberAccess(node.tag, context, async (member) => {
17181
17346
  if (member.kind === "nullish") throw new TypeError("Tagged template tag must be a function.");
17347
+ if (member.privateName !== void 0) return invokeTag(await readPrivateValue(member.object, member.privateName, context), member.object);
17182
17348
  const key = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
17183
17349
  const receiver = member.superReceiver === void 0 ? member.object : member.superReceiver.value;
17184
17350
  return invokeTag(await getPropertyValue(member.object, key, context, receiver), receiver);
@@ -17211,6 +17377,12 @@ async function evaluateAwait(node, context) {
17211
17377
  return evaluateAwaitExpression(node, context, evaluateNode);
17212
17378
  }
17213
17379
  async function evaluateBinaryExpression(node, context) {
17380
+ if (node.left.type === "PrivateIdentifier" && node.operator === "in") {
17381
+ const name = context.scope.resolvePrivateName(node.left.name);
17382
+ const right = await evaluateNode(node.right, context);
17383
+ if (right.kind !== "normal") return right;
17384
+ return { kind: "normal", hasValue: true, value: findPrivateElement(right.value, name) !== void 0 };
17385
+ }
17214
17386
  const restored = context.generatorResume === void 0 || node.nodeId === void 0 ? void 0 : context.restoredGeneratorExpressionStates?.get(node.nodeId);
17215
17387
  if (restored !== void 0 && restored.kind !== "binary") throw new TypeError("Invalid binary expression continuation.");
17216
17388
  const left = restored?.kind === "binary" ? { kind: "normal", hasValue: true, value: restored.left } : await evaluateNode(node.left, context);
@@ -17358,12 +17530,12 @@ async function evaluateMemberAssignmentExpression(node, context) {
17358
17530
  if (member.object === null || member.object === void 0) {
17359
17531
  throw new TypeError("Cannot assign properties of null or undefined.");
17360
17532
  }
17361
- property = await toPropertyKey(
17533
+ property = member.privateName === void 0 ? await toPropertyKey(
17362
17534
  member.property,
17363
17535
  context.budget,
17364
17536
  createCoercionContext(context)
17365
- );
17366
- current = await getPropertyValue(
17537
+ ) : void 0;
17538
+ current = member.privateName !== void 0 ? await readPrivateValue(member.object, member.privateName, context) : await getPropertyValue(
17367
17539
  member.object,
17368
17540
  property,
17369
17541
  context,
@@ -17397,6 +17569,7 @@ async function evaluateMemberAssignmentExpression(node, context) {
17397
17569
  object: member.object,
17398
17570
  property: member.property,
17399
17571
  current,
17572
+ ...member.privateName === void 0 ? {} : { privateName: member.privateName.description },
17400
17573
  ...property === void 0 ? {} : { key: property },
17401
17574
  ...member.superReceiver === void 0 ? {} : { superReceiver: member.superReceiver.value }
17402
17575
  };
@@ -17415,12 +17588,13 @@ async function evaluateMemberAssignmentExpression(node, context) {
17415
17588
  throw new TypeError("Cannot assign properties of null or undefined.");
17416
17589
  }
17417
17590
  operands = [value, member.object, member.property, member.superReceiver?.value];
17418
- property ??= await toPropertyKey(
17591
+ if (member.privateName === void 0) property ??= await toPropertyKey(
17419
17592
  member.property,
17420
17593
  context.budget,
17421
17594
  createCoercionContext(context)
17422
17595
  );
17423
- if (member.superReceiver === void 0)
17596
+ if (member.privateName !== void 0) await writePrivateValue(member.object, member.privateName, value, context);
17597
+ else if (member.superReceiver === void 0)
17424
17598
  await setSandboxProperty(
17425
17599
  member.object,
17426
17600
  property,
@@ -17444,6 +17618,7 @@ async function evaluateMemberAssignmentExpression(node, context) {
17444
17618
  kind: "resolved",
17445
17619
  object: restored.object,
17446
17620
  property: restored.property,
17621
+ ...restored.privateName === void 0 ? {} : { privateName: context.scope.resolvePrivateName(restored.privateName) },
17447
17622
  ...Object.hasOwn(restored, "superReceiver") ? { superReceiver: { value: restored.superReceiver } } : {}
17448
17623
  });
17449
17624
  return evaluateMemberAccess(node.left, context, assign);
@@ -18650,11 +18825,12 @@ async function evaluateMemberUpdateExpression(node, context) {
18650
18825
  if (member.kind === "nullish" || member.object === null || member.object === void 0) {
18651
18826
  throw new TypeError("Cannot update properties of null or undefined.");
18652
18827
  }
18653
- const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
18654
- const primitive = await toNumericPrimitive(await getPropertyValue(member.object, property, context, member.superReceiver === void 0 ? member.object : member.superReceiver.value), context);
18828
+ const property = member.privateName === void 0 ? await toPropertyKey(member.property, context.budget, createCoercionContext(context)) : void 0;
18829
+ const primitive = await toNumericPrimitive(member.privateName !== void 0 ? await readPrivateValue(member.object, member.privateName, context) : await getPropertyValue(member.object, property, context, member.superReceiver === void 0 ? member.object : member.superReceiver.value), context);
18655
18830
  const current = typeof primitive === "bigint" ? primitive : toNumber(primitive);
18656
18831
  const next = typeof current === "bigint" ? bigIntOperation(node.operator === "++" ? "+" : "-", current, 1n, context.budget) : node.operator === "++" ? current + 1 : current - 1;
18657
- if (member.superReceiver === void 0) await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
18832
+ if (member.privateName !== void 0) await writePrivateValue(member.object, member.privateName, next, context);
18833
+ else if (member.superReceiver === void 0) await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
18658
18834
  else await setSuperProperty(member.object, member.superReceiver.value, property, next, context);
18659
18835
  return {
18660
18836
  kind: "normal",
@@ -18672,7 +18848,7 @@ async function evaluateMemberExpression(node, context) {
18672
18848
  return {
18673
18849
  kind: "normal",
18674
18850
  hasValue: true,
18675
- value: await getPropertyValue(
18851
+ value: member.privateName !== void 0 ? await readPrivateValue(member.object, member.privateName, context) : await getPropertyValue(
18676
18852
  member.object,
18677
18853
  await toPropertyKey(member.property, context.budget, createCoercionContext(context)),
18678
18854
  context,
@@ -18681,6 +18857,23 @@ async function evaluateMemberExpression(node, context) {
18681
18857
  };
18682
18858
  });
18683
18859
  }
18860
+ async function readPrivateValue(receiver, name, context) {
18861
+ const element = findPrivateElement(receiver, name);
18862
+ if (element === void 0) throw new TypeError(`Receiver does not declare #${name.description}.`);
18863
+ if (element.kind !== "accessor") return element.value;
18864
+ if (element.get === void 0) throw new TypeError(`Private accessor #${name.description} has no getter.`);
18865
+ return invokeBuiltinClosure(element.get, [], context.budget, createCoercionContext(context), receiver);
18866
+ }
18867
+ async function writePrivateValue(receiver, name, value, context) {
18868
+ const element = findPrivateElement(receiver, name);
18869
+ if (element === void 0) throw new TypeError(`Receiver does not declare #${name.description}.`);
18870
+ if (element.kind === "field") {
18871
+ element.value = value;
18872
+ return;
18873
+ }
18874
+ if (element.kind === "method" || element.set === void 0) throw new TypeError(`Private element #${name.description} is not writable.`);
18875
+ await invokeBuiltinClosure(element.set, [value], context.budget, createCoercionContext(context), receiver);
18876
+ }
18684
18877
  function getPropertyValue(target, property, context, receiver = target) {
18685
18878
  if (isGuestHostObject(target)) return typeof property === "symbol" ? void 0 : getHostObjectMember(target, String(property));
18686
18879
  const descriptor = getSandboxPropertyDescriptor(target, property, context.budget);
@@ -18727,13 +18920,14 @@ function createPatternContext(context, scope = context.scope, evaluate = evaluat
18727
18920
  let reference;
18728
18921
  const result = await evaluateMemberAccess(pattern, evaluationContext, async (member) => {
18729
18922
  if (member.kind === "nullish") throw new TypeError("Cannot assign properties of null or undefined.");
18730
- reference = { object: member.object, key: await toPropertyKey(member.property, context.budget, createCoercionContext(evaluationContext)) };
18923
+ reference = member.privateName === void 0 ? { object: member.object, key: await toPropertyKey(member.property, context.budget, createCoercionContext(evaluationContext)) } : { object: member.object, key: member.privateName.description, privateName: member.privateName.description };
18731
18924
  return normalEmptyResult();
18732
18925
  });
18733
18926
  return result.kind === "normal" ? { ok: true, reference } : { ok: false, result };
18734
18927
  },
18735
18928
  budget: context.budget,
18736
18929
  callContext: createCoercionContext(evaluationContext),
18930
+ setPrivateProperty: (receiver, name, value) => writePrivateValue(receiver, scope.resolvePrivateName(name), value, evaluationContext),
18737
18931
  evaluate: (node, inferredName) => evaluate(node, { ...evaluationContext, inferredName }),
18738
18932
  toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
18739
18933
  getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
@@ -18851,6 +19045,13 @@ async function evaluateMemberAccess(node, context, consume) {
18851
19045
  if ((object.value === null || object.value === void 0) && node.optional) {
18852
19046
  return consume({ kind: "nullish" });
18853
19047
  }
19048
+ if (node.property.type === "PrivateIdentifier")
19049
+ return consume({
19050
+ kind: "resolved",
19051
+ object: object.value,
19052
+ property: void 0,
19053
+ privateName: context.scope.resolvePrivateName(node.property.name)
19054
+ });
18854
19055
  let property;
18855
19056
  if (node.computed && context.generatorYield !== void 0 && node.nodeId !== void 0) {
18856
19057
  const state = {
@@ -18922,6 +19123,8 @@ async function evaluateMemberCallExpression(node, context) {
18922
19123
  }
18923
19124
  throw new TypeError("Cannot read properties of null or undefined.");
18924
19125
  }
19126
+ if (reference.privateName !== void 0)
19127
+ return evaluateResolvedCallExpression(node, await readPrivateValue(reference.object, reference.privateName, context), context, reference.object);
18925
19128
  const member = {
18926
19129
  ...reference,
18927
19130
  property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
@@ -22036,6 +22239,11 @@ function serializeCollectionProperties(value, encode, dataOnly = false) {
22036
22239
 
22037
22240
  // packages/safe-js/src/snapshot/guest-heap.ts
22038
22241
  function captureGuestHeapNode(value, encode) {
22242
+ if (hasGuestObjectState(value) || privateElements.has(value)) {
22243
+ if (isSandboxRegex(value)) return { kind: "guest-regex", source: value.source, flags: value.flags, state: captureObjectState(value, encode) };
22244
+ if (isSandboxBox(value)) return { kind: "guest-boxed", value: encode(boxedValue(value)), state: captureObjectState(value, encode) };
22245
+ if (isSandboxDate(value)) return { kind: "guest-date", value: encode(dateTime(value)), state: captureObjectState(value, encode) };
22246
+ }
22039
22247
  const helper = iteratorHelperStates.get(value);
22040
22248
  if (helper !== void 0) {
22041
22249
  if (helper.status === "executing") throw new TypeError("Cannot snapshot an executing iterator helper.");
@@ -22101,8 +22309,18 @@ function captureGuestHeapNode(value, encode) {
22101
22309
  state: captureObjectState(value, encode)
22102
22310
  };
22103
22311
  }
22104
- if (isSandboxMap(value)) return { kind: "map", entries: [...value.entries].map(([key, entry]) => [encode(key), encode(entry)]), ...serializeCollectionProperties(value, encode) };
22105
- if (isSandboxSet(value)) return { kind: "set", values: [...value.values].map(encode), ...serializeCollectionProperties(value, encode) };
22312
+ if (isSandboxMap(value)) return {
22313
+ kind: "map",
22314
+ entries: [...value.entries].map(([key, entry]) => [encode(key), encode(entry)]),
22315
+ ...serializeCollectionProperties(value, encode),
22316
+ ...privateElements.has(value) ? { privateElements: capturePrivateElements(privateElements.get(value), encode) } : {}
22317
+ };
22318
+ if (isSandboxSet(value)) return {
22319
+ kind: "set",
22320
+ values: [...value.values].map(encode),
22321
+ ...serializeCollectionProperties(value, encode),
22322
+ ...privateElements.has(value) ? { privateElements: capturePrivateElements(privateElements.get(value), encode) } : {}
22323
+ };
22106
22324
  if (isSandboxArrayIterator(value)) {
22107
22325
  const cursor = arrayIteratorState(value);
22108
22326
  return {
@@ -22122,7 +22340,12 @@ function captureGuestHeapNode(value, encode) {
22122
22340
  astNodeId: classOrigin.node.nodeId,
22123
22341
  scope: encode(classOrigin.scope),
22124
22342
  ...isSandboxClosure(value) && value.name !== void 0 ? { name: value.name } : {},
22125
- fields: classOrigin.fields.map((field) => ({ index: classOrigin.node.body.body.indexOf(field.element), key: encode(field.key) })),
22343
+ fields: classOrigin.fields.map((field) => ({
22344
+ index: classOrigin.node.body.body.indexOf(field.element),
22345
+ key: encode(field.key),
22346
+ ...field.privateName === void 0 ? {} : { privateName: encode(field.privateName) }
22347
+ })),
22348
+ ...classOrigin.privateMethods.size === 0 ? {} : { privateMethods: capturePrivateElements(classOrigin.privateMethods, encode) },
22126
22349
  state: captureObjectState(value, encode)
22127
22350
  };
22128
22351
  }
@@ -22135,6 +22358,7 @@ function captureGuestHeapNode(value, encode) {
22135
22358
  functionBoundary: frame.functionBoundary,
22136
22359
  chargeData: frame.chargeData,
22137
22360
  bindings: frame.bindings,
22361
+ ...frame.privateNames === void 0 ? {} : { privateNames: frame.privateNames.map(([name, identity]) => [name, encode(identity)]) },
22138
22362
  cells: frame.cells.map((cell) => cell.initialized ? { ...cell, value: encode(cell.value) } : cell),
22139
22363
  ...frame.restoredBindings === void 0 ? {} : {
22140
22364
  restoredBindings: frame.restoredBindings.map(([name, entry]) => [name, encode(entry)])
@@ -22182,6 +22406,7 @@ function captureGuestHeapNode(value, encode) {
22182
22406
  kind: "object-pattern",
22183
22407
  phase: expression.phase,
22184
22408
  index: expression.index,
22409
+ ...expression.privateName === void 0 ? {} : { privateName: expression.privateName },
22185
22410
  excludedKeys: expression.excludedKeys.map(encode),
22186
22411
  key: encode(expression.key),
22187
22412
  current: encode(expression.current),
@@ -22192,6 +22417,7 @@ function captureGuestHeapNode(value, encode) {
22192
22417
  index: expression.index,
22193
22418
  done: expression.done,
22194
22419
  current: encode(expression.current),
22420
+ ...expression.privateName === void 0 ? {} : { privateName: expression.privateName },
22195
22421
  iterator: mapIteratorSnapshot("kind" in expression.iterator ? expression.iterator : expression.iterator.snapshot?.() ?? { kind: "unsupported" }, encode),
22196
22422
  ...Object.hasOwn(expression, "referenceObject") ? { referenceObject: encode(expression.referenceObject), referenceKey: encode(expression.referenceKey) } : {}
22197
22423
  } : expression.kind === "for-of-array" ? { ...expression, values: encode(expression.values), current: encode(expression.current), scope: encode(expression.scope) } : expression.kind === "for-of-iterator" ? {
@@ -22205,6 +22431,7 @@ function captureGuestHeapNode(value, encode) {
22205
22431
  object: encode(expression.object),
22206
22432
  property: encode(expression.property),
22207
22433
  current: encode(expression.current),
22434
+ ...expression.privateName === void 0 ? {} : { privateName: expression.privateName },
22208
22435
  ...Object.hasOwn(expression, "key") ? { key: encode(expression.key) } : {},
22209
22436
  ...Object.hasOwn(expression, "superReceiver") ? { superReceiver: encode(expression.superReceiver) } : {}
22210
22437
  } : expression.kind === "member" ? {
@@ -22273,6 +22500,7 @@ function captureGuestHeapNode(value, encode) {
22273
22500
  }
22274
22501
  function captureObjectState(value, encode) {
22275
22502
  let properties = value;
22503
+ if (isSandboxRegex(value)) properties = getRegexProperties(value);
22276
22504
  if (isSandboxGenerator(value)) properties = getGeneratorProperties(value);
22277
22505
  if (isSandboxClosure(value)) {
22278
22506
  properties = value.properties;
@@ -22281,9 +22509,13 @@ function captureObjectState(value, encode) {
22281
22509
  if (properties === void 0) return void 0;
22282
22510
  return {
22283
22511
  properties: serializePropertyDescriptors(properties, encode),
22512
+ ...privateElements.has(value) ? { privateElements: capturePrivateElements(privateElements.get(value), encode) } : {},
22284
22513
  ...hasExplicitSandboxPrototype(value) ? { prototype: encode(getSandboxPrototype(value)) } : {}
22285
22514
  };
22286
22515
  }
22516
+ function capturePrivateElements(elements, encode) {
22517
+ return [...elements].map(([name, element]) => element.kind === "accessor" ? { name: encode(name), kind: "accessor", get: encode(element.get), set: encode(element.set) } : { name: encode(name), kind: element.kind, value: encode(element.value) });
22518
+ }
22287
22519
 
22288
22520
  // packages/safe-js/src/snapshot/arguments.ts
22289
22521
  function serializeArguments(value, serializeValue) {
@@ -22353,6 +22585,7 @@ function captureTypedArrayState(value, encode) {
22353
22585
  if (!Object.isExtensible(value)) Object.preventExtensions(metadata);
22354
22586
  return {
22355
22587
  properties: serializePropertyDescriptors(metadata, encode),
22588
+ ...privateElements.has(value) ? { privateElements: capturePrivateElements(privateElements.get(value), encode) } : {},
22356
22589
  ...hasExplicitSandboxPrototype(value) ? { prototype: encode(getSandboxPrototype(value)) } : {}
22357
22590
  };
22358
22591
  }
@@ -22422,6 +22655,7 @@ function encodeDataViewLayout(value) {
22422
22655
  function captureDataViewState(value, encode) {
22423
22656
  return {
22424
22657
  properties: serializePropertyDescriptors(value, encode),
22658
+ ...privateElements.has(value) ? { privateElements: capturePrivateElements(privateElements.get(value), encode) } : {},
22425
22659
  ...hasExplicitSandboxPrototype(value) ? { prototype: encode(getSandboxPrototype(value)) } : {}
22426
22660
  };
22427
22661
  }
@@ -22446,6 +22680,7 @@ function decodeDataViewStorage(value, resolve, budget) {
22446
22680
  function captureArrayBufferState(value, encode) {
22447
22681
  return {
22448
22682
  properties: serializePropertyDescriptors(value, encode),
22683
+ ...privateElements.has(value) ? { privateElements: capturePrivateElements(privateElements.get(value), encode) } : {},
22449
22684
  ...hasExplicitSandboxPrototype(value) ? { prototype: encode(getSandboxPrototype(value)) } : {}
22450
22685
  };
22451
22686
  }
@@ -27446,7 +27681,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27446
27681
  createRawJson(node.text);
27447
27682
  return true;
27448
27683
  }
27449
- if (!["intrinsic", "bound-function", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "array-iterator", "string-iterator", "iterator-wrapper", "iterator-helper", "guest-collection-iterator", "guest-regexp-iterator", "map", "set"].includes(String(node.kind))) return false;
27684
+ if (!["intrinsic", "bound-function", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "guest-boxed", "guest-date", "guest-regex", "array-iterator", "string-iterator", "iterator-wrapper", "iterator-helper", "guest-collection-iterator", "guest-regexp-iterator", "map", "set"].includes(String(node.kind))) return false;
27450
27685
  const reference = (value, kinds) => {
27451
27686
  const ref = record3(value);
27452
27687
  fields(ref, ["kind", "id"]);
@@ -27461,9 +27696,35 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27461
27696
  if (target.kind === "intrinsic" && intrinsicCatalogue().get(String(target.id)) !== true)
27462
27697
  throw new TypeError("Guest accessor reference is not callable.");
27463
27698
  };
27699
+ const privateIdentity = (value, expected) => {
27700
+ const identity = reference(value, ["object"]);
27701
+ fields(identity, ["kind", "entries"]);
27702
+ const entries = record3(identity.entries);
27703
+ fields(entries, ["description"]);
27704
+ if (typeof entries.description !== "string" || entries.description.length === 0 || expected !== void 0 && entries.description !== expected) throw new TypeError("Invalid private-name identity.");
27705
+ };
27706
+ const privateState = (value, methodsOnly = false) => {
27707
+ const names = /* @__PURE__ */ new Set();
27708
+ for (const raw2 of array(value)) {
27709
+ const element = record3(raw2);
27710
+ fields(element, element.kind === "accessor" ? ["name", "kind", "get", "set"] : ["name", "kind", "value"]);
27711
+ privateIdentity(element.name);
27712
+ const id = integer(record3(element.name).id);
27713
+ if (names.has(id)) throw new TypeError("Duplicate private element.");
27714
+ names.add(id);
27715
+ if (element.kind === "accessor") {
27716
+ callable(element.get);
27717
+ callable(element.set);
27718
+ } else if (element.kind === "method") {
27719
+ if (absent(element.value)) throw new TypeError("Missing private method.");
27720
+ callable(element.value);
27721
+ } else if (element.kind !== "field" || methodsOnly) throw new TypeError("Invalid private element kind.");
27722
+ }
27723
+ };
27464
27724
  const state = (value) => {
27465
27725
  const object = record3(value);
27466
- fields(object, ["properties"], ["prototype"]);
27726
+ fields(object, ["properties"], ["prototype", "privateElements"]);
27727
+ if (object.privateElements !== void 0) privateState(object.privateElements);
27467
27728
  if (Object.hasOwn(object, "prototype") && object.prototype !== null) reference(object.prototype);
27468
27729
  const properties = record3(object.properties);
27469
27730
  fields(properties, ["properties", "extensible"]);
@@ -27493,14 +27754,29 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27493
27754
  }
27494
27755
  };
27495
27756
  if (node.kind === "map" || node.kind === "set") {
27496
- fields(node, ["kind", node.kind === "map" ? "entries" : "values"], ["propertyState", "prototype"]);
27757
+ fields(node, ["kind", node.kind === "map" ? "entries" : "values"], ["propertyState", "prototype", "privateElements"]);
27758
+ if (node.privateElements !== void 0) privateState(node.privateElements);
27497
27759
  state({
27498
27760
  properties: Object.hasOwn(node, "propertyState") ? node.propertyState : { properties: [], extensible: true },
27499
27761
  ...Object.hasOwn(node, "prototype") ? { prototype: node.prototype } : {}
27500
27762
  });
27501
27763
  return false;
27502
27764
  }
27503
- if (node.kind === "iterator-helper") {
27765
+ if (node.kind === "guest-regex") {
27766
+ fields(node, ["kind", "source", "flags", "state"]);
27767
+ if (typeof node.source !== "string" || typeof node.flags !== "string") throw new TypeError("Invalid guest RegExp payload.");
27768
+ state(node.state);
27769
+ } else if (node.kind === "guest-boxed" || node.kind === "guest-date") {
27770
+ fields(node, ["kind", "value", "state"]);
27771
+ if (node.kind === "guest-date") {
27772
+ if (typeof node.value !== "number" && record3(node.value).kind !== "number") throw new TypeError("Invalid guest date time.");
27773
+ } else if (!["number", "string", "boolean"].includes(typeof node.value)) {
27774
+ const payload = record3(node.value);
27775
+ if (payload.kind === "ref") reference(node.value, ["symbol"]);
27776
+ else if (payload.kind !== "number" && payload.kind !== "bigint") throw new TypeError("Invalid guest boxed payload.");
27777
+ }
27778
+ state(node.state);
27779
+ } else if (node.kind === "iterator-helper") {
27504
27780
  fields(node, ["kind", "method", "status", "callback", "remaining", "index", "state"], ["outer", "inner"]);
27505
27781
  if (!["map", "filter", "take", "drop", "flatMap"].includes(String(node.method)) || !["start", "yield", "done"].includes(String(node.status))) throw new TypeError("Invalid iterator helper mode.");
27506
27782
  integer(node.index);
@@ -27592,14 +27868,19 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27592
27868
  }
27593
27869
  }
27594
27870
  } else if (node.kind === "guest-class") {
27595
- fields(node, ["kind", "astNodeId", "scope", "state", "fields"], ["name"]);
27871
+ fields(node, ["kind", "astNodeId", "scope", "state", "fields"], ["name", "privateMethods"]);
27872
+ if (node.privateMethods !== void 0) privateState(node.privateMethods, true);
27596
27873
  if (integer(node.astNodeId) < 1) throw new TypeError("Invalid class AST identity.");
27597
27874
  reference(node.scope, ["scope-frame"]);
27598
27875
  if (Object.hasOwn(node, "name") && typeof node.name !== "string") throw new TypeError("Invalid class name.");
27599
27876
  let previous = -1;
27600
27877
  for (const item of array(node.fields)) {
27601
27878
  const field = record3(item);
27602
- fields(field, ["index", "key"]);
27879
+ fields(field, ["index", "key"], ["privateName"]);
27880
+ if (field.privateName !== void 0) {
27881
+ if (typeof field.key !== "string" || !field.key.startsWith("#")) throw new TypeError("Invalid private field key.");
27882
+ privateIdentity(field.privateName, field.key.slice(1));
27883
+ }
27603
27884
  const index = integer(field.index);
27604
27885
  if (index <= previous) throw new TypeError("Invalid class field order.");
27605
27886
  previous = index;
@@ -27666,7 +27947,8 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27666
27947
  } else if (expression.kind === "pattern-source") {
27667
27948
  fields(expression, ["kind", "value"]);
27668
27949
  } else if (expression.kind === "object-pattern") {
27669
- fields(expression, ["kind", "phase", "index", "excludedKeys", "key", "current"], ["referenceObject", "referenceKey"]);
27950
+ fields(expression, ["kind", "phase", "index", "excludedKeys", "key", "current"], ["referenceObject", "referenceKey", "privateName"]);
27951
+ if (expression.privateName !== void 0 && (typeof expression.privateName !== "string" || !Object.hasOwn(expression, "referenceObject"))) throw new TypeError("Invalid private pattern reference.");
27670
27952
  integer(expression.index);
27671
27953
  if (!["key", "reference", "binding"].includes(String(expression.phase)) || Object.hasOwn(expression, "referenceObject") !== Object.hasOwn(expression, "referenceKey")) throw new TypeError("Invalid object pattern state.");
27672
27954
  for (const key of array(expression.excludedKeys)) if (typeof key !== "string") reference(key, ["symbol"]);
@@ -27678,7 +27960,8 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27678
27960
  fields(expression, ["kind", "async", "value", "current", "iterator"]);
27679
27961
  if (typeof expression.async !== "boolean") throw new TypeError("Invalid delegated yield protocol.");
27680
27962
  } else if (expression.kind === "array-pattern") {
27681
- fields(expression, ["kind", "phase", "index", "done", "current", "iterator"], ["referenceObject", "referenceKey"]);
27963
+ fields(expression, ["kind", "phase", "index", "done", "current", "iterator"], ["referenceObject", "referenceKey", "privateName"]);
27964
+ if (expression.privateName !== void 0 && (typeof expression.privateName !== "string" || !Object.hasOwn(expression, "referenceObject"))) throw new TypeError("Invalid private pattern reference.");
27682
27965
  if (!["reference", "binding"].includes(String(expression.phase)) || typeof expression.done !== "boolean" || Object.hasOwn(expression, "referenceObject") !== Object.hasOwn(expression, "referenceKey")) throw new TypeError("Invalid array pattern state.");
27683
27966
  if (Object.hasOwn(expression, "referenceKey") && typeof expression.referenceKey !== "string") reference(expression.referenceKey, ["symbol"]);
27684
27967
  } else {
@@ -27751,7 +28034,8 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27751
28034
  } else if (expression.kind === "identifier-assignment") {
27752
28035
  fields(expression, ["kind", "current"]);
27753
28036
  } else if (expression.kind === "member-assignment") {
27754
- fields(expression, ["kind", "object", "property", "current"], ["key", "superReceiver"]);
28037
+ fields(expression, ["kind", "object", "property", "current"], ["key", "superReceiver", "privateName"]);
28038
+ if (expression.privateName !== void 0 && (typeof expression.privateName !== "string" || Object.hasOwn(expression, "key") || Object.hasOwn(expression, "superReceiver"))) throw new TypeError("Invalid private assignment reference.");
27755
28039
  if (Object.hasOwn(expression, "key") && typeof expression.key !== "string") reference(expression.key, ["symbol"]);
27756
28040
  } else if (expression.kind === "member") {
27757
28041
  fields(expression, ["kind", "object"], ["superReceiver"]);
@@ -27806,7 +28090,16 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
27806
28090
  if (Object.hasOwn(environment, "newTarget")) callable(environment.newTarget);
27807
28091
  }
27808
28092
  } else {
27809
- fields(node, ["kind", "parent", "importMeta", "functionBoundary", "chargeData", "bindings", "cells"], ["restoredBindings"]);
28093
+ fields(node, ["kind", "parent", "importMeta", "functionBoundary", "chargeData", "bindings", "cells"], ["restoredBindings", "privateNames"]);
28094
+ if (node.privateNames !== void 0) {
28095
+ const names2 = /* @__PURE__ */ new Set();
28096
+ for (const raw2 of array(node.privateNames)) {
28097
+ const entry = array(raw2);
28098
+ if (entry.length !== 2 || typeof entry[0] !== "string" || names2.has(entry[0])) throw new TypeError("Invalid private-name scope.");
28099
+ names2.add(entry[0]);
28100
+ privateIdentity(entry[1], entry[0]);
28101
+ }
28102
+ }
27810
28103
  if (!absent(node.parent)) reference(node.parent, ["scope-frame"]);
27811
28104
  if (typeof node.functionBoundary !== "boolean" || typeof node.chargeData !== "boolean") throw new TypeError("Invalid guest frame flags.");
27812
28105
  const cells = array(node.cells);
@@ -27855,6 +28148,15 @@ function validateGuestScopeParents(heap) {
27855
28148
  }
27856
28149
 
27857
28150
  // packages/safe-js/src/snapshot/guest-ast-validation.ts
28151
+ function privateAssignmentName(value) {
28152
+ if (value === null || typeof value !== "object") return void 0;
28153
+ let node = value;
28154
+ while (node.type === "AssignmentPattern" || node.type === "RestElement")
28155
+ node = node.type === "AssignmentPattern" ? node.left : node.argument;
28156
+ if (node.type !== "MemberExpression") return void 0;
28157
+ const property = node.property;
28158
+ return property.type === "PrivateIdentifier" ? String(property.name) : void 0;
28159
+ }
27858
28160
  function validateGuestFunctionAst(record4, origin) {
27859
28161
  if (record4.kind === "guest-class") {
27860
28162
  if (origin === null || typeof origin !== "object" || !["ClassDeclaration", "ClassExpression"].includes(String(origin.type)))
@@ -27866,8 +28168,9 @@ function validateGuestFunctionAst(record4, origin) {
27866
28168
  expected.forEach(({ element, index }, position) => {
27867
28169
  const field = fields2[position];
27868
28170
  if (field.index !== index) throw new TypeError("Invalid class field AST identity.");
28171
+ if (element.key.type === "PrivateIdentifier" !== (field.privateName !== void 0)) throw new TypeError("Invalid private field identity.");
27869
28172
  if (!element.computed) {
27870
- const key = element.key.type === "Identifier" ? element.key.name : String(element.key.value);
28173
+ const key = element.key.type === "PrivateIdentifier" ? `#${element.key.name}` : element.key.type === "Identifier" ? element.key.name : String(element.key.value);
27871
28174
  if (field.key !== key) throw new TypeError("Invalid class field key.");
27872
28175
  }
27873
28176
  });
@@ -27944,7 +28247,12 @@ function validateGuestFunctionAst(record4, origin) {
27944
28247
  value: property[part],
27945
28248
  blocks,
27946
28249
  finalizers: frame.finalizers,
27947
- expressions: new Map([...frame.expressions, [id, { kind: "object-pattern", index, key: part === "key" }]])
28250
+ expressions: new Map([...frame.expressions, [id, {
28251
+ kind: "object-pattern",
28252
+ index,
28253
+ key: part === "key",
28254
+ privateName: part === "key" ? void 0 : privateAssignmentName(property[part])
28255
+ }]])
27948
28256
  });
27949
28257
  }
27950
28258
  });
@@ -27980,6 +28288,7 @@ function validateGuestFunctionAst(record4, origin) {
27980
28288
  expressions: new Map([...frame.expressions, [node.nodeId, {
27981
28289
  kind,
27982
28290
  index,
28291
+ ...kind === "array-pattern" ? { privateName: privateAssignmentName(element) } : {},
27983
28292
  member: kind === "call" && node.callee?.type === "MemberExpression"
27984
28293
  }]])
27985
28294
  }));
@@ -27990,7 +28299,8 @@ function validateGuestFunctionAst(record4, origin) {
27990
28299
  blocks,
27991
28300
  expressions: (node.type === "VariableDeclarator" && key === "id" && node.init !== void 0 || (node.type === "AssignmentExpression" || node.type === "AssignmentPattern") && key === "left") && typeof node.nodeId === "number" && ["ArrayPattern", "ObjectPattern"].includes(String(value?.type)) ? new Map([...frame.expressions, [node.nodeId, { kind: "pattern-source" }]]) : node.type === "ForOfStatement" && ["left", "body"].includes(key) && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "for-of", phase: key, async: node.await === true }]]) : node.type === "ForInStatement" && ["left", "body"].includes(key) && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "for-in", phase: key }]]) : node.type === "ForStatement" && ["init", "test", "body", "update"].includes(key) && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "for", phase: key }]]) : node.type === "BinaryExpression" && key === "right" && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "binary" }]]) : node.type === "AssignmentExpression" && key === "right" && typeof node.nodeId === "number" && node.left.type === "Identifier" ? new Map([...frame.expressions, [node.nodeId, { kind: "identifier-assignment" }]]) : node.type === "AssignmentExpression" && key === "right" && typeof node.nodeId === "number" && node.left.type === "MemberExpression" ? new Map([...frame.expressions, [node.nodeId, {
27992
28301
  kind: "member-assignment",
27993
- key: node.operator !== "=",
28302
+ key: node.operator !== "=" && node.left.property.type !== "PrivateIdentifier",
28303
+ privateName: node.left.property.type === "PrivateIdentifier" ? String(node.left.property.name) : void 0,
27994
28304
  superReceiver: node.left.object.type === "Super"
27995
28305
  }]]) : node.type === "MemberExpression" && node.computed === true && key === "property" && typeof node.nodeId === "number" ? new Map([...frame.expressions, [node.nodeId, { kind: "member", superReceiver: node.object.type === "Super" }]]) : frame.expressions,
27996
28306
  finalizers: node.type === "TryStatement" && key === "finalizer" && typeof node.nodeId === "number" ? /* @__PURE__ */ new Set([...frame.finalizers, node.nodeId]) : frame.finalizers
@@ -28018,7 +28328,7 @@ function validateGuestFunctionAst(record4, origin) {
28018
28328
  for (const [id, expression] of expressions) {
28019
28329
  const expected = yieldExpressions?.get(Number(id));
28020
28330
  const compatibleKind = expected?.kind === expression.kind || expected?.kind === "for-of" && (expression.kind === "for-of-iterator" || !expected.async && expression.kind === "for-of-array") || expected?.kind === "call" && expected.member === true && expression.kind === "array-call";
28021
- if (expected === void 0 || !compatibleKind || expected.kind !== "binary" && expected.kind !== "yield-delegate" && expected.kind !== "pattern-source" && expected.kind !== "identifier-assignment" && expected.kind !== "member" && expected.kind !== "member-assignment" && expected.kind !== "for" && expected.kind !== "for-in" && expected.kind !== "for-of" && expected.index !== expression.index || expected.kind === "yield-delegate" && expected.async !== expression.async || expected.kind === "switch" && (expected.phase !== expression.phase || expected.statementIndex !== expression.statementIndex) || (expected.kind === "for" || expected.kind === "for-of") && expected.phase !== expression.phase || expected.kind === "for-in" && expected.phase !== (expression.phase ?? "body") || expected.kind === "object-pattern" && expected.key !== (expression.phase === "key") || expected.kind === "for-of" && expression.kind === "for-of-iterator" && expected.async !== expression.async || expected.kind === "member-assignment" && (expected.key !== Object.hasOwn(expression, "key") || expected.superReceiver !== Object.hasOwn(expression, "superReceiver")) || expected.kind === "member" && expected.superReceiver !== Object.hasOwn(expression, "superReceiver") || expected.kind === "object" && expected.key !== Object.hasOwn(expression, "key"))
28331
+ if (expected === void 0 || !compatibleKind || expected.kind !== "binary" && expected.kind !== "yield-delegate" && expected.kind !== "pattern-source" && expected.kind !== "identifier-assignment" && expected.kind !== "member" && expected.kind !== "member-assignment" && expected.kind !== "for" && expected.kind !== "for-in" && expected.kind !== "for-of" && expected.index !== expression.index || expected.kind === "yield-delegate" && expected.async !== expression.async || expected.kind === "switch" && (expected.phase !== expression.phase || expected.statementIndex !== expression.statementIndex) || (expected.kind === "for" || expected.kind === "for-of") && expected.phase !== expression.phase || expected.kind === "for-in" && expected.phase !== (expression.phase ?? "body") || expected.kind === "object-pattern" && expected.key !== (expression.phase === "key") || (expected.kind === "object-pattern" || expected.kind === "array-pattern") && (expression.phase === "binding" ? expected.privateName : void 0) !== expression.privateName || expected.kind === "for-of" && expression.kind === "for-of-iterator" && expected.async !== expression.async || expected.kind === "member-assignment" && (expected.key !== Object.hasOwn(expression, "key") || expected.privateName !== expression.privateName || expected.superReceiver !== Object.hasOwn(expression, "superReceiver")) || expected.kind === "member" && expected.superReceiver !== Object.hasOwn(expression, "superReceiver") || expected.kind === "object" && expected.key !== Object.hasOwn(expression, "key"))
28022
28332
  throw new TypeError("Invalid generator AST identity: unrelated expression continuation");
28023
28333
  }
28024
28334
  }
@@ -29471,6 +29781,16 @@ function measureSandboxData(values, options = {}) {
29471
29781
  assertSandboxDataDepth(depth);
29472
29782
  seen.add(value);
29473
29783
  usage += 1;
29784
+ const privateSlots = privateElements.get(value);
29785
+ if (privateSlots !== void 0) {
29786
+ for (const [name, element] of privateSlots) {
29787
+ visit(name, depth + 1);
29788
+ if (element.kind === "accessor") {
29789
+ visit(element.get, depth + 1);
29790
+ visit(element.set, depth + 1);
29791
+ } else visit(element.value, depth + 1);
29792
+ }
29793
+ }
29474
29794
  if (!isGuestHostObject(value)) {
29475
29795
  const symbols = Object.getOwnPropertySymbols(value);
29476
29796
  const descriptors2 = symbols.length === 0 ? [] : symbols.filter((key) => !internalSymbols.has(key)).map((key) => [key, Object.getOwnPropertyDescriptor(value, key)]);
@@ -35640,6 +35960,8 @@ function variableDeclarationContainsAwait(node) {
35640
35960
  }
35641
35961
  function expressionContainsAwait(node) {
35642
35962
  switch (node.type) {
35963
+ case "PrivateIdentifier":
35964
+ return false;
35643
35965
  case "ClassExpression":
35644
35966
  return classDefinitionContains(node, expressionContainsAwait);
35645
35967
  case "NewTargetExpression":
@@ -39325,6 +39647,8 @@ function variableDeclarationContainsAwait2(node) {
39325
39647
  }
39326
39648
  function expressionContainsAwait2(node) {
39327
39649
  switch (node.type) {
39650
+ case "PrivateIdentifier":
39651
+ return false;
39328
39652
  case "ClassExpression":
39329
39653
  return classDefinitionContains(node, expressionContainsAwait2);
39330
39654
  case "NewTargetExpression":
@@ -44607,11 +44931,11 @@ export {
44607
44931
  safeEndSpan,
44608
44932
  runResources,
44609
44933
  defineExtension,
44934
+ assertSnapshotInactive,
44610
44935
  encodeReplayData,
44611
44936
  HostOperationResumePolicyError,
44612
44937
  registerPendingHostCallPolicy,
44613
44938
  HostCallResumabilityError,
44614
- assertSnapshotInactive,
44615
44939
  isSandboxClosure,
44616
44940
  deepCopyToSandbox,
44617
44941
  deepCopyFromSandbox,
@@ -44638,4 +44962,4 @@ export {
44638
44962
  FileSnapshotBackend,
44639
44963
  run
44640
44964
  };
44641
- //# sourceMappingURL=chunk-MT4D4J5E.js.map
44965
+ //# sourceMappingURL=chunk-GYLSKXNZ.js.map