@opencode/codemode 2.0.3 → 2.0.5

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 (72) hide show
  1. package/README.md +5 -2
  2. package/dist/codemode.d.ts +7 -2
  3. package/dist/codemode.js +15 -2
  4. package/dist/data.d.ts +14 -21
  5. package/dist/data.js +72 -140
  6. package/dist/extension.d.ts +11 -0
  7. package/dist/extension.js +9 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +1 -0
  10. package/dist/interpreter/callback.d.ts +20 -0
  11. package/dist/interpreter/{runner.js → callback.js} +14 -14
  12. package/dist/interpreter/errors.d.ts +12 -5
  13. package/dist/interpreter/errors.js +66 -54
  14. package/dist/interpreter/execute.d.ts +2 -2
  15. package/dist/interpreter/execute.js +15 -15
  16. package/dist/interpreter/extensions.d.ts +8 -0
  17. package/dist/interpreter/extensions.js +160 -0
  18. package/dist/interpreter/generators.d.ts +2 -3
  19. package/dist/interpreter/generators.js +10 -10
  20. package/dist/interpreter/globals.d.ts +4 -12
  21. package/dist/interpreter/globals.js +56 -49
  22. package/dist/interpreter/interpreter.d.ts +34 -0
  23. package/dist/interpreter/{runtime.js → interpreter.js} +250 -215
  24. package/dist/interpreter/intrinsics.d.ts +5 -5
  25. package/dist/interpreter/intrinsics.js +16 -10
  26. package/dist/interpreter/limits.d.ts +10 -0
  27. package/dist/interpreter/limits.js +19 -0
  28. package/dist/interpreter/model.d.ts +27 -14
  29. package/dist/interpreter/model.js +22 -14
  30. package/dist/interpreter/native.d.ts +12 -13
  31. package/dist/interpreter/native.js +17 -16
  32. package/dist/interpreter/objects.d.ts +55 -48
  33. package/dist/interpreter/objects.js +64 -44
  34. package/dist/interpreter/promises.d.ts +13 -15
  35. package/dist/interpreter/promises.js +89 -85
  36. package/dist/interpreter/references.d.ts +1 -2
  37. package/dist/interpreter/references.js +18 -16
  38. package/dist/interpreter/scope.js +6 -6
  39. package/dist/openapi/types.d.ts +1 -1
  40. package/dist/stdlib/array.d.ts +3 -4
  41. package/dist/stdlib/array.js +115 -110
  42. package/dist/stdlib/bytes.d.ts +10 -0
  43. package/dist/stdlib/bytes.js +228 -0
  44. package/dist/stdlib/collections.d.ts +4 -4
  45. package/dist/stdlib/collections.js +89 -89
  46. package/dist/stdlib/console.d.ts +5 -3
  47. package/dist/stdlib/console.js +30 -37
  48. package/dist/stdlib/date.d.ts +2 -2
  49. package/dist/stdlib/date.js +35 -35
  50. package/dist/stdlib/json.d.ts +3 -3
  51. package/dist/stdlib/json.js +29 -67
  52. package/dist/stdlib/math.d.ts +3 -3
  53. package/dist/stdlib/math.js +17 -21
  54. package/dist/stdlib/number.d.ts +3 -3
  55. package/dist/stdlib/number.js +32 -36
  56. package/dist/stdlib/object.d.ts +5 -5
  57. package/dist/stdlib/object.js +59 -62
  58. package/dist/stdlib/regexp.d.ts +7 -8
  59. package/dist/stdlib/regexp.js +40 -48
  60. package/dist/stdlib/string.d.ts +2 -2
  61. package/dist/stdlib/string.js +110 -88
  62. package/dist/stdlib/url.d.ts +4 -6
  63. package/dist/stdlib/url.js +86 -90
  64. package/dist/stdlib/value.d.ts +3 -3
  65. package/dist/stdlib/value.js +26 -24
  66. package/dist/stdlib/web.d.ts +4 -4
  67. package/dist/stdlib/web.js +22 -8
  68. package/dist/tool-runtime.d.ts +38 -19
  69. package/dist/tool-runtime.js +70 -48
  70. package/package.json +1 -1
  71. package/dist/interpreter/runner.d.ts +0 -28
  72. package/dist/interpreter/runtime.d.ts +0 -19
@@ -1,14 +1,14 @@
1
1
  import { ToolReference } from "../tool-runtime.js";
