@opencode/codemode 0.0.0-dev-19530 → 2.0.0

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 (62) hide show
  1. package/dist/data.d.ts +5 -6
  2. package/dist/data.js +44 -47
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +1 -0
  5. package/dist/interpreter/errors.d.ts +3 -5
  6. package/dist/interpreter/errors.js +22 -51
  7. package/dist/interpreter/execute.js +3 -5
  8. package/dist/interpreter/globals.js +47 -69
  9. package/dist/interpreter/host.d.ts +41 -0
  10. package/dist/interpreter/host.js +44 -0
  11. package/dist/interpreter/methods.d.ts +4 -0
  12. package/dist/interpreter/methods.js +837 -0
  13. package/dist/interpreter/model.d.ts +36 -13
  14. package/dist/interpreter/model.js +45 -15
  15. package/dist/interpreter/objects.d.ts +13 -106
  16. package/dist/interpreter/objects.js +65 -192
  17. package/dist/interpreter/promises.d.ts +13 -12
  18. package/dist/interpreter/promises.js +54 -59
  19. package/dist/interpreter/references.d.ts +0 -1
  20. package/dist/interpreter/references.js +33 -20
  21. package/dist/interpreter/runner.d.ts +11 -15
  22. package/dist/interpreter/runner.js +21 -21
  23. package/dist/interpreter/runtime.d.ts +3 -3
  24. package/dist/interpreter/runtime.js +327 -165
  25. package/dist/interpreter/scope.js +6 -6
  26. package/dist/stdlib/array.d.ts +2 -4
  27. package/dist/stdlib/array.js +32 -424
  28. package/dist/stdlib/collections.d.ts +7 -3
  29. package/dist/stdlib/collections.js +119 -291
  30. package/dist/stdlib/console.d.ts +2 -3
  31. package/dist/stdlib/console.js +30 -35
  32. package/dist/stdlib/date.d.ts +7 -1
  33. package/dist/stdlib/date.js +188 -93
  34. package/dist/stdlib/json.d.ts +2 -2
  35. package/dist/stdlib/json.js +27 -27
  36. package/dist/stdlib/math.d.ts +2 -2
  37. package/dist/stdlib/math.js +76 -96
  38. package/dist/stdlib/number.d.ts +4 -3
  39. package/dist/stdlib/number.js +60 -95
  40. package/dist/stdlib/object.d.ts +4 -4
  41. package/dist/stdlib/object.js +54 -128
  42. package/dist/stdlib/regexp.d.ts +8 -6
  43. package/dist/stdlib/regexp.js +68 -76
  44. package/dist/stdlib/string.d.ts +2 -2
  45. package/dist/stdlib/string.js +50 -213
  46. package/dist/stdlib/url.d.ts +13 -5
  47. package/dist/stdlib/url.js +102 -202
  48. package/dist/stdlib/value.d.ts +9 -5
  49. package/dist/stdlib/value.js +38 -16
  50. package/dist/stdlib/web.d.ts +4 -4
  51. package/dist/stdlib/web.js +10 -12
  52. package/dist/tool-runtime.d.ts +1 -2
  53. package/dist/tool-runtime.js +2 -2
  54. package/dist/values.d.ts +37 -0
  55. package/dist/values.js +56 -0
  56. package/package.json +1 -1
  57. package/dist/interpreter/generators.d.ts +0 -4
  58. package/dist/interpreter/generators.js +0 -25
  59. package/dist/interpreter/intrinsics.d.ts +0 -13
  60. package/dist/interpreter/intrinsics.js +0 -82
  61. package/dist/interpreter/native.d.ts +0 -19
  62. package/dist/interpreter/native.js +0 -40
@@ -1,9 +1,13 @@
1
- import { type NativeFunction } from "../interpreter/objects.js";
2
- import type { Runner } from "../interpreter/runner.js";
1
+ import { type HostFunction, type SyncOptions } from "../interpreter/host.js";
2
+ import { ProgramError } from "../interpreter/objects.js";
3
+ export declare const errorConstructors: Set<string>;
3
4
  export declare const compoundOperators: Set<string>;
4
- /** The built-in string form of a value, without consulting program-defined `toString` methods. */
5
+ export declare const createErrorValue: (name: string, message: string) => ProgramError;
6
+ export declare const createAggregateErrorValue: (errors: Array<unknown>, message: string) => ProgramError;
7
+ export declare const errorBrandName: (value: unknown) => string | undefined;
5
8
  export declare const coerceToString: (value: unknown) => string;
