poe-code 14.0.60 → 14.0.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/index.js +313 -135
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-js/dist/chunks/{chunk-C7UCTQDN.js → chunk-F7TJSPDZ.js} +7 -3
  6. package/packages/safe-js/dist/chunks/chunk-F7TJSPDZ.js.map +7 -0
  7. package/packages/safe-js/dist/chunks/{chunk-MKJBQPBH.js → chunk-VKGWGZBH.js} +268 -126
  8. package/packages/safe-js/dist/chunks/chunk-VKGWGZBH.js.map +7 -0
  9. package/packages/safe-js/dist/cli.js +2 -2
  10. package/packages/safe-js/dist/core.js +1 -1
  11. package/packages/safe-js/dist/index.js +2 -2
  12. package/packages/safe-js/dist/interp/async.js +3 -0
  13. package/packages/safe-js/dist/interp/function-string.d.ts +2 -0
  14. package/packages/safe-js/dist/interp/function-string.js +21 -0
  15. package/packages/safe-js/dist/interp/globals/misc.js +11 -12
  16. package/packages/safe-js/dist/interp/globals/numeric-parsers.d.ts +5 -0
  17. package/packages/safe-js/dist/interp/globals/numeric-parsers.js +47 -0
  18. package/packages/safe-js/dist/interp/globals/object-array.js +2 -10
  19. package/packages/safe-js/dist/interp/interpreter.js +9 -14
  20. package/packages/safe-js/dist/interp/methods/function.d.ts +2 -0
  21. package/packages/safe-js/dist/interp/methods/function.js +10 -1
  22. package/packages/safe-js/dist/interp/methods/string.js +18 -0
  23. package/packages/safe-js/dist/interp/resources.d.ts +3 -0
  24. package/packages/safe-js/dist/interp/resources.js +11 -0
  25. package/packages/safe-js/dist/interp/string-coercion.js +16 -4
  26. package/packages/safe-js/dist/interp/values.d.ts +3 -0
  27. package/packages/safe-js/dist/interp/values.js +3 -0
  28. package/packages/safe-js/dist/migrate.js +1 -1
  29. package/packages/safe-js/dist/parse/function-source.d.ts +7 -0
  30. package/packages/safe-js/dist/parse/function-source.js +1 -0
  31. package/packages/safe-js/dist/parse/hash.d.ts +2 -2
  32. package/packages/safe-js/dist/parse/hash.js +23 -9
  33. package/packages/safe-js/dist/parse/parser.js +36 -23
  34. package/packages/safe-js/dist/restore.js +2 -1
  35. package/packages/safe-js/dist/run.js +16 -5
  36. package/packages/safe-js/dist/snapshot/dump-format.d.ts +1 -1
  37. package/packages/safe-js/dist/snapshot/dump-format.js +1 -1
  38. package/packages/safe-js/dist/snapshot/migration.js +2 -2
  39. package/packages/safe-js/dist/snapshot/restore.js +2 -0
  40. package/packages/safe-js/dist/chunks/chunk-C7UCTQDN.js.map +0 -7
  41. package/packages/safe-js/dist/chunks/chunk-MKJBQPBH.js.map +0 -7
@@ -1,6 +1,7 @@
1
1
  import { boundIdentifiers } from "./bindings.js";
2
2
  import { tokenize } from "./tokenizer.js";
3
3
  import { assignIds } from "./assign-ids.js";
4
+ import { functionSources } from "./function-source.js";
4
5
  import { formatParseError } from "./format-error.js";
5
6
  import { createExportDefaultDeclaration, createExportNamedDeclaration } from "./parse-export.js";
6
7
  import { createImportMeta, isImportMetaTokenSequence } from "./parse-import-meta.js";
