poe-code 11.0.4 → 11.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,7 +19,7 @@ import {
19
19
  parseMcpConfig,
20
20
  splitFrontmatter,
21
21
  withBrokenPipeGuard
22
- } from "./chunks/chunk-NBVIHENC.js";
22
+ } from "./chunks/chunk-NP42RTIU.js";
23
23
  import {
24
24
  Budget,
25
25
  SandboxError,
@@ -31,7 +31,7 @@ import {
31
31
  replaceErrorStack,
32
32
  restore,
33
33
  run
34
- } from "./chunks/chunk-CA342J7E.js";
34
+ } from "./chunks/chunk-OPNWSDXC.js";
35
35
  import "./chunks/chunk-4YIDX44G.js";
36
36
 
37
37
  // packages/safejs/src/cli.ts
@@ -3,7 +3,7 @@ import {
3
3
  createReplayableRandom,
4
4
  lint,
5
5
  run
6
- } from "./chunks/chunk-CA342J7E.js";
6
+ } from "./chunks/chunk-OPNWSDXC.js";
7
7
  import "./chunks/chunk-4YIDX44G.js";
8
8
  export {
9
9
  Budget,
@@ -26,7 +26,7 @@ import {
26
26
  runWithSpawnUsageAccumulator,
27
27
  splitFrontmatter,
28
28
  supportsSpawnMode
29
- } from "./chunks/chunk-NBVIHENC.js";
29
+ } from "./chunks/chunk-NP42RTIU.js";
30
30
  import {
31
31
  Budget,
32
32
  FileSnapshotBackend,
@@ -48,7 +48,7 @@ import {
48
48
  registerPendingHostCallPolicy,
49
49
  restore,
50
50
  run
51
- } from "./chunks/chunk-CA342J7E.js";
51
+ } from "./chunks/chunk-OPNWSDXC.js";
52
52
  import "./chunks/chunk-4YIDX44G.js";
53
53
 
54
54
  // packages/safejs/src/runner/run-harness.ts
@@ -667,17 +667,35 @@ async function evaluateVariableDeclaration(node, context) {
667
667
  value: undefined
668
668
  };
669
669
  }