6
9
  export declare const coerceToNumber: (value: unknown) => number;
7
- export type Coercion = "Number" | "String" | "Boolean" | "parseInt" | "parseFloat" | "isFinite" | "isNaN";
10
+ type Coercion = "Number" | "String" | "Boolean" | "parseInt" | "parseFloat" | "isFinite" | "isNaN";
8
11
  /** A global coercion function such as `Number` or `parseInt`. */
9
- export declare const coercion: <R>(runner: Runner<R>, name: Coercion, length?: number) => NativeFunction<R>;
12
+ export declare const coercion: (name: Coercion, options?: SyncOptions) => HostFunction;
13
+ export {};
@@ -1,25 +1,47 @@
1
- import { toProgram } from "../data.js";
2
- import { fn } from "../interpreter/native.js";
1
+ import { sync } from "../interpreter/host.js";
3
2
  import { InterpreterRuntimeError } from "../interpreter/model.js";
4
- import { get, isWrapper, ProgramArray, ProgramDate, ProgramError, ProgramMap, ProgramRegExp, ProgramSet, ProgramURL, ProgramURLSearchParams, } from "../interpreter/objects.js";
3
+ import { toProgram } from "../data.js";
4
+ import { get, ProgramArray, ProgramError, set } from "../interpreter/objects.js";
5
+ import { Values } from "../values.js";
6
+ export const errorConstructors = new Set([
7
+ "Error",
8
+ "TypeError",
9
+ "RangeError",
10
+ "SyntaxError",
11
+ "ReferenceError",
12
+ "EvalError",
13
+ "URIError",
14
+ "AggregateError",
15
+ ]);
5
16
  export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