@@ -42,7 +43,7 @@ const TOP_LEVEL_STATEMENT_KEYWORDS = new Set([
42
43
  export function parse(source, filename = "<input>", owner) {
43
44
  const compilation = new CompileScope(owner);
44
45
  try {
45
- const result = assignIds(parseTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation));
46
+ const result = assignIds(new Parser(tokenize(source, { allowRegexLiterals: true, compilation }), source, compilation).parseTopLevel());
46
47
  const regexLiteral = findRegexLiteral(result);
47
48
  if (regexLiteral !== undefined) {
48
49
  throw new Error(`Regular expression literals are not supported at line ${regexLiteral.span.start.line}, column ${regexLiteral.span.start.column}.`);
@@ -66,7 +67,7 @@ export function parse(source, filename = "<input>", owner) {
66
67
  export function parseModule(source, filename = "<input>", owner) {
67
68
  const compilation = new CompileScope(owner);
68
69
  try {
69
- return assignIds(parseModuleTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation));
70
+ return assignIds(new Parser(tokenize(source, { allowRegexLiterals: true, compilation }), source, compilation).parseModule());
70
71
  }
71
72
  catch (error) {
72
73
  if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
@@ -84,7 +85,7 @@ export function parseModule(source, filename = "<input>", owner) {
84
85
  export function parseExecutableModule(source, filename = "<input>", owner) {
85
86
  const compilation = new CompileScope(owner);
86
87
  try {
87
- const result = assignIds(parseModuleTokens(tokenize(source, { allowRegexLiterals: true, compilation }), compilation));
88
+ const result = assignIds(new Parser(tokenize(source, { allowRegexLiterals: true, compilation }), source, compilation).parseModule());
88
89
  throwIfImportMetaAssignment(result);
89
90
  return result;
90
91
  }
@@ -101,14 +102,9 @@ export function parseExecutableModule(source, filename = "<input>", owner) {
101
102
  compilation.dispose();
102
103
  }
103
104
  }
104
- function parseTokens(tokens, compilation) {
105
- return new Parser(tokens, compilation).parseTopLevel();
106
- }
107
- function parseModuleTokens(tokens, compilation) {
108
- return new Parser(tokens, compilation).parseModule();
109
- }
110
105
  class Parser {
111
106
  tokens;
107
+ source;
112
108
  compilation;
113
109
  functionContext;
114
110
  index = 0;
@@ -119,12 +115,21 @@ class Parser {
119
115
  scopes = [new Map()];
120
116
  functionScopes = new WeakSet();
121
117
  varNames = new WeakMap();
122
- constructor(tokens, compilation, functionContext = "normal") {
118
+ constructor(tokens, source, compilation, functionContext = "normal") {
123
119
  this.tokens = tokens;
120
+ this.source = source;
124
121
  this.compilation = compilation;
125
122
  this.functionContext = functionContext;
126
123
  this.functionScopes.add(this.scopes[0]);
127
124
  }
125
+ withFunctionSource(node) {
126
+ functionSources.set(node, {
127
+ text: this.source,
128
+ start: node.span.start.offset,
129
+ end: node.span.end.offset
130
+ });
131
+ return node;
132
+ }
128
133
  parseTopLevel() {
129
134
  if (this.isExportToken(this.currentToken())) {
130
135
  throw new DisallowedSyntaxError("export", this.currentToken().start);
@@ -270,14 +275,14 @@ class Parser {
270
275
  });
271
276
  this.expectPunctuator("=>");
272
277
  const body = this.parseArrowFunctionBody(params);
273
- return {
278
+ return this.withFunctionSource({
274
279
  type: "ArrowFunctionExpression",
275
280
  async: isAsync,
276
281
  body,
277
282
  expression: body.type !== "BlockStatement",
278
283
  params,
279
284
  span: createSpan(start, body.span.end)
280
- };
285
+ });
281
286
  }
282
287
  parseConditionalExpression() {
283
288
  if (this.conditionalExpressionDepth >= MAX_CONDITIONAL_EXPRESSION_DEPTH) {
@@ -920,7 +925,7 @@ class Parser {
920
925
  });
921
926
  const generator = generatorToken !== undefined;
922
927
  const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
923
- return {
928
+ return this.withFunctionSource({
924
929
  type: "FunctionDeclaration",
925
930
  async: asyncToken !== undefined,
926
931
  body,
@@ -928,7 +933,7 @@ class Parser {
928
933
  id,
929
934
  params,
930
935
  span: createSpan(asyncToken?.start ?? functionToken.start, body.span.end)
931
- };
936
+ });
932
937
  }
933
938
  parseVariableDeclarator(kind) {
934
939
  const id = this.parseBindingTarget();
@@ -1669,7 +1674,11 @@ class Parser {
1669
1674
  continue;
1670
1675
  }
1671
1676
  if (this.currentToken().type === "template") {
1672
- const quasi = createTemplateLiteral(this.currentToken(), { allowMalformedEscapes: true, functionContext: this.functionContext }, this.compilation);
1677
+ const quasi = createTemplateLiteral(this.currentToken(), {
1678
+ allowMalformedEscapes: true,
1679
+ functionContext: this.functionContext,
1680
+ source: this.source
1681
+ }, this.compilation);
1673
1682
  this.index += 1;
1674
1683
  expression = {
1675
1684
  node: {
@@ -1757,7 +1766,11 @@ class Parser {
1757
1766
  if (token.type === "template") {
1758
1767
  this.index += 1;
1759
1768
  return {
1760
- node: createTemplateLiteral(token, { allowMalformedEscapes: false, functionContext: this.functionContext }, this.compilation),
1769
+ node: createTemplateLiteral(token, {
1770
+ allowMalformedEscapes: false,
1771
+ functionContext: this.functionContext,
1772
+ source: this.source
1773
+ }, this.compilation),
1761
1774
  parenthesized: false
1762
1775
  };
1763
1776
  }
@@ -1875,7 +1888,7 @@ class Parser {
1875
1888
  });
1876
1889
  const generator = generatorToken !== undefined;
1877
1890
  const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
1878
- return {
1891
+ return this.withFunctionSource({
1879
1892
  type: "FunctionExpression",
1880
1893
  async: asyncToken !== undefined,
1881
1894
  body,
@@ -1883,7 +1896,7 @@ class Parser {
1883
1896
  id,
1884
1897
  params,
1885
1898
  span: createSpan(asyncToken?.start ?? functionToken.start, body.span.end)
1886
- };
1899
+ });
1887
1900
  }
1888
1901
  parseArrayExpression() {
1889
1902
  const start = this.expectPunctuator("[");
@@ -2139,7 +2152,7 @@ class Parser {
2139
2152
  return parsedParams;
2140
2153
  });
2141
2154
  const body = this.withFunctionContext("normal", () => this.parseBlockStatement(params));
2142
- return {
2155
+ return this.withFunctionSource({
2143
2156
  type: "FunctionExpression",
2144
2157
  async: asyncToken !== undefined,
2145
2158
  body,
@@ -2148,7 +2161,7 @@ class Parser {
2148
2161
  method: true,
2149
2162
  params,
2150
2163
  span: createSpan(asyncToken?.start ?? methodStart, body.span.end)
2151
- };
2164
+ });
2152
2165
  }
2153
2166
  parseIdentifierName() {
2154
2167
  const token = this.currentToken();
@@ -3033,7 +3046,7 @@ function createTemplateLiteral(token, options, compilation) {
3033
3046
  quasis.push(createTemplateElement(token.start, raw, quasiStart, cursor, false, options));
3034
3047
  const expressionStart = cursor + 2;
3035
3048
  const expressionEnd = findTemplateExpressionEnd(raw, expressionStart);
3036
- expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), options.functionContext, compilation));
3049
+ expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), options.functionContext, options.source, compilation));
3037
3050
  quasiStart = expressionEnd + 1;
3038
3051
  cursor = expressionEnd + 1;
3039
3052
  continue;
@@ -3394,13 +3407,13 @@ function decodeHexEscape(value, start) {
3394
3407
  end: index + 2
3395
3408
  };
3396
3409
  }
3397
- function parseEmbeddedExpression(source, base, functionContext, compilation) {
3410
+ function parseEmbeddedExpression(source, base, functionContext, fullSource, compilation) {
3398
3411
  const tokens = tokenize(source, { allowRegexLiterals: true, compilation }).map((token) => ({
3399
3412
  ...token,
3400
3413
  start: rebasePosition(token.start, base),
3401
3414
  end: rebasePosition(token.end, base)
3402
3415
  }));
3403
- return new Parser(tokens, compilation, functionContext).parseExpressionOnly();
3416
+ return new Parser(tokens, fullSource, compilation, functionContext).parseExpressionOnly();
3404
3417
  }
3405
3418
  export function findRegexLiteral(node) {
3406
3419
  if (node === null || node === undefined) {
@@ -21,13 +21,14 @@ export function restore(snapshot, options, owner) {
21
21
  validateSnapshotMigration(snapshot.migration, snapshot.sourceHash, owner);
22
22
  if (snapshot.executionSemantics !== EXECUTION_SEMANTICS &&
23
23
  snapshot.executionSemantics !== "jobs-v6" &&
24
+ snapshot.executionSemantics !== "jobs-v7" &&
24
25
  (snapshot.executionSemantics !== undefined ||
25
26
  snapshot.promiseReplay !== undefined ||
26
27
  snapshot.replay !== undefined ||
27
28
  snapshot.initialInputs !== undefined)) {
28
29
  throw new SnapshotValidationError("unsupportedVersion", "$.executionSemantics", "incompatible execution semantics; resume with the SafeJS version that created this snapshot. Migration requires explicit reconciliation, not changing its version marker.");
29
30
  }
30
- const currentSourceHash = hashSource(options.source, owner);
31
+ const currentSourceHash = hashSource(options.source, owner, snapshot.executionSemantics !== "jobs-v6" && snapshot.executionSemantics !== "jobs-v7");
31
32
  if (snapshot.sourceHash !== currentSourceHash) {
32
33
  throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
33
34
  }
@@ -1,7 +1,7 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import { runWithExtensions } from "./realm.js";
3
3
  import { hashParsedAst, hashSource } from "./parse/hash.js";
4
- import { withRunResources } from "./interp/resources.js";
4
+ import { runResources, withRunResources } from "./interp/resources.js";
5
5
  import { createReplayableRandom } from "./random.js";
6
6
  import { attachErrorSpan, describeThrownValue, materializeWrappedErrorCause, replaceErrorStack } from "./error/shape.js";
7
7
  import { findRegexLiteral, parseExecutableModule } from "./parse/parser.js";
@@ -76,7 +76,11 @@ export function run(source, options = {}) {
76
76
  const restoredSnapshot = options.snapshot === undefined
77
77
  ? undefined
78
78
  : restore(options.snapshot, { source }, operation.owner);
79
- const executionSemantics = restoredSnapshot?.executionSemantics === "jobs-v6" ? "jobs-v6" : EXECUTION_SEMANTICS;
79
+ const executionSemantics = restoredSnapshot?.executionSemantics === "jobs-v6" ||
80
+ restoredSnapshot?.executionSemantics === "jobs-v7"
81
+ ? restoredSnapshot.executionSemantics
82
+ : EXECUTION_SEMANTICS;
83
+ runResources.getStore().functionSourceText = executionSemantics === EXECUTION_SEMANTICS;
80
84
  const convertInitialInput = (convert) => executionSemantics === "jobs-v6" ? convert() : promiseReplayContext.exit(convert);
81
85
  if (restoredSnapshot !== undefined) {
82
86
  leaveSnapshotRun = enterSnapshotRun(restoredSnapshot);
@@ -86,8 +90,8 @@ export function run(source, options = {}) {
86
90
  const module = parseExecutableModule(source, filename, operation.owner);
87
91
  promiseReplay.validateNodes(module);
88
92
  const sourceHash = findRegexLiteral(module) === undefined
89
- ? hashSource(source, operation.owner)
90
- : hashParsedAst(module);
93
+ ? hashSource(source, operation.owner, executionSemantics === EXECUTION_SEMANTICS)
94
+ : hashParsedAst(module, executionSemantics === EXECUTION_SEMANTICS);
91
95
  const hostCalls = new HostCallJournal(sourceHash, readHostCallSnapshot(restoredSnapshot), options.hostCallResumeProvider, restoredSnapshot?.replay, budget, operation.owner);
92
96
  leaveHostReplay = hostCalls.dispose.bind(hostCalls);
93
97
  promiseReplay.validateCallbacks(hostCalls.callbackPositions());
@@ -110,7 +114,14 @@ export function run(source, options = {}) {
110
114
  signal: options.signal,
111
115
  lifecycle
112
116
  }));
113
- const builtinBindings = createBuiltinBindings({ compileOwner: operation.owner, budget, hostCalls, sink: options.sink, random: random?.generator.next, clock: options.clock });
117
+ const builtinBindings = createBuiltinBindings({
118
+ compileOwner: operation.owner,
119
+ budget,
120
+ hostCalls,
121
+ sink: options.sink,
122
+ random: random?.generator.next,
123
+ clock: options.clock
124
+ });
114
125
  const importMeta = convertInitialInput(() => deepCopyToSandbox(options.importMeta ?? {}));
115
126
  if (restoredSnapshot?.migration !== undefined) {
116
127
  if (Object.hasOwn(importMeta, "migration"))
@@ -1,5 +1,5 @@
1
1
  export declare const DUMP_FORMAT_VERSION = 1;
2
- export declare const EXECUTION_SEMANTICS = "jobs-v7";
2
+ export declare const EXECUTION_SEMANTICS = "jobs-v8";
3
3
  export type DumpableSnapshot = {
4
4
  sourceHash: string;
5
5
  [key: string]: unknown;
@@ -1,5 +1,5 @@
1
1
  export const DUMP_FORMAT_VERSION = 1;
2
- export const EXECUTION_SEMANTICS = "jobs-v7";
2
+ export const EXECUTION_SEMANTICS = "jobs-v8";
3
3
  import { assertSnapshotGraphDepth } from "../graph-depth.js";
4
4
  import { hasGuestObjectState } from "../interp/object-model.js";
5
5
  import { sandboxErrorTypes } from "../error/shape.js";
@@ -3,8 +3,8 @@ import { decodeReplayData } from "./replay-data.js";
3
3
  import { validateSnapshotData } from "./validation.js";
4
4
  import { CompileScope } from "../interp/regex/compile-guard.js";
5
5
  export function validateMigrationSemantics(value) {
6
- if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7"].includes(value))
7
- throw new TypeError("Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v7).");
6
+ if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7", "jobs-v8"].includes(value))
7
+ throw new TypeError("Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v8).");
8
8
  }
9
9
  export function validateMigrationJournal(sourceHash, replay, hostCalls = [], owner) {
10
10
  if (replay === undefined)
@@ -8,6 +8,7 @@ import { sandboxErrorTypes } from "../error/shape.js";
8
8
  import { SnapshotMismatchError } from "../restore.js";
9
9
  import { Scope, setSandboxProperty } from "../interp/interpreter.js";
10
10
  import { getGuestFunctionProperties, getGuestFunctionProperty, getSandboxDataProperty, registerGuestClosure, setSandboxPrototype } from "../interp/object-model.js";
11
+ import { functionSources } from "../parse/function-source.js";
11
12
  import { wrapCallerInjectedBindings } from "../interp/host-bridge.js";
12
13
  import { restoreSandboxCollectionIterator } from "../interp/collection-iterator.js";
13
14
  import { isSandboxMap, isSandboxSet } from "../interp/values.js";
@@ -454,6 +455,7 @@ function restoreClosureValue(astNodeId, capturedScopeId, state) {
454
455
  throw new Error(`Snapshot references unknown closure AST node ${astNodeId}.`);
455
456
  }
456
457
  const baseClosure = createSandboxClosure({
458
+ sourceRange: functionSources.get(node),
457
459
  async: node.async,
458
460
  sandbox: true,
459
461
  length: getFunctionLength(node.params),