@jigging/jig 0.0.0 → 0.1.0-alpha.2
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/LICENSE +373 -0
- package/README.md +124 -1
- package/THIRD_PARTY_NOTICES +83 -0
- package/bin/jig +42 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1975 -0
- package/dist/json.d.ts +21 -0
- package/dist/project/author.d.ts +47 -0
- package/libexec/evaluator/project-authoring-1.schema.json +111 -0
- package/libexec/evaluator/project-evaluator-sdk.bundle.js +1975 -0
- package/libexec/evaluator/project-evaluator-worker.js +431 -0
- package/libexec/installed-cli.js +25840 -0
- package/libexec/linux-rootless-supervisor.js +623 -0
- package/libexec/preparation/bun-native-preparation-worker.js +388 -0
- package/package.json +68 -6
- package/bun.lock +0 -26
- package/index.ts +0 -1
- package/tsconfig.json +0 -30
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/internal/project-evaluator-worker.ts
|
|
3
|
+
import vm from "vm";
|
|
4
|
+
|
|
5
|
+
// src/json.ts
|
|
6
|
+
var JSON_1_LIMITS = Object.freeze({
|
|
7
|
+
bytes: 16777216,
|
|
8
|
+
depth: 128,
|
|
9
|
+
nodes: 262144,
|
|
10
|
+
containerEntries: 65536,
|
|
11
|
+
stringBytes: 8388608,
|
|
12
|
+
memberNameBytes: 1024,
|
|
13
|
+
numberTokenBytes: 128
|
|
14
|
+
});
|
|
15
|
+
var encoder = new TextEncoder;
|
|
16
|
+
var decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
17
|
+
|
|
18
|
+
class Json1Error extends Error {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "Json1Error";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function validateJson1(value) {
|
|
25
|
+
visitJson(value, 1, { nodes: 0, encodedBytes: 0, active: new WeakSet }, false);
|
|
26
|
+
}
|
|
27
|
+
function visitJson(value, depth, state, memberName) {
|
|
28
|
+
if (depth > JSON_1_LIMITS.depth)
|
|
29
|
+
throw new Json1Error("maximum value depth exceeded");
|
|
30
|
+
state.nodes += 1;
|
|
31
|
+
if (state.nodes > JSON_1_LIMITS.nodes)
|
|
32
|
+
throw new Json1Error("maximum value nodes exceeded");
|
|
33
|
+
if (value === null) {
|
|
34
|
+
chargeEncodedBytes(state, 4);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value === "boolean") {
|
|
38
|
+
chargeEncodedBytes(state, value ? 4 : 5);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (typeof value === "number") {
|
|
42
|
+
if (!Number.isFinite(value))
|
|
43
|
+
throw new Json1Error("non-finite number");
|
|
44
|
+
if (Number.isInteger(value) && !Number.isSafeInteger(value)) {
|
|
45
|
+
throw new Json1Error("integral number outside safe range");
|
|
46
|
+
}
|
|
47
|
+
chargeEncodedBytes(state, (Object.is(value, -0) ? "0" : JSON.stringify(value)).length);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (typeof value === "string") {
|
|
51
|
+
validateString(value, memberName ? JSON_1_LIMITS.memberNameBytes : JSON_1_LIMITS.stringBytes);
|
|
52
|
+
chargeEncodedBytes(state, encodedJsonStringBytes(value));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (typeof value !== "object")
|
|
56
|
+
throw new Json1Error("value is not JSON/1");
|
|
57
|
+
if (state.active.has(value))
|
|
58
|
+
throw new Json1Error("cyclic value");
|
|
59
|
+
state.active.add(value);
|
|
60
|
+
try {
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
if (value.length > JSON_1_LIMITS.containerEntries) {
|
|
63
|
+
throw new Json1Error("maximum array items exceeded");
|
|
64
|
+
}
|
|
65
|
+
chargeEncodedBytes(state, 2 + Math.max(0, value.length - 1));
|
|
66
|
+
for (const child of value)
|
|
67
|
+
visitJson(child, depth + 1, state, false);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const object = value;
|
|
71
|
+
const keys = Object.keys(object);
|
|
72
|
+
if (keys.length > JSON_1_LIMITS.containerEntries) {
|
|
73
|
+
throw new Json1Error("maximum object members exceeded");
|
|
74
|
+
}
|
|
75
|
+
chargeEncodedBytes(state, 2 + keys.length + Math.max(0, keys.length - 1));
|
|
76
|
+
for (const key of keys) {
|
|
77
|
+
validateString(key, JSON_1_LIMITS.memberNameBytes);
|
|
78
|
+
chargeEncodedBytes(state, encodedJsonStringBytes(key));
|
|
79
|
+
visitJson(object[key], depth + 1, state, false);
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
state.active.delete(value);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function chargeEncodedBytes(state, bytes) {
|
|
86
|
+
if (bytes > JSON_1_LIMITS.bytes - state.encodedBytes) {
|
|
87
|
+
throw new Json1Error("maximum encoded bytes exceeded");
|
|
88
|
+
}
|
|
89
|
+
state.encodedBytes += bytes;
|
|
90
|
+
}
|
|
91
|
+
function encodedJsonStringBytes(value) {
|
|
92
|
+
return encoder.encode(JSON.stringify(value)).byteLength;
|
|
93
|
+
}
|
|
94
|
+
function validateString(value, byteLimit) {
|
|
95
|
+
if (encoder.encode(value).byteLength > byteLimit) {
|
|
96
|
+
throw new Json1Error("maximum string bytes exceeded");
|
|
97
|
+
}
|
|
98
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
99
|
+
const code = value.charCodeAt(index);
|
|
100
|
+
if (code >= 55296 && code <= 56319) {
|
|
101
|
+
const next = value.charCodeAt(index + 1);
|
|
102
|
+
if (!(next >= 56320 && next <= 57343))
|
|
103
|
+
throw new Json1Error("lone Unicode surrogate");
|
|
104
|
+
index += 1;
|
|
105
|
+
} else if (code >= 56320 && code <= 57343) {
|
|
106
|
+
throw new Json1Error("lone Unicode surrogate");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function canonicalJson(value) {
|
|
111
|
+
validateJson1(value);
|
|
112
|
+
return encoder.encode(canonicalText(value));
|
|
113
|
+
}
|
|
114
|
+
function canonicalText(value) {
|
|
115
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") {
|
|
116
|
+
return JSON.stringify(value);
|
|
117
|
+
}
|
|
118
|
+
if (typeof value === "number")
|
|
119
|
+
return Object.is(value, -0) ? "0" : JSON.stringify(value);
|
|
120
|
+
if (Array.isArray(value))
|
|
121
|
+
return `[${value.map(canonicalText).join(",")}]`;
|
|
122
|
+
const object = value;
|
|
123
|
+
const members = Object.keys(object).sort(compareUtf16).map((key) => `${JSON.stringify(key)}:${canonicalText(object[key])}`);
|
|
124
|
+
return `{${members.join(",")}}`;
|
|
125
|
+
}
|
|
126
|
+
function compareUtf16(left, right) {
|
|
127
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/internal/project-evaluator-worker.ts
|
|
131
|
+
var PROTOCOL = "jig-author-evaluator/1";
|
|
132
|
+
var MAX_REQUEST_BYTES = 2 * 1024 * 1024;
|
|
133
|
+
var VM_TIMEOUT_MS = 1000;
|
|
134
|
+
var SDK_ENTRY = "/jig-evaluator/project-evaluator-sdk.bundle.js";
|
|
135
|
+
var EVALUATION_CODES = new Set([
|
|
136
|
+
"PROJECT_AUTHORING_VALUE",
|
|
137
|
+
"PROJECT_DEFAULT_EXPORT",
|
|
138
|
+
"PROJECT_EVALUATION_FAILED",
|
|
139
|
+
"PROJECT_EVALUATION_LIMIT",
|
|
140
|
+
"PROJECT_EVALUATOR_COMPILE",
|
|
141
|
+
"PROJECT_EVALUATOR_IMPORT",
|
|
142
|
+
"PROJECT_EVALUATOR_PROTOCOL"
|
|
143
|
+
]);
|
|
144
|
+
var runtime = globalThis.Bun;
|
|
145
|
+
try {
|
|
146
|
+
const request = await readRequest();
|
|
147
|
+
const code = await build(request);
|
|
148
|
+
const value = evaluate(code);
|
|
149
|
+
write({ protocol: PROTOCOL, status: "ok", value });
|
|
150
|
+
} catch (error) {
|
|
151
|
+
write({
|
|
152
|
+
protocol: PROTOCOL,
|
|
153
|
+
status: "error",
|
|
154
|
+
code: errorCode(error),
|
|
155
|
+
message: boundedMessage(error)
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async function readRequest() {
|
|
159
|
+
const bytes = new Uint8Array(await runtime.stdin.arrayBuffer());
|
|
160
|
+
if (bytes.byteLength === 0 || bytes.byteLength > MAX_REQUEST_BYTES) {
|
|
161
|
+
throw tagged("PROJECT_EVALUATION_LIMIT", "evaluator request exceeds its byte bound");
|
|
162
|
+
}
|
|
163
|
+
let value;
|
|
164
|
+
try {
|
|
165
|
+
value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
166
|
+
} catch {
|
|
167
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator request is not valid JSON");
|
|
168
|
+
}
|
|
169
|
+
if (!isRecord(value) || value.protocol !== PROTOCOL || !isAuthoringProfile(value.authoringProfile) || typeof value.entryProjectPath !== "string" || !Array.isArray(value.modules) || Object.keys(value).length !== 4) {
|
|
170
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator request has an invalid shape");
|
|
171
|
+
}
|
|
172
|
+
const paths = new Set;
|
|
173
|
+
const modules = [];
|
|
174
|
+
for (const candidate of value.modules) {
|
|
175
|
+
if (!isRecord(candidate) || typeof candidate.projectPath !== "string" || typeof candidate.source !== "string" || !Array.isArray(candidate.imports) || Object.keys(candidate).length !== 3 || paths.has(candidate.projectPath)) {
|
|
176
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator module has an invalid shape");
|
|
177
|
+
}
|
|
178
|
+
paths.add(candidate.projectPath);
|
|
179
|
+
const imports = [];
|
|
180
|
+
const edges = new Set;
|
|
181
|
+
for (const edge of candidate.imports) {
|
|
182
|
+
if (!isRecord(edge) || typeof edge.specifier !== "string" || typeof edge.projectPath !== "string" || Object.keys(edge).length !== 2) {
|
|
183
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator import has an invalid shape");
|
|
184
|
+
}
|
|
185
|
+
const key = `${edge.specifier}\x00${edge.projectPath}`;
|
|
186
|
+
if (edges.has(key)) {
|
|
187
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator request repeats an import edge");
|
|
188
|
+
}
|
|
189
|
+
edges.add(key);
|
|
190
|
+
imports.push({ specifier: edge.specifier, projectPath: edge.projectPath });
|
|
191
|
+
}
|
|
192
|
+
modules.push({
|
|
193
|
+
projectPath: candidate.projectPath,
|
|
194
|
+
source: candidate.source,
|
|
195
|
+
imports
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (!paths.has(value.entryProjectPath)) {
|
|
199
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator entry is absent from its module closure");
|
|
200
|
+
}
|
|
201
|
+
for (const module of modules) {
|
|
202
|
+
for (const edge of module.imports) {
|
|
203
|
+
if (!paths.has(edge.projectPath)) {
|
|
204
|
+
throw tagged("PROJECT_EVALUATOR_PROTOCOL", "evaluator import target is absent from its module closure");
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
protocol: PROTOCOL,
|
|
210
|
+
authoringProfile: value.authoringProfile,
|
|
211
|
+
entryProjectPath: value.entryProjectPath,
|
|
212
|
+
modules
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
async function build(request) {
|
|
216
|
+
const sdkSource = await runtime.file(SDK_ENTRY).text();
|
|
217
|
+
const modules = new Map(request.modules.map((module) => [module.projectPath, module]));
|
|
218
|
+
const edges = new Map;
|
|
219
|
+
for (const module of request.modules) {
|
|
220
|
+
for (const edge of module.imports) {
|
|
221
|
+
edges.set(`${module.projectPath}\x00${edge.specifier}`, edge.projectPath);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const bridge = [
|
|
225
|
+
'import * as declaration from "jig-author:entry";',
|
|
226
|
+
"const keys = Object.keys(declaration);",
|
|
227
|
+
'if (keys.length !== 1 || keys[0] !== "default") {',
|
|
228
|
+
' const error = new Error("author module must export only default");',
|
|
229
|
+
' error.code = "PROJECT_DEFAULT_EXPORT";',
|
|
230
|
+
" throw error;",
|
|
231
|
+
"}",
|
|
232
|
+
"export default declaration.default;"
|
|
233
|
+
].join(`
|
|
234
|
+
`);
|
|
235
|
+
let result;
|
|
236
|
+
try {
|
|
237
|
+
result = await runtime.build({
|
|
238
|
+
entrypoints: ["jig-author:bridge"],
|
|
239
|
+
format: "cjs",
|
|
240
|
+
target: "bun",
|
|
241
|
+
write: false,
|
|
242
|
+
sourcemap: "none",
|
|
243
|
+
plugins: [{
|
|
244
|
+
name: "jig-closed-author-module",
|
|
245
|
+
setup(builder) {
|
|
246
|
+
builder.onResolve({ filter: /^jig-author:bridge$/ }, (arguments_) => {
|
|
247
|
+
if (arguments_.kind !== "entry-point-build" || arguments_.importer !== "") {
|
|
248
|
+
throw deniedImport(arguments_.path);
|
|
249
|
+
}
|
|
250
|
+
return { path: arguments_.path, namespace: "jig-author" };
|
|
251
|
+
});
|
|
252
|
+
builder.onResolve({ filter: /^jig-author:entry$/ }, (arguments_) => {
|
|
253
|
+
if (arguments_.kind !== "import-statement" || arguments_.importer !== "jig-author:bridge") {
|
|
254
|
+
throw deniedImport(arguments_.path);
|
|
255
|
+
}
|
|
256
|
+
return { path: request.entryProjectPath, namespace: "jig-project" };
|
|
257
|
+
});
|
|
258
|
+
builder.onResolve({ filter: /^jig-author:/ }, (arguments_) => {
|
|
259
|
+
throw deniedImport(arguments_.path);
|
|
260
|
+
});
|
|
261
|
+
builder.onLoad({ filter: /^jig-author:bridge$/, namespace: "jig-author" }, () => ({
|
|
262
|
+
loader: "ts",
|
|
263
|
+
contents: bridge
|
|
264
|
+
}));
|
|
265
|
+
builder.onResolve({ filter: /^@jigging\/jig$/ }, (arguments_) => {
|
|
266
|
+
if (arguments_.kind !== "import-statement" || !modules.has(arguments_.importer)) {
|
|
267
|
+
throw deniedImport(arguments_.path);
|
|
268
|
+
}
|
|
269
|
+
return { path: "sdk", namespace: "jig-sealed" };
|
|
270
|
+
});
|
|
271
|
+
builder.onLoad({ filter: /^sdk$/, namespace: "jig-sealed" }, () => ({
|
|
272
|
+
loader: "js",
|
|
273
|
+
contents: sdkSource
|
|
274
|
+
}));
|
|
275
|
+
builder.onResolve({ filter: /.*/, namespace: "jig-sealed" }, (arguments_) => {
|
|
276
|
+
throw deniedImport(arguments_.path);
|
|
277
|
+
});
|
|
278
|
+
builder.onResolve({ filter: /.*/ }, (arguments_) => {
|
|
279
|
+
if (arguments_.kind !== "import-statement") {
|
|
280
|
+
throw deniedImport(`${arguments_.path} (${arguments_.kind} from ${arguments_.importer})`);
|
|
281
|
+
}
|
|
282
|
+
if (!modules.has(arguments_.importer)) {
|
|
283
|
+
throw deniedImport(`${arguments_.path} (from ${arguments_.importer})`);
|
|
284
|
+
}
|
|
285
|
+
const target = edges.get(`${arguments_.importer}\x00${arguments_.path}`);
|
|
286
|
+
if (target === undefined || !modules.has(target)) {
|
|
287
|
+
throw deniedImport(`${arguments_.path} (from ${arguments_.importer})`);
|
|
288
|
+
}
|
|
289
|
+
return { path: target, namespace: "jig-project" };
|
|
290
|
+
});
|
|
291
|
+
builder.onLoad({ filter: /.*/, namespace: "jig-project" }, (arguments_) => {
|
|
292
|
+
const module = modules.get(arguments_.path);
|
|
293
|
+
if (module === undefined)
|
|
294
|
+
return;
|
|
295
|
+
return { loader: "ts", contents: module.source };
|
|
296
|
+
});
|
|
297
|
+
builder.onResolve({ filter: /.*/, namespace: "jig-author" }, (arguments_) => {
|
|
298
|
+
throw deniedImport(arguments_.path);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}]
|
|
302
|
+
});
|
|
303
|
+
} catch (error) {
|
|
304
|
+
const message = boundedMessage(error);
|
|
305
|
+
throw tagged(message.includes("ResolveMessage") || message.includes("Could not resolve") || message.includes("[PROJECT_EVALUATOR_IMPORT]") ? "PROJECT_EVALUATOR_IMPORT" : "PROJECT_EVALUATOR_COMPILE", message);
|
|
306
|
+
}
|
|
307
|
+
if (!result.success || result.outputs.length !== 1) {
|
|
308
|
+
const detail = result.logs.map((log) => log.message ?? "compile failure").join("; ");
|
|
309
|
+
throw tagged(detail.includes("[PROJECT_EVALUATOR_IMPORT]") ? "PROJECT_EVALUATOR_IMPORT" : "PROJECT_EVALUATOR_COMPILE", detail || "author module did not compile");
|
|
310
|
+
}
|
|
311
|
+
return await result.outputs[0].text();
|
|
312
|
+
}
|
|
313
|
+
function isAuthoringProfile(value) {
|
|
314
|
+
return value === "project-authoring/1";
|
|
315
|
+
}
|
|
316
|
+
function deniedImport(path) {
|
|
317
|
+
return tagged("PROJECT_EVALUATOR_IMPORT", `[PROJECT_EVALUATOR_IMPORT] author module import is outside the one-module checkpoint: ${path}`);
|
|
318
|
+
}
|
|
319
|
+
function evaluate(code) {
|
|
320
|
+
const context = vm.createContext(Object.create(null), {
|
|
321
|
+
codeGeneration: { strings: false, wasm: false },
|
|
322
|
+
name: "jig-author-declaration"
|
|
323
|
+
});
|
|
324
|
+
new vm.Script(guestBootstrap(), { filename: "/jig-bootstrap.js" }).runInContext(context, {
|
|
325
|
+
timeout: VM_TIMEOUT_MS
|
|
326
|
+
});
|
|
327
|
+
const invocation = `${code}
|
|
328
|
+
(__jigModule.exports, __jigRequire, __jigModule, "/author.ts", "/");`;
|
|
329
|
+
new vm.Script(invocation, { filename: "/author.ts" }).runInContext(context, {
|
|
330
|
+
timeout: VM_TIMEOUT_MS
|
|
331
|
+
});
|
|
332
|
+
const exports = new vm.Script("__jigModule.exports").runInContext(context, {
|
|
333
|
+
timeout: VM_TIMEOUT_MS
|
|
334
|
+
});
|
|
335
|
+
if (!isRecord(exports) || Object.keys(exports).length !== 1 || !("default" in exports)) {
|
|
336
|
+
throw tagged("PROJECT_DEFAULT_EXPORT", "compiled author module did not expose one default value");
|
|
337
|
+
}
|
|
338
|
+
return JSON.parse(new TextDecoder().decode(canonicalJson(exports.default)));
|
|
339
|
+
}
|
|
340
|
+
function guestBootstrap() {
|
|
341
|
+
return `
|
|
342
|
+
"use strict";
|
|
343
|
+
globalThis.process = Object.freeze({
|
|
344
|
+
versions: Object.freeze({ unicode: "15.1" }),
|
|
345
|
+
});
|
|
346
|
+
globalThis.__jigModule = { exports: {} };
|
|
347
|
+
globalThis.__jigRequire = function __jigRequire() {
|
|
348
|
+
const error = new Error("CommonJS require is unavailable");
|
|
349
|
+
error.code = "PROJECT_EVALUATOR_IMPORT";
|
|
350
|
+
throw error;
|
|
351
|
+
};
|
|
352
|
+
globalThis.TextEncoder = class TextEncoder {
|
|
353
|
+
encode(value = "") {
|
|
354
|
+
const input = String(value);
|
|
355
|
+
const bytes = [];
|
|
356
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
357
|
+
let point = input.charCodeAt(index);
|
|
358
|
+
if (point >= 0xd800 && point <= 0xdbff) {
|
|
359
|
+
const next = input.charCodeAt(index + 1);
|
|
360
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
361
|
+
point = 0x10000 + ((point - 0xd800) << 10) + (next - 0xdc00);
|
|
362
|
+
index += 1;
|
|
363
|
+
} else {
|
|
364
|
+
point = 0xfffd;
|
|
365
|
+
}
|
|
366
|
+
} else if (point >= 0xdc00 && point <= 0xdfff) {
|
|
367
|
+
point = 0xfffd;
|
|
368
|
+
}
|
|
369
|
+
if (point <= 0x7f) bytes.push(point);
|
|
370
|
+
else if (point <= 0x7ff) {
|
|
371
|
+
bytes.push(0xc0 | (point >> 6), 0x80 | (point & 0x3f));
|
|
372
|
+
} else if (point <= 0xffff) {
|
|
373
|
+
bytes.push(0xe0 | (point >> 12), 0x80 | ((point >> 6) & 0x3f), 0x80 | (point & 0x3f));
|
|
374
|
+
} else {
|
|
375
|
+
bytes.push(
|
|
376
|
+
0xf0 | (point >> 18),
|
|
377
|
+
0x80 | ((point >> 12) & 0x3f),
|
|
378
|
+
0x80 | ((point >> 6) & 0x3f),
|
|
379
|
+
0x80 | (point & 0x3f),
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return new Uint8Array(bytes);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
globalThis.TextDecoder = class TextDecoder {
|
|
387
|
+
constructor(label = "utf-8") {
|
|
388
|
+
if (String(label).toLowerCase() !== "utf-8") throw new RangeError("only UTF-8 is available");
|
|
389
|
+
}
|
|
390
|
+
decode() {
|
|
391
|
+
throw new TypeError("TextDecoder.decode is unavailable in the authoring realm");
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
Object.freeze(globalThis.process);
|
|
395
|
+
Object.freeze(globalThis.TextEncoder);
|
|
396
|
+
Object.freeze(globalThis.TextDecoder);
|
|
397
|
+
`;
|
|
398
|
+
}
|
|
399
|
+
function write(value) {
|
|
400
|
+
process.stdout.write(canonicalJson(value));
|
|
401
|
+
}
|
|
402
|
+
function tagged(code, message) {
|
|
403
|
+
return Object.assign(new Error(message), { code });
|
|
404
|
+
}
|
|
405
|
+
function errorCode(error) {
|
|
406
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ERR_SCRIPT_EXECUTION_TIMEOUT") {
|
|
407
|
+
return "PROJECT_EVALUATION_LIMIT";
|
|
408
|
+
}
|
|
409
|
+
if (typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" && EVALUATION_CODES.has(error.code)) {
|
|
410
|
+
return error.code;
|
|
411
|
+
}
|
|
412
|
+
if (error instanceof TypeError)
|
|
413
|
+
return "PROJECT_AUTHORING_VALUE";
|
|
414
|
+
return "PROJECT_EVALUATION_FAILED";
|
|
415
|
+
}
|
|
416
|
+
function boundedMessage(error) {
|
|
417
|
+
let message;
|
|
418
|
+
try {
|
|
419
|
+
if (error instanceof AggregateError) {
|
|
420
|
+
message = [error.message, ...error.errors.map((item) => item instanceof Error ? item.message : String(item))].join(": ");
|
|
421
|
+
} else {
|
|
422
|
+
message = error instanceof Error ? error.message : String(error);
|
|
423
|
+
}
|
|
424
|
+
} catch {
|
|
425
|
+
message = "author evaluation failed";
|
|
426
|
+
}
|
|
427
|
+
return message.slice(0, 4096);
|
|
428
|
+
}
|
|
429
|
+
function isRecord(value) {
|
|
430
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
431
|
+
}
|