@aprovan/patchwork-compiler 0.1.2-dev.68f15f3 → 0.1.2-dev.78c0b14
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/dist/index.cjs +552 -547
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -28
- package/dist/index.d.ts +75 -28
- package/dist/index.js +542 -544
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CompileOptionsSchema: () => CompileOptionsSchema,
|
|
34
|
+
DEFAULT_CDN_BASE: () => DEFAULT_CDN_BASE,
|
|
34
35
|
DEFAULT_CLI_IMAGE_CONFIG: () => DEFAULT_CLI_IMAGE_CONFIG,
|
|
35
36
|
DEFAULT_IMAGE_CONFIG: () => DEFAULT_IMAGE_CONFIG,
|
|
36
37
|
DEV_SANDBOX: () => DEV_SANDBOX,
|
|
@@ -49,8 +50,8 @@ __export(index_exports, {
|
|
|
49
50
|
cdnTransformPlugin: () => cdnTransformPlugin,
|
|
50
51
|
createCompiler: () => createCompiler,
|
|
51
52
|
createFieldAccessProxy: () => createFieldAccessProxy,
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
createHttpProxy: () => createHttpProxy,
|
|
54
|
+
createIframeProxy: () => createIframeProxy,
|
|
54
55
|
createImageRegistry: () => createImageRegistry,
|
|
55
56
|
createProjectFromFiles: () => createProjectFromFiles,
|
|
56
57
|
createSingleFileProject: () => createSingleFileProject,
|
|
@@ -62,14 +63,19 @@ __export(index_exports, {
|
|
|
62
63
|
generateImportMap: () => generateImportMap,
|
|
63
64
|
generateNamespaceGlobals: () => generateNamespaceGlobals,
|
|
64
65
|
getCdnBaseUrl: () => getCdnBaseUrl,
|
|
66
|
+
getCommonExports: () => getCommonExports,
|
|
65
67
|
getImageRegistry: () => getImageRegistry,
|
|
66
68
|
injectNamespaceGlobals: () => injectNamespaceGlobals,
|
|
69
|
+
isBareImport: () => isBareImport,
|
|
67
70
|
loadImage: () => loadImage,
|
|
71
|
+
matchAlias: () => matchAlias,
|
|
68
72
|
mountEmbedded: () => mountEmbedded,
|
|
69
73
|
mountIframe: () => mountIframe,
|
|
70
74
|
parseImageConfig: () => parseImageConfig,
|
|
71
75
|
parseImageSpec: () => parseImageSpec,
|
|
76
|
+
parseImportPath: () => parseImportPath,
|
|
72
77
|
parseManifest: () => parseManifest,
|
|
78
|
+
parsePackageSpec: () => parsePackageSpec,
|
|
73
79
|
reloadEmbedded: () => reloadEmbedded,
|
|
74
80
|
reloadIframe: () => reloadIframe,
|
|
75
81
|
removeNamespaceGlobals: () => removeNamespaceGlobals,
|
|
@@ -77,59 +83,18 @@ __export(index_exports, {
|
|
|
77
83
|
safeParseImageConfig: () => safeParseImageConfig,
|
|
78
84
|
safeParseManifest: () => safeParseManifest,
|
|
79
85
|
setCdnBaseUrl: () => setCdnBaseUrl,
|
|
86
|
+
toEsmShUrl: () => toEsmShUrl,
|
|
80
87
|
vfsPlugin: () => vfsPlugin
|
|
81
88
|
});
|
|
82
89
|
module.exports = __toCommonJS(index_exports);
|
|
83
90
|
|
|
84
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.
|
|
91
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.16_tsx@4.23.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
|
|
85
92
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
86
93
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
87
94
|
|
|
88
95
|
// src/compiler.ts
|
|
89
96
|
var esbuild = __toESM(require("esbuild-wasm"), 1);
|
|
90
97
|
|
|
91
|
-
// src/vfs/project.ts
|
|
92
|
-
function createProjectFromFiles(files, id = crypto.randomUUID()) {
|
|
93
|
-
const fileMap = /* @__PURE__ */ new Map();
|
|
94
|
-
for (const file of files) {
|
|
95
|
-
fileMap.set(file.path, file);
|
|
96
|
-
}
|
|
97
|
-
return { id, entry: resolveEntry(fileMap), files: fileMap };
|
|
98
|
-
}
|
|
99
|
-
function resolveEntry(files) {
|
|
100
|
-
const paths = Array.from(files.keys());
|
|
101
|
-
const mainFile = paths.find((p) => /\bmain\.(tsx?|jsx?)$/.test(p));
|
|
102
|
-
if (mainFile) return mainFile;
|
|
103
|
-
const indexFile = paths.find((p) => /\bindex\.(tsx?|jsx?)$/.test(p));
|
|
104
|
-
if (indexFile) return indexFile;
|
|
105
|
-
const firstTsx = paths.find((p) => /\.(tsx|jsx)$/.test(p));
|
|
106
|
-
if (firstTsx) return firstTsx;
|
|
107
|
-
return paths[0] || "main.tsx";
|
|
108
|
-
}
|
|
109
|
-
function detectMainFile(language) {
|
|
110
|
-
switch (language) {
|
|
111
|
-
case "tsx":
|
|
112
|
-
case "typescript":
|
|
113
|
-
return "main.tsx";
|
|
114
|
-
case "jsx":
|
|
115
|
-
case "javascript":
|
|
116
|
-
return "main.jsx";
|
|
117
|
-
case "ts":
|
|
118
|
-
return "main.ts";
|
|
119
|
-
case "js":
|
|
120
|
-
return "main.js";
|
|
121
|
-
default:
|
|
122
|
-
return "main.tsx";
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
function createSingleFileProject(content, entry = "main.tsx", id = "inline") {
|
|
126
|
-
return {
|
|
127
|
-
id,
|
|
128
|
-
entry,
|
|
129
|
-
files: /* @__PURE__ */ new Map([[entry, { path: entry, content }]])
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
98
|
// src/schemas.ts
|
|
134
99
|
var import_zod = require("zod");
|
|
135
100
|
var PlatformSchema = import_zod.z.enum(["browser", "cli"]);
|
|
@@ -217,7 +182,7 @@ var DEFAULT_CLI_IMAGE_CONFIG = {
|
|
|
217
182
|
}
|
|
218
183
|
};
|
|
219
184
|
|
|
220
|
-
// src/
|
|
185
|
+
// src/cdn-config.ts
|
|
221
186
|
var DEFAULT_CDN_BASE = "https://esm.sh";
|
|
222
187
|
var cdnBaseUrl = DEFAULT_CDN_BASE;
|
|
223
188
|
function setCdnBaseUrl(url) {
|
|
@@ -226,7 +191,24 @@ function setCdnBaseUrl(url) {
|
|
|
226
191
|
function getCdnBaseUrl() {
|
|
227
192
|
return cdnBaseUrl;
|
|
228
193
|
}
|
|
229
|
-
function
|
|
194
|
+
function toEsmShUrl(packageName, version2, subpath, deps) {
|
|
195
|
+
let url = `${cdnBaseUrl}/${packageName}`;
|
|
196
|
+
if (version2) {
|
|
197
|
+
url += `@${version2}`;
|
|
198
|
+
}
|
|
199
|
+
if (subpath) {
|
|
200
|
+
url += `/${subpath}`;
|
|
201
|
+
}
|
|
202
|
+
if (deps && Object.keys(deps).length > 0) {
|
|
203
|
+
const depsStr = Object.entries(deps).map(([name, ver]) => `${name}@${ver}`).join(",");
|
|
204
|
+
url += `?deps=${depsStr}`;
|
|
205
|
+
}
|
|
206
|
+
return url;
|
|
207
|
+
}
|
|
208
|
+
function isBareImport(path) {
|
|
209
|
+
return !(path.startsWith(".") || path.startsWith("/") || path.startsWith("http://") || path.startsWith("https://"));
|
|
210
|
+
}
|
|
211
|
+
function parsePackageSpec(spec) {
|
|
230
212
|
if (spec.startsWith("@")) {
|
|
231
213
|
const parts = spec.split("/");
|
|
232
214
|
if (parts.length >= 2) {
|
|
@@ -251,14 +233,77 @@ function parseImageSpec(spec) {
|
|
|
251
233
|
}
|
|
252
234
|
return { name: spec };
|
|
253
235
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
236
|
+
function parseImportPath(importPath) {
|
|
237
|
+
if (importPath.startsWith("@")) {
|
|
238
|
+
const parts2 = importPath.split("/");
|
|
239
|
+
if (parts2.length >= 2) {
|
|
240
|
+
const packageName2 = `${parts2[0]}/${parts2[1]}`;
|
|
241
|
+
const subpath2 = parts2.slice(2).join("/");
|
|
242
|
+
return { packageName: packageName2, subpath: subpath2 || void 0 };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const parts = importPath.split("/");
|
|
246
|
+
const packageName = parts[0];
|
|
247
|
+
const subpath = parts.slice(1).join("/");
|
|
248
|
+
return { packageName, subpath: subpath || void 0 };
|
|
249
|
+
}
|
|
250
|
+
function matchAlias(importPath, aliases) {
|
|
251
|
+
for (const [pattern, target] of Object.entries(aliases)) {
|
|
252
|
+
if (pattern.endsWith("/*")) {
|
|
253
|
+
const prefix = pattern.slice(0, -2);
|
|
254
|
+
if (importPath === prefix || importPath.startsWith(prefix + "/")) {
|
|
255
|
+
return target;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (importPath === pattern) {
|
|
259
|
+
return target;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
var COMMON_EXPORTS = {
|
|
265
|
+
react: [
|
|
266
|
+
"useState",
|
|
267
|
+
"useEffect",
|
|
268
|
+
"useCallback",
|
|
269
|
+
"useMemo",
|
|
270
|
+
"useRef",
|
|
271
|
+
"useContext",
|
|
272
|
+
"useReducer",
|
|
273
|
+
"useLayoutEffect",
|
|
274
|
+
"useId",
|
|
275
|
+
"createContext",
|
|
276
|
+
"createElement",
|
|
277
|
+
"cloneElement",
|
|
278
|
+
"createRef",
|
|
279
|
+
"forwardRef",
|
|
280
|
+
"lazy",
|
|
281
|
+
"memo",
|
|
282
|
+
"Fragment",
|
|
283
|
+
"Suspense",
|
|
284
|
+
"StrictMode",
|
|
285
|
+
"Component",
|
|
286
|
+
"PureComponent",
|
|
287
|
+
"Children",
|
|
288
|
+
"isValidElement"
|
|
289
|
+
],
|
|
290
|
+
"react-dom": ["createPortal", "flushSync", "render", "hydrate", "unmountComponentAtNode"]
|
|
291
|
+
};
|
|
292
|
+
function getCommonExports(packageName) {
|
|
293
|
+
return COMMON_EXPORTS[packageName] ?? [];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/images/loader.ts
|
|
297
|
+
function parseImageSpec(spec) {
|
|
298
|
+
return parsePackageSpec(spec);
|
|
299
|
+
}
|
|
300
|
+
async function fetchPackageJson(packageName, version2) {
|
|
301
|
+
const cdnBaseUrl2 = getCdnBaseUrl();
|
|
302
|
+
const versionSuffix = version2 ? `@${version2}` : "";
|
|
303
|
+
const url = `${cdnBaseUrl2}/${packageName}${versionSuffix}/package.json`;
|
|
257
304
|
const response = await fetch(url);
|
|
258
305
|
if (!response.ok) {
|
|
259
|
-
throw new Error(
|
|
260
|
-
`Failed to fetch package.json for ${packageName}: ${response.statusText}`
|
|
261
|
-
);
|
|
306
|
+
throw new Error(`Failed to fetch package.json for ${packageName}: ${response.statusText}`);
|
|
262
307
|
}
|
|
263
308
|
return response.json();
|
|
264
309
|
}
|
|
@@ -313,21 +358,22 @@ async function loadLocalImage(name) {
|
|
|
313
358
|
}
|
|
314
359
|
}
|
|
315
360
|
async function loadImage(spec) {
|
|
316
|
-
const { name, version } = parseImageSpec(spec);
|
|
361
|
+
const { name, version: version2 } = parseImageSpec(spec);
|
|
317
362
|
const localImage = await loadLocalImage(name);
|
|
318
363
|
if (localImage) {
|
|
319
364
|
return localImage;
|
|
320
365
|
}
|
|
321
|
-
const packageJson = await fetchPackageJson(name,
|
|
366
|
+
const packageJson = await fetchPackageJson(name, version2);
|
|
322
367
|
const config = safeParseImageConfig(packageJson.patchwork) || DEFAULT_IMAGE_CONFIG;
|
|
323
368
|
let setup;
|
|
324
369
|
let mount;
|
|
325
370
|
let moduleUrl;
|
|
326
371
|
if (packageJson.main && typeof window !== "undefined") {
|
|
327
372
|
try {
|
|
328
|
-
const
|
|
373
|
+
const cdnBaseUrl2 = getCdnBaseUrl();
|
|
374
|
+
const versionSuffix = version2 ? `@${version2}` : "";
|
|
329
375
|
const mainEntry = packageJson.main.startsWith("./") ? packageJson.main.slice(2) : packageJson.main;
|
|
330
|
-
const importUrl = `${
|
|
376
|
+
const importUrl = `${cdnBaseUrl2}/${name}${versionSuffix}/${mainEntry}`;
|
|
331
377
|
moduleUrl = importUrl;
|
|
332
378
|
const imageModule = await import(
|
|
333
379
|
/* @vite-ignore */
|
|
@@ -354,447 +400,89 @@ async function loadImage(spec) {
|
|
|
354
400
|
};
|
|
355
401
|
}
|
|
356
402
|
|
|
357
|
-
// src/images/registry.ts
|
|
358
|
-
var ImageRegistry = class {
|
|
359
|
-
images = /* @__PURE__ */ new Map();
|
|
360
|
-
loading = /* @__PURE__ */ new Map();
|
|
361
|
-
/**
|
|
362
|
-
* Get a loaded image by spec
|
|
363
|
-
*/
|
|
364
|
-
get(spec) {
|
|
365
|
-
const { name } = parseImageSpec(spec);
|
|
366
|
-
return this.images.get(name);
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Check if an image is loaded
|
|
370
|
-
*/
|
|
371
|
-
has(spec) {
|
|
372
|
-
const { name } = parseImageSpec(spec);
|
|
373
|
-
return this.images.has(name);
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Load an image (or return cached)
|
|
377
|
-
*/
|
|
378
|
-
async load(spec) {
|
|
379
|
-
const { name } = parseImageSpec(spec);
|
|
380
|
-
const cached = this.images.get(name);
|
|
381
|
-
if (cached) {
|
|
382
|
-
return cached;
|
|
383
|
-
}
|
|
384
|
-
const inProgress = this.loading.get(name);
|
|
385
|
-
if (inProgress) {
|
|
386
|
-
return inProgress;
|
|
387
|
-
}
|
|
388
|
-
const loadPromise = loadImage(spec).then((image) => {
|
|
389
|
-
this.images.set(name, image);
|
|
390
|
-
this.loading.delete(name);
|
|
391
|
-
return image;
|
|
392
|
-
});
|
|
393
|
-
this.loading.set(name, loadPromise);
|
|
394
|
-
return loadPromise;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Preload an image
|
|
398
|
-
*/
|
|
399
|
-
async preload(spec) {
|
|
400
|
-
await this.load(spec);
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Clear a specific image from cache
|
|
404
|
-
*/
|
|
405
|
-
clear(spec) {
|
|
406
|
-
const { name } = parseImageSpec(spec);
|
|
407
|
-
this.images.delete(name);
|
|
408
|
-
this.loading.delete(name);
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Clear all cached images
|
|
412
|
-
*/
|
|
413
|
-
clearAll() {
|
|
414
|
-
this.images.clear();
|
|
415
|
-
this.loading.clear();
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Get all loaded image names
|
|
419
|
-
*/
|
|
420
|
-
getLoadedNames() {
|
|
421
|
-
return Array.from(this.images.keys());
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
var globalRegistry = null;
|
|
425
|
-
function getImageRegistry() {
|
|
426
|
-
if (!globalRegistry) {
|
|
427
|
-
globalRegistry = new ImageRegistry();
|
|
428
|
-
}
|
|
429
|
-
return globalRegistry;
|
|
430
|
-
}
|
|
431
|
-
function createImageRegistry() {
|
|
432
|
-
return new ImageRegistry();
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// src/transforms/cdn.ts
|
|
436
|
-
var DEFAULT_CDN_BASE2 = "https://esm.sh";
|
|
437
|
-
var cdnBaseUrl2 = DEFAULT_CDN_BASE2;
|
|
438
|
-
function setCdnBaseUrl2(url) {
|
|
439
|
-
cdnBaseUrl2 = url;
|
|
440
|
-
}
|
|
441
|
-
var EXTERNAL_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom", "ink"]);
|
|
442
|
-
var NODE_BUILTINS = /* @__PURE__ */ new Set([
|
|
443
|
-
"assert",
|
|
444
|
-
"buffer",
|
|
445
|
-
"child_process",
|
|
446
|
-
"cluster",
|
|
447
|
-
"crypto",
|
|
448
|
-
"dgram",
|
|
449
|
-
"dns",
|
|
450
|
-
"events",
|
|
451
|
-
"fs",
|
|
452
|
-
"http",
|
|
453
|
-
"http2",
|
|
454
|
-
"https",
|
|
455
|
-
"net",
|
|
456
|
-
"os",
|
|
457
|
-
"path",
|
|
458
|
-
"perf_hooks",
|
|
459
|
-
"process",
|
|
460
|
-
"querystring",
|
|
461
|
-
"readline",
|
|
462
|
-
"stream",
|
|
463
|
-
"string_decoder",
|
|
464
|
-
"timers",
|
|
465
|
-
"tls",
|
|
466
|
-
"tty",
|
|
467
|
-
"url",
|
|
468
|
-
"util",
|
|
469
|
-
"v8",
|
|
470
|
-
"vm",
|
|
471
|
-
"worker_threads",
|
|
472
|
-
"zlib"
|
|
473
|
-
]);
|
|
474
|
-
function toEsmShUrl(packageName, version, subpath, deps) {
|
|
475
|
-
let url = `${cdnBaseUrl2}/${packageName}`;
|
|
476
|
-
if (version) {
|
|
477
|
-
url += `@${version}`;
|
|
478
|
-
}
|
|
479
|
-
if (subpath) {
|
|
480
|
-
url += `/${subpath}`;
|
|
481
|
-
}
|
|
482
|
-
if (deps && Object.keys(deps).length > 0) {
|
|
483
|
-
const depsStr = Object.entries(deps).map(([name, ver]) => `${name}@${ver}`).join(",");
|
|
484
|
-
url += `?deps=${depsStr}`;
|
|
485
|
-
}
|
|
486
|
-
return url;
|
|
487
|
-
}
|
|
488
|
-
function isBareImport(path) {
|
|
489
|
-
if (path.startsWith(".") || path.startsWith("/") || path.startsWith("http://") || path.startsWith("https://")) {
|
|
490
|
-
return false;
|
|
491
|
-
}
|
|
492
|
-
return true;
|
|
493
|
-
}
|
|
494
|
-
function parseImportPath(importPath) {
|
|
495
|
-
if (importPath.startsWith("@")) {
|
|
496
|
-
const parts2 = importPath.split("/");
|
|
497
|
-
if (parts2.length >= 2) {
|
|
498
|
-
const packageName2 = `${parts2[0]}/${parts2[1]}`;
|
|
499
|
-
const subpath2 = parts2.slice(2).join("/");
|
|
500
|
-
return { packageName: packageName2, subpath: subpath2 || void 0 };
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
const parts = importPath.split("/");
|
|
504
|
-
const packageName = parts[0];
|
|
505
|
-
const subpath = parts.slice(1).join("/");
|
|
506
|
-
return { packageName, subpath: subpath || void 0 };
|
|
507
|
-
}
|
|
508
|
-
function matchAlias(importPath, aliases) {
|
|
509
|
-
for (const [pattern, target] of Object.entries(aliases)) {
|
|
510
|
-
if (pattern.endsWith("/*")) {
|
|
511
|
-
const prefix = pattern.slice(0, -2);
|
|
512
|
-
if (importPath === prefix || importPath.startsWith(prefix + "/")) {
|
|
513
|
-
return target;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
if (importPath === pattern) {
|
|
517
|
-
return target;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
return null;
|
|
521
|
-
}
|
|
522
|
-
function cdnTransformPlugin(options = {}) {
|
|
523
|
-
const {
|
|
524
|
-
packages = {},
|
|
525
|
-
external = [],
|
|
526
|
-
bundle = false,
|
|
527
|
-
globals = {},
|
|
528
|
-
deps = {},
|
|
529
|
-
aliases = {}
|
|
530
|
-
} = options;
|
|
531
|
-
const externalSet = /* @__PURE__ */ new Set([...EXTERNAL_PACKAGES, ...external]);
|
|
532
|
-
const globalsSet = new Set(Object.keys(globals));
|
|
533
|
-
return {
|
|
534
|
-
name: "cdn-transform",
|
|
535
|
-
setup(build2) {
|
|
536
|
-
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
537
|
-
const aliasTarget = matchAlias(args.path, aliases);
|
|
538
|
-
if (aliasTarget) {
|
|
539
|
-
const { packageName, subpath } = parseImportPath(aliasTarget);
|
|
540
|
-
if (globalsSet.has(packageName)) {
|
|
541
|
-
return {
|
|
542
|
-
path: aliasTarget,
|
|
543
|
-
namespace: "global-inject"
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
const version = packages[packageName];
|
|
547
|
-
let url = toEsmShUrl(
|
|
548
|
-
packageName,
|
|
549
|
-
version,
|
|
550
|
-
subpath,
|
|
551
|
-
Object.keys(deps).length > 0 ? deps : void 0
|
|
552
|
-
);
|
|
553
|
-
if (bundle) {
|
|
554
|
-
url += url.includes("?") ? "&bundle" : "?bundle";
|
|
555
|
-
}
|
|
556
|
-
return {
|
|
557
|
-
path: url,
|
|
558
|
-
external: true
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
return null;
|
|
562
|
-
});
|
|
563
|
-
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
564
|
-
if (!isBareImport(args.path)) {
|
|
565
|
-
return null;
|
|
566
|
-
}
|
|
567
|
-
const { packageName } = parseImportPath(args.path);
|
|
568
|
-
if (globalsSet.has(packageName)) {
|
|
569
|
-
return {
|
|
570
|
-
path: args.path,
|
|
571
|
-
namespace: "global-inject"
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
return null;
|
|
575
|
-
});
|
|
576
|
-
build2.onLoad({ filter: /.*/, namespace: "global-inject" }, (args) => {
|
|
577
|
-
const { packageName, subpath } = parseImportPath(args.path);
|
|
578
|
-
const globalName = globals[packageName];
|
|
579
|
-
if (!globalName) return null;
|
|
580
|
-
if (subpath) {
|
|
581
|
-
return {
|
|
582
|
-
contents: `export * from '${packageName}'; export { default } from '${packageName}';`,
|
|
583
|
-
loader: "js"
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
const contents = `
|
|
587
|
-
const mod = window.${globalName};
|
|
588
|
-
export default mod;
|
|
589
|
-
// Re-export all properties as named exports
|
|
590
|
-
const { ${getCommonExports(packageName).join(", ")} } = mod;
|
|
591
|
-
export { ${getCommonExports(packageName).join(", ")} };
|
|
592
|
-
`;
|
|
593
|
-
return {
|
|
594
|
-
contents,
|
|
595
|
-
loader: "js"
|
|
596
|
-
};
|
|
597
|
-
});
|
|
598
|
-
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
599
|
-
if (!isBareImport(args.path)) {
|
|
600
|
-
return null;
|
|
601
|
-
}
|
|
602
|
-
if (NODE_BUILTINS.has(args.path)) {
|
|
603
|
-
return { external: true };
|
|
604
|
-
}
|
|
605
|
-
const { packageName, subpath } = parseImportPath(args.path);
|
|
606
|
-
if (globalsSet.has(packageName)) {
|
|
607
|
-
return null;
|
|
608
|
-
}
|
|
609
|
-
if (externalSet.has(packageName)) {
|
|
610
|
-
return { external: true };
|
|
611
|
-
}
|
|
612
|
-
const version = packages[packageName];
|
|
613
|
-
let url = toEsmShUrl(
|
|
614
|
-
packageName,
|
|
615
|
-
version,
|
|
616
|
-
subpath,
|
|
617
|
-
Object.keys(deps).length > 0 ? deps : void 0
|
|
618
|
-
);
|
|
619
|
-
if (bundle) {
|
|
620
|
-
url += url.includes("?") ? "&bundle" : "?bundle";
|
|
621
|
-
}
|
|
622
|
-
return {
|
|
623
|
-
path: url,
|
|
624
|
-
external: true
|
|
625
|
-
};
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
function getCommonExports(packageName) {
|
|
631
|
-
const exports2 = {
|
|
632
|
-
react: [
|
|
633
|
-
"useState",
|
|
634
|
-
"useEffect",
|
|
635
|
-
"useCallback",
|
|
636
|
-
"useMemo",
|
|
637
|
-
"useRef",
|
|
638
|
-
"useContext",
|
|
639
|
-
"useReducer",
|
|
640
|
-
"useLayoutEffect",
|
|
641
|
-
"useId",
|
|
642
|
-
"createContext",
|
|
643
|
-
"createElement",
|
|
644
|
-
"cloneElement",
|
|
645
|
-
"createRef",
|
|
646
|
-
"forwardRef",
|
|
647
|
-
"lazy",
|
|
648
|
-
"memo",
|
|
649
|
-
"Fragment",
|
|
650
|
-
"Suspense",
|
|
651
|
-
"StrictMode",
|
|
652
|
-
"Component",
|
|
653
|
-
"PureComponent",
|
|
654
|
-
"Children",
|
|
655
|
-
"isValidElement"
|
|
656
|
-
],
|
|
657
|
-
"react-dom": [
|
|
658
|
-
"createPortal",
|
|
659
|
-
"flushSync",
|
|
660
|
-
"render",
|
|
661
|
-
"hydrate",
|
|
662
|
-
"unmountComponentAtNode"
|
|
663
|
-
]
|
|
664
|
-
};
|
|
665
|
-
return exports2[packageName] || [];
|
|
666
|
-
}
|
|
667
|
-
function generateImportMap(packages) {
|
|
668
|
-
const imports = {};
|
|
669
|
-
for (const [name, version] of Object.entries(packages)) {
|
|
670
|
-
imports[name] = toEsmShUrl(name, version);
|
|
671
|
-
}
|
|
672
|
-
return imports;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// src/transforms/vfs.ts
|
|
676
|
-
function dirname(path) {
|
|
677
|
-
const idx = path.lastIndexOf("/");
|
|
678
|
-
return idx === -1 ? "." : path.slice(0, idx) || ".";
|
|
679
|
-
}
|
|
680
|
-
function normalizePath(path) {
|
|
681
|
-
const parts = [];
|
|
682
|
-
for (const segment of path.split("/")) {
|
|
683
|
-
if (segment === "..") parts.pop();
|
|
684
|
-
else if (segment && segment !== ".") parts.push(segment);
|
|
685
|
-
}
|
|
686
|
-
return parts.join("/");
|
|
687
|
-
}
|
|
688
|
-
function inferLoader(path, language) {
|
|
689
|
-
if (language) {
|
|
690
|
-
switch (language) {
|
|
691
|
-
case "typescript":
|
|
692
|
-
case "ts":
|
|
693
|
-
return "ts";
|
|
694
|
-
case "tsx":
|
|
695
|
-
return "tsx";
|
|
696
|
-
case "javascript":
|
|
697
|
-
case "js":
|
|
698
|
-
return "js";
|
|
699
|
-
case "jsx":
|
|
700
|
-
return "jsx";
|
|
701
|
-
case "json":
|
|
702
|
-
return "json";
|
|
703
|
-
case "css":
|
|
704
|
-
return "css";
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
const ext = path.split(".").pop();
|
|
708
|
-
switch (ext) {
|
|
709
|
-
case "ts":
|
|
710
|
-
return "ts";
|
|
711
|
-
case "tsx":
|
|
712
|
-
return "tsx";
|
|
713
|
-
case "js":
|
|
714
|
-
return "js";
|
|
715
|
-
case "jsx":
|
|
716
|
-
return "jsx";
|
|
717
|
-
case "json":
|
|
718
|
-
return "json";
|
|
719
|
-
case "css":
|
|
720
|
-
return "css";
|
|
721
|
-
default:
|
|
722
|
-
return "tsx";
|
|
403
|
+
// src/images/registry.ts
|
|
404
|
+
var ImageRegistry = class {
|
|
405
|
+
images = /* @__PURE__ */ new Map();
|
|
406
|
+
loading = /* @__PURE__ */ new Map();
|
|
407
|
+
/**
|
|
408
|
+
* Get a loaded image by spec
|
|
409
|
+
*/
|
|
410
|
+
get(spec) {
|
|
411
|
+
const { name } = parseImageSpec(spec);
|
|
412
|
+
return this.images.get(name);
|
|
723
413
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
414
|
+
/**
|
|
415
|
+
* Check if an image is loaded
|
|
416
|
+
*/
|
|
417
|
+
has(spec) {
|
|
418
|
+
const { name } = parseImageSpec(spec);
|
|
419
|
+
return this.images.has(name);
|
|
728
420
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if (!aliases) return null;
|
|
738
|
-
for (const [pattern, target] of Object.entries(aliases)) {
|
|
739
|
-
if (pattern.endsWith("/*")) {
|
|
740
|
-
const prefix = pattern.slice(0, -2);
|
|
741
|
-
if (importPath === prefix || importPath.startsWith(prefix + "/")) {
|
|
742
|
-
return target;
|
|
743
|
-
}
|
|
421
|
+
/**
|
|
422
|
+
* Load an image (or return cached)
|
|
423
|
+
*/
|
|
424
|
+
async load(spec) {
|
|
425
|
+
const { name } = parseImageSpec(spec);
|
|
426
|
+
const cached = this.images.get(name);
|
|
427
|
+
if (cached) {
|
|
428
|
+
return cached;
|
|
744
429
|
}
|
|
745
|
-
|
|
746
|
-
|
|
430
|
+
const inProgress = this.loading.get(name);
|
|
431
|
+
if (inProgress) {
|
|
432
|
+
return inProgress;
|
|
747
433
|
}
|
|
434
|
+
const loadPromise = loadImage(spec).then((image) => {
|
|
435
|
+
this.images.set(name, image);
|
|
436
|
+
this.loading.delete(name);
|
|
437
|
+
return image;
|
|
438
|
+
});
|
|
439
|
+
this.loading.set(name, loadPromise);
|
|
440
|
+
return loadPromise;
|
|
748
441
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
for (const ext of extensions) {
|
|
755
|
-
if (project.files.has(path + ext)) return path + ext;
|
|
442
|
+
/**
|
|
443
|
+
* Preload an image
|
|
444
|
+
*/
|
|
445
|
+
async preload(spec) {
|
|
446
|
+
await this.load(spec);
|
|
756
447
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Clear a specific image from cache
|
|
450
|
+
*/
|
|
451
|
+
clear(spec) {
|
|
452
|
+
const { name } = parseImageSpec(spec);
|
|
453
|
+
this.images.delete(name);
|
|
454
|
+
this.loading.delete(name);
|
|
760
455
|
}
|
|
761
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Clear all cached images
|
|
458
|
+
*/
|
|
459
|
+
clearAll() {
|
|
460
|
+
this.images.clear();
|
|
461
|
+
this.loading.clear();
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Get all loaded image names
|
|
465
|
+
*/
|
|
466
|
+
getLoadedNames() {
|
|
467
|
+
return Array.from(this.images.keys());
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
var globalRegistry = null;
|
|
471
|
+
function getImageRegistry() {
|
|
472
|
+
if (!globalRegistry) {
|
|
473
|
+
globalRegistry = new ImageRegistry();
|
|
474
|
+
}
|
|
475
|
+
return globalRegistry;
|
|
762
476
|
}
|
|
763
|
-
function
|
|
764
|
-
return
|
|
765
|
-
name: "patchwork-vfs",
|
|
766
|
-
setup(build2) {
|
|
767
|
-
build2.onResolve({ filter: /^@\// }, (args) => {
|
|
768
|
-
const aliased = matchAlias2(args.path, options.aliases);
|
|
769
|
-
if (aliased) return null;
|
|
770
|
-
return { path: args.path, namespace: "vfs" };
|
|
771
|
-
});
|
|
772
|
-
build2.onResolve({ filter: /^\./ }, (args) => {
|
|
773
|
-
if (args.namespace !== "vfs") return null;
|
|
774
|
-
const resolved = resolveRelativePath(args.importer, args.path);
|
|
775
|
-
return { path: resolved, namespace: "vfs" };
|
|
776
|
-
});
|
|
777
|
-
build2.onLoad({ filter: /.*/, namespace: "vfs" }, (args) => {
|
|
778
|
-
const normalPath = normalizeVFSPath(args.path);
|
|
779
|
-
const filePath = findFile(project, normalPath);
|
|
780
|
-
if (!filePath) {
|
|
781
|
-
throw new Error(`File not found in VFS: ${args.path}`);
|
|
782
|
-
}
|
|
783
|
-
const file = project.files.get(filePath);
|
|
784
|
-
return {
|
|
785
|
-
contents: file.content,
|
|
786
|
-
loader: inferLoader(filePath, file.language)
|
|
787
|
-
};
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
};
|
|
477
|
+
function createImageRegistry() {
|
|
478
|
+
return new ImageRegistry();
|
|
791
479
|
}
|
|
792
480
|
|
|
793
481
|
// src/mount/bridge.ts
|
|
794
482
|
function generateMessageId() {
|
|
795
483
|
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
796
484
|
}
|
|
797
|
-
function
|
|
485
|
+
function createHttpProxy(proxyUrl) {
|
|
798
486
|
return {
|
|
799
487
|
async call(namespace, procedure, args) {
|
|
800
488
|
const url = `${proxyUrl}/${namespace}/${procedure}`;
|
|
@@ -938,7 +626,7 @@ var ParentBridge = class {
|
|
|
938
626
|
this.pendingCalls.clear();
|
|
939
627
|
}
|
|
940
628
|
};
|
|
941
|
-
function
|
|
629
|
+
function createIframeProxy() {
|
|
942
630
|
const pendingCalls = /* @__PURE__ */ new Map();
|
|
943
631
|
if (typeof window !== "undefined") {
|
|
944
632
|
window.addEventListener("message", (event) => {
|
|
@@ -1070,9 +758,9 @@ function injectImportMap(globals, preloadUrls, deps) {
|
|
|
1070
758
|
if (preloadUrls[index]) {
|
|
1071
759
|
imports[pkgName] = preloadUrls[index];
|
|
1072
760
|
} else if (deps?.[pkgName]) {
|
|
1073
|
-
imports[pkgName] =
|
|
761
|
+
imports[pkgName] = toEsmShUrl(pkgName, deps[pkgName]);
|
|
1074
762
|
} else {
|
|
1075
|
-
imports[pkgName] =
|
|
763
|
+
imports[pkgName] = toEsmShUrl(pkgName);
|
|
1076
764
|
}
|
|
1077
765
|
});
|
|
1078
766
|
if (imports["react-dom"]) {
|
|
@@ -1141,18 +829,12 @@ async function mountEmbedded(widget, options, image, proxy) {
|
|
|
1141
829
|
const globalMapping = frameworkConfig.globals || {};
|
|
1142
830
|
const deps = frameworkConfig.deps || {};
|
|
1143
831
|
injectImportMap(globalMapping, preloadUrls, deps);
|
|
1144
|
-
const preloadCache = window.__preloadedModules;
|
|
1145
832
|
const preloadedModules = await Promise.all(
|
|
1146
|
-
preloadUrls.map(
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
/* webpackIgnore: true */
|
|
1152
|
-
/* @vite-ignore */
|
|
1153
|
-
url
|
|
1154
|
-
);
|
|
1155
|
-
})
|
|
833
|
+
preloadUrls.map((url) => import(
|
|
834
|
+
/* webpackIgnore: true */
|
|
835
|
+
/* @vite-ignore */
|
|
836
|
+
url
|
|
837
|
+
))
|
|
1156
838
|
);
|
|
1157
839
|
const win = window;
|
|
1158
840
|
const globalNames = Object.values(globalMapping);
|
|
@@ -1196,48 +878,198 @@ async function mountEmbedded(widget, options, image, proxy) {
|
|
|
1196
878
|
if (typeof root.unmount === "function") {
|
|
1197
879
|
moduleCleanup = () => root.unmount();
|
|
1198
880
|
}
|
|
1199
|
-
} else if (createElement && renderer?.kind === "render") {
|
|
1200
|
-
renderer.render(createElement(Component, inputs), container);
|
|
1201
|
-
} else {
|
|
1202
|
-
const result = Component(inputs);
|
|
1203
|
-
if (result instanceof HTMLElement) {
|
|
1204
|
-
container.appendChild(result);
|
|
1205
|
-
} else if (typeof result === "string") {
|
|
1206
|
-
container.innerHTML = result;
|
|
881
|
+
} else if (createElement && renderer?.kind === "render") {
|
|
882
|
+
renderer.render(createElement(Component, inputs), container);
|
|
883
|
+
} else {
|
|
884
|
+
const result = Component(inputs);
|
|
885
|
+
if (result instanceof HTMLElement) {
|
|
886
|
+
container.appendChild(result);
|
|
887
|
+
} else if (typeof result === "string") {
|
|
888
|
+
container.innerHTML = result;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
} finally {
|
|
893
|
+
URL.revokeObjectURL(scriptUrl);
|
|
894
|
+
}
|
|
895
|
+
const unmount = () => {
|
|
896
|
+
if (moduleCleanup) {
|
|
897
|
+
moduleCleanup();
|
|
898
|
+
}
|
|
899
|
+
removeNamespaceGlobals(window, namespaceNames);
|
|
900
|
+
const style = document.getElementById(`${mountId}-style`);
|
|
901
|
+
if (style) {
|
|
902
|
+
style.remove();
|
|
903
|
+
}
|
|
904
|
+
container.remove();
|
|
905
|
+
};
|
|
906
|
+
return {
|
|
907
|
+
id: mountId,
|
|
908
|
+
widget,
|
|
909
|
+
mode: "embedded",
|
|
910
|
+
target,
|
|
911
|
+
inputs,
|
|
912
|
+
unmount
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
async function reloadEmbedded(mounted, widget, image, proxy) {
|
|
916
|
+
mounted.unmount();
|
|
917
|
+
return mountEmbedded(
|
|
918
|
+
widget,
|
|
919
|
+
{ target: mounted.target, mode: "embedded", inputs: mounted.inputs },
|
|
920
|
+
image,
|
|
921
|
+
proxy
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// src/transforms/cdn.ts
|
|
926
|
+
var EXTERNAL_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom", "ink"]);
|
|
927
|
+
var NODE_BUILTINS = /* @__PURE__ */ new Set([
|
|
928
|
+
"assert",
|
|
929
|
+
"buffer",
|
|
930
|
+
"child_process",
|
|
931
|
+
"cluster",
|
|
932
|
+
"crypto",
|
|
933
|
+
"dgram",
|
|
934
|
+
"dns",
|
|
935
|
+
"events",
|
|
936
|
+
"fs",
|
|
937
|
+
"http",
|
|
938
|
+
"http2",
|
|
939
|
+
"https",
|
|
940
|
+
"net",
|
|
941
|
+
"os",
|
|
942
|
+
"path",
|
|
943
|
+
"perf_hooks",
|
|
944
|
+
"process",
|
|
945
|
+
"querystring",
|
|
946
|
+
"readline",
|
|
947
|
+
"stream",
|
|
948
|
+
"string_decoder",
|
|
949
|
+
"timers",
|
|
950
|
+
"tls",
|
|
951
|
+
"tty",
|
|
952
|
+
"url",
|
|
953
|
+
"util",
|
|
954
|
+
"v8",
|
|
955
|
+
"vm",
|
|
956
|
+
"worker_threads",
|
|
957
|
+
"zlib"
|
|
958
|
+
]);
|
|
959
|
+
function cdnTransformPlugin(options = {}) {
|
|
960
|
+
const {
|
|
961
|
+
packages = {},
|
|
962
|
+
external = [],
|
|
963
|
+
bundle = false,
|
|
964
|
+
globals = {},
|
|
965
|
+
deps = {},
|
|
966
|
+
aliases = {}
|
|
967
|
+
} = options;
|
|
968
|
+
const externalSet = /* @__PURE__ */ new Set([...EXTERNAL_PACKAGES, ...external]);
|
|
969
|
+
const globalsSet = new Set(Object.keys(globals));
|
|
970
|
+
return {
|
|
971
|
+
name: "cdn-transform",
|
|
972
|
+
setup(build2) {
|
|
973
|
+
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
974
|
+
const aliasTarget = matchAlias(args.path, aliases);
|
|
975
|
+
if (aliasTarget) {
|
|
976
|
+
const { packageName, subpath } = parseImportPath(aliasTarget);
|
|
977
|
+
if (globalsSet.has(packageName)) {
|
|
978
|
+
return {
|
|
979
|
+
path: aliasTarget,
|
|
980
|
+
namespace: "global-inject"
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
const version2 = packages[packageName];
|
|
984
|
+
let url = toEsmShUrl(
|
|
985
|
+
packageName,
|
|
986
|
+
version2,
|
|
987
|
+
subpath,
|
|
988
|
+
Object.keys(deps).length > 0 ? deps : void 0
|
|
989
|
+
);
|
|
990
|
+
if (bundle) {
|
|
991
|
+
url += url.includes("?") ? "&bundle" : "?bundle";
|
|
992
|
+
}
|
|
993
|
+
return {
|
|
994
|
+
path: url,
|
|
995
|
+
external: true
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
return null;
|
|
999
|
+
});
|
|
1000
|
+
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
1001
|
+
if (!isBareImport(args.path)) {
|
|
1002
|
+
return null;
|
|
1003
|
+
}
|
|
1004
|
+
const { packageName } = parseImportPath(args.path);
|
|
1005
|
+
if (globalsSet.has(packageName)) {
|
|
1006
|
+
return {
|
|
1007
|
+
path: args.path,
|
|
1008
|
+
namespace: "global-inject"
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
return null;
|
|
1012
|
+
});
|
|
1013
|
+
build2.onLoad({ filter: /.*/, namespace: "global-inject" }, (args) => {
|
|
1014
|
+
const { packageName, subpath } = parseImportPath(args.path);
|
|
1015
|
+
const globalName = globals[packageName];
|
|
1016
|
+
if (!globalName) return null;
|
|
1017
|
+
if (subpath) {
|
|
1018
|
+
return {
|
|
1019
|
+
contents: `export * from '${packageName}'; export { default } from '${packageName}';`,
|
|
1020
|
+
loader: "js"
|
|
1021
|
+
};
|
|
1207
1022
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1023
|
+
const contents = `
|
|
1024
|
+
const mod = window.${globalName};
|
|
1025
|
+
export default mod;
|
|
1026
|
+
// Re-export all properties as named exports
|
|
1027
|
+
const { ${getCommonExports(packageName).join(", ")} } = mod;
|
|
1028
|
+
export { ${getCommonExports(packageName).join(", ")} };
|
|
1029
|
+
`;
|
|
1030
|
+
return {
|
|
1031
|
+
contents,
|
|
1032
|
+
loader: "js"
|
|
1033
|
+
};
|
|
1034
|
+
});
|
|
1035
|
+
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
1036
|
+
if (!isBareImport(args.path)) {
|
|
1037
|
+
return null;
|
|
1038
|
+
}
|
|
1039
|
+
if (NODE_BUILTINS.has(args.path)) {
|
|
1040
|
+
return { external: true };
|
|
1041
|
+
}
|
|
1042
|
+
const { packageName, subpath } = parseImportPath(args.path);
|
|
1043
|
+
if (globalsSet.has(packageName)) {
|
|
1044
|
+
return null;
|
|
1045
|
+
}
|
|
1046
|
+
if (externalSet.has(packageName)) {
|
|
1047
|
+
return { external: true };
|
|
1048
|
+
}
|
|
1049
|
+
const version2 = packages[packageName];
|
|
1050
|
+
let url = toEsmShUrl(
|
|
1051
|
+
packageName,
|
|
1052
|
+
version2,
|
|
1053
|
+
subpath,
|
|
1054
|
+
Object.keys(deps).length > 0 ? deps : void 0
|
|
1055
|
+
);
|
|
1056
|
+
if (bundle) {
|
|
1057
|
+
url += url.includes("?") ? "&bundle" : "?bundle";
|
|
1058
|
+
}
|
|
1059
|
+
return {
|
|
1060
|
+
path: url,
|
|
1061
|
+
external: true
|
|
1062
|
+
};
|
|
1063
|
+
});
|
|
1221
1064
|
}
|
|
1222
|
-
container.remove();
|
|
1223
|
-
};
|
|
1224
|
-
return {
|
|
1225
|
-
id: mountId,
|
|
1226
|
-
widget,
|
|
1227
|
-
mode: "embedded",
|
|
1228
|
-
target,
|
|
1229
|
-
inputs,
|
|
1230
|
-
unmount
|
|
1231
1065
|
};
|
|
1232
1066
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
proxy
|
|
1240
|
-
);
|
|
1067
|
+
function generateImportMap(packages) {
|
|
1068
|
+
const imports = {};
|
|
1069
|
+
for (const [name, version2] of Object.entries(packages)) {
|
|
1070
|
+
imports[name] = toEsmShUrl(name, version2);
|
|
1071
|
+
}
|
|
1072
|
+
return imports;
|
|
1241
1073
|
}
|
|
1242
1074
|
|
|
1243
1075
|
// src/mount/iframe.ts
|
|
@@ -1565,10 +1397,171 @@ function disposeIframeBridge() {
|
|
|
1565
1397
|
}
|
|
1566
1398
|
}
|
|
1567
1399
|
|
|
1400
|
+
// src/transforms/vfs.ts
|
|
1401
|
+
function dirname(path) {
|
|
1402
|
+
const idx = path.lastIndexOf("/");
|
|
1403
|
+
return idx === -1 ? "." : path.slice(0, idx) || ".";
|
|
1404
|
+
}
|
|
1405
|
+
function normalizePath(path) {
|
|
1406
|
+
const parts = [];
|
|
1407
|
+
for (const segment of path.split("/")) {
|
|
1408
|
+
if (segment === "..") parts.pop();
|
|
1409
|
+
else if (segment && segment !== ".") parts.push(segment);
|
|
1410
|
+
}
|
|
1411
|
+
return parts.join("/");
|
|
1412
|
+
}
|
|
1413
|
+
function inferLoader(path, language) {
|
|
1414
|
+
if (language) {
|
|
1415
|
+
switch (language) {
|
|
1416
|
+
case "typescript":
|
|
1417
|
+
case "ts":
|
|
1418
|
+
return "ts";
|
|
1419
|
+
case "tsx":
|
|
1420
|
+
return "tsx";
|
|
1421
|
+
case "javascript":
|
|
1422
|
+
case "js":
|
|
1423
|
+
return "js";
|
|
1424
|
+
case "jsx":
|
|
1425
|
+
return "jsx";
|
|
1426
|
+
case "json":
|
|
1427
|
+
return "json";
|
|
1428
|
+
case "css":
|
|
1429
|
+
return "css";
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const ext = path.split(".").pop();
|
|
1433
|
+
switch (ext) {
|
|
1434
|
+
case "ts":
|
|
1435
|
+
return "ts";
|
|
1436
|
+
case "tsx":
|
|
1437
|
+
return "tsx";
|
|
1438
|
+
case "js":
|
|
1439
|
+
return "js";
|
|
1440
|
+
case "jsx":
|
|
1441
|
+
return "jsx";
|
|
1442
|
+
case "json":
|
|
1443
|
+
return "json";
|
|
1444
|
+
case "css":
|
|
1445
|
+
return "css";
|
|
1446
|
+
default:
|
|
1447
|
+
return "tsx";
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
function normalizeVFSPath(path) {
|
|
1451
|
+
if (path.startsWith("@/")) {
|
|
1452
|
+
return path.slice(2);
|
|
1453
|
+
}
|
|
1454
|
+
return path;
|
|
1455
|
+
}
|
|
1456
|
+
function resolveRelativePath(importer, target) {
|
|
1457
|
+
const importerDir = dirname(normalizeVFSPath(importer));
|
|
1458
|
+
const combined = importerDir === "." ? target : `${importerDir}/${target}`;
|
|
1459
|
+
return normalizePath(combined);
|
|
1460
|
+
}
|
|
1461
|
+
function matchAlias2(importPath, aliases) {
|
|
1462
|
+
if (!aliases) return null;
|
|
1463
|
+
for (const [pattern, target] of Object.entries(aliases)) {
|
|
1464
|
+
if (pattern.endsWith("/*")) {
|
|
1465
|
+
const prefix = pattern.slice(0, -2);
|
|
1466
|
+
if (importPath === prefix || importPath.startsWith(prefix + "/")) {
|
|
1467
|
+
return target;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
if (importPath === pattern) {
|
|
1471
|
+
return target;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
return null;
|
|
1475
|
+
}
|
|
1476
|
+
function findFile(project, path) {
|
|
1477
|
+
if (project.files.has(path)) return path;
|
|
1478
|
+
const extensions = [".tsx", ".ts", ".jsx", ".js", ".json"];
|
|
1479
|
+
for (const ext of extensions) {
|
|
1480
|
+
if (project.files.has(path + ext)) return path + ext;
|
|
1481
|
+
}
|
|
1482
|
+
for (const ext of extensions) {
|
|
1483
|
+
const indexPath = `${path}/index${ext}`;
|
|
1484
|
+
if (project.files.has(indexPath)) return indexPath;
|
|
1485
|
+
}
|
|
1486
|
+
return null;
|
|
1487
|
+
}
|
|
1488
|
+
function vfsPlugin(project, options = {}) {
|
|
1489
|
+
return {
|
|
1490
|
+
name: "patchwork-vfs",
|
|
1491
|
+
setup(build2) {
|
|
1492
|
+
build2.onResolve({ filter: /^@\// }, (args) => {
|
|
1493
|
+
const aliased = matchAlias2(args.path, options.aliases);
|
|
1494
|
+
if (aliased) return null;
|
|
1495
|
+
return { path: args.path, namespace: "vfs" };
|
|
1496
|
+
});
|
|
1497
|
+
build2.onResolve({ filter: /^\./ }, (args) => {
|
|
1498
|
+
const fromEntry = args.namespace !== "vfs" && args.importer === project.entry;
|
|
1499
|
+
if (args.namespace !== "vfs" && !fromEntry) return null;
|
|
1500
|
+
const resolved = resolveRelativePath(args.importer, args.path);
|
|
1501
|
+
return { path: resolved, namespace: "vfs" };
|
|
1502
|
+
});
|
|
1503
|
+
build2.onLoad({ filter: /.*/, namespace: "vfs" }, (args) => {
|
|
1504
|
+
const normalPath = normalizeVFSPath(args.path);
|
|
1505
|
+
const filePath = findFile(project, normalPath);
|
|
1506
|
+
if (!filePath) {
|
|
1507
|
+
throw new Error(`File not found in VFS: ${args.path}`);
|
|
1508
|
+
}
|
|
1509
|
+
const file = project.files.get(filePath);
|
|
1510
|
+
return {
|
|
1511
|
+
contents: file.content,
|
|
1512
|
+
loader: inferLoader(filePath, file.language)
|
|
1513
|
+
};
|
|
1514
|
+
});
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
// src/vfs/project.ts
|
|
1520
|
+
function createProjectFromFiles(files, id = crypto.randomUUID()) {
|
|
1521
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
1522
|
+
for (const file of files) {
|
|
1523
|
+
fileMap.set(file.path, file);
|
|
1524
|
+
}
|
|
1525
|
+
return { id, entry: resolveEntry(fileMap), files: fileMap };
|
|
1526
|
+
}
|
|
1527
|
+
function resolveEntry(files) {
|
|
1528
|
+
const paths = Array.from(files.keys());
|
|
1529
|
+
const mainFile = paths.find((p) => /\bmain\.(tsx?|jsx?)$/.test(p));
|
|
1530
|
+
if (mainFile) return mainFile;
|
|
1531
|
+
const indexFile = paths.find((p) => /\bindex\.(tsx?|jsx?)$/.test(p));
|
|
1532
|
+
if (indexFile) return indexFile;
|
|
1533
|
+
const firstTsx = paths.find((p) => /\.(tsx|jsx)$/.test(p));
|
|
1534
|
+
if (firstTsx) return firstTsx;
|
|
1535
|
+
return paths[0] || "main.tsx";
|
|
1536
|
+
}
|
|
1537
|
+
function detectMainFile(language) {
|
|
1538
|
+
switch (language) {
|
|
1539
|
+
case "tsx":
|
|
1540
|
+
case "typescript":
|
|
1541
|
+
return "main.tsx";
|
|
1542
|
+
case "jsx":
|
|
1543
|
+
case "javascript":
|
|
1544
|
+
return "main.jsx";
|
|
1545
|
+
case "ts":
|
|
1546
|
+
return "main.ts";
|
|
1547
|
+
case "js":
|
|
1548
|
+
return "main.js";
|
|
1549
|
+
default:
|
|
1550
|
+
return "main.tsx";
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
function createSingleFileProject(content, entry = "main.tsx", id = "inline") {
|
|
1554
|
+
return {
|
|
1555
|
+
id,
|
|
1556
|
+
entry,
|
|
1557
|
+
files: /* @__PURE__ */ new Map([[entry, { path: entry, content }]])
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1568
1561
|
// src/compiler.ts
|
|
1569
1562
|
var esbuildInitialized = false;
|
|
1570
1563
|
var esbuildInitPromise = null;
|
|
1571
|
-
var DEFAULT_ESBUILD_WASM_URL =
|
|
1564
|
+
var DEFAULT_ESBUILD_WASM_URL = `https://unpkg.com/esbuild-wasm@${esbuild.version}/esbuild.wasm`;
|
|
1572
1565
|
async function initEsbuild(urlOverrides) {
|
|
1573
1566
|
if (esbuildInitialized) return;
|
|
1574
1567
|
if (esbuildInitPromise) return esbuildInitPromise;
|
|
@@ -1600,18 +1593,18 @@ function hashContent(content) {
|
|
|
1600
1593
|
}
|
|
1601
1594
|
async function createCompiler(options) {
|
|
1602
1595
|
await initEsbuild(options.urlOverrides);
|
|
1603
|
-
const { image: imageSpec, proxyUrl, cdnBaseUrl:
|
|
1604
|
-
if (
|
|
1605
|
-
setCdnBaseUrl(
|
|
1596
|
+
const { image: imageSpec, proxyUrl, cdnBaseUrl: cdnBaseUrl2, widgetCdnBaseUrl } = options;
|
|
1597
|
+
if (cdnBaseUrl2) {
|
|
1598
|
+
setCdnBaseUrl(cdnBaseUrl2);
|
|
1606
1599
|
}
|
|
1607
1600
|
if (widgetCdnBaseUrl) {
|
|
1608
|
-
|
|
1609
|
-
} else if (
|
|
1610
|
-
|
|
1601
|
+
setCdnBaseUrl(widgetCdnBaseUrl);
|
|
1602
|
+
} else if (cdnBaseUrl2) {
|
|
1603
|
+
setCdnBaseUrl(cdnBaseUrl2);
|
|
1611
1604
|
}
|
|
1612
1605
|
const registry = getImageRegistry();
|
|
1613
1606
|
await registry.preload(imageSpec);
|
|
1614
|
-
const proxy =
|
|
1607
|
+
const proxy = createHttpProxy(proxyUrl);
|
|
1615
1608
|
return new PatchworkCompiler(proxy, registry);
|
|
1616
1609
|
}
|
|
1617
1610
|
var PatchworkCompiler = class {
|
|
@@ -2034,6 +2027,8 @@ var SyncEngineImpl = class {
|
|
|
2034
2027
|
this.basePath = config.basePath ?? "";
|
|
2035
2028
|
this.startRemoteWatch();
|
|
2036
2029
|
}
|
|
2030
|
+
local;
|
|
2031
|
+
remote;
|
|
2037
2032
|
status = "idle";
|
|
2038
2033
|
intervalId;
|
|
2039
2034
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -2339,7 +2334,7 @@ function openDB() {
|
|
|
2339
2334
|
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
2340
2335
|
request.onerror = () => reject(request.error);
|
|
2341
2336
|
request.onsuccess = () => resolve(request.result);
|
|
2342
|
-
request.onupgradeneeded = (
|
|
2337
|
+
request.onupgradeneeded = (_event) => {
|
|
2343
2338
|
const db = request.result;
|
|
2344
2339
|
if (!db.objectStoreNames.contains(FILES_STORE)) {
|
|
2345
2340
|
db.createObjectStore(FILES_STORE);
|
|
@@ -2365,6 +2360,7 @@ var IndexedDBBackend = class {
|
|
|
2365
2360
|
constructor(prefix = "vfs") {
|
|
2366
2361
|
this.prefix = prefix;
|
|
2367
2362
|
}
|
|
2363
|
+
prefix;
|
|
2368
2364
|
key(path) {
|
|
2369
2365
|
return `${this.prefix}:${normalizePath2(path)}`;
|
|
2370
2366
|
}
|
|
@@ -2535,6 +2531,7 @@ var HttpBackend = class {
|
|
|
2535
2531
|
constructor(config) {
|
|
2536
2532
|
this.config = config;
|
|
2537
2533
|
}
|
|
2534
|
+
config;
|
|
2538
2535
|
async readFile(path) {
|
|
2539
2536
|
const res = await fetch(this.url(path));
|
|
2540
2537
|
if (!res.ok) throw new Error(`ENOENT: ${path}`);
|
|
@@ -2638,6 +2635,7 @@ var VFSStore = class {
|
|
|
2638
2635
|
}
|
|
2639
2636
|
}
|
|
2640
2637
|
}
|
|
2638
|
+
provider;
|
|
2641
2639
|
local;
|
|
2642
2640
|
syncEngine;
|
|
2643
2641
|
root;
|
|
@@ -2791,6 +2789,7 @@ var VFSStore = class {
|
|
|
2791
2789
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2792
2790
|
0 && (module.exports = {
|
|
2793
2791
|
CompileOptionsSchema,
|
|
2792
|
+
DEFAULT_CDN_BASE,
|
|
2794
2793
|
DEFAULT_CLI_IMAGE_CONFIG,
|
|
2795
2794
|
DEFAULT_IMAGE_CONFIG,
|
|
2796
2795
|
DEV_SANDBOX,
|
|
@@ -2809,8 +2808,8 @@ var VFSStore = class {
|
|
|
2809
2808
|
cdnTransformPlugin,
|
|
2810
2809
|
createCompiler,
|
|
2811
2810
|
createFieldAccessProxy,
|
|
2812
|
-
|
|
2813
|
-
|
|
2811
|
+
createHttpProxy,
|
|
2812
|
+
createIframeProxy,
|
|
2814
2813
|
createImageRegistry,
|
|
2815
2814
|
createProjectFromFiles,
|
|
2816
2815
|
createSingleFileProject,
|
|
@@ -2822,14 +2821,19 @@ var VFSStore = class {
|
|
|
2822
2821
|
generateImportMap,
|
|
2823
2822
|
generateNamespaceGlobals,
|
|
2824
2823
|
getCdnBaseUrl,
|
|
2824
|
+
getCommonExports,
|
|
2825
2825
|
getImageRegistry,
|
|
2826
2826
|
injectNamespaceGlobals,
|
|
2827
|
+
isBareImport,
|
|
2827
2828
|
loadImage,
|
|
2829
|
+
matchAlias,
|
|
2828
2830
|
mountEmbedded,
|
|
2829
2831
|
mountIframe,
|
|
2830
2832
|
parseImageConfig,
|
|
2831
2833
|
parseImageSpec,
|
|
2834
|
+
parseImportPath,
|
|
2832
2835
|
parseManifest,
|
|
2836
|
+
parsePackageSpec,
|
|
2833
2837
|
reloadEmbedded,
|
|
2834
2838
|
reloadIframe,
|
|
2835
2839
|
removeNamespaceGlobals,
|
|
@@ -2837,6 +2841,7 @@ var VFSStore = class {
|
|
|
2837
2841
|
safeParseImageConfig,
|
|
2838
2842
|
safeParseManifest,
|
|
2839
2843
|
setCdnBaseUrl,
|
|
2844
|
+
toEsmShUrl,
|
|
2840
2845
|
vfsPlugin
|
|
2841
2846
|
});
|
|
2842
2847
|
//# sourceMappingURL=index.cjs.map
|