wasm-idle 1.0.8 → 1.0.9
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 +48 -11
- package/dist/playground/applicationAssets.js +18 -0
- package/dist/playground/assets.d.ts +70 -0
- package/dist/playground/assets.js +120 -0
- package/dist/playground/cachedClang.js +43 -5
- package/dist/playground/clang.d.ts +5 -0
- package/dist/playground/clang.js +96 -0
- package/dist/playground/clangWorkerProtocol.d.ts +12 -1
- package/dist/playground/fennel.d.ts +9 -0
- package/dist/playground/fennel.js +30 -0
- package/dist/playground/fennelBootstrap.d.ts +31 -0
- package/dist/playground/fennelBootstrap.js +118 -0
- package/dist/playground/grain.d.ts +9 -0
- package/dist/playground/grain.js +127 -0
- package/dist/playground/hy.d.ts +21 -0
- package/dist/playground/hy.js +24 -0
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.js +49 -0
- package/dist/playground/lua.d.ts +19 -0
- package/dist/playground/lua.js +64 -39
- package/dist/playground/objectivec.d.ts +3 -1
- package/dist/playground/objectivec.js +6 -2
- package/dist/playground/options.js +1 -1
- package/dist/playground/postgresql.d.ts +36 -0
- package/dist/playground/postgresql.js +543 -0
- package/dist/playground/python.d.ts +5 -0
- package/dist/playground/python.js +13 -0
- package/dist/playground/rescript.d.ts +5 -0
- package/dist/playground/rescript.js +58 -0
- package/dist/playground/rescriptPreflight.d.ts +26 -0
- package/dist/playground/rescriptPreflight.js +381 -0
- package/dist/playground/staticRuntimeModuleVersion.d.ts +1 -1
- package/dist/playground/staticRuntimeModuleVersion.js +1 -1
- package/dist/playground/staticRuntimePreflightExecute.d.ts +2 -1
- package/dist/playground/staticRuntimePreflightExecute.js +9 -0
- package/dist/playground/staticRuntimePreflightProtocol.d.ts +1 -1
- package/dist/playground/v.d.ts +46 -0
- package/dist/playground/v.js +703 -0
- package/dist/playground/wasmFennelVersion.d.ts +23 -0
- package/dist/playground/wasmFennelVersion.js +16 -0
- package/dist/playground/wasmGrainVersion.d.ts +24 -0
- package/dist/playground/wasmGrainVersion.js +25 -0
- package/dist/playground/wasmHyVersion.d.ts +7 -0
- package/dist/playground/wasmHyVersion.js +15 -0
- package/dist/playground/wasmReScriptVersion.d.ts +20 -0
- package/dist/playground/wasmReScriptVersion.js +20 -0
- package/dist/playground/worker/cachedClangCompile.js +37 -4
- package/dist/playground/worker/clang.js +35 -7
- package/dist/playground/worker/lua.js +48 -11
- package/dist/playground/worker/postgresql.d.ts +1 -0
- package/dist/playground/worker/postgresql.js +205 -0
- package/dist/playground/worker/python.js +106 -9
- package/dist/playground/worker/staticRuntimePreflight.js +2 -1
- package/dist/playground/worker/v.d.ts +1 -0
- package/dist/playground/worker/v.js +106 -0
- package/package.json +18 -7
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReScriptRuntimePreflightProfile } from './assets';
|
|
2
|
+
import { type ExecutionLimits, type RuntimeAssetCacheOptions, type RuntimeAssetPreflightProgress } from '@wasm-idle/core';
|
|
3
|
+
export declare const RESCRIPT_PREFLIGHT_PROTOCOL: "wasm-idle-rescript-preflight";
|
|
4
|
+
export declare const RESCRIPT_PREFLIGHT_PROTOCOL_VERSION: 1;
|
|
5
|
+
export declare const RESCRIPT_PREFLIGHT_RUNTIME_ID: "RESCRIPT";
|
|
6
|
+
export interface ReScriptRuntimePreflightRequest {
|
|
7
|
+
readonly baseUrl: string;
|
|
8
|
+
readonly manifestUrl: string;
|
|
9
|
+
readonly profile: ReScriptRuntimePreflightProfile;
|
|
10
|
+
readonly limits?: Partial<ExecutionLimits>;
|
|
11
|
+
readonly persistentCache?: RuntimeAssetCacheOptions;
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
14
|
+
readonly reportProgress?: (progress: RuntimeAssetPreflightProgress) => void;
|
|
15
|
+
readonly reportDecompressionProgress?: (loadedBytes: number, totalBytes: number) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface ReScriptRuntimePreflightPayload {
|
|
18
|
+
readonly protocol: typeof RESCRIPT_PREFLIGHT_PROTOCOL;
|
|
19
|
+
readonly protocolVersion: typeof RESCRIPT_PREFLIGHT_PROTOCOL_VERSION;
|
|
20
|
+
readonly profileId: string;
|
|
21
|
+
readonly sourceRevision: string;
|
|
22
|
+
readonly manifestFingerprint: string;
|
|
23
|
+
readonly manifestBytes: Uint8Array;
|
|
24
|
+
readonly compilerBytes: Uint8Array;
|
|
25
|
+
}
|
|
26
|
+
export declare function preflightReScriptRuntimeAssets(request: ReScriptRuntimePreflightRequest): Promise<ReScriptRuntimePreflightPayload>;
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { AssetIntegrityError, AssetTooLargeError, CancelledError, RuntimeConfigurationError, TimeoutError, UnsupportedBrowserFeatureError, isWasmIdleError, preflightRuntimeAssets, resolveExecutionLimits, verifyRuntimeAssetIntegrity } from '@wasm-idle/core';
|
|
2
|
+
export const RESCRIPT_PREFLIGHT_PROTOCOL = 'wasm-idle-rescript-preflight';
|
|
3
|
+
export const RESCRIPT_PREFLIGHT_PROTOCOL_VERSION = 1;
|
|
4
|
+
export const RESCRIPT_PREFLIGHT_RUNTIME_ID = 'RESCRIPT';
|
|
5
|
+
const MAX_MANIFEST_BYTES = 64 * 1024;
|
|
6
|
+
const HARD_MAX_ASSET_BYTES = 16 * 1024 * 1024;
|
|
7
|
+
const VERIFIED_COMPILER_STORAGE_PATH = 'compiler.js.gz.bin';
|
|
8
|
+
export async function preflightReScriptRuntimeAssets(request) {
|
|
9
|
+
if (!request || typeof request !== 'object') {
|
|
10
|
+
throw new RuntimeConfigurationError('ReScript runtime preflight request is required', {
|
|
11
|
+
phase: 'asset',
|
|
12
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
let baseUrl;
|
|
16
|
+
let manifestUrl;
|
|
17
|
+
try {
|
|
18
|
+
baseUrl = new URL(request.baseUrl);
|
|
19
|
+
if (!baseUrl.pathname.endsWith('/'))
|
|
20
|
+
baseUrl.pathname += '/';
|
|
21
|
+
manifestUrl = new URL(request.manifestUrl, baseUrl);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
throw new RuntimeConfigurationError('ReScript runtime asset URLs are invalid', {
|
|
25
|
+
cause: error,
|
|
26
|
+
phase: 'asset',
|
|
27
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if ((baseUrl.protocol !== 'https:' && baseUrl.protocol !== 'http:') ||
|
|
31
|
+
baseUrl.username ||
|
|
32
|
+
baseUrl.password ||
|
|
33
|
+
baseUrl.search ||
|
|
34
|
+
baseUrl.hash) {
|
|
35
|
+
throw new RuntimeConfigurationError('ReScript runtime base must be a credential-free HTTP(S) directory URL without a query or fragment', { phase: 'asset', runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID });
|
|
36
|
+
}
|
|
37
|
+
if ((manifestUrl.protocol !== 'https:' && manifestUrl.protocol !== 'http:') ||
|
|
38
|
+
manifestUrl.username ||
|
|
39
|
+
manifestUrl.password ||
|
|
40
|
+
manifestUrl.hash ||
|
|
41
|
+
manifestUrl.origin !== baseUrl.origin ||
|
|
42
|
+
!manifestUrl.pathname.startsWith(baseUrl.pathname)) {
|
|
43
|
+
throw new RuntimeConfigurationError('ReScript runtime manifest must be an HTTP(S) asset beneath the configured runtime base', { phase: 'asset', runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID });
|
|
44
|
+
}
|
|
45
|
+
const manifestPath = manifestUrl.pathname.slice(baseUrl.pathname.length);
|
|
46
|
+
if (!manifestPath ||
|
|
47
|
+
manifestPath.includes('\\') ||
|
|
48
|
+
manifestPath.includes('\0') ||
|
|
49
|
+
manifestPath.split('/').some((segment) => !segment || segment === '.' || segment === '..')) {
|
|
50
|
+
throw new RuntimeConfigurationError('ReScript runtime manifest path must be a normalized file beneath the runtime base', { phase: 'asset', runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID });
|
|
51
|
+
}
|
|
52
|
+
if (manifestPath === VERIFIED_COMPILER_STORAGE_PATH) {
|
|
53
|
+
throw new RuntimeConfigurationError('ReScript runtime manifest and compiler storage paths must be distinct', { phase: 'asset', runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID });
|
|
54
|
+
}
|
|
55
|
+
const profile = request.profile;
|
|
56
|
+
if (!profile ||
|
|
57
|
+
typeof profile !== 'object' ||
|
|
58
|
+
typeof profile.profileId !== 'string' ||
|
|
59
|
+
!/^rescript-[A-Za-z0-9._+-]+$/u.test(profile.profileId) ||
|
|
60
|
+
typeof profile.sourceRevision !== 'string' ||
|
|
61
|
+
profile.sourceRevision !== 'v12.3.1' ||
|
|
62
|
+
typeof profile.manifestFingerprint !== 'string' ||
|
|
63
|
+
!/^[a-f0-9]{64}$/u.test(profile.manifestFingerprint)) {
|
|
64
|
+
throw new RuntimeConfigurationError('ReScript runtime preflight profile is invalid', {
|
|
65
|
+
phase: 'asset',
|
|
66
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const manifestReceipt = profile.manifestReceipt;
|
|
70
|
+
if (!manifestReceipt ||
|
|
71
|
+
typeof manifestReceipt !== 'object' ||
|
|
72
|
+
!Number.isSafeInteger(manifestReceipt.bytes) ||
|
|
73
|
+
(manifestReceipt.bytes ?? 0) <= 0 ||
|
|
74
|
+
typeof manifestReceipt.sha256 !== 'string' ||
|
|
75
|
+
!/^[a-f0-9]{64}$/u.test(manifestReceipt.sha256)) {
|
|
76
|
+
throw new RuntimeConfigurationError('ReScript runtime manifest preflight receipt is invalid', {
|
|
77
|
+
phase: 'asset',
|
|
78
|
+
profileId: profile.profileId,
|
|
79
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const compilerReceipt = profile.compilerReceipt;
|
|
83
|
+
if (!compilerReceipt ||
|
|
84
|
+
typeof compilerReceipt !== 'object' ||
|
|
85
|
+
!Number.isSafeInteger(compilerReceipt.bytes) ||
|
|
86
|
+
(compilerReceipt.bytes ?? 0) <= 0 ||
|
|
87
|
+
typeof compilerReceipt.sha256 !== 'string' ||
|
|
88
|
+
!/^[a-f0-9]{64}$/u.test(compilerReceipt.sha256) ||
|
|
89
|
+
!Number.isSafeInteger(compilerReceipt.uncompressedBytes) ||
|
|
90
|
+
(compilerReceipt.uncompressedBytes ?? 0) <= 0 ||
|
|
91
|
+
typeof compilerReceipt.uncompressedSha256 !== 'string' ||
|
|
92
|
+
!/^[a-f0-9]{64}$/u.test(compilerReceipt.uncompressedSha256)) {
|
|
93
|
+
throw new RuntimeConfigurationError('ReScript runtime compiler preflight receipt is invalid', {
|
|
94
|
+
phase: 'asset',
|
|
95
|
+
profileId: profile.profileId,
|
|
96
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const limits = resolveExecutionLimits(request.limits);
|
|
100
|
+
const maxAssetBytes = Math.min(limits.maxAssetBytes, HARD_MAX_ASSET_BYTES);
|
|
101
|
+
const oversized = [
|
|
102
|
+
['manifest', manifestReceipt.bytes, Math.min(MAX_MANIFEST_BYTES, maxAssetBytes)],
|
|
103
|
+
['compressed compiler', compilerReceipt.bytes, maxAssetBytes],
|
|
104
|
+
['logical compiler', compilerReceipt.uncompressedBytes, maxAssetBytes]
|
|
105
|
+
];
|
|
106
|
+
for (const [label, bytes, limit] of oversized) {
|
|
107
|
+
if (bytes > limit) {
|
|
108
|
+
throw new AssetTooLargeError(`ReScript runtime ${label} exceeds the ${limit} byte limit`, {
|
|
109
|
+
actual: bytes,
|
|
110
|
+
limit,
|
|
111
|
+
phase: 'asset',
|
|
112
|
+
profileId: profile.profileId,
|
|
113
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (typeof DecompressionStream !== 'function') {
|
|
118
|
+
throw new UnsupportedBrowserFeatureError('DecompressionStream(gzip)', {
|
|
119
|
+
phase: 'asset',
|
|
120
|
+
profileId: profile.profileId,
|
|
121
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const expectedManifestQuery = `?v=${profile.manifestFingerprint}`;
|
|
125
|
+
if (manifestUrl.search && manifestUrl.search !== expectedManifestQuery) {
|
|
126
|
+
throw new RuntimeConfigurationError('ReScript runtime manifest query must be the pinned manifest fingerprint cache-buster', {
|
|
127
|
+
phase: 'asset',
|
|
128
|
+
profileId: profile.profileId,
|
|
129
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
const manifestRequestUrl = new URL(manifestUrl);
|
|
133
|
+
if (!manifestRequestUrl.search) {
|
|
134
|
+
manifestRequestUrl.searchParams.set('v', profile.manifestFingerprint);
|
|
135
|
+
}
|
|
136
|
+
const compilerRequestUrl = new URL(VERIFIED_COMPILER_STORAGE_PATH, baseUrl);
|
|
137
|
+
compilerRequestUrl.searchParams.set('v', compilerReceipt.sha256);
|
|
138
|
+
const registry = {
|
|
139
|
+
schemaVersion: 2,
|
|
140
|
+
manifestId: 'wasm-idle/rescript-preflight',
|
|
141
|
+
revision: profile.manifestFingerprint,
|
|
142
|
+
runtimes: [
|
|
143
|
+
{
|
|
144
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID,
|
|
145
|
+
identity: {
|
|
146
|
+
languageId: 'RESCRIPT',
|
|
147
|
+
implementationId: 'rescript-playground',
|
|
148
|
+
implementationVersion: profile.sourceRevision,
|
|
149
|
+
profile: {
|
|
150
|
+
profileId: profile.profileId,
|
|
151
|
+
manifestSchemaVersion: 2,
|
|
152
|
+
manifestSha256: manifestReceipt.sha256,
|
|
153
|
+
protocolVersion: RESCRIPT_PREFLIGHT_PROTOCOL_VERSION,
|
|
154
|
+
trustProfileId: 'wasm-idle-static-worker-v1',
|
|
155
|
+
trustProfileSchemaVersion: 1
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
capabilities: {
|
|
159
|
+
stdin: 'streaming',
|
|
160
|
+
workspace: true,
|
|
161
|
+
abort: true,
|
|
162
|
+
artifacts: false,
|
|
163
|
+
streamingOutput: true
|
|
164
|
+
},
|
|
165
|
+
workerLifetime: { mode: 'per-run' },
|
|
166
|
+
requiredBrowserFeatures: ['decompression-stream'],
|
|
167
|
+
assetRoot: '.',
|
|
168
|
+
assets: [
|
|
169
|
+
{
|
|
170
|
+
key: 'manifest',
|
|
171
|
+
path: manifestPath,
|
|
172
|
+
compressedSha256: manifestReceipt.sha256,
|
|
173
|
+
uncompressedSha256: manifestReceipt.sha256,
|
|
174
|
+
compressedBytes: manifestReceipt.bytes,
|
|
175
|
+
uncompressedBytes: manifestReceipt.bytes,
|
|
176
|
+
mediaType: 'application/json',
|
|
177
|
+
encoding: 'identity'
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
key: 'compiler',
|
|
181
|
+
path: VERIFIED_COMPILER_STORAGE_PATH,
|
|
182
|
+
compressedSha256: compilerReceipt.sha256,
|
|
183
|
+
uncompressedSha256: compilerReceipt.uncompressedSha256,
|
|
184
|
+
compressedBytes: compilerReceipt.bytes,
|
|
185
|
+
uncompressedBytes: compilerReceipt.uncompressedBytes,
|
|
186
|
+
mediaType: 'text/javascript',
|
|
187
|
+
encoding: 'gzip'
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
contracts: {
|
|
191
|
+
routeId: 'rescript',
|
|
192
|
+
runtimeAssetKey: 'rescript',
|
|
193
|
+
documentationId: 'RESCRIPT',
|
|
194
|
+
syncTarget: 'sync:wasm-rescript',
|
|
195
|
+
browserTestId: 'browser:rescript'
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
};
|
|
200
|
+
const controller = new AbortController();
|
|
201
|
+
let timedOut = false;
|
|
202
|
+
const abortFromCaller = () => controller.abort(request.signal?.reason);
|
|
203
|
+
request.signal?.addEventListener('abort', abortFromCaller, { once: true });
|
|
204
|
+
if (request.signal?.aborted)
|
|
205
|
+
abortFromCaller();
|
|
206
|
+
const timeout = setTimeout(() => {
|
|
207
|
+
timedOut = true;
|
|
208
|
+
controller.abort(new DOMException('ReScript runtime preflight timed out', 'TimeoutError'));
|
|
209
|
+
}, limits.assetTimeoutMs);
|
|
210
|
+
try {
|
|
211
|
+
const preflight = await preflightRuntimeAssets({
|
|
212
|
+
manifest: registry,
|
|
213
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID,
|
|
214
|
+
rootUrl: baseUrl,
|
|
215
|
+
assetUrls: {
|
|
216
|
+
manifest: manifestRequestUrl,
|
|
217
|
+
compiler: compilerRequestUrl
|
|
218
|
+
},
|
|
219
|
+
fetch: request.fetch,
|
|
220
|
+
persistentCache: request.persistentCache,
|
|
221
|
+
signal: controller.signal,
|
|
222
|
+
limits: { ...limits, maxAssetBytes },
|
|
223
|
+
maxConcurrentDownloads: 2,
|
|
224
|
+
reportProgress: request.reportProgress
|
|
225
|
+
});
|
|
226
|
+
const manifestAsset = preflight.assets.manifest;
|
|
227
|
+
const compilerAsset = preflight.assets.compiler;
|
|
228
|
+
if (!manifestAsset || !compilerAsset) {
|
|
229
|
+
throw new RuntimeConfigurationError('ReScript runtime preflight returned an incomplete asset set', {
|
|
230
|
+
phase: 'asset',
|
|
231
|
+
profileId: profile.profileId,
|
|
232
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
if (compilerAsset.bytes[0] !== 0x1f || compilerAsset.bytes[1] !== 0x8b) {
|
|
236
|
+
throw new AssetIntegrityError('ReScript runtime compiler storage asset is not gzip data', {
|
|
237
|
+
profileId: profile.profileId,
|
|
238
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
const compressedBody = new Response(Uint8Array.from(compilerAsset.bytes)).body;
|
|
242
|
+
if (!compressedBody) {
|
|
243
|
+
throw new UnsupportedBrowserFeatureError('ReadableStream response bodies', {
|
|
244
|
+
phase: 'asset',
|
|
245
|
+
profileId: profile.profileId,
|
|
246
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const stream = compressedBody.pipeThrough(new DecompressionStream('gzip'));
|
|
250
|
+
const reader = stream.getReader();
|
|
251
|
+
const compilerBytes = new Uint8Array(compilerReceipt.uncompressedBytes);
|
|
252
|
+
let offset = 0;
|
|
253
|
+
const cancelDecompression = () => {
|
|
254
|
+
try {
|
|
255
|
+
void reader.cancel(controller.signal.reason).catch(() => undefined);
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// Preserve the cancellation or integrity failure that stopped decompression.
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
controller.signal.addEventListener('abort', cancelDecompression, { once: true });
|
|
262
|
+
try {
|
|
263
|
+
for (;;) {
|
|
264
|
+
if (controller.signal.aborted)
|
|
265
|
+
throw controller.signal.reason;
|
|
266
|
+
const { done, value } = await reader.read();
|
|
267
|
+
if (done)
|
|
268
|
+
break;
|
|
269
|
+
if (offset + value.byteLength > compilerBytes.byteLength) {
|
|
270
|
+
const error = new AssetIntegrityError('ReScript compiler gzip output exceeds its logical receipt', {
|
|
271
|
+
profileId: profile.profileId,
|
|
272
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
273
|
+
});
|
|
274
|
+
try {
|
|
275
|
+
await reader.cancel(error);
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// Preserve the expansion-limit failure.
|
|
279
|
+
}
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
compilerBytes.set(value, offset);
|
|
283
|
+
offset += value.byteLength;
|
|
284
|
+
request.reportDecompressionProgress?.(offset, compilerBytes.byteLength);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
if (controller.signal.aborted || isWasmIdleError(error))
|
|
289
|
+
throw error;
|
|
290
|
+
throw new AssetIntegrityError('ReScript runtime compiler gzip decompression failed', {
|
|
291
|
+
cause: error,
|
|
292
|
+
profileId: profile.profileId,
|
|
293
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
controller.signal.removeEventListener('abort', cancelDecompression);
|
|
298
|
+
try {
|
|
299
|
+
reader.releaseLock();
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Cancellation may already have detached the stream reader.
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (offset !== compilerBytes.byteLength) {
|
|
306
|
+
throw new AssetIntegrityError('ReScript compiler gzip output is shorter than its logical receipt', {
|
|
307
|
+
profileId: profile.profileId,
|
|
308
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
const logicalIntegrity = verifyRuntimeAssetIntegrity({
|
|
312
|
+
asset: 'compiler.js',
|
|
313
|
+
bytes: compilerBytes,
|
|
314
|
+
expected: compilerReceipt,
|
|
315
|
+
stage: 'uncompressed',
|
|
316
|
+
mimeType: 'text/javascript',
|
|
317
|
+
profileId: profile.profileId,
|
|
318
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
319
|
+
});
|
|
320
|
+
await new Promise((resolve, reject) => {
|
|
321
|
+
let settled = false;
|
|
322
|
+
const rejectOnAbort = () => {
|
|
323
|
+
if (settled)
|
|
324
|
+
return;
|
|
325
|
+
settled = true;
|
|
326
|
+
controller.signal.removeEventListener('abort', rejectOnAbort);
|
|
327
|
+
reject(controller.signal.reason ??
|
|
328
|
+
new DOMException('ReScript runtime integrity verification aborted', 'AbortError'));
|
|
329
|
+
};
|
|
330
|
+
controller.signal.addEventListener('abort', rejectOnAbort, { once: true });
|
|
331
|
+
void logicalIntegrity.then(() => {
|
|
332
|
+
if (settled)
|
|
333
|
+
return;
|
|
334
|
+
settled = true;
|
|
335
|
+
controller.signal.removeEventListener('abort', rejectOnAbort);
|
|
336
|
+
resolve();
|
|
337
|
+
}, (error) => {
|
|
338
|
+
if (settled)
|
|
339
|
+
return;
|
|
340
|
+
settled = true;
|
|
341
|
+
controller.signal.removeEventListener('abort', rejectOnAbort);
|
|
342
|
+
reject(error);
|
|
343
|
+
});
|
|
344
|
+
if (controller.signal.aborted)
|
|
345
|
+
rejectOnAbort();
|
|
346
|
+
});
|
|
347
|
+
return Object.freeze({
|
|
348
|
+
protocol: RESCRIPT_PREFLIGHT_PROTOCOL,
|
|
349
|
+
protocolVersion: RESCRIPT_PREFLIGHT_PROTOCOL_VERSION,
|
|
350
|
+
profileId: profile.profileId,
|
|
351
|
+
sourceRevision: profile.sourceRevision,
|
|
352
|
+
manifestFingerprint: profile.manifestFingerprint,
|
|
353
|
+
manifestBytes: Uint8Array.from(manifestAsset.bytes),
|
|
354
|
+
compilerBytes
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
if (timedOut) {
|
|
359
|
+
throw new TimeoutError(`ReScript runtime preflight timed out after ${limits.assetTimeoutMs} ms`, {
|
|
360
|
+
cause: error,
|
|
361
|
+
phase: 'asset',
|
|
362
|
+
profileId: profile.profileId,
|
|
363
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID,
|
|
364
|
+
timeoutMs: limits.assetTimeoutMs
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (request.signal?.aborted) {
|
|
368
|
+
throw new CancelledError('ReScript runtime preflight cancelled', {
|
|
369
|
+
cause: request.signal.reason,
|
|
370
|
+
phase: 'asset',
|
|
371
|
+
profileId: profile.profileId,
|
|
372
|
+
runtimeId: RESCRIPT_PREFLIGHT_RUNTIME_ID
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
clearTimeout(timeout);
|
|
379
|
+
request.signal?.removeEventListener('abort', abortFromCaller);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const STATIC_RUNTIME_MODULE_VERSION = "
|
|
1
|
+
export declare const STATIC_RUNTIME_MODULE_VERSION = "be977a78d3a13730";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by scripts/build-static-runtime-modules.mjs.
|
|
2
|
-
export const STATIC_RUNTIME_MODULE_VERSION = '
|
|
2
|
+
export const STATIC_RUNTIME_MODULE_VERSION = 'be977a78d3a13730';
|
|
@@ -2,7 +2,8 @@ import type { BqnRuntimePreflightPayload } from './bqnPreflight';
|
|
|
2
2
|
import type { ClojureScriptRuntimePreflightPayload } from './clojurescriptPreflight';
|
|
3
3
|
import type { ForthRuntimePreflightPayload } from './forthPreflight';
|
|
4
4
|
import type { JRuntimePreflightPayload } from './jPreflight';
|
|
5
|
+
import type { ReScriptRuntimePreflightPayload } from './rescriptPreflight';
|
|
5
6
|
import type { StaticRuntimePreflightProgress, StaticRuntimePreflightRequestMessage } from './staticRuntimePreflightProtocol';
|
|
6
7
|
import { type JanetRuntimePreflightPayload, type PrologRuntimePreflightPayload } from '@wasm-idle/core';
|
|
7
|
-
export type StaticRuntimePreflightPayload = BqnRuntimePreflightPayload | ClojureScriptRuntimePreflightPayload | ForthRuntimePreflightPayload | JRuntimePreflightPayload | JanetRuntimePreflightPayload | PrologRuntimePreflightPayload;
|
|
8
|
+
export type StaticRuntimePreflightPayload = BqnRuntimePreflightPayload | ClojureScriptRuntimePreflightPayload | ForthRuntimePreflightPayload | JRuntimePreflightPayload | JanetRuntimePreflightPayload | PrologRuntimePreflightPayload | ReScriptRuntimePreflightPayload;
|
|
8
9
|
export declare function executeStaticRuntimePreflight(request: StaticRuntimePreflightRequestMessage, reportProgress: (progress: StaticRuntimePreflightProgress) => void, signal?: AbortSignal): Promise<StaticRuntimePreflightPayload>;
|
|
@@ -2,6 +2,7 @@ import { preflightBqnRuntimeAssets } from './bqnPreflight';
|
|
|
2
2
|
import { preflightClojureScriptRuntimeAssets } from './clojurescriptPreflight';
|
|
3
3
|
import { preflightForthRuntimeAssets } from './forthPreflight';
|
|
4
4
|
import { preflightJRuntimeAssets } from './jPreflight';
|
|
5
|
+
import { preflightReScriptRuntimeAssets } from './rescriptPreflight';
|
|
5
6
|
import { preflightJanetRuntimeAssets, preflightPrologRuntimeAssets } from '@wasm-idle/core';
|
|
6
7
|
export async function executeStaticRuntimePreflight(request, reportProgress, signal) {
|
|
7
8
|
const shared = {
|
|
@@ -63,5 +64,13 @@ export async function executeStaticRuntimePreflight(request, reportProgress, sig
|
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
});
|
|
67
|
+
case 'RESCRIPT':
|
|
68
|
+
return await preflightReScriptRuntimeAssets({
|
|
69
|
+
...shared,
|
|
70
|
+
profile: request.profile,
|
|
71
|
+
reportDecompressionProgress(loadedBytes, totalBytes) {
|
|
72
|
+
reportProgress({ kind: 'decompression', loadedBytes, totalBytes });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
66
75
|
}
|
|
67
76
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ExecutionLimits, type RuntimeAssetCacheOptions, type RuntimeAssetPreflightProgress, type RuntimeErrorCode, type RuntimePhase, type RuntimeResourceKind } from '@wasm-idle/core';
|
|
2
2
|
export declare const STATIC_RUNTIME_PREFLIGHT_PROTOCOL_VERSION: 1;
|
|
3
|
-
export type StaticRuntimePreflightRuntimeId = 'BQN' | 'CLOJURESCRIPT' | 'FORTH' | 'J' | 'JANET' | 'PROLOG';
|
|
3
|
+
export type StaticRuntimePreflightRuntimeId = 'BQN' | 'CLOJURESCRIPT' | 'FORTH' | 'J' | 'JANET' | 'PROLOG' | 'RESCRIPT';
|
|
4
4
|
export type StaticRuntimePreflightProgress = {
|
|
5
5
|
readonly kind: 'asset';
|
|
6
6
|
readonly progress: RuntimeAssetPreflightProgress;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { WorkerAssetBridge } from './assetBridge';
|
|
2
|
+
import { type PlaygroundRuntimeAssets } from './assets';
|
|
3
|
+
import type { SandboxExecutionOptions } from './options';
|
|
4
|
+
import type { Sandbox, SandboxProgress } from './sandbox';
|
|
5
|
+
declare class VLang implements Sandbox {
|
|
6
|
+
language: string;
|
|
7
|
+
output?: (data: string) => void;
|
|
8
|
+
worker?: Worker;
|
|
9
|
+
buffer: import("./sharedBuffer").WasmIdleSharedBuffer;
|
|
10
|
+
pendingInput: string[];
|
|
11
|
+
begin: number;
|
|
12
|
+
elapse: number;
|
|
13
|
+
uid: number;
|
|
14
|
+
log: boolean;
|
|
15
|
+
waitingForInput: boolean;
|
|
16
|
+
pendingEof: boolean;
|
|
17
|
+
exit: boolean;
|
|
18
|
+
assetBridge: WorkerAssetBridge | null;
|
|
19
|
+
activeVBaseUrl: string;
|
|
20
|
+
private activeOperation;
|
|
21
|
+
private disposed;
|
|
22
|
+
private disposePromise;
|
|
23
|
+
private readonly disposeCancellation;
|
|
24
|
+
private readonly workerSession;
|
|
25
|
+
private beginOperation;
|
|
26
|
+
private isOperationActive;
|
|
27
|
+
private releaseOperation;
|
|
28
|
+
private cleanupOperation;
|
|
29
|
+
private releaseBeforeSession;
|
|
30
|
+
private bindPreSessionAbort;
|
|
31
|
+
private bindAbortSignal;
|
|
32
|
+
private bindOperationTimeout;
|
|
33
|
+
private resetExplicitStdinState;
|
|
34
|
+
private finishExplicitStdin;
|
|
35
|
+
load(runtimeAssets?: string | PlaygroundRuntimeAssets, code?: string, log?: boolean, args?: string[], options?: SandboxExecutionOptions, progress?: SandboxProgress): Promise<void>;
|
|
36
|
+
write(input: string): void;
|
|
37
|
+
eof(): void;
|
|
38
|
+
private flushPendingInput;
|
|
39
|
+
run(code: string, prepare: boolean, log?: boolean, prog?: SandboxProgress, args?: string[], options?: SandboxExecutionOptions): Promise<boolean | string>;
|
|
40
|
+
private cancelOperation;
|
|
41
|
+
kill(): void;
|
|
42
|
+
terminate(reason?: unknown): void;
|
|
43
|
+
clear(): Promise<void>;
|
|
44
|
+
dispose(): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
export default VLang;
|