@opencode/codemode 2.0.0 → 2.0.2
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 +6 -5
- package/dist/data.js +47 -44
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/interpreter/errors.d.ts +5 -3
- package/dist/interpreter/errors.js +51 -22
- package/dist/interpreter/execute.js +5 -3
- package/dist/interpreter/generators.d.ts +4 -0
- package/dist/interpreter/generators.js +25 -0
- package/dist/interpreter/globals.js +69 -47
- package/dist/interpreter/intrinsics.d.ts +13 -0
- package/dist/interpreter/intrinsics.js +82 -0
- package/dist/interpreter/model.d.ts +13 -36
- package/dist/interpreter/model.js +15 -45
- package/dist/interpreter/native.d.ts +19 -0
- package/dist/interpreter/native.js +40 -0
- package/dist/interpreter/objects.d.ts +106 -13
- package/dist/interpreter/objects.js +192 -65
- package/dist/interpreter/promises.d.ts +12 -13
- package/dist/interpreter/promises.js +59 -54
- package/dist/interpreter/references.d.ts +1 -0
- package/dist/interpreter/references.js +20 -33
- package/dist/interpreter/runner.d.ts +15 -11
- package/dist/interpreter/runner.js +21 -21
- package/dist/interpreter/runtime.d.ts +3 -3
- package/dist/interpreter/runtime.js +165 -327
- package/dist/interpreter/scope.js +6 -6
- package/dist/stdlib/array.d.ts +4 -2
- package/dist/stdlib/array.js +424 -32
- package/dist/stdlib/collections.d.ts +3 -7
- package/dist/stdlib/collections.js +291 -119
- package/dist/stdlib/console.d.ts +3 -2
- package/dist/stdlib/console.js +35 -30
- package/dist/stdlib/date.d.ts +1 -7
- package/dist/stdlib/date.js +93 -188
- package/dist/stdlib/json.d.ts +2 -2
- package/dist/stdlib/json.js +27 -27
- package/dist/stdlib/math.d.ts +2 -2
- package/dist/stdlib/math.js +96 -76
- package/dist/stdlib/number.d.ts +3 -4
- package/dist/stdlib/number.js +95 -60
- package/dist/stdlib/object.d.ts +4 -4
- package/dist/stdlib/object.js +128 -54
- package/dist/stdlib/regexp.d.ts +6 -8
- package/dist/stdlib/regexp.js +76 -68
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +213 -50
- package/dist/stdlib/url.d.ts +5 -13
- package/dist/stdlib/url.js +202 -102
- package/dist/stdlib/value.d.ts +5 -9
- package/dist/stdlib/value.js +16 -38
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +12 -10
- package/dist/tool-runtime.d.ts +2 -1
- package/dist/tool-runtime.js +2 -2
- package/package.json +1 -1
- package/dist/interpreter/host.d.ts +0 -41
- package/dist/interpreter/host.js +0 -44
- package/dist/interpreter/methods.d.ts +0 -4
- package/dist/interpreter/methods.js +0 -837
- package/dist/values.d.ts +0 -37
- package/dist/values.js +0 -56
package/dist/data.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
export * as Data from "./data.js";
|
|
2
2
|
import type { DiagnosticKind } from "./codemode.js";
|
|
3
|
+
import type { Prototypes } from "./interpreter/intrinsics.js";
|
|
3
4
|
export declare class ToolRuntimeError extends Error {
|
|
4
5
|
readonly kind: Extract<DiagnosticKind, "UnknownTool" | "InvalidToolInput" | "InvalidToolOutput" | "InvalidDataValue" | "ToolCallLimitExceeded">;
|
|
5
6
|
readonly suggestions: ReadonlyArray<string>;
|
|
6
7
|
constructor(kind: Extract<DiagnosticKind, "UnknownTool" | "InvalidToolInput" | "InvalidToolOutput" | "InvalidDataValue" | "ToolCallLimitExceeded">, message: string, suggestions?: ReadonlyArray<string>);
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
|
-
* Brings a host-produced value into the program: program
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Brings a host-produced value into the program: program values pass through, host Date, RegExp,
|
|
11
|
+
* Map, Set, URL, and URLSearchParams become their built-in wrappers, and host objects and arrays
|
|
12
|
+
* are copied.
|
|
12
13
|
*/
|
|
13
|
-
export declare const toProgram: (value: unknown, label: string) => unknown;
|
|
14
|
+
export declare const toProgram: (protos: Prototypes, value: unknown, label: string) => unknown;
|
|
14
15
|
/**
|
|
15
16
|
* Brings host data into the program: Date and URL become strings, other host collections become
|
|
16
17
|
* empty objects, and objects become program copies. Used for tool results and parsed JSON.
|
|
17
18
|
*/
|
|
18
|
-
export declare const fromData: (value: unknown, label: string) => unknown;
|
|
19
|
+
export declare const fromData: (protos: Prototypes, value: unknown, label: string) => unknown;
|
|
19
20
|
/**
|
|
20
21
|
* Takes a program value out as plain JSON: runtime values serialize like `JSON.stringify` would,
|
|
21
22
|
* non-finite numbers become null, and array holes become null. `undefined` object properties are
|
package/dist/data.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * as Data from "./data.js";
|
|
2
|
-
import {
|
|
3
|
-
import { Values } from "./values.js";
|
|
2
|
+
import { Callable, define, entries, get, isWrapper, parseArrayIndex, ProgramArray, ProgramDate, ProgramError, ProgramGenerator, ProgramMap, ProgramObject, ProgramPromise, ProgramRegExp, ProgramSet, ProgramURL, ProgramURLSearchParams, } from "./interpreter/objects.js";
|
|
4
3
|
const MAX_VALUE_DEPTH = 32;
|
|
5
4
|
export class ToolRuntimeError extends Error {
|
|
6
5
|
kind;
|
|
@@ -13,16 +12,16 @@ export class ToolRuntimeError extends Error {
|
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
/**
|
|
16
|
-
* Brings a host-produced value into the program: program
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* Brings a host-produced value into the program: program values pass through, host Date, RegExp,
|
|
16
|
+
* Map, Set, URL, and URLSearchParams become their built-in wrappers, and host objects and arrays
|
|
17
|
+
* are copied.
|
|
19
18
|
*/
|
|
20
|
-
export const toProgram = (value, label) => copy(value, label, "program", 0, new Set());
|
|
19
|
+
export const toProgram = (protos, value, label) => copy(value, label, "program", 0, new Set(), protos);
|
|
21
20
|
/**
|
|
22
21
|
* Brings host data into the program: Date and URL become strings, other host collections become
|
|
23
22
|
* empty objects, and objects become program copies. Used for tool results and parsed JSON.
|
|
24
23
|
*/
|
|
25
|
-
export const fromData = (value, label) => copy(value, label, "data", 0, new Set());
|
|
24
|
+
export const fromData = (protos, value, label) => copy(value, label, "data", 0, new Set(), protos);
|
|
26
25
|
/**
|
|
27
26
|
* Takes a program value out as plain JSON: runtime values serialize like `JSON.stringify` would,
|
|
28
27
|
* non-finite numbers become null, and array holes become null. `undefined` object properties are
|
|
@@ -30,7 +29,8 @@ export const fromData = (value, label) => copy(value, label, "data", 0, new Set(
|
|
|
30
29
|
* undefined); a bare `undefined` follows the same rule.
|
|
31
30
|
*/
|
|
32
31
|
export const toData = (value, label, undefinedAs = "json") => copy(value, label, undefinedAs, 0, new Set());
|
|
33
|
-
const copy = (value, label, mode, depth, seen) => {
|
|
32
|
+
const copy = (value, label, mode, depth, seen, protos) => {
|
|
33
|
+
const next = (item) => copy(item, label, mode, depth + 1, seen, protos);
|
|
34
34
|
if (depth > MAX_VALUE_DEPTH) {
|
|
35
35
|
throw new ToolRuntimeError("InvalidDataValue", `${label} exceeds the maximum value depth of ${MAX_VALUE_DEPTH}.`);
|
|
36
36
|
}
|
|
@@ -43,85 +43,88 @@ const copy = (value, label, mode, depth, seen) => {
|
|
|
43
43
|
if (typeof value !== "object") {
|
|
44
44
|
throw new ToolRuntimeError("InvalidDataValue", `${label} must contain data only.`);
|
|
45
45
|
}
|
|
46
|
-
if (value instanceof
|
|
46
|
+
if (value instanceof ProgramPromise) {
|
|
47
47
|
throw new ToolRuntimeError("InvalidDataValue", `${label} contains an un-awaited Promise; await tool calls (e.g. \`const result = await tools.ns.tool(...)\`) before using their results.`);
|
|
48
48
|
}
|
|
49
|
-
if (value instanceof
|
|
49
|
+
if ((value instanceof Callable || value instanceof ProgramGenerator) && mode !== "program") {
|
|
50
50
|
throw new ToolRuntimeError("InvalidDataValue", `${label} must contain data only.`);
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (value instanceof ProgramObject || Values.isValue(value))
|
|
52
|
+
if (protos !== undefined && mode === "program") {
|
|
53
|
+
if (value instanceof ProgramObject)
|
|
55
54
|
return value;
|
|
56
55
|
if (value instanceof Date)
|
|
57
|
-
return new
|
|
56
|
+
return new ProgramDate(protos.Date, value.getTime());
|
|
58
57
|
if (value instanceof RegExp)
|
|
59
|
-
return new
|
|
58
|
+
return new ProgramRegExp(protos.RegExp, value.source, value.flags);
|
|
60
59
|
if (value instanceof Map) {
|
|
61
|
-
const wrapped = new
|
|
62
|
-
for (const [key, item] of value.entries())
|
|
63
|
-
wrapped.map.set(
|
|
64
|
-
}
|
|
60
|
+
const wrapped = new ProgramMap(protos.Map);
|
|
61
|
+
for (const [key, item] of value.entries())
|
|
62
|
+
wrapped.map.set(next(key), next(item));
|
|
65
63
|
return wrapped;
|
|
66
64
|
}
|
|
67
65
|
if (value instanceof Set) {
|
|
68
|
-
const wrapped = new
|
|
66
|
+
const wrapped = new ProgramSet(protos.Set);
|
|
69
67
|
for (const item of value.values())
|
|
70
|
-
wrapped.set.add(
|
|
68
|
+
wrapped.set.add(next(item));
|
|
71
69
|
return wrapped;
|
|
72
70
|
}
|
|
73
71
|
if (value instanceof URL)
|
|
74
|
-
return new
|
|
72
|
+
return new ProgramURL(protos.URL, protos.URLSearchParams, new URL(value.href));
|
|
75
73
|
if (value instanceof URLSearchParams)
|
|
76
|
-
return new
|
|
74
|
+
return new ProgramURLSearchParams(protos.URLSearchParams, new URLSearchParams(value));
|
|
77
75
|
}
|
|
78
|
-
if (value instanceof
|
|
76
|
+
if (value instanceof ProgramDate)
|
|
79
77
|
return Number.isFinite(value.time) ? new Date(value.time).toISOString() : null;
|
|
80
78
|
if (value instanceof Date)
|
|
81
79
|
return Number.isFinite(value.getTime()) ? value.toISOString() : null;
|
|
82
|
-
if (value instanceof
|
|
80
|
+
if (value instanceof ProgramURL)
|
|
83
81
|
return value.url.href;
|
|
84
82
|
if (value instanceof URL)
|
|
85
83
|
return value.href;
|
|
86
|
-
// Remaining
|
|
87
|
-
if (
|
|
84
|
+
// Remaining wrappers and their host counterparts serialize as empty objects, like JSON.stringify.
|
|
85
|
+
if (isWrapper(value) ||
|
|
88
86
|
value instanceof RegExp ||
|
|
89
87
|
value instanceof Map ||
|
|
90
88
|
value instanceof Set ||
|
|
91
89
|
value instanceof URLSearchParams) {
|
|
92
|
-
return
|
|
90
|
+
return protos !== undefined ? new ProgramObject(protos.Object) : {};
|
|
93
91
|
}
|
|
94
92
|
if (seen.has(value)) {
|
|
95
93
|
throw new ToolRuntimeError("InvalidDataValue", `${label} contains a circular value.`);
|
|
96
94
|
}
|
|
97
95
|
seen.add(value);
|
|
98
96
|
if (value instanceof ProgramArray) {
|
|
99
|
-
const copied = Array.from(value.items, (item) =>
|
|
97
|
+
const copied = Array.from(value.items, (item) => next(item) ?? null);
|
|
100
98
|
seen.delete(value);
|
|
101
99
|
return copied;
|
|
102
100
|
}
|
|
103
101
|
if (value instanceof ProgramObject) {
|
|
104
102
|
const copied = {};
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
// Errors serialize as { name, message, ...own }: both may be inherited, and neither is enumerable in JS.
|
|
104
|
+
if (value instanceof ProgramError) {
|
|
105
|
+
defineHost(copied, "name", next(get(value, "name")));
|
|
106
|
+
defineHost(copied, "message", next(get(value, "message")));
|
|
107
|
+
}
|
|
108
|
+
for (const [key, item] of entries(value)) {
|
|
109
|
+
const copiedItem = next(item);
|
|
110
|
+
if (copiedItem === undefined && mode === "json")
|
|
108
111
|
continue;
|
|
109
|
-
|
|
112
|
+
defineHost(copied, key, copiedItem);
|
|
110
113
|
}
|
|
111
114
|
seen.delete(value);
|
|
112
115
|
return copied;
|
|
113
116
|
}
|
|
114
117
|
if (Array.isArray(value)) {
|
|
115
|
-
if (
|
|
116
|
-
const copied = new ProgramArray(value.map(
|
|
118
|
+
if (protos !== undefined) {
|
|
119
|
+
const copied = new ProgramArray(protos.Array, value.map(next));
|
|
117
120
|
for (const [key, item] of Object.entries(value)) {
|
|
118
121
|
if (parseArrayIndex(key) === undefined)
|
|
119
|
-
|
|
122
|
+
define(copied, key, next(item));
|
|
120
123
|
}
|
|
121
124
|
seen.delete(value);
|
|
122
125
|
return copied;
|
|
123
126
|
}
|
|
124
|
-
const copied = Array.from(value, (item) =>
|
|
127
|
+
const copied = Array.from(value, (item) => next(item) ?? null);
|
|
125
128
|
seen.delete(value);
|
|
126
129
|
return copied;
|
|
127
130
|
}
|
|
@@ -129,25 +132,25 @@ const copy = (value, label, mode, depth, seen) => {
|
|
|
129
132
|
if (prototype !== Object.prototype && prototype !== null) {
|
|
130
133
|
throw new ToolRuntimeError("InvalidDataValue", `${label} must contain plain objects only.`);
|
|
131
134
|
}
|
|
132
|
-
if (
|
|
133
|
-
const copied = new ProgramObject();
|
|
135
|
+
if (protos !== undefined) {
|
|
136
|
+
const copied = new ProgramObject(protos.Object);
|
|
134
137
|
for (const [key, item] of Object.entries(value))
|
|
135
|
-
|
|
138
|
+
define(copied, key, next(item));
|
|
136
139
|
seen.delete(value);
|
|
137
140
|
return copied;
|
|
138
141
|
}
|
|
139
142
|
const copied = {};
|
|
140
143
|
for (const [key, item] of Object.entries(value)) {
|
|
141
|
-
const
|
|
142
|
-
if (
|
|
144
|
+
const copiedItem = next(item);
|
|
145
|
+
if (copiedItem === undefined && mode === "json")
|
|
143
146
|
continue;
|
|
144
|
-
|
|
147
|
+
defineHost(copied, key, copiedItem);
|
|
145
148
|
}
|
|
146
149
|
seen.delete(value);
|
|
147
150
|
return copied;
|
|
148
151
|
};
|
|
149
152
|
// Own data property regardless of the target's prototype, so a "__proto__" key on a host object
|
|
150
153
|
// never reaches the Object.prototype setter.
|
|
151
|
-
const
|
|
154
|
+
const defineHost = (target, key, value) => {
|
|
152
155
|
Object.defineProperty(target, key, { value, enumerable: true, writable: true, configurable: true });
|
|
153
156
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,5 @@ export * as CodeMode from "./codemode.js";
|
|
|
2
2
|
export * as Namespace from "./namespace.js";
|
|
3
3
|
export * as Tool from "./tool.js";
|
|
4
4
|
export * as OpenAPI from "./openapi/index.js";
|
|
5
|
-
export { Values } from "./values.js";
|
|
6
5
|
export { searchSignature, toolExpression } from "./codemode.js";
|
|
7
6
|
export { ToolError, toolError } from "./tool-error.js";
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,5 @@ export * as CodeMode from "./codemode.js";
|
|
|
2
2
|
export * as Namespace from "./namespace.js";
|
|
3
3
|
export * as Tool from "./tool.js";
|
|
4
4
|
export * as OpenAPI from "./openapi/index.js";
|
|
5
|
-
export { Values } from "./values.js";
|
|
6
5
|
export { searchSignature, toolExpression } from "./codemode.js";
|
|
7
6
|
export { ToolError, toolError } from "./tool-error.js";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Diagnostic } from "../codemode.js";
|
|
2
|
-
import {
|
|
2
|
+
import { type ErrorType } from "./intrinsics.js";
|
|
3
|
+
import { type NativeFunction, ProgramError, ProgramObject } from "./objects.js";
|
|
3
4
|
import { type Runner } from "./runner.js";
|
|
4
5
|
export declare const normalizeError: (error: unknown) => Diagnostic;
|
|
5
|
-
export declare const caughtErrorValue: (thrown: unknown) => unknown;
|
|
6
|
+
export declare const caughtErrorValue: <R>(runner: Runner<R>, thrown: unknown) => unknown;
|
|
7
|
+
export declare const createAggregateErrorValue: <R>(runner: Runner<R>, errors: Array<unknown>, message: string, proto?: ProgramObject) => ProgramError;
|
|
6
8
|
/** An error constructor such as `Error` or `TypeError`; callable with or without `new`, like JS. */
|
|
7
|
-
export declare const errorGlobal: <R>(
|
|
9
|
+
export declare const errorGlobal: <R>(type: ErrorType, runner: Runner<R>) => NativeFunction<R>;
|
|
@@ -3,10 +3,11 @@ import { ToolError } from "../tool-error.js";
|
|
|
3
3
|
import { toData, ToolRuntimeError } from "../data.js";
|
|
4
4
|
import { formatLocation, InterpreterRuntimeError, ProgramThrow, sourceLocation } from "./model.js";
|
|
5
5
|
import { containsRuntimeReference } from "./references.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { createErrorValue, isErrorType } from "./intrinsics.js";
|
|
7
|
+
import { constructor, methods, prototypeFrom, receiver } from "./native.js";
|
|
8
|
+
import { define, get, hidden, ProgramArray, ProgramError, ProgramObject, } from "./objects.js";
|
|
8
9
|
import {} from "./runner.js";
|
|
9
|
-
import { coerceToString
|
|
10
|
+
import { coerceToString } from "../stdlib/value.js";
|
|
10
11
|
export const normalizeError = (error) => {
|
|
11
12
|
if (error instanceof InterpreterRuntimeError) {
|
|
12
13
|
return {
|
|
@@ -66,41 +67,69 @@ export const normalizeError = (error) => {
|
|
|
66
67
|
message: String(error),
|
|
67
68
|
};
|
|
68
69
|
};
|
|
69
|
-
export const caughtErrorValue = (thrown) => {
|
|
70
|
+
export const caughtErrorValue = (runner, thrown) => {
|
|
70
71
|
if (thrown instanceof ProgramThrow)
|
|
71
72
|
return thrown.value;
|
|
73
|
+
const prototypes = runner.prototypes;
|
|
72
74
|
if (thrown instanceof InterpreterRuntimeError)
|
|
73
|
-
return createErrorValue(thrown.
|
|
74
|
-
const
|
|
75
|
-
return createErrorValue(
|
|
75
|
+
return createErrorValue(prototypes[thrown.type], thrown.message);
|
|
76
|
+
const type = thrown instanceof Error && isErrorType(thrown.name) ? thrown.name : "Error";
|
|
77
|
+
return createErrorValue(prototypes[type], normalizeError(thrown).message);
|
|
76
78
|
};
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
+
export const createAggregateErrorValue = (runner, errors, message, proto = runner.prototypes.AggregateError) => {
|
|
80
|
+
const value = createErrorValue(proto, message);
|
|
81
|
+
define(value, "errors", new ProgramArray(runner.prototypes.Array, errors), { ...hidden });
|
|
82
|
+
return value;
|
|
83
|
+
};
|
|
84
|
+
const constructAggregateErrorValue = (runner, args, proto, node) => Effect.gen(function* () {
|
|
79
85
|
const cursor = yield* runner.syncIterator(args[0], node);
|
|
80
86
|
if (cursor === undefined) {
|
|
81
|
-
throw new InterpreterRuntimeError("new AggregateError(...) expects a synchronous iterable of errors.", node)
|
|
87
|
+
throw new InterpreterRuntimeError("new AggregateError(...) expects a synchronous iterable of errors.", node);
|
|
82
88
|
}
|
|
83
89
|
const errors = [];
|
|
84
90
|
while (true) {
|
|
85
91
|
const step = yield* cursor.next;
|
|
86
92
|
if (step.done) {
|
|
87
|
-
return createAggregateErrorValue(errors, args[1] === undefined ? "" : coerceToString(args[1]));
|
|
93
|
+
return createAggregateErrorValue(runner, errors, args[1] === undefined ? "" : coerceToString(args[1]), proto);
|
|
88
94
|
}
|
|
89
95
|
errors.push(step.value);
|
|
90
96
|
}
|
|
91
97
|
});
|
|
92
98
|
/** An error constructor such as `Error` or `TypeError`; callable with or without `new`, like JS. */
|
|
93
|
-
export const errorGlobal = (
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
export const errorGlobal = (type, runner) => {
|
|
100
|
+
const protos = runner.prototypes;
|
|
101
|
+
const prototype = protos[type];
|
|
102
|
+
const construct = (args, newTarget, node) => {
|
|
103
|
+
const proto = prototypeFrom(newTarget, prototype);
|
|
104
|
+
return type === "AggregateError"
|
|
105
|
+
? constructAggregateErrorValue(runner, args, proto, node)
|
|
106
|
+
: Effect.sync(() => createErrorValue(proto, args[0] === undefined ? undefined : coerceToString(args[0])));
|
|
107
|
+
};
|
|
108
|
+
const ctor = constructor(protos, prototype, {
|
|
109
|
+
name: type,
|
|
110
|
+
length: type === "AggregateError" ? 2 : 1,
|
|
111
|
+
call: (_, args, node) => construct(args, ctor, node),
|
|
100
112
|
construct,
|
|
101
|
-
instanceOf: (value) => {
|
|
102
|
-
const brand = errorBrandName(value);
|
|
103
|
-
return brand !== undefined && (name === "Error" || brand === name);
|
|
104
|
-
},
|
|
105
113
|
});
|
|
114
|
+
if (type === "Error") {
|
|
115
|
+
methods(protos, prototype, [
|
|
116
|
+
[
|
|
117
|
+
"toString",
|
|
118
|
+
0,
|
|
119
|
+
(thisValue, _, node) => {
|
|
120
|
+
const self = receiver(ProgramObject, thisValue, "Error.prototype.toString", node);
|
|
121
|
+
const name = get(self, "name");
|
|
122
|
+
const message = get(self, "message");
|
|
123
|
+
const shownName = name === undefined ? "Error" : coerceToString(name);
|
|
124
|
+
const shownMessage = message === undefined ? "" : coerceToString(message);
|
|
125
|
+
if (shownMessage === "")
|
|
126
|
+
return shownName;
|
|
127
|
+
if (shownName === "")
|
|
128
|
+
return shownMessage;
|
|
129
|
+
return `${shownName}: ${shownMessage}`;
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
]);
|
|
133
|
+
}
|
|
134
|
+
return ctor;
|
|
106
135
|
};
|
|
@@ -6,6 +6,7 @@ import { transpile } from "#transpile";
|
|
|
6
6
|
import { toData } from "../data.js";
|
|
7
7
|
import { ToolRuntime } from "../tool-runtime.js";
|
|
8
8
|
import { normalizeError } from "./errors.js";
|
|
9
|
+
import { createPrototypes } from "./intrinsics.js";
|
|
9
10
|
import { InterpreterRuntimeError } from "./model.js";
|
|
10
11
|
import { PromiseRuntime } from "./promises.js";
|
|
11
12
|
import { Runtime } from "./runtime.js";
|
|
@@ -19,15 +20,16 @@ export const executeProgram = (code, prepared, limits, hooks, extraGlobals) => {
|
|
|
19
20
|
}
|
|
20
21
|
// Allocate execution state inside suspension so reused Effects never share it.
|
|
21
22
|
return Effect.suspend(() => {
|
|
22
|
-
const
|
|
23
|
+
const prototypes = createPrototypes();
|
|
24
|
+
const tools = ToolRuntime.make(prepared, prototypes, limits.maxToolCalls, hooks);
|
|
23
25
|
const logs = [];
|
|
24
26
|
const logged = () => (logs.length > 0 ? { logs: [...logs] } : {});
|
|
25
27
|
// Set only after copy-out so timeouts cannot report invalid values as completed.
|
|
26
28
|
let returned;
|
|
27
29
|
const base = Effect.acquireUseRelease(Scope.make("parallel"), (scope) => Effect.gen(function* () {
|
|
28
30
|
const program = parseProgram(code);
|
|
29
|
-
const promises = new PromiseRuntime(scope);
|
|
30
|
-
const value = yield* new Runtime(tools.execute, tools.search, tools.keys, promises, logs, extraGlobals).run(program);
|
|
31
|
+
const promises = new PromiseRuntime(scope, prototypes.Promise);
|
|
32
|
+
const value = yield* new Runtime(tools.execute, tools.search, tools.keys, promises, prototypes, logs, extraGlobals).run(program);
|
|
31
33
|
const result = toData(value, "Execution result", "result");
|
|
32
34
|
returned = { value: result, promises };
|
|
33
35
|
const warnings = yield* promises.interrupt();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PromiseRuntime } from "./promises.js";
|
|
2
|
+
import type { Runner } from "./runner.js";
|
|
3
|
+
/** `next`/`return`/`throw` on the generator prototypes; async generators answer with promises. */
|
|
4
|
+
export declare const generatorGlobals: <R>(runner: Runner<R>, promises: PromiseRuntime<R>) => void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { fn, methods, receiver } from "./native.js";
|
|
3
|
+
import { AsyncIteratorSymbol, IteratorSymbol } from "./model.js";
|
|
4
|
+
import { define, hidden, ProgramGenerator } from "./objects.js";
|
|
5
|
+
/** `next`/`return`/`throw` on the generator prototypes; async generators answer with promises. */
|
|
6
|
+
export const generatorGlobals = (runner, promises) => {
|
|
7
|
+
const protos = runner.prototypes;
|
|
8
|
+
const install = (asynchronous) => {
|
|
9
|
+
const proto = asynchronous ? protos.AsyncGenerator : protos.Generator;
|
|
10
|
+
const label = asynchronous ? "AsyncGenerator" : "Generator";
|
|
11
|
+
const request = (kind) => [
|
|
12
|
+
kind,
|
|
13
|
+
1,
|
|
14
|
+
(thisValue, args, node) => {
|
|
15
|
+
const generator = receiver(ProgramGenerator, thisValue, `${label}.prototype.${kind}`, node);
|
|
16
|
+
const requested = generator.request(kind, args[0], node);
|
|
17
|
+
return generator.asynchronous ? promises.create(requested) : requested;
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
methods(protos, proto, [request("next"), request("return"), request("throw")]);
|
|
21
|
+
define(asynchronous ? protos.AsyncIterator : protos.Iterator, asynchronous ? AsyncIteratorSymbol : IteratorSymbol, fn(protos, asynchronous ? "[Symbol.asyncIterator]" : "[Symbol.iterator]", 0, (thisValue) => thisValue), hidden);
|
|
22
|
+
};
|
|
23
|
+
install(false);
|
|
24
|
+
install(true);
|
|
25
|
+
};
|
|
@@ -5,59 +5,81 @@ import { consoleGlobal } from "../stdlib/console.js";
|
|
|
5
5
|
import { dateGlobal } from "../stdlib/date.js";
|
|
6
6
|
import { jsonGlobal } from "../stdlib/json.js";
|
|
7
7
|
import { mathGlobal } from "../stdlib/math.js";
|
|
8
|
-
import { numberGlobal } from "../stdlib/number.js";
|
|
8
|
+
import { booleanGlobal, numberGlobal } from "../stdlib/number.js";
|
|
9
9
|
import { objectGlobal } from "../stdlib/object.js";
|
|
10
10
|
import { regexpGlobal } from "../stdlib/regexp.js";
|
|
11
11
|
import { stringGlobal } from "../stdlib/string.js";
|
|
12
12
|
import { uriGlobal, urlGlobal, urlSearchParamsGlobal } from "../stdlib/url.js";
|
|
13
|
-
import { coercion
|
|
14
|
-
import {
|
|
13
|
+
import { coercion } from "../stdlib/value.js";
|
|
14
|
+
import { base64Global, cryptoGlobal } from "../stdlib/web.js";
|
|
15
15
|
import { ToolReference } from "../tool-runtime.js";
|
|
16
16
|
import { errorGlobal } from "./errors.js";
|
|
17
|
-
import {
|
|
17
|
+
import { errorTypes } from "./intrinsics.js";
|
|
18
|
+
import { constants, constructor, native } from "./native.js";
|
|
18
19
|
import { AsyncIteratorSymbol, InterpreterRuntimeError, IteratorSymbol } from "./model.js";
|
|
20
|
+
import { generatorGlobals } from "./generators.js";
|
|
19
21
|
import { promiseGlobal } from "./promises.js";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
throw new InterpreterRuntimeError("
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
// Function.prototype.constructor exists so `fn.constructor === Function` holds; dynamic code is unsupported.
|
|
23
|
+
const functionGlobal = (runner) => {
|
|
24
|
+
const reject = (_, __, node) => Effect.sync(() => {
|
|
25
|
+
throw new InterpreterRuntimeError("The Function constructor is not supported; write the function inline.", node);
|
|
26
|
+
});
|
|
27
|
+
return constructor(runner.prototypes, runner.prototypes.Function, {
|
|
28
|
+
name: "Function",
|
|
29
|
+
length: 1,
|
|
30
|
+
call: reject,
|
|
31
|
+
construct: (args, _, node) => reject(undefined, args, node),
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const symbolGlobal = (runner) => {
|
|
35
|
+
const symbol = native(runner.prototypes, {
|
|
36
|
+
name: "Symbol",
|
|
37
|
+
call: (_, __, node) => Effect.sync(() => {
|
|
38
|
+
throw new InterpreterRuntimeError("Symbol is not callable; only Symbol.asyncIterator and Symbol.iterator are available.", node);
|
|
39
|
+
}),
|
|
40
|
+
callback: false,
|
|
41
|
+
});
|
|
42
|
+
constants(symbol, { asyncIterator: AsyncIteratorSymbol, iterator: IteratorSymbol });
|
|
43
|
+
return symbol;
|
|
44
|
+
};
|
|
28
45
|
/** The immutable global bindings of every program, in declaration order. */
|
|
29
|
-
export const globals = (host) =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]
|
|
46
|
+
export const globals = (host) => {
|
|
47
|
+
const runner = host.runner;
|
|
48
|
+
generatorGlobals(runner, host.promises);
|
|
49
|
+
return [
|
|
50
|
+
["tools", new ToolReference([])],
|
|
51
|
+
["search", native(runner.prototypes, { name: "search", call: (_, args) => host.search(args), callback: false })],
|
|
52
|
+
["undefined", undefined],
|
|
53
|
+
["NaN", NaN],
|
|
54
|
+
["Infinity", Infinity],
|
|
55
|
+
["Object", objectGlobal(runner, host.toolKeys)],
|
|
56
|
+
["Function", functionGlobal(runner)],
|
|
57
|
+
["Array", arrayGlobal(runner)],
|
|
58
|
+
["Math", mathGlobal(runner)],
|
|
59
|
+
["JSON", jsonGlobal(runner)],
|
|
60
|
+
["console", consoleGlobal(runner, host.logs)],
|
|
61
|
+
["Promise", promiseGlobal(runner, host.promises)],
|
|
62
|
+
["Symbol", symbolGlobal(runner)],
|
|
63
|
+
["Number", numberGlobal(runner)],
|
|
64
|
+
["String", stringGlobal(runner)],
|
|
65
|
+
["Boolean", booleanGlobal(runner)],
|
|
66
|
+
["parseInt", coercion(runner, "parseInt", 2)],
|
|
67
|
+
["parseFloat", coercion(runner, "parseFloat")],
|
|
68
|
+
["isFinite", coercion(runner, "isFinite")],
|
|
69
|
+
["isNaN", coercion(runner, "isNaN")],
|
|
70
|
+
["Date", dateGlobal(runner)],
|
|
71
|
+
["RegExp", regexpGlobal(runner)],
|
|
72
|
+
["Map", mapGlobal(runner)],
|
|
73
|
+
["Set", setGlobal(runner)],
|
|
74
|
+
["URL", urlGlobal(runner)],
|
|
75
|
+
["URLSearchParams", urlSearchParamsGlobal(runner)],
|
|
76
|
+
["encodeURI", uriGlobal(runner, "encodeURI")],
|
|
77
|
+
["encodeURIComponent", uriGlobal(runner, "encodeURIComponent")],
|
|
78
|
+
["decodeURI", uriGlobal(runner, "decodeURI")],
|
|
79
|
+
["decodeURIComponent", uriGlobal(runner, "decodeURIComponent")],
|
|
80
|
+
["atob", base64Global(runner, "atob")],
|
|
81
|
+
["btoa", base64Global(runner, "btoa")],
|
|
82
|
+
["crypto", cryptoGlobal(runner)],
|
|
83
|
+
...errorTypes.map((type) => [type, errorGlobal(type, runner)]),
|
|
84
|
+
];
|
|
85
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProgramError, ProgramObject } from "./objects.js";
|
|
2
|
+
export declare const errorTypes: readonly ["Error", "TypeError", "RangeError", "SyntaxError", "ReferenceError", "EvalError", "URIError", "AggregateError"];
|
|
3
|
+
export type ErrorType = (typeof errorTypes)[number];
|
|
4
|
+
export declare const isErrorType: (name: string) => name is ErrorType;
|
|
5
|
+
declare const builtins: readonly ["Object", "Function", "Array", "String", "Number", "Boolean", "Date", "RegExp", "Map", "Set", "URL", "URLSearchParams", "Promise", "Iterator", "AsyncIterator", "Generator", "AsyncGenerator"];
|
|
6
|
+
/**
|
|
7
|
+
* The built-in prototype objects of one runtime, allocated empty in dependency order. The globals populate them
|
|
8
|
+
* and attach their constructors when the runtime is built.
|
|
9
|
+
*/
|
|
10
|
+
export type Prototypes = Readonly<Record<(typeof builtins)[number] | ErrorType, ProgramObject>>;
|
|
11
|
+
export declare const createErrorValue: (prototype: ProgramObject, message: string | undefined) => ProgramError;
|
|
12
|
+
export declare const createPrototypes: () => Prototypes;
|
|
13
|
+
export {};
|