670
- function isRestorableBindingValue(value) {
671
- if (Array.isArray(value)) {
672
- return value.every(isRestorableBindingValue);
673
- }
670
+ function isRestorableBindingValue(value, seen = new WeakSet()) {
674
671
  if (typeof value !== "object" || value === null) {
675
672
  return true;
676
673
  }
674
+ if (seen.has(value))
675
+ return true;
676
+ seen.add(value);
677
+ if (isSandboxMap(value)) {
678
+ for (const [key, entry] of value.entries) {
679
+ if (!isRestorableBindingValue(key, seen) || !isRestorableBindingValue(entry, seen)) {
680
+ return false;
681
+ }
682
+ }
683
+ return true;
684
+ }
685
+ if (isSandboxSet(value)) {
686
+ for (const entry of value.values) {
687
+ if (!isRestorableBindingValue(entry, seen))
688
+ return false;
689
+ }
690
+ return true;
691
+ }
692
+ if (Array.isArray(value)) {
693
+ return value.every((entry) => isRestorableBindingValue(entry, seen));
694
+ }
677
695
  if (Object.hasOwn(value, "kind")) {
678
696
  return !["fn", "generator", "map", "promise", "regex", "set"].includes(String(value.kind));
679
697
  }
680
- return Object.values(value).every(isRestorableBindingValue);
698
+ return Object.values(value).every((entry) => isRestorableBindingValue(entry, seen));
681
699
  }
682
700
  function predeclareDeclarationBindings(node, scope) {
683
701
  for (const name of getDeclarationBindingNames(node)) {
@@ -893,13 +911,24 @@ async function evaluateIfStatement(node, context) {
893
911
  return evaluateNode(branch, context);
894
912
  }
895
913
  async function evaluateForOfStatement(node, context) {
914
+ const restoredIteration = context.restoredLoopIterations.get(node.nodeId ?? -1);
915
+ let restoredEntry;
916
+ if (typeof restoredIteration === "object" && typeof restoredIteration.values[0] === "string") {
917
+ const restored = context.scope.consumeRestoredBinding(restoredIteration.values[0]);
918
+ if (restored.found && Array.isArray(restored.value)) {
919
+ restoredEntry = { done: false, value: restored.value[1] };
920
+ if (isSandboxMap(restored.value[0]) || isSandboxSet(restored.value[0])) {
921
+ return evaluateForOfIterator(node, restored.value[0], context, restoredEntry);
922
+ }
923
+ }
924
+ }
896
925
  const iterable = await evaluateNode(node.right, context);
897
926
  if (iterable.kind !== "normal") {
898
927
  return iterable;
899
928
  }
900
929
  const values = snapshotableIterationValues(iterable.value);
901
930
  if (values === undefined) {
902
- return evaluateForOfIterator(node, iterable.value, context);
931
+ return evaluateForOfIterator(node, iterable.value, context, restoredEntry);
903
932
  }
904
933
  const restoredIndex = consumeRestoredLoopIterationIndex(node, context);
905
934
  for (let index = restoredIndex; index < values.length; index += 1) {
@@ -935,7 +964,7 @@ async function evaluateForOfStatement(node, context) {
935
964
  value: undefined
936
965
  };
937
966
  }
938
- async function evaluateForOfIterator(node, value, context) {
967
+ async function evaluateForOfIterator(node, value, context, restoredEntry) {
939
968
  const iterator = getSandboxIterator(value);
940
969
  if (iterator === undefined) {
941
970
  throw new TypeError(`${String(value)} is not a supported iterable`);
@@ -952,7 +981,8 @@ async function evaluateForOfIterator(node, value, context) {
952
981
  }
953
982
  }
954
983
  while (true) {
955
- const iteration = await iterator.next();
984
+ const iteration = restoredEntry ?? (await iterator.next());
985
+ restoredEntry = undefined;
956
986
  if (typeof iteration !== "object" || iteration === null) {
957
987
  throw new TypeError("Iterator result must be an object.");
958
988
  }
@@ -960,7 +990,14 @@ async function evaluateForOfIterator(node, value, context) {
960
990
  context.activeLoopIterations.delete(nodeId);
961
991
  return normalEmptyResult();
962
992
  }
963
- context.activeLoopIterations.set(nodeId, index);
993
+ context.activeLoopIterations.set(nodeId, iterator.snapshotIndex === undefined
994
+ ? index
995
+ : {
996
+ get index() {
997
+ return iterator.snapshotIndex();
998
+ },
999
+ values: [value, iteration.value]
1000
+ });
964
1001
  const scope = context.scope.child();
965
1002
  const binding = await bindForOfLoopVariable(node.left, iteration.value, scope, context);
966
1003
  if (!binding.ok) {
@@ -1203,12 +1240,24 @@ function createLoopIterationContext(context, scope) {
1203
1240
  return {
1204
1241
  ...context,
1205
1242
  scope,
1206
- snapshot: (currentScope) => ({
1207
- ...currentScope.snapshot(),
1208
- ...(context.activeLoopIterations.size === 0
1209
- ? {}
1210
- : { loopIterations: Object.fromEntries(context.activeLoopIterations) })
1211
- })
1243
+ snapshot: (currentScope) => {
1244
+ const snapshot = currentScope.snapshot();
1245
+ if (context.activeLoopIterations.size === 0)
1246
+ return snapshot;
1247
+ snapshot.loopIterations = {};
1248
+ for (const [nodeId, iteration] of context.activeLoopIterations) {
1249
+ if (typeof iteration !== "number" &&
1250
+ (isSandboxMap(iteration.values[0]) || isSandboxSet(iteration.values[0]))) {
1251
+ const bindingName = `#for-of:${nodeId}`;
1252
+ snapshot.bindings[bindingName] = iteration.values;
1253
+ snapshot.loopIterations[nodeId] = { index: iteration.index, values: [bindingName] };
1254
+ }
1255
+ else {
1256
+ snapshot.loopIterations[nodeId] = iteration;
1257
+ }
1258
+ }
1259
+ return snapshot;
1260
+ }
1212
1261
  };
1213
1262
  }
1214
1263
  function consumeRestoredLoopIteration(node, context) {
@@ -1228,12 +1277,6 @@ function snapshotableIterationValues(value) {
1228
1277
  if (Array.isArray(value)) {
1229
1278
  return value;
1230
1279
  }
1231
- if (isSandboxMap(value)) {
1232
- return Array.from(value.entries, ([key, entry]) => [key, entry]);
1233
- }
1234
- if (isSandboxSet(value)) {
1235
- return Array.from(value.values);
1236
- }
1237
1280
  return undefined;
1238
1281
  }
1239
1282
  function isMatchingBreak(result, labels) {
@@ -1,6 +1,7 @@
1
1
  import { type SandboxValue } from "./values.js";
2
2
  export type SandboxIterator = {
3
3
  readonly generator?: true;
4
+ snapshotIndex?(): number;
4
5
  next(value?: SandboxValue): IteratorResult<SandboxValue> | Promise<IteratorResult<SandboxValue>>;
5
6
  return?(value?: SandboxValue): IteratorResult<SandboxValue> | Promise<IteratorResult<SandboxValue>>;
6
7
  throw?(error?: SandboxValue): IteratorResult<SandboxValue> | Promise<IteratorResult<SandboxValue>>;
@@ -8,10 +8,10 @@ export function getSandboxIterator(value) {
8
8
  return syncIterator(value[Symbol.iterator]());
9
9
  }
10
10
  if (isSandboxMap(value)) {
11
- return syncIterator(Array.from(value.entries, ([key, entry]) => [key, entry])[Symbol.iterator]());
11
+ return collectionIterator(value.entries);
12
12
  }
13
13
  if (isSandboxSet(value)) {
14
- return syncIterator(value.values[Symbol.iterator]());
14
+ return collectionIterator(value.values);
15
15
  }
16
16
  if ((typeof value !== "object" && typeof value !== "function") || value === null) {
17
17
  return undefined;
@@ -22,6 +22,33 @@ export function getSandboxIterator(value) {
22
22
  }
23
23
  return syncIterator(Reflect.apply(iteratorMethod, value, []));
24
24
  }
25
+ function collectionIterator(collection) {
26
+ let iterator = collection[Symbol.iterator]();
27
+ let exhausted = false;
28
+ return {
29
+ ...syncIterator({
30
+ next: () => {
31
+ if (exhausted)
32
+ return { done: true, value: undefined };
33
+ const result = iterator.next();
34
+ exhausted = result.done === true;
35
+ return result;
36
+ }
37
+ }),
38
+ snapshotIndex: () => {
39
+ if (exhausted)
40
+ return collection.size;
41
+ let remaining = 0;
42
+ while (!iterator.next().done)
43
+ remaining += 1;
44
+ const index = collection.size - remaining;
45
+ iterator = collection[Symbol.iterator]();
46
+ for (let skipped = 0; skipped < index; skipped += 1)
47
+ iterator.next();
48
+ return index;
49
+ }
50
+ };
51
+ }
25
52
  function generatorIterator(generator) {
26
53
  const invoke = async (method, value) => {
27
54
  const leaveRunning = enterRunningState(generator);
@@ -759,7 +759,13 @@ class Parser {
759
759
  }
760
760
  ];
761
761
  }
762
- this.expectKeyword("from");
762
+ const fromToken = this.currentToken();
763
+ if (fromToken.type !== "identifier" ||
764
+ fromToken.value !== "from" ||
765
+ fromToken.end.offset - fromToken.start.offset !== fromToken.value.length) {
766
+ throw new Error(`Expected 'from' at line ${fromToken.start.line}, column ${fromToken.start.column}.`);
767
+ }
768
+ this.index += 1;
763
769
  const sourceToken = this.currentToken();
764
770
  if (sourceToken.type !== "string") {
765
771
  throw unexpectedTokenError(sourceToken);
@@ -18,7 +18,6 @@ const KEYWORDS = new Set([
18
18
  "await",
19
19
  "yield",
20
20
  "import",
21
- "from",
22
21
  "as",
23
22
  "true",
24
23
  "false",