@immediately-run/sandpack-client 2.19.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +26 -0
  2. package/dist/.ir-build-stamp.json +6 -0
  3. package/dist/base-DBh7xJX9.mjs +48 -0
  4. package/dist/base-DelKLlDk.js +50 -0
  5. package/dist/clients/base.d.ts +34 -0
  6. package/dist/clients/event-emitter.d.ts +10 -0
  7. package/dist/clients/iframe-factory.d.ts +27 -0
  8. package/dist/clients/index.d.ts +4 -0
  9. package/dist/clients/node/client.utils.d.ts +7 -0
  10. package/dist/clients/node/iframe.utils.d.ts +3 -0
  11. package/dist/clients/node/index.d.ts +49 -0
  12. package/dist/clients/node/index.js +631 -0
  13. package/dist/clients/node/index.mjs +629 -0
  14. package/dist/clients/node/inject-scripts/historyListener.d.ts +5 -0
  15. package/dist/clients/node/inject-scripts/index.d.ts +1 -0
  16. package/dist/clients/node/inject-scripts/resize.d.ts +5 -0
  17. package/dist/clients/node/taskManager.d.ts +20 -0
  18. package/dist/clients/node/types.d.ts +63 -0
  19. package/dist/clients/runtime/file-resolver-protocol.d.ts +17 -0
  20. package/dist/clients/runtime/iframe-protocol.d.ts +17 -0
  21. package/dist/clients/runtime/immutable-fetch-protocol.d.ts +39 -0
  22. package/dist/clients/runtime/index.d.ts +76 -0
  23. package/dist/clients/runtime/index.js +1046 -0
  24. package/dist/clients/runtime/index.mjs +1044 -0
  25. package/dist/clients/runtime/mime.d.ts +1 -0
  26. package/dist/clients/runtime/types.d.ts +129 -0
  27. package/dist/clients/runtime/utils.d.ts +8 -0
  28. package/dist/clients/static/index.d.ts +25 -0
  29. package/dist/clients/static/utils.d.ts +5 -0
  30. package/dist/consoleHook-DQVWjDRE.mjs +230 -0
  31. package/dist/consoleHook-znXctRzh.js +236 -0
  32. package/dist/fs/SandpackFS.d.ts +116 -0
  33. package/dist/iframe-factory-BcC-S_XQ.js +54 -0
  34. package/dist/iframe-factory-DybmkzJZ.mjs +51 -0
  35. package/dist/index--fILWAw8.js +210 -0
  36. package/dist/index-rbhm_KmF.mjs +208 -0
  37. package/dist/index.d.ts +4 -0
  38. package/dist/index.js +53 -0
  39. package/dist/index.mjs +40 -0
  40. package/dist/inject-scripts/consoleHook.d.ts +6 -0
  41. package/dist/types-BFONOA2L.mjs +531 -0
  42. package/dist/types-BIIEoWr6.js +534 -0
  43. package/dist/types.d.ts +348 -0
  44. package/dist/utils-BiVyytui.js +262 -0
  45. package/dist/utils-DG1HA4RZ.mjs +250 -0
  46. package/dist/utils.d.ts +18 -0
  47. package/dist/utils.js +13 -0
  48. package/dist/utils.mjs +2 -0
  49. package/package.json +82 -0
