@opencode/codemode 0.0.0-dev-19631 → 0.0.0-dev-19633

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/codemode.js +1 -1
  2. package/dist/data.d.ts +3 -3
  3. package/dist/data.js +37 -31
  4. package/dist/interpreter/callback.d.ts +20 -0
  5. package/dist/interpreter/{runner.js → callback.js} +10 -10
  6. package/dist/interpreter/errors.d.ts +5 -5
  7. package/dist/interpreter/errors.js +21 -22
  8. package/dist/interpreter/execute.d.ts +2 -2
  9. package/dist/interpreter/execute.js +11 -11
  10. package/dist/interpreter/extensions.d.ts +2 -2
  11. package/dist/interpreter/extensions.js +42 -36
  12. package/dist/interpreter/generators.d.ts +2 -3
  13. package/dist/interpreter/generators.js +8 -8
  14. package/dist/interpreter/globals.d.ts +2 -12
  15. package/dist/interpreter/globals.js +41 -37
  16. package/dist/interpreter/interpreter.d.ts +31 -0
  17. package/dist/interpreter/{runtime.js → interpreter.js} +118 -117
  18. package/dist/interpreter/intrinsics.d.ts +5 -5
  19. package/dist/interpreter/intrinsics.js +16 -10
  20. package/dist/interpreter/model.d.ts +3 -3
  21. package/dist/interpreter/model.js +1 -1
  22. package/dist/interpreter/native.d.ts +9 -9
  23. package/dist/interpreter/native.js +9 -9
  24. package/dist/interpreter/objects.d.ts +51 -46
  25. package/dist/interpreter/objects.js +57 -40
  26. package/dist/interpreter/promises.d.ts +13 -13
  27. package/dist/interpreter/promises.js +70 -70
  28. package/dist/interpreter/references.js +17 -15
  29. package/dist/openapi/types.d.ts +1 -1
  30. package/dist/stdlib/array.d.ts +3 -3
  31. package/dist/stdlib/array.js +31 -31
  32. package/dist/stdlib/bytes.d.ts +10 -0
  33. package/dist/stdlib/bytes.js +228 -0
  34. package/dist/stdlib/collections.d.ts +4 -4
  35. package/dist/stdlib/collections.js +55 -55
  36. package/dist/stdlib/console.d.ts +3 -3
  37. package/dist/stdlib/console.js +24 -22
  38. package/dist/stdlib/date.d.ts +2 -2
  39. package/dist/stdlib/date.js +19 -19
  40. package/dist/stdlib/json.d.ts +3 -3
  41. package/dist/stdlib/json.js +24 -24
  42. package/dist/stdlib/math.d.ts +3 -3
  43. package/dist/stdlib/math.js +7 -7
  44. package/dist/stdlib/number.d.ts +3 -3
  45. package/dist/stdlib/number.js +11 -11
  46. package/dist/stdlib/object.d.ts +5 -5
  47. package/dist/stdlib/object.js +41 -39
  48. package/dist/stdlib/regexp.d.ts +6 -6
  49. package/dist/stdlib/regexp.js +24 -24
  50. package/dist/stdlib/string.d.ts +2 -2
  51. package/dist/stdlib/string.js +24 -24
  52. package/dist/stdlib/url.d.ts +6 -6
  53. package/dist/stdlib/url.js +39 -39
  54. package/dist/stdlib/value.d.ts +3 -3
  55. package/dist/stdlib/value.js +18 -14
  56. package/dist/stdlib/web.d.ts +4 -4
  57. package/dist/stdlib/web.js +19 -5
  58. package/dist/tool-runtime.d.ts +2 -2
  59. package/dist/tool-runtime.js +2 -2
  60. package/package.json +1 -1
  61. package/dist/interpreter/runner.d.ts +0 -27
  62. package/dist/interpreter/runtime.d.ts +0 -19
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
2
  import { constructor, methods, prototypeFrom, receiver } from "../interpreter/native.js";
3
3
  import { syntaxError, typeError } from "../interpreter/model.js";
4
- import { define, defineAccessor, getOwn, ProgramArray, ProgramObject, ProgramRegExp, record, set, } from "../interpreter/objects.js";
4
+ import { define, defineAccessor, getOwn, Arr, Obj, RegExpObj, record, set } from "../interpreter/objects.js";
5
5
  import { coerceToNumber, coerceToString } from "./value.js";
