@opencode/codemode 0.0.0-dev-19483 → 0.0.0-dev-19485
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/data.d.ts +4 -6
- package/dist/data.js +41 -18
- package/dist/interpreter/errors.js +3 -4
- package/dist/interpreter/methods.js +53 -55
- package/dist/interpreter/model.d.ts +2 -2
- package/dist/interpreter/objects.d.ts +25 -0
- package/dist/interpreter/objects.js +122 -0
- package/dist/interpreter/promises.js +7 -9
- package/dist/interpreter/references.d.ts +0 -1
- package/dist/interpreter/references.js +7 -17
- package/dist/interpreter/runner.js +7 -4
- package/dist/interpreter/runtime.js +71 -120
- package/dist/stdlib/array.js +12 -14
- package/dist/stdlib/collections.js +10 -9
- package/dist/stdlib/console.js +16 -14
- package/dist/stdlib/json.js +21 -36
- package/dist/stdlib/object.d.ts +2 -1
- package/dist/stdlib/object.js +21 -42
- package/dist/stdlib/regexp.d.ts +2 -1
- package/dist/stdlib/regexp.js +14 -20
- package/dist/stdlib/url.js +3 -3
- package/dist/stdlib/value.d.ts +3 -3
- package/dist/stdlib/value.js +25 -26
- package/dist/tool-runtime.d.ts +1 -1
- package/package.json +1 -1
package/dist/stdlib/array.js
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { HostFunction, sync, syncCall } from "../interpreter/host.js";
|
|
3
3
|
import { CodeModeGenerator, InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
+
import { get, ProgramArray, ProgramObject } from "../interpreter/objects.js";
|
|
4
5
|
import { describeValue } from "../interpreter/references.js";
|
|
5
6
|
import { applyCollectionCallback, preserveConsumerError } from "../interpreter/runner.js";
|
|
6
7
|
const constructArray = (args, node) => {
|
|
7
8
|
if (args.length !== 1)
|
|
8
|
-
return [...args];
|
|
9
|
+
return new ProgramArray([...args]);
|
|
9
10
|
const first = args[0];
|
|
10
11
|
if (typeof first !== "number")
|
|
11
|
-
return [first];
|
|
12
|
+
return new ProgramArray([first]);
|
|
12
13
|
if (!Number.isInteger(first) || first < 0 || first > 4294967295) {
|
|
13
14
|
throw new InterpreterRuntimeError("Invalid array length.", node).as("RangeError");
|
|
14
15
|
}
|
|
15
16
|
// Sparse like JS: Array(3) has holes, and combinator loops already skip them.
|
|
16
|
-
return new Array(first);
|
|
17
|
+
return new ProgramArray(new Array(first));
|
|
17
18
|
};
|
|
18
19
|
const arrayLikeSource = (source, node) => {
|
|
19
|
-
if (source
|
|
20
|
-
|
|
21
|
-
(Object.getPrototypeOf(source) === Object.prototype || Object.getPrototypeOf(source) === null) &&
|
|
22
|
-
typeof source.length === "number") {
|
|
23
|
-
const length = source.length;
|
|
20
|
+
if (source instanceof ProgramObject && typeof get(source, "length") === "number") {
|
|
21
|
+
const length = get(source, "length");
|
|
24
22
|
const normalized = Number.isNaN(length) || length <= 0 ? 0 : Math.trunc(length);
|
|
25
23
|
if (normalized > 4_294_967_295)
|
|
26
24
|
throw new RangeError("Invalid array length");
|
|
@@ -40,17 +38,17 @@ const arrayFrom = (runner, args, node) => {
|
|
|
40
38
|
const arrayLike = arrayLikeSource(source, node);
|
|
41
39
|
const values = [];
|
|
42
40
|
for (let index = 0; index < arrayLike.length; index += 1) {
|
|
43
|
-
const item =
|
|
41
|
+
const item = get(arrayLike.source, index);
|
|
44
42
|
values.push(apply === undefined ? item : yield* apply([item, index]));
|
|
45
43
|
}
|
|
46
|
-
return values;
|
|
44
|
+
return new ProgramArray(values);
|
|
47
45
|
}
|
|
48
46
|
const values = [];
|
|
49
47
|
let index = 0;
|
|
50
48
|
while (true) {
|
|
51
49
|
const step = yield* cursor.next;
|
|
52
50
|
if (step.done)
|
|
53
|
-
return values;
|
|
51
|
+
return new ProgramArray(values);
|
|
54
52
|
values.push(apply === undefined ? step.value : yield* preserveConsumerError(cursor, apply([step.value, index])));
|
|
55
53
|
index += 1;
|
|
56
54
|
}
|
|
@@ -61,10 +59,10 @@ export const arrayGlobal = (runner) => new HostFunction({
|
|
|
61
59
|
name: "Array",
|
|
62
60
|
call: syncCall(constructArray),
|
|
63
61
|
construct: syncCall(constructArray),
|
|
64
|
-
instanceOf: (value) =>
|
|
62
|
+
instanceOf: (value) => value instanceof ProgramArray,
|
|
65
63
|
members: {
|
|
66
|
-
isArray: sync("Array.isArray", (args) =>
|
|
67
|
-
of: sync("Array.of", (args) => [...args]),
|
|
64
|
+
isArray: sync("Array.isArray", (args) => args[0] instanceof ProgramArray),
|
|
65
|
+
of: sync("Array.of", (args) => new ProgramArray([...args])),
|
|
68
66
|
from: new HostFunction({ name: "Array.from", call: (args, node) => arrayFrom(runner, args, node) }),
|
|
69
67
|
},
|
|
70
68
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { HostFunction, requiresNew } from "../interpreter/host.js";
|
|
3
|
-
import { InterpreterRuntimeError
|
|
3
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
+
import { getOwn, ProgramArray, ProgramObject, set } from "../interpreter/objects.js";
|
|
4
5
|
import { describeValue, isRuntimeReference } from "../interpreter/references.js";
|
|
5
6
|
import { applyCollectionCallback, preserveConsumerError, toPrimitive } from "../interpreter/runner.js";
|
|
6
7
|
import { Values } from "../values.js";
|
|
@@ -94,13 +95,13 @@ export const groupBy = (runner, namespace) => new HostFunction({
|
|
|
94
95
|
const key = yield* preserveConsumerError(cursor, apply([item, index]));
|
|
95
96
|
const group = result.map.get(key);
|
|
96
97
|
if (group === undefined)
|
|
97
|
-
result.map.set(key, [item]);
|
|
98
|
+
result.map.set(key, new ProgramArray([item]));
|
|
98
99
|
else
|
|
99
|
-
group.push(item);
|
|
100
|
+
group.items.push(item);
|
|
100
101
|
index += 1;
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
|
-
const result =
|
|
104
|
+
const result = new ProgramObject();
|
|
104
105
|
let index = 0;
|
|
105
106
|
while (true) {
|
|
106
107
|
const step = yield* cursor.next;
|
|
@@ -108,11 +109,11 @@ export const groupBy = (runner, namespace) => new HostFunction({
|
|
|
108
109
|
return result;
|
|
109
110
|
const item = step.value;
|
|
110
111
|
const key = yield* preserveConsumerError(cursor, Effect.flatMap(apply([item, index]), (value) => coerceGroupByPropertyKey(runner, value, node)));
|
|
111
|
-
const group = result
|
|
112
|
+
const group = getOwn(result, key);
|
|
112
113
|
if (group === undefined)
|
|
113
|
-
result
|
|
114
|
+
set(result, key, new ProgramArray([item]));
|
|
114
115
|
else
|
|
115
|
-
group.push(item);
|
|
116
|
+
group.items.push(item);
|
|
116
117
|
index += 1;
|
|
117
118
|
}
|
|
118
119
|
});
|
|
@@ -132,10 +133,10 @@ const constructMap = (runner, init, node) => {
|
|
|
132
133
|
if (step.done)
|
|
133
134
|
return target;
|
|
134
135
|
yield* preserveConsumerError(cursor, Effect.sync(() => {
|
|
135
|
-
if (!
|
|
136
|
+
if (!(step.value instanceof ProgramObject)) {
|
|
136
137
|
throw new InterpreterRuntimeError("new Map(...) expects [key, value] pairs as entry objects.", node).as("TypeError");
|
|
137
138
|
}
|
|
138
|
-
target.map.set(step.value
|
|
139
|
+
target.map.set(getOwn(step.value, 0), getOwn(step.value, 1));
|
|
139
140
|
}));
|
|
140
141
|
}
|
|
141
142
|
});
|
package/dist/stdlib/console.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { toData, toProgram } from "../data.js";
|
|
2
2
|
import { HostNamespace, sync } from "../interpreter/host.js";
|
|
3
|
+
import { get, ownEntries, ProgramArray, ProgramObject } from "../interpreter/objects.js";
|
|
3
4
|
import { containsOpaqueReference, containsRuntimeReference, isRuntimeReference } from "../interpreter/references.js";
|
|
4
5
|
import { Values } from "../values.js";
|
|
5
6
|
import { coerceToString } from "./value.js";
|
|
@@ -54,8 +55,8 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
54
55
|
if (value instanceof Values.Map) {
|
|
55
56
|
seen.add(value);
|
|
56
57
|
try {
|
|
57
|
-
const entries = Array.from(value.map.entries(), ([key, item]) => [key, item]);
|
|
58
|
-
return `Map(${value.map.size}) ${formatConsoleValue(entries, seen, depth + 1)}`;
|
|
58
|
+
const entries = Array.from(value.map.entries(), ([key, item]) => new ProgramArray([key, item]));
|
|
59
|
+
return `Map(${value.map.size}) ${formatConsoleValue(new ProgramArray(entries), seen, depth + 1)}`;
|
|
59
60
|
}
|
|
60
61
|
finally {
|
|
61
62
|
seen.delete(value);
|
|
@@ -64,7 +65,7 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
64
65
|
if (value instanceof Values.Set) {
|
|
65
66
|
seen.add(value);
|
|
66
67
|
try {
|
|
67
|
-
return `Set(${value.set.size}) ${formatConsoleValue(
|
|
68
|
+
return `Set(${value.set.size}) ${formatConsoleValue(new ProgramArray([...value.set.values()]), seen, depth + 1)}`;
|
|
68
69
|
}
|
|
69
70
|
finally {
|
|
70
71
|
seen.delete(value);
|
|
@@ -74,10 +75,12 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
74
75
|
return "[opaque reference]";
|
|
75
76
|
seen.add(value);
|
|
76
77
|
try {
|
|
77
|
-
if (
|
|
78
|
-
return `[${value.map((item) => formatConsoleValue(item, seen, depth + 1)).join(",")}]`;
|
|
78
|
+
if (value instanceof ProgramArray) {
|
|
79
|
+
return `[${value.items.map((item) => formatConsoleValue(item, seen, depth + 1)).join(",")}]`;
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
+
if (!(value instanceof ProgramObject))
|
|
82
|
+
return "[object Object]";
|
|
83
|
+
return `{${ownEntries(value)
|
|
81
84
|
.map(([key, item]) => `${JSON.stringify(key)}:${formatConsoleValue(item, seen, depth + 1)}`)
|
|
82
85
|
.join(",")}}`;
|
|
83
86
|
}
|
|
@@ -109,20 +112,19 @@ const consoleTableColumns = (value) => {
|
|
|
109
112
|
return Array.isArray(columns) ? columns.map((column) => String(column)) : undefined;
|
|
110
113
|
};
|
|
111
114
|
const consoleTableRows = (data, columns) => {
|
|
112
|
-
if (
|
|
113
|
-
return data.map((item, index) => ({ index: String(index), values: consoleTableValues(item, columns) }));
|
|
115
|
+
if (data instanceof ProgramArray) {
|
|
116
|
+
return data.items.map((item, index) => ({ index: String(index), values: consoleTableValues(item, columns) }));
|
|
114
117
|
}
|
|
115
|
-
if (data
|
|
116
|
-
return
|
|
118
|
+
if (data instanceof ProgramObject) {
|
|
119
|
+
return ownEntries(data).map(([index, item]) => ({ index, values: consoleTableValues(item, columns) }));
|
|
117
120
|
}
|
|
118
121
|
return [{ index: "0", values: { Value: data } }];
|
|
119
122
|
};
|
|
120
123
|
const consoleTableValues = (value, columns) => {
|
|
121
|
-
if (value
|
|
122
|
-
const source = value;
|
|
124
|
+
if (value instanceof ProgramObject && !(value instanceof ProgramArray)) {
|
|
123
125
|
if (columns !== undefined)
|
|
124
|
-
return Object.fromEntries(columns.map((column) => [column,
|
|
125
|
-
return Object.fromEntries(
|
|
126
|
+
return Object.fromEntries(columns.map((column) => [column, get(value, column)]));
|
|
127
|
+
return Object.fromEntries(ownEntries(value));
|
|
126
128
|
}
|
|
127
129
|
return { Value: value };
|
|
128
130
|
};
|
package/dist/stdlib/json.js
CHANGED
|
@@ -4,6 +4,7 @@ import { applyCollectionCallback } from "../interpreter/runner.js";
|
|
|
4
4
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
5
5
|
import { typeofValue } from "../interpreter/references.js";
|
|
6
6
|
import { fromData, toData, toProgram } from "../data.js";
|
|
7
|
+
import { get, ownKeys, ProgramArray, ProgramObject, record, remove, set } from "../interpreter/objects.js";
|
|
7
8
|
import { Values } from "../values.js";
|
|
8
9
|
export const jsonGlobal = (runner) => new HostNamespace("JSON", {
|
|
9
10
|
parse: new HostFunction({ name: "JSON.parse", call: (args, node) => parse(runner, args, node) }),
|
|
@@ -24,40 +25,28 @@ const parse = (runner, args, node) => {
|
|
|
24
25
|
if (typeofValue(args[1]) !== "function")
|
|
25
26
|
return Effect.succeed(parsed);
|
|
26
27
|
const apply = applyCollectionCallback(runner, args[1], "JSON.parse", node);
|
|
27
|
-
const root = Object.create(null);
|
|
28
|
-
root[""] = parsed;
|
|
29
28
|
const visit = (holder, key) => Effect.gen(function* () {
|
|
30
|
-
const value = holder
|
|
31
|
-
if (
|
|
32
|
-
const
|
|
33
|
-
for (let index = 0; index < length; index += 1) {
|
|
34
|
-
const revived = yield* visit(value, String(index));
|
|
35
|
-
if (revived === undefined)
|
|
36
|
-
Reflect.deleteProperty(value, index);
|
|
37
|
-
else
|
|
38
|
-
value[index] = revived;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
else if (isPlainObject(value)) {
|
|
42
|
-
for (const name of Object.keys(value)) {
|
|
29
|
+
const value = get(holder, key);
|
|
30
|
+
if (value instanceof ProgramObject) {
|
|
31
|
+
for (const name of ownKeys(value)) {
|
|
43
32
|
const revived = yield* visit(value, name);
|
|
44
33
|
if (revived === undefined)
|
|
45
|
-
|
|
34
|
+
remove(value, name);
|
|
46
35
|
else
|
|
47
|
-
value
|
|
36
|
+
set(value, name, revived);
|
|
48
37
|
}
|
|
49
38
|
}
|
|
50
39
|
return yield* apply([key, value]);
|
|
51
40
|
});
|
|
52
|
-
return visit(
|
|
41
|
+
return visit(record({ "": parsed }), "");
|
|
53
42
|
};
|
|
54
43
|
const stringify = (runner, args, node) => {
|
|
55
44
|
const space = args[2];
|
|
56
45
|
const indent = typeof space === "number" || typeof space === "string" ? space : undefined;
|
|
57
46
|
const replacer = args[1];
|
|
58
47
|
if (typeofValue(replacer) !== "function") {
|
|
59
|
-
const properties =
|
|
60
|
-
? replacer
|
|
48
|
+
const properties = replacer instanceof ProgramArray
|
|
49
|
+
? replacer.items
|
|
61
50
|
.filter((item) => typeof item === "string" || typeof item === "number")
|
|
62
51
|
.map(String)
|
|
63
52
|
: null;
|
|
@@ -66,11 +55,9 @@ const stringify = (runner, args, node) => {
|
|
|
66
55
|
// Validate up front; the replacer walk below reads the original value.
|
|
67
56
|
toProgram(args[0], "JSON.stringify value");
|
|
68
57
|
const apply = applyCollectionCallback(runner, replacer, "JSON.stringify", node);
|
|
69
|
-
const root = Object.create(null);
|
|
70
|
-
root[""] = args[0];
|
|
71
58
|
const stack = new Set();
|
|
72
59
|
const visit = (holder, key) => Effect.gen(function* () {
|
|
73
|
-
const value = yield* apply([key, toJSONValue(holder
|
|
60
|
+
const value = yield* apply([key, toJSONValue(get(holder, key))]);
|
|
74
61
|
if (value === undefined || typeofValue(value) === "function")
|
|
75
62
|
return undefined;
|
|
76
63
|
toProgram(value, "JSON.stringify replacer result");
|
|
@@ -78,24 +65,23 @@ const stringify = (runner, args, node) => {
|
|
|
78
65
|
return Number.isFinite(value) ? value : null;
|
|
79
66
|
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
80
67
|
return value;
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
68
|
+
if (!(value instanceof ProgramObject))
|
|
69
|
+
return {};
|
|
70
|
+
if (stack.has(value))
|
|
71
|
+
throw new InterpreterRuntimeError("Converting circular structure to JSON.", node).as("TypeError");
|
|
72
|
+
stack.add(value);
|
|
73
|
+
if (value instanceof ProgramArray) {
|
|
85
74
|
const result = [];
|
|
86
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
75
|
+
for (let index = 0; index < value.items.length; index += 1) {
|
|
87
76
|
result.push((yield* visit(value, String(index))) ?? null);
|
|
88
77
|
}
|
|
89
78
|
stack.delete(value);
|
|
90
79
|
return result;
|
|
91
80
|
}
|
|
92
|
-
if (!isPlainObject(value))
|
|
93
|
-
return {};
|
|
94
|
-
if (stack.has(value))
|
|
95
|
-
throw new InterpreterRuntimeError("Converting circular structure to JSON.", node).as("TypeError");
|
|
96
|
-
stack.add(value);
|
|
97
81
|
const result = Object.create(null);
|
|
98
|
-
for (const name of
|
|
82
|
+
for (const name of ownKeys(value)) {
|
|
83
|
+
if (typeof name !== "string")
|
|
84
|
+
continue;
|
|
99
85
|
const item = yield* visit(value, name);
|
|
100
86
|
if (item !== undefined)
|
|
101
87
|
result[name] = item;
|
|
@@ -103,7 +89,7 @@ const stringify = (runner, args, node) => {
|
|
|
103
89
|
stack.delete(value);
|
|
104
90
|
return result;
|
|
105
91
|
});
|
|
106
|
-
return Effect.map(visit(
|
|
92
|
+
return Effect.map(visit(record({ "": args[0] }), ""), (value) => JSON.stringify(value, null, indent));
|
|
107
93
|
};
|
|
108
94
|
const toJSONValue = (value) => {
|
|
109
95
|
if (value instanceof Values.Date) {
|
|
@@ -113,4 +99,3 @@ const toJSONValue = (value) => {
|
|
|
113
99
|
return value.url.href;
|
|
114
100
|
return value;
|
|
115
101
|
};
|
|
116
|
-
const isPlainObject = (value) => value !== null && typeof value === "object" && !Values.isValue(value);
|
package/dist/stdlib/object.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HostFunction } from "../interpreter/host.js";
|
|
2
2
|
import { type AstNode } from "../interpreter/model.js";
|
|
3
|
+
import { ProgramObject } from "../interpreter/objects.js";
|
|
3
4
|
import { type Runner } from "../interpreter/runner.js";
|
|
4
|
-
export declare const enumerableSource: (label: string, value: unknown, node: AstNode) =>
|
|
5
|
+
export declare const enumerableSource: (label: string, value: unknown, node: AstNode) => ProgramObject;
|
|
5
6
|
export declare const objectAssign: (args: Array<unknown>, node: AstNode) => unknown;
|
|
6
7
|
export declare const objectGlobal: <R>(runner: Runner<R>, toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>) => HostFunction<R>;
|
package/dist/stdlib/object.js
CHANGED
|
@@ -2,14 +2,14 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { toProgram } from "../data.js";
|
|
3
3
|
import { HostFunction, sync, syncCall } from "../interpreter/host.js";
|
|
4
4
|
import { AsyncIteratorSymbol, InterpreterRuntimeError, IteratorSymbol } from "../interpreter/model.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getOwn, hasOwn, ownEntries, ownKeys, ProgramArray, ProgramObject, set } from "../interpreter/objects.js";
|
|
6
|
+
import { containsOpaqueReference, describeValue, rejectCircularInsertion, typeofValue, } from "../interpreter/references.js";
|
|
6
7
|
import { preserveConsumerError } from "../interpreter/runner.js";
|
|
7
8
|
import { ToolReference } from "../tool-runtime.js";
|
|
8
9
|
import { Values } from "../values.js";
|
|
9
10
|
import { groupBy } from "./collections.js";
|
|
10
11
|
import { coerceToString } from "./value.js";
|
|
11
|
-
// ToObject for enumeration.
|
|
12
|
-
// primitive string directly. Numbers, booleans, wrappers, and functions have no own enumerable keys.
|
|
12
|
+
// ToObject for enumeration.
|
|
13
13
|
export const enumerableSource = (label, value, node) => {
|
|
14
14
|
if (value === null || value === undefined) {
|
|
15
15
|
throw new InterpreterRuntimeError(`${label} cannot convert ${describeValue(value)} to an object.`, node).as("TypeError");
|
|
@@ -21,49 +21,35 @@ export const enumerableSource = (label, value, node) => {
|
|
|
21
21
|
throw new InterpreterRuntimeError(`${label} cannot read tool references: they are not plain data. Use Object.keys(tools) for names, or search({ query }) for signatures.`, node, "InvalidDataValue");
|
|
22
22
|
}
|
|
23
23
|
if (typeof value === "string")
|
|
24
|
+
return new ProgramArray([...value]);
|
|
25
|
+
if (value instanceof ProgramObject)
|
|
24
26
|
return value;
|
|
25
|
-
|
|
26
|
-
return {};
|
|
27
|
-
return value;
|
|
27
|
+
return new ProgramObject();
|
|
28
28
|
};
|
|
29
29
|
export const objectAssign = (args, node) => {
|
|
30
30
|
const target = args[0];
|
|
31
31
|
// JS would box a primitive target; wrappers and primitives cannot hold fields here.
|
|
32
|
-
if (
|
|
32
|
+
if (!(target instanceof ProgramObject)) {
|
|
33
33
|
throw new InterpreterRuntimeError(`Object.assign expects a data object or array target, received ${describeValue(target)}.`, node).as("TypeError");
|
|
34
34
|
}
|
|
35
|
-
const out = target;
|
|
36
35
|
const seen = new Set();
|
|
37
|
-
const guardedSet = (key, item) => {
|
|
38
|
-
// Arrays hold only indexed elements, as with direct assignment; Reflect.set would otherwise
|
|
39
|
-
// reach Array's length and Object.prototype's __proto__ setter.
|
|
40
|
-
if (Array.isArray(out) && (typeof key === "symbol" || parseArrayIndex(key) === undefined)) {
|
|
41
|
-
throw new InterpreterRuntimeError(`Object.assign cannot assign '${String(key)}' to an array: only array indexes may be assigned.`, node).as("TypeError");
|
|
42
|
-
}
|
|
43
|
-
rejectCircularInsertion(out, item, "Object.assign result", node, seen);
|
|
44
|
-
if (!Reflect.set(out, key, item))
|
|
45
|
-
throw new InterpreterRuntimeError(`Object.assign could not assign property '${String(key)}'.`, node).as("TypeError");
|
|
46
|
-
};
|
|
47
36
|
for (const source of args.slice(1)) {
|
|
48
37
|
if (source === null || source === undefined)
|
|
49
38
|
continue;
|
|
50
39
|
const from = enumerableSource("Object.assign(...)", source, node);
|
|
51
|
-
|
|
52
|
-
for (const [key, item] of Object.entries(from))
|
|
53
|
-
guardedSet(key, item);
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
for (const key of Reflect.ownKeys(from)) {
|
|
40
|
+
for (const key of ownKeys(from)) {
|
|
57
41
|
if (typeof key === "symbol" && key !== AsyncIteratorSymbol && key !== IteratorSymbol)
|
|
58
42
|
continue;
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
rejectCircularInsertion(target, getOwn(from, key), "Object.assign result", node, seen);
|
|
44
|
+
if (!set(target, key, getOwn(from, key))) {
|
|
45
|
+
throw new InterpreterRuntimeError("Invalid array length", node).as("RangeError");
|
|
46
|
+
}
|
|
61
47
|
}
|
|
62
48
|
}
|
|
63
|
-
return
|
|
49
|
+
return target;
|
|
64
50
|
};
|
|
65
51
|
const objectFromEntries = (runner, source, node) => {
|
|
66
|
-
const out =
|
|
52
|
+
const out = new ProgramObject();
|
|
67
53
|
return Effect.gen(function* () {
|
|
68
54
|
const cursor = yield* runner.syncIterator(source, node);
|
|
69
55
|
if (cursor === undefined) {
|
|
@@ -74,17 +60,10 @@ const objectFromEntries = (runner, source, node) => {
|
|
|
74
60
|
if (step.done)
|
|
75
61
|
return out;
|
|
76
62
|
yield* preserveConsumerError(cursor, Effect.sync(() => {
|
|
77
|
-
if (step.value
|
|
78
|
-
typeof step.value !== "object" ||
|
|
79
|
-
Values.isValue(step.value) ||
|
|
80
|
-
containsOpaqueReference(step.value)) {
|
|
63
|
+
if (!(step.value instanceof ProgramObject) || containsOpaqueReference(step.value)) {
|
|
81
64
|
throw new InterpreterRuntimeError("Object.fromEntries expects [key, value] entry objects.", node).as("TypeError");
|
|
82
65
|
}
|
|
83
|
-
|
|
84
|
-
toProgram(entry[0], "Object.fromEntries key");
|
|
85
|
-
toProgram(entry[1], "Object.fromEntries value");
|
|
86
|
-
const key = coerceToString(entry[0]);
|
|
87
|
-
out[key] = entry[1];
|
|
66
|
+
set(out, coerceToString(getOwn(step.value, 0)), getOwn(step.value, 1));
|
|
88
67
|
}));
|
|
89
68
|
}
|
|
90
69
|
});
|
|
@@ -92,7 +71,7 @@ const objectFromEntries = (runner, source, node) => {
|
|
|
92
71
|
const constructObject = (args, node) => {
|
|
93
72
|
const first = args[0];
|
|
94
73
|
if (first === null || first === undefined)
|
|
95
|
-
return
|
|
74
|
+
return new ProgramObject();
|
|
96
75
|
if (typeof first === "object")
|
|
97
76
|
return first;
|
|
98
77
|
throw new InterpreterRuntimeError(`Object(${typeof first}) wrapper objects are not supported; use the primitive value directly.`, node);
|
|
@@ -107,10 +86,10 @@ export const objectGlobal = (runner, toolKeys) => new HostFunction({
|
|
|
107
86
|
members: {
|
|
108
87
|
keys: sync("Object.keys", (args, node) => toProgram(args[0] instanceof ToolReference
|
|
109
88
|
? [...toolKeys(args[0].path)]
|
|
110
|
-
:
|
|
111
|
-
values: sync("Object.values", (args, node) =>
|
|
112
|
-
entries: sync("Object.entries", (args, node) =>
|
|
113
|
-
hasOwn: sync("Object.hasOwn", (args, node) =>
|
|
89
|
+
: ownKeys(enumerableSource("Object.keys(...)", args[0], node)).filter((key) => typeof key === "string"), "Object.keys result")),
|
|
90
|
+
values: sync("Object.values", (args, node) => new ProgramArray(ownEntries(enumerableSource("Object.values(...)", args[0], node)).map((entry) => entry[1]))),
|
|
91
|
+
entries: sync("Object.entries", (args, node) => new ProgramArray(ownEntries(enumerableSource("Object.entries(...)", args[0], node)).map((entry) => new ProgramArray(entry)))),
|
|
92
|
+
hasOwn: sync("Object.hasOwn", (args, node) => hasOwn(enumerableSource("Object.hasOwn(...)", args[0], node), args[1] === AsyncIteratorSymbol || args[1] === IteratorSymbol ? args[1] : String(args[1]))),
|
|
114
93
|
is: sync("Object.is", (args, node) => {
|
|
115
94
|
if (containsOpaqueReference(args[0]) || containsOpaqueReference(args[1])) {
|
|
116
95
|
throw new InterpreterRuntimeError("Object.is requires data values.", node, "InvalidDataValue");
|
package/dist/stdlib/regexp.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type AstNode } from "../interpreter/model.js";
|
|
2
|
+
import { ProgramArray } from "../interpreter/objects.js";
|
|
2
3
|
import { Values } from "../values.js";
|
|
3
4
|
export declare const regexpMethods: Set<string>;
|
|
4
5
|
export declare const regexpProperties: Set<string>;
|
|
5
6
|
export declare const toHostRegex: (arg: unknown, method: string, node: AstNode, extraFlags?: string) => RegExp;
|
|
6
|
-
export declare const matchToValue: (match: RegExpMatchArray) =>
|
|
7
|
+
export declare const matchToValue: (match: RegExpMatchArray) => ProgramArray;
|
|
7
8
|
export declare const constructRegExp: (args: Array<unknown>, node: AstNode) => Values.RegExp;
|
|
8
9
|
export declare const regexpGlobal: import("../interpreter/host.js").HostFunction<never>;
|
|
9
10
|
export declare const invokeRegExpMethod: (value: Values.RegExp, name: string, args: Array<unknown>, node: AstNode) => unknown;
|
package/dist/stdlib/regexp.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { sync, syncCall } from "../interpreter/host.js";
|
|
2
2
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
3
|
+
import { ProgramArray, record, set } from "../interpreter/objects.js";
|
|
3
4
|
import { Values } from "../values.js";
|
|
4
5
|
import { coerceToNumber, coerceToString } from "./value.js";
|
|
5
6
|
export const regexpMethods = new Set(["test", "exec", "toString"]);
|
|
@@ -35,18 +36,15 @@ export const toHostRegex = (arg, method, node, extraFlags = "") => {
|
|
|
35
36
|
throw new InterpreterRuntimeError(`String.${method} expects a regular expression (a /pattern/flags literal or new RegExp(...)) or a string pattern, not ${arg === null ? "null" : typeof arg}.`, node);
|
|
36
37
|
};
|
|
37
38
|
export const matchToValue = (match) => {
|
|
38
|
-
const result = Array.from(match, (group) => group);
|
|
39
|
+
const result = new ProgramArray(Array.from(match, (group) => group));
|
|
39
40
|
if (match.index !== undefined)
|
|
40
|
-
result
|
|
41
|
-
if (match.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
result.groups = groups;
|
|
47
|
-
}
|
|
41
|
+
set(result, "index", match.index);
|
|
42
|
+
if (match.input !== undefined)
|
|
43
|
+
set(result, "input", match.input);
|
|
44
|
+
if (match.groups)
|
|
45
|
+
set(result, "groups", record(match.groups));
|
|
48
46
|
if (match.indices)
|
|
49
|
-
result
|
|
47
|
+
set(result, "indices", indicesToValue(match.indices));
|
|
50
48
|
return result;
|
|
51
49
|
};
|
|
52
50
|
export const constructRegExp = (args, node) => {
|
|
@@ -112,15 +110,11 @@ const toLength = (value) => {
|
|
|
112
110
|
return Math.min(Math.floor(number), Number.MAX_SAFE_INTEGER);
|
|
113
111
|
};
|
|
114
112
|
const indicesToValue = (indices) => {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
result.groups = groups;
|
|
122
|
-
return result;
|
|
123
|
-
}
|
|
124
|
-
result.groups = undefined;
|
|
113
|
+
const range = (pair) => (pair === undefined ? undefined : new ProgramArray([...pair]));
|
|
114
|
+
const result = new ProgramArray(Array.from(indices, range));
|
|
115
|
+
const groups = indices.groups;
|
|
116
|
+
set(result, "groups", groups === undefined
|
|
117
|
+
? undefined
|
|
118
|
+
: record(Object.fromEntries(Object.entries(groups).map(([key, pair]) => [key, range(pair)]))));
|
|
125
119
|
return result;
|
|
126
120
|
};
|
package/dist/stdlib/url.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { toProgram } from "../data.js";
|
|
3
3
|
import { HostFunction, requiresNew, sync, syncCall } from "../interpreter/host.js";
|
|
4
4
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
5
|
+
import { ownEntries, ProgramObject } from "../interpreter/objects.js";
|
|
5
6
|
import { isRuntimeReference } from "../interpreter/references.js";
|
|
6
7
|
import { preserveConsumerError } from "../interpreter/runner.js";
|
|
7
8
|
import { Values } from "../values.js";
|
|
@@ -141,11 +142,10 @@ const constructURLSearchParams = (runner, init, node) => {
|
|
|
141
142
|
}
|
|
142
143
|
if (Values.isValue(init))
|
|
143
144
|
return new Values.URLSearchParams(new URLSearchParams());
|
|
144
|
-
|
|
145
|
-
if (data === null || typeof data !== "object") {
|
|
145
|
+
if (!(init instanceof ProgramObject)) {
|
|
146
146
|
throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.", node).as("TypeError");
|
|
147
147
|
}
|
|
148
|
-
return new Values.URLSearchParams(new URLSearchParams(Object.fromEntries(
|
|
148
|
+
return new Values.URLSearchParams(new URLSearchParams(Object.fromEntries(ownEntries(init).map(([key, value]) => [key, coerceToString(value)]))));
|
|
149
149
|
});
|
|
150
150
|
};
|
|
151
151
|
export const urlSearchParamsGlobal = (runner) => new HostFunction({
|
package/dist/stdlib/value.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type HostFunction, type SyncOptions } from "../interpreter/host.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ProgramError } from "../interpreter/objects.js";
|
|
3
3
|
export declare const errorConstructors: Set<string>;
|
|
4
4
|
export declare const compoundOperators: Set<string>;
|
|
5
|
-
export declare const createErrorValue: (name: string, message: string) =>
|
|
6
|
-
export declare const createAggregateErrorValue: (errors: Array<unknown>, message: string) =>
|
|
5
|
+
export declare const createErrorValue: (name: string, message: string) => ProgramError;
|
|
6
|
+
export declare const createAggregateErrorValue: (errors: Array<unknown>, message: string) => ProgramError;
|
|
7
7
|
export declare const errorBrandName: (value: unknown) => string | undefined;
|
|
8
8
|
export declare const coerceToString: (value: unknown) => string;
|
|
9
9
|
export declare const coerceToNumber: (value: unknown) => number;
|