@@ -0,0 +1,1044 @@
1
+ import { _ as __awaiter, a as __generator, h as __assign, i as __rest, j as __spreadArray, g as __extends, f as nullthrows, e as extractErrorDetails, c as createError, d as createPackageJSON } from '../../utils-DG1HA4RZ.mjs';
2
+ import { dequal } from 'dequal';
3
+ import { a as SandpackLogLevel } from '../../types-BFONOA2L.mjs';
4
+ import { S as SandpackClient } from '../../base-DBh7xJX9.mjs';
5
+ import { c as createSandboxedIframe, e as ensureSandboxed } from '../../iframe-factory-DybmkzJZ.mjs';
6
+ import mimeDB from 'mime-db';
7
+ import 'outvariant';
8
+ import '@zenfs/core';
9
+
10
+ /**
11
+ * This file is a copy of the resolver from the `codesandbox-api` package.
12
+ * We wanted to avoid to reference codesandbox-api because of the code that runs on load in the package.
13
+ * The plan is to take some time and refactor codesandbox-api into what it was supposed to be in the first place,
14
+ * an abstraction over the actions that can be dispatched between the bundler and the iframe.
15
+ */
16
+ var Protocol = /** @class */ (function () {
17
+ function Protocol(type, handleMessage, protocol) {
18
+ var _this = this;
19
+ this.type = type;
20
+ this.handleMessage = handleMessage;
21
+ this.protocol = protocol;
22
+ this._disposeMessageListener = this.protocol.channelListen(function (msg) { return __awaiter(_this, void 0, void 0, function () {
23
+ var message, result, response, err_1, response;
24
+ return __generator(this, function (_a) {
25
+ switch (_a.label) {
26
+ case 0:
27
+ if (!(msg.type === this.getTypeId() && msg.method)) return [3 /*break*/, 4];
28
+ message = msg;
29
+ _a.label = 1;
30
+ case 1:
31
+ _a.trys.push([1, 3, , 4]);
32
+ return [4 /*yield*/, this.handleMessage(message)];
33
+ case 2:
34
+ result = _a.sent();
35
+ response = {
36
+ type: this.getTypeId(),
37
+ msgId: message.msgId,
38
+ result: result,
39
+ };
40
+ this.protocol.dispatch(response);
41
+ return [3 /*break*/, 4];
42
+ case 3:
43
+ err_1 = _a.sent();
44
+ response = {
45
+ type: this.getTypeId(),
46
+ msgId: message.msgId,
47
+ error: {
48
+ message: err_1.message,
49
+ },
50
+ };
51
+ this.protocol.dispatch(response);
52
+ return [3 /*break*/, 4];
53
+ case 4: return [2 /*return*/];
54
+ }
55
+ });
56
+ }); });
57
+ }
58
+ Protocol.prototype.getTypeId = function () {
59
+ return "protocol-".concat(this.type);
60
+ };
61
+ Protocol.prototype.dispose = function () {
62
+ this._disposeMessageListener();
63
+ };
64
+ return Protocol;
65
+ }());
66
+
67
+ var IFrameProtocol = /** @class */ (function () {
68
+ function IFrameProtocol(iframe, origin) {
69
+ // React to messages from any iframe
70
+ this.globalListeners = {};
71
+ this.globalListenersCount = 0;
72
+ // React to messages from the iframe owned by this instance
73
+ this.channelListeners = {};
74
+ this.channelListenersCount = 0;
75
+ // Random number to identify this instance of the client when messages are coming from multiple iframes
76
+ this.channelId = Math.floor(Math.random() * 1000000);
77
+ this.frameWindow = iframe.contentWindow;
78
+ this.origin = '*'; //origin;
79
+ this.globalListeners = [];
80
+ this.channelListeners = [];
81
+ this.eventListener = this.eventListener.bind(this);
82
+ if (typeof window !== "undefined") {
83
+ window.addEventListener("message", this.eventListener);
84
+ }
85
+ }
86
+ IFrameProtocol.prototype.cleanup = function () {
87
+ window.removeEventListener("message", this.eventListener);
88
+ this.globalListeners = {};
89
+ this.channelListeners = {};
90
+ this.globalListenersCount = 0;
91
+ this.channelListenersCount = 0;
92
+ };
93
+ // Sends the channelId and triggers an iframeHandshake promise to resolve,
94
+ // so the iframe can start listening for messages (based on the id).
95
+ // `config` carries the bundler's bootstrap configuration (template/logLevel/
96
+ // recompileDelay) — the bundler watches the shared filesystem itself and no
97
+ // longer receives a `compile` message, so it needs this delivered once here.
98
+ IFrameProtocol.prototype.register = function (port, config, babelPort) {
99
+ if (!this.frameWindow) {
100
+ return;
101
+ }
102
+ console.log("[IFrameProtocol] Registering iframe with channelId", this.channelId, this);
103
+ // Order matters: the bundler reads ports[0] as the fs port and ports[1] as
104
+ // the Babel worker port. `filter` keeps that order as long as the fs port
105
+ // is always present (it is, in normal operation).
106
+ var ports = [port, babelPort].filter(function (p) { return p != null; });
107
+ this.frameWindow.postMessage(__assign({ type: "register-frame", origin: document.location.origin, id: this.channelId }, config), this.origin, ports);
108
+ };
109
+ // Messages are dispatched from the client directly to the instance iframe
110
+ IFrameProtocol.prototype.dispatch = function (message) {
111
+ if (!this.frameWindow) {
112
+ return;
113
+ }
114
+ // `_transfer` (e.g. a MessagePort for a mount's filesystem) must be passed
115
+ // as the postMessage transfer list, not as a serialized payload field.
116
+ var _transfer = message._transfer, payload = __rest(message, ["_transfer"]);
117
+ this.frameWindow.postMessage(__assign({ $id: this.channelId, codesandbox: true }, payload), this.origin, _transfer !== null && _transfer !== void 0 ? _transfer : []);
118
+ };
119
+ // Add a listener that is called on any message coming from an iframe in the page
120
+ // This is needed for the `initialize` message which comes without a channelId
121
+ IFrameProtocol.prototype.globalListen = function (listener) {
122
+ var _this = this;
123
+ if (typeof listener !== "function") {
124
+ return function () {
125
+ return;
126
+ };
127
+ }
128
+ var listenerId = this.globalListenersCount;
129
+ this.globalListeners[listenerId] = listener;
130
+ this.globalListenersCount++;
131
+ return function () {
132
+ delete _this.globalListeners[listenerId];
133
+ };
134
+ };
135
+ // Add a listener that is called on any message coming from an iframe with the instance channelId
136
+ // All other messages (eg: from other iframes) are ignored
137
+ IFrameProtocol.prototype.channelListen = function (listener) {
138
+ var _this = this;
139
+ if (typeof listener !== "function") {
140
+ return function () {
141
+ return;
142
+ };
143
+ }
144
+ var listenerId = this.channelListenersCount;
145
+ this.channelListeners[listenerId] = listener;
146
+ this.channelListenersCount++;
147
+ return function () {
148
+ delete _this.channelListeners[listenerId];
149
+ };
150
+ };
151
+ // Handles message windows coming from iframes
152
+ IFrameProtocol.prototype.eventListener = function (evt) {
153
+ // skip events originating from different iframes
154
+ if (evt.source !== this.frameWindow) {
155
+ return;
156
+ }
157
+ var message = evt.data;
158
+ if (!message.codesandbox) {
159
+ return;
160
+ }
161
+ Object.values(this.globalListeners).forEach(function (listener) {
162
+ return listener(message);
163
+ });
164
+ if (message.$id !== this.channelId) {
165
+ return;
166
+ }
167
+ Object.values(this.channelListeners).forEach(function (listener) {
168
+ return listener(message);
169
+ });
170
+ };
171
+ return IFrameProtocol;
172
+ }());
173
+
174
+ /**
175
+ * Parent-side fetch + cache for immutable, exact-versioned module URLs.
176
+ *
177
+ * The bundler iframe runs at an opaque origin (sandboxed without
178
+ * `allow-same-origin`), so it has no persistent storage of any kind — its own
179
+ * Cache API is unavailable. It therefore forwards immutable-URL fetches here
180
+ * over the iframe protocol (`protocol-immutable-fetch`), and the parent — a
181
+ * real origin — serves them cache-first from a persistent Cache API cache.
182
+ *
183
+ * Security: the handler only fetches URLs matching {@link IMMUTABLE_URL_ALLOWLIST}.
184
+ * The iframe runs untrusted code, and an unrestricted parent-side fetch proxy
185
+ * would let it read arbitrary cross-origin responses with the parent's network
186
+ * context (a CORS bypass). The allowlist mirrors the prefixes the bundler
187
+ * registers via `registerImmutableUrlPrefix` (see sandpack-bundler
188
+ * `src/utils/fetch.ts`) — keep the two in sync.
189
+ */
190
+ /**
191
+ * URL prefixes whose responses never change for a given URL (the URL encodes
192
+ * the exact content version). Only these may be fetched on the iframe's
193
+ * behalf, and they are safe to cache forever.
194
+ */
195
+ var IMMUTABLE_URL_ALLOWLIST = [
196
+ // Module CDN, exact-versioned package bundles. (NOT /dep_tree/, which
197
+ // resolves semver ranges and changes as new versions publish.)
198
+ "https://sandpack-cdn-staging.blazingly.io/package/",
199
+ // unpkg files, requested by the bundler at registry-resolved exact versions.
200
+ "https://unpkg.com/",
201
+ // Self-hosted, versioned @immediately-run/sdk builds (SDK_PACKAGING_SPEC
202
+ // §5/§11, Option A). The /v/<version>/ path encodes the exact version, so
203
+ // responses are immutable; the bundler fetches these when an app opts the SDK
204
+ // into immediately.run.resolveFromRegistry. Keep in sync with the prefix the
205
+ // bundler registers via registerImmutableUrlPrefix (sandbox bundler.ts).
206
+ "https://immediately-run.github.io/immediately-run-sdk/v/",
207
+ ];
208
+ var IMMUTABLE_CACHE_NAME = "sandpack-immutable-fetch-v1";
209
+ var serializeResponse = function (res) { return __awaiter(void 0, void 0, void 0, function () {
210
+ var _a;
211
+ var _b;
212
+ return __generator(this, function (_c) {
213
+ switch (_c.label) {
214
+ case 0:
215
+ _a = {
216
+ status: res.status,
217
+ contentType: (_b = res.headers.get("content-type")) !== null && _b !== void 0 ? _b : ""
218
+ };
219
+ return [4 /*yield*/, res.arrayBuffer()];
220
+ case 1: return [2 /*return*/, (_a.body = _c.sent(),
221
+ _a)];
222
+ }
223
+ });
224
+ }); };
225
+ // CacheStorage may be unavailable (insecure context) or fail (storage
226
+ // pressure); degrade to a plain fetch rather than failing the request.
227
+ var openCache = function () { return __awaiter(void 0, void 0, void 0, function () {
228
+ return __generator(this, function (_b) {
229
+ switch (_b.label) {
230
+ case 0:
231
+ _b.trys.push([0, 2, , 3]);
232
+ return [4 /*yield*/, caches.open(IMMUTABLE_CACHE_NAME)];
233
+ case 1: return [2 /*return*/, _b.sent()];
234
+ case 2:
235
+ _b.sent();
236
+ return [2 /*return*/, undefined];
237
+ case 3: return [2 /*return*/];
238
+ }
239
+ });
240
+ }); };
241
+ /** SHA-384 of bytes, formatted `sha384-<base64>` (SRI style). */
242
+ var sha384 = function (body) { return __awaiter(void 0, void 0, void 0, function () {
243
+ var digest, bin, view, i;
244
+ return __generator(this, function (_a) {
245
+ switch (_a.label) {
246
+ case 0: return [4 /*yield*/, crypto.subtle.digest("SHA-384", body)];
247
+ case 1:
248
+ digest = _a.sent();
249
+ bin = "";
250
+ view = new Uint8Array(digest);
251
+ for (i = 0; i < view.length; i++)
252
+ bin += String.fromCharCode(view[i]);
253
+ return [2 /*return*/, "sha384-".concat(btoa(bin))];
254
+ }
255
+ });
256
+ }); };
257
+ /**
258
+ * Does `body` match the caller-supplied `integrity` (an `sha384-<base64>` SRI
259
+ * hash)? Returns true when no integrity was supplied (nothing to check).
260
+ */
261
+ var matchesIntegrity = function (body, integrity) { return __awaiter(void 0, void 0, void 0, function () {
262
+ return __generator(this, function (_b) {
263
+ switch (_b.label) {
264
+ case 0:
265
+ if (!integrity)
266
+ return [2 /*return*/, true];
267
+ _b.label = 1;
268
+ case 1:
269
+ _b.trys.push([1, 3, , 4]);
270
+ return [4 /*yield*/, sha384(body)];
271
+ case 2: return [2 /*return*/, (_b.sent()) === integrity];
272
+ case 3:
273
+ _b.sent();
274
+ // crypto unavailable → can't verify; treat as a non-match so we neither
275
+ // serve nor persist bytes we couldn't validate (fail safe).
276
+ return [2 /*return*/, false];
277
+ case 4: return [2 /*return*/];
278
+ }
279
+ });
280
+ }); };
281
+ /**
282
+ * `protocol-immutable-fetch` handler: serve an allowlisted immutable URL,
283
+ * cache-first from the persistent parent-side cache.
284
+ *
285
+ * INTEGRITY-AWARE CACHING (cache-poisoning prevention). When the caller passes
286
+ * the expected SHA-384 (`integrity`), the cache is never allowed to serve or
287
+ * persist bytes that don't match it:
288
+ * - verify-on-read: a cache HIT whose bytes no longer match the expected hash
289
+ * (the host re-pinned the version under the cached bytes) is EVICTED and the
290
+ * URL refetched, so a stale/poisoned entry self-heals instead of failing the
291
+ * consumer forever.
292
+ * - verify-before-cache: freshly fetched bytes are only stored when they match.
293
+ * Mismatched bytes are returned (so the consumer's own check fails closed with
294
+ * a clear error) but NEVER cached, so a bad upstream window can't poison the
295
+ * cache. Without an `integrity` argument the URL is cached by URL as before.
296
+ */
297
+ function handleImmutableFetch(url, integrity) {
298
+ return __awaiter(this, void 0, void 0, function () {
299
+ var expected, cache, hit, body, res, result, _a;
300
+ return __generator(this, function (_b) {
301
+ switch (_b.label) {
302
+ case 0:
303
+ if (typeof url !== "string" ||
304
+ !IMMUTABLE_URL_ALLOWLIST.some(function (prefix) { return url.startsWith(prefix); })) {
305
+ throw new Error("URL not allowed for immutable fetch: ".concat(String(url)));
306
+ }
307
+ expected = typeof integrity === "string" ? integrity : undefined;
308
+ return [4 /*yield*/, openCache()];
309
+ case 1:
310
+ cache = _b.sent();
311
+ if (!cache) return [3 /*break*/, 6];
312
+ return [4 /*yield*/, cache.match(url).catch(function () { return undefined; })];
313
+ case 2:
314
+ hit = _b.sent();
315
+ if (!hit) return [3 /*break*/, 6];
316
+ return [4 /*yield*/, hit.clone().arrayBuffer()];
317
+ case 3:
318
+ body = _b.sent();
319
+ return [4 /*yield*/, matchesIntegrity(body, expected)];
320
+ case 4:
321
+ if (_b.sent()) {
322
+ return [2 /*return*/, serializeResponse(hit)];
323
+ }
324
+ // Stale/poisoned entry: drop it and fall through to a fresh fetch.
325
+ return [4 /*yield*/, cache.delete(url).catch(function () { })];
326
+ case 5:
327
+ // Stale/poisoned entry: drop it and fall through to a fresh fetch.
328
+ _b.sent();
329
+ _b.label = 6;
330
+ case 6: return [4 /*yield*/, fetch(url)];
331
+ case 7:
332
+ res = _b.sent();
333
+ if (!res.ok) {
334
+ throw new Error("Immutable fetch failed with status ".concat(res.status, ": ").concat(url));
335
+ }
336
+ return [4 /*yield*/, serializeResponse(res)];
337
+ case 8:
338
+ result = _b.sent();
339
+ _a = cache;
340
+ if (!_a) return [3 /*break*/, 10];
341
+ return [4 /*yield*/, matchesIntegrity(result.body, expected)];
342
+ case 9:
343
+ _a = (_b.sent());
344
+ _b.label = 10;
345
+ case 10:
346
+ if (!_a) return [3 /*break*/, 12];
347
+ // Only persist verified bytes. A failed put (quota) only costs the entry.
348
+ return [4 /*yield*/, cache
349
+ .put(url, new Response(result.body.slice(0), { status: result.status, headers: { "content-type": result.contentType } }))
350
+ .catch(function () { })];
351
+ case 11:
352
+ // Only persist verified bytes. A failed put (quota) only costs the entry.
353
+ _b.sent();
354
+ _b.label = 12;
355
+ case 12: return [2 /*return*/, result];
356
+ }
357
+ });
358
+ });
359
+ }
360
+
361
+ var extensionMap = new Map();
362
+ var entries = Object.entries(mimeDB);
363
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
364
+ var _a$1 = entries_1[_i], mimetype = _a$1[0], entry = _a$1[1];
365
+ // eslint-disable-next-line
366
+ // @ts-ignore
367
+ if (!entry.extensions) {
368
+ continue;
369
+ }
370
+ // eslint-disable-next-line
371
+ // @ts-ignore
372
+ var extensions = entry.extensions;
373
+ if (extensions.length) {
374
+ for (var _b = 0, extensions_1 = extensions; _b < extensions_1.length; _b++) {
375
+ var ext = extensions_1[_b];
376
+ extensionMap.set(ext, mimetype);
377
+ }
378
+ }
379
+ }
380
+ var EXTENSIONS_MAP = extensionMap;
381
+
382
+ var CHANNEL_NAME = "$CSB_RELAY";
383
+
384
+ var MAX_CLIENT_DEPENDENCY_COUNT = 50;
385
+ function getTemplate(pkg,
386
+ /* eslint-disable @typescript-eslint/no-explicit-any */
387
+ modules) {
388
+ if (!pkg) {
389
+ return "static";
390
+ }
391
+ var _a = pkg.dependencies, dependencies = _a === void 0 ? {} : _a, _b = pkg.devDependencies, devDependencies = _b === void 0 ? {} : _b;
392
+ var totalDependencies = __spreadArray(__spreadArray([], Object.keys(dependencies), true), Object.keys(devDependencies), true);
393
+ var moduleNames = Object.keys(modules);
394
+ var adonis = ["@adonisjs/framework", "@adonisjs/core"];
395
+ if (totalDependencies.some(function (dep) { return adonis.indexOf(dep) > -1; })) {
396
+ return "adonis";
397
+ }
398
+ var nuxt = ["nuxt", "nuxt-edge", "nuxt-ts", "nuxt-ts-edge", "nuxt3"];
399
+ if (totalDependencies.some(function (dep) { return nuxt.indexOf(dep) > -1; })) {
400
+ return "nuxt";
401
+ }
402
+ if (totalDependencies.indexOf("next") > -1) {
403
+ return "next";
404
+ }
405
+ var apollo = [
406
+ "apollo-server",
407
+ "apollo-server-express",
408
+ "apollo-server-hapi",
409
+ "apollo-server-koa",
410
+ "apollo-server-lambda",
411
+ "apollo-server-micro",
412
+ ];
413
+ if (totalDependencies.some(function (dep) { return apollo.indexOf(dep) > -1; })) {
414
+ return "apollo";
415
+ }
416
+ if (totalDependencies.indexOf("mdx-deck") > -1) {
417
+ return "mdx-deck";
418
+ }
419
+ if (totalDependencies.indexOf("gridsome") > -1) {
420
+ return "gridsome";
421
+ }
422
+ if (totalDependencies.indexOf("vuepress") > -1) {
423
+ return "vuepress";
424
+ }
425
+ if (totalDependencies.indexOf("ember-cli") > -1) {
426
+ return "ember";
427
+ }
428
+ if (totalDependencies.indexOf("sapper") > -1) {
429
+ return "sapper";
430
+ }
431
+ if (totalDependencies.indexOf("gatsby") > -1) {
432
+ return "gatsby";
433
+ }
434
+ if (totalDependencies.indexOf("quasar") > -1) {
435
+ return "quasar";
436
+ }
437
+ if (totalDependencies.indexOf("@docusaurus/core") > -1) {
438
+ return "docusaurus";
439
+ }
440
+ if (totalDependencies.indexOf("remix") > -1) {
441
+ return "remix";
442
+ }
443
+ if (totalDependencies.indexOf("astro") > -1) {
444
+ return "node";
445
+ }
446
+ // CLIENT
447
+ if (moduleNames.some(function (m) { return m.endsWith(".re"); })) {
448
+ return "reason";
449
+ }
450
+ var parcel = ["parcel-bundler", "parcel"];
451
+ if (totalDependencies.some(function (dep) { return parcel.indexOf(dep) > -1; })) {
452
+ return "parcel";
453
+ }
454
+ var dojo = ["@dojo/core", "@dojo/framework"];
455
+ if (totalDependencies.some(function (dep) { return dojo.indexOf(dep) > -1; })) {
456
+ return "@dojo/cli-create-app";
457
+ }
458
+ if (totalDependencies.indexOf("@nestjs/core") > -1 ||
459
+ totalDependencies.indexOf("@nestjs/common") > -1) {
460
+ return "nest";
461
+ }
462
+ if (totalDependencies.indexOf("react-styleguidist") > -1) {
463
+ return "styleguidist";
464
+ }
465
+ if (totalDependencies.indexOf("react-scripts") > -1) {
466
+ return "create-react-app";
467
+ }
468
+ if (totalDependencies.indexOf("react-scripts-ts") > -1) {
469
+ return "create-react-app-typescript";
470
+ }
471
+ if (totalDependencies.indexOf("@angular/core") > -1) {
472
+ return "angular-cli";
473
+ }
474
+ if (totalDependencies.indexOf("preact-cli") > -1) {
475
+ return "preact-cli";
476
+ }
477
+ if (totalDependencies.indexOf("@sveltech/routify") > -1 ||
478
+ totalDependencies.indexOf("@roxi/routify") > -1) {
479
+ return "node";
480
+ }
481
+ if (totalDependencies.indexOf("vite") > -1) {
482
+ return "node";
483
+ }
484
+ if (totalDependencies.indexOf("@frontity/core") > -1) {
485
+ return "node";
486
+ }
487
+ if (totalDependencies.indexOf("svelte") > -1) {
488
+ return "svelte";
489
+ }
490
+ if (totalDependencies.indexOf("vue") > -1) {
491
+ return "vue-cli";
492
+ }
493
+ if (totalDependencies.indexOf("cx") > -1) {
494
+ return "cxjs";
495
+ }
496
+ var nodeDeps = [
497
+ "express",
498
+ "koa",
499
+ "nodemon",
500
+ "ts-node",
501
+ "@tensorflow/tfjs-node",
502
+ "webpack-dev-server",
503
+ "snowpack",
504
+ ];
505
+ if (totalDependencies.some(function (dep) { return nodeDeps.indexOf(dep) > -1; })) {
506
+ return "node";
507
+ }
508
+ if (Object.keys(dependencies).length >= MAX_CLIENT_DEPENDENCY_COUNT) {
509
+ // The dependencies are too much for client sandboxes to handle
510
+ return "node";
511
+ }
512
+ return undefined;
513
+ }
514
+ function getExtension(filepath) {
515
+ var parts = filepath.split(".");
516
+ if (parts.length <= 1) {
517
+ return "";
518
+ }
519
+ else {
520
+ var ext = parts[parts.length - 1];
521
+ return ext;
522
+ }
523
+ }
524
+
525
+ var _a;
526
+ var SUFFIX_PLACEHOLDER = "-{{suffix}}";
527
+ var BUNDLER_URL = "https://".concat((_a = "2.19.8") === null || _a === void 0 ? void 0 : _a.replace(/\./g, "-")).concat(SUFFIX_PLACEHOLDER, "-sandpack.codesandbox.io/");
528
+ var SandpackRuntime = /** @class */ (function (_super) {
529
+ __extends(SandpackRuntime, _super);
530
+ function SandpackRuntime(selector, sandboxSetup, options) {
531
+ if (options === void 0) { options = {}; }
532
+ var _this = _super.call(this, selector, sandboxSetup, options) || this;
533
+ /** Parent-owned Babel transpiler worker, connected to the iframe by port. */
534
+ _this.babelWorker = null;
535
+ _this.getTranspilerContext = function () {
536
+ return new Promise(function (resolve) {
537
+ var unsubscribe = _this.listen(function (message) {
538
+ if (message.type === "transpiler-context") {
539
+ resolve(message.data);
540
+ unsubscribe();
541
+ }
542
+ });
543
+ _this.dispatch({ type: "get-transpiler-context" });
544
+ });
545
+ };
546
+ _this.getTranspiledFiles = function () {
547
+ return new Promise(function (resolve) {
548
+ var unsubscribe = _this.listen(function (message) {
549
+ if (message.type === "all-modules") {
550
+ resolve(message.data);
551
+ unsubscribe();
552
+ }
553
+ });
554
+ _this.dispatch({ type: "get-modules" });
555
+ });
556
+ };
557
+ _this.bundlerURL = _this.createBundlerURL();
558
+ _this.bundlerState = undefined;
559
+ _this.errors = [];
560
+ _this.status = "initializing";
561
+ _this.fs = sandboxSetup.fs;
562
+ if (typeof selector === "string") {
563
+ _this.selector = selector;
564
+ var element = document.querySelector(selector);
565
+ nullthrows(element, "The element '".concat(selector, "' was not found"));
566
+ _this.element = element;
567
+ // Opaque-origin app iframe via the single factory (G1/T1). No
568
+ // `allow-same-origin`: the iframe runs untrusted code at an opaque origin
569
+ // so it can't read domain-scoped cookies, register service workers, or
570
+ // touch shared storage on the bundler origin. The Babel worker that used
571
+ // to require same-origin is now owned by the parent and reached over a
572
+ // transferred `MessagePort` (see `createBabelWorkerPort`).
573
+ _this.iframe = createSandboxedIframe();
574
+ _this.initializeElement();
575
+ }
576
+ else {
577
+ _this.element = selector;
578
+ _this.iframe = selector;
579
+ }
580
+ // Set-and-assert: a host-provided iframe is hardened here, and any iframe
581
+ // (created or passed) is verified to carry no `allow-same-origin`.
582
+ ensureSandboxed(_this.iframe);
583
+ _this.setLocationURLIntoIFrame();
584
+ _this.iframeProtocol = new IFrameProtocol(_this.iframe, _this.bundlerURL);
585
+ _this.unsubscribeGlobalListener = _this.iframeProtocol.globalListen(function (mes) {
586
+ if (mes.type !== "initialized" || !_this.iframe.contentWindow) {
587
+ return;
588
+ }
589
+ // this may not work with a boundedcontext, it may require an actual FS instance
590
+ var remotePortPromise = _this.fs.connectRemote();
591
+ remotePortPromise.then(function (remotePort) { return __awaiter(_this, void 0, void 0, function () {
592
+ var config, babelPort;
593
+ var _this = this;
594
+ return __generator(this, function (_a) {
595
+ switch (_a.label) {
596
+ case 0:
597
+ /**
598
+ * Lazy file resolution over the iframe protocol, backed by the
599
+ * {@link SandpackFS} passed on construction. Created before `register`
600
+ * so it's ready for the bundler's lazy file reads as soon as the
601
+ * bundler has the fs port.
602
+ */
603
+ this.fileResolverProtocol = new Protocol("fs", function (data) { return __awaiter(_this, void 0, void 0, function () {
604
+ return __generator(this, function (_a) {
605
+ if (data.method === "isFile") {
606
+ return [2 /*return*/, this.sandboxSetup.fs.exists(data.params[0])];
607
+ }
608
+ else if (data.method === "readFile") {
609
+ return [2 /*return*/, this.sandboxSetup.fs.readFile(data.params[0])];
610
+ }
611
+ else {
612
+ throw new Error("Method not supported");
613
+ }
614
+ });
615
+ }); }, this.iframeProtocol);
616
+ /**
617
+ * Parent-side fetch + persistent cache for immutable module URLs.
618
+ * The iframe's opaque origin has no storage, so it forwards these
619
+ * here (see immutable-fetch-protocol.ts for the allowlist).
620
+ */
621
+ this.immutableFetchProtocol = new Protocol("immutable-fetch", function (data) { return __awaiter(_this, void 0, void 0, function () {
622
+ return __generator(this, function (_a) {
623
+ if (data.method !== "fetch") {
624
+ throw new Error("Method not supported");
625
+ }
626
+ // params[1] is an optional `sha384-…` integrity the caller pins
627
+ // for this URL (SDK files); the cache verifies against it.
628
+ return [2 /*return*/, handleImmutableFetch(data.params[0], data.params[1])];
629
+ });
630
+ }); }, this.iframeProtocol);
631
+ return [4 /*yield*/, this.computeInitConfig()];
632
+ case 1:
633
+ config = _a.sent();
634
+ babelPort = this.createBabelWorkerPort();
635
+ this.iframeProtocol.register(remotePort, config, babelPort);
636
+ return [2 /*return*/];
637
+ }
638
+ });
639
+ }); });
640
+ });
641
+ _this.unsubscribeChannelListener = _this.iframeProtocol.channelListen(function (mes) {
642
+ switch (mes.type) {
643
+ case "start": {
644
+ _this.errors = [];
645
+ break;
646
+ }
647
+ case "status": {
648
+ _this.status = mes.status;
649
+ break;
650
+ }
651
+ case "action": {
652
+ if (mes.action === "show-error") {
653
+ _this.errors = __spreadArray(__spreadArray([], _this.errors, true), [extractErrorDetails(mes)], false);
654
+ }
655
+ break;
656
+ }
657
+ case "done": {
658
+ _this.status = "done";
659
+ break;
660
+ }
661
+ case "state": {
662
+ _this.bundlerState = mes.state;
663
+ break;
664
+ }
665
+ }
666
+ });
667
+ if (options.experimental_enableServiceWorker) {
668
+ _this.serviceWorkerHandshake();
669
+ }
670
+ return _this;
671
+ }
672
+ SandpackRuntime.prototype.createBundlerURL = function () {
673
+ var _a;
674
+ var bundlerURL = this.options.bundlerURL || BUNDLER_URL;
675
+ // if it's a custom, skip the rest
676
+ if (this.options.bundlerURL) {
677
+ return bundlerURL;
678
+ }
679
+ if (this.options.teamId) {
680
+ bundlerURL =
681
+ bundlerURL.replace("https://", "https://" + this.options.teamId + "-") +
682
+ "?cache=".concat(Date.now());
683
+ }
684
+ if (this.options.experimental_enableServiceWorker) {
685
+ var suffixes = [];
686
+ suffixes.push(Math.random().toString(36).slice(4));
687
+ bundlerURL = bundlerURL.replace(SUFFIX_PLACEHOLDER, "-".concat((_a = this.options.experimental_stableServiceWorkerId) !== null && _a !== void 0 ? _a : suffixes.join("-")));
688
+ }
689
+ else {
690
+ bundlerURL = bundlerURL.replace(SUFFIX_PLACEHOLDER, "");
691
+ }
692
+ return bundlerURL;
693
+ };
694
+ /**
695
+ * Creates (or recreates) the parent-owned Babel transpiler worker and returns
696
+ * the `MessagePort` to transfer into the iframe. The iframe can no longer run
697
+ * its own worker — without `allow-same-origin` it has an opaque origin, and a
698
+ * same-origin worker script won't load there — so transpilation happens in
699
+ * this worker on the parent's real origin. Per-transform traffic then flows
700
+ * iframe<->worker directly over the entangled ports; the parent doesn't relay.
701
+ */
702
+ SandpackRuntime.prototype.createBabelWorkerPort = function () {
703
+ var _a;
704
+ var workerURL = this.options.babelWorkerURL;
705
+ if (!workerURL) {
706
+ console.warn("[SandpackRuntime] No `babelWorkerURL` configured — the bundler cannot transpile without a Babel worker.");
707
+ return undefined;
708
+ }
709
+ // A reload re-runs this handshake; terminate the previous worker first so
710
+ // we don't leak one per reload.
711
+ (_a = this.babelWorker) === null || _a === void 0 ? void 0 : _a.terminate();
712
+ // Classic (not module) worker: the bundled worker lazily loads its Babel
713
+ // plugin/preset chunks via importScripts(), which a `{ type: "module" }`
714
+ // worker forbids. The worker artifact is built with outputFormat "globalThis"
715
+ // to match (see sandpack-bundler's babelWorker Parcel target).
716
+ var worker = new Worker(workerURL);
717
+ this.babelWorker = worker;
718
+ var channel = new MessageChannel();
719
+ // Hand the worker one end; it binds its message bus to this port on receipt.
720
+ worker.postMessage({ type: "connect" }, [channel.port1]);
721
+ return channel.port2;
722
+ };
723
+ SandpackRuntime.prototype.serviceWorkerHandshake = function () {
724
+ var _this = this;
725
+ var channel = new MessageChannel();
726
+ var iframeContentWindow = this.iframe.contentWindow;
727
+ if (!iframeContentWindow) {
728
+ throw new Error("Could not get iframe contentWindow");
729
+ }
730
+ var port = channel.port1;
731
+ port.onmessage = function (evt) {
732
+ if (typeof evt.data === "object" && evt.data.$channel === CHANNEL_NAME) {
733
+ switch (evt.data.$type) {
734
+ case "preview/ready":
735
+ // no op for now
736
+ break;
737
+ case "preview/request":
738
+ _this.handleWorkerRequest(evt.data, port);
739
+ break;
740
+ }
741
+ }
742
+ };
743
+ var sendMessage = function () {
744
+ var initMsg = {
745
+ $channel: CHANNEL_NAME,
746
+ $type: "preview/init",
747
+ };
748
+ iframeContentWindow.postMessage(initMsg, "*", [channel.port2]);
749
+ _this.iframe.removeEventListener("load", sendMessage);
750
+ };
751
+ this.iframe.addEventListener("load", sendMessage);
752
+ };
753
+ SandpackRuntime.prototype.handleWorkerRequest = function (request, port) {
754
+ return __awaiter(this, void 0, void 0, function () {
755
+ var notFound, filepath_1, headers, body, modulesFromManager, match, extension, foundMimetype, responseMessage, err_1;
756
+ return __generator(this, function (_a) {
757
+ switch (_a.label) {
758
+ case 0:
759
+ notFound = function () {
760
+ var responseMessage = {
761
+ $channel: CHANNEL_NAME,
762
+ $type: "preview/response",
763
+ id: request.id,
764
+ headers: {
765
+ "Content-Type": "text/html; charset=utf-8",
766
+ },
767
+ status: 404,
768
+ body: "File not found",
769
+ };
770
+ port.postMessage(responseMessage);
771
+ };
772
+ _a.label = 1;
773
+ case 1:
774
+ _a.trys.push([1, 7, , 8]);
775
+ filepath_1 = new URL(request.url, this.bundlerURL).pathname;
776
+ headers = {};
777
+ body = void 0;
778
+ return [4 /*yield*/, this.sandboxSetup.fs.exists(filepath_1)];
779
+ case 2:
780
+ if (!_a.sent()) return [3 /*break*/, 4];
781
+ return [4 /*yield*/, this.sandboxSetup.fs.readFile(filepath_1)];
782
+ case 3:
783
+ body = _a.sent();
784
+ return [3 /*break*/, 6];
785
+ case 4: return [4 /*yield*/, this.getTranspiledFiles()];
786
+ case 5:
787
+ modulesFromManager = _a.sent();
788
+ match = modulesFromManager.find(function (item) {
789
+ return item.path.endsWith(filepath_1);
790
+ });
791
+ if (match) {
792
+ body = match.code;
793
+ }
794
+ _a.label = 6;
795
+ case 6:
796
+ if (body === undefined) {
797
+ notFound();
798
+ return [2 /*return*/];
799
+ }
800
+ if (!headers["Content-Type"]) {
801
+ extension = getExtension(filepath_1);
802
+ foundMimetype = EXTENSIONS_MAP.get(extension);
803
+ if (foundMimetype) {
804
+ headers["Content-Type"] = foundMimetype;
805
+ }
806
+ }
807
+ responseMessage = {
808
+ $channel: CHANNEL_NAME,
809
+ $type: "preview/response",
810
+ id: request.id,
811
+ headers: headers,
812
+ status: 200,
813
+ body: body,
814
+ };
815
+ port.postMessage(responseMessage);
816
+ return [3 /*break*/, 8];
817
+ case 7:
818
+ err_1 = _a.sent();
819
+ console.error(err_1);
820
+ notFound();
821
+ return [3 /*break*/, 8];
822
+ case 8: return [2 /*return*/];
823
+ }
824
+ });
825
+ });
826
+ };
827
+ SandpackRuntime.prototype.setLocationURLIntoIFrame = function () {
828
+ var _a;
829
+ var urlSource = this.options.startRoute
830
+ ? new URL(this.options.startRoute, this.bundlerURL).toString()
831
+ : this.bundlerURL;
832
+ (_a = this.iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.location.replace(urlSource);
833
+ this.iframe.src = urlSource;
834
+ };
835
+ SandpackRuntime.prototype.destroy = function () {
836
+ var _a, _b, _c, _d;
837
+ this.unsubscribeChannelListener();
838
+ this.unsubscribeGlobalListener();
839
+ (_a = this.unsubscribeFsWatcher) === null || _a === void 0 ? void 0 : _a.call(this);
840
+ (_b = this.fileResolverProtocol) === null || _b === void 0 ? void 0 : _b.dispose();
841
+ (_c = this.immutableFetchProtocol) === null || _c === void 0 ? void 0 : _c.dispose();
842
+ (_d = this.babelWorker) === null || _d === void 0 ? void 0 : _d.terminate();
843
+ this.iframeProtocol.cleanup();
844
+ };
845
+ SandpackRuntime.prototype.updateOptions = function (options) {
846
+ if (!dequal(this.options, options)) {
847
+ this.options = options;
848
+ this.updateSandbox();
849
+ }
850
+ };
851
+ /**
852
+ * Updates the local sandbox state. The bundler watches the shared filesystem
853
+ * itself, so there is nothing to push to the iframe here — a file mutation
854
+ * triggers a rebuild on the bundler side without a `compile` message. A
855
+ * template/environment change is handled by re-registering the client (see
856
+ * `useClient`'s `watchFileChanges` effect), which re-runs `computeInitConfig`.
857
+ */
858
+ SandpackRuntime.prototype.updateSandbox = function (sandboxSetup) {
859
+ if (sandboxSetup === void 0) { sandboxSetup = this.sandboxSetup; }
860
+ this.sandboxSetup = __assign(__assign({}, this.sandboxSetup), sandboxSetup);
861
+ };
862
+ /**
863
+ * Computes the bundler's bootstrap config. Delivered once via the
864
+ * `register-frame` handshake (see the `initialized` handler) instead of a
865
+ * `compile` message, since the bundler now self-watches the filesystem.
866
+ */
867
+ SandpackRuntime.prototype.computeInitConfig = function () {
868
+ return __awaiter(this, void 0, void 0, function () {
869
+ var fs, packageJSON, _a, _b, e_1, fileNames, fileNameMap;
870
+ var _c;
871
+ return __generator(this, function (_d) {
872
+ switch (_d.label) {
873
+ case 0:
874
+ fs = this.sandboxSetup.fs;
875
+ packageJSON = JSON.parse(createPackageJSON(this.sandboxSetup.dependencies, this.sandboxSetup.devDependencies, this.sandboxSetup.entry));
876
+ _d.label = 1;
877
+ case 1:
878
+ _d.trys.push([1, 5, , 6]);
879
+ return [4 /*yield*/, fs.exists("/package.json")];
880
+ case 2:
881
+ if (!_d.sent()) return [3 /*break*/, 4];
882
+ _b = (_a = JSON).parse;
883
+ return [4 /*yield*/, fs.readFile("/package.json")];
884
+ case 3:
885
+ packageJSON = _b.apply(_a, [_d.sent()]);
886
+ _d.label = 4;
887
+ case 4: return [3 /*break*/, 6];
888
+ case 5:
889
+ e_1 = _d.sent();
890
+ console.error(createError("could not parse package.json file: " + e_1.message));
891
+ return [3 /*break*/, 6];
892
+ case 6: return [4 /*yield*/, fs.list()];
893
+ case 7:
894
+ fileNames = _d.sent();
895
+ fileNameMap = Object.fromEntries(fileNames.map(function (p) { return [p, true]; }));
896
+ return [2 /*return*/, {
897
+ template: this.sandboxSetup.template || getTemplate(packageJSON, fileNameMap),
898
+ logLevel: (_c = this.options.logLevel) !== null && _c !== void 0 ? _c : SandpackLogLevel.Info,
899
+ // Host-pinned SDK integrity hashes (SDK_PACKAGING_SPEC §5.2), forwarded
900
+ // verbatim into register-frame for the bundler to verify against. The host
901
+ // sets it via client options; absent → the bundler skips verification.
902
+ sdkIntegrity: this.options.sdkIntegrity,
903
+ // The §5.2 dirty set, forwarded verbatim into register-frame so the bundler
904
+ // skips seeding artifacts for paths edited in a previous session. Absent ⇒
905
+ // nothing dirty.
906
+ dirtyPaths: this.options.dirtyPaths,
907
+ // R3-49b batch-hydration snapshot, forwarded verbatim into register-frame so
908
+ // the bundler hydrates its read caches before the first compile. Absent ⇒
909
+ // reads cross the Port as before.
910
+ fsSnapshot: this.options.fsSnapshot,
911
+ // The chrome region this frame occupies (R3-114), forwarded verbatim into
912
+ // register-frame so the bundler surfaces it on the runtime globalThis for the
913
+ // SDK's getRegion(). Absent ⇒ the app reads no region.
914
+ region: this.options.region,
915
+ // BOOT_SCAFFOLDING_SPEC §3 — the resolved root package.json, forwarded
916
+ // out-of-band so the bundler reads it from config instead of the FS and no
917
+ // synthesized `package.json` is written into the CoW writable layer. This
918
+ // is the same object `getTemplate` consumes above (the repo's file when
919
+ // present, else the setup-derived default).
920
+ packageJSON: packageJSON,
921
+ }];
922
+ }
923
+ });
924
+ });
925
+ };
926
+ /**
927
+ * Relays the set of changed file paths to the bundler so it can re-bundle.
928
+ * The bundler can't observe parent-side writes to the shared filesystem on
929
+ * its own: zenfs's `Port` backend doesn't forward watch events across the
930
+ * iframe boundary. This lightweight signal replaces the old per-change
931
+ * `compile` message — it carries only paths, not template/options/config.
932
+ */
933
+ SandpackRuntime.prototype.notifyFilesChanged = function (paths) {
934
+ if (!paths.length) {
935
+ return;
936
+ }
937
+ this.dispatch({ type: "fs-change", paths: paths });
938
+ };
939
+ SandpackRuntime.prototype.dispatch = function (message) {
940
+ /**
941
+ * Intercept "refresh" dispatch: this will make sure
942
+ * that the iframe is still in the location it's supposed to be.
943
+ * External links inside the iframe will change the location and
944
+ * prevent the user from navigating back.
945
+ */
946
+ if (message.type === "refresh") {
947
+ this.setLocationURLIntoIFrame();
948
+ if (this.options.experimental_enableServiceWorker) {
949
+ this.serviceWorkerHandshake();
950
+ }
951
+ }
952
+ this.iframeProtocol.dispatch(message);
953
+ };
954
+ SandpackRuntime.prototype.listen = function (listener) {
955
+ return this.iframeProtocol.channelListen(listener);
956
+ };
957
+ /**
958
+ * Get the URL of the contents of the current sandbox
959
+ */
960
+ SandpackRuntime.prototype.getCodeSandboxURL = function () {
961
+ return __awaiter(this, void 0, void 0, function () {
962
+ var snapshot, paramFiles, res, sandboxId;
963
+ return __generator(this, function (_a) {
964
+ switch (_a.label) {
965
+ case 0: return [4 /*yield*/, snapshotFS(this.sandboxSetup.fs)];
966
+ case 1:
967
+ snapshot = _a.sent();
968
+ paramFiles = Object.keys(snapshot).reduce(function (prev, next) {
969
+ var _a;
970
+ return (__assign(__assign({}, prev), (_a = {}, _a[next.replace("/", "")] = {
971
+ content: snapshot[next],
972
+ isBinary: false,
973
+ }, _a)));
974
+ }, {});
975
+ return [4 /*yield*/, fetch("https://codesandbox.io/api/v1/sandboxes/define?json=1", {
976
+ method: "POST",
977
+ body: JSON.stringify({ files: paramFiles }),
978
+ headers: {
979
+ Accept: "application/json",
980
+ "Content-Type": "application/json",
981
+ },
982
+ })];
983
+ case 2:
984
+ res = _a.sent();
985
+ return [4 /*yield*/, res.json()];
986
+ case 3:
987
+ sandboxId = (_a.sent()).sandbox_id;
988
+ return [2 /*return*/, {
989
+ sandboxId: sandboxId,
990
+ editorUrl: "https://codesandbox.io/s/".concat(sandboxId),
991
+ embedUrl: "https://codesandbox.io/embed/".concat(sandboxId),
992
+ }];
993
+ }
994
+ });
995
+ });
996
+ };
997
+ SandpackRuntime.prototype.initializeElement = function () {
998
+ this.iframe.style.border = "0";
999
+ this.iframe.style.width = this.options.width || "100%";
1000
+ this.iframe.style.height = this.options.height || "100%";
1001
+ this.iframe.style.overflow = "hidden";
1002
+ nullthrows(this.element.parentNode, "The given iframe does not have a parent.");
1003
+ this.element.parentNode.replaceChild(this.iframe, this.element);
1004
+ };
1005
+ return SandpackRuntime;
1006
+ }(SandpackClient));
1007
+ /**
1008
+ * Read every tracked file from the filesystem into a plain `{ path: code }`
1009
+ * snapshot. Used wherever the bundler protocol still expects a flat module
1010
+ * map (the iframe `compile` payload, Open-in-CodeSandbox, etc.).
1011
+ */
1012
+ function snapshotFS(fs) {
1013
+ return __awaiter(this, void 0, void 0, function () {
1014
+ var paths, out;
1015
+ var _this = this;
1016
+ return __generator(this, function (_a) {
1017
+ switch (_a.label) {
1018
+ case 0: return [4 /*yield*/, fs.list()];
1019
+ case 1:
1020
+ paths = _a.sent();
1021
+ out = {};
1022
+ return [4 /*yield*/, Promise.all(paths.map(function (path) { return __awaiter(_this, void 0, void 0, function () {
1023
+ var _a, _b;
1024
+ return __generator(this, function (_c) {
1025
+ switch (_c.label) {
1026
+ case 0:
1027
+ _a = out;
1028
+ _b = path;
1029
+ return [4 /*yield*/, fs.readFile(path)];
1030
+ case 1:
1031
+ _a[_b] = _c.sent();
1032
+ return [2 /*return*/];
1033
+ }
1034
+ });
1035
+ }); }))];
1036
+ case 2:
1037
+ _a.sent();
1038
+ return [2 /*return*/, out];
1039
+ }
1040
+ });
1041
+ });
1042
+ }
1043
+
1044
+ export { SandpackRuntime };