@opencode/codemode 2.0.12 → 2.0.14
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 +5 -4
- package/dist/interpreter/callback.d.ts +10 -15
- package/dist/interpreter/callback.js +15 -7
- package/dist/interpreter/errors.d.ts +3 -3
- package/dist/interpreter/errors.js +1 -2
- package/dist/interpreter/execute.d.ts +2 -1
- package/dist/interpreter/extensions.d.ts +2 -1
- package/dist/interpreter/extensions.js +7 -35
- package/dist/interpreter/globals.d.ts +2 -1
- package/dist/interpreter/globals.js +1 -1
- package/dist/interpreter/interpreter.d.ts +8 -19
- package/dist/interpreter/interpreter.js +96 -98
- package/dist/interpreter/intrinsics.d.ts +3 -3
- package/dist/interpreter/intrinsics.js +2 -0
- package/dist/interpreter/model.d.ts +7 -8
- package/dist/interpreter/model.js +0 -1
- package/dist/interpreter/native.d.ts +5 -5
- package/dist/interpreter/objects.d.ts +148 -47
- package/dist/interpreter/objects.js +224 -26
- package/dist/interpreter/promises.d.ts +7 -7
- package/dist/interpreter/promises.js +32 -11
- package/dist/interpreter/references.d.ts +8 -7
- package/dist/interpreter/references.js +10 -46
- package/dist/interpreter/scope.d.ts +5 -4
- package/dist/stdlib/array.d.ts +2 -1
- package/dist/stdlib/array.js +29 -51
- package/dist/stdlib/bytes.js +14 -24
- package/dist/stdlib/collections.js +27 -30
- package/dist/stdlib/console.d.ts +2 -2
- package/dist/stdlib/console.js +6 -50
- package/dist/stdlib/date.js +1 -2
- package/dist/stdlib/headers.js +10 -22
- package/dist/stdlib/iterator.d.ts +1 -1
- package/dist/stdlib/iterator.js +294 -6
- package/dist/stdlib/json.js +3 -5
- package/dist/stdlib/math.js +5 -17
- package/dist/stdlib/number.js +8 -21
- package/dist/stdlib/object.d.ts +3 -4
- package/dist/stdlib/object.js +5 -16
- package/dist/stdlib/regexp.d.ts +3 -3
- package/dist/stdlib/regexp.js +1 -2
- package/dist/stdlib/string.js +10 -20
- package/dist/stdlib/url.d.ts +2 -1
- package/dist/stdlib/url.js +6 -16
- package/dist/stdlib/value.d.ts +0 -3
- package/dist/stdlib/value.js +2 -74
- package/dist/stdlib/web.js +1 -2
- package/dist/tool-runtime.js +38 -28
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { BlockStatement, Expression, Pattern } from "acorn";
|
|
2
|
-
import
|
|
2
|
+
import { Effect, type Fiber } from "effect";
|
|
3
|
+
import { ToolReference } from "../tool-runtime.js";
|
|
4
|
+
import type { Builtins } from "./intrinsics.js";
|
|
3
5
|
import { type Binding, type GeneratorRequestKind, type PendingThrow } from "./model.js";
|
|
4
6
|
/** Property attributes, as in a JS property descriptor. */
|
|
5
7
|
export type Attributes = {
|
|
@@ -7,11 +9,11 @@ export type Attributes = {
|
|
|
7
9
|
readonly enumerable: boolean;
|
|
8
10
|
readonly configurable: boolean;
|
|
9
11
|
};
|
|
10
|
-
export type Getter = (receiver:
|
|
11
|
-
export type Setter = (receiver:
|
|
12
|
+
export type Getter = (receiver: Value) => Value;
|
|
13
|
+
export type Setter = (receiver: Value, value: Value) => void;
|
|
12
14
|
/** One own property: a data slot or a native accessor pair. */
|
|
13
15
|
export type Slot = {
|
|
14
|
-
value:
|
|
16
|
+
value: Value;
|
|
15
17
|
writable: boolean;
|
|
16
18
|
enumerable: boolean;
|
|
17
19
|
configurable: boolean;
|
|
@@ -29,34 +31,69 @@ export declare const hidden: Attributes;
|
|
|
29
31
|
export declare const readonly: Attributes;
|
|
30
32
|
/** Constants such as `Math.PI` and a constructor's `prototype`. */
|
|
31
33
|
export declare const frozen: Attributes;
|
|
32
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* An object owned by the program: own properties plus a prototype link. Subclasses answer, in one place, how a
|
|
36
|
+
* built-in kind of object prints, coerces, iterates, and crosses to the host.
|
|
37
|
+
*/
|
|
33
38
|
export declare class Obj {
|
|
34
39
|
proto: Obj | null;
|
|
35
40
|
readonly props: Map<string | symbol, Slot>;
|
|
36
41
|
constructor(proto: Obj | null);
|
|
42
|
+
/** The class name `Object.prototype.toString` reports: `[object Map]`. */
|
|
43
|
+
readonly tag: string;
|
|
44
|
+
/** How diagnostics refer to a value of this kind. */
|
|
45
|
+
get describe(): string;
|
|
46
|
+
/** ToString without consulting program-defined methods. */
|
|
47
|
+
toString(): string;
|
|
48
|
+
/** ToPrimitive without consulting program-defined methods: only a Date answers a number hint differently. */
|
|
49
|
+
toPrimitive(hint: "default" | "number" | "string"): string | number;
|
|
50
|
+
/** ToNumber without consulting program-defined methods. */
|
|
51
|
+
toNumber(): number;
|
|
52
|
+
/** How `console.log` shows the value; `item` formats a child with cycle and depth tracking. */
|
|
53
|
+
inspect(item: (value: Value) => string): string;
|
|
54
|
+
/** A copy the host can hold; `item` converts a child. A `__proto__` key never reaches host code. */
|
|
55
|
+
toHost(item: (value: Value) => unknown): unknown;
|
|
56
|
+
/** The built-in iteration `for...of` and spread use, when this kind of object has one. */
|
|
57
|
+
iterator(builtins: Builtins): Iterator<Value, undefined> | undefined;
|
|
37
58
|
}
|
|
38
59
|
export declare class Arr extends Obj {
|
|
39
|
-
readonly items: Array<
|
|
40
|
-
|
|
60
|
+
readonly items: Array<Value>;
|
|
61
|
+
readonly tag = "Array";
|
|
62
|
+
constructor(proto: Obj, items?: Array<Value>);
|
|
63
|
+
get describe(): string;
|
|
64
|
+
toString(): string;
|
|
65
|
+
inspect(item: (value: Value) => string): string;
|
|
66
|
+
toHost(item: (value: Value) => unknown): unknown[];
|
|
67
|
+
iterator(): ArrayIterator<Value>;
|
|
41
68
|
}
|
|
42
69
|
/** An object with the [[ErrorData]] slot: what `Error.prototype.toString` and the host boundary recognize as an error. */
|
|
43
70
|
export declare class ErrorObj extends Obj {
|
|
71
|
+
readonly tag = "Error";
|
|
44
72
|
/** The interpreter failure this error materialized from, so rethrowing it keeps the diagnostic kind and location. */
|
|
45
73
|
host?: PendingThrow;
|
|
74
|
+
/** Error.prototype.toString: "name: message", or just one when the other is empty. */
|
|
75
|
+
toString(): string;
|
|
76
|
+
inspect(): string;
|
|
46
77
|
}
|
|
47
|
-
|
|
78
|
+
/** Interpreter machinery a program can hold but never inspect, serialize, or hand to the host. */
|
|
79
|
+
export declare abstract class Opaque extends Obj {
|
|
80
|
+
inspect(): string;
|
|
81
|
+
}
|
|
82
|
+
export declare abstract class Callable extends Opaque {
|
|
83
|
+
readonly tag = "Function";
|
|
48
84
|
constructor(proto: Obj, name: string, length: number);
|
|
85
|
+
get describe(): string;
|
|
49
86
|
}
|
|
50
87
|
export declare class Fn extends Callable {
|
|
51
88
|
readonly parameters: ReadonlyArray<Pattern>;
|
|
52
89
|
readonly body: BlockStatement | Expression;
|
|
53
|
-
readonly capturedScopes:
|
|
90
|
+
readonly capturedScopes: Array<Map<string, Binding>>;
|
|
54
91
|
readonly async: boolean;
|
|
55
92
|
readonly generator: boolean;
|
|
56
|
-
constructor(proto: Obj, name: string, parameters: ReadonlyArray<Pattern>, body: BlockStatement | Expression, capturedScopes:
|
|
93
|
+
constructor(proto: Obj, name: string, parameters: ReadonlyArray<Pattern>, body: BlockStatement | Expression, capturedScopes: Array<Map<string, Binding>>, async: boolean, generator: boolean);
|
|
57
94
|
}
|
|
58
|
-
export type NativeCall<R> = (thisValue:
|
|
59
|
-
export type NativeConstruct<R> = (args: Array<
|
|
95
|
+
export type NativeCall<R> = (thisValue: Value, args: Array<Value>) => Effect.Effect<Value, unknown, R>;
|
|
96
|
+
export type NativeConstruct<R> = (args: Array<Value>, newTarget: Callable) => Effect.Effect<Value, unknown, R>;
|
|
60
97
|
export type NativeOptions<R> = {
|
|
61
98
|
readonly name: string;
|
|
62
99
|
readonly length?: number;
|
|
@@ -72,67 +109,131 @@ export declare class Native<R = never> extends Callable {
|
|
|
72
109
|
readonly callback: boolean;
|
|
73
110
|
constructor(proto: Obj, options: NativeOptions<R>);
|
|
74
111
|
}
|
|
75
|
-
export declare class PromiseObj extends
|
|
76
|
-
readonly fiber: Fiber.Fiber<
|
|
77
|
-
|
|
112
|
+
export declare class PromiseObj extends Opaque {
|
|
113
|
+
readonly fiber: Fiber.Fiber<Value, unknown>;
|
|
114
|
+
readonly tag = "Promise";
|
|
115
|
+
constructor(proto: Obj, fiber: Fiber.Fiber<Value, unknown>);
|
|
116
|
+
get describe(): string;
|
|
117
|
+
inspect(): string;
|
|
78
118
|
}
|
|
79
|
-
export declare class GeneratorObj extends
|
|
119
|
+
export declare class GeneratorObj extends Opaque {
|
|
80
120
|
readonly asynchronous: boolean;
|
|
81
|
-
readonly request: (kind: GeneratorRequestKind, value:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
121
|
+
readonly request: (kind: GeneratorRequestKind, value: Value) => Effect.Effect<Value, unknown, unknown>;
|
|
122
|
+
readonly tag = "Generator";
|
|
123
|
+
constructor(proto: Obj, asynchronous: boolean, request: (kind: GeneratorRequestKind, value: Value) => Effect.Effect<Value, unknown, unknown>);
|
|
124
|
+
get describe(): string;
|
|
125
|
+
}
|
|
126
|
+
/** One pull from an iterator, as `for...of` sees it. */
|
|
127
|
+
export type Step = {
|
|
128
|
+
readonly done: boolean;
|
|
129
|
+
readonly value: Value;
|
|
130
|
+
};
|
|
131
|
+
/** How the interpreter drives any iterator: pull the next step, or close it early. */
|
|
132
|
+
export type Cursor<R = unknown> = {
|
|
133
|
+
readonly next: Effect.Effect<Step, unknown, R>;
|
|
134
|
+
readonly close: Effect.Effect<void, unknown, R>;
|
|
135
|
+
};
|
|
136
|
+
/** A cursor over a host iterator; there is nothing to close. */
|
|
137
|
+
export declare const hostCursor: (iterator: Iterator<Value, undefined>) => Cursor<never>;
|
|
138
|
+
/** A built-in iterator: a live cursor over a host collection or an iterator helper, yielding program values. */
|
|
139
|
+
export declare class IteratorObj extends Opaque {
|
|
140
|
+
readonly cursor: Cursor;
|
|
141
|
+
readonly tag = "Iterator";
|
|
142
|
+
constructor(proto: Obj, cursor: Cursor);
|
|
143
|
+
get describe(): string;
|
|
144
|
+
}
|
|
145
|
+
/** A built-in iterator over a host iterator, e.g. `array.values()`. */
|
|
146
|
+
export declare const hostIterator: (builtins: Builtins, iterator: Iterator<Value, undefined>) => IteratorObj;
|
|
147
|
+
/** A built-in object around a host value: data-like, so it prints as itself and crosses to extensions as a copy. */
|
|
148
|
+
export declare abstract class Wrapper extends Obj {
|
|
149
|
+
inspect(item: (value: Value) => string): string;
|
|
150
|
+
}
|
|
151
|
+
export declare class DateObj extends Wrapper {
|
|
90
152
|
time: number;
|
|
153
|
+
readonly tag = "Date";
|
|
91
154
|
constructor(proto: Obj, time: number);
|
|
155
|
+
toString(): string;
|
|
156
|
+
toPrimitive(hint: "default" | "number" | "string"): string | number;
|
|
157
|
+
toHost(): Date;
|
|
92
158
|
}
|
|
93
|
-
export declare class RegExpObj extends
|
|
159
|
+
export declare class RegExpObj extends Wrapper {
|
|
160
|
+
readonly tag = "RegExp";
|
|
94
161
|
readonly regex: RegExp;
|
|
95
162
|
constructor(proto: Obj, pattern: string, flags: string);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
readonly
|
|
102
|
-
|
|
103
|
-
|
|
163
|
+
toString(): string;
|
|
164
|
+
toHost(): RegExp;
|
|
165
|
+
}
|
|
166
|
+
export declare class MapObj extends Wrapper {
|
|
167
|
+
readonly tag = "Map";
|
|
168
|
+
readonly map: Map<Value, Value>;
|
|
169
|
+
inspect(item: (value: Value) => string): string;
|
|
170
|
+
toHost(item: (value: Value) => unknown): Map<unknown, unknown>;
|
|
171
|
+
iterator(builtins: Builtins): IteratorObject<Arr, undefined, unknown>;
|
|
172
|
+
}
|
|
173
|
+
export declare class SetObj extends Wrapper {
|
|
174
|
+
readonly tag = "Set";
|
|
175
|
+
readonly set: Set<Value>;
|
|
176
|
+
inspect(item: (value: Value) => string): string;
|
|
177
|
+
toHost(item: (value: Value) => unknown): Set<unknown>;
|
|
178
|
+
iterator(): SetIterator<Value>;
|
|
179
|
+
}
|
|
180
|
+
export declare class URLSearchParamsObj extends Wrapper {
|
|
104
181
|
readonly params: URLSearchParams;
|
|
182
|
+
readonly tag = "URLSearchParams";
|
|
105
183
|
constructor(proto: Obj, params: URLSearchParams);
|
|
184
|
+
toString(): string;
|
|
185
|
+
toHost(): URLSearchParams;
|
|
186
|
+
iterator(builtins: Builtins): IteratorObject<Arr, undefined, unknown>;
|
|
106
187
|
}
|
|
107
|
-
export declare class HeadersObj extends
|
|
188
|
+
export declare class HeadersObj extends Wrapper {
|
|
108
189
|
readonly headers: Headers;
|
|
190
|
+
readonly tag = "Headers";
|
|
109
191
|
constructor(proto: Obj, headers: Headers);
|
|
192
|
+
inspect(): string;
|
|
193
|
+
toHost(): Headers;
|
|
194
|
+
iterator(builtins: Builtins): IteratorObject<Arr, undefined, unknown>;
|
|
110
195
|
}
|
|
111
|
-
export declare class URLObj extends
|
|
196
|
+
export declare class URLObj extends Wrapper {
|
|
112
197
|
readonly url: URL;
|
|
198
|
+
readonly tag = "URL";
|
|
113
199
|
readonly searchParams: URLSearchParamsObj;
|
|
114
200
|
constructor(proto: Obj, searchParamsProto: Obj, url: URL);
|
|
201
|
+
toString(): string;
|
|
202
|
+
toHost(): URL;
|
|
115
203
|
}
|
|
116
204
|
/** A `Uint8Array`: the host array does the byte clamping and ignores out-of-range writes, as JS does. */
|
|
117
|
-
export declare class Bytes extends
|
|
205
|
+
export declare class Bytes extends Wrapper {
|
|
118
206
|
readonly bytes: Uint8Array;
|
|
207
|
+
readonly tag = "Uint8Array";
|
|
119
208
|
constructor(proto: Obj, bytes: Uint8Array);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
209
|
+
toString(): string;
|
|
210
|
+
inspect(): string;
|
|
211
|
+
toHost(): Uint8Array<ArrayBuffer>;
|
|
212
|
+
iterator(): ArrayIterator<number>;
|
|
213
|
+
}
|
|
214
|
+
/** Every value a program can hold. Host values never appear here; they are copied in at the boundaries. */
|
|
215
|
+
export type Value = string | number | boolean | null | undefined | symbol | Obj | ToolReference;
|
|
216
|
+
/** ToString without consulting program-defined methods. */
|
|
217
|
+
export declare const coerceToString: (value: Value) => string;
|
|
218
|
+
/** ToNumber without consulting program-defined methods; tool references are not numbers. */
|
|
219
|
+
export declare const coerceToNumber: (value: Value) => number;
|
|
220
|
+
/** ToIntegerOrInfinity: NaN is 0, fractions truncate. */
|
|
221
|
+
export declare const coerceToInteger: (value: Value) => number;
|
|
222
|
+
/** Values that cannot cross the data boundary: opaque machinery and host-backed wrappers. */
|
|
223
|
+
export declare const isRuntimeReference: (value: Value) => boolean;
|
|
123
224
|
export declare const parseArrayIndex: (key: string | number) => number | undefined;
|
|
124
225
|
/** The own property under `key`, including an array's live indexes and `length`. */
|
|
125
226
|
export declare const own: (target: Obj, key: PropertyKey) => Slot | undefined;
|
|
126
227
|
export declare const hasOwn: (target: Obj, key: PropertyKey) => boolean;
|
|
127
|
-
export declare const getOwn: (target: Obj, key: PropertyKey) =>
|
|
228
|
+
export declare const getOwn: (target: Obj, key: PropertyKey) => Value;
|
|
128
229
|
/** [[Get]]: walks the prototype chain; accessors see `receiver`, which is the primitive for wrapper prototypes. */
|
|
129
|
-
export declare const get: (target: Obj, key: PropertyKey, receiver?:
|
|
230
|
+
export declare const get: (target: Obj, key: PropertyKey, receiver?: Value) => Value;
|
|
130
231
|
export declare const has: (target: Obj, key: PropertyKey) => boolean;
|
|
131
|
-
export declare const hasPrototype: (value:
|
|
232
|
+
export declare const hasPrototype: (value: Value, proto: Obj) => boolean;
|
|
132
233
|
/** [[Set]]: an inherited setter or read-only property decides before an own data property is created. */
|
|
133
|
-
export declare const set: (target: Obj, key: PropertyKey, value:
|
|
234
|
+
export declare const set: (target: Obj, key: PropertyKey, value: Value) => boolean;
|
|
134
235
|
/** [[DefineOwnProperty]] for a data property, ignoring the chain. */
|
|
135
|
-
export declare const define: (target: Obj, key: PropertyKey, value:
|
|
236
|
+
export declare const define: (target: Obj, key: PropertyKey, value: Value, attrs?: Attributes) => void;
|
|
136
237
|
export declare const defineAccessor: (target: Obj, key: PropertyKey, get: Getter | undefined, set?: Setter) => void;
|
|
137
238
|
export declare const remove: (target: Obj, key: PropertyKey) => boolean;
|
|
138
239
|
export declare const ownKeys: (target: Obj) => Array<string | symbol>;
|
|
@@ -141,6 +242,6 @@ export declare const enumerableKeys: (target: Obj) => Array<string | symbol>;
|
|
|
141
242
|
/** Own enumerable string keys: `Object.keys`. */
|
|
142
243
|
export declare const keys: (target: Obj) => Array<string>;
|
|
143
244
|
/** Own enumerable string entries: `Object.entries` and serialization. */
|
|
144
|
-
export declare const entries: (target: Obj) => Array<[string,
|
|
145
|
-
export declare const record: (proto: Obj, fields: Record<string,
|
|
245
|
+
export declare const entries: (target: Obj) => Array<[string, Value]>;
|
|
246
|
+
export declare const record: (proto: Obj, fields: Record<string, Value>) => Obj;
|
|
146
247
|
export declare const assign: (target: Obj, source: Obj, skip?: ReadonlySet<PropertyKey>) => void;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ToolReference } from "../tool-runtime.js";
|
|
1
3
|
import { checkArrayLength } from "./limits.js";
|
|
2
4
|
import { AsyncIteratorSymbol, IteratorSymbol, } from "./model.js";
|
|
3
5
|
/** Ordinary assignment: writable, enumerable, configurable. */
|
|
@@ -8,32 +10,113 @@ export const hidden = { writable: true, enumerable: false, configurable: true };
|
|
|
8
10
|
export const readonly = { writable: false, enumerable: false, configurable: true };
|
|
9
11
|
/** Constants such as `Math.PI` and a constructor's `prototype`. */
|
|
10
12
|
export const frozen = { writable: false, enumerable: false, configurable: false };
|
|
11
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* An object owned by the program: own properties plus a prototype link. Subclasses answer, in one place, how a
|
|
15
|
+
* built-in kind of object prints, coerces, iterates, and crosses to the host.
|
|
16
|
+
*/
|
|
12
17
|
export class Obj {
|
|
13
18
|
proto;
|
|
14
19
|
props = new Map();
|
|
15
20
|
constructor(proto) {
|
|
16
21
|
this.proto = proto;
|
|
17
22
|
}
|
|
23
|
+
/** The class name `Object.prototype.toString` reports: `[object Map]`. */
|
|
24
|
+
tag = "Object";
|
|
25
|
+
/** How diagnostics refer to a value of this kind. */
|
|
26
|
+
get describe() {
|
|
27
|
+
if (this.tag === "Object")
|
|
28
|
+
return "a data object";
|
|
29
|
+
return `${/^[AEIO]/.test(this.tag) ? "an" : "a"} ${this.tag}`;
|
|
30
|
+
}
|
|
31
|
+
/** ToString without consulting program-defined methods. */
|
|
32
|
+
toString() {
|
|
33
|
+
return `[object ${this.tag}]`;
|
|
34
|
+
}
|
|
35
|
+
/** ToPrimitive without consulting program-defined methods: only a Date answers a number hint differently. */
|
|
36
|
+
toPrimitive(hint) {
|
|
37
|
+
return this.toString();
|
|
38
|
+
}
|
|
39
|
+
/** ToNumber without consulting program-defined methods. */
|
|
40
|
+
toNumber() {
|
|
41
|
+
return Number(this.toPrimitive("number"));
|
|
42
|
+
}
|
|
43
|
+
/** How `console.log` shows the value; `item` formats a child with cycle and depth tracking. */
|
|
44
|
+
inspect(item) {
|
|
45
|
+
return `{${entries(this)
|
|
46
|
+
.map(([key, value]) => `${JSON.stringify(key)}:${item(value)}`)
|
|
47
|
+
.join(",")}}`;
|
|
48
|
+
}
|
|
49
|
+
/** A copy the host can hold; `item` converts a child. A `__proto__` key never reaches host code. */
|
|
50
|
+
toHost(item) {
|
|
51
|
+
return Object.fromEntries(entries(this)
|
|
52
|
+
.filter(([key]) => key !== "__proto__")
|
|
53
|
+
.map(([key, value]) => [key, item(value)]));
|
|
54
|
+
}
|
|
55
|
+
/** The built-in iteration `for...of` and spread use, when this kind of object has one. */
|
|
56
|
+
iterator(builtins) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
18
59
|
}
|
|
19
60
|
export class Arr extends Obj {
|
|
20
61
|
items;
|
|
62
|
+
tag = "Array";
|
|
21
63
|
constructor(proto, items = []) {
|
|
22
64
|
super(proto);
|
|
23
65
|
this.items = items;
|
|
24
66
|
}
|
|
67
|
+
get describe() {
|
|
68
|
+
return "an array";
|
|
69
|
+
}
|
|
70
|
+
toString() {
|
|
71
|
+
return this.items.map((item) => (item === null || item === undefined ? "" : coerceToString(item))).join(",");
|
|
72
|
+
}
|
|
73
|
+
inspect(item) {
|
|
74
|
+
return `[${this.items.map(item).join(",")}]`;
|
|
75
|
+
}
|
|
76
|
+
toHost(item) {
|
|
77
|
+
return this.items.map(item);
|
|
78
|
+
}
|
|
79
|
+
iterator() {
|
|
80
|
+
return this.items.values();
|
|
81
|
+
}
|
|
25
82
|
}
|
|
26
83
|
/** An object with the [[ErrorData]] slot: what `Error.prototype.toString` and the host boundary recognize as an error. */
|
|
27
84
|
export class ErrorObj extends Obj {
|
|
85
|
+
tag = "Error";
|
|
28
86
|
/** The interpreter failure this error materialized from, so rethrowing it keeps the diagnostic kind and location. */
|
|
29
87
|
host;
|
|
88
|
+
/** Error.prototype.toString: "name: message", or just one when the other is empty. */
|
|
89
|
+
toString() {
|
|
90
|
+
const name = get(this, "name");
|
|
91
|
+
const message = get(this, "message");
|
|
92
|
+
const shownName = typeof name === "string" ? name : "Error";
|
|
93
|
+
const shownMessage = typeof message === "string" ? message : "";
|
|
94
|
+
if (shownMessage === "")
|
|
95
|
+
return shownName;
|
|
96
|
+
if (shownName === "")
|
|
97
|
+
return shownMessage;
|
|
98
|
+
return `${shownName}: ${shownMessage}`;
|
|
99
|
+
}
|
|
100
|
+
inspect() {
|
|
101
|
+
return this.toString();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Interpreter machinery a program can hold but never inspect, serialize, or hand to the host. */
|
|
105
|
+
export class Opaque extends Obj {
|
|
106
|
+
inspect() {
|
|
107
|
+
return "[opaque reference]";
|
|
108
|
+
}
|
|
30
109
|
}
|
|
31
|
-
export class Callable extends
|
|
110
|
+
export class Callable extends Opaque {
|
|
111
|
+
tag = "Function";
|
|
32
112
|
constructor(proto, name, length) {
|
|
33
113
|
super(proto);
|
|
34
114
|
define(this, "length", length, readonly);
|
|
35
115
|
define(this, "name", name, readonly);
|
|
36
116
|
}
|
|
117
|
+
get describe() {
|
|
118
|
+
return "a function";
|
|
119
|
+
}
|
|
37
120
|
}
|
|
38
121
|
export class Fn extends Callable {
|
|
39
122
|
parameters;
|
|
@@ -62,90 +145,205 @@ export class Native extends Callable {
|
|
|
62
145
|
this.callback = options.callback ?? true;
|
|
63
146
|
}
|
|
64
147
|
}
|
|
65
|
-
export class PromiseObj extends
|
|
148
|
+
export class PromiseObj extends Opaque {
|
|
66
149
|
fiber;
|
|
150
|
+
tag = "Promise";
|
|
67
151
|
constructor(proto, fiber) {
|
|
68
152
|
super(proto);
|
|
69
153
|
this.fiber = fiber;
|
|
70
154
|
}
|
|
155
|
+
get describe() {
|
|
156
|
+
return "an un-awaited Promise";
|
|
157
|
+
}
|
|
158
|
+
inspect() {
|
|
159
|
+
return "[Promise (await it to get its value)]";
|
|
160
|
+
}
|
|
71
161
|
}
|
|
72
|
-
export class GeneratorObj extends
|
|
162
|
+
export class GeneratorObj extends Opaque {
|
|
73
163
|
asynchronous;
|
|
74
164
|
request;
|
|
165
|
+
tag = "Generator";
|
|
75
166
|
constructor(proto, asynchronous, request) {
|
|
76
167
|
super(proto);
|
|
77
168
|
this.asynchronous = asynchronous;
|
|
78
169
|
this.request = request;
|
|
79
170
|
}
|
|
171
|
+
get describe() {
|
|
172
|
+
return "a generator";
|
|
173
|
+
}
|
|
80
174
|
}
|
|
81
|
-
/** A
|
|
82
|
-
export
|
|
83
|
-
|
|
84
|
-
|
|
175
|
+
/** A cursor over a host iterator; there is nothing to close. */
|
|
176
|
+
export const hostCursor = (iterator) => ({
|
|
177
|
+
next: Effect.sync(() => {
|
|
178
|
+
const step = iterator.next();
|
|
179
|
+
return { done: Boolean(step.done), value: step.value };
|
|
180
|
+
}),
|
|
181
|
+
close: Effect.void,
|
|
182
|
+
});
|
|
183
|
+
/** A built-in iterator: a live cursor over a host collection or an iterator helper, yielding program values. */
|
|
184
|
+
export class IteratorObj extends Opaque {
|
|
185
|
+
cursor;
|
|
186
|
+
tag = "Iterator";
|
|
187
|
+
constructor(proto, cursor) {
|
|
85
188
|
super(proto);
|
|
86
|
-
this.
|
|
189
|
+
this.cursor = cursor;
|
|
190
|
+
}
|
|
191
|
+
get describe() {
|
|
192
|
+
return "an iterator";
|
|
87
193
|
}
|
|
88
194
|
}
|
|
89
|
-
|
|
195
|
+
/** A built-in iterator over a host iterator, e.g. `array.values()`. */
|
|
196
|
+
export const hostIterator = (builtins, iterator) => new IteratorObj(builtins.Iterator, hostCursor(iterator));
|
|
197
|
+
/** A built-in object around a host value: data-like, so it prints as itself and crosses to extensions as a copy. */
|
|
198
|
+
export class Wrapper extends Obj {
|
|
199
|
+
inspect(item) {
|
|
200
|
+
return this.toString();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
export class DateObj extends Wrapper {
|
|
90
204
|
time;
|
|
205
|
+
tag = "Date";
|
|
91
206
|
constructor(proto, time) {
|
|
92
207
|
super(proto);
|
|
93
208
|
this.time = time;
|
|
94
209
|
}
|
|
210
|
+
toString() {
|
|
211
|
+
return Number.isFinite(this.time) ? new Date(this.time).toISOString() : "Invalid Date";
|
|
212
|
+
}
|
|
213
|
+
toPrimitive(hint) {
|
|
214
|
+
return hint === "number" ? this.time : this.toString();
|
|
215
|
+
}
|
|
216
|
+
toHost() {
|
|
217
|
+
return new Date(this.time);
|
|
218
|
+
}
|
|
95
219
|
}
|
|
96
|
-
export class RegExpObj extends
|
|
220
|
+
export class RegExpObj extends Wrapper {
|
|
221
|
+
tag = "RegExp";
|
|
97
222
|
regex;
|
|
98
223
|
constructor(proto, pattern, flags) {
|
|
99
224
|
super(proto);
|
|
100
225
|
this.regex = new RegExp(pattern, flags);
|
|
101
226
|
}
|
|
227
|
+
toString() {
|
|
228
|
+
return `/${this.regex.source}/${this.regex.flags}`;
|
|
229
|
+
}
|
|
230
|
+
toHost() {
|
|
231
|
+
return new RegExp(this.regex.source, this.regex.flags);
|
|
232
|
+
}
|
|
102
233
|
}
|
|
103
|
-
export class MapObj extends
|
|
234
|
+
export class MapObj extends Wrapper {
|
|
235
|
+
tag = "Map";
|
|
104
236
|
map = new Map();
|
|
237
|
+
inspect(item) {
|
|
238
|
+
return `Map(${this.map.size}) [${[...this.map].map(([key, value]) => `[${item(key)},${item(value)}]`).join(",")}]`;
|
|
239
|
+
}
|
|
240
|
+
toHost(item) {
|
|
241
|
+
return new Map([...this.map].map(([key, value]) => [item(key), item(value)]));
|
|
242
|
+
}
|
|
243
|
+
iterator(builtins) {
|
|
244
|
+
return this.map.entries().map((entry) => new Arr(builtins.Array, entry));
|
|
245
|
+
}
|
|
105
246
|
}
|
|
106
|
-
export class SetObj extends
|
|
247
|
+
export class SetObj extends Wrapper {
|
|
248
|
+
tag = "Set";
|
|
107
249
|
set = new Set();
|
|
250
|
+
inspect(item) {
|
|
251
|
+
return `Set(${this.set.size}) [${[...this.set].map(item).join(",")}]`;
|
|
252
|
+
}
|
|
253
|
+
toHost(item) {
|
|
254
|
+
return new Set([...this.set].map(item));
|
|
255
|
+
}
|
|
256
|
+
iterator() {
|
|
257
|
+
return this.set.values();
|
|
258
|
+
}
|
|
108
259
|
}
|
|
109
|
-
export class URLSearchParamsObj extends
|
|
260
|
+
export class URLSearchParamsObj extends Wrapper {
|
|
110
261
|
params;
|
|
262
|
+
tag = "URLSearchParams";
|
|
111
263
|
constructor(proto, params) {
|
|
112
264
|
super(proto);
|
|
113
265
|
this.params = params;
|
|
114
266
|
}
|
|
267
|
+
toString() {
|
|
268
|
+
return this.params.toString();
|
|
269
|
+
}
|
|
270
|
+
toHost() {
|
|
271
|
+
return new URLSearchParams(this.params);
|
|
272
|
+
}
|
|
273
|
+
iterator(builtins) {
|
|
274
|
+
return this.params.entries().map((entry) => new Arr(builtins.Array, entry));
|
|
275
|
+
}
|
|
115
276
|
}
|
|
116
|
-
export class HeadersObj extends
|
|
277
|
+
export class HeadersObj extends Wrapper {
|
|
117
278
|
headers;
|
|
279
|
+
tag = "Headers";
|
|
118
280
|
constructor(proto, headers) {
|
|
119
281
|
super(proto);
|
|
120
282
|
this.headers = headers;
|
|
121
283
|
}
|
|
284
|
+
inspect() {
|
|
285
|
+
return `Headers ${JSON.stringify(Object.fromEntries(this.headers))}`;
|
|
286
|
+
}
|
|
287
|
+
toHost() {
|
|
288
|
+
return new Headers(this.headers);
|
|
289
|
+
}
|
|
290
|
+
iterator(builtins) {
|
|
291
|
+
// Bun's Headers typings lack the iterator helpers, so the host iterator is lifted first.
|
|
292
|
+
return Iterator.from(this.headers.entries()).map((entry) => new Arr(builtins.Array, entry));
|
|
293
|
+
}
|
|
122
294
|
}
|
|
123
|
-
export class URLObj extends
|
|
295
|
+
export class URLObj extends Wrapper {
|
|
124
296
|
url;
|
|
297
|
+
tag = "URL";
|
|
125
298
|
searchParams;
|
|
126
299
|
constructor(proto, searchParamsProto, url) {
|
|
127
300
|
super(proto);
|
|
128
301
|
this.url = url;
|
|
129
302
|
this.searchParams = new URLSearchParamsObj(searchParamsProto, url.searchParams);
|
|
130
303
|
}
|
|
304
|
+
toString() {
|
|
305
|
+
return this.url.href;
|
|
306
|
+
}
|
|
307
|
+
toHost() {
|
|
308
|
+
return new URL(this.url.href);
|
|
309
|
+
}
|
|
131
310
|
}
|
|
132
311
|
/** A `Uint8Array`: the host array does the byte clamping and ignores out-of-range writes, as JS does. */
|
|
133
|
-
export class Bytes extends
|
|
312
|
+
export class Bytes extends Wrapper {
|
|
134
313
|
bytes;
|
|
314
|
+
tag = "Uint8Array";
|
|
135
315
|
constructor(proto, bytes) {
|
|
136
316
|
super(proto);
|
|
137
317
|
this.bytes = bytes;
|
|
138
318
|
}
|
|
319
|
+
toString() {
|
|
320
|
+
return this.bytes.join(",");
|
|
321
|
+
}
|
|
322
|
+
inspect() {
|
|
323
|
+
return `Uint8Array(${this.bytes.length}) [${this.bytes.join(",")}]`;
|
|
324
|
+
}
|
|
325
|
+
toHost() {
|
|
326
|
+
return new Uint8Array(this.bytes);
|
|
327
|
+
}
|
|
328
|
+
iterator() {
|
|
329
|
+
return this.bytes.values();
|
|
330
|
+
}
|
|
139
331
|
}
|
|
140
|
-
/**
|
|
141
|
-
export const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
value instanceof
|
|
145
|
-
|
|
146
|
-
value instanceof
|
|
147
|
-
|
|
148
|
-
|
|
332
|
+
/** ToString without consulting program-defined methods. */
|
|
333
|
+
export const coerceToString = (value) => (value instanceof Obj ? value.toString() : String(value));
|
|
334
|
+
/** ToNumber without consulting program-defined methods; tool references are not numbers. */
|
|
335
|
+
export const coerceToNumber = (value) => {
|
|
336
|
+
if (value instanceof Obj)
|
|
337
|
+
return value.toNumber();
|
|
338
|
+
return value instanceof ToolReference ? Number.NaN : Number(value);
|
|
339
|
+
};
|
|
340
|
+
/** ToIntegerOrInfinity: NaN is 0, fractions truncate. */
|
|
341
|
+
export const coerceToInteger = (value) => {
|
|
342
|
+
const number = coerceToNumber(value);
|
|
343
|
+
return Number.isNaN(number) ? 0 : Math.trunc(number);
|
|
344
|
+
};
|
|
345
|
+
/** Values that cannot cross the data boundary: opaque machinery and host-backed wrappers. */
|
|
346
|
+
export const isRuntimeReference = (value) => value instanceof Opaque || value instanceof Wrapper || value instanceof ToolReference;
|
|
149
347
|
const MAX_ARRAY_INDEX = 4_294_967_295;
|
|
150
348
|
export const parseArrayIndex = (key) => {
|
|
151
349
|
const property = String(key);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Exit, Scope } from "effect";
|
|
2
2
|
import type { Diagnostic } from "../codemode.js";
|
|
3
|
-
import { Obj, PromiseObj } from "./objects.js";
|
|
3
|
+
import { Obj, PromiseObj, type Value } from "./objects.js";
|
|
4
4
|
import type { Interpreter } from "./interpreter.js";
|
|
5
5
|
export declare class Pending<R> {
|
|
6
6
|
private readonly scope;
|
|
@@ -13,16 +13,16 @@ export declare class Pending<R> {
|
|
|
13
13
|
constructor(scope: Scope.Scope, proto: Obj);
|
|
14
14
|
createWithSelf(body: (self: {
|
|
15
15
|
promise?: PromiseObj;
|
|
16
|
-
}) => Effect.Effect<
|
|
17
|
-
create(effect: Effect.Effect<
|
|
16
|
+
}) => Effect.Effect<Value, unknown, R>): Effect.Effect<PromiseObj, never, R>;
|
|
17
|
+
create(effect: Effect.Effect<Value, unknown, R>): Effect.Effect<PromiseObj, never, R>;
|
|
18
18
|
markObserved(promise: PromiseObj): void;
|
|
19
|
-
await(promise: PromiseObj): Effect.Effect<Exit.Exit<
|
|
19
|
+
await(promise: PromiseObj): Effect.Effect<Exit.Exit<Value, unknown>>;
|
|
20
20
|
fork(effect: Effect.Effect<unknown, unknown, R>): Effect.Effect<void, never, R>;
|
|
21
21
|
diagnostics(): Array<Diagnostic>;
|
|
22
22
|
interrupt(): Effect.Effect<Array<Diagnostic>>;
|
|
23
23
|
}
|
|
24
|
-
export declare const resolvePromiseValue: <R>(ctx: Interpreter<R>, value:
|
|
24
|
+
export declare const resolvePromiseValue: <R>(ctx: Interpreter<R>, value: Value, own?: {
|
|
25
25
|
promise?: PromiseObj;
|
|
26
|
-
}) => Effect.Effect<
|
|
27
|
-
export declare const resolvePromise: <R>(ctx: Interpreter<R>, value:
|
|
26
|
+
}) => Effect.Effect<Value, unknown, R>;
|
|
27
|
+
export declare const resolvePromise: <R>(ctx: Interpreter<R>, value: Value) => Effect.Effect<PromiseObj, never, R>;
|
|
28
28
|
export declare const promiseGlobal: <R>(ctx: Interpreter<R>) => import("./objects.js").Native<R>;
|