@opencode/codemode 0.0.0-dev-19364 → 0.0.0-dev-19367
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/interpreter/errors.d.ts +4 -6
- package/dist/interpreter/errors.js +20 -4
- package/dist/interpreter/globals.d.ts +13 -0
- package/dist/interpreter/globals.js +59 -0
- package/dist/interpreter/host.d.ts +41 -0
- package/dist/interpreter/host.js +44 -0
- package/dist/interpreter/methods.d.ts +3 -23
- package/dist/interpreter/methods.js +8 -183
- package/dist/interpreter/model.d.ts +0 -41
- package/dist/interpreter/model.js +0 -56
- package/dist/interpreter/promises.d.ts +7 -8
- package/dist/interpreter/promises.js +45 -22
- package/dist/interpreter/references.js +11 -28
- package/dist/interpreter/runner.d.ts +23 -0
- package/dist/interpreter/runner.js +42 -0
- package/dist/interpreter/runtime.d.ts +0 -11
- package/dist/interpreter/runtime.js +33 -423
- package/dist/stdlib/array.d.ts +3 -0
- package/dist/stdlib/array.js +73 -0
- package/dist/stdlib/collections.d.ts +6 -1
- package/dist/stdlib/collections.js +120 -1
- package/dist/stdlib/console.d.ts +3 -2
- package/dist/stdlib/console.js +11 -2
- package/dist/stdlib/date.d.ts +3 -2
- package/dist/stdlib/date.js +27 -11
- package/dist/stdlib/json.d.ts +4 -4
- package/dist/stdlib/json.js +6 -2
- package/dist/stdlib/math.d.ts +3 -7
- package/dist/stdlib/math.js +85 -153
- package/dist/stdlib/number.d.ts +1 -3
- package/dist/stdlib/number.js +28 -36
- package/dist/stdlib/object.d.ts +4 -6
- package/dist/stdlib/object.js +101 -71
- package/dist/stdlib/regexp.d.ts +2 -4
- package/dist/stdlib/regexp.js +32 -9
- package/dist/stdlib/string.d.ts +1 -3
- package/dist/stdlib/string.js +14 -16
- package/dist/stdlib/url.d.ts +8 -4
- package/dist/stdlib/url.js +97 -21
- package/dist/stdlib/value.d.ts +5 -3
- package/dist/stdlib/value.js +21 -19
- package/package.json +1 -1
- package/dist/interpreter/iterator.d.ts +0 -13
- package/dist/interpreter/iterator.js +0 -4
- package/dist/stdlib/promise.d.ts +0 -2
- package/dist/stdlib/promise.js +0 -1
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { Cause, Deferred, Effect, Exit, Fiber, Scope } from "effect";
|
|
2
|
-
import { CodeModeFunction, InterpreterRuntimeError, ProgramThrow,
|
|
2
|
+
import { CodeModeFunction, InterpreterRuntimeError, ProgramThrow, PromiseInstanceMethodReference, } from "./model.js";
|
|
3
|
+
import { HostFunction, requiresNew, sync } from "./host.js";
|
|
3
4
|
import { caughtErrorValue, normalizeError } from "./errors.js";
|
|
4
|
-
import { applyCollectionCallback, isSupportedCallback } from "./methods.js";
|
|
5
5
|
import { typeofValue } from "./references.js";
|
|
6
6
|
import { createAggregateErrorValue } from "../stdlib/value.js";
|
|
7
7
|
import { Values } from "../values.js";
|
|
8
|
+
import { applyCollectionCallback, isSupportedCallback } from "./runner.js";
|
|
9
|
+
// A `resolve`/`reject` handed to an executor or thenable: calling it settles the capability.
|
|
10
|
+
const capability = (name, settle) => sync(name, (args) => {
|
|
11
|
+
settle(args[0]);
|
|
12
|
+
return undefined;
|
|
13
|
+
});
|
|
8
14
|
// Observation only controls rejection reporting; program completion interrupts all promise work.
|
|
9
15
|
export class PromiseRuntime {
|
|
10
16
|
scope;
|
|
@@ -83,12 +89,8 @@ export const resolvePromiseValue = (runner, value, node, own) => {
|
|
|
83
89
|
// Promise resolution invokes a thenable's method in a later job.
|
|
84
90
|
yield* Effect.yieldNow;
|
|
85
91
|
const deferred = Deferred.makeUnsafe();
|
|
86
|
-
const resolve =
|
|
87
|
-
|
|
88
|
-
});
|
|
89
|
-
const reject = new PromiseCapabilityFunction((reason) => {
|
|
90
|
-
Deferred.doneUnsafe(deferred, Exit.fail(new ProgramThrow(reason)));
|
|
91
|
-
});
|
|
92
|
+
const resolve = capability("resolve", (result) => Deferred.doneUnsafe(deferred, Exit.succeed(result)));
|
|
93
|
+
const reject = capability("reject", (reason) => Deferred.doneUnsafe(deferred, Exit.fail(new ProgramThrow(reason))));
|
|
92
94
|
const executed = yield* Effect.exit(runner.invokeCallable(then, [resolve, reject], node));
|
|
93
95
|
if (!Exit.isSuccess(executed)) {
|
|
94
96
|
if (Cause.hasInterruptsOnly(executed.cause))
|
|
@@ -107,17 +109,18 @@ export const resolvePromise = (runner, promises, value, node) => {
|
|
|
107
109
|
return promise;
|
|
108
110
|
});
|
|
109
111
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
const promiseStatics = ["all", "allSettled", "race", "any", "resolve", "reject"];
|
|
113
|
+
const invokePromiseMethod = (runner, promises, name, args, node) => {
|
|
114
|
+
if (name === "resolve") {
|
|
112
115
|
return resolvePromise(runner, promises, args[0], node);
|
|
113
116
|
}
|
|
114
|
-
if (
|
|
117
|
+
if (name === "reject") {
|
|
115
118
|
return promises.create(Effect.fail(new ProgramThrow(args[0])));
|
|
116
119
|
}
|
|
117
120
|
return promises.create(Effect.gen(function* () {
|
|
118
121
|
const cursor = yield* runner.syncIterator(args[0], node);
|
|
119
122
|
if (cursor === undefined) {
|
|
120
|
-
throw new InterpreterRuntimeError(`Promise.${
|
|
123
|
+
throw new InterpreterRuntimeError(`Promise.${name} expects an array or other synchronous iterable.`, node).as("TypeError");
|
|
121
124
|
}
|
|
122
125
|
const items = [];
|
|
123
126
|
while (true) {
|
|
@@ -128,10 +131,10 @@ export const invokePromiseMethod = (runner, promises, ref, args, node) => {
|
|
|
128
131
|
promises.markObserved(item);
|
|
129
132
|
items.push(item);
|
|
130
133
|
}
|
|
131
|
-
if (
|
|
134
|
+
if (name === "all") {
|
|
132
135
|
return yield* settleAfterTurn(Effect.all(items.map((item) => Effect.flatten(promises.await(item))), { concurrency: "unbounded" }));
|
|
133
136
|
}
|
|
134
|
-
if (
|
|
137
|
+
if (name === "allSettled") {
|
|
135
138
|
const outcomes = [];
|
|
136
139
|
for (const item of items) {
|
|
137
140
|
const exit = yield* promises.await(item);
|
|
@@ -149,7 +152,7 @@ export const invokePromiseMethod = (runner, promises, ref, args, node) => {
|
|
|
149
152
|
yield* Effect.yieldNow;
|
|
150
153
|
return outcomes;
|
|
151
154
|
}
|
|
152
|
-
if (
|
|
155
|
+
if (name === "race") {
|
|
153
156
|
if (items.length === 0) {
|
|
154
157
|
throw new InterpreterRuntimeError("Promise.race([]) would never settle; provide at least one promise or value.", node);
|
|
155
158
|
}
|
|
@@ -175,7 +178,7 @@ export const invokePromiseInstanceMethod = (runner, promises, ref, args, node) =
|
|
|
175
178
|
const onRejected = reactionHandler(ref.name === "then" ? args[1] : args[0], method, node);
|
|
176
179
|
return chainReaction(runner, promises, ref.promise, onFulfilled, onRejected, method, node);
|
|
177
180
|
};
|
|
178
|
-
|
|
181
|
+
const constructPromise = (runner, promises, executor, node) => {
|
|
179
182
|
if (!(executor instanceof CodeModeFunction)) {
|
|
180
183
|
throw new InterpreterRuntimeError("new Promise(...) expects an executor function (e.g. new Promise((resolve, reject) => { ... })).", node).as("TypeError");
|
|
181
184
|
}
|
|
@@ -184,12 +187,8 @@ export const constructPromise = (runner, promises, executor, node) => {
|
|
|
184
187
|
const box = {};
|
|
185
188
|
const promise = yield* promises.create(Effect.flatMap(Deferred.await(deferred), (value) => resolvePromiseValue(runner, value, node, box)));
|
|
186
189
|
box.promise = promise;
|
|
187
|
-
const resolve =
|
|
188
|
-
|
|
189
|
-
});
|
|
190
|
-
const reject = new PromiseCapabilityFunction((value) => {
|
|
191
|
-
Deferred.doneUnsafe(deferred, Exit.fail(new ProgramThrow(value)));
|
|
192
|
-
});
|
|
190
|
+
const resolve = capability("resolve", (value) => Deferred.doneUnsafe(deferred, Exit.succeed(value)));
|
|
191
|
+
const reject = capability("reject", (value) => Deferred.doneUnsafe(deferred, Exit.fail(new ProgramThrow(value))));
|
|
193
192
|
const executed = yield* Effect.exit(runner.invokeFunction(executor, [resolve, reject]));
|
|
194
193
|
if (!Exit.isSuccess(executed)) {
|
|
195
194
|
if (Cause.hasInterruptsOnly(executed.cause))
|
|
@@ -251,3 +250,27 @@ const chainFinally = (runner, promises, source, cleanup, method, node) => promis
|
|
|
251
250
|
}
|
|
252
251
|
return yield* exit;
|
|
253
252
|
}));
|
|
253
|
+
export const promiseGlobal = (runner, promises) => {
|
|
254
|
+
// Combinators are not callbacks: `[p].map(Promise.resolve)` must ask for an arrow function.
|
|
255
|
+
const statics = new Map(promiseStatics.map((name) => [
|
|
256
|
+
name,
|
|
257
|
+
new HostFunction({
|
|
258
|
+
name: `Promise.${name}`,
|
|
259
|
+
call: (args, node) => invokePromiseMethod(runner, promises, name, args, node),
|
|
260
|
+
callback: false,
|
|
261
|
+
}),
|
|
262
|
+
]));
|
|
263
|
+
return new HostFunction({
|
|
264
|
+
name: "Promise",
|
|
265
|
+
call: requiresNew("Promise"),
|
|
266
|
+
construct: (args, node) => constructPromise(runner, promises, args[0], node),
|
|
267
|
+
instanceOf: (value) => value instanceof Values.Promise,
|
|
268
|
+
// Unknown statics fail loudly so a missing await cannot hide behind `undefined`.
|
|
269
|
+
members: (key, node) => {
|
|
270
|
+
const method = typeof key === "string" ? statics.get(key) : undefined;
|
|
271
|
+
if (method !== undefined)
|
|
272
|
+
return method;
|
|
273
|
+
throw new InterpreterRuntimeError(`Promise.${String(key)} is not available. Available: Promise.all, Promise.allSettled, Promise.race, Promise.any, Promise.resolve, and Promise.reject; consume promises with await.`, node);
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
};
|
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
import { AsyncIteratorSymbol, CodeModeFunction, CodeModeGenerator, CoercionFunction, ErrorConstructorReference, GlobalMethodReference, GlobalNamespace, GeneratorMethodReference, InterpreterRuntimeError, IntrinsicReference, IteratorSymbol, JsonMethodReference, PromiseCapabilityFunction, PromiseInstanceMethodReference, PromiseMethodReference, PromiseNamespace, SearchFunction, SymbolNamespace, UriFunction, } from "./model.js";
|
|
2
1
|
import { ToolReference } from "../tool-runtime.js";
|
|
3
2
|
import { Values } from "../values.js";
|
|
4
|
-
|
|
3
|
+
import { HostFunction, HostNamespace } from "./host.js";
|
|
4
|
+
import { AsyncIteratorSymbol, CodeModeFunction, CodeModeGenerator, GeneratorMethodReference, InterpreterRuntimeError, IntrinsicReference, IteratorSymbol, PromiseInstanceMethodReference, } from "./model.js";
|
|
5
|
+
export const isRuntimeReference = (value) => value instanceof HostFunction ||
|
|
6
|
+
value instanceof HostNamespace ||
|
|
7
|
+
value instanceof CodeModeFunction ||
|
|
5
8
|
value instanceof CodeModeGenerator ||
|
|
6
9
|
value instanceof GeneratorMethodReference ||
|
|
7
10
|
value instanceof ToolReference ||
|
|
8
11
|
value instanceof IntrinsicReference ||
|
|
9
|
-
value instanceof GlobalNamespace ||
|
|
10
|
-
value instanceof GlobalMethodReference ||
|
|
11
|
-
value instanceof JsonMethodReference ||
|
|
12
|
-
value instanceof PromiseNamespace ||
|
|
13
|
-
value instanceof PromiseMethodReference ||
|
|
14
12
|
value instanceof PromiseInstanceMethodReference ||
|
|
15
13
|
value instanceof Values.Promise ||
|
|
16
|
-
value instanceof CoercionFunction ||
|
|
17
|
-
value instanceof UriFunction ||
|
|
18
|
-
value instanceof SearchFunction ||
|
|
19
|
-
value instanceof PromiseCapabilityFunction ||
|
|
20
|
-
value instanceof ErrorConstructorReference ||
|
|
21
|
-
value instanceof SymbolNamespace ||
|
|
22
14
|
Values.isValue(value);
|
|
23
15
|
function* childValues(value) {
|
|
24
16
|
for (const key of Reflect.ownKeys(value)) {
|
|
@@ -59,25 +51,16 @@ export const rejectCircularInsertion = (container, value, label, node, seen = ne
|
|
|
59
51
|
}
|
|
60
52
|
};
|
|
61
53
|
export const typeofValue = (value) => {
|
|
62
|
-
if (value instanceof
|
|
54
|
+
if (value instanceof HostFunction ||
|
|
55
|
+
value instanceof CodeModeFunction ||
|
|
63
56
|
value instanceof GeneratorMethodReference ||
|
|
64
|
-
value instanceof CoercionFunction ||
|
|
65
57
|
value instanceof IntrinsicReference ||
|
|
66
|
-
value instanceof
|
|
67
|
-
value instanceof JsonMethodReference ||
|
|
68
|
-
value instanceof PromiseMethodReference ||
|
|
69
|
-
value instanceof PromiseInstanceMethodReference ||
|
|
70
|
-
value instanceof PromiseNamespace ||
|
|
71
|
-
value instanceof PromiseCapabilityFunction ||
|
|
72
|
-
value instanceof ErrorConstructorReference ||
|
|
73
|
-
value instanceof SymbolNamespace)
|
|
74
|
-
return "function";
|
|
75
|
-
if (value instanceof UriFunction || value instanceof SearchFunction)
|
|
58
|
+
value instanceof PromiseInstanceMethodReference) {
|
|
76
59
|
return "function";
|
|
60
|
+
}
|
|
61
|
+
if (value instanceof HostNamespace)
|
|
62
|
+
return "object";
|
|
77
63
|
if (value instanceof ToolReference)
|
|
78
64
|
return value.path.length > 0 ? "function" : "object";
|
|
79
|
-
if (value instanceof GlobalNamespace) {
|
|
80
|
-
return value.name === "Math" || value.name === "JSON" || value.name === "console" ? "object" : "function";
|
|
81
|
-
}
|
|
82
65
|
return typeof value;
|
|
83
66
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Values } from "../values.js";
|
|
3
|
+
import { HostFunction } from "./host.js";
|
|
4
|
+
import { type AstNode, CodeModeFunction, IntrinsicReference } from "./model.js";
|
|
5
|
+
export type IteratorCursor<R> = {
|
|
6
|
+
readonly next: Effect.Effect<{
|
|
7
|
+
readonly done: boolean;
|
|
8
|
+
readonly value: unknown;
|
|
9
|
+
}, unknown, R>;
|
|
10
|
+
readonly close: Effect.Effect<void, unknown, R>;
|
|
11
|
+
};
|
|
12
|
+
/** Everything a host function needs to call back into the program. */
|
|
13
|
+
export type Runner<R> = {
|
|
14
|
+
readonly invokeFunction: (fn: CodeModeFunction, args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
|
|
15
|
+
readonly invokeCallable: (callable: unknown, args: Array<unknown>, node: AstNode) => Effect.Effect<unknown, unknown, R>;
|
|
16
|
+
readonly settlePromise: (promise: Values.Promise) => Effect.Effect<unknown, unknown, never>;
|
|
17
|
+
readonly syncIterator: (value: unknown, node: AstNode) => Effect.Effect<IteratorCursor<R> | undefined, unknown, R>;
|
|
18
|
+
};
|
|
19
|
+
export declare const preserveConsumerError: <A, R>(cursor: IteratorCursor<R>, effect: Effect.Effect<A, unknown, R>) => Effect.Effect<A, unknown, R>;
|
|
20
|
+
export declare const toPrimitive: <R>(runner: Runner<R>, value: unknown, hint: "number" | "string", node: AstNode) => Effect.Effect<unknown, unknown, R>;
|
|
21
|
+
export type SupportedCallback = CodeModeFunction | HostFunction<unknown> | IntrinsicReference;
|
|
22
|
+
export declare const isSupportedCallback: (value: unknown) => value is SupportedCallback;
|
|
23
|
+
export declare const applyCollectionCallback: <R>(runner: Runner<R>, callback: unknown, name: string, node: AstNode) => ((args: Array<unknown>) => Effect.Effect<unknown, unknown, R>);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Effect, Exit } from "effect";
|
|
2
|
+
import { Values } from "../values.js";
|
|
3
|
+
import { coerceToString } from "../stdlib/value.js";
|
|
4
|
+
import { HostFunction } from "./host.js";
|
|
5
|
+
import { CodeModeFunction, InterpreterRuntimeError, IntrinsicReference } from "./model.js";
|
|
6
|
+
import { typeofValue } from "./references.js";
|
|
7
|
+
export const preserveConsumerError = (cursor, effect) => Effect.flatMap(Effect.exit(effect), (exit) => Exit.isSuccess(exit)
|
|
8
|
+
? Effect.succeed(exit.value)
|
|
9
|
+
: Effect.andThen(Effect.exit(cursor.close), Effect.failCause(exit.cause)));
|
|
10
|
+
export const toPrimitive = (runner, value, hint, node) => {
|
|
11
|
+
if (value === null || typeof value !== "object")
|
|
12
|
+
return Effect.succeed(value);
|
|
13
|
+
if (Values.isValue(value)) {
|
|
14
|
+
return Effect.succeed(value instanceof Values.Date && hint === "number" ? value.time : coerceToString(value));
|
|
15
|
+
}
|
|
16
|
+
const object = value;
|
|
17
|
+
const order = hint === "number" ? ["valueOf", "toString"] : ["toString", "valueOf"];
|
|
18
|
+
return Effect.gen(function* () {
|
|
19
|
+
for (const method of order) {
|
|
20
|
+
if (method === "toString" && !Object.hasOwn(object, "toString"))
|
|
21
|
+
return coerceToString(value);
|
|
22
|
+
if (!Object.hasOwn(object, method) || typeofValue(object[method]) !== "function")
|
|
23
|
+
continue;
|
|
24
|
+
const result = yield* runner.invokeCallable(object[method], [], node);
|
|
25
|
+
if (result === null || (typeof result !== "object" && typeof result !== "function"))
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
throw new InterpreterRuntimeError("Cannot convert object to primitive value.", node).as("TypeError");
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
export const isSupportedCallback = (value) => value instanceof CodeModeFunction ||
|
|
32
|
+
(value instanceof HostFunction && value.callback) ||
|
|
33
|
+
value instanceof IntrinsicReference;
|
|
34
|
+
export const applyCollectionCallback = (runner, callback, name, node) => {
|
|
35
|
+
if (!isSupportedCallback(callback)) {
|
|
36
|
+
if (typeofValue(callback) === "function") {
|
|
37
|
+
throw new InterpreterRuntimeError(`${name} cannot use this callable as a callback; wrap it in an arrow function, e.g. (value) => tools.ns.tool(value).`, node);
|
|
38
|
+
}
|
|
39
|
+
throw new InterpreterRuntimeError(`${name} expects a function callback.`, node).as("TypeError");
|
|
40
|
+
}
|
|
41
|
+
return (callbackArgs) => runner.invokeCallable(callback, callbackArgs, node);
|
|
42
|
+
};
|
|
@@ -52,15 +52,6 @@ export declare class Interpreter<R> {
|
|
|
52
52
|
private destructuringPropertyValue;
|
|
53
53
|
private evaluateExpression;
|
|
54
54
|
private evaluateNewExpression;
|
|
55
|
-
private constructArray;
|
|
56
|
-
private constructObject;
|
|
57
|
-
private constructDate;
|
|
58
|
-
private constructRegExp;
|
|
59
|
-
private constructMap;
|
|
60
|
-
private constructSet;
|
|
61
|
-
private constructURL;
|
|
62
|
-
private constructURLSearchParams;
|
|
63
|
-
private readURLSearchParamsPair;
|
|
64
55
|
private evaluateBinaryExpression;
|
|
65
56
|
private applyBinaryOperator;
|
|
66
57
|
private evaluateLogicalExpression;
|
|
@@ -70,8 +61,6 @@ export declare class Interpreter<R> {
|
|
|
70
61
|
private evaluateUpdateExpression;
|
|
71
62
|
private evaluateCallExpression;
|
|
72
63
|
private invokeCallable;
|
|
73
|
-
private invokeObjectMethodOnTools;
|
|
74
|
-
private invokeConsole;
|
|
75
64
|
private evaluateCallArguments;
|
|
76
65
|
private invokeFunction;
|
|
77
66
|
private createGenerator;
|