@aprovan/patchwork-compiler 0.1.2-dev.98a5bc4 → 0.1.2-dev.99f9769
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 +555 -546
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -27
- package/dist/index.d.ts +74 -27
- package/dist/index.js +545 -543
- 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 */
|
|
@@ -351,450 +397,92 @@ async function loadImage(spec) {
|
|
|
351
397
|
dependencies: packageJson.dependencies || {},
|
|
352
398
|
setup,
|
|
353
399
|
mount
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
|
|
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";
|
|
723
|
-
}
|
|
400
|
+
};
|
|
724
401
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
402
|
+
|
|
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);
|
|
728
413
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
414
|
+
/**
|
|
415
|
+
* Check if an image is loaded
|
|
416
|
+
*/
|
|
417
|
+
has(spec) {
|
|
418
|
+
const { name } = parseImageSpec(spec);
|
|
419
|
+
return this.images.has(name);
|
|
420
|
+
}
|
|
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"]) {
|
|
@@ -1142,13 +830,11 @@ async function mountEmbedded(widget, options, image, proxy) {
|
|
|
1142
830
|
const deps = frameworkConfig.deps || {};
|
|
1143
831
|
injectImportMap(globalMapping, preloadUrls, deps);
|
|
1144
832
|
const preloadedModules = await Promise.all(
|
|
1145
|
-
preloadUrls.map(
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
)
|
|
1151
|
-
)
|
|
833
|
+
preloadUrls.map((url) => import(
|
|
834
|
+
/* webpackIgnore: true */
|
|
835
|
+
/* @vite-ignore */
|
|
836
|
+
url
|
|
837
|
+
))
|
|
1152
838
|
);
|
|
1153
839
|
const win = window;
|
|
1154
840
|
const globalNames = Object.values(globalMapping);
|
|
@@ -1192,48 +878,198 @@ async function mountEmbedded(widget, options, image, proxy) {
|
|
|
1192
878
|
if (typeof root.unmount === "function") {
|
|
1193
879
|
moduleCleanup = () => root.unmount();
|
|
1194
880
|
}
|
|
1195
|
-
} else if (createElement && renderer?.kind === "render") {
|
|
1196
|
-
renderer.render(createElement(Component, inputs), container);
|
|
1197
|
-
} else {
|
|
1198
|
-
const result = Component(inputs);
|
|
1199
|
-
if (result instanceof HTMLElement) {
|
|
1200
|
-
container.appendChild(result);
|
|
1201
|
-
} else if (typeof result === "string") {
|
|
1202
|
-
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
|
+
};
|
|
1203
1022
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
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
|
+
});
|
|
1217
1064
|
}
|
|
1218
|
-
container.remove();
|
|
1219
|
-
};
|
|
1220
|
-
return {
|
|
1221
|
-
id: mountId,
|
|
1222
|
-
widget,
|
|
1223
|
-
mode: "embedded",
|
|
1224
|
-
target,
|
|
1225
|
-
inputs,
|
|
1226
|
-
unmount
|
|
1227
1065
|
};
|
|
1228
1066
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
proxy
|
|
1236
|
-
);
|
|
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;
|
|
1237
1073
|
}
|
|
1238
1074
|
|
|
1239
1075
|
// src/mount/iframe.ts
|
|
@@ -1561,10 +1397,171 @@ function disposeIframeBridge() {
|
|
|
1561
1397
|
}
|
|
1562
1398
|
}
|
|
1563
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
|
+
|
|
1564
1561
|
// src/compiler.ts
|
|
1565
1562
|
var esbuildInitialized = false;
|
|
1566
1563
|
var esbuildInitPromise = null;
|
|
1567
|
-
var DEFAULT_ESBUILD_WASM_URL =
|
|
1564
|
+
var DEFAULT_ESBUILD_WASM_URL = `https://unpkg.com/esbuild-wasm@${esbuild.version}/esbuild.wasm`;
|
|
1568
1565
|
async function initEsbuild(urlOverrides) {
|
|
1569
1566
|
if (esbuildInitialized) return;
|
|
1570
1567
|
if (esbuildInitPromise) return esbuildInitPromise;
|
|
@@ -1596,18 +1593,18 @@ function hashContent(content) {
|
|
|
1596
1593
|
}
|
|
1597
1594
|
async function createCompiler(options) {
|
|
1598
1595
|
await initEsbuild(options.urlOverrides);
|
|
1599
|
-
const { image: imageSpec, proxyUrl, cdnBaseUrl:
|
|
1600
|
-
if (
|
|
1601
|
-
setCdnBaseUrl(
|
|
1596
|
+
const { image: imageSpec, proxyUrl, cdnBaseUrl: cdnBaseUrl2, widgetCdnBaseUrl } = options;
|
|
1597
|
+
if (cdnBaseUrl2) {
|
|
1598
|
+
setCdnBaseUrl(cdnBaseUrl2);
|
|
1602
1599
|
}
|
|
1603
1600
|
if (widgetCdnBaseUrl) {
|
|
1604
|
-
|
|
1605
|
-
} else if (
|
|
1606
|
-
|
|
1601
|
+
setCdnBaseUrl(widgetCdnBaseUrl);
|
|
1602
|
+
} else if (cdnBaseUrl2) {
|
|
1603
|
+
setCdnBaseUrl(cdnBaseUrl2);
|
|
1607
1604
|
}
|
|
1608
1605
|
const registry = getImageRegistry();
|
|
1609
1606
|
await registry.preload(imageSpec);
|
|
1610
|
-
const proxy =
|
|
1607
|
+
const proxy = createHttpProxy(proxyUrl);
|
|
1611
1608
|
return new PatchworkCompiler(proxy, registry);
|
|
1612
1609
|
}
|
|
1613
1610
|
var PatchworkCompiler = class {
|
|
@@ -2030,6 +2027,8 @@ var SyncEngineImpl = class {
|
|
|
2030
2027
|
this.basePath = config.basePath ?? "";
|
|
2031
2028
|
this.startRemoteWatch();
|
|
2032
2029
|
}
|
|
2030
|
+
local;
|
|
2031
|
+
remote;
|
|
2033
2032
|
status = "idle";
|
|
2034
2033
|
intervalId;
|
|
2035
2034
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -2335,7 +2334,7 @@ function openDB() {
|
|
|
2335
2334
|
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
2336
2335
|
request.onerror = () => reject(request.error);
|
|
2337
2336
|
request.onsuccess = () => resolve(request.result);
|
|
2338
|
-
request.onupgradeneeded = (
|
|
2337
|
+
request.onupgradeneeded = (_event) => {
|
|
2339
2338
|
const db = request.result;
|
|
2340
2339
|
if (!db.objectStoreNames.contains(FILES_STORE)) {
|
|
2341
2340
|
db.createObjectStore(FILES_STORE);
|
|
@@ -2361,6 +2360,7 @@ var IndexedDBBackend = class {
|
|
|
2361
2360
|
constructor(prefix = "vfs") {
|
|
2362
2361
|
this.prefix = prefix;
|
|
2363
2362
|
}
|
|
2363
|
+
prefix;
|
|
2364
2364
|
key(path) {
|
|
2365
2365
|
return `${this.prefix}:${normalizePath2(path)}`;
|
|
2366
2366
|
}
|
|
@@ -2531,6 +2531,7 @@ var HttpBackend = class {
|
|
|
2531
2531
|
constructor(config) {
|
|
2532
2532
|
this.config = config;
|
|
2533
2533
|
}
|
|
2534
|
+
config;
|
|
2534
2535
|
async readFile(path) {
|
|
2535
2536
|
const res = await fetch(this.url(path));
|
|
2536
2537
|
if (!res.ok) throw new Error(`ENOENT: ${path}`);
|
|
@@ -2634,6 +2635,7 @@ var VFSStore = class {
|
|
|
2634
2635
|
}
|
|
2635
2636
|
}
|
|
2636
2637
|
}
|
|
2638
|
+
provider;
|
|
2637
2639
|
local;
|
|
2638
2640
|
syncEngine;
|
|
2639
2641
|
root;
|
|
@@ -2787,6 +2789,7 @@ var VFSStore = class {
|
|
|
2787
2789
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2788
2790
|
0 && (module.exports = {
|
|
2789
2791
|
CompileOptionsSchema,
|
|
2792
|
+
DEFAULT_CDN_BASE,
|
|
2790
2793
|
DEFAULT_CLI_IMAGE_CONFIG,
|
|
2791
2794
|
DEFAULT_IMAGE_CONFIG,
|
|
2792
2795
|
DEV_SANDBOX,
|
|
@@ -2805,8 +2808,8 @@ var VFSStore = class {
|
|
|
2805
2808
|
cdnTransformPlugin,
|
|
2806
2809
|
createCompiler,
|
|
2807
2810
|
createFieldAccessProxy,
|
|
2808
|
-
|
|
2809
|
-
|
|
2811
|
+
createHttpProxy,
|
|
2812
|
+
createIframeProxy,
|
|
2810
2813
|
createImageRegistry,
|
|
2811
2814
|
createProjectFromFiles,
|
|
2812
2815
|
createSingleFileProject,
|
|
@@ -2818,14 +2821,19 @@ var VFSStore = class {
|
|
|
2818
2821
|
generateImportMap,
|
|
2819
2822
|
generateNamespaceGlobals,
|
|
2820
2823
|
getCdnBaseUrl,
|
|
2824
|
+
getCommonExports,
|
|
2821
2825
|
getImageRegistry,
|
|
2822
2826
|
injectNamespaceGlobals,
|
|
2827
|
+
isBareImport,
|
|
2823
2828
|
loadImage,
|
|
2829
|
+
matchAlias,
|
|
2824
2830
|
mountEmbedded,
|
|
2825
2831
|
mountIframe,
|
|
2826
2832
|
parseImageConfig,
|
|
2827
2833
|
parseImageSpec,
|
|
2834
|
+
parseImportPath,
|
|
2828
2835
|
parseManifest,
|
|
2836
|
+
parsePackageSpec,
|
|
2829
2837
|
reloadEmbedded,
|
|
2830
2838
|
reloadIframe,
|
|
2831
2839
|
removeNamespaceGlobals,
|
|
@@ -2833,6 +2841,7 @@ var VFSStore = class {
|
|
|
2833
2841
|
safeParseImageConfig,
|
|
2834
2842
|
safeParseManifest,
|
|
2835
2843
|
setCdnBaseUrl,
|
|
2844
|
+
toEsmShUrl,
|
|
2836
2845
|
vfsPlugin
|
|
2837
2846
|
});
|
|
2838
2847
|
//# sourceMappingURL=index.cjs.map
|