6
6
  const flagProperties = [
7
7
  "hasIndices",
@@ -19,7 +19,7 @@ export const toHostRegex = (arg, method, extraFlags = "") => {
19
19
  // Native parity: an undefined pattern behaves as an empty pattern.
20
20
  if (arg === undefined)
21
21
  return new RegExp("", extraFlags);
22
- if (arg instanceof ProgramRegExp)
22
+ if (arg instanceof RegExpObj)
23
23
  return arg.regex;
24
24
  if (typeof arg === "string") {
25
25
  try {
@@ -31,28 +31,28 @@ export const toHostRegex = (arg, method, extraFlags = "") => {
31
31
  }
32
32
  throw typeError(`String.${method} expects a regular expression (a /pattern/flags literal or new RegExp(...)) or a string pattern, not ${arg === null ? "null" : typeof arg}.`);
33
33
  };
34
- export const matchToValue = (protos, match) => {
35
- const result = new ProgramArray(protos.Array, Array.from(match, (group) => group));
34
+ export const matchToValue = (builtins, match) => {
35
+ const result = new Arr(builtins.Array, Array.from(match, (group) => group));
36
36
  if (match.index !== undefined)
37
37
  define(result, "index", match.index);
38
38
  if (match.input !== undefined)
39
39
  define(result, "input", match.input);
40
40
  if (match.groups)
41
- define(result, "groups", record(protos.Object, match.groups));
41
+ define(result, "groups", record(builtins.Object, match.groups));
42
42
  if (match.indices)
43
- define(result, "indices", indicesToValue(protos, match.indices));
43
+ define(result, "indices", indicesToValue(builtins, match.indices));
44
44
  return result;
45
45
  };
46
- export const constructRegExp = (protos, args, proto = protos.RegExp) => {
46
+ export const constructRegExp = (builtins, args, proto = builtins.RegExp) => {
47
47
  const first = args[0];
48
- const pattern = first instanceof ProgramRegExp ? first.regex.source : first === undefined ? "" : coerceToString(first);
48
+ const pattern = first instanceof RegExpObj ? first.regex.source : first === undefined ? "" : coerceToString(first);
49
49
  const flagsArg = args[1];
50
50
  if (flagsArg !== undefined && typeof flagsArg !== "string") {
51
51
  throw syntaxError(`RegExp flags must be a string of flag characters (e.g. "g", "gi"), not ${flagsArg === null ? "null" : typeof flagsArg}.`);
52
52
  }
53
- const flags = flagsArg ?? (first instanceof ProgramRegExp ? first.regex.flags : "");
53
+ const flags = flagsArg ?? (first instanceof RegExpObj ? first.regex.flags : "");
54
54
  try {
55
- return new ProgramRegExp(proto, pattern, flags);
55
+ return new RegExpObj(proto, pattern, flags);
56
56
  }
57
57
  catch (error) {
58
58
  const reason = regexFailureReason(error);
@@ -68,16 +68,16 @@ const toLength = (value) => {
68
68
  return Math.min(Math.floor(number), Number.MAX_SAFE_INTEGER);
69
69
  };
70
70
  // RegExp constructs identically with or without new, like JS.
71
- export const regexpGlobal = (runner) => {
72
- const protos = runner.prototypes;
73
- const proto = protos.RegExp;
74
- const regexp = constructor(protos, proto, {
71
+ export const regexpGlobal = (ctx) => {
72
+ const builtins = ctx.builtins;
73
+ const proto = builtins.RegExp;
74
+ const regexp = constructor(builtins, proto, {
75
75
  name: "RegExp",
76
76
  length: 2,
77
- call: (_, args) => Effect.sync(() => constructRegExp(protos, args)),
78
- construct: (args, newTarget) => Effect.sync(() => constructRegExp(protos, args, prototypeFrom(newTarget, proto))),
77
+ call: (_, args) => Effect.sync(() => constructRegExp(builtins, args)),
78
+ construct: (args, newTarget) => Effect.sync(() => constructRegExp(builtins, args, prototypeFrom(newTarget, proto))),
79
79
  });
80
- methods(protos, regexp, [
80
+ methods(builtins, regexp, [
81
81
  [
82
82
  "escape",
83
83
  1,
@@ -88,7 +88,7 @@ export const regexpGlobal = (runner) => {
88
88
  },
89
89
  ],
90
90
  ]);
91
- const self = (thisValue, name) => receiver(ProgramRegExp, thisValue, `RegExp.prototype.${name}`);
91
+ const self = (thisValue, name) => receiver(RegExpObj, thisValue, `RegExp.prototype.${name}`);
92
92
  defineAccessor(proto, "source", (thisValue) => self(thisValue, "source").regex.source);
93
93
  defineAccessor(proto, "flags", (thisValue) => self(thisValue, "flags").regex.flags);
94
94
  for (const name of flagProperties)
@@ -107,22 +107,22 @@ export const regexpGlobal = (runner) => {
107
107
  set(value, "lastIndex", value.regex.lastIndex);
108
108
  if (name === "test")
109
109
  return matched !== null;
110
- return matched === null ? null : matchToValue(protos, matched);
110
+ return matched === null ? null : matchToValue(builtins, matched);
111
111
  },
112
112
  ];
113
- methods(protos, proto, [
113
+ methods(builtins, proto, [
114
114
  run("exec"),
115
115
  run("test"),
116
116
  ["toString", 0, (thisValue) => coerceToString(self(thisValue, "toString"))],
117
117
  ]);
118
118
  return regexp;
119
119
  };
120
- const indicesToValue = (protos, indices) => {
121
- const range = (pair) => pair === undefined ? undefined : new ProgramArray(protos.Array, [...pair]);
122
- const result = new ProgramArray(protos.Array, Array.from(indices, range));
120
+ const indicesToValue = (builtins, indices) => {
121
+ const range = (pair) => pair === undefined ? undefined : new Arr(builtins.Array, [...pair]);
122
+ const result = new Arr(builtins.Array, Array.from(indices, range));
123
123
  const groups = indices.groups;
124
124
  define(result, "groups", groups === undefined
125
125
  ? undefined
126
- : record(protos.Object, Object.fromEntries(Object.entries(groups).map(([key, pair]) => [key, range(pair)]))));
126
+ : record(builtins.Object, Object.fromEntries(Object.entries(groups).map(([key, pair]) => [key, range(pair)]))));
127
127
  return result;
128
128
  };
@@ -1,2 +1,2 @@
1
- import { type Runner } from "../interpreter/runner.js";
2
- export declare const stringGlobal: <R>(runner: Runner<R>) => import("../interpreter/objects.js").NativeFunction<R>;
1
+ import type { Interpreter } from "../interpreter/interpreter.js";
2
+ export declare const stringGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
@@ -3,9 +3,9 @@ import { toProgram } from "../data.js";
3
3
  import { constructor, methods } from "../interpreter/native.js";
4
4
  import { checkArrayLength, checkStringLength } from "../interpreter/limits.js";
5
5
  import { invalidData, rangeError, typeError } from "../interpreter/model.js";
6
- import { ProgramArray, ProgramPromise, ProgramRegExp, record } from "../interpreter/objects.js";
6
+ import { Arr, PromiseObj, RegExpObj, record } from "../interpreter/objects.js";
7
7
  import { containsOpaqueReference, typeofValue } from "../interpreter/references.js";
8
- import { applyCollectionCallback, isSupportedCallback } from "../interpreter/runner.js";
8
+ import { applyCollectionCallback, isSupportedCallback } from "../interpreter/callback.js";
9
9
  import { matchToValue, toHostRegex } from "./regexp.js";
10
10
  import { coerceToNumber, coerceToString, coercion } from "./value.js";
11
11
  // console is intercepted by the interpreter before reaching here.
@@ -20,9 +20,9 @@ const replaceAllNeedsGlobal = (pattern) => {
20
20
  throw typeError(`String.replaceAll requires a regular expression with the global (g) flag: write /${pattern.source}/${pattern.flags}g, or use String.replace to replace only the first match.`);
21
21
  }
22
22
  };
23
- const replaceWithCallback = (runner, value, name, args) => {
24
- const protos = runner.prototypes;
25
- const apply = applyCollectionCallback(runner, args[1], `String.${name}`);
23
+ const replaceWithCallback = (ctx, value, name, args) => {
24
+ const builtins = ctx.builtins;
25
+ const apply = applyCollectionCallback(ctx, args[1], `String.${name}`);
26
26
  const matches = [];
27
27
  const collect = (...callbackArgs) => {
28
28
  const match = callbackArgs[0];
@@ -33,12 +33,12 @@ const replaceWithCallback = (runner, value, name, args) => {
33
33
  throw typeError(`String.${name} produced an invalid replacement match.`);
34
34
  }
35
35
  if (hasGroups)
36
- callbackArgs[callbackArgs.length - 1] = record(protos.Object, groups);
36
+ callbackArgs[callbackArgs.length - 1] = record(builtins.Object, groups);
37
37
  matches.push({ match, offset, args: callbackArgs });
38
38
  return match;
39
39
  };
40
40
  const pattern = args[0];
41
- if (pattern instanceof ProgramRegExp) {
41
+ if (pattern instanceof RegExpObj) {
42
42
  if (name === "replaceAll")
43
43
  replaceAllNeedsGlobal(pattern.regex);
44
44
  if (name === "replace")
@@ -58,21 +58,21 @@ const replaceWithCallback = (runner, value, name, args) => {
58
58
  let end = 0;
59
59
  for (const match of matches) {
60
60
  const replacement = yield* apply(match.args);
61
- output.push(value.slice(end, match.offset), replacement instanceof ProgramPromise
61
+ output.push(value.slice(end, match.offset), replacement instanceof PromiseObj
62
62
  ? "[object Promise]"
63
- : coerceToString(toProgram(protos, replacement, `String.${name} replacer result`)));
63
+ : coerceToString(toProgram(builtins, replacement, `String.${name} replacer result`)));
64
64
  end = match.offset + match.match.length;
65
65
  }
66
66
  output.push(value.slice(end));
67
67
  return output.join("");
68
68
  });
69
69
  };
70
- export const stringGlobal = (runner) => {
71
- const protos = runner.prototypes;
72
- const string = constructor(protos, protos.String, {
70
+ export const stringGlobal = (ctx) => {
71
+ const builtins = ctx.builtins;
72
+ const string = constructor(builtins, builtins.String, {
73
73
  name: "String",
74
74
  length: 1,
75
- call: coercion(runner, "String").call,
75
+ call: coercion(ctx, "String").call,
76
76
  });
77
77
  const codeUnits = (name, op) => [
78
78
  name,
@@ -84,7 +84,7 @@ export const stringGlobal = (runner) => {
84
84
  return arg;
85
85
  })),
86
86
  ];
87
- methods(protos, string, [
87
+ methods(builtins, string, [
88
88
  codeUnits("fromCharCode", String.fromCharCode),
89
89
  codeUnits("fromCodePoint", String.fromCodePoint),
90
90
  ]);
@@ -102,7 +102,7 @@ export const stringGlobal = (runner) => {
102
102
  const optNum = (name, args, index) => args[index] === undefined ? undefined : num(name, args, index);
103
103
  const optStr = (name, args, index) => args[index] === undefined ? undefined : str(name, args, index);
104
104
  const rejectRegex = (name, args) => {
105
- if (args[0] instanceof ProgramRegExp) {
105
+ if (args[0] instanceof RegExpObj) {
106
106
  throw typeError(`String.${name} cannot take a regular expression; use regex.test(string) or String.search instead.`);
107
107
  }
108
108
  };
@@ -113,11 +113,11 @@ export const stringGlobal = (runner) => {
113
113
  ];
114
114
  const replace = (name) => simple(name, 2, (value, args) => {
115
115
  if (isSupportedCallback(args[1]))
116
- return replaceWithCallback(runner, value, name, args);
116
+ return replaceWithCallback(ctx, value, name, args);
117
117
  if (typeofValue(args[1]) === "function") {
118
118
  throw typeError(`String.${name} cannot use this callable as a replacer; wrap it in an arrow function, e.g. (match) => tools.ns.tool(match).`);
119
119
  }
120
- if (args[0] instanceof ProgramRegExp) {
120
+ if (args[0] instanceof RegExpObj) {
121
121
  const pattern = args[0].regex;
122
122
  const replacement = str(name, args, 1);
123
123
  if (name === "replaceAll")
@@ -128,7 +128,7 @@ export const stringGlobal = (runner) => {
128
128
  return value.replace(str(name, args, 0), str(name, args, 1));
129
129
  return value.replaceAll(str(name, args, 0), str(name, args, 1));
130
130
  });
131
- methods(protos, protos.String, [
131
+ methods(builtins, builtins.String, [
132
132
  simple("toString", 0, (value) => value),
133
133
  simple("valueOf", 0, (value) => value),
134
134
  simple("toLowerCase", 0, (value) => value.toLowerCase()),
@@ -150,14 +150,14 @@ export const stringGlobal = (runner) => {
150
150
  }
151
151
  }),
152
152
  simple("split", 2, (value, args) => {
153
- const wrap = (parts) => new ProgramArray(protos.Array, parts);
153
+ const wrap = (parts) => new Arr(builtins.Array, parts);
154
154
  // Native: an undefined separator returns the whole string, not a split on "undefined",
155
155
  // unless the limit truncates to zero.
156
156
  const requestedLimit = optNum("split", args, 1);
157
157
  if (args[0] === undefined) {
158
158
  return wrap(requestedLimit !== undefined && requestedLimit >>> 0 === 0 ? [] : [value]);
159
159
  }
160
- const parts = args[0] instanceof ProgramRegExp
160
+ const parts = args[0] instanceof RegExpObj
161
161
  ? value.split(args[0].regex, requestedLimit)
162
162
  : value.split(str("split", args, 0), requestedLimit === undefined ? undefined : requestedLimit >>> 0);
163
163
  checkArrayLength(parts.length);
@@ -187,8 +187,8 @@ export const stringGlobal = (runner) => {
187
187
  return null;
188
188
  // Preserve the own `index` and `groups` properties on non-global matches.
189
189
  if (pattern.global)
190
- return toProgram(protos, matched, "String.match result");
191
- return matchToValue(protos, matched);
190
+ return toProgram(builtins, matched, "String.match result");
191
+ return matchToValue(builtins, matched);
192
192
  }),
193
193
  simple("matchAll", 1, (value, args) => {
194
194
  const pattern = toHostRegex(args[0], "matchAll", "g");
@@ -198,9 +198,9 @@ export const stringGlobal = (runner) => {
198
198
  const matches = [];
199
199
  for (const match of value.matchAll(pattern)) {
200
200
  checkArrayLength(matches.length + 1);
201
- matches.push(matchToValue(protos, match));
201
+ matches.push(matchToValue(builtins, match));
202
202
  }
203
- return new ProgramArray(protos.Array, matches);
203
+ return new Arr(builtins.Array, matches);
204
204
  }),
205
205
  simple("search", 1, (value, args) => value.search(toHostRegex(args[0], "search"))),
206
206
  simple("repeat", 1, (value, args) => {
@@ -1,8 +1,8 @@
1
- import type { Prototypes } from "../interpreter/intrinsics.js";
2
- import { type Runner } from "../interpreter/runner.js";
3
- export declare const uriArgument: (protos: Prototypes, value: unknown, label: string) => string;
1
+ import type { Builtins } from "../interpreter/intrinsics.js";
2
+ import type { Interpreter } from "../interpreter/interpreter.js";
3
+ export declare const uriArgument: (builtins: Builtins, value: unknown, label: string) => string;
4
4
  type UriFunction = "encodeURI" | "encodeURIComponent" | "decodeURI" | "decodeURIComponent";
5
- export declare const uriGlobal: <R>(runner: Runner<R>, name: UriFunction) => import("../interpreter/objects.js").NativeFunction<R>;
6
- export declare const urlGlobal: <R>(runner: Runner<R>) => import("../interpreter/objects.js").NativeFunction<R>;
7
- export declare const urlSearchParamsGlobal: <R>(runner: Runner<R>) => import("../interpreter/objects.js").NativeFunction<R>;
5
+ export declare const uriGlobal: <R>(ctx: Interpreter<R>, name: UriFunction) => import("../interpreter/objects.js").Native<R>;
6
+ export declare const urlGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
7
+ export declare const urlSearchParamsGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
8
8
  export {};
@@ -2,9 +2,9 @@ import { Effect } from "effect";
2
2
  import { toProgram, ToolRuntimeError } from "../data.js";
3
3
  import { constructor, fn, methods, prototypeFrom, receiver, requiresNew } from "../interpreter/native.js";
4
4
  import { PendingThrow, typeError, uriError } from "../interpreter/model.js";
5
- import { defineAccessor, entries, isWrapper, ProgramArray, ProgramObject, ProgramURL, ProgramURLSearchParams, } from "../interpreter/objects.js";
5
+ import { defineAccessor, entries, isWrapper, Arr, Obj, URLObj, URLSearchParamsObj } from "../interpreter/objects.js";
6
6
  import { isRuntimeReference } from "../interpreter/references.js";
7
- import { applyCollectionCallback, preserveConsumerError } from "../interpreter/runner.js";
7
+ import { applyCollectionCallback, preserveConsumerError } from "../interpreter/callback.js";
8
8
  import { coerceToString } from "./value.js";
9
9
  const urlProperties = [
10
10
  "href",
@@ -19,15 +19,15 @@ const urlProperties = [
19
19
  "search",
20
20
  "hash",
21
21
  ];
22
- export const uriArgument = (protos, value, label) => coerceToString(toProgram(protos, value, label));
22
+ export const uriArgument = (builtins, value, label) => coerceToString(toProgram(builtins, value, label));
23
23
  const uriFunctions = {
24
24
  encodeURI,
25
25
  encodeURIComponent,
26
26
  decodeURI,
27
27
  decodeURIComponent,
28
28
  };
29
- export const uriGlobal = (runner, name) => fn(runner.prototypes, name, 1, (_, args) => {
30
- const value = uriArgument(runner.prototypes, args[0], `${name} input`);
29
+ export const uriGlobal = (ctx, name) => fn(ctx.builtins, name, 1, (_, args) => {
30
+ const value = uriArgument(ctx.builtins, args[0], `${name} input`);
31
31
  try {
32
32
  return uriFunctions[name](value);
33
33
  }
@@ -35,24 +35,24 @@ export const uriGlobal = (runner, name) => fn(runner.prototypes, name, 1, (_, ar
35
35
  throw uriError(`${name} received malformed URI data: ${error instanceof Error ? error.message : String(error)}`);
36
36
  }
37
37
  });
38
- const urlArgument = (protos, value, label) => value instanceof ProgramURL ? value.url.href : uriArgument(protos, value, label);
39
- export const urlGlobal = (runner) => {
40
- const protos = runner.prototypes;
41
- const proto = protos.URL;
38
+ const urlArgument = (builtins, value, label) => value instanceof URLObj ? value.url.href : uriArgument(builtins, value, label);
39
+ export const urlGlobal = (ctx) => {
40
+ const builtins = ctx.builtins;
41
+ const proto = builtins.URL;
42
42
  const construct = (args, into) => {
43
43
  if (args.length === 0) {
44
44
  throw typeError("new URL(...) requires a URL string and an optional base URL.");
45
45
  }
46
- const input = urlArgument(protos, args[0], "new URL input");
47
- const base = args[1] === undefined ? undefined : urlArgument(protos, args[1], "new URL base");
46
+ const input = urlArgument(builtins, args[0], "new URL input");
47
+ const base = args[1] === undefined ? undefined : urlArgument(builtins, args[1], "new URL base");
48
48
  try {
49
- return new ProgramURL(into, protos.URLSearchParams, new URL(input, base));
49
+ return new URLObj(into, builtins.URLSearchParams, new URL(input, base));
50
50
  }
51
51
  catch {
52
52
  throw typeError(`new URL(...) received an invalid URL${base === undefined ? "" : " or base URL"}.`);
53
53
  }
54
54
  };
55
- const url = constructor(protos, proto, {
55
+ const url = constructor(builtins, proto, {
56
56
  name: "URL",
57
57
  length: 1,
58
58
  call: requiresNew("URL"),
@@ -64,19 +64,19 @@ export const urlGlobal = (runner) => {
64
64
  (_, args) => {
65
65
  if (args.length === 0)
66
66
  throw typeError(`URL.${name} requires a URL argument.`);
67
- const input = urlArgument(protos, args[0], `URL.${name} input`);
68
- const base = args[1] === undefined ? undefined : urlArgument(protos, args[1], `URL.${name} base`);
67
+ const input = urlArgument(builtins, args[0], `URL.${name} input`);
68
+ const base = args[1] === undefined ? undefined : urlArgument(builtins, args[1], `URL.${name} base`);
69
69
  try {
70
70
  const parsed = new URL(input, base);
71
- return name === "canParse" ? true : new ProgramURL(proto, protos.URLSearchParams, parsed);
71
+ return name === "canParse" ? true : new URLObj(proto, builtins.URLSearchParams, parsed);
72
72
  }
73
73
  catch {
74
74
  return name === "canParse" ? false : null;
75
75
  }
76
76
  },
77
77
  ];
78
- methods(protos, url, [parse("canParse"), parse("parse")]);
79
- const self = (thisValue, name) => receiver(ProgramURL, thisValue, `URL.prototype.${name}`);
78
+ methods(builtins, url, [parse("canParse"), parse("parse")]);
79
+ const self = (thisValue, name) => receiver(URLObj, thisValue, `URL.prototype.${name}`);
80
80
  for (const name of urlProperties) {
81
81
  defineAccessor(proto, name, (thisValue) => self(thisValue, name).url[name], name === "origin"
82
82
  ? undefined
@@ -84,7 +84,7 @@ export const urlGlobal = (runner) => {
84
84
  const target = self(thisValue, name);
85
85
  try {
86
86
  ;
87
- target.url[name] = uriArgument(protos, value, `URL.${name} value`);
87
+ target.url[name] = uriArgument(builtins, value, `URL.${name} value`);
88
88
  }
89
89
  catch (error) {
90
90
  if (error instanceof PendingThrow || error instanceof ToolRuntimeError)
@@ -94,14 +94,14 @@ export const urlGlobal = (runner) => {
94
94
  });
95
95
  }
96
96
  defineAccessor(proto, "searchParams", (thisValue) => self(thisValue, "searchParams").searchParams);
97
- methods(protos, proto, [
97
+ methods(builtins, proto, [
98
98
  ["toString", 0, (thisValue) => self(thisValue, "toString").url.href],
99
99
  ["toJSON", 0, (thisValue) => self(thisValue, "toJSON").url.href],
100
100
  ]);
101
101
  return url;
102
102
  };
103
- const readPair = (runner, value) => Effect.gen(function* () {
104
- const cursor = yield* runner.syncIterator(value);
103
+ const readPair = (ctx, value) => Effect.gen(function* () {
104
+ const cursor = yield* ctx.iterate(value);
105
105
  if (cursor === undefined) {
106
106
  throw typeError("new URLSearchParams(...) expects iterable [name, value] pairs.");
107
107
  }
@@ -110,14 +110,14 @@ const readPair = (runner, value) => Effect.gen(function* () {
110
110
  const step = yield* cursor.next;
111
111
  if (step.done)
112
112
  return items;
113
- items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(runner.prototypes, step.value, "URLSearchParams pair value"))));
113
+ items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(ctx.builtins, step.value, "URLSearchParams pair value"))));
114
114
  }
115
115
  });
116
- const constructURLSearchParams = (runner, init, proto) => {
117
- const wrap = (params) => new ProgramURLSearchParams(proto, params);
116
+ const constructURLSearchParams = (ctx, init, proto) => {
117
+ const wrap = (params) => new URLSearchParamsObj(proto, params);
118
118
  if (init === undefined)
119
119
  return Effect.succeed(wrap(new URLSearchParams()));
120
- if (init instanceof ProgramURLSearchParams)
120
+ if (init instanceof URLSearchParamsObj)
121
121
  return Effect.succeed(wrap(new URLSearchParams(init.params)));
122
122
  if (typeof init === "string")
123
123
  return Effect.succeed(wrap(new URLSearchParams(init)));
@@ -125,7 +125,7 @@ const constructURLSearchParams = (runner, init, proto) => {
125
125
  return Effect.succeed(wrap(new URLSearchParams(coerceToString(init))));
126
126
  }
127
127
  return Effect.gen(function* () {
128
- const cursor = yield* runner.syncIterator(init);
128
+ const cursor = yield* ctx.iterate(init);
129
129
  if (cursor !== undefined) {
130
130
  const pairs = [];
131
131
  while (true) {
@@ -136,7 +136,7 @@ const constructURLSearchParams = (runner, init, proto) => {
136
136
  }
137
137
  return wrap(new URLSearchParams(pairs.map((entry) => [entry[0] ?? "", entry[1] ?? ""])));
138
138
  }
139
- pairs.push(yield* preserveConsumerError(cursor, readPair(runner, step.value)));
139
+ pairs.push(yield* preserveConsumerError(cursor, readPair(ctx, step.value)));
140
140
  }
141
141
  }
142
142
  if (isRuntimeReference(init)) {
@@ -144,30 +144,30 @@ const constructURLSearchParams = (runner, init, proto) => {
144
144
  }
145
145
  if (isWrapper(init))
146
146
  return wrap(new URLSearchParams());
147
- if (!(init instanceof ProgramObject)) {
147
+ if (!(init instanceof Obj)) {
148
148
  throw typeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.");
149
149
  }
150
150
  return wrap(new URLSearchParams(Object.fromEntries(entries(init).map(([key, value]) => [key, coerceToString(value)]))));
151
151
  });
152
152
  };
153
- export const urlSearchParamsGlobal = (runner) => {
154
- const protos = runner.prototypes;
155
- const proto = protos.URLSearchParams;
156
- const searchParams = constructor(protos, proto, {
153
+ export const urlSearchParamsGlobal = (ctx) => {
154
+ const builtins = ctx.builtins;
155
+ const proto = builtins.URLSearchParams;
156
+ const searchParams = constructor(builtins, proto, {
157
157
  name: "URLSearchParams",
158
158
  call: requiresNew("URLSearchParams"),
159
- construct: (args, newTarget) => constructURLSearchParams(runner, args[0], prototypeFrom(newTarget, proto)),
159
+ construct: (args, newTarget) => constructURLSearchParams(ctx, args[0], prototypeFrom(newTarget, proto)),
160
160
  });
161
- const self = (thisValue, name) => receiver(ProgramURLSearchParams, thisValue, `URLSearchParams.prototype.${name}`);
162
- const wrap = (items) => new ProgramArray(protos.Array, items);
163
- const arg = (name, args, index) => uriArgument(protos, args[index], `URLSearchParams.${name} argument ${index + 1}`);
161
+ const self = (thisValue, name) => receiver(URLSearchParamsObj, thisValue, `URLSearchParams.prototype.${name}`);
162
+ const wrap = (items) => new Arr(builtins.Array, items);
163
+ const arg = (name, args, index) => uriArgument(builtins, args[index], `URLSearchParams.${name} argument ${index + 1}`);
164
164
  const requireArgs = (name, args, count) => {
165
165
  if (args.length < count) {
166
166
  throw typeError(`URLSearchParams.${name} requires ${count} argument${count === 1 ? "" : "s"}.`);
167
167
  }
168
168
  };
169
169
  defineAccessor(proto, "size", (thisValue) => self(thisValue, "size").params.size);
170
- methods(protos, proto, [
170
+ methods(builtins, proto, [
171
171
  [
172
172
  "append",
173
173
  2,
@@ -248,7 +248,7 @@ export const urlSearchParamsGlobal = (runner) => {
248
248
  (thisValue, args) => {
249
249
  requireArgs("forEach", args, 1);
250
250
  const target = self(thisValue, "forEach");
251
- const apply = applyCollectionCallback(runner, args[0], "URLSearchParams.forEach");
251
+ const apply = applyCollectionCallback(ctx, args[0], "URLSearchParams.forEach");
252
252
  return Effect.gen(function* () {
253
253
  for (const [key, value] of Array.from(target.params.entries()))
254
254
  yield* apply([value, key, target]);
@@ -1,9 +1,9 @@
1
- import { type NativeFunction } from "../interpreter/objects.js";
2
- import type { Runner } from "../interpreter/runner.js";
1
+ import { type Native } from "../interpreter/objects.js";
2
+ import type { Interpreter } from "../interpreter/interpreter.js";
3
3
  export declare const compoundOperators: Set<string>;
4
4
  /** The built-in string form of a value, without consulting program-defined `toString` methods. */
5
5
  export declare const coerceToString: (value: unknown) => string;
6
6
  export declare const coerceToNumber: (value: unknown) => number;
7
7
  export type Coercion = "Number" | "String" | "Boolean" | "parseInt" | "parseFloat" | "isFinite" | "isNaN";
8
8
  /** A global coercion function such as `Number` or `parseInt`. */
9
- export declare const coercion: <R>(runner: Runner<R>, name: Coercion, length?: number) => NativeFunction<R>;
9
+ export declare const coercion: <R>(ctx: Interpreter<R>, name: Coercion, length?: number) => Native<R>;
@@ -1,7 +1,7 @@
1
1
  import { toProgram } from "../data.js";
2
2
  import { fn } from "../interpreter/native.js";
3
3
  import { typeError } from "../interpreter/model.js";
4
- import { get, isWrapper, ProgramArray, ProgramDate, ProgramError, ProgramMap, ProgramRegExp, ProgramSet, ProgramURL, ProgramURLSearchParams, } from "../interpreter/objects.js";
4
+ import { get, isWrapper, Arr, Bytes, DateObj, ErrorObj, MapObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "../interpreter/objects.js";
5
5
  export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
6
6
  /** The built-in string form of a value, without consulting program-defined `toString` methods. */
7
7
  export const coerceToString = (value) => {
@@ -9,19 +9,21 @@ export const coerceToString = (value) => {
9
9
  return "null";
10
10
  if (value === undefined)
11
11
  return "undefined";
12
- if (value instanceof ProgramDate)
12
+ if (value instanceof DateObj)
13
13
  return Number.isFinite(value.time) ? new Date(value.time).toISOString() : "Invalid Date";
14
- if (value instanceof ProgramRegExp)
14
+ if (value instanceof RegExpObj)
15
15
  return `/${value.regex.source}/${value.regex.flags}`;
16
- if (value instanceof ProgramMap)
16
+ if (value instanceof MapObj)
17
17
  return "[object Map]";
18
- if (value instanceof ProgramSet)
18
+ if (value instanceof SetObj)
19
19
  return "[object Set]";
20
- if (value instanceof ProgramURL)
20
+ if (value instanceof URLObj)
21
21
  return value.url.href;
22
- if (value instanceof ProgramURLSearchParams)
22
+ if (value instanceof URLSearchParamsObj)
23
23
  return value.params.toString();
24
- if (value instanceof ProgramError) {
24
+ if (value instanceof Bytes)
25
+ return value.bytes.join(",");
26
+ if (value instanceof ErrorObj) {
25
27
  // Match Error.prototype.toString: "name: message", or just one when the other is empty.
26
28
  const name = get(value, "name");
27
29
  const message = get(value, "message");
@@ -33,7 +35,7 @@ export const coerceToString = (value) => {
33
35
  return shownMessage;
34
36
  return `${shownName}: ${shownMessage}`;
35
37
  }
36
- if (value instanceof ProgramArray) {
38
+ if (value instanceof Arr) {
37
39
  return value.items.map((item) => (item === null || item === undefined ? "" : coerceToString(item))).join(",");
38
40
  }
39
41
  if (typeof value === "object")
@@ -41,15 +43,17 @@ export const coerceToString = (value) => {
41
43
  return String(value);
42
44
  };
43
45
  export const coerceToNumber = (value) => {
44
- if (value instanceof ProgramDate)
46
+ if (value instanceof DateObj)
45
47
  return value.time;
48
+ if (value instanceof Bytes)
49
+ return Number(coerceToString(value));
46
50
  if (isWrapper(value))
47
51
  return Number.NaN;
48
- if (value instanceof ProgramArray)
52
+ if (value instanceof Arr)
49
53
  return Number(coerceToString(value));
50
54
  return value !== null && typeof value === "object" ? Number.NaN : Number(value);
51
55
  };
52
- const coerce = (runner, name, args) => {
56
+ const coerce = (ctx, name, args) => {
53
57
  // Native: Number() is 0 and String() is "", unlike their undefined-argument forms; the
54
58
  // other coercers match native through the undefined-argument path below.
55
59
  if (args.length === 0) {
@@ -74,7 +78,7 @@ const coerce = (runner, name, args) => {
74
78
  return parseInt(coerceToString(raw));
75
79
  return parseFloat(coerceToString(raw));
76
80
  }
77
- const value = toProgram(runner.prototypes, raw, `${name} input`);
81
+ const value = toProgram(ctx.builtins, raw, `${name} input`);
78
82
  if (name === "Number")
79
83
  return coerceToNumber(value);
80
84
  if (name === "Boolean")
@@ -95,4 +99,4 @@ const coerce = (runner, name, args) => {
95
99
  return coerceToString(value);
96
100
  };
97
101
  /** A global coercion function such as `Number` or `parseInt`. */
98
- export const coercion = (runner, name, length = 1) => fn(runner.prototypes, name, length, (_, args) => toProgram(runner.prototypes, coerce(runner, name, args), `${name} result`));
102
+ export const coercion = (ctx, name, length = 1) => fn(ctx.builtins, name, length, (_, args) => toProgram(ctx.builtins, coerce(ctx, name, args), `${name} result`));
@@ -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 { Obj } from "../interpreter/objects.js";
2
+ import type { Interpreter } from "../interpreter/interpreter.js";
3
+ export declare const base64Global: <R>(ctx: Interpreter<R>, name: "atob" | "btoa") => import("../interpreter/objects.js").Native<R>;
4
+ export declare const cryptoGlobal: <R>(ctx: Interpreter<R>) => Obj;
@@ -1,10 +1,11 @@
1
1
  import { fn, methods } from "../interpreter/native.js";
2
2
  import { typeError } from "../interpreter/model.js";
3
- import { ProgramObject } from "../interpreter/objects.js";
3
+ import { Bytes, Obj } from "../interpreter/objects.js";
4
+ import { describeValue } from "../interpreter/references.js";
4
5
  import { coerceToString } from "./value.js";
5
6
  // WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies. Invalid input is a
6
7
  // 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) => {
8
+ export const base64Global = (ctx, name) => fn(ctx.builtins, name, 1, (_, args) => {
8
9
  if (args.length === 0)
9
10
  throw typeError(`${name} requires 1 argument (a string)`);
10
11
  const input = coerceToString(args[0]);
@@ -15,8 +16,21 @@ export const base64Global = (runner, name) => fn(runner.prototypes, name, 1, (_,
15
16
  throw typeError("The string contains invalid characters.");
16
17
  }
17
18
  });
18
- export const cryptoGlobal = (runner) => {
19
- const object = new ProgramObject(runner.prototypes.Object);
20
- methods(runner.prototypes, object, [["randomUUID", 0, () => crypto.randomUUID()]]);
19
+ export const cryptoGlobal = (ctx) => {
20
+ const object = new Obj(ctx.builtins.Object);
21
+ methods(ctx.builtins, object, [
22
+ ["randomUUID", 0, () => crypto.randomUUID()],
23
+ [
24
+ "getRandomValues",
25
+ 1,
26
+ (_, args) => {
27
+ if (!(args[0] instanceof Bytes)) {
28
+ throw typeError(`crypto.getRandomValues expects a Uint8Array, received ${describeValue(args[0])}.`);
29
+ }
30
+ crypto.getRandomValues(args[0].bytes);
31
+ return args[0];
32
+ },
33
+ ],
34
+ ]);
21
35
  return object;
22
36
  };