6
- /** The built-in string form of a value, without consulting program-defined `toString` methods. */
17
+ export const createErrorValue = (name, message) => {
18
+ const value = new ProgramError(name);
19
+ set(value, "name", name);
20
+ set(value, "message", message);
21
+ return value;
22
+ };
23
+ export const createAggregateErrorValue = (errors, message) => {
24
+ const value = createErrorValue("AggregateError", message);
25
+ set(value, "errors", new ProgramArray(errors));
26
+ return value;
27
+ };
28
+ export const errorBrandName = (value) => value instanceof ProgramError ? value.errorName : undefined;
7
29
  export const coerceToString = (value) => {
8
30
  if (value === null)
9
31
  return "null";
10
32
  if (value === undefined)
11
33
  return "undefined";
12
- if (value instanceof ProgramDate)
34
+ if (value instanceof Values.Date)
13
35
  return Number.isFinite(value.time) ? new Date(value.time).toISOString() : "Invalid Date";
14
- if (value instanceof ProgramRegExp)
36
+ if (value instanceof Values.RegExp)
15
37
  return `/${value.regex.source}/${value.regex.flags}`;
16
- if (value instanceof ProgramMap)
38
+ if (value instanceof Values.Map)
17
39
  return "[object Map]";
18
- if (value instanceof ProgramSet)
40
+ if (value instanceof Values.Set)
19
41
  return "[object Set]";
20
- if (value instanceof ProgramURL)
42
+ if (value instanceof Values.URL)
21
43
  return value.url.href;
22
- if (value instanceof ProgramURLSearchParams)
44
+ if (value instanceof Values.URLSearchParams)
23
45
  return value.params.toString();
24
46
  if (value instanceof ProgramError) {
25
47
  // Match Error.prototype.toString: "name: message", or just one when the other is empty.
@@ -41,15 +63,15 @@ export const coerceToString = (value) => {
41
63
  return String(value);
42
64
  };
43
65
  export const coerceToNumber = (value) => {
44
- if (value instanceof ProgramDate)
66
+ if (value instanceof Values.Date)
45
67
  return value.time;
46
- if (isWrapper(value))
68
+ if (Values.isValue(value))
47
69
  return Number.NaN;
48
70
  if (value instanceof ProgramArray)
49
71
  return Number(coerceToString(value));
50
72
  return value !== null && typeof value === "object" ? Number.NaN : Number(value);
51
73
  };
52
- const coerce = (runner, name, args, node) => {
74
+ const coerce = (name, args, node) => {
53
75
  // Native: Number() is 0 and String() is "", unlike their undefined-argument forms; the
54
76
  // other coercers match native through the undefined-argument path below.
55
77
  if (args.length === 0) {
@@ -59,7 +81,7 @@ const coerce = (runner, name, args, node) => {
59
81
  return "";
60
82
  }
61
83
  const raw = args[0];
62
- if (isWrapper(raw)) {
84
+ if (Values.isValue(raw)) {
63
85
  if (name === "Boolean")
64
86
  return true;
65
87
  if (name === "Number")
@@ -74,7 +96,7 @@ const coerce = (runner, name, args, node) => {
74
96
  return parseInt(coerceToString(raw));
75
97
  return parseFloat(coerceToString(raw));
76
98
  }
77
- const value = toProgram(runner.prototypes, raw, `${name} input`);
99
+ const value = toProgram(raw, `${name} input`);
78
100
  if (name === "Number")
79
101
  return coerceToNumber(value);
80
102
  if (name === "Boolean")
@@ -95,4 +117,4 @@ const coerce = (runner, name, args, node) => {
95
117
  return coerceToString(value);
96
118
  };
97
119
  /** A global coercion function such as `Number` or `parseInt`. */
98
- export const coercion = (runner, name, length = 1) => fn(runner.prototypes, name, length, (_, args, node) => toProgram(runner.prototypes, coerce(runner, name, args, node), `${name} result`));
120
+ export const coercion = (name, options = {}) => sync(name, (args, node) => toProgram(coerce(name, args, node), `${name} result`), options);
@@ -1,4 +1,4 @@
1
- import { ProgramObject } from "../interpreter/objects.js";
2
- import type { Runner } from "../interpreter/runner.js";
3
- export declare const base64Global: <R>(runner: Runner<R>, name: "atob" | "btoa") => import("../interpreter/objects.js").NativeFunction<R>;
4
- export declare const cryptoGlobal: <R>(runner: Runner<R>) => ProgramObject;
1
+ import { HostNamespace } from "../interpreter/host.js";
2
+ export declare const atobGlobal: import("../interpreter/host.js").HostFunction<never>;
3
+ export declare const btoaGlobal: import("../interpreter/host.js").HostFunction<never>;
4
+ export declare const cryptoGlobal: HostNamespace;
@@ -1,22 +1,20 @@
1
- import { fn, methods } from "../interpreter/native.js";
1
+ import { HostNamespace, sync } from "../interpreter/host.js";
2
2
  import { InterpreterRuntimeError } from "../interpreter/model.js";
3
- import { ProgramObject } from "../interpreter/objects.js";
4
3
  import { coerceToString } from "./value.js";
5
- // WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies. Invalid input is a
6
- // TypeError as well; browsers throw a DOMException named InvalidCharacterError, which CodeMode does not have.
7
- export const base64Global = (runner, name) => fn(runner.prototypes, name, 1, (_, args, node) => {
4
+ // WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies.
5
+ const base64 = (name) => sync(name, (args, node) => {
8
6
  if (args.length === 0)
9
- throw new InterpreterRuntimeError(`${name} requires 1 argument (a string)`, node);
7
+ throw new InterpreterRuntimeError(`${name} requires 1 argument (a string)`, node).as("TypeError");
10
8
  const input = coerceToString(args[0]);
11
9
  try {
12
10
  return name === "atob" ? atob(input) : btoa(input);
13
11
  }
14
12
  catch {
15
- throw new InterpreterRuntimeError("The string contains invalid characters.", node);
13
+ throw new InterpreterRuntimeError("The string contains invalid characters.", node).as("InvalidCharacterError");
16
14
  }
17
15
  });
18
- export const cryptoGlobal = (runner) => {
19
- const object = new ProgramObject(runner.prototypes.Object);
20
- methods(runner.prototypes, object, [["randomUUID", 0, () => crypto.randomUUID()]]);
21
- return object;
22
- };
16
+ export const atobGlobal = base64("atob");
17
+ export const btoaGlobal = base64("btoa");
18
+ export const cryptoGlobal = new HostNamespace("crypto", {
19
+ randomUUID: sync("crypto.randomUUID", () => crypto.randomUUID()),
20
+ });
@@ -1,5 +1,4 @@
1
1
  import { Effect } from "effect";
2
- import type { Prototypes } from "./interpreter/intrinsics.js";
3
2
  import { type Namespace } from "./namespace.js";
4
3
  import { type Tool } from "./tool.js";
5
4
  import type { Tools } from "./tools.js";
@@ -66,5 +65,5 @@ export type ToolRuntime<R = never> = {
66
65
  readonly keys: (path: ReadonlyArray<string>) => ReadonlyArray<string>;
67
66
  };
68
67
  /** Per-execution call state over tools prepared once for the runtime. */
69
- export declare const make: <R>(prepared: Prepared<R>, prototypes: Prototypes, maxToolCalls: number | undefined, hooks?: ToolCallHooks<R>) => ToolRuntime<R>;
68
+ export declare const make: <R>(prepared: Prepared<R>, maxToolCalls: number | undefined, hooks?: ToolCallHooks<R>) => ToolRuntime<R>;
70
69
  export * as ToolRuntime from "./tool-runtime.js";
@@ -184,7 +184,7 @@ const resolve = (root, path) => {
184
184
  return node.tool;
185
185
  };
186
186
  /** Per-execution call state over tools prepared once for the runtime. */
187
- export const make = (prepared, prototypes, maxToolCalls, hooks) => {
187
+ export const make = (prepared, maxToolCalls, hooks) => {
188
188
  const calls = [];
189
189
  const root = prepared.root;
190
190
  const searchTool = makeSearchTool(prepared.searchIndex);
@@ -234,7 +234,7 @@ export const make = (prepared, prototypes, maxToolCalls, hooks) => {
234
234
  .join("\n")));
235
235
  }));
236
236
  return yield* Effect.try({
237
- try: () => fromData(prototypes, decodeToolOutput(tool, raw), `Result from tool '${name}'`),
237
+ try: () => fromData(decodeToolOutput(tool, raw), `Result from tool '${name}'`),
238
238
  catch: (cause) => new ToolRuntimeError("InvalidToolOutput", `Invalid output from tool '${name}': ${cause}`),
239
239
  });
240
240
  }), call);
@@ -0,0 +1,37 @@
1
+ export * as Values from "./values.js";
2
+ import type { Fiber } from "effect";
3
+ /**
4
+ * Runtime values the interpreter recognizes by class. Each wraps the host value it stands for,
5
+ * so hosts construct these to hand a value to a program and receive them back unchanged.
6
+ */
7
+ export declare class Promise {
8
+ readonly fiber: Fiber.Fiber<unknown, unknown>;
9
+ constructor(fiber: Fiber.Fiber<unknown, unknown>);
10
+ }
11
+ export declare class Date {
12
+ time: number;
13
+ constructor(time: number);
14
+ }
15
+ export declare class RegExp {
16
+ readonly regex: globalThis.RegExp;
17
+ constructor(pattern: string, flags: string);
18
+ get lastIndex(): unknown;
19
+ set lastIndex(value: unknown);
20
+ }
21
+ export declare class Map {
22
+ readonly map: globalThis.Map<unknown, unknown>;
23
+ }
24
+ export declare class Set {
25
+ readonly set: globalThis.Set<unknown>;
26
+ }
27
+ export declare class URLSearchParams {
28
+ readonly params: globalThis.URLSearchParams;
29
+ constructor(params: globalThis.URLSearchParams);
30
+ }
31
+ export declare class URL {
32
+ readonly url: globalThis.URL;
33
+ readonly searchParams: URLSearchParams;
34
+ constructor(url: globalThis.URL);
35
+ }
36
+ /** Data-like runtime values; excludes Promise, which never crosses a boundary. */
37
+ export declare const isValue: (value: unknown) => value is Date | RegExp | Map | Set | URL | URLSearchParams;
package/dist/values.js ADDED
@@ -0,0 +1,56 @@
1
+ export * as Values from "./values.js";
2
+ /**
3
+ * Runtime values the interpreter recognizes by class. Each wraps the host value it stands for,
4
+ * so hosts construct these to hand a value to a program and receive them back unchanged.
5
+ */
6
+ export class Promise {
7
+ fiber;
8
+ constructor(fiber) {
9
+ this.fiber = fiber;
10
+ }
11
+ }
12
+ export class Date {
13
+ time;
14
+ constructor(time) {
15
+ this.time = time;
16
+ }
17
+ }
18
+ export class RegExp {
19
+ regex;
20
+ constructor(pattern, flags) {
21
+ this.regex = new globalThis.RegExp(pattern, flags);
22
+ }
23
+ get lastIndex() {
24
+ return Reflect.get(this.regex, "lastIndex");
25
+ }
26
+ set lastIndex(value) {
27
+ Reflect.set(this.regex, "lastIndex", value);
28
+ }
29
+ }
30
+ export class Map {
31
+ map = new globalThis.Map();
32
+ }
33
+ export class Set {
34
+ set = new globalThis.Set();
35
+ }
36
+ export class URLSearchParams {
37
+ params;
38
+ constructor(params) {
39
+ this.params = params;
40
+ }
41
+ }
42
+ export class URL {
43
+ url;
44
+ searchParams;
45
+ constructor(url) {
46
+ this.url = url;
47
+ this.searchParams = new URLSearchParams(url.searchParams);
48
+ }
49
+ }
50
+ /** Data-like runtime values; excludes Promise, which never crosses a boundary. */
51
+ export const isValue = (value) => value instanceof Date ||
52
+ value instanceof RegExp ||
53
+ value instanceof Map ||
54
+ value instanceof Set ||
55
+ value instanceof URL ||
56
+ value instanceof URLSearchParams;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode/codemode",
4
- "version": "0.0.0-dev-19530",
4
+ "version": "2.0.0",
5
5
  "description": "Effect-native confined code execution over schema-described tools",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -1,4 +0,0 @@
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;
@@ -1,25 +0,0 @@
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
- };
@@ -1,13 +0,0 @@
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 {};
@@ -1,82 +0,0 @@
1
- import { Effect } from "effect";
2
- import { define, hidden, NativeFunction, ProgramArray, ProgramError, ProgramObject } from "./objects.js";
3
- export const errorTypes = [
4
- "Error",
5
- "TypeError",
6
- "RangeError",
7
- "SyntaxError",
8
- "ReferenceError",
9
- "EvalError",
10
- "URIError",
11
- "AggregateError",
12
- ];
13
- export const isErrorType = (name) => errorTypes.includes(name);
14
- const builtins = [
15
- "Object",
16
- "Function",
17
- "Array",
18
- "String",
19
- "Number",
20
- "Boolean",
21
- "Date",
22
- "RegExp",
23
- "Map",
24
- "Set",
25
- "URL",
26
- "URLSearchParams",
27
- "Promise",
28
- "Iterator",
29
- "AsyncIterator",
30
- "Generator",
31
- "AsyncGenerator",
32
- ];
33
- export const createErrorValue = (prototype, message) => {
34
- const value = new ProgramError(prototype);
35
- if (message !== undefined)
36
- define(value, "message", message, hidden);
37
- return value;
38
- };
39
- export const createPrototypes = () => {
40
- const object = new ProgramObject(null);
41
- // Function.prototype is itself callable and returns undefined.
42
- const fn = new NativeFunction(object, { name: "", call: () => Effect.undefined });
43
- const plain = () => new ProgramObject(object);
44
- const error = plain();
45
- define(error, "name", "Error", hidden);
46
- define(error, "message", "", hidden);
47
- const derived = (type) => {
48
- const proto = new ProgramObject(error);
49
- define(proto, "name", type, hidden);
50
- define(proto, "message", "", hidden);
51
- return proto;
52
- };
53
- const iterator = plain();
54
- const asyncIterator = plain();
55
- return {
56
- Object: object,
57
- Function: fn,
58
- Array: new ProgramArray(object),
59
- String: plain(),
60
- Number: plain(),
61
- Boolean: plain(),
62
- Date: plain(),
63
- RegExp: plain(),
64
- Map: plain(),
65
- Set: plain(),
66
- URL: plain(),
67
- URLSearchParams: plain(),
68
- Promise: plain(),
69
- Iterator: iterator,
70
- AsyncIterator: asyncIterator,
71
- Generator: new ProgramObject(iterator),
72
- AsyncGenerator: new ProgramObject(asyncIterator),
73
- Error: error,
74
- TypeError: derived("TypeError"),
75
- RangeError: derived("RangeError"),
76
- SyntaxError: derived("SyntaxError"),
77
- ReferenceError: derived("ReferenceError"),
78
- EvalError: derived("EvalError"),
79
- URIError: derived("URIError"),
80
- AggregateError: derived("AggregateError"),
81
- };
82
- };
@@ -1,19 +0,0 @@
1
- import { Effect } from "effect";
2
- import type { Prototypes } from "./intrinsics.js";
3
- import { type AstNode } from "./model.js";
4
- import { type Callable, NativeFunction, type NativeOptions, ProgramObject } from "./objects.js";
5
- /** A native function body: a plain value, a thrown `InterpreterRuntimeError`, or an Effect. */
6
- export type Impl = (thisValue: unknown, args: Array<unknown>, node: AstNode) => unknown;
7
- export declare const native: <R>(protos: Prototypes, options: NativeOptions<R>) => NativeFunction<R>;
8
- export declare const fn: <R>(protos: Prototypes, name: string, length: number, impl: Impl) => NativeFunction<R>;
9
- export type Method = readonly [name: string, length: number, impl: Impl];
10
- export declare const methods: (protos: Prototypes, target: ProgramObject, table: ReadonlyArray<Method>) => void;
11
- export declare const constants: (target: ProgramObject, table: Record<string, unknown>) => void;
12
- /** A constructor wired to its prototype: `C.prototype === proto` and `proto.constructor === C`. */
13
- export declare const constructor: <R>(protos: Prototypes, proto: ProgramObject, options: NativeOptions<R>) => NativeFunction<R>;
14
- /** The `call` of a constructor that JS requires to be invoked with `new`. */
15
- export declare const requiresNew: (name: string) => (_: unknown, __: Array<unknown>, node: AstNode) => Effect.Effect<never, unknown, never>;
16
- /** The instance prototype for `new` via `newTarget.prototype`, falling back to the built-in's own. */
17
- export declare const prototypeFrom: (newTarget: Callable, fallback: ProgramObject) => ProgramObject;
18
- /** Narrows a method receiver to the built-in it belongs to, or throws the TypeError JS would. */
19
- export declare const receiver: <T extends ProgramObject>(cls: abstract new (...args: never) => T, thisValue: unknown, method: string, node?: AstNode) => T;
@@ -1,40 +0,0 @@
1
- import { Effect } from "effect";
2
- import { InterpreterRuntimeError } from "./model.js";
3
- import { define, frozen, hidden, NativeFunction, ProgramObject } from "./objects.js";
4
- import { describeValue } from "./references.js";
5
- const lift = (impl) => (thisValue, args, node) => Effect.suspend(() => {
6
- const result = impl(thisValue, args, node);
7
- return Effect.isEffect(result) ? result : Effect.succeed(result);
8
- });
9
- export const native = (protos, options) => new NativeFunction(protos.Function, options);
10
- export const fn = (protos, name, length, impl) => native(protos, { name, length, call: lift(impl) });
11
- export const methods = (protos, target, table) => {
12
- for (const [name, length, impl] of table)
13
- define(target, name, fn(protos, name, length, impl), hidden);
14
- };
15
- export const constants = (target, table) => {
16
- for (const [name, value] of Object.entries(table))
17
- define(target, name, value, frozen);
18
- };
19
- /** A constructor wired to its prototype: `C.prototype === proto` and `proto.constructor === C`. */
20
- export const constructor = (protos, proto, options) => {
21
- const ctor = native(protos, options);
22
- define(ctor, "prototype", proto, frozen);
23
- define(proto, "constructor", ctor, hidden);
24
- return ctor;
25
- };
26
- /** The `call` of a constructor that JS requires to be invoked with `new`. */
27
- export const requiresNew = (name) => (_, __, node) => Effect.sync(() => {
28
- throw new InterpreterRuntimeError(`Constructor ${name} requires 'new'.`, node);
29
- });
30
- /** The instance prototype for `new` via `newTarget.prototype`, falling back to the built-in's own. */
31
- export const prototypeFrom = (newTarget, fallback) => {
32
- const proto = newTarget.props.get("prototype");
33
- return proto !== undefined && "value" in proto && proto.value instanceof ProgramObject ? proto.value : fallback;
34
- };
35
- /** Narrows a method receiver to the built-in it belongs to, or throws the TypeError JS would. */
36
- export const receiver = (cls, thisValue, method, node) => {
37
- if (thisValue instanceof cls)
38
- return thisValue;
39
- throw new InterpreterRuntimeError(`${method} called on incompatible receiver ${describeValue(thisValue)}.`, node);
40
- };