@opencode/codemode 0.0.0-beta-19507 → 0.0.0-dev-19276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -6
- package/dist/codemode.d.ts +12 -9
- package/dist/codemode.js +9 -5
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/interpreter/errors.d.ts +6 -4
- package/dist/interpreter/errors.js +10 -25
- package/dist/interpreter/execute.d.ts +3 -4
- package/dist/interpreter/execute.js +18 -11
- package/dist/interpreter/iterator.d.ts +13 -0
- package/dist/interpreter/iterator.js +4 -0
- package/dist/interpreter/methods.d.ts +16 -3
- package/dist/interpreter/methods.js +290 -101
- package/dist/interpreter/model.d.ts +79 -10
- package/dist/interpreter/model.js +102 -2
- package/dist/interpreter/promises.d.ts +13 -15
- package/dist/interpreter/promises.js +52 -70
- package/dist/interpreter/references.d.ts +0 -1
- package/dist/interpreter/references.js +77 -57
- package/dist/interpreter/runtime.d.ts +95 -16
- package/dist/interpreter/runtime.js +960 -549
- package/dist/openapi/spec.js +6 -3
- package/dist/stdlib/collections.d.ts +1 -6
- package/dist/stdlib/collections.js +1 -117
- package/dist/stdlib/console.d.ts +2 -3
- package/dist/stdlib/console.js +28 -39
- package/dist/stdlib/date.d.ts +4 -5
- package/dist/stdlib/date.js +12 -34
- package/dist/stdlib/json.d.ts +6 -3
- package/dist/stdlib/json.js +63 -40
- package/dist/stdlib/math.d.ts +7 -3
- package/dist/stdlib/math.js +153 -85
- package/dist/stdlib/number.d.ts +4 -2
- package/dist/stdlib/number.js +37 -30
- package/dist/stdlib/object.d.ts +6 -6
- package/dist/stdlib/object.js +87 -84
- package/dist/stdlib/promise.d.ts +2 -0
- package/dist/stdlib/promise.js +1 -0
- package/dist/stdlib/regexp.d.ts +7 -6
- package/dist/stdlib/regexp.js +34 -48
- package/dist/stdlib/string.d.ts +3 -1
- package/dist/stdlib/string.js +17 -20
- package/dist/stdlib/url.d.ts +6 -10
- package/dist/stdlib/url.js +25 -102
- package/dist/stdlib/value.d.ts +7 -8
- package/dist/stdlib/value.js +56 -56
- package/dist/tool-runtime.d.ts +15 -16
- package/dist/tool-runtime.js +150 -13
- package/dist/values.d.ts +16 -22
- package/dist/values.js +17 -23
- package/package.json +1 -1
- package/dist/data.d.ts +0 -25
- package/dist/data.js +0 -153
- package/dist/interpreter/globals.d.ts +0 -13
- package/dist/interpreter/globals.js +0 -63
- package/dist/interpreter/host.d.ts +0 -41
- package/dist/interpreter/host.js +0 -44
- package/dist/interpreter/objects.d.ts +0 -37
- package/dist/interpreter/objects.js +0 -151
- package/dist/interpreter/runner.d.ts +0 -24
- package/dist/interpreter/runner.js +0 -45
- package/dist/stdlib/array.d.ts +0 -3
- package/dist/stdlib/array.js +0 -68
- package/dist/stdlib/web.d.ts +0 -4
- package/dist/stdlib/web.js +0 -20
package/dist/openapi/spec.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fromSchemaOpenApi3_0, fromSchemaOpenApi3_1 } from "effect/JsonSchema";
|
|
2
|
+
import { isBlockedMember } from "../tool-runtime.js";
|
|
2
3
|
export const methods = new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
3
4
|
const parameterLocations = ["path", "query", "header"];
|
|
4
5
|
const ignoredHeaderParameters = new Set(["accept", "content-type", "authorization"]);
|
|
@@ -362,7 +363,8 @@ export const operationInput = (document, pathItem, operation) => {
|
|
|
362
363
|
ok: true,
|
|
363
364
|
value: {
|
|
364
365
|
fields: fields.map((field) => {
|
|
365
|
-
const
|
|
366
|
+
const visibleName = isBlockedMember(field.name) ? `${field.name}_2` : field.name;
|
|
367
|
+
const base = conflicts.has(field.name) ? `${field.location}_${visibleName}` : visibleName;
|
|
366
368
|
const next = (index) => {
|
|
367
369
|
const candidate = index === 1 ? base : `${base}_${index}`;
|
|
368
370
|
return used.has(candidate) ? next(index + 1) : candidate;
|
|
@@ -442,10 +444,11 @@ export const operationOutput = (document, operation, definitions) => {
|
|
|
442
444
|
};
|
|
443
445
|
};
|
|
444
446
|
const sanitizeOperationSegment = (raw) => {
|
|
445
|
-
|
|
447
|
+
const base = raw
|
|
446
448
|
.replaceAll(/[^A-Za-z0-9_$]+/g, "_")
|
|
447
449
|
.replace(/^_+|_+$/g, "")
|
|
448
|
-
.replace(/^([0-9])/, "_$1") || "operation"
|
|
450
|
+
.replace(/^([0-9])/, "_$1") || "operation";
|
|
451
|
+
return isBlockedMember(base) ? `${base}_2` : base;
|
|
449
452
|
};
|
|
450
453
|
const fallbackOperationId = (method, path) => [
|
|
451
454
|
method,
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import { HostFunction } from "../interpreter/host.js";
|
|
2
|
-
import { type Runner } from "../interpreter/runner.js";
|
|
3
1
|
export declare const arrayMethods: Set<string>;
|
|
4
2
|
export declare const mapMethods: Set<string>;
|
|
3
|
+
export declare const mapStatics: Set<string>;
|
|
5
4
|
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>;
|
|
@@ -1,11 +1,3 @@
|
|
|
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
1
|
export const arrayMethods = new Set([
|
|
10
2
|
"map",
|
|
11
3
|
"filter",
|
|
@@ -45,6 +37,7 @@ export const arrayMethods = new Set([
|
|
|
45
37
|
"entries",
|
|
46
38
|
]);
|
|
47
39
|
export const mapMethods = new Set(["get", "set", "has", "delete", "clear", "forEach", "keys", "values", "entries"]);
|
|
40
|
+
export const mapStatics = new Set(["groupBy"]);
|
|
48
41
|
export const setMethods = new Set([
|
|
49
42
|
"add",
|
|
50
43
|
"has",
|
|
@@ -62,112 +55,3 @@ export const setMethods = new Set([
|
|
|
62
55
|
"isSupersetOf",
|
|
63
56
|
"isDisjointFrom",
|
|
64
57
|
]);
|
|
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
|
-
});
|
package/dist/stdlib/console.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export declare const consoleGlobal: (logs: Array<string>) => HostNamespace;
|
|
1
|
+
export declare const consoleMethods: Set<string>;
|
|
2
|
+
export declare const formatConsoleMessage: (name: string, args: Array<unknown>) => string;
|
package/dist/stdlib/console.js
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
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
1
|
import { containsOpaqueReference, containsRuntimeReference, isRuntimeReference } from "../interpreter/references.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
])));
|
|
2
|
+
import { copyIn, copyOut } from "../tool-runtime.js";
|
|
3
|
+
import { isCodeModeValue, CodeModeDate, CodeModeMap, CodeModePromise, CodeModeRegExp, CodeModeSet, CodeModeURL, CodeModeURLSearchParams, } from "../values.js";
|
|
4
|
+
import { boundedData, coerceToString } from "./value.js";
|
|
5
|
+
export const consoleMethods = new Set(["log", "info", "debug", "warn", "error", "dir", "table"]);
|
|
16
6
|
const MAX_CONSOLE_DEPTH = 32;
|
|
17
|
-
const formatConsoleMessage = (name, args) => {
|
|
7
|
+
export const formatConsoleMessage = (name, args) => {
|
|
18
8
|
if (name === "dir")
|
|
19
9
|
return args.length === 0 ? "undefined" : formatConsoleArgument(args[0]);
|
|
20
10
|
if (name === "table")
|
|
@@ -38,34 +28,34 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
38
28
|
return String(value);
|
|
39
29
|
if (typeof value !== "object")
|
|
40
30
|
return String(value);
|
|
41
|
-
if (value instanceof
|
|
31
|
+
if (value instanceof CodeModePromise)
|
|
42
32
|
return "[Promise (await it to get its value)]";
|
|
43
|
-
if (value instanceof
|
|
33
|
+
if (value instanceof CodeModeDate)
|
|
44
34
|
return coerceToString(value);
|
|
45
|
-
if (value instanceof
|
|
35
|
+
if (value instanceof CodeModeRegExp)
|
|
46
36
|
return coerceToString(value);
|
|
47
|
-
if (value instanceof
|
|
37
|
+
if (value instanceof CodeModeURL)
|
|
48
38
|
return coerceToString(value);
|
|
49
|
-
if (value instanceof
|
|
39
|
+
if (value instanceof CodeModeURLSearchParams)
|
|
50
40
|
return coerceToString(value);
|
|
51
41
|
if (depth > MAX_CONSOLE_DEPTH)
|
|
52
42
|
return "...";
|
|
53
43
|
if (seen.has(value))
|
|
54
44
|
return "[Circular]";
|
|
55
|
-
if (value instanceof
|
|
45
|
+
if (value instanceof CodeModeMap) {
|
|
56
46
|
seen.add(value);
|
|
57
47
|
try {
|
|
58
|
-
const entries = Array.from(value.map.entries(), ([key, item]) =>
|
|
59
|
-
return `Map(${value.map.size}) ${formatConsoleValue(
|
|
48
|
+
const entries = Array.from(value.map.entries(), ([key, item]) => [key, item]);
|
|
49
|
+
return `Map(${value.map.size}) ${formatConsoleValue(entries, seen, depth + 1)}`;
|
|
60
50
|
}
|
|
61
51
|
finally {
|
|
62
52
|
seen.delete(value);
|
|
63
53
|
}
|
|
64
54
|
}
|
|
65
|
-
if (value instanceof
|
|
55
|
+
if (value instanceof CodeModeSet) {
|
|
66
56
|
seen.add(value);
|
|
67
57
|
try {
|
|
68
|
-
return `Set(${value.set.size}) ${formatConsoleValue(
|
|
58
|
+
return `Set(${value.set.size}) ${formatConsoleValue(Array.from(value.set.values()), seen, depth + 1)}`;
|
|
69
59
|
}
|
|
70
60
|
finally {
|
|
71
61
|
seen.delete(value);
|
|
@@ -75,12 +65,10 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
75
65
|
return "[opaque reference]";
|
|
76
66
|
seen.add(value);
|
|
77
67
|
try {
|
|
78
|
-
if (value
|
|
79
|
-
return `[${value.
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
return `[${value.map((item) => formatConsoleValue(item, seen, depth + 1)).join(",")}]`;
|
|
80
70
|
}
|
|
81
|
-
|
|
82
|
-
return "[object Object]";
|
|
83
|
-
return `{${ownEntries(value)
|
|
71
|
+
return `{${Object.entries(value)
|
|
84
72
|
.map(([key, item]) => `${JSON.stringify(key)}:${formatConsoleValue(item, seen, depth + 1)}`)
|
|
85
73
|
.join(",")}}`;
|
|
86
74
|
}
|
|
@@ -93,7 +81,7 @@ const formatConsoleTable = (value, columnsArgument) => {
|
|
|
93
81
|
return "undefined";
|
|
94
82
|
if (containsOpaqueReference(value))
|
|
95
83
|
return "[opaque reference]";
|
|
96
|
-
const data =
|
|
84
|
+
const data = boundedData(value, "console.table argument");
|
|
97
85
|
const columns = consoleTableColumns(columnsArgument);
|
|
98
86
|
const rows = consoleTableRows(data, columns);
|
|
99
87
|
const keys = columns ?? Array.from(new Set(rows.flatMap((row) => Object.keys(row.values))));
|
|
@@ -108,23 +96,24 @@ const consoleTableColumns = (value) => {
|
|
|
108
96
|
return undefined;
|
|
109
97
|
if (containsRuntimeReference(value))
|
|
110
98
|
return undefined;
|
|
111
|
-
const columns =
|
|
99
|
+
const columns = copyOut(copyIn(value, "console.table columns"), "nullify");
|
|
112
100
|
return Array.isArray(columns) ? columns.map((column) => String(column)) : undefined;
|
|
113
101
|
};
|
|
114
102
|
const consoleTableRows = (data, columns) => {
|
|
115
|
-
if (data
|
|
116
|
-
return data.
|
|
103
|
+
if (Array.isArray(data)) {
|
|
104
|
+
return data.map((item, index) => ({ index: String(index), values: consoleTableValues(item, columns) }));
|
|
117
105
|
}
|
|
118
|
-
if (data
|
|
119
|
-
return
|
|
106
|
+
if (data !== null && typeof data === "object" && !isCodeModeValue(data)) {
|
|
107
|
+
return Object.entries(data).map(([index, item]) => ({ index, values: consoleTableValues(item, columns) }));
|
|
120
108
|
}
|
|
121
109
|
return [{ index: "0", values: { Value: data } }];
|
|
122
110
|
};
|
|
123
111
|
const consoleTableValues = (value, columns) => {
|
|
124
|
-
if (value
|
|
112
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value) && !isCodeModeValue(value)) {
|
|
113
|
+
const source = value;
|
|
125
114
|
if (columns !== undefined)
|
|
126
|
-
return Object.fromEntries(columns.map((column) => [column,
|
|
127
|
-
return Object.fromEntries(
|
|
115
|
+
return Object.fromEntries(columns.map((column) => [column, source[column]]));
|
|
116
|
+
return Object.fromEntries(Object.entries(source));
|
|
128
117
|
}
|
|
129
118
|
return { Value: value };
|
|
130
119
|
};
|
package/dist/stdlib/date.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { HostFunction } from "../interpreter/host.js";
|
|
2
1
|
import { type AstNode } from "../interpreter/model.js";
|
|
3
|
-
import {
|
|
4
|
-
import { Values } from "../values.js";
|
|
2
|
+
import { CodeModeDate } from "../values.js";
|
|
5
3
|
export declare const dateMethods: Set<string>;
|
|
6
|
-
export declare const
|
|
4
|
+
export declare const dateStatics: Set<string>;
|
|
5
|
+
export declare const invokeDateStatic: (name: string, args: Array<unknown>, node: AstNode) => number;
|
|
7
6
|
export declare const dateSetterArgumentCount: (name: string) => number | undefined;
|
|
8
|
-
export declare const invokeDateMethod: (value:
|
|
7
|
+
export declare const invokeDateMethod: (value: CodeModeDate, name: string, args: Array<number>, node: AstNode, initialTime?: number) => unknown;
|
package/dist/stdlib/date.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { HostFunction, sync } from "../interpreter/host.js";
|
|
3
1
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
-
import {
|
|
5
|
-
import { Values } from "../values.js";
|
|
2
|
+
import { CodeModeDate } from "../values.js";
|
|
6
3
|
import { coerceToNumber, coerceToString } from "./value.js";
|
|
7
4
|
const dateSetterArguments = new Map([
|
|
8
5
|
["setTime", 1],
|
|
@@ -27,8 +24,6 @@ export const dateMethods = new Set([
|
|
|
27
24
|
"toISOString",
|
|
28
25
|
"toJSON",
|
|
29
26
|
"toString",
|
|
30
|
-
"toDateString",
|
|
31
|
-
"toTimeString",
|
|
32
27
|
"toUTCString",
|
|
33
28
|
"toGMTString",
|
|
34
29
|
"getFullYear",
|
|
@@ -50,32 +45,19 @@ export const dateMethods = new Set([
|
|
|
50
45
|
"getTimezoneOffset",
|
|
51
46
|
...dateSetterArguments.keys(),
|
|
52
47
|
]);
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
export const dateStatics = new Set(["now", "parse", "UTC"]);
|
|
49
|
+
export const invokeDateStatic = (name, args, node) => {
|
|
50
|
+
switch (name) {
|
|
51
|
+
case "now":
|
|
52
|
+
return Date.now();
|
|
53
|
+
case "parse":
|
|
54
|
+
return Date.parse(coerceToString(args[0]));
|
|
55
|
+
case "UTC":
|
|
56
|
+
return Date.UTC(...args.map((arg) => coerceToNumber(arg)));
|
|
57
|
+
default:
|
|
58
|
+
throw new InterpreterRuntimeError(`Date.${name} is not available.`, node);
|
|
63
59
|
}
|
|
64
|
-
const parts = args.map((arg) => coerceToNumber(arg));
|
|
65
|
-
return Effect.succeed(new Values.Date(new Date(...parts).getTime()));
|
|
66
60
|
};
|
|
67
|
-
export const dateGlobal = (runner) => new HostFunction({
|
|
68
|
-
name: "Date",
|
|
69
|
-
// ISO instead of the host's locale string: date strings are deterministic and must not leak the host timezone.
|
|
70
|
-
call: () => Effect.sync(() => new Date().toISOString()),
|
|
71
|
-
construct: (args, node) => constructDate(runner, args, node),
|
|
72
|
-
instanceOf: (value) => value instanceof Values.Date,
|
|
73
|
-
members: {
|
|
74
|
-
now: sync("Date.now", () => Date.now()),
|
|
75
|
-
parse: sync("Date.parse", (args) => Date.parse(coerceToString(args[0]))),
|
|
76
|
-
UTC: sync("Date.UTC", (args) => Date.UTC(...args.map((arg) => coerceToNumber(arg)))),
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
61
|
export const dateSetterArgumentCount = (name) => dateSetterArguments.get(name);
|
|
80
62
|
export const invokeDateMethod = (value, name, args, node, initialTime = value.time) => {
|
|
81
63
|
const hosted = new Date(initialTime);
|
|
@@ -91,10 +73,6 @@ export const invokeDateMethod = (value, name, args, node, initialTime = value.ti
|
|
|
91
73
|
return Number.isFinite(value.time) ? hosted.toISOString() : null;
|
|
92
74
|
case "toString":
|
|
93
75
|
return coerceToString(value);
|
|
94
|
-
case "toDateString":
|
|
95
|
-
return hosted.toDateString();
|
|
96
|
-
case "toTimeString":
|
|
97
|
-
return hosted.toTimeString();
|
|
98
76
|
case "toUTCString":
|
|
99
77
|
case "toGMTString":
|
|
100
78
|
return hosted.toUTCString();
|
package/dist/stdlib/json.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { CallbackRunner } from "../interpreter/methods.js";
|
|
3
|
+
import { type AstNode } from "../interpreter/model.js";
|
|
4
|
+
export declare const jsonStatics: Set<string>;
|
|
5
|
+
export type JsonMethodName = "parse" | "stringify";
|
|
6
|
+
export declare const invokeJsonMethod: <R>(runner: CallbackRunner<R>, name: JsonMethodName, args: Array<unknown>, node: AstNode) => Effect.Effect<unknown, unknown, R>;
|
package/dist/stdlib/json.js
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import { applyCollectionCallback } from "../interpreter/runner.js";
|
|
2
|
+
import { applyCollectionCallback } from "../interpreter/methods.js";
|
|
4
3
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
5
4
|
import { typeofValue } from "../interpreter/references.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
export const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
});
|
|
5
|
+
import { copyIn, copyOut } from "../tool-runtime.js";
|
|
6
|
+
import { CodeModeDate, CodeModeMap, CodeModeRegExp, CodeModeSet, CodeModeURL, CodeModeURLSearchParams, } from "../values.js";
|
|
7
|
+
export const jsonStatics = new Set(["parse", "stringify"]);
|
|
8
|
+
export const invokeJsonMethod = (runner, name, args, node) => {
|
|
9
|
+
return name === "parse" ? parse(runner, args, node) : stringify(runner, args, node);
|
|
10
|
+
};
|
|
13
11
|
const parse = (runner, args, node) => {
|
|
14
12
|
const text = args[0];
|
|
15
13
|
if (typeof text !== "string")
|
|
16
14
|
throw new InterpreterRuntimeError("JSON.parse expects a string.", node);
|
|
17
15
|
const parsed = (() => {
|
|
18
16
|
try {
|
|
19
|
-
return
|
|
17
|
+
return copyIn(JSON.parse(text), "JSON.parse result");
|
|
20
18
|
}
|
|
21
19
|
catch (error) {
|
|
22
20
|
throw new InterpreterRuntimeError(`JSON.parse received invalid JSON: ${error instanceof Error ? error.message : String(error)}`, node).as("SyntaxError");
|
|
@@ -25,63 +23,80 @@ const parse = (runner, args, node) => {
|
|
|
25
23
|
if (typeofValue(args[1]) !== "function")
|
|
26
24
|
return Effect.succeed(parsed);
|
|
27
25
|
const apply = applyCollectionCallback(runner, args[1], "JSON.parse", node);
|
|
26
|
+
const root = Object.create(null);
|
|
27
|
+
root[""] = parsed;
|
|
28
28
|
const visit = (holder, key) => Effect.gen(function* () {
|
|
29
|
-
const value =
|
|
30
|
-
if (value
|
|
31
|
-
|
|
29
|
+
const value = holder[key];
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
const length = value.length;
|
|
32
|
+
for (let index = 0; index < length; index += 1) {
|
|
33
|
+
const revived = yield* visit(value, String(index));
|
|
34
|
+
if (revived === undefined)
|
|
35
|
+
Reflect.deleteProperty(value, index);
|
|
36
|
+
else
|
|
37
|
+
value[index] = revived;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else if (isPlainObject(value)) {
|
|
41
|
+
for (const name of Object.keys(value)) {
|
|
32
42
|
const revived = yield* visit(value, name);
|
|
33
43
|
if (revived === undefined)
|
|
34
|
-
|
|
44
|
+
Reflect.deleteProperty(value, name);
|
|
35
45
|
else
|
|
36
|
-
|
|
46
|
+
value[name] = revived;
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
49
|
return yield* apply([key, value]);
|
|
40
50
|
});
|
|
41
|
-
return visit(
|
|
51
|
+
return visit(root, "");
|
|
42
52
|
};
|
|
43
53
|
const stringify = (runner, args, node) => {
|
|
44
54
|
const space = args[2];
|
|
45
55
|
const indent = typeof space === "number" || typeof space === "string" ? space : undefined;
|
|
46
56
|
const replacer = args[1];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
const callable = typeofValue(replacer) === "function";
|
|
58
|
+
const checked = copyIn(args[0], "JSON.stringify value", callable);
|
|
59
|
+
const input = callable ? args[0] : checked;
|
|
60
|
+
if (Array.isArray(replacer)) {
|
|
61
|
+
const properties = replacer
|
|
62
|
+
.filter((item) => typeof item === "string" || typeof item === "number")
|
|
63
|
+
.map(String);
|
|
64
|
+
return Effect.succeed(JSON.stringify(copyOut(input, "json"), properties, indent));
|
|
65
|
+
}
|
|
66
|
+
if (!callable) {
|
|
67
|
+
return Effect.succeed(JSON.stringify(copyOut(input, "json"), null, indent));
|
|
54
68
|
}
|
|
55
|
-
// Validate up front; the replacer walk below reads the original value.
|
|
56
|
-
toProgram(args[0], "JSON.stringify value");
|
|
57
69
|
const apply = applyCollectionCallback(runner, replacer, "JSON.stringify", node);
|
|
70
|
+
const root = Object.create(null);
|
|
71
|
+
root[""] = input;
|
|
58
72
|
const stack = new Set();
|
|
59
73
|
const visit = (holder, key) => Effect.gen(function* () {
|
|
60
|
-
const value = yield* apply([key, toJSONValue(
|
|
74
|
+
const value = yield* apply([key, toJSONValue(holder[key])]);
|
|
61
75
|
if (value === undefined || typeofValue(value) === "function")
|
|
62
76
|
return undefined;
|
|
63
|
-
|
|
77
|
+
copyIn(value, "JSON.stringify replacer result", true);
|
|
64
78
|
if (typeof value === "number")
|
|
65
79
|
return Number.isFinite(value) ? value : null;
|
|
66
80
|
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
67
81
|
return value;
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
stack.add(value);
|
|
73
|
-
if (value instanceof ProgramArray) {
|
|
82
|
+
if (Array.isArray(value)) {
|
|
83
|
+
if (stack.has(value))
|
|
84
|
+
throw new InterpreterRuntimeError("Converting circular structure to JSON.", node).as("TypeError");
|
|
85
|
+
stack.add(value);
|
|
74
86
|
const result = [];
|
|
75
|
-
for (let index = 0; index < value.
|
|
87
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
76
88
|
result.push((yield* visit(value, String(index))) ?? null);
|
|
77
89
|
}
|
|
78
90
|
stack.delete(value);
|
|
79
91
|
return result;
|
|
80
92
|
}
|
|
93
|
+
if (!isPlainObject(value))
|
|
94
|
+
return {};
|
|
95
|
+
if (stack.has(value))
|
|
96
|
+
throw new InterpreterRuntimeError("Converting circular structure to JSON.", node).as("TypeError");
|
|
97
|
+
stack.add(value);
|
|
81
98
|
const result = Object.create(null);
|
|
82
|
-
for (const name of
|
|
83
|
-
if (typeof name !== "string")
|
|
84
|
-
continue;
|
|
99
|
+
for (const name of Object.keys(value)) {
|
|
85
100
|
const item = yield* visit(value, name);
|
|
86
101
|
if (item !== undefined)
|
|
87
102
|
result[name] = item;
|
|
@@ -89,13 +104,21 @@ const stringify = (runner, args, node) => {
|
|
|
89
104
|
stack.delete(value);
|
|
90
105
|
return result;
|
|
91
106
|
});
|
|
92
|
-
return Effect.map(visit(
|
|
107
|
+
return Effect.map(visit(root, ""), (value) => JSON.stringify(value, null, indent));
|
|
93
108
|
};
|
|
94
109
|
const toJSONValue = (value) => {
|
|
95
|
-
if (value instanceof
|
|
110
|
+
if (value instanceof CodeModeDate) {
|
|
96
111
|
return Number.isFinite(value.time) ? new Date(value.time).toISOString() : null;
|
|
97
112
|
}
|
|
98
|
-
if (value instanceof
|
|
113
|
+
if (value instanceof CodeModeURL)
|
|
99
114
|
return value.url.href;
|
|
100
115
|
return value;
|
|
101
116
|
};
|
|
117
|
+
const isPlainObject = (value) => value !== null &&
|
|
118
|
+
typeof value === "object" &&
|
|
119
|
+
!(value instanceof CodeModeDate) &&
|
|
120
|
+
!(value instanceof CodeModeRegExp) &&
|
|
121
|
+
!(value instanceof CodeModeMap) &&
|
|
122
|
+
!(value instanceof CodeModeSet) &&
|
|
123
|
+
!(value instanceof CodeModeURL) &&
|
|
124
|
+
!(value instanceof CodeModeURLSearchParams);
|
package/dist/stdlib/math.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { type SyncIteratorRunner } from "../interpreter/iterator.js";
|
|
3
|
+
import { type AstNode } from "../interpreter/model.js";
|
|
3
4
|
declare global {
|
|
4
5
|
interface Math {
|
|
5
6
|
sumPrecise(values: Iterable<number>): number;
|
|
6
7
|
}
|
|
7
8
|
}
|
|
8
|
-
export declare const
|
|
9
|
+
export declare const mathConstants: Set<string>;
|
|
10
|
+
export declare const mathMethods: Set<string>;
|
|
11
|
+
export declare const invokeMathMethod: (name: string, args: Array<unknown>, node: AstNode) => number;
|
|
12
|
+
export declare const invokeMathSumPrecise: <R>(runner: SyncIteratorRunner<R>, source: unknown, node: AstNode) => Effect.Effect<number, unknown, R>;
|