2
- import { InterpreterRuntimeError } from "./model.js";
3
- import { Callable, getOwn, isWrapper, ownKeys, ProgramArray, ProgramDate, ProgramGenerator, ProgramMap, ProgramObject, ProgramPromise, ProgramRegExp, ProgramSet, ProgramURL, ProgramURLSearchParams, } from "./objects.js";
2
+ import { invalidData } from "./model.js";
3
+ import { Callable, getOwn, isWrapper, ownKeys, Arr, Bytes, DateObj, GeneratorObj, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "./objects.js";
4
4
  /** Values that cannot cross the data boundary. */
5
5
  export const isRuntimeReference = (value) => value instanceof Callable ||
6
- value instanceof ProgramGenerator ||
6
+ value instanceof GeneratorObj ||
7
7
  value instanceof ToolReference ||
8
- value instanceof ProgramPromise ||
8
+ value instanceof PromiseObj ||
9
9
  isWrapper(value);
10
10
  function* childValues(value) {
11
- if (!(value instanceof ProgramObject))
11
+ if (!(value instanceof Obj))
12
12
  return;
13
13
  for (const key of ownKeys(value))
14
14
  yield getOwn(value, key);
@@ -37,33 +37,35 @@ export const containsRuntimeReference = (value) => find(value, isRuntimeReferenc
37
37
  // Wrapper values are data here, not opaque interpreter references.
38
38
  export const containsOpaqueReference = (value) => find(value, (current) => !isWrapper(current) && isRuntimeReference(current), isWrapper, new Set());
39
39
  // Reject cycles before mutation so later boundary walks remain safe.
40
- export const rejectCircularInsertion = (container, value, label, node, seen = new Set()) => {
40
+ export const rejectCircularInsertion = (container, value, label, seen = new Set()) => {
41
41
  if (find(value, (current) => current === container, isRuntimeReference, seen)) {
42
- throw new InterpreterRuntimeError(`${label} contains a circular value.`, node, "InvalidDataValue");
42
+ throw invalidData(`${label} contains a circular value.`);
43
43
  }
44
44
  };
45
45
  export const describeValue = (value) => {
46
46
  if (value === null || value === undefined)
47
47
  return String(value);
48
- if (value instanceof ProgramArray)
48
+ if (value instanceof Arr)
49
49
  return "an array";
50
- if (value instanceof ProgramPromise)
50
+ if (value instanceof PromiseObj)
51
51
  return "an un-awaited Promise";
52
52
  if (value instanceof ToolReference)
53
53
  return "a tool reference";
54
- if (value instanceof ProgramDate)
54
+ if (value instanceof DateObj)
55
55
  return "a Date";
56
- if (value instanceof ProgramRegExp)
56
+ if (value instanceof RegExpObj)
57
57
  return "a RegExp";
58
- if (value instanceof ProgramMap)
58
+ if (value instanceof MapObj)
59
59
  return "a Map";
60
- if (value instanceof ProgramSet)
60
+ if (value instanceof SetObj)
61
61
  return "a Set";
62
- if (value instanceof ProgramURL)
62
+ if (value instanceof URLObj)
63
63
  return "a URL";
64
- if (value instanceof ProgramURLSearchParams)
64
+ if (value instanceof URLSearchParamsObj)
65
65
  return "a URLSearchParams";
66
- if (value instanceof ProgramGenerator)
66
+ if (value instanceof Bytes)
67
+ return "a Uint8Array";
68
+ if (value instanceof GeneratorObj)
67
69
  return "a generator";
68
70
  if (isRuntimeReference(value))
69
71
  return "a function";
@@ -1,4 +1,4 @@
1
- import { InterpreterRuntimeError, referenceError } from "./model.js";
1
+ import { referenceError, typeError } from "./model.js";
2
2
  export class ScopeStack {
3
3
  scopes;
4
4
  constructor(scopes) {
@@ -7,14 +7,14 @@ export class ScopeStack {
7
7
  reserve(name, mutable, node) {
8
8
  const scope = this.current();
9
9
  if (scope.has(name)) {
10
- throw new InterpreterRuntimeError(`Identifier '${name}' has already been declared.`, node);
10
+ throw typeError(`Identifier '${name}' has already been declared.`, node);
11
11
  }
12
12
  scope.set(name, { mutable, value: undefined, initialized: false });
13
13
  }
14
14
  initialize(name, value, node) {
15
15
  const binding = this.current().get(name);
16
16
  if (!binding || binding.initialized !== false) {
17
- throw new InterpreterRuntimeError(`Identifier '${name}' has not been reserved for initialization.`, node);
17
+ throw typeError(`Identifier '${name}' has not been reserved for initialization.`, node);
18
18
  }
19
19
  binding.value = value;
20
20
  binding.initialized = true;
@@ -22,7 +22,7 @@ export class ScopeStack {
22
22
  declare(name, value, mutable, node) {
23
23
  const scope = this.current();
24
24
  if (scope.has(name)) {
25
- throw new InterpreterRuntimeError(`Identifier '${name}' has already been declared.`, node);
25
+ throw typeError(`Identifier '${name}' has already been declared.`, node);
26
26
  }
27
27
  scope.set(name, { mutable, value, initialized: true });
28
28
  }
@@ -45,7 +45,7 @@ export class ScopeStack {
45
45
  throw referenceError(`Cannot access '${name}' before initialization.`, node);
46
46
  }
47
47
  if (!binding.mutable) {
48
- throw new InterpreterRuntimeError(`Cannot assign to constant '${name}'.`, node);
48
+ throw typeError(`Cannot assign to constant '${name}'.`, node);
49
49
  }
50
50
  binding.value = value;
51
51
  return value;
@@ -63,7 +63,7 @@ export class ScopeStack {
63
63
  current() {
64
64
  const scope = this.scopes[this.scopes.length - 1];
65
65
  if (!scope) {
66
- throw new InterpreterRuntimeError("Interpreter scope stack is empty.");
66
+ throw typeError("Interpreter scope stack is empty.");
67
67
  }
68
68
  return scope;
69
69
  }
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
2
  import { HttpClient } from "effect/unstable/http";
3
3
  import type { Tool, JsonSchema } from "../tool.js";
4
- /** A parsed OpenAPI 3.x document. YAML must be parsed by the host. */
4
+ /** A parsed OpenAPI 3.x document. YAML must be parsed by the ctx. */
5
5
  export type Document = Record<string, unknown>;
6
6
  /** The operation identity handed to auth resolution and errors. */
7
7
  export type Operation = {
@@ -1,5 +1,4 @@
1
1
  import { Effect } from "effect";
2
- import { type AstNode } from "../interpreter/model.js";
3
- import { type Runner } from "../interpreter/runner.js";
4
- export declare const sortArray: <R>(runner: Runner<R>, target: Array<unknown>, comparator: unknown, name: string, node: AstNode) => Effect.Effect<Array<unknown>, unknown, R>;
5
- export declare const arrayGlobal: <R>(runner: Runner<R>) => import("../interpreter/objects.js").NativeFunction<R>;
2
+ import type { Interpreter } from "../interpreter/interpreter.js";
3
+ export declare const sortArray: <R>(ctx: Interpreter<R>, target: Array<unknown>, comparator: unknown, name: string) => Effect.Effect<Array<unknown>, unknown, R>;
4
+ export declare const arrayGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
@@ -1,56 +1,55 @@
1
1
  import { Effect } from "effect";
2
2
  import { constructor, methods, prototypeFrom, receiver } from "../interpreter/native.js";
3
- import { InterpreterRuntimeError, rangeError } from "../interpreter/model.js";
4
- import { get, ProgramArray, ProgramGenerator, ProgramObject } from "../interpreter/objects.js";
3
+ import { checkArrayLength, checkStringLength, MAX_ARRAY_LENGTH } from "../interpreter/limits.js";
4
+ import { invalidData, rangeError, typeError } from "../interpreter/model.js";
5
+ import { get, Arr, GeneratorObj, Obj } from "../interpreter/objects.js";
5
6
  import { describeValue, rejectCircularInsertion } from "../interpreter/references.js";
6
- import { applyCollectionCallback, preserveConsumerError } from "../interpreter/runner.js";
7
+ import { applyCollectionCallback, preserveConsumerError } from "../interpreter/callback.js";
7
8
  import { compareText } from "../tool-runtime.js";
8
9
  import { coerceToNumber, coerceToString } from "./value.js";
9
- const MAX_LENGTH = 4_294_967_295;
10
- const arrayLikeSource = (source, node) => {
11
- if (source instanceof ProgramObject && typeof get(source, "length") === "number") {
10
+ const arrayLikeSource = (source) => {
11
+ if (source instanceof Obj && typeof get(source, "length") === "number") {
12
12
  const length = get(source, "length");
13
13
  const normalized = Number.isNaN(length) || length <= 0 ? 0 : Math.trunc(length);
14
- if (normalized > MAX_LENGTH)
15
- throw new RangeError("Invalid array length");
14
+ checkArrayLength(normalized);
16
15
  return { length: normalized, source };
17
16
  }
18
- throw new InterpreterRuntimeError(`Array.from expects an array, string, Map, Set, or array-like value, received ${describeValue(source)}.`, node, "InvalidDataValue");
17
+ throw invalidData(`Array.from expects an array, string, Map, Set, or array-like value, received ${describeValue(source)}.`);
19
18
  };
20
- const arrayFrom = (runner, args, node) => {
19
+ const arrayFrom = (ctx, args) => {
21
20
  const source = args[0];
22
- const proto = runner.prototypes.Array;
23
- const apply = args.length < 2 || args[1] === undefined ? undefined : applyCollectionCallback(runner, args[1], "Array.from", node);
21
+ const proto = ctx.builtins.Array;
22
+ const apply = args.length < 2 || args[1] === undefined ? undefined : applyCollectionCallback(ctx, args[1], "Array.from");
24
23
  return Effect.gen(function* () {
25
- const cursor = yield* runner.syncIterator(source, node);
24
+ const cursor = yield* ctx.iterate(source);
26
25
  if (cursor === undefined) {
27
- if (source instanceof ProgramGenerator) {
28
- throw new InterpreterRuntimeError("Array.from expects a synchronous iterable or array-like value.", node);
26
+ if (source instanceof GeneratorObj) {
27
+ throw typeError("Array.from expects a synchronous iterable or array-like value.");
29
28
  }
30
- const arrayLike = arrayLikeSource(source, node);
29
+ const arrayLike = arrayLikeSource(source);
31
30
  const values = [];
32
31
  for (let index = 0; index < arrayLike.length; index += 1) {
33
32
  const item = get(arrayLike.source, index);
34
33
  values.push(apply === undefined ? item : yield* apply([item, index]));
35
34
  }
36
- return new ProgramArray(proto, values);
35
+ return new Arr(proto, values);
37
36
  }
38
37
  const values = [];
39
38
  let index = 0;
40
39
  while (true) {
41
40
  const step = yield* cursor.next;
42
41
  if (step.done)
43
- return new ProgramArray(proto, values);
42
+ return new Arr(proto, values);
44
43
  values.push(apply === undefined ? step.value : yield* preserveConsumerError(cursor, apply([step.value, index])));
45
44
  index += 1;
46
45
  }
47
46
  });
48
47
  };
49
- export const sortArray = (runner, target, comparator, name, node) => {
48
+ export const sortArray = (ctx, target, comparator, name) => {
50
49
  if (comparator === undefined) {
51
50
  return Effect.sync(() => [...target].sort((a, b) => compareText(coerceToString(a), coerceToString(b))));
52
51
  }
53
- const apply = applyCollectionCallback(runner, comparator, name, node);
52
+ const apply = applyCollectionCallback(ctx, comparator, name);
54
53
  const mergeSort = (items) => {
55
54
  if (items.length <= 1)
56
55
  return Effect.succeed(items);
@@ -77,38 +76,38 @@ export const sortArray = (runner, target, comparator, name, node) => {
77
76
  return Effect.map(mergeSort(defined), (items) => [...items, ...Array(undefinedCount).fill(undefined)]);
78
77
  };
79
78
  // Array constructs identically with or without new, like JS.
80
- export const arrayGlobal = (runner) => {
81
- const protos = runner.prototypes;
82
- const proto = protos.Array;
83
- const wrap = (items) => new ProgramArray(proto, items);
84
- const construct = (args, into, node) => {
79
+ export const arrayGlobal = (ctx) => {
80
+ const builtins = ctx.builtins;
81
+ const proto = builtins.Array;
82
+ const wrap = (items) => new Arr(proto, items);
83
+ const construct = (args, into) => {
85
84
  if (args.length !== 1)
86
- return new ProgramArray(into, [...args]);
85
+ return new Arr(into, [...args]);
87
86
  const first = args[0];
88
87
  if (typeof first !== "number")
89
- return new ProgramArray(into, [first]);
90
- if (!Number.isInteger(first) || first < 0 || first > MAX_LENGTH)
91
- throw rangeError("Invalid array length.", node);
88
+ return new Arr(into, [first]);
89
+ if (!Number.isInteger(first) || first < 0 || first > MAX_ARRAY_LENGTH)
90
+ throw rangeError("Invalid array length.");
92
91
  // Sparse like JS: Array(3) has holes, and combinator loops already skip them.
93
- return new ProgramArray(into, new Array(first));
92
+ return new Arr(into, new Array(first));
94
93
  };
95
- const array = constructor(protos, proto, {
94
+ const array = constructor(builtins, proto, {
96
95
  name: "Array",
97
96
  length: 1,
98
- call: (_, args, node) => Effect.sync(() => construct(args, proto, node)),
99
- construct: (args, newTarget, node) => Effect.sync(() => construct(args, prototypeFrom(newTarget, proto), node)),
97
+ call: (_, args) => Effect.sync(() => construct(args, proto)),
98
+ construct: (args, newTarget) => Effect.sync(() => construct(args, prototypeFrom(newTarget, proto))),
100
99
  });
101
- methods(protos, array, [
102
- ["isArray", 1, (_, args) => args[0] instanceof ProgramArray],
100
+ methods(builtins, array, [
101
+ ["isArray", 1, (_, args) => args[0] instanceof Arr],
103
102
  ["of", 0, (_, args) => wrap([...args])],
104
- ["from", 1, (_, args, node) => arrayFrom(runner, args, node)],
103
+ ["from", 1, (_, args) => arrayFrom(ctx, args)],
105
104
  ]);
106
- const self = (thisValue, name, node) => receiver(ProgramArray, thisValue, `Array.prototype.${name}`, node);
107
- const optNumber = (name, value, label, node) => {
105
+ const self = (thisValue, name) => receiver(Arr, thisValue, `Array.prototype.${name}`);
106
+ const optNumber = (name, value, label) => {
108
107
  if (value === undefined)
109
108
  return undefined;
110
109
  if (typeof value !== "number") {
111
- throw new InterpreterRuntimeError(`Array.${name} expects ${label} to be a number.`, node);
110
+ throw typeError(`Array.${name} expects ${label} to be a number.`);
112
111
  }
113
112
  return value;
114
113
  };
@@ -116,84 +115,90 @@ export const arrayGlobal = (runner) => {
116
115
  const iterate = (name, length, body) => [
117
116
  name,
118
117
  length,
119
- (thisValue, args, node) => {
120
- const target = self(thisValue, name, node);
121
- return body(target.items, target, applyCollectionCallback(runner, args[0], `Array.${name}`, node), args, node);
118
+ (thisValue, args) => {
119
+ const target = self(thisValue, name);
120
+ return body(target.items, target, applyCollectionCallback(ctx, args[0], `Array.${name}`), args);
122
121
  },
123
122
  ];
124
- methods(protos, proto, [
123
+ methods(builtins, proto, [
125
124
  [
126
125
  "join",
127
126
  1,
128
- (thisValue, args, node) => {
129
- const target = self(thisValue, "join", node).items;
127
+ (thisValue, args) => {
128
+ const target = self(thisValue, "join").items;
130
129
  if (args.length > 1 || (args.length === 1 && typeof args[0] !== "string")) {
131
- throw new InterpreterRuntimeError("Array.join expects zero arguments or one string separator.", node);
130
+ throw typeError("Array.join expects zero arguments or one string separator.");
132
131
  }
133
- return target.map((item) => coerceToString(item ?? "")).join(args.length === 0 ? "," : args[0]);
132
+ const joined = target
133
+ .map((item) => coerceToString(item ?? ""))
134
+ .join(args.length === 0 ? "," : args[0]);
135
+ checkStringLength(joined.length);
136
+ return joined;
134
137
  },
135
138
  ],
136
139
  [
137
140
  "toString",
138
141
  0,
139
- (thisValue, _, node) => self(thisValue, "toString", node)
142
+ (thisValue) => self(thisValue, "toString")
140
143
  .items.map((item) => coerceToString(item ?? ""))
141
144
  .join(","),
142
145
  ],
143
146
  [
144
147
  "includes",
145
148
  1,
146
- (thisValue, args, node) => {
147
- const target = self(thisValue, "includes", node).items;
149
+ (thisValue, args) => {
150
+ const target = self(thisValue, "includes").items;
148
151
  if (args.length === 0 || args.length > 2) {
149
- throw new InterpreterRuntimeError("Array.includes expects a value and optional start index.", node);
152
+ throw typeError("Array.includes expects a value and optional start index.");
150
153
  }
151
- return target.includes(args[0], optNumber("includes", args[1], "start index", node));
154
+ return target.includes(args[0], optNumber("includes", args[1], "start index"));
152
155
  },
153
156
  ],
154
157
  [
155
158
  "indexOf",
156
159
  1,
157
- (thisValue, args, node) => self(thisValue, "indexOf", node).items.indexOf(args[0], optNumber("indexOf", args[1], "start index", node)),
160
+ (thisValue, args) => self(thisValue, "indexOf").items.indexOf(args[0], optNumber("indexOf", args[1], "start index")),
158
161
  ],
159
162
  [
160
163
  "lastIndexOf",
161
164
  1,
162
- (thisValue, args, node) => {
163
- const target = self(thisValue, "lastIndexOf", node).items;
165
+ (thisValue, args) => {
166
+ const target = self(thisValue, "lastIndexOf").items;
164
167
  return args[1] === undefined
165
168
  ? target.lastIndexOf(args[0])
166
- : target.lastIndexOf(args[0], optNumber("lastIndexOf", args[1], "start index", node));
169
+ : target.lastIndexOf(args[0], optNumber("lastIndexOf", args[1], "start index"));
167
170
  },
168
171
  ],
169
- [
170
- "at",
171
- 1,
172
- (thisValue, args, node) => self(thisValue, "at", node).items.at(optNumber("at", args[0], "index", node) ?? 0),
173
- ],
172
+ ["at", 1, (thisValue, args) => self(thisValue, "at").items.at(optNumber("at", args[0], "index") ?? 0)],
174
173
  [
175
174
  "slice",
176
175
  2,
177
- (thisValue, args, node) => wrap(self(thisValue, "slice", node).items.slice(optNumber("slice", args[0], "start", node), optNumber("slice", args[1], "end", node))),
176
+ (thisValue, args) => wrap(self(thisValue, "slice").items.slice(optNumber("slice", args[0], "start"), optNumber("slice", args[1], "end"))),
178
177
  ],
179
178
  [
180
179
  "concat",
181
180
  1,
182
- (thisValue, args, node) => wrap(self(thisValue, "concat", node).items.concat(...args.map((item) => (item instanceof ProgramArray ? item.items : item)))),
181
+ (thisValue, args) => {
182
+ const joined = self(thisValue, "concat").items.concat(...args.map((item) => (item instanceof Arr ? item.items : item)));
183
+ checkArrayLength(joined.length);
184
+ return wrap(joined);
185
+ },
183
186
  ],
184
187
  [
185
188
  "flat",
186
189
  0,
187
- (thisValue, args, node) => {
188
- const flatten = (items, depth) => items.flatMap((item) => (item instanceof ProgramArray && depth > 0 ? flatten(item.items, depth - 1) : [item]));
189
- return wrap(flatten(self(thisValue, "flat", node).items, optNumber("flat", args[0], "depth", node) ?? 1));
190
+ (thisValue, args) => {
191
+ const flatten = (items, depth) => items.flatMap((item) => (item instanceof Arr && depth > 0 ? flatten(item.items, depth - 1) : [item]));
192
+ const flattened = flatten(self(thisValue, "flat").items, optNumber("flat", args[0], "depth") ?? 1);
193
+ checkArrayLength(flattened.length);
194
+ return wrap(flattened);
190
195
  },
191
196
  ],
192
197
  [
193
198
  "reverse",
194
199
  0,
195
- (thisValue, _, node) => {
196
- const target = self(thisValue, "reverse", node);
200
+ (thisValue) => {
201
+ const target = self(thisValue, "reverse");
197
202
  target.items.reverse();
198
203
  return target;
199
204
  },
@@ -201,18 +206,18 @@ export const arrayGlobal = (runner) => {
201
206
  [
202
207
  "sort",
203
208
  1,
204
- (thisValue, args, node) => {
205
- const target = self(thisValue, "sort", node);
209
+ (thisValue, args) => {
210
+ const target = self(thisValue, "sort");
206
211
  const items = target.items;
207
212
  const length = items.length;
208
213
  const holeCount = Array.from({ length }, (_, index) => Object.hasOwn(items, index)).filter((o) => !o).length;
209
214
  const itemCount = length - holeCount;
210
- return Effect.map(sortArray(runner, items, args[0], "Array.sort", node), (sorted) => {
215
+ return Effect.map(sortArray(ctx, items, args[0], "Array.sort"), (sorted) => {
211
216
  sorted.slice(0, itemCount).forEach((item, index) => {
212
217
  items[index] = item;
213
218
  });
214
219
  Array.from({ length: holeCount }, (_, index) => itemCount + index).forEach((index) => {
215
- Reflect.deleteProperty(items, index);
220
+ delete items[index];
216
221
  });
217
222
  return target;
218
223
  });
@@ -221,18 +226,18 @@ export const arrayGlobal = (runner) => {
221
226
  [
222
227
  "toSorted",
223
228
  1,
224
- (thisValue, args, node) => Effect.map(sortArray(runner, self(thisValue, "toSorted", node).items, args[0], "Array.toSorted", node), wrap),
229
+ (thisValue, args) => Effect.map(sortArray(ctx, self(thisValue, "toSorted").items, args[0], "Array.toSorted"), wrap),
225
230
  ],
226
- ["toReversed", 0, (thisValue, _, node) => wrap([...self(thisValue, "toReversed", node).items].reverse())],
231
+ ["toReversed", 0, (thisValue) => wrap([...self(thisValue, "toReversed").items].reverse())],
227
232
  [
228
233
  "with",
229
234
  2,
230
- (thisValue, args, node) => {
231
- const target = self(thisValue, "with", node).items;
232
- const index = optNumber("with", args[0], "index", node) ?? 0;
235
+ (thisValue, args) => {
236
+ const target = self(thisValue, "with").items;
237
+ const index = optNumber("with", args[0], "index") ?? 0;
233
238
  const resolved = index < 0 ? target.length + index : index;
234
239
  if (resolved < 0 || resolved >= target.length)
235
- throw rangeError("Array.with index is out of range.", node);
240
+ throw rangeError("Array.with index is out of range.");
236
241
  const copied = [...target];
237
242
  copied[resolved] = args[1];
238
243
  return wrap(copied);
@@ -241,83 +246,83 @@ export const arrayGlobal = (runner) => {
241
246
  [
242
247
  "push",
243
248
  1,
244
- (thisValue, args, node) => {
245
- const target = self(thisValue, "push", node);
249
+ (thisValue, args) => {
250
+ const target = self(thisValue, "push");
246
251
  // Validate all insertions before mutating to avoid partial cyclic updates.
247
252
  for (const item of args)
248
- rejectCircularInsertion(target, item, "Array.push result", node);
253
+ rejectCircularInsertion(target, item, "Array.push result");
249
254
  return target.items.push(...args);
250
255
  },
251
256
  ],
252
257
  [
253
258
  "unshift",
254
259
  1,
255
- (thisValue, args, node) => {
256
- const target = self(thisValue, "unshift", node);
260
+ (thisValue, args) => {
261
+ const target = self(thisValue, "unshift");
257
262
  for (const item of args)
258
- rejectCircularInsertion(target, item, "Array.unshift result", node);
263
+ rejectCircularInsertion(target, item, "Array.unshift result");
259
264
  return target.items.unshift(...args);
260
265
  },
261
266
  ],
262
- ["pop", 0, (thisValue, _, node) => self(thisValue, "pop", node).items.pop()],
263
- ["shift", 0, (thisValue, _, node) => self(thisValue, "shift", node).items.shift()],
267
+ ["pop", 0, (thisValue) => self(thisValue, "pop").items.pop()],
268
+ ["shift", 0, (thisValue) => self(thisValue, "shift").items.shift()],
264
269
  [
265
270
  "splice",
266
271
  2,
267
- (thisValue, args, node) => {
268
- const target = self(thisValue, "splice", node);
272
+ (thisValue, args) => {
273
+ const target = self(thisValue, "splice");
269
274
  if (args.length === 0)
270
275
  return wrap(target.items.splice(0, 0));
271
- const start = optNumber("splice", args[0], "start", node) ?? 0;
276
+ const start = optNumber("splice", args[0], "start") ?? 0;
272
277
  if (args.length === 1)
273
278
  return wrap(target.items.splice(start));
274
- const deleteCount = optNumber("splice", args[1], "delete count", node) ?? 0;
279
+ const deleteCount = optNumber("splice", args[1], "delete count") ?? 0;
275
280
  const inserted = args.slice(2);
276
281
  for (const item of inserted)
277
- rejectCircularInsertion(target, item, "Array.splice result", node);
282
+ rejectCircularInsertion(target, item, "Array.splice result");
278
283
  return wrap(target.items.splice(start, deleteCount, ...inserted));
279
284
  },
280
285
  ],
281
286
  [
282
287
  "toSpliced",
283
288
  2,
284
- (thisValue, args, node) => {
285
- const copied = [...self(thisValue, "toSpliced", node).items];
289
+ (thisValue, args) => {
290
+ const copied = [...self(thisValue, "toSpliced").items];
286
291
  if (args.length === 0)
287
292
  return wrap(copied);
288
- const start = optNumber("toSpliced", args[0], "start", node) ?? 0;
293
+ const start = optNumber("toSpliced", args[0], "start") ?? 0;
289
294
  if (args.length === 1)
290
295
  copied.splice(start);
291
296
  else
292
- copied.splice(start, optNumber("toSpliced", args[1], "delete count", node) ?? 0, ...args.slice(2));
297
+ copied.splice(start, optNumber("toSpliced", args[1], "delete count") ?? 0, ...args.slice(2));
293
298
  return wrap(copied);
294
299
  },
295
300
  ],
296
301
  [
297
302
  "fill",
298
303
  1,
299
- (thisValue, args, node) => {
300
- const target = self(thisValue, "fill", node);
301
- rejectCircularInsertion(target, args[0], "Array.fill result", node);
302
- target.items.fill(args[0], optNumber("fill", args[1], "start", node), optNumber("fill", args[2], "end", node));
304
+ (thisValue, args) => {
305
+ const target = self(thisValue, "fill");
306
+ rejectCircularInsertion(target, args[0], "Array.fill result");
307
+ target.items.fill(args[0], optNumber("fill", args[1], "start"), optNumber("fill", args[2], "end"));
303
308
  return target;
304
309
  },
305
310
  ],
306
311
  [
307
312
  "copyWithin",
308
313
  2,
309
- (thisValue, args, node) => {
310
- const target = self(thisValue, "copyWithin", node);
311
- target.items.copyWithin(optNumber("copyWithin", args[0], "target index", node) ?? 0, optNumber("copyWithin", args[1], "start", node) ?? 0, optNumber("copyWithin", args[2], "end", node));
314
+ (thisValue, args) => {
315
+ const target = self(thisValue, "copyWithin");
316
+ target.items.copyWithin(optNumber("copyWithin", args[0], "target index") ?? 0, optNumber("copyWithin", args[1], "start") ?? 0, optNumber("copyWithin", args[2], "end"));
312
317
  return target;
313
318
  },
314
319
  ],
315
- ["keys", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "keys", node).items.keys()))],
316
- ["values", 0, (thisValue, _, node) => wrap([...self(thisValue, "values", node).items])],
320
+ ["keys", 0, (thisValue) => wrap(Array.from(self(thisValue, "keys").items.keys()))],
321
+ ["values", 0, (thisValue) => wrap([...self(thisValue, "values").items])],
317
322
  [
318
323
  "entries",
319
324
  0,
320
- (thisValue, _, node) => wrap(Array.from(self(thisValue, "entries", node).items.entries(), ([index, item]) => wrap([index, item]))),
325
+ (thisValue) => wrap(Array.from(self(thisValue, "entries").items.entries(), ([index, item]) => wrap([index, item]))),
321
326
  ],
322
327
  iterate("map", 1, (target, receiver, apply) => Effect.gen(function* () {
323
328
  const length = target.length;
@@ -337,7 +342,7 @@ export const arrayGlobal = (runner) => {
337
342
  if (!(index in target))
338
343
  continue;
339
344
  const mapped = yield* apply([target[index], index, receiver]);
340
- if (mapped instanceof ProgramArray)
345
+ if (mapped instanceof Arr)
341
346
  values.push(...mapped.items);
342
347
  else
343
348
  values.push(mapped);
@@ -416,7 +421,7 @@ export const arrayGlobal = (runner) => {
416
421
  }
417
422
  return undefined;
418
423
  })),
419
- iterate("reduce", 1, (target, receiver, apply, args, node) => Effect.gen(function* () {
424
+ iterate("reduce", 1, (target, receiver, apply, args) => Effect.gen(function* () {
420
425
  const length = target.length;
421
426
  let start = 0;
422
427
  let accumulator = args[1];
@@ -424,7 +429,7 @@ export const arrayGlobal = (runner) => {
424
429
  while (start < length && !(start in target))
425
430
  start += 1;
426
431
  if (start === length) {
427
- throw new InterpreterRuntimeError("Array.reduce of an empty array with no initial value.", node);
432
+ throw typeError("Array.reduce of an empty array with no initial value.");
428
433
  }
429
434
  accumulator = target[start];
430
435
  start += 1;
@@ -436,14 +441,14 @@ export const arrayGlobal = (runner) => {
436
441
  }
437
442
  return accumulator;
438
443
  })),
439
- iterate("reduceRight", 1, (target, receiver, apply, args, node) => Effect.gen(function* () {
444
+ iterate("reduceRight", 1, (target, receiver, apply, args) => Effect.gen(function* () {
440
445
  let start = target.length - 1;
441
446
  let accumulator = args[1];
442
447
  if (args.length < 2) {
443
448
  while (start >= 0 && !(start in target))
444
449
  start -= 1;
445
450
  if (start < 0) {
446
- throw new InterpreterRuntimeError("Array.reduceRight of an empty array with no initial value.", node);
451
+ throw typeError("Array.reduceRight of an empty array with no initial value.");
447
452
  }
448
453
  accumulator = target[start];
449
454
  start -= 1;
@@ -0,0 +1,10 @@
1
+ import { Obj } from "../interpreter/objects.js";
2
+ import type { Interpreter } from "../interpreter/interpreter.js";
3
+ export declare const uint8ArrayGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
4
+ export declare const textEncoderGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
5
+ /** A `TextDecoder` holding the host decoder its label and options configured. */
6
+ export declare class TextDecoderObj extends Obj {
7
+ readonly decoder: TextDecoder;
8
+ constructor(proto: Obj, decoder: TextDecoder);
9
+ }
10
+ export declare const textDecoderGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;