@opencode/codemode 0.0.0-reserved → 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 (84) hide show
  1. package/README.md +184 -2
  2. package/dist/codemode.d.ts +145 -0
  3. package/dist/codemode.js +66 -0
  4. package/dist/data.d.ts +25 -0
  5. package/dist/data.js +153 -0
  6. package/dist/index.d.ts +7 -0
  7. package/dist/index.js +7 -0
  8. package/dist/interpreter/errors.d.ts +7 -0
  9. package/dist/interpreter/errors.js +106 -0
  10. package/dist/interpreter/execute.d.ts +5 -0
  11. package/dist/interpreter/execute.js +171 -0
  12. package/dist/interpreter/globals.d.ts +13 -0
  13. package/dist/interpreter/globals.js +63 -0
  14. package/dist/interpreter/host.d.ts +41 -0
  15. package/dist/interpreter/host.js +44 -0
  16. package/dist/interpreter/methods.d.ts +4 -0
  17. package/dist/interpreter/methods.js +837 -0
  18. package/dist/interpreter/model.d.ts +82 -0
  19. package/dist/interpreter/model.js +86 -0
  20. package/dist/interpreter/objects.d.ts +37 -0
  21. package/dist/interpreter/objects.js +151 -0
  22. package/dist/interpreter/promises.d.ts +31 -0
  23. package/dist/interpreter/promises.js +271 -0
  24. package/dist/interpreter/references.d.ts +7 -0
  25. package/dist/interpreter/references.js +93 -0
  26. package/dist/interpreter/runner.d.ts +24 -0
  27. package/dist/interpreter/runner.js +45 -0
  28. package/dist/interpreter/runtime.d.ts +19 -0
  29. package/dist/interpreter/runtime.js +1940 -0
  30. package/dist/interpreter/scope.d.ts +15 -0
  31. package/dist/interpreter/scope.js +79 -0
  32. package/dist/interpreter/transpile.node.d.ts +5 -0
  33. package/dist/interpreter/transpile.node.js +19 -0
  34. package/dist/interpreter/transpile.workerd.d.ts +5 -0
  35. package/dist/interpreter/transpile.workerd.js +6 -0
  36. package/dist/namespace.d.ts +15 -0
  37. package/dist/namespace.js +7 -0
  38. package/dist/openapi/index.d.ts +7 -0
  39. package/dist/openapi/index.js +101 -0
  40. package/dist/openapi/runtime.d.ts +4 -0
  41. package/dist/openapi/runtime.js +283 -0
  42. package/dist/openapi/spec.d.ts +20 -0
  43. package/dist/openapi/spec.js +583 -0
  44. package/dist/openapi/types.d.ts +122 -0
  45. package/dist/openapi/types.js +2 -0
  46. package/dist/stdlib/array.d.ts +3 -0
  47. package/dist/stdlib/array.js +68 -0
  48. package/dist/stdlib/collections.d.ts +9 -0
  49. package/dist/stdlib/collections.js +173 -0
  50. package/dist/stdlib/console.d.ts +3 -0
  51. package/dist/stdlib/console.js +137 -0
  52. package/dist/stdlib/date.d.ts +8 -0
  53. package/dist/stdlib/date.js +208 -0
  54. package/dist/stdlib/json.d.ts +3 -0
  55. package/dist/stdlib/json.js +101 -0
  56. package/dist/stdlib/math.d.ts +8 -0
  57. package/dist/stdlib/math.js +89 -0
  58. package/dist/stdlib/number.d.ts +4 -0
  59. package/dist/stdlib/number.js +69 -0
  60. package/dist/stdlib/object.d.ts +7 -0
  61. package/dist/stdlib/object.js +106 -0
  62. package/dist/stdlib/regexp.d.ts +10 -0
  63. package/dist/stdlib/regexp.js +120 -0
  64. package/dist/stdlib/string.d.ts +2 -0
  65. package/dist/stdlib/string.js +51 -0
  66. package/dist/stdlib/url.d.ts +16 -0
  67. package/dist/stdlib/url.js +161 -0
  68. package/dist/stdlib/value.d.ts +13 -0
  69. package/dist/stdlib/value.js +120 -0
  70. package/dist/stdlib/web.d.ts +4 -0
  71. package/dist/stdlib/web.js +20 -0
  72. package/dist/tool-error.d.ts +11 -0
  73. package/dist/tool-error.js +9 -0
  74. package/dist/tool-runtime.d.ts +69 -0
  75. package/dist/tool-runtime.js +254 -0
  76. package/dist/tool-schema.d.ts +16 -0
  77. package/dist/tool-schema.js +263 -0
  78. package/dist/tool.d.ts +66 -0
  79. package/dist/tool.js +16 -0
  80. package/dist/tools.d.ts +5 -0
  81. package/dist/tools.js +1 -0
  82. package/dist/values.d.ts +37 -0
  83. package/dist/values.js +56 -0
  84. package/package.json +37 -6
