@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.
Files changed (49) hide show
  1. package/dist/data.d.ts +5 -4
  2. package/dist/interpreter/callback.d.ts +10 -15
  3. package/dist/interpreter/callback.js +15 -7
  4. package/dist/interpreter/errors.d.ts +3 -3
  5. package/dist/interpreter/errors.js +1 -2
  6. package/dist/interpreter/execute.d.ts +2 -1
  7. package/dist/interpreter/extensions.d.ts +2 -1
  8. package/dist/interpreter/extensions.js +7 -35
  9. package/dist/interpreter/globals.d.ts +2 -1
  10. package/dist/interpreter/globals.js +1 -1
  11. package/dist/interpreter/interpreter.d.ts +8 -19
  12. package/dist/interpreter/interpreter.js +96 -98
  13. package/dist/interpreter/intrinsics.d.ts +3 -3
  14. package/dist/interpreter/intrinsics.js +2 -0
  15. package/dist/interpreter/model.d.ts +7 -8
  16. package/dist/interpreter/model.js +0 -1
  17. package/dist/interpreter/native.d.ts +5 -5
  18. package/dist/interpreter/objects.d.ts +148 -47
  19. package/dist/interpreter/objects.js +224 -26
  20. package/dist/interpreter/promises.d.ts +7 -7
  21. package/dist/interpreter/promises.js +32 -11
  22. package/dist/interpreter/references.d.ts +8 -7
  23. package/dist/interpreter/references.js +10 -46
  24. package/dist/interpreter/scope.d.ts +5 -4
  25. package/dist/stdlib/array.d.ts +2 -1
  26. package/dist/stdlib/array.js +29 -51
  27. package/dist/stdlib/bytes.js +14 -24
  28. package/dist/stdlib/collections.js +27 -30
  29. package/dist/stdlib/console.d.ts +2 -2
  30. package/dist/stdlib/console.js +6 -50
  31. package/dist/stdlib/date.js +1 -2
  32. package/dist/stdlib/headers.js +10 -22
  33. package/dist/stdlib/iterator.d.ts +1 -1
  34. package/dist/stdlib/iterator.js +294 -6
  35. package/dist/stdlib/json.js +3 -5
  36. package/dist/stdlib/math.js +5 -17
  37. package/dist/stdlib/number.js +8 -21
  38. package/dist/stdlib/object.d.ts +3 -4
  39. package/dist/stdlib/object.js +5 -16
  40. package/dist/stdlib/regexp.d.ts +3 -3
  41. package/dist/stdlib/regexp.js +1 -2
  42. package/dist/stdlib/string.js +10 -20
  43. package/dist/stdlib/url.d.ts +2 -1
  44. package/dist/stdlib/url.js +6 -16
  45. package/dist/stdlib/value.d.ts +0 -3
  46. package/dist/stdlib/value.js +2 -74
  47. package/dist/stdlib/web.js +1 -2
  48. package/dist/tool-runtime.js +38 -28
  49. package/package.json +1 -1
@@ -1,5 +1,7 @@
1
1
  import type { BlockStatement, Expression, Pattern } from "acorn";
2
- import type { Effect, Fiber } from "effect";
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: unknown) => unknown;
11
- export type Setter = (receiver: unknown, value: unknown) => void;
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: unknown;
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
- /** An object owned by the program: own properties plus a prototype link. */
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<unknown>;
40
- constructor(proto: Obj, items?: Array<unknown>);
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
- export declare abstract class Callable extends Obj {
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: ReadonlyArray<Map<string, Binding>>;
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: ReadonlyArray<Map<string, Binding>>, async: boolean, generator: boolean);
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: unknown, args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
59
- export type NativeConstruct<R> = (args: Array<unknown>, newTarget: Callable) => Effect.Effect<unknown, unknown, R>;
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 Obj {
76
- readonly fiber: Fiber.Fiber<unknown, unknown>;
77
- constructor(proto: Obj, fiber: Fiber.Fiber<unknown, unknown>);
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 Obj {
119
+ export declare class GeneratorObj extends Opaque {
80
120
  readonly asynchronous: boolean;
81
- readonly request: (kind: GeneratorRequestKind, value: unknown) => Effect.Effect<unknown, unknown, unknown>;
82
- constructor(proto: Obj, asynchronous: boolean, request: (kind: GeneratorRequestKind, value: unknown) => Effect.Effect<unknown, unknown, unknown>);
83
- }
84
- /** A built-in collection iterator: live over the host collection, yielding program values. */
85
- export declare class IteratorObj extends Obj {
86
- readonly iterator: IteratorObject<unknown>;
87
- constructor(proto: Obj, iterator: IteratorObject<unknown>);
88
- }
89
- export declare class DateObj extends Obj {
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 Obj {
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
- export declare class MapObj extends Obj {
98
- readonly map: Map<unknown, unknown>;
99
- }
100
- export declare class SetObj extends Obj {
101
- readonly set: Set<unknown>;
102
- }
103
- export declare class URLSearchParamsObj extends Obj {
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 Obj {
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 Obj {
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 Obj {
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
- /** Built-in objects that wrap a host value; data-like, but never plain data. */
122
- export declare const isWrapper: (value: unknown) => value is DateObj | RegExpObj | MapObj | SetObj | URLObj | URLSearchParamsObj | HeadersObj | Bytes;
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) => unknown;
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?: unknown) => unknown;
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: unknown, proto: Obj) => boolean;
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: unknown) => boolean;
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: unknown, attrs?: Attributes) => void;
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, unknown]>;
145
- export declare const record: (proto: Obj, fields: Record<string, unknown>) => Obj;
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
- /** An object owned by the program: own properties plus a prototype link. */
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 Obj {
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 Obj {
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 Obj {
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 built-in collection iterator: live over the host collection, yielding program values. */
82
- export class IteratorObj extends Obj {
83
- iterator;
84
- constructor(proto, iterator) {
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.iterator = iterator;
189
+ this.cursor = cursor;
190
+ }
191
+ get describe() {
192
+ return "an iterator";
87
193
  }
88
194
  }
89
- export class DateObj extends Obj {
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 Obj {
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 Obj {
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 Obj {
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 Obj {
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 Obj {
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 Obj {
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 Obj {
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
- /** Built-in objects that wrap a host value; data-like, but never plain data. */
141
- export const isWrapper = (value) => value instanceof DateObj ||
142
- value instanceof RegExpObj ||
143
- value instanceof MapObj ||
144
- value instanceof SetObj ||
145
- value instanceof URLObj ||
146
- value instanceof URLSearchParamsObj ||
147
- value instanceof HeadersObj ||
148
- value instanceof Bytes;
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<unknown, unknown, R>): Effect.Effect<PromiseObj, never, R>;
17
- create(effect: Effect.Effect<unknown, unknown, R>): Effect.Effect<PromiseObj, never, R>;
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<unknown, unknown>>;
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: unknown, own?: {
24
+ export declare const resolvePromiseValue: <R>(ctx: Interpreter<R>, value: Value, own?: {
25
25
  promise?: PromiseObj;
26
- }) => Effect.Effect<unknown, unknown, R>;
27
- export declare const resolvePromise: <R>(ctx: Interpreter<R>, value: unknown) => Effect.Effect<PromiseObj, never, R>;
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>;