@poe-platform/safe-js 0.1.802 → 0.1.804
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 +4 -4
- package/dist/safe-js/bundled-yaml/LICENSE +13 -0
- package/dist/safe-js/bundled-yaml/index.js +6601 -0
- package/dist/safe-js/chunks/{chunk-HFRBLE6Y.js → chunk-36PBWSDR.js} +23 -11
- package/dist/safe-js/chunks/{chunk-CK3YK2EC.js → chunk-6AO2T2VZ.js} +1 -1
- package/dist/safe-js/chunks/{chunk-5RLD4TVI.js → chunk-BKNQTNHP.js} +36 -23
- package/dist/safe-js/chunks/{chunk-YCFOANSU.js → chunk-BYDDUKS3.js} +3 -3
- package/dist/safe-js/chunks/{chunk-6H5VC5W5.js → chunk-CKOGIOB3.js} +470 -464
- package/dist/safe-js/chunks/{chunk-XOMGWE37.js → chunk-CVPZFRCC.js} +3 -3
- package/dist/safe-js/chunks/{chunk-4KMUWNZD.js → chunk-ECMGBHAB.js} +13 -137
- package/dist/safe-js/chunks/{chunk-A3LXCGMJ.js → chunk-EQUBWQJN.js} +57 -34
- package/dist/safe-js/chunks/{chunk-QRWRR6IA.js → chunk-JMDWLOJV.js} +26 -3
- package/dist/safe-js/chunks/{chunk-3NFTBEZR.js → chunk-JQ5QJV5Q.js} +2 -2
- package/dist/safe-js/chunks/{chunk-MMN3IESA.js → chunk-KMBCLXER.js} +1 -1
- package/dist/safe-js/chunks/{chunk-PMOXSLM5.js → chunk-MJH73KJI.js} +2 -2
- package/dist/safe-js/chunks/{chunk-IB6WAQAE.js → chunk-P66QKVQC.js} +3 -3
- package/dist/safe-js/chunks/{chunk-HPHCQNFV.js → chunk-RPGCF4KE.js} +130 -3
- package/dist/safe-js/chunks/{chunk-F6Y734YA.js → chunk-SIR35W6T.js} +5 -5
- package/dist/safe-js/chunks/{chunk-7THYP46K.js → chunk-SMGNJNDU.js} +1 -1
- package/dist/safe-js/chunks/{chunk-XV5OYKND.js → chunk-VLRTLEDI.js} +2 -2
- package/dist/safe-js/chunks/{chunk-JCHJGIQA.js → chunk-VVOPJZRG.js} +2 -0
- package/dist/safe-js/chunks/{cli-runtime-L4IABN2W.js → cli-runtime-A353G7DR.js} +15 -15
- package/dist/safe-js/chunks/{dump-KUPBSXSL.js → dump-KQZFULX2.js} +4 -4
- package/dist/safe-js/chunks/harness-XT6K6X67.js +10 -0
- package/dist/safe-js/chunks/mcp-VWE444VD.js +11 -0
- package/dist/safe-js/chunks/migration-file-NSKXOMAO.js +14 -0
- package/dist/safe-js/chunks/restore-SHPORPY4.js +13 -0
- package/dist/safe-js/chunks/run-FQOSICOT.js +19 -0
- package/dist/safe-js/chunks/{runtime-modules-MGSXY4BN.js → runtime-modules-DBRXXRND.js} +4 -4
- package/dist/safe-js/chunks/{source-files-BSDM22Y2.js → source-files-A2WSOO6G.js} +3 -3
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.d.ts +19 -0
- package/dist/safe-js/core.js +39 -15
- package/dist/safe-js/error/format.d.ts +3 -0
- package/dist/safe-js/index.d.ts +1 -12
- package/dist/safe-js/index.js +30 -39
- package/dist/safe-js/interp/host-call.d.ts +1 -0
- package/dist/safe-js/interp/interpreter.d.ts +1 -3
- package/dist/safe-js/modules/fs.js +5 -5
- package/dist/safe-js/platform/node.d.ts +1 -0
- package/dist/safe-js/platform/node.js +1 -0
- package/dist/safe-js/platform/workerd.d.ts +1 -0
- package/dist/safe-js/platform/workerd.js +2 -0
- package/dist/safe-js/portable/chunks/{chunk-XCTU25SU.js → chunk-NLGXLZCK.js} +1 -1
- package/dist/safe-js/portable/chunks/{chunk-2FNMGWDK.js → chunk-SRMMDXD3.js} +127 -91
- package/dist/safe-js/portable/chunks/{chunk-H5X3T5VP.js → chunk-W6MZOTYR.js} +2 -0
- package/dist/safe-js/portable/chunks/{source-files-CVU252FB.js → source-files-AEDWESAJ.js} +2 -2
- package/dist/safe-js/portable/core.js +467 -249
- package/dist/safe-js/portable/modules/fs.js +2 -2
- package/dist/safe-js/workerd.js +57987 -57738
- package/package.json +6 -5
- package/dist/safe-js/chunks/harness-3DDUS3RY.js +0 -10
- package/dist/safe-js/chunks/mcp-5TMFK3UE.js +0 -11
- package/dist/safe-js/chunks/migration-file-4CYSJ6LO.js +0 -14
- package/dist/safe-js/chunks/restore-GDHBT5ZD.js +0 -13
- package/dist/safe-js/chunks/run-M6N5KCPF.js +0 -19
- package/dist/safe-js/node-unavailable.d.ts +0 -1
|
@@ -119,10 +119,10 @@ import {
|
|
|
119
119
|
wrapCallerInjectedBindings,
|
|
120
120
|
wrapCancelableBindings,
|
|
121
121
|
wrapHostConstructor
|
|
122
|
-
} from "./chunks/chunk-
|
|
122
|
+
} from "./chunks/chunk-SRMMDXD3.js";
|
|
123
123
|
import {
|
|
124
124
|
createRootedSourceResolver
|
|
125
|
-
} from "./chunks/chunk-
|
|
125
|
+
} from "./chunks/chunk-NLGXLZCK.js";
|
|
126
126
|
import {
|
|
127
127
|
AsyncLocalStorage,
|
|
128
128
|
Budget,
|
|
@@ -131,12 +131,257 @@ import {
|
|
|
131
131
|
createHostCallbackContext,
|
|
132
132
|
describeThrownValue,
|
|
133
133
|
dirname,
|
|
134
|
+
hostEnv,
|
|
134
135
|
hostErrorData,
|
|
135
136
|
hostFs,
|
|
136
137
|
materializeWrappedErrorCause,
|
|
137
138
|
replaceErrorStack,
|
|
138
139
|
types
|
|
139
|
-
} from "./chunks/chunk-
|
|
140
|
+
} from "./chunks/chunk-W6MZOTYR.js";
|
|
141
|
+
|
|
142
|
+
// packages/safe-js/src/parse/hash.ts
|
|
143
|
+
var FNV_OFFSET_BASIS = 2166136261;
|
|
144
|
+
var FNV_PRIME = 16777619;
|
|
145
|
+
var IGNORED_KEYS = /* @__PURE__ */ new Set(["nodeId", "raw", "span"]);
|
|
146
|
+
function hashSource(source, owner, includeFunctionSource = true) {
|
|
147
|
+
try {
|
|
148
|
+
return hashParsedAst(parse(source, "<input>", owner), includeFunctionSource);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
if (error instanceof SandboxError) throw error;
|
|
151
|
+
return hashParsedAst(parseModule(source, "<input>", owner), includeFunctionSource);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function hashParsedAst(ast, includeFunctionSource = true) {
|
|
155
|
+
let hash = FNV_OFFSET_BASIS;
|
|
156
|
+
visit(ast);
|
|
157
|
+
return hash.toString(16).padStart(8, "0");
|
|
158
|
+
function visit(value, includeTemplateRaw = false, enclosingSource, identifierName = false) {
|
|
159
|
+
if (value === null) {
|
|
160
|
+
write("null");
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (value === void 0) {
|
|
164
|
+
write("undefined");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (Array.isArray(value)) {
|
|
168
|
+
write("[");
|
|
169
|
+
for (const entry of value) {
|
|
170
|
+
visit(entry, includeTemplateRaw, enclosingSource);
|
|
171
|
+
write(",");
|
|
172
|
+
}
|
|
173
|
+
write("]");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
switch (typeof value) {
|
|
177
|
+
case "boolean":
|
|
178
|
+
write(value ? "true" : "false");
|
|
179
|
+
return;
|
|
180
|
+
case "number":
|
|
181
|
+
write(Object.is(value, -0) ? "-0" : String(value));
|
|
182
|
+
return;
|
|
183
|
+
case "string":
|
|
184
|
+
write(JSON.stringify(value));
|
|
185
|
+
return;
|
|
186
|
+
case "object": {
|
|
187
|
+
const record = value;
|
|
188
|
+
if (record.type === "Identifier" && record.name === "undefined" && !identifierName) {
|
|
189
|
+
visit({ type: "UndefinedLiteral", value: void 0 });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const source = includeFunctionSource ? functionSources.get(value) : void 0;
|
|
193
|
+
if (source !== void 0 && !(enclosingSource !== void 0 && source.text === enclosingSource.text && source.start >= enclosingSource.start && source.end <= enclosingSource.end)) {
|
|
194
|
+
write("function-source:");
|
|
195
|
+
write(String(source.end - source.start));
|
|
196
|
+
write(":");
|
|
197
|
+
write(source.text, source.start, source.end);
|
|
198
|
+
}
|
|
199
|
+
const keys = Object.keys(value).filter((key) => shouldHashKey(record, key, includeTemplateRaw)).sort();
|
|
200
|
+
write("{");
|
|
201
|
+
for (const key of keys) {
|
|
202
|
+
write(JSON.stringify(key));
|
|
203
|
+
write(":");
|
|
204
|
+
visit(
|
|
205
|
+
record[key],
|
|
206
|
+
shouldIncludeTemplateRaw(record, key, includeTemplateRaw),
|
|
207
|
+
source ?? enclosingSource,
|
|
208
|
+
key === "property" && record.type === "MemberExpression" && !record.computed || key === "key" && !record.computed || (key === "imported" || key === "local") && record.type === "ImportSpecifier" || key === "exported" && record.type === "ExportSpecifier"
|
|
209
|
+
);
|
|
210
|
+
write(",");
|
|
211
|
+
}
|
|
212
|
+
write("}");
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
throw new TypeError(`Unsupported AST value type: ${typeof value}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function write(chunk, start = 0, end = chunk.length) {
|
|
220
|
+
for (let index = start; index < end; index += 1) {
|
|
221
|
+
hash ^= chunk.charCodeAt(index);
|
|
222
|
+
hash = Math.imul(hash, FNV_PRIME) >>> 0;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function shouldHashKey(record, key, includeTemplateRaw) {
|
|
227
|
+
if (key !== "raw") {
|
|
228
|
+
return !IGNORED_KEYS.has(key);
|
|
229
|
+
}
|
|
230
|
+
return includeTemplateRaw || record.type === "RegexLiteral";
|
|
231
|
+
}
|
|
232
|
+
function shouldIncludeTemplateRaw(record, key, includeTemplateRaw) {
|
|
233
|
+
if (record.type === "TaggedTemplateExpression" && key === "quasi") {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
if (includeTemplateRaw && record.type === "TemplateLiteral" && key === "quasis") {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
if (includeTemplateRaw && record.type === "TemplateElement" && key === "value") {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// packages/safe-js/src/snapshot/migration.ts
|
|
246
|
+
function validateMigrationSemantics(value) {
|
|
247
|
+
if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7", "jobs-v8", "jobs-v9"].includes(
|
|
248
|
+
value
|
|
249
|
+
))
|
|
250
|
+
throw new TypeError(
|
|
251
|
+
"Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v9)."
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
function validateMigrationJournal(sourceHash, replay, hostCalls = [], owner) {
|
|
255
|
+
if (replay === void 0)
|
|
256
|
+
throw new TypeError("Migration requires a complete host replay journal.");
|
|
257
|
+
if (!Array.isArray(hostCalls)) throw new TypeError("Invalid migration hostCalls.");
|
|
258
|
+
const journal = new HostCallJournal(
|
|
259
|
+
sourceHash,
|
|
260
|
+
hostCalls,
|
|
261
|
+
void 0,
|
|
262
|
+
replay,
|
|
263
|
+
owner?.budget,
|
|
264
|
+
owner
|
|
265
|
+
);
|
|
266
|
+
try {
|
|
267
|
+
const restored = journal.snapshotReplay();
|
|
268
|
+
for (const call of restored.calls) {
|
|
269
|
+
if (["created", "running"].includes(call.lifecycle) && call.outcome !== void 0)
|
|
270
|
+
throw new TypeError("Unresolved migration calls cannot contain a recorded outcome.");
|
|
271
|
+
for (const callback of call.callbacks ?? []) {
|
|
272
|
+
if (!call.functions?.includes(callback.id))
|
|
273
|
+
throw new TypeError("Migration callback has no registered source function.");
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return restored;
|
|
277
|
+
} finally {
|
|
278
|
+
journal.dispose();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function validateMigrationReconciliation(value, checkpointDigest, calls) {
|
|
282
|
+
validateSnapshotData(value);
|
|
283
|
+
const receipt = value;
|
|
284
|
+
if (receipt === null || typeof receipt !== "object" || receipt.checkpointDigest !== checkpointDigest || !isCheckpointDigest(receipt.checkpointDigest))
|
|
285
|
+
throw new TypeError("Migration reconciliation must identify this exact checkpoint digest.");
|
|
286
|
+
if (receipt.quiescent !== true)
|
|
287
|
+
throw new TypeError(
|
|
288
|
+
"Migration requires explicit host confirmation that execution, operations, and callbacks are quiescent."
|
|
289
|
+
);
|
|
290
|
+
if (!Array.isArray(receipt.calls))
|
|
291
|
+
throw new TypeError("Migration reconciliation calls must be an array.");
|
|
292
|
+
const pending = new Map(
|
|
293
|
+
calls.filter((call) => !["settled", "consumed"].includes(call.lifecycle)).map((call) => [call.id, call])
|
|
294
|
+
);
|
|
295
|
+
for (const resolution of receipt.calls) {
|
|
296
|
+
if (resolution === null || typeof resolution !== "object" || !pending.has(resolution.callId))
|
|
297
|
+
throw new TypeError("Migration contains an unknown or duplicate call resolution.");
|
|
298
|
+
if (!["not-performed", "fulfilled", "rejected"].includes(resolution.disposition) || resolution.disposition === "fulfilled" && !Object.hasOwn(resolution, "value") || resolution.disposition === "rejected" && !Object.hasOwn(resolution, "reason"))
|
|
299
|
+
throw new TypeError(
|
|
300
|
+
"Migration call resolution requires a reconciled outcome or confirmed non-performance."
|
|
301
|
+
);
|
|
302
|
+
pending.delete(resolution.callId);
|
|
303
|
+
}
|
|
304
|
+
if (pending.size > 0)
|
|
305
|
+
throw new TypeError(
|
|
306
|
+
`Migration requires external reconciliation for: ${[...pending.keys()].join(", ")}`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
function validateSnapshotMigration(value, sourceHash, owner) {
|
|
310
|
+
if (value === void 0) return void 0;
|
|
311
|
+
validateSnapshotData(value);
|
|
312
|
+
const migration = value;
|
|
313
|
+
if (migration === null || typeof migration !== "object" || migration.version !== 1 || !Array.isArray(migration.history) || migration.history.length === 0)
|
|
314
|
+
throw new TypeError("Invalid snapshot migration history.");
|
|
315
|
+
const compilation = new CompileScope(owner);
|
|
316
|
+
try {
|
|
317
|
+
decodeReplayData(migration.state, {}, compilation);
|
|
318
|
+
} finally {
|
|
319
|
+
compilation.dispose();
|
|
320
|
+
}
|
|
321
|
+
let previousTarget;
|
|
322
|
+
for (const entry of migration.history) {
|
|
323
|
+
if (entry === null || typeof entry !== "object" || typeof entry.sourceHash !== "string" || entry.sourceHash.length === 0 || typeof entry.targetSourceHash !== "string" || entry.targetSourceHash.length === 0 || previousTarget !== void 0 && previousTarget !== entry.sourceHash)
|
|
324
|
+
throw new TypeError("Invalid snapshot migration ancestry.");
|
|
325
|
+
validateMigrationSemantics(entry.executionSemantics);
|
|
326
|
+
const replay = validateMigrationJournal(entry.sourceHash, entry.replay, [], owner);
|
|
327
|
+
validateMigrationReconciliation(
|
|
328
|
+
entry.reconciliation,
|
|
329
|
+
entry.reconciliation?.checkpointDigest,
|
|
330
|
+
replay.calls
|
|
331
|
+
);
|
|
332
|
+
previousTarget = entry.targetSourceHash;
|
|
333
|
+
}
|
|
334
|
+
if (previousTarget !== sourceHash)
|
|
335
|
+
throw new TypeError("Migration ancestry does not match the target source.");
|
|
336
|
+
return migration;
|
|
337
|
+
}
|
|
338
|
+
function isCheckpointDigest(value) {
|
|
339
|
+
return typeof value === "string" && value.length === 64 && [...value].every((character) => "0123456789abcdef".includes(character));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// packages/safe-js/src/restore.ts
|
|
343
|
+
var SnapshotMismatchError = class extends Error {
|
|
344
|
+
actualHash;
|
|
345
|
+
expectedHash;
|
|
346
|
+
constructor(expectedHash, actualHash) {
|
|
347
|
+
super(
|
|
348
|
+
`source changed since snapshot was taken (hash ${expectedHash} expected, got ${actualHash}); pass --reset to discard`
|
|
349
|
+
);
|
|
350
|
+
this.name = "SnapshotMismatchError";
|
|
351
|
+
this.actualHash = actualHash;
|
|
352
|
+
this.expectedHash = expectedHash;
|
|
353
|
+
replaceErrorStack(this);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
function restore(snapshot, options, owner) {
|
|
357
|
+
assertSnapshotInactive(snapshot);
|
|
358
|
+
try {
|
|
359
|
+
validateDumpEnvelope(snapshot, { resume: true });
|
|
360
|
+
} catch (error) {
|
|
361
|
+
if (!(error instanceof SnapshotValidationError) || error.code !== "invalidState" || error.path === "$.replayError" || !inMemoryRunSnapshots.has(snapshot)) throw error;
|
|
362
|
+
validateRuntimeSnapshotDescriptors(snapshot);
|
|
363
|
+
snapshot = JSON.parse(serializeSafeJSSnapshot(snapshot));
|
|
364
|
+
validateDumpEnvelope(snapshot, { resume: true });
|
|
365
|
+
}
|
|
366
|
+
validateSnapshotMigration(snapshot.migration, snapshot.sourceHash, owner);
|
|
367
|
+
const includeFunctionSource = snapshot.executionSemantics !== "jobs-v6" && snapshot.executionSemantics !== "jobs-v7";
|
|
368
|
+
const currentSourceHash = options.importSpecifiers === void 0 ? hashSource(options.source, owner, includeFunctionSource) : hashParsedAst(parseExecutableModule(options.source, "<input>", owner, options.importSpecifiers), includeFunctionSource);
|
|
369
|
+
if (snapshot.sourceHash !== currentSourceHash) {
|
|
370
|
+
throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
|
|
371
|
+
}
|
|
372
|
+
if (snapshot.heap !== void 0 && typeof snapshot.heap === "object" && snapshot.heap !== null) {
|
|
373
|
+
try {
|
|
374
|
+
validateGuestHeapSource(snapshot.heap, options.importSpecifiers === void 0 ? parseModule(options.source, "<input>", owner) : parseExecutableModule(options.source, "<input>", owner, options.importSpecifiers), owner);
|
|
375
|
+
} catch (error) {
|
|
376
|
+
if (error instanceof SnapshotValidationError || error instanceof SandboxError) throw error;
|
|
377
|
+
throw new SnapshotValidationError("invalidValue", "$.heap", String(error));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return snapshot;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// packages/safe-js/src/parse.ts
|
|
384
|
+
var parse2 = parse;
|
|
140
385
|
|
|
141
386
|
// packages/safe-js/src/lint/rules/AS001.ts
|
|
142
387
|
function AS001(source, options = {}) {
|
|
@@ -11302,109 +11547,6 @@ function hasOnlyRegexLiteralDiagnostics(diagnostics) {
|
|
|
11302
11547
|
);
|
|
11303
11548
|
}
|
|
11304
11549
|
|
|
11305
|
-
// packages/safe-js/src/parse/hash.ts
|
|
11306
|
-
var FNV_OFFSET_BASIS = 2166136261;
|
|
11307
|
-
var FNV_PRIME = 16777619;
|
|
11308
|
-
var IGNORED_KEYS = /* @__PURE__ */ new Set(["nodeId", "raw", "span"]);
|
|
11309
|
-
function hashSource(source, owner, includeFunctionSource = true) {
|
|
11310
|
-
try {
|
|
11311
|
-
return hashParsedAst(parse(source, "<input>", owner), includeFunctionSource);
|
|
11312
|
-
} catch (error) {
|
|
11313
|
-
if (error instanceof SandboxError) throw error;
|
|
11314
|
-
return hashParsedAst(parseModule(source, "<input>", owner), includeFunctionSource);
|
|
11315
|
-
}
|
|
11316
|
-
}
|
|
11317
|
-
function hashParsedAst(ast, includeFunctionSource = true) {
|
|
11318
|
-
let hash = FNV_OFFSET_BASIS;
|
|
11319
|
-
visit(ast);
|
|
11320
|
-
return hash.toString(16).padStart(8, "0");
|
|
11321
|
-
function visit(value, includeTemplateRaw = false, enclosingSource, identifierName = false) {
|
|
11322
|
-
if (value === null) {
|
|
11323
|
-
write("null");
|
|
11324
|
-
return;
|
|
11325
|
-
}
|
|
11326
|
-
if (value === void 0) {
|
|
11327
|
-
write("undefined");
|
|
11328
|
-
return;
|
|
11329
|
-
}
|
|
11330
|
-
if (Array.isArray(value)) {
|
|
11331
|
-
write("[");
|
|
11332
|
-
for (const entry of value) {
|
|
11333
|
-
visit(entry, includeTemplateRaw, enclosingSource);
|
|
11334
|
-
write(",");
|
|
11335
|
-
}
|
|
11336
|
-
write("]");
|
|
11337
|
-
return;
|
|
11338
|
-
}
|
|
11339
|
-
switch (typeof value) {
|
|
11340
|
-
case "boolean":
|
|
11341
|
-
write(value ? "true" : "false");
|
|
11342
|
-
return;
|
|
11343
|
-
case "number":
|
|
11344
|
-
write(Object.is(value, -0) ? "-0" : String(value));
|
|
11345
|
-
return;
|
|
11346
|
-
case "string":
|
|
11347
|
-
write(JSON.stringify(value));
|
|
11348
|
-
return;
|
|
11349
|
-
case "object": {
|
|
11350
|
-
const record = value;
|
|
11351
|
-
if (record.type === "Identifier" && record.name === "undefined" && !identifierName) {
|
|
11352
|
-
visit({ type: "UndefinedLiteral", value: void 0 });
|
|
11353
|
-
return;
|
|
11354
|
-
}
|
|
11355
|
-
const source = includeFunctionSource ? functionSources.get(value) : void 0;
|
|
11356
|
-
if (source !== void 0 && !(enclosingSource !== void 0 && source.text === enclosingSource.text && source.start >= enclosingSource.start && source.end <= enclosingSource.end)) {
|
|
11357
|
-
write("function-source:");
|
|
11358
|
-
write(String(source.end - source.start));
|
|
11359
|
-
write(":");
|
|
11360
|
-
write(source.text, source.start, source.end);
|
|
11361
|
-
}
|
|
11362
|
-
const keys = Object.keys(value).filter((key) => shouldHashKey(record, key, includeTemplateRaw)).sort();
|
|
11363
|
-
write("{");
|
|
11364
|
-
for (const key of keys) {
|
|
11365
|
-
write(JSON.stringify(key));
|
|
11366
|
-
write(":");
|
|
11367
|
-
visit(
|
|
11368
|
-
record[key],
|
|
11369
|
-
shouldIncludeTemplateRaw(record, key, includeTemplateRaw),
|
|
11370
|
-
source ?? enclosingSource,
|
|
11371
|
-
key === "property" && record.type === "MemberExpression" && !record.computed || key === "key" && !record.computed || (key === "imported" || key === "local") && record.type === "ImportSpecifier" || key === "exported" && record.type === "ExportSpecifier"
|
|
11372
|
-
);
|
|
11373
|
-
write(",");
|
|
11374
|
-
}
|
|
11375
|
-
write("}");
|
|
11376
|
-
return;
|
|
11377
|
-
}
|
|
11378
|
-
default:
|
|
11379
|
-
throw new TypeError(`Unsupported AST value type: ${typeof value}`);
|
|
11380
|
-
}
|
|
11381
|
-
}
|
|
11382
|
-
function write(chunk, start = 0, end = chunk.length) {
|
|
11383
|
-
for (let index = start; index < end; index += 1) {
|
|
11384
|
-
hash ^= chunk.charCodeAt(index);
|
|
11385
|
-
hash = Math.imul(hash, FNV_PRIME) >>> 0;
|
|
11386
|
-
}
|
|
11387
|
-
}
|
|
11388
|
-
}
|
|
11389
|
-
function shouldHashKey(record, key, includeTemplateRaw) {
|
|
11390
|
-
if (key !== "raw") {
|
|
11391
|
-
return !IGNORED_KEYS.has(key);
|
|
11392
|
-
}
|
|
11393
|
-
return includeTemplateRaw || record.type === "RegexLiteral";
|
|
11394
|
-
}
|
|
11395
|
-
function shouldIncludeTemplateRaw(record, key, includeTemplateRaw) {
|
|
11396
|
-
if (record.type === "TaggedTemplateExpression" && key === "quasi") {
|
|
11397
|
-
return true;
|
|
11398
|
-
}
|
|
11399
|
-
if (includeTemplateRaw && record.type === "TemplateLiteral" && key === "quasis") {
|
|
11400
|
-
return true;
|
|
11401
|
-
}
|
|
11402
|
-
if (includeTemplateRaw && record.type === "TemplateElement" && key === "value") {
|
|
11403
|
-
return true;
|
|
11404
|
-
}
|
|
11405
|
-
return false;
|
|
11406
|
-
}
|
|
11407
|
-
|
|
11408
11550
|
// packages/safe-js/src/modules/source-graph.ts
|
|
11409
11551
|
var ambiguous = /* @__PURE__ */ Symbol("ambiguous module export");
|
|
11410
11552
|
var sourceRecords = /* @__PURE__ */ new WeakSet();
|
|
@@ -13103,144 +13245,6 @@ function readRealmOptions(value, oneShot = false) {
|
|
|
13103
13245
|
return options;
|
|
13104
13246
|
}
|
|
13105
13247
|
|
|
13106
|
-
// packages/safe-js/src/snapshot/migration.ts
|
|
13107
|
-
function validateMigrationSemantics(value) {
|
|
13108
|
-
if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7", "jobs-v8", "jobs-v9"].includes(
|
|
13109
|
-
value
|
|
13110
|
-
))
|
|
13111
|
-
throw new TypeError(
|
|
13112
|
-
"Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v9)."
|
|
13113
|
-
);
|
|
13114
|
-
}
|
|
13115
|
-
function validateMigrationJournal(sourceHash, replay, hostCalls = [], owner) {
|
|
13116
|
-
if (replay === void 0)
|
|
13117
|
-
throw new TypeError("Migration requires a complete host replay journal.");
|
|
13118
|
-
if (!Array.isArray(hostCalls)) throw new TypeError("Invalid migration hostCalls.");
|
|
13119
|
-
const journal = new HostCallJournal(
|
|
13120
|
-
sourceHash,
|
|
13121
|
-
hostCalls,
|
|
13122
|
-
void 0,
|
|
13123
|
-
replay,
|
|
13124
|
-
owner?.budget,
|
|
13125
|
-
owner
|
|
13126
|
-
);
|
|
13127
|
-
try {
|
|
13128
|
-
const restored = journal.snapshotReplay();
|
|
13129
|
-
for (const call of restored.calls) {
|
|
13130
|
-
if (["created", "running"].includes(call.lifecycle) && call.outcome !== void 0)
|
|
13131
|
-
throw new TypeError("Unresolved migration calls cannot contain a recorded outcome.");
|
|
13132
|
-
for (const callback of call.callbacks ?? []) {
|
|
13133
|
-
if (!call.functions?.includes(callback.id))
|
|
13134
|
-
throw new TypeError("Migration callback has no registered source function.");
|
|
13135
|
-
}
|
|
13136
|
-
}
|
|
13137
|
-
return restored;
|
|
13138
|
-
} finally {
|
|
13139
|
-
journal.dispose();
|
|
13140
|
-
}
|
|
13141
|
-
}
|
|
13142
|
-
function validateMigrationReconciliation(value, checkpointDigest, calls) {
|
|
13143
|
-
validateSnapshotData(value);
|
|
13144
|
-
const receipt = value;
|
|
13145
|
-
if (receipt === null || typeof receipt !== "object" || receipt.checkpointDigest !== checkpointDigest || !isCheckpointDigest(receipt.checkpointDigest))
|
|
13146
|
-
throw new TypeError("Migration reconciliation must identify this exact checkpoint digest.");
|
|
13147
|
-
if (receipt.quiescent !== true)
|
|
13148
|
-
throw new TypeError(
|
|
13149
|
-
"Migration requires explicit host confirmation that execution, operations, and callbacks are quiescent."
|
|
13150
|
-
);
|
|
13151
|
-
if (!Array.isArray(receipt.calls))
|
|
13152
|
-
throw new TypeError("Migration reconciliation calls must be an array.");
|
|
13153
|
-
const pending = new Map(
|
|
13154
|
-
calls.filter((call) => !["settled", "consumed"].includes(call.lifecycle)).map((call) => [call.id, call])
|
|
13155
|
-
);
|
|
13156
|
-
for (const resolution of receipt.calls) {
|
|
13157
|
-
if (resolution === null || typeof resolution !== "object" || !pending.has(resolution.callId))
|
|
13158
|
-
throw new TypeError("Migration contains an unknown or duplicate call resolution.");
|
|
13159
|
-
if (!["not-performed", "fulfilled", "rejected"].includes(resolution.disposition) || resolution.disposition === "fulfilled" && !Object.hasOwn(resolution, "value") || resolution.disposition === "rejected" && !Object.hasOwn(resolution, "reason"))
|
|
13160
|
-
throw new TypeError(
|
|
13161
|
-
"Migration call resolution requires a reconciled outcome or confirmed non-performance."
|
|
13162
|
-
);
|
|
13163
|
-
pending.delete(resolution.callId);
|
|
13164
|
-
}
|
|
13165
|
-
if (pending.size > 0)
|
|
13166
|
-
throw new TypeError(
|
|
13167
|
-
`Migration requires external reconciliation for: ${[...pending.keys()].join(", ")}`
|
|
13168
|
-
);
|
|
13169
|
-
}
|
|
13170
|
-
function validateSnapshotMigration(value, sourceHash, owner) {
|
|
13171
|
-
if (value === void 0) return void 0;
|
|
13172
|
-
validateSnapshotData(value);
|
|
13173
|
-
const migration = value;
|
|
13174
|
-
if (migration === null || typeof migration !== "object" || migration.version !== 1 || !Array.isArray(migration.history) || migration.history.length === 0)
|
|
13175
|
-
throw new TypeError("Invalid snapshot migration history.");
|
|
13176
|
-
const compilation = new CompileScope(owner);
|
|
13177
|
-
try {
|
|
13178
|
-
decodeReplayData(migration.state, {}, compilation);
|
|
13179
|
-
} finally {
|
|
13180
|
-
compilation.dispose();
|
|
13181
|
-
}
|
|
13182
|
-
let previousTarget;
|
|
13183
|
-
for (const entry of migration.history) {
|
|
13184
|
-
if (entry === null || typeof entry !== "object" || typeof entry.sourceHash !== "string" || entry.sourceHash.length === 0 || typeof entry.targetSourceHash !== "string" || entry.targetSourceHash.length === 0 || previousTarget !== void 0 && previousTarget !== entry.sourceHash)
|
|
13185
|
-
throw new TypeError("Invalid snapshot migration ancestry.");
|
|
13186
|
-
validateMigrationSemantics(entry.executionSemantics);
|
|
13187
|
-
const replay = validateMigrationJournal(entry.sourceHash, entry.replay, [], owner);
|
|
13188
|
-
validateMigrationReconciliation(
|
|
13189
|
-
entry.reconciliation,
|
|
13190
|
-
entry.reconciliation?.checkpointDigest,
|
|
13191
|
-
replay.calls
|
|
13192
|
-
);
|
|
13193
|
-
previousTarget = entry.targetSourceHash;
|
|
13194
|
-
}
|
|
13195
|
-
if (previousTarget !== sourceHash)
|
|
13196
|
-
throw new TypeError("Migration ancestry does not match the target source.");
|
|
13197
|
-
return migration;
|
|
13198
|
-
}
|
|
13199
|
-
function isCheckpointDigest(value) {
|
|
13200
|
-
return typeof value === "string" && value.length === 64 && [...value].every((character) => "0123456789abcdef".includes(character));
|
|
13201
|
-
}
|
|
13202
|
-
|
|
13203
|
-
// packages/safe-js/src/restore.ts
|
|
13204
|
-
var SnapshotMismatchError = class extends Error {
|
|
13205
|
-
actualHash;
|
|
13206
|
-
expectedHash;
|
|
13207
|
-
constructor(expectedHash, actualHash) {
|
|
13208
|
-
super(
|
|
13209
|
-
`source changed since snapshot was taken (hash ${expectedHash} expected, got ${actualHash}); pass --reset to discard`
|
|
13210
|
-
);
|
|
13211
|
-
this.name = "SnapshotMismatchError";
|
|
13212
|
-
this.actualHash = actualHash;
|
|
13213
|
-
this.expectedHash = expectedHash;
|
|
13214
|
-
replaceErrorStack(this);
|
|
13215
|
-
}
|
|
13216
|
-
};
|
|
13217
|
-
function restore(snapshot, options, owner) {
|
|
13218
|
-
assertSnapshotInactive(snapshot);
|
|
13219
|
-
try {
|
|
13220
|
-
validateDumpEnvelope(snapshot, { resume: true });
|
|
13221
|
-
} catch (error) {
|
|
13222
|
-
if (!(error instanceof SnapshotValidationError) || error.code !== "invalidState" || error.path === "$.replayError" || !inMemoryRunSnapshots.has(snapshot)) throw error;
|
|
13223
|
-
validateRuntimeSnapshotDescriptors(snapshot);
|
|
13224
|
-
snapshot = JSON.parse(serializeSafeJSSnapshot(snapshot));
|
|
13225
|
-
validateDumpEnvelope(snapshot, { resume: true });
|
|
13226
|
-
}
|
|
13227
|
-
validateSnapshotMigration(snapshot.migration, snapshot.sourceHash, owner);
|
|
13228
|
-
const includeFunctionSource = snapshot.executionSemantics !== "jobs-v6" && snapshot.executionSemantics !== "jobs-v7";
|
|
13229
|
-
const currentSourceHash = options.importSpecifiers === void 0 ? hashSource(options.source, owner, includeFunctionSource) : hashParsedAst(parseExecutableModule(options.source, "<input>", owner, options.importSpecifiers), includeFunctionSource);
|
|
13230
|
-
if (snapshot.sourceHash !== currentSourceHash) {
|
|
13231
|
-
throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
|
|
13232
|
-
}
|
|
13233
|
-
if (snapshot.heap !== void 0 && typeof snapshot.heap === "object" && snapshot.heap !== null) {
|
|
13234
|
-
try {
|
|
13235
|
-
validateGuestHeapSource(snapshot.heap, options.importSpecifiers === void 0 ? parseModule(options.source, "<input>", owner) : parseExecutableModule(options.source, "<input>", owner, options.importSpecifiers), owner);
|
|
13236
|
-
} catch (error) {
|
|
13237
|
-
if (error instanceof SnapshotValidationError || error instanceof SandboxError) throw error;
|
|
13238
|
-
throw new SnapshotValidationError("invalidValue", "$.heap", String(error));
|
|
13239
|
-
}
|
|
13240
|
-
}
|
|
13241
|
-
return snapshot;
|
|
13242
|
-
}
|
|
13243
|
-
|
|
13244
13248
|
// packages/safe-js/src/snapshot/dump.ts
|
|
13245
13249
|
var RUN_DUMP_CONTROLLER = /* @__PURE__ */ Symbol("SafeJS.run-dump-controller");
|
|
13246
13250
|
function attachDumpController(result, controller) {
|
|
@@ -13384,9 +13388,37 @@ function createDumpController(lifecycle, pause) {
|
|
|
13384
13388
|
function isDataBudgetError(error) {
|
|
13385
13389
|
return typeof error === "object" && error !== null && "code" in error && error.code === "budgetExceeded" && "budget" in error && error.budget === "dataSize";
|
|
13386
13390
|
}
|
|
13391
|
+
function dump(result, options = {}) {
|
|
13392
|
+
const controller = readDumpController(result);
|
|
13393
|
+
if (controller !== void 0) {
|
|
13394
|
+
return controller.requestSnapshot(options);
|
|
13395
|
+
}
|
|
13396
|
+
if (hasSnapshot(result)) {
|
|
13397
|
+
try {
|
|
13398
|
+
return Promise.resolve(serializeRunSnapshot(result.snapshot));
|
|
13399
|
+
} catch (error) {
|
|
13400
|
+
return Promise.reject(error);
|
|
13401
|
+
}
|
|
13402
|
+
}
|
|
13403
|
+
return Promise.resolve(result).then((resolved) => {
|
|
13404
|
+
if (!hasSnapshot(resolved)) {
|
|
13405
|
+
throw new Error("Run completed without producing a snapshot.");
|
|
13406
|
+
}
|
|
13407
|
+
return serializeRunSnapshot(resolved.snapshot);
|
|
13408
|
+
});
|
|
13409
|
+
}
|
|
13387
13410
|
function serializeRunSnapshot(snapshot) {
|
|
13388
13411
|
return serializeSafeJSSnapshot(snapshot);
|
|
13389
13412
|
}
|
|
13413
|
+
function hasSnapshot(value) {
|
|
13414
|
+
return typeof value === "object" && value !== null && Object.prototype.hasOwnProperty.call(value, "snapshot");
|
|
13415
|
+
}
|
|
13416
|
+
function readDumpController(value) {
|
|
13417
|
+
if (typeof value !== "object" || value === null) {
|
|
13418
|
+
return void 0;
|
|
13419
|
+
}
|
|
13420
|
+
return value[RUN_DUMP_CONTROLLER];
|
|
13421
|
+
}
|
|
13390
13422
|
|
|
13391
13423
|
// packages/safe-js/src/snapshot/backend.ts
|
|
13392
13424
|
import { createFsBridge } from "@poe-platform/safe-fs/core";
|
|
@@ -13659,7 +13691,7 @@ var UnsnapshotableValueError = class extends Error {
|
|
|
13659
13691
|
};
|
|
13660
13692
|
|
|
13661
13693
|
// packages/safe-js/src/snapshot/replay-inputs.ts
|
|
13662
|
-
function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestored, compilation, onInputSymbols) {
|
|
13694
|
+
function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestored, compilation, onInputSymbols, restoredPromiseOrder = []) {
|
|
13663
13695
|
const identities = /* @__PURE__ */ new WeakMap();
|
|
13664
13696
|
const capabilities = /* @__PURE__ */ new Map();
|
|
13665
13697
|
const promises = /* @__PURE__ */ new Map();
|
|
@@ -13754,6 +13786,8 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
|
|
|
13754
13786
|
return isSandboxClosure(value) ? value : void 0;
|
|
13755
13787
|
};
|
|
13756
13788
|
const memo = { nodes: context.nodes, values: /* @__PURE__ */ new Map() };
|
|
13789
|
+
const restoredRootPromises = /* @__PURE__ */ new Set();
|
|
13790
|
+
const restoredNamespacePromises = /* @__PURE__ */ new Map();
|
|
13757
13791
|
if (saved !== void 0) validateSnapshotData(saved);
|
|
13758
13792
|
const snapshot = saved === void 0 ? encodeReplayData(current, {
|
|
13759
13793
|
context,
|
|
@@ -13771,6 +13805,7 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
|
|
|
13771
13805
|
resolveCapability,
|
|
13772
13806
|
resolvePromise: (id) => {
|
|
13773
13807
|
readCapability(id);
|
|
13808
|
+
restoredRootPromises.add(id);
|
|
13774
13809
|
return createSandboxPromise(Promise.resolve(void 0), { trackReplay: false });
|
|
13775
13810
|
}
|
|
13776
13811
|
}, validationScope);
|
|
@@ -13779,7 +13814,8 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
|
|
|
13779
13814
|
if (snapshot.namespaceRoots === null || typeof snapshot.namespaceRoots !== "object" || Array.isArray(snapshot.namespaceRoots))
|
|
13780
13815
|
throw new TypeError("Invalid replay namespace roots.");
|
|
13781
13816
|
const validationCapability = createSandboxClosure({ call: () => void 0 });
|
|
13782
|
-
for (const root of Object.
|
|
13817
|
+
for (const [name, root] of Object.entries(snapshot.namespaceRoots)) {
|
|
13818
|
+
const ids = /* @__PURE__ */ new Set();
|
|
13783
13819
|
const namespace = decodeReplayData({ root, nodes: snapshot.nodes }, {
|
|
13784
13820
|
resolveCapability: (id) => {
|
|
13785
13821
|
readCapability(id);
|
|
@@ -13787,10 +13823,12 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
|
|
|
13787
13823
|
},
|
|
13788
13824
|
resolvePromise: (id) => {
|
|
13789
13825
|
readCapability(id);
|
|
13826
|
+
ids.add(id);
|
|
13790
13827
|
return createSandboxPromise(Promise.resolve(void 0), { trackReplay: false });
|
|
13791
13828
|
}
|
|
13792
13829
|
}, validationScope);
|
|
13793
13830
|
if (!isSandboxModuleNamespace(namespace)) throw new TypeError("Invalid replay module namespace.");
|
|
13831
|
+
restoredNamespacePromises.set(name, ids);
|
|
13794
13832
|
}
|
|
13795
13833
|
}
|
|
13796
13834
|
} finally {
|
|
@@ -13813,6 +13851,7 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
|
|
|
13813
13851
|
promises.set(id, preparePromise(isSandboxPromise(value) ? value : void 0, id));
|
|
13814
13852
|
return promises.get(id);
|
|
13815
13853
|
};
|
|
13854
|
+
for (const id of restoredPromiseOrder) if (restoredRootPromises.has(id)) resolvePromise(id);
|
|
13816
13855
|
if (inputPromises.size > 0) {
|
|
13817
13856
|
memo.values.clear();
|
|
13818
13857
|
for (const [id, symbol] of inputSymbols) memo.values.set(id, symbol);
|
|
@@ -13843,6 +13882,10 @@ function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestore
|
|
|
13843
13882
|
captureNamespace,
|
|
13844
13883
|
prepareNamespace: (namespace, name) => {
|
|
13845
13884
|
captureNamespace(namespace, name);
|
|
13885
|
+
const ids = restoredNamespacePromises.get(name);
|
|
13886
|
+
if (ids !== void 0) {
|
|
13887
|
+
for (const id of restoredPromiseOrder) if (ids.has(id)) resolvePromise(id);
|
|
13888
|
+
}
|
|
13846
13889
|
return decodeReplayData(
|
|
13847
13890
|
{ root: snapshot.namespaceRoots[name], nodes: snapshot.nodes },
|
|
13848
13891
|
{ memo, resolveCapability, resolvePromise, onCapabilityRestored },
|
|
@@ -13885,7 +13928,7 @@ function run(source, options = {}) {
|
|
|
13885
13928
|
throw new TypeError("Source resolution requires sourceType: 'module'.");
|
|
13886
13929
|
if (options.sourceRoot !== void 0) {
|
|
13887
13930
|
if (options.sourceResolver !== void 0) throw new TypeError("Specify sourceRoot or sourceResolver, not both.");
|
|
13888
|
-
const { createRootedSourceResolver: createRootedSourceResolver2 } = await import("./chunks/source-files-
|
|
13931
|
+
const { createRootedSourceResolver: createRootedSourceResolver2 } = await import("./chunks/source-files-AEDWESAJ.js");
|
|
13889
13932
|
const { sourceRoot, ...resolved } = options;
|
|
13890
13933
|
const sourceResolver = await createRootedSourceResolver2(sourceRoot);
|
|
13891
13934
|
return runWithExtensions(source, { ...resolved, filename: await sourceResolver.entryId(options.filename), sourceResolver }, jobs);
|
|
@@ -14049,7 +14092,8 @@ function run(source, options = {}) {
|
|
|
14049
14092
|
prepareInputPromise,
|
|
14050
14093
|
hostCalls.rebindHostCapability.bind(hostCalls),
|
|
14051
14094
|
compilation,
|
|
14052
|
-
hostCalls.registerInputSymbols.bind(hostCalls)
|
|
14095
|
+
hostCalls.registerInputSymbols.bind(hostCalls),
|
|
14096
|
+
hostCalls.inputPromiseOrder()
|
|
14053
14097
|
);
|
|
14054
14098
|
leaveInputReplay = () => {
|
|
14055
14099
|
budget.setRetainedDataUsage(initialInputs, 0);
|
|
@@ -14497,7 +14541,7 @@ function makeEnvModule(input) {
|
|
|
14497
14541
|
get(name) {
|
|
14498
14542
|
const variable = readEnvName(name, "Environment variable name");
|
|
14499
14543
|
if (!allowedNames.has(variable)) throw new EnvAccessError(variable);
|
|
14500
|
-
return readEnvValue(values ?? (
|
|
14544
|
+
return readEnvValue(values ?? hostEnv(), variable);
|
|
14501
14545
|
}
|
|
14502
14546
|
};
|
|
14503
14547
|
}
|
|
@@ -14741,23 +14785,197 @@ function assertSleepDelay(ms) {
|
|
|
14741
14785
|
function createSleepAbortError() {
|
|
14742
14786
|
return new Error("time.sleep aborted.");
|
|
14743
14787
|
}
|
|
14788
|
+
|
|
14789
|
+
// packages/safe-js/src/output-stream.ts
|
|
14790
|
+
function createBrokenPipeState() {
|
|
14791
|
+
return { closed: false };
|
|
14792
|
+
}
|
|
14793
|
+
function createSafeOutputStream(stream, brokenPipe) {
|
|
14794
|
+
return {
|
|
14795
|
+
write(chunk) {
|
|
14796
|
+
if (brokenPipe.closed) {
|
|
14797
|
+
return;
|
|
14798
|
+
}
|
|
14799
|
+
try {
|
|
14800
|
+
stream.write(chunk);
|
|
14801
|
+
} catch (error) {
|
|
14802
|
+
if (isBrokenPipeError(error)) {
|
|
14803
|
+
brokenPipe.closed = true;
|
|
14804
|
+
return;
|
|
14805
|
+
}
|
|
14806
|
+
throw error;
|
|
14807
|
+
}
|
|
14808
|
+
}
|
|
14809
|
+
};
|
|
14810
|
+
}
|
|
14811
|
+
function addBrokenPipeListener(stream, brokenPipe) {
|
|
14812
|
+
const onError = (error) => {
|
|
14813
|
+
if (isBrokenPipeError(error)) {
|
|
14814
|
+
brokenPipe.closed = true;
|
|
14815
|
+
return;
|
|
14816
|
+
}
|
|
14817
|
+
throw error;
|
|
14818
|
+
};
|
|
14819
|
+
stream.on?.("error", onError);
|
|
14820
|
+
return () => {
|
|
14821
|
+
stream.off?.("error", onError);
|
|
14822
|
+
};
|
|
14823
|
+
}
|
|
14824
|
+
function isBrokenPipeError(error) {
|
|
14825
|
+
return hasOwnErrorCode(error, "EPIPE");
|
|
14826
|
+
}
|
|
14827
|
+
|
|
14828
|
+
// packages/safe-js/src/modules/log.ts
|
|
14829
|
+
var stdoutSinks = /* @__PURE__ */ new WeakMap();
|
|
14830
|
+
function makeLogModule(sink = createJsonlStdoutSink()) {
|
|
14831
|
+
const normalizedSink = readSink(sink);
|
|
14832
|
+
return {
|
|
14833
|
+
info(...args) {
|
|
14834
|
+
normalizedSink({
|
|
14835
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14836
|
+
type: "info",
|
|
14837
|
+
args
|
|
14838
|
+
});
|
|
14839
|
+
},
|
|
14840
|
+
error(...args) {
|
|
14841
|
+
normalizedSink({
|
|
14842
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14843
|
+
type: "error",
|
|
14844
|
+
args
|
|
14845
|
+
});
|
|
14846
|
+
},
|
|
14847
|
+
event(name, payload) {
|
|
14848
|
+
normalizedSink({
|
|
14849
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14850
|
+
type: "event",
|
|
14851
|
+
name: readNonEmptyString3(name, "Event name"),
|
|
14852
|
+
payload
|
|
14853
|
+
});
|
|
14854
|
+
}
|
|
14855
|
+
};
|
|
14856
|
+
}
|
|
14857
|
+
function createJsonlStdoutSink() {
|
|
14858
|
+
const stream = typeof process !== "undefined" ? process.stdout : void 0;
|
|
14859
|
+
if (stream == null || typeof stream.write !== "function") {
|
|
14860
|
+
return (entry) => console.log(JSON.stringify(toJsonValue(entry, /* @__PURE__ */ new WeakSet())));
|
|
14861
|
+
}
|
|
14862
|
+
const existing = stdoutSinks.get(stream);
|
|
14863
|
+
if (existing) return existing;
|
|
14864
|
+
const brokenPipe = createBrokenPipeState();
|
|
14865
|
+
const stdout = createSafeOutputStream(stream, brokenPipe);
|
|
14866
|
+
addBrokenPipeListener(stream, brokenPipe);
|
|
14867
|
+
const sink = (entry) => {
|
|
14868
|
+
stdout.write(`${JSON.stringify(toJsonValue(entry, /* @__PURE__ */ new WeakSet()))}
|
|
14869
|
+
`);
|
|
14870
|
+
};
|
|
14871
|
+
stdoutSinks.set(stream, sink);
|
|
14872
|
+
return sink;
|
|
14873
|
+
}
|
|
14874
|
+
function readNonEmptyString3(value, label) {
|
|
14875
|
+
if (typeof value !== "string") {
|
|
14876
|
+
throw new Error(`${label} must be a non-empty string.`);
|
|
14877
|
+
}
|
|
14878
|
+
const normalizedValue = value.trim();
|
|
14879
|
+
if (normalizedValue.length === 0) {
|
|
14880
|
+
throw new Error(`${label} must be a non-empty string.`);
|
|
14881
|
+
}
|
|
14882
|
+
return normalizedValue;
|
|
14883
|
+
}
|
|
14884
|
+
function readSink(value) {
|
|
14885
|
+
if (typeof value !== "function") {
|
|
14886
|
+
throw new Error("Log sink must be a function.");
|
|
14887
|
+
}
|
|
14888
|
+
return value;
|
|
14889
|
+
}
|
|
14890
|
+
function toJsonValue(value, seen) {
|
|
14891
|
+
if (value === void 0) {
|
|
14892
|
+
return null;
|
|
14893
|
+
}
|
|
14894
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
14895
|
+
return value;
|
|
14896
|
+
}
|
|
14897
|
+
if (typeof value === "number") {
|
|
14898
|
+
return Number.isFinite(value) ? value : String(value);
|
|
14899
|
+
}
|
|
14900
|
+
if (typeof value === "bigint" || typeof value === "symbol") {
|
|
14901
|
+
return String(value);
|
|
14902
|
+
}
|
|
14903
|
+
if (typeof value === "function") {
|
|
14904
|
+
return `[Function ${value.name || "anonymous"}]`;
|
|
14905
|
+
}
|
|
14906
|
+
if (value instanceof Date) {
|
|
14907
|
+
return Number.isNaN(value.getTime()) ? "Invalid Date" : value.toISOString();
|
|
14908
|
+
}
|
|
14909
|
+
if (value instanceof Error) {
|
|
14910
|
+
const serializedError = {
|
|
14911
|
+
name: value.name,
|
|
14912
|
+
message: value.message
|
|
14913
|
+
};
|
|
14914
|
+
if (typeof value.stack === "string" && value.stack.length > 0) {
|
|
14915
|
+
serializedError.stack = value.stack;
|
|
14916
|
+
}
|
|
14917
|
+
if (Object.prototype.hasOwnProperty.call(value, "cause")) {
|
|
14918
|
+
serializedError.cause = toJsonValue(value.cause, seen);
|
|
14919
|
+
}
|
|
14920
|
+
return serializedError;
|
|
14921
|
+
}
|
|
14922
|
+
if (Array.isArray(value)) {
|
|
14923
|
+
if (seen.has(value)) {
|
|
14924
|
+
return "[Circular]";
|
|
14925
|
+
}
|
|
14926
|
+
seen.add(value);
|
|
14927
|
+
const normalized = value.map((entry) => toJsonValue(entry, seen));
|
|
14928
|
+
seen.delete(value);
|
|
14929
|
+
return normalized;
|
|
14930
|
+
}
|
|
14931
|
+
if (typeof value === "object") {
|
|
14932
|
+
if (seen.has(value)) {
|
|
14933
|
+
return "[Circular]";
|
|
14934
|
+
}
|
|
14935
|
+
seen.add(value);
|
|
14936
|
+
const normalized = /* @__PURE__ */ Object.create(null);
|
|
14937
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
14938
|
+
normalized[key] = toJsonValue(entry, seen);
|
|
14939
|
+
}
|
|
14940
|
+
seen.delete(value);
|
|
14941
|
+
return normalized;
|
|
14942
|
+
}
|
|
14943
|
+
return String(value);
|
|
14944
|
+
}
|
|
14945
|
+
|
|
14946
|
+
// packages/safe-js/src/core.ts
|
|
14947
|
+
var parseModule2 = parseModule;
|
|
14948
|
+
var parseSourceModule2 = parseSourceModule;
|
|
14949
|
+
var restore2 = restore;
|
|
14950
|
+
var deepCopyFromSandbox2 = deepCopyFromSandbox;
|
|
14744
14951
|
export {
|
|
14745
14952
|
Budget,
|
|
14746
14953
|
EnvAccessError,
|
|
14747
14954
|
FS_OPTION_SURFACE,
|
|
14748
14955
|
HarnessFailure,
|
|
14956
|
+
SandboxError,
|
|
14957
|
+
SnapshotValidationError,
|
|
14749
14958
|
admitNativePromiseProperties,
|
|
14750
14959
|
createRealm,
|
|
14751
14960
|
createReplayableRandom,
|
|
14752
14961
|
createRootedSourceResolver,
|
|
14962
|
+
declareHostOperation,
|
|
14963
|
+
deepCopyFromSandbox2 as deepCopyFromSandbox,
|
|
14964
|
+
deepCopyToSandbox,
|
|
14753
14965
|
defineExtension,
|
|
14966
|
+
dump,
|
|
14754
14967
|
lint,
|
|
14755
14968
|
makeEnvModule,
|
|
14756
14969
|
makeFailModule,
|
|
14757
14970
|
makeFsModule,
|
|
14758
14971
|
makeHarnessModule,
|
|
14972
|
+
makeLogModule,
|
|
14759
14973
|
makeMetricModule,
|
|
14760
14974
|
makeTimeModule,
|
|
14975
|
+
parse2 as parse,
|
|
14761
14976
|
parseEnvConfig,
|
|
14977
|
+
parseModule2 as parseModule,
|
|
14978
|
+
parseSourceModule2 as parseSourceModule,
|
|
14979
|
+
restore2 as restore,
|
|
14762
14980
|
run
|
|
14763
14981
|
};
|