@opencode/codemode 2.0.3 → 2.0.4
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.
- package/dist/codemode.d.ts +3 -0
- package/dist/codemode.js +12 -1
- package/dist/data.d.ts +14 -21
- package/dist/data.js +72 -140
- package/dist/extension.d.ts +11 -0
- package/dist/extension.js +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interpreter/callback.d.ts +20 -0
- package/dist/interpreter/{runner.js → callback.js} +14 -14
- package/dist/interpreter/errors.d.ts +12 -5
- package/dist/interpreter/errors.js +66 -54
- package/dist/interpreter/execute.d.ts +2 -2
- package/dist/interpreter/execute.js +15 -15
- package/dist/interpreter/extensions.d.ts +8 -0
- package/dist/interpreter/extensions.js +155 -0
- package/dist/interpreter/generators.d.ts +2 -3
- package/dist/interpreter/generators.js +10 -10
- package/dist/interpreter/globals.d.ts +4 -12
- package/dist/interpreter/globals.js +56 -49
- package/dist/interpreter/interpreter.d.ts +34 -0
- package/dist/interpreter/{runtime.js → interpreter.js} +250 -215
- package/dist/interpreter/intrinsics.d.ts +5 -5
- package/dist/interpreter/intrinsics.js +16 -10
- package/dist/interpreter/limits.d.ts +10 -0
- package/dist/interpreter/limits.js +19 -0
- package/dist/interpreter/model.d.ts +27 -14
- package/dist/interpreter/model.js +22 -14
- package/dist/interpreter/native.d.ts +12 -13
- package/dist/interpreter/native.js +17 -16
- package/dist/interpreter/objects.d.ts +55 -48
- package/dist/interpreter/objects.js +64 -44
- package/dist/interpreter/promises.d.ts +13 -15
- package/dist/interpreter/promises.js +89 -85
- package/dist/interpreter/references.d.ts +1 -2
- package/dist/interpreter/references.js +18 -16
- package/dist/interpreter/scope.js +6 -6
- package/dist/openapi/types.d.ts +1 -1
- package/dist/stdlib/array.d.ts +3 -4
- package/dist/stdlib/array.js +115 -110
- package/dist/stdlib/bytes.d.ts +10 -0
- package/dist/stdlib/bytes.js +228 -0
- package/dist/stdlib/collections.d.ts +4 -4
- package/dist/stdlib/collections.js +89 -89
- package/dist/stdlib/console.d.ts +5 -3
- package/dist/stdlib/console.js +30 -37
- package/dist/stdlib/date.d.ts +2 -2
- package/dist/stdlib/date.js +35 -35
- package/dist/stdlib/json.d.ts +3 -3
- package/dist/stdlib/json.js +29 -67
- package/dist/stdlib/math.d.ts +3 -3
- package/dist/stdlib/math.js +17 -21
- package/dist/stdlib/number.d.ts +3 -3
- package/dist/stdlib/number.js +32 -36
- package/dist/stdlib/object.d.ts +5 -5
- package/dist/stdlib/object.js +59 -62
- package/dist/stdlib/regexp.d.ts +7 -8
- package/dist/stdlib/regexp.js +40 -48
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +110 -88
- package/dist/stdlib/url.d.ts +4 -6
- package/dist/stdlib/url.js +86 -90
- package/dist/stdlib/value.d.ts +3 -3
- package/dist/stdlib/value.js +26 -24
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +22 -8
- package/dist/tool-runtime.d.ts +12 -5
- package/dist/tool-runtime.js +25 -11
- package/package.json +1 -1
- package/dist/interpreter/runner.d.ts +0 -28
- package/dist/interpreter/runtime.d.ts +0 -19
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ToolReference } from "../tool-runtime.js";
|
|
2
|
-
import {
|
|
3
|
-
import { Callable, getOwn, isWrapper, ownKeys,
|
|
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
|
|
6
|
+
value instanceof GeneratorObj ||
|
|
7
7
|
value instanceof ToolReference ||
|
|
8
|
-
value instanceof
|
|
8
|
+
value instanceof PromiseObj ||
|
|
9
9
|
isWrapper(value);
|
|
10
10
|
function* childValues(value) {
|
|
11
|
-
if (!(value instanceof
|
|
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,
|
|
40
|
+
export const rejectCircularInsertion = (container, value, label, seen = new Set()) => {
|
|
41
41
|
if (find(value, (current) => current === container, isRuntimeReference, seen)) {
|
|
42
|
-
throw
|
|
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
|
|
48
|
+
if (value instanceof Arr)
|
|
49
49
|
return "an array";
|
|
50
|
-
if (value instanceof
|
|
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
|
|
54
|
+
if (value instanceof DateObj)
|
|
55
55
|
return "a Date";
|
|
56
|
-
if (value instanceof
|
|
56
|
+
if (value instanceof RegExpObj)
|
|
57
57
|
return "a RegExp";
|
|
58
|
-
if (value instanceof
|
|
58
|
+
if (value instanceof MapObj)
|
|
59
59
|
return "a Map";
|
|
60
|
-
if (value instanceof
|
|
60
|
+
if (value instanceof SetObj)
|
|
61
61
|
return "a Set";
|
|
62
|
-
if (value instanceof
|
|
62
|
+
if (value instanceof URLObj)
|
|
63
63
|
return "a URL";
|
|
64
|
-
if (value instanceof
|
|
64
|
+
if (value instanceof URLSearchParamsObj)
|
|
65
65
|
return "a URLSearchParams";
|
|
66
|
-
if (value instanceof
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
66
|
+
throw typeError("Interpreter scope stack is empty.");
|
|
67
67
|
}
|
|
68
68
|
return scope;
|
|
69
69
|
}
|
package/dist/openapi/types.d.ts
CHANGED
|
@@ -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
|
|
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 = {
|
package/dist/stdlib/array.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
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>;
|
package/dist/stdlib/array.js
CHANGED
|
@@ -1,56 +1,55 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { constructor, methods, prototypeFrom, receiver } from "../interpreter/native.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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/
|
|
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
|
|
10
|
-
|
|
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
|
-
|
|
15
|
-
throw new RangeError("Invalid array length");
|
|
14
|
+
checkArrayLength(normalized);
|
|
16
15
|
return { length: normalized, source };
|
|
17
16
|
}
|
|
18
|
-
throw
|
|
17
|
+
throw invalidData(`Array.from expects an array, string, Map, Set, or array-like value, received ${describeValue(source)}.`);
|
|
19
18
|
};
|
|
20
|
-
const arrayFrom = (
|
|
19
|
+
const arrayFrom = (ctx, args) => {
|
|
21
20
|
const source = args[0];
|
|
22
|
-
const proto =
|
|
23
|
-
const apply = args.length < 2 || args[1] === undefined ? undefined : applyCollectionCallback(
|
|
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*
|
|
24
|
+
const cursor = yield* ctx.iterate(source);
|
|
26
25
|
if (cursor === undefined) {
|
|
27
|
-
if (source instanceof
|
|
28
|
-
throw
|
|
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
|
|
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
|
|
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
|
|
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 = (
|
|
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(
|
|
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 = (
|
|
81
|
-
const
|
|
82
|
-
const proto =
|
|
83
|
-
const wrap = (items) => new
|
|
84
|
-
const construct = (args, into
|
|
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
|
|
85
|
+
return new Arr(into, [...args]);
|
|
87
86
|
const first = args[0];
|
|
88
87
|
if (typeof first !== "number")
|
|
89
|
-
return new
|
|
90
|
-
if (!Number.isInteger(first) || first < 0 || first >
|
|
91
|
-
throw rangeError("Invalid array length."
|
|
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
|
|
92
|
+
return new Arr(into, new Array(first));
|
|
94
93
|
};
|
|
95
|
-
const array = constructor(
|
|
94
|
+
const array = constructor(builtins, proto, {
|
|
96
95
|
name: "Array",
|
|
97
96
|
length: 1,
|
|
98
|
-
call: (_, args
|
|
99
|
-
construct: (args, newTarget
|
|
97
|
+
call: (_, args) => Effect.sync(() => construct(args, proto)),
|
|
98
|
+
construct: (args, newTarget) => Effect.sync(() => construct(args, prototypeFrom(newTarget, proto))),
|
|
100
99
|
});
|
|
101
|
-
methods(
|
|
102
|
-
["isArray", 1, (_, args) => args[0] instanceof
|
|
100
|
+
methods(builtins, array, [
|
|
101
|
+
["isArray", 1, (_, args) => args[0] instanceof Arr],
|
|
103
102
|
["of", 0, (_, args) => wrap([...args])],
|
|
104
|
-
["from", 1, (_, args
|
|
103
|
+
["from", 1, (_, args) => arrayFrom(ctx, args)],
|
|
105
104
|
]);
|
|
106
|
-
const self = (thisValue, name
|
|
107
|
-
const optNumber = (name, value, label
|
|
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
|
|
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
|
|
120
|
-
const target = self(thisValue, name
|
|
121
|
-
return body(target.items, target, applyCollectionCallback(
|
|
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(
|
|
123
|
+
methods(builtins, proto, [
|
|
125
124
|
[
|
|
126
125
|
"join",
|
|
127
126
|
1,
|
|
128
|
-
(thisValue, args
|
|
129
|
-
const target = self(thisValue, "join"
|
|
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
|
|
130
|
+
throw typeError("Array.join expects zero arguments or one string separator.");
|
|
132
131
|
}
|
|
133
|
-
|
|
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
|
|
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
|
|
147
|
-
const target = self(thisValue, "includes"
|
|
149
|
+
(thisValue, args) => {
|
|
150
|
+
const target = self(thisValue, "includes").items;
|
|
148
151
|
if (args.length === 0 || args.length > 2) {
|
|
149
|
-
throw
|
|
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"
|
|
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
|
|
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
|
|
163
|
-
const target = self(thisValue, "lastIndexOf"
|
|
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"
|
|
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
|
|
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
|
|
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
|
|
188
|
-
const flatten = (items, depth) => items.flatMap((item) => (item instanceof
|
|
189
|
-
|
|
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
|
|
196
|
-
const target = self(thisValue, "reverse"
|
|
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
|
|
205
|
-
const target = self(thisValue, "sort"
|
|
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(
|
|
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
|
-
|
|
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
|
|
229
|
+
(thisValue, args) => Effect.map(sortArray(ctx, self(thisValue, "toSorted").items, args[0], "Array.toSorted"), wrap),
|
|
225
230
|
],
|
|
226
|
-
["toReversed", 0, (thisValue
|
|
231
|
+
["toReversed", 0, (thisValue) => wrap([...self(thisValue, "toReversed").items].reverse())],
|
|
227
232
|
[
|
|
228
233
|
"with",
|
|
229
234
|
2,
|
|
230
|
-
(thisValue, args
|
|
231
|
-
const target = self(thisValue, "with"
|
|
232
|
-
const index = optNumber("with", args[0], "index"
|
|
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."
|
|
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
|
|
245
|
-
const target = self(thisValue, "push"
|
|
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"
|
|
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
|
|
256
|
-
const target = self(thisValue, "unshift"
|
|
260
|
+
(thisValue, args) => {
|
|
261
|
+
const target = self(thisValue, "unshift");
|
|
257
262
|
for (const item of args)
|
|
258
|
-
rejectCircularInsertion(target, item, "Array.unshift result"
|
|
263
|
+
rejectCircularInsertion(target, item, "Array.unshift result");
|
|
259
264
|
return target.items.unshift(...args);
|
|
260
265
|
},
|
|
261
266
|
],
|
|
262
|
-
["pop", 0, (thisValue
|
|
263
|
-
["shift", 0, (thisValue
|
|
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
|
|
268
|
-
const target = self(thisValue, "splice"
|
|
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"
|
|
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"
|
|
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"
|
|
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
|
|
285
|
-
const copied = [...self(thisValue, "toSpliced"
|
|
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"
|
|
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"
|
|
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
|
|
300
|
-
const target = self(thisValue, "fill"
|
|
301
|
-
rejectCircularInsertion(target, args[0], "Array.fill result"
|
|
302
|
-
target.items.fill(args[0], optNumber("fill", args[1], "start"
|
|
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
|
|
310
|
-
const target = self(thisValue, "copyWithin"
|
|
311
|
-
target.items.copyWithin(optNumber("copyWithin", args[0], "target index"
|
|
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
|
|
316
|
-
["values", 0, (thisValue
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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>;
|