@@ -0,0 +1,122 @@
1
+ import { Effect } from "effect";
2
+ import { HttpClient } from "effect/unstable/http";
3
+ import type { Tool, JsonSchema } from "../tool.js";
4
+ /** A parsed OpenAPI 3.x document. YAML must be parsed by the host. */
5
+ export type Document = Record<string, unknown>;
6
+ /** The operation identity handed to auth resolution and errors. */
7
+ export type Operation = {
8
+ readonly operationId: string | undefined;
9
+ readonly method: string;
10
+ readonly path: string;
11
+ readonly summary: string | undefined;
12
+ readonly description: string | undefined;
13
+ };
14
+ /** A resolved OpenAPI security scheme from `components.securitySchemes`. */
15
+ export type SecurityScheme = {
16
+ readonly type: "apiKey";
17
+ readonly name: string;
18
+ readonly in: "header" | "query" | "cookie";
19
+ } | {
20
+ readonly type: "http";
21
+ readonly scheme: string;
22
+ } | {
23
+ readonly type: "oauth2";
24
+ } | {
25
+ readonly type: "openIdConnect";
26
+ };
27
+ /**
28
+ * Credential material returned by a host auth resolver. `apiKey` uses the scheme's carrier;
29
+ * `header` supports nonstandard schemes.
30
+ */
31
+ export type Credential = {
32
+ readonly type: "bearer";
33
+ readonly token: string;
34
+ } | {
35
+ readonly type: "basic";
36
+ readonly username: string;
37
+ readonly password: string;
38
+ } | {
39
+ readonly type: "apiKey";
40
+ readonly value: string;
41
+ } | {
42
+ readonly type: "header";
43
+ readonly name: string;
44
+ readonly value: string;
45
+ };
46
+ /**
47
+ * Resolves credentials at call time. `undefined` tries the next OR alternative; failure aborts.
48
+ */
49
+ export type AuthResolver = (context: {
50
+ readonly name: string;
51
+ readonly definition: SecurityScheme;
52
+ readonly scopes: ReadonlyArray<string>;
53
+ readonly operation: Operation;
54
+ }) => Effect.Effect<Credential | undefined, unknown>;
55
+ export type Options = {
56
+ readonly spec: Document;
57
+ /** Overrides all document, path, and operation `servers`. Required when no applicable absolute server URL exists. */
58
+ readonly baseUrl?: string | undefined;
59
+ /** Host credential resolution, keyed by security scheme name. */
60
+ readonly auth?: {
61
+ readonly resolve: AuthResolver;
62
+ } | undefined;
63
+ /** Static headers on every request. Not model-visible; declared header params may override them, auth always wins. */
64
+ readonly headers?: Readonly<Record<string, string>> | undefined;
65
+ };
66
+ /** An operation that could not be represented as a tool, and why. */
67
+ export type Skipped = {
68
+ readonly method: string;
69
+ readonly path: string;
70
+ readonly reason: string;
71
+ };
72
+ export type Tools = {
73
+ [name: string]: Tool<HttpClient.HttpClient> | Tools;
74
+ };
75
+ export type Result = {
76
+ /** Namespaced tools; the host places them under a key in its `tools` object. */
77
+ readonly tools: Tools;
78
+ readonly skipped: ReadonlyArray<Skipped>;
79
+ };
80
+ export type Parsed<T> = {
81
+ readonly ok: true;
82
+ readonly value: T;
83
+ } | {
84
+ readonly ok: false;
85
+ readonly reason: string;
86
+ };
87
+ export type InputLocation = "path" | "query" | "header" | "body";
88
+ export type InputField = {
89
+ readonly inputName: string;
90
+ readonly name: string;
91
+ readonly location: InputLocation;
92
+ readonly required: boolean;
93
+ readonly schema: JsonSchema;
94
+ readonly style: "simple" | "form" | "deepObject" | undefined;
95
+ readonly explode: boolean | undefined;
96
+ };
97
+ export type Body = {
98
+ readonly required: boolean;
99
+ readonly mode: "object" | "value";
100
+ readonly mediaType: string;
101
+ };
102
+ export type OperationInput = {
103
+ readonly fields: ReadonlyArray<InputField>;
104
+ readonly body: Body | undefined;
105
+ };
106
+ export type SecurityRequirement = Readonly<Record<string, ReadonlyArray<string>>>;
107
+ export type Plan = {
108
+ readonly operation: Operation;
109
+ readonly url: string;
110
+ readonly fields: ReadonlyArray<InputField>;
111
+ readonly body: Body | undefined;
112
+ readonly security: ReadonlyArray<SecurityRequirement>;
113
+ readonly schemes: Readonly<Record<string, SecurityScheme>>;
114
+ readonly auth: {
115
+ readonly resolve: AuthResolver;
116
+ } | undefined;
117
+ readonly headers: Readonly<Record<string, string>>;
118
+ };
119
+ export type AppliedAuth = {
120
+ readonly headers: Readonly<Record<string, string>>;
121
+ readonly query: Readonly<Record<string, string>>;
122
+ };
@@ -0,0 +1,2 @@
1
+ import { Effect } from "effect";
2
+ import { HttpClient } from "effect/unstable/http";
@@ -0,0 +1,3 @@
1
+ import { HostFunction } from "../interpreter/host.js";
2
+ import { type Runner } from "../interpreter/runner.js";
3
+ export declare const arrayGlobal: <R>(runner: Runner<R>) => HostFunction<R>;
@@ -0,0 +1,68 @@
1
+ import { Effect } from "effect";
2
+ import { HostFunction, sync, syncCall } from "../interpreter/host.js";
3
+ import { CodeModeGenerator, InterpreterRuntimeError } from "../interpreter/model.js";
4
+ import { get, ProgramArray, ProgramObject } from "../interpreter/objects.js";
5
+ import { describeValue } from "../interpreter/references.js";
6
+ import { applyCollectionCallback, preserveConsumerError } from "../interpreter/runner.js";
7
+ const constructArray = (args, node) => {
8
+ if (args.length !== 1)
9
+ return new ProgramArray([...args]);
10
+ const first = args[0];
11
+ if (typeof first !== "number")
12
+ return new ProgramArray([first]);
13
+ if (!Number.isInteger(first) || first < 0 || first > 4294967295) {
14
+ throw new InterpreterRuntimeError("Invalid array length.", node).as("RangeError");
15
+ }
16
+ // Sparse like JS: Array(3) has holes, and combinator loops already skip them.
17
+ return new ProgramArray(new Array(first));
18
+ };
19
+ const arrayLikeSource = (source, node) => {
20
+ if (source instanceof ProgramObject && typeof get(source, "length") === "number") {
21
+ const length = get(source, "length");
22
+ const normalized = Number.isNaN(length) || length <= 0 ? 0 : Math.trunc(length);
23
+ if (normalized > 4_294_967_295)
24
+ throw new RangeError("Invalid array length");
25
+ return { length: normalized, source };
26
+ }
27
+ throw new InterpreterRuntimeError(`Array.from expects an array, string, Map, Set, or array-like value, received ${describeValue(source)}.`, node, "InvalidDataValue");
28
+ };
29
+ const arrayFrom = (runner, args, node) => {
30
+ const source = args[0];
31
+ const apply = args.length < 2 || args[1] === undefined ? undefined : applyCollectionCallback(runner, args[1], "Array.from", node);
32
+ return Effect.gen(function* () {
33
+ const cursor = yield* runner.syncIterator(source, node);
34
+ if (cursor === undefined) {
35
+ if (source instanceof CodeModeGenerator) {
36
+ throw new InterpreterRuntimeError("Array.from expects a synchronous iterable or array-like value.", node).as("TypeError");
37
+ }
38
+ const arrayLike = arrayLikeSource(source, node);
39
+ const values = [];
40
+ for (let index = 0; index < arrayLike.length; index += 1) {
41
+ const item = get(arrayLike.source, index);
42
+ values.push(apply === undefined ? item : yield* apply([item, index]));
43
+ }
44
+ return new ProgramArray(values);
45
+ }
46
+ const values = [];
47
+ let index = 0;
48
+ while (true) {
49
+ const step = yield* cursor.next;
50
+ if (step.done)
51
+ return new ProgramArray(values);
52
+ values.push(apply === undefined ? step.value : yield* preserveConsumerError(cursor, apply([step.value, index])));
53
+ index += 1;
54
+ }
55
+ });
56
+ };
57
+ // Array constructs identically with or without new, like JS.
58
+ export const arrayGlobal = (runner) => new HostFunction({
59
+ name: "Array",
60
+ call: syncCall(constructArray),
61
+ construct: syncCall(constructArray),
62
+ instanceOf: (value) => value instanceof ProgramArray,
63
+ members: {
64
+ isArray: sync("Array.isArray", (args) => args[0] instanceof ProgramArray),
65
+ of: sync("Array.of", (args) => new ProgramArray([...args])),
66
+ from: new HostFunction({ name: "Array.from", call: (args, node) => arrayFrom(runner, args, node) }),
67
+ },
68
+ });
@@ -0,0 +1,9 @@
1
+ import { HostFunction } from "../interpreter/host.js";
2
+ import { type Runner } from "../interpreter/runner.js";
3
+ export declare const arrayMethods: Set<string>;
4
+ export declare const mapMethods: Set<string>;
5
+ export declare const setMethods: Set<string>;
6
+ /** `Map.groupBy` and `Object.groupBy`: the same iteration, keyed into a Map or a data object. */
7
+ export declare const groupBy: <R>(runner: Runner<R>, namespace: "Map" | "Object") => HostFunction<R>;
8
+ export declare const mapGlobal: <R>(runner: Runner<R>) => HostFunction<R>;
9
+ export declare const setGlobal: <R>(runner: Runner<R>) => HostFunction<R>;
@@ -0,0 +1,173 @@
1
+ import { Effect } from "effect";
2
+ import { HostFunction, requiresNew } from "../interpreter/host.js";
3
+ import { InterpreterRuntimeError } from "../interpreter/model.js";
4
+ import { getOwn, ProgramArray, ProgramObject, set } from "../interpreter/objects.js";
5
+ import { describeValue, isRuntimeReference } from "../interpreter/references.js";
6
+ import { applyCollectionCallback, preserveConsumerError, toPrimitive } from "../interpreter/runner.js";
7
+ import { Values } from "../values.js";
8
+ import { coerceToString } from "./value.js";
9
+ export const arrayMethods = new Set([
10
+ "map",
11
+ "filter",
12
+ "find",
13
+ "findIndex",
14
+ "findLast",
15
+ "findLastIndex",
16
+ "some",
17
+ "every",
18
+ "includes",
19
+ "join",
20
+ "reduce",
21
+ "reduceRight",
22
+ "flatMap",
23
+ "forEach",
24
+ "sort",
25
+ "toSorted",
26
+ "slice",
27
+ "concat",
28
+ "indexOf",
29
+ "lastIndexOf",
30
+ "at",
31
+ "flat",
32
+ "reverse",
33
+ "toReversed",
34
+ "with",
35
+ "push",
36
+ "pop",
37
+ "shift",
38
+ "unshift",
39
+ "splice",
40
+ "toSpliced",
41
+ "fill",
42
+ "copyWithin",
43
+ "keys",
44
+ "values",
45
+ "entries",
46
+ ]);
47
+ export const mapMethods = new Set(["get", "set", "has", "delete", "clear", "forEach", "keys", "values", "entries"]);
48
+ export const setMethods = new Set([
49
+ "add",
50
+ "has",
51
+ "delete",
52
+ "clear",
53
+ "forEach",
54
+ "keys",
55
+ "values",
56
+ "entries",
57
+ "union",
58
+ "intersection",
59
+ "difference",
60
+ "symmetricDifference",
61
+ "isSubsetOf",
62
+ "isSupersetOf",
63
+ "isDisjointFrom",
64
+ ]);
65
+ const coerceGroupByPropertyKey = (runner, value, node) => {
66
+ if (value instanceof Values.Promise)
67
+ return Effect.succeed("[object Promise]");
68
+ if (!Values.isValue(value) && isRuntimeReference(value)) {
69
+ throw new InterpreterRuntimeError(`Object.groupBy callback must return a data value, received ${describeValue(value)}.`, node, "InvalidDataValue");
70
+ }
71
+ return Effect.map(toPrimitive(runner, value, "string", node), coerceToString);
72
+ };
73
+ /** `Map.groupBy` and `Object.groupBy`: the same iteration, keyed into a Map or a data object. */
74
+ export const groupBy = (runner, namespace) => new HostFunction({
75
+ name: `${namespace}.groupBy`,
76
+ call: (args, node) => {
77
+ const source = args[0];
78
+ if (source === null || source === undefined) {
79
+ throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node).as("TypeError");
80
+ }
81
+ const apply = applyCollectionCallback(runner, args[1], `${namespace}.groupBy`, node);
82
+ return Effect.gen(function* () {
83
+ const cursor = yield* runner.syncIterator(source, node);
84
+ if (cursor === undefined) {
85
+ throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node).as("TypeError");
86
+ }
87
+ if (namespace === "Map") {
88
+ const result = new Values.Map();
89
+ let index = 0;
90
+ while (true) {
91
+ const step = yield* cursor.next;
92
+ if (step.done)
93
+ return result;
94
+ const item = step.value;
95
+ const key = yield* preserveConsumerError(cursor, apply([item, index]));
96
+ const group = result.map.get(key);
97
+ if (group === undefined)
98
+ result.map.set(key, new ProgramArray([item]));
99
+ else
100
+ group.items.push(item);
101
+ index += 1;
102
+ }
103
+ }
104
+ const result = new ProgramObject();
105
+ let index = 0;
106
+ while (true) {
107
+ const step = yield* cursor.next;
108
+ if (step.done)
109
+ return result;
110
+ const item = step.value;
111
+ const key = yield* preserveConsumerError(cursor, Effect.flatMap(apply([item, index]), (value) => coerceGroupByPropertyKey(runner, value, node)));
112
+ const group = getOwn(result, key);
113
+ if (group === undefined)
114
+ set(result, key, new ProgramArray([item]));
115
+ else
116
+ group.items.push(item);
117
+ index += 1;
118
+ }
119
+ });
120
+ },
121
+ });
122
+ const constructMap = (runner, init, node) => {
123
+ const target = new Values.Map();
124
+ if (init === undefined || init === null)
125
+ return Effect.succeed(target);
126
+ return Effect.gen(function* () {
127
+ const cursor = yield* runner.syncIterator(init, node);
128
+ if (cursor === undefined) {
129
+ throw new InterpreterRuntimeError("new Map(...) expects an iterable of [key, value] pairs or no argument.", node).as("TypeError");
130
+ }
131
+ while (true) {
132
+ const step = yield* cursor.next;
133
+ if (step.done)
134
+ return target;
135
+ yield* preserveConsumerError(cursor, Effect.sync(() => {
136
+ if (!(step.value instanceof ProgramObject)) {
137
+ throw new InterpreterRuntimeError("new Map(...) expects [key, value] pairs as entry objects.", node).as("TypeError");
138
+ }
139
+ target.map.set(getOwn(step.value, 0), getOwn(step.value, 1));
140
+ }));
141
+ }
142
+ });
143
+ };
144
+ const constructSet = (runner, init, node) => {
145
+ const target = new Values.Set();
146
+ if (init === undefined || init === null)
147
+ return Effect.succeed(target);
148
+ return Effect.gen(function* () {
149
+ const cursor = yield* runner.syncIterator(init, node);
150
+ if (cursor === undefined) {
151
+ throw new InterpreterRuntimeError("new Set(...) expects a synchronous iterable or no argument.", node).as("TypeError");
152
+ }
153
+ while (true) {
154
+ const step = yield* cursor.next;
155
+ if (step.done)
156
+ return target;
157
+ target.set.add(step.value);
158
+ }
159
+ });
160
+ };
161
+ export const mapGlobal = (runner) => new HostFunction({
162
+ name: "Map",
163
+ call: requiresNew("Map"),
164
+ construct: (args, node) => constructMap(runner, args[0], node),
165
+ instanceOf: (value) => value instanceof Values.Map,
166
+ members: { groupBy: groupBy(runner, "Map") },
167
+ });
168
+ export const setGlobal = (runner) => new HostFunction({
169
+ name: "Set",
170
+ call: requiresNew("Set"),
171
+ construct: (args, node) => constructSet(runner, args[0], node),
172
+ instanceOf: (value) => value instanceof Values.Set,
173
+ });
@@ -0,0 +1,3 @@
1
+ import { HostNamespace } from "../interpreter/host.js";
2
+ /** Captured console: every method appends one formatted line to `logs`. */
3
+ export declare const consoleGlobal: (logs: Array<string>) => HostNamespace;
@@ -0,0 +1,137 @@
1
+ import { toData, toProgram } from "../data.js";
2
+ import { HostNamespace, sync } from "../interpreter/host.js";
3
+ import { get, ownEntries, ProgramArray, ProgramObject } from "../interpreter/objects.js";
4
+ import { containsOpaqueReference, containsRuntimeReference, isRuntimeReference } from "../interpreter/references.js";
5
+ import { Values } from "../values.js";
6
+ import { coerceToString } from "./value.js";
7
+ const consoleMethods = ["log", "info", "debug", "warn", "error", "dir", "table"];
8
+ /** Captured console: every method appends one formatted line to `logs`. */
9
+ export const consoleGlobal = (logs) => new HostNamespace("console", Object.fromEntries(consoleMethods.map((name) => [
10
+ name,
11
+ sync(`console.${name}`, (args) => {
12
+ logs.push(formatConsoleMessage(name, args));
13
+ return undefined;
14
+ }),
15
+ ])));
16
+ const MAX_CONSOLE_DEPTH = 32;
17
+ const formatConsoleMessage = (name, args) => {
18
+ if (name === "dir")
19
+ return args.length === 0 ? "undefined" : formatConsoleArgument(args[0]);
20
+ if (name === "table")
21
+ return formatConsoleTable(args[0], args[1]);
22
+ const prefix = name === "warn" ? "[warn] " : name === "error" ? "[error] " : name === "debug" ? "[debug] " : "";
23
+ return `${prefix}${args.map((arg) => formatConsoleArgument(arg)).join(" ")}`;
24
+ };
25
+ const formatConsoleArgument = (value) => {
26
+ if (value === undefined)
27
+ return "undefined";
28
+ if (typeof value === "string")
29
+ return value;
30
+ return formatConsoleValue(value, new Set(), 0);
31
+ };
32
+ const formatConsoleValue = (value, seen, depth) => {
33
+ if (value === null || value === undefined)
34
+ return "null";
35
+ if (typeof value === "string")
36
+ return JSON.stringify(value);
37
+ if (typeof value === "number" || typeof value === "boolean")
38
+ return String(value);
39
+ if (typeof value !== "object")
40
+ return String(value);
41
+ if (value instanceof Values.Promise)
42
+ return "[Promise (await it to get its value)]";
43
+ if (value instanceof Values.Date)
44
+ return coerceToString(value);
45
+ if (value instanceof Values.RegExp)
46
+ return coerceToString(value);
47
+ if (value instanceof Values.URL)
48
+ return coerceToString(value);
49
+ if (value instanceof Values.URLSearchParams)
50
+ return coerceToString(value);
51
+ if (depth > MAX_CONSOLE_DEPTH)
52
+ return "...";
53
+ if (seen.has(value))
54
+ return "[Circular]";
55
+ if (value instanceof Values.Map) {
56
+ seen.add(value);
57
+ try {
58
+ const entries = Array.from(value.map.entries(), ([key, item]) => new ProgramArray([key, item]));
59
+ return `Map(${value.map.size}) ${formatConsoleValue(new ProgramArray(entries), seen, depth + 1)}`;
60
+ }
61
+ finally {
62
+ seen.delete(value);
63
+ }
64
+ }
65
+ if (value instanceof Values.Set) {
66
+ seen.add(value);
67
+ try {
68
+ return `Set(${value.set.size}) ${formatConsoleValue(new ProgramArray([...value.set.values()]), seen, depth + 1)}`;
69
+ }
70
+ finally {
71
+ seen.delete(value);
72
+ }
73
+ }
74
+ if (isRuntimeReference(value))
75
+ return "[opaque reference]";
76
+ seen.add(value);
77
+ try {
78
+ if (value instanceof ProgramArray) {
79
+ return `[${value.items.map((item) => formatConsoleValue(item, seen, depth + 1)).join(",")}]`;
80
+ }
81
+ if (!(value instanceof ProgramObject))
82
+ return "[object Object]";
83
+ return `{${ownEntries(value)
84
+ .map(([key, item]) => `${JSON.stringify(key)}:${formatConsoleValue(item, seen, depth + 1)}`)
85
+ .join(",")}}`;
86
+ }
87
+ finally {
88
+ seen.delete(value);
89
+ }
90
+ };
91
+ const formatConsoleTable = (value, columnsArgument) => {
92
+ if (value === undefined)
93
+ return "undefined";
94
+ if (containsOpaqueReference(value))
95
+ return "[opaque reference]";
96
+ const data = toProgram(value, "console.table argument");
97
+ const columns = consoleTableColumns(columnsArgument);
98
+ const rows = consoleTableRows(data, columns);
99
+ const keys = columns ?? Array.from(new Set(rows.flatMap((row) => Object.keys(row.values))));
100
+ const header = ["(index)", ...keys].join("\t");
101
+ return [
102
+ header,
103
+ ...rows.map((row) => [row.index, ...keys.map((key) => formatConsoleTableCell(row.values[key]))].join("\t")),
104
+ ].join("\n");
105
+ };
106
+ const consoleTableColumns = (value) => {
107
+ if (value === undefined)
108
+ return undefined;
109
+ if (containsRuntimeReference(value))
110
+ return undefined;
111
+ const columns = toData(value, "console.table columns", "result");
112
+ return Array.isArray(columns) ? columns.map((column) => String(column)) : undefined;
113
+ };
114
+ const consoleTableRows = (data, columns) => {
115
+ if (data instanceof ProgramArray) {
116
+ return data.items.map((item, index) => ({ index: String(index), values: consoleTableValues(item, columns) }));
117
+ }
118
+ if (data instanceof ProgramObject) {
119
+ return ownEntries(data).map(([index, item]) => ({ index, values: consoleTableValues(item, columns) }));
120
+ }
121
+ return [{ index: "0", values: { Value: data } }];
122
+ };
123
+ const consoleTableValues = (value, columns) => {
124
+ if (value instanceof ProgramObject && !(value instanceof ProgramArray)) {
125
+ if (columns !== undefined)
126
+ return Object.fromEntries(columns.map((column) => [column, get(value, column)]));
127
+ return Object.fromEntries(ownEntries(value));
128
+ }
129
+ return { Value: value };
130
+ };
131
+ const formatConsoleTableCell = (value) => {
132
+ if (value === undefined)
133
+ return "";
134
+ if (typeof value === "string")
135
+ return value;
136
+ return formatConsoleValue(value, new Set(), 0);
137
+ };
@@ -0,0 +1,8 @@
1
+ import { HostFunction } from "../interpreter/host.js";
2
+ import { type AstNode } from "../interpreter/model.js";
3
+ import { type Runner } from "../interpreter/runner.js";
4
+ import { Values } from "../values.js";
5
+ export declare const dateMethods: Set<string>;
6
+ export declare const dateGlobal: <R>(runner: Runner<R>) => HostFunction<R>;
7
+ export declare const dateSetterArgumentCount: (name: string) => number | undefined;
8
+ export declare const invokeDateMethod: (value: Values.Date, name: string, args: Array<number>, node: AstNode, initialTime?: number) => unknown;