@aprovan/patchwork-compiler 0.1.0 → 0.1.2-dev.6bd527d
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/LICENSE +261 -247
- package/dist/index.cjs +2822 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +828 -0
- package/dist/index.d.ts +130 -54
- package/dist/index.js +990 -115
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,828 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Plugin } from 'esbuild-wasm';
|
|
3
|
+
|
|
4
|
+
interface VirtualFile {
|
|
5
|
+
path: string;
|
|
6
|
+
content: string;
|
|
7
|
+
language?: string;
|
|
8
|
+
note?: string;
|
|
9
|
+
encoding?: "utf8" | "base64";
|
|
10
|
+
}
|
|
11
|
+
interface VirtualProject {
|
|
12
|
+
id: string;
|
|
13
|
+
entry: string;
|
|
14
|
+
files: Map<string, VirtualFile>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Core types for the Patchwork compiler
|
|
19
|
+
*/
|
|
20
|
+
type Platform = 'browser' | 'cli';
|
|
21
|
+
interface Manifest$1 {
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
platform: Platform;
|
|
26
|
+
image: string;
|
|
27
|
+
inputs?: Record<string, InputSpec>;
|
|
28
|
+
services?: string[];
|
|
29
|
+
packages?: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
interface InputSpec {
|
|
32
|
+
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
33
|
+
default?: unknown;
|
|
34
|
+
required?: boolean;
|
|
35
|
+
description?: string;
|
|
36
|
+
}
|
|
37
|
+
interface CompileOptions {
|
|
38
|
+
}
|
|
39
|
+
interface CompiledWidget {
|
|
40
|
+
/** Compiled ESM code */
|
|
41
|
+
code: string;
|
|
42
|
+
/** Content hash for caching */
|
|
43
|
+
hash: string;
|
|
44
|
+
/** Original manifest */
|
|
45
|
+
manifest: Manifest$1;
|
|
46
|
+
/** Source map (if generated) */
|
|
47
|
+
sourceMap?: string;
|
|
48
|
+
}
|
|
49
|
+
type MountMode = 'embedded' | 'iframe';
|
|
50
|
+
interface MountOptions {
|
|
51
|
+
/** Target DOM element to mount into */
|
|
52
|
+
target: HTMLElement;
|
|
53
|
+
/** Mount mode: embedded (trusted) or iframe (sandboxed) */
|
|
54
|
+
mode: MountMode;
|
|
55
|
+
/** CSP sandbox attributes for iframe mode */
|
|
56
|
+
sandbox?: string[];
|
|
57
|
+
/** Initial props/inputs to pass to widget */
|
|
58
|
+
inputs?: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
interface MountedWidget {
|
|
61
|
+
/** Unique mount ID */
|
|
62
|
+
id: string;
|
|
63
|
+
/** The compiled widget */
|
|
64
|
+
widget: CompiledWidget;
|
|
65
|
+
/** Mount mode used */
|
|
66
|
+
mode: MountMode;
|
|
67
|
+
/** Target element */
|
|
68
|
+
target: HTMLElement;
|
|
69
|
+
/** Iframe element (if mode is 'iframe') */
|
|
70
|
+
iframe?: HTMLIFrameElement;
|
|
71
|
+
/** Inputs used for the mount (if provided) */
|
|
72
|
+
inputs?: Record<string, unknown>;
|
|
73
|
+
/** Sandbox attributes used for iframe mode (if provided) */
|
|
74
|
+
sandbox?: string[];
|
|
75
|
+
/** Unmount function */
|
|
76
|
+
unmount: () => void;
|
|
77
|
+
}
|
|
78
|
+
interface ImageConfig$1 {
|
|
79
|
+
platform: Platform;
|
|
80
|
+
esbuild?: {
|
|
81
|
+
target?: string;
|
|
82
|
+
format?: 'esm' | 'cjs' | 'iife';
|
|
83
|
+
jsx?: 'automatic' | 'transform' | 'preserve';
|
|
84
|
+
jsxFactory?: string;
|
|
85
|
+
jsxFragment?: string;
|
|
86
|
+
};
|
|
87
|
+
framework?: {
|
|
88
|
+
/** Map of package names to window global names (e.g., { react: 'React' }) */
|
|
89
|
+
globals?: Record<string, string>;
|
|
90
|
+
/** CDN URLs to preload before widget execution */
|
|
91
|
+
preload?: string[];
|
|
92
|
+
/** Dependency version overrides for CDN packages (e.g., { react: '18' }) */
|
|
93
|
+
deps?: Record<string, string>;
|
|
94
|
+
};
|
|
95
|
+
/** Import path aliases (e.g., { '@/components/ui/*': '@packagedcn/react' }) */
|
|
96
|
+
aliases?: Record<string, string>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Mount function signature provided by images to handle widget mounting.
|
|
100
|
+
* Takes the widget module exports and mounts it to the container.
|
|
101
|
+
*
|
|
102
|
+
* @param module - The widget module with its exports (default, mount, render, game, etc.)
|
|
103
|
+
* @param container - The DOM element to mount into
|
|
104
|
+
* @param inputs - Props/inputs to pass to the widget
|
|
105
|
+
* @returns A cleanup function to unmount, or void
|
|
106
|
+
*/
|
|
107
|
+
type ImageMountFn = (module: Record<string, unknown>, container: HTMLElement, inputs: Record<string, unknown>) => void | (() => void) | Promise<void | (() => void)>;
|
|
108
|
+
interface LoadedImage {
|
|
109
|
+
/** Package name */
|
|
110
|
+
name: string;
|
|
111
|
+
/** Resolved version */
|
|
112
|
+
version: string;
|
|
113
|
+
/** Browser-importable module URL for this image (when loaded from CDN/local HTTP) */
|
|
114
|
+
moduleUrl?: string;
|
|
115
|
+
/** Package configuration */
|
|
116
|
+
config: ImageConfig$1;
|
|
117
|
+
/** Package dependencies */
|
|
118
|
+
dependencies: Record<string, string>;
|
|
119
|
+
/** Setup function (if available) */
|
|
120
|
+
setup?: (root: HTMLElement) => void | Promise<void>;
|
|
121
|
+
/** CSS content (if available) */
|
|
122
|
+
css?: string;
|
|
123
|
+
/**
|
|
124
|
+
* Mount function to handle widget mounting.
|
|
125
|
+
* Each image defines how it expects widgets to export their entry points.
|
|
126
|
+
* Falls back to default mounting behavior if not provided.
|
|
127
|
+
*/
|
|
128
|
+
mount?: ImageMountFn;
|
|
129
|
+
}
|
|
130
|
+
interface CompilerOptions {
|
|
131
|
+
/** Image package to use (e.g., '@aprovan/patchwork-image-shadcnshadcn') */
|
|
132
|
+
image: string;
|
|
133
|
+
/** Backend proxy URL for service calls */
|
|
134
|
+
proxyUrl: string;
|
|
135
|
+
/** Base URL for CDN (default: 'https://esm.sh'). Used for loading image packages. */
|
|
136
|
+
cdnBaseUrl?: string;
|
|
137
|
+
/** Base URL for widget imports (default: same as cdnBaseUrl). Used for transforming imports in widget code. */
|
|
138
|
+
widgetCdnBaseUrl?: string;
|
|
139
|
+
}
|
|
140
|
+
interface Compiler {
|
|
141
|
+
/** Pre-load an image package */
|
|
142
|
+
preloadImage(spec: string): Promise<void>;
|
|
143
|
+
/** Check if an image is loaded */
|
|
144
|
+
isImageLoaded(spec: string): boolean;
|
|
145
|
+
/** Compile widget source to ESM */
|
|
146
|
+
compile(source: string | VirtualProject, manifest: Manifest$1, options?: CompileOptions): Promise<CompiledWidget>;
|
|
147
|
+
/** Mount a compiled widget to the DOM */
|
|
148
|
+
mount(widget: CompiledWidget, options: MountOptions): Promise<MountedWidget>;
|
|
149
|
+
/** Unmount a mounted widget */
|
|
150
|
+
unmount(mounted: MountedWidget): void;
|
|
151
|
+
/** Hot reload a mounted widget */
|
|
152
|
+
reload(mounted: MountedWidget, source: string | VirtualProject, manifest: Manifest$1): Promise<void>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Service proxy interface - abstracts service calls to backend
|
|
156
|
+
*
|
|
157
|
+
* The compiler provides the interface; actual implementation (e.g., UTCP, MCP)
|
|
158
|
+
* is handled by the runtime/backend.
|
|
159
|
+
*/
|
|
160
|
+
interface ServiceProxy {
|
|
161
|
+
call(namespace: string, procedure: string, args: unknown[]): Promise<unknown>;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Service call handler - function that handles calls for a specific namespace
|
|
165
|
+
*/
|
|
166
|
+
type ServiceCallHandler = (procedure: string, args: unknown[]) => Promise<unknown>;
|
|
167
|
+
/**
|
|
168
|
+
* Global interface definition for code generation
|
|
169
|
+
*
|
|
170
|
+
* Describes available global namespaces and their methods that widgets can call.
|
|
171
|
+
* Used during compilation to generate proper TypeScript declarations.
|
|
172
|
+
*/
|
|
173
|
+
interface GlobalInterfaceDefinition {
|
|
174
|
+
/** Namespace name (e.g., 'git', 'github') */
|
|
175
|
+
name: string;
|
|
176
|
+
/** Methods available on this namespace (supports nested paths like 'repos.list') */
|
|
177
|
+
methods: string[];
|
|
178
|
+
/** Optional TypeScript type definitions for methods */
|
|
179
|
+
types?: string;
|
|
180
|
+
}
|
|
181
|
+
type BridgeMessageType = 'service-call' | 'service-result' | 'error';
|
|
182
|
+
interface BridgeMessage {
|
|
183
|
+
type: BridgeMessageType;
|
|
184
|
+
id: string;
|
|
185
|
+
payload: unknown;
|
|
186
|
+
}
|
|
187
|
+
interface ServiceCallPayload {
|
|
188
|
+
namespace: string;
|
|
189
|
+
procedure: string;
|
|
190
|
+
args: unknown[];
|
|
191
|
+
}
|
|
192
|
+
interface ServiceResultPayload {
|
|
193
|
+
result?: unknown;
|
|
194
|
+
error?: string;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Create a compiler instance
|
|
199
|
+
*/
|
|
200
|
+
declare function createCompiler(options: CompilerOptions): Promise<Compiler>;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Zod schemas for Patchwork compiler types
|
|
204
|
+
*
|
|
205
|
+
* These schemas validate:
|
|
206
|
+
* - ImageConfig from package.json patchwork field
|
|
207
|
+
* - Widget manifests
|
|
208
|
+
* - Input specifications
|
|
209
|
+
*/
|
|
210
|
+
|
|
211
|
+
declare const PlatformSchema: z.ZodEnum<["browser", "cli"]>;
|
|
212
|
+
declare const EsbuildConfigSchema: z.ZodOptional<z.ZodObject<{
|
|
213
|
+
target: z.ZodOptional<z.ZodString>;
|
|
214
|
+
format: z.ZodOptional<z.ZodEnum<["esm", "cjs", "iife"]>>;
|
|
215
|
+
jsx: z.ZodOptional<z.ZodEnum<["automatic", "transform", "preserve"]>>;
|
|
216
|
+
jsxFactory: z.ZodOptional<z.ZodString>;
|
|
217
|
+
jsxFragment: z.ZodOptional<z.ZodString>;
|
|
218
|
+
}, "strict", z.ZodTypeAny, {
|
|
219
|
+
jsx?: "automatic" | "transform" | "preserve" | undefined;
|
|
220
|
+
target?: string | undefined;
|
|
221
|
+
format?: "esm" | "cjs" | "iife" | undefined;
|
|
222
|
+
jsxFactory?: string | undefined;
|
|
223
|
+
jsxFragment?: string | undefined;
|
|
224
|
+
}, {
|
|
225
|
+
jsx?: "automatic" | "transform" | "preserve" | undefined;
|
|
226
|
+
target?: string | undefined;
|
|
227
|
+
format?: "esm" | "cjs" | "iife" | undefined;
|
|
228
|
+
jsxFactory?: string | undefined;
|
|
229
|
+
jsxFragment?: string | undefined;
|
|
230
|
+
}>>;
|
|
231
|
+
declare const ImageConfigSchema: z.ZodObject<{
|
|
232
|
+
platform: z.ZodEnum<["browser", "cli"]>;
|
|
233
|
+
dependencies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
234
|
+
esbuild: z.ZodOptional<z.ZodObject<{
|
|
235
|
+
target: z.ZodOptional<z.ZodString>;
|
|
236
|
+
format: z.ZodOptional<z.ZodEnum<["esm", "cjs", "iife"]>>;
|
|
237
|
+
jsx: z.ZodOptional<z.ZodEnum<["automatic", "transform", "preserve"]>>;
|
|
238
|
+
jsxFactory: z.ZodOptional<z.ZodString>;
|
|
239
|
+
jsxFragment: z.ZodOptional<z.ZodString>;
|
|
240
|
+
}, "strict", z.ZodTypeAny, {
|
|
241
|
+
jsx?: "automatic" | "transform" | "preserve" | undefined;
|
|
242
|
+
target?: string | undefined;
|
|
243
|
+
format?: "esm" | "cjs" | "iife" | undefined;
|
|
244
|
+
jsxFactory?: string | undefined;
|
|
245
|
+
jsxFragment?: string | undefined;
|
|
246
|
+
}, {
|
|
247
|
+
jsx?: "automatic" | "transform" | "preserve" | undefined;
|
|
248
|
+
target?: string | undefined;
|
|
249
|
+
format?: "esm" | "cjs" | "iife" | undefined;
|
|
250
|
+
jsxFactory?: string | undefined;
|
|
251
|
+
jsxFragment?: string | undefined;
|
|
252
|
+
}>>;
|
|
253
|
+
framework: z.ZodOptional<z.ZodObject<{
|
|
254
|
+
globals: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
255
|
+
preload: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
256
|
+
deps: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
257
|
+
}, "strict", z.ZodTypeAny, {
|
|
258
|
+
globals?: Record<string, string> | undefined;
|
|
259
|
+
preload?: string[] | undefined;
|
|
260
|
+
deps?: Record<string, string> | undefined;
|
|
261
|
+
}, {
|
|
262
|
+
globals?: Record<string, string> | undefined;
|
|
263
|
+
preload?: string[] | undefined;
|
|
264
|
+
deps?: Record<string, string> | undefined;
|
|
265
|
+
}>>;
|
|
266
|
+
aliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
267
|
+
}, "strict", z.ZodTypeAny, {
|
|
268
|
+
platform: "browser" | "cli";
|
|
269
|
+
dependencies?: Record<string, string> | undefined;
|
|
270
|
+
esbuild?: {
|
|
271
|
+
jsx?: "automatic" | "transform" | "preserve" | undefined;
|
|
272
|
+
target?: string | undefined;
|
|
273
|
+
format?: "esm" | "cjs" | "iife" | undefined;
|
|
274
|
+
jsxFactory?: string | undefined;
|
|
275
|
+
jsxFragment?: string | undefined;
|
|
276
|
+
} | undefined;
|
|
277
|
+
framework?: {
|
|
278
|
+
globals?: Record<string, string> | undefined;
|
|
279
|
+
preload?: string[] | undefined;
|
|
280
|
+
deps?: Record<string, string> | undefined;
|
|
281
|
+
} | undefined;
|
|
282
|
+
aliases?: Record<string, string> | undefined;
|
|
283
|
+
}, {
|
|
284
|
+
platform: "browser" | "cli";
|
|
285
|
+
dependencies?: Record<string, string> | undefined;
|
|
286
|
+
esbuild?: {
|
|
287
|
+
jsx?: "automatic" | "transform" | "preserve" | undefined;
|
|
288
|
+
target?: string | undefined;
|
|
289
|
+
format?: "esm" | "cjs" | "iife" | undefined;
|
|
290
|
+
jsxFactory?: string | undefined;
|
|
291
|
+
jsxFragment?: string | undefined;
|
|
292
|
+
} | undefined;
|
|
293
|
+
framework?: {
|
|
294
|
+
globals?: Record<string, string> | undefined;
|
|
295
|
+
preload?: string[] | undefined;
|
|
296
|
+
deps?: Record<string, string> | undefined;
|
|
297
|
+
} | undefined;
|
|
298
|
+
aliases?: Record<string, string> | undefined;
|
|
299
|
+
}>;
|
|
300
|
+
type ImageConfig = z.infer<typeof ImageConfigSchema>;
|
|
301
|
+
declare const InputSpecSchema: z.ZodObject<{
|
|
302
|
+
type: z.ZodEnum<["string", "number", "boolean", "object", "array"]>;
|
|
303
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
304
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
305
|
+
description: z.ZodOptional<z.ZodString>;
|
|
306
|
+
}, "strip", z.ZodTypeAny, {
|
|
307
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
308
|
+
default?: unknown;
|
|
309
|
+
required?: boolean | undefined;
|
|
310
|
+
description?: string | undefined;
|
|
311
|
+
}, {
|
|
312
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
313
|
+
default?: unknown;
|
|
314
|
+
required?: boolean | undefined;
|
|
315
|
+
description?: string | undefined;
|
|
316
|
+
}>;
|
|
317
|
+
declare const ManifestSchema: z.ZodObject<{
|
|
318
|
+
name: z.ZodString;
|
|
319
|
+
version: z.ZodString;
|
|
320
|
+
description: z.ZodOptional<z.ZodString>;
|
|
321
|
+
platform: z.ZodEnum<["browser", "cli"]>;
|
|
322
|
+
image: z.ZodString;
|
|
323
|
+
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
324
|
+
type: z.ZodEnum<["string", "number", "boolean", "object", "array"]>;
|
|
325
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
326
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
327
|
+
description: z.ZodOptional<z.ZodString>;
|
|
328
|
+
}, "strip", z.ZodTypeAny, {
|
|
329
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
330
|
+
default?: unknown;
|
|
331
|
+
required?: boolean | undefined;
|
|
332
|
+
description?: string | undefined;
|
|
333
|
+
}, {
|
|
334
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
335
|
+
default?: unknown;
|
|
336
|
+
required?: boolean | undefined;
|
|
337
|
+
description?: string | undefined;
|
|
338
|
+
}>>>;
|
|
339
|
+
services: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
340
|
+
packages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
341
|
+
}, "strip", z.ZodTypeAny, {
|
|
342
|
+
platform: "browser" | "cli";
|
|
343
|
+
name: string;
|
|
344
|
+
version: string;
|
|
345
|
+
image: string;
|
|
346
|
+
description?: string | undefined;
|
|
347
|
+
inputs?: Record<string, {
|
|
348
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
349
|
+
default?: unknown;
|
|
350
|
+
required?: boolean | undefined;
|
|
351
|
+
description?: string | undefined;
|
|
352
|
+
}> | undefined;
|
|
353
|
+
services?: string[] | undefined;
|
|
354
|
+
packages?: Record<string, string> | undefined;
|
|
355
|
+
}, {
|
|
356
|
+
platform: "browser" | "cli";
|
|
357
|
+
name: string;
|
|
358
|
+
version: string;
|
|
359
|
+
image: string;
|
|
360
|
+
description?: string | undefined;
|
|
361
|
+
inputs?: Record<string, {
|
|
362
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
363
|
+
default?: unknown;
|
|
364
|
+
required?: boolean | undefined;
|
|
365
|
+
description?: string | undefined;
|
|
366
|
+
}> | undefined;
|
|
367
|
+
services?: string[] | undefined;
|
|
368
|
+
packages?: Record<string, string> | undefined;
|
|
369
|
+
}>;
|
|
370
|
+
type Manifest = z.infer<typeof ManifestSchema>;
|
|
371
|
+
declare const CompileOptionsSchema: z.ZodOptional<z.ZodObject<{
|
|
372
|
+
typescript: z.ZodOptional<z.ZodBoolean>;
|
|
373
|
+
}, "strict", z.ZodTypeAny, {
|
|
374
|
+
typescript?: boolean | undefined;
|
|
375
|
+
}, {
|
|
376
|
+
typescript?: boolean | undefined;
|
|
377
|
+
}>>;
|
|
378
|
+
declare const MountModeSchema: z.ZodEnum<["embedded", "iframe"]>;
|
|
379
|
+
declare const MountOptionsSchema: z.ZodObject<{
|
|
380
|
+
target: z.ZodType<HTMLElement, z.ZodTypeDef, HTMLElement>;
|
|
381
|
+
mode: z.ZodEnum<["embedded", "iframe"]>;
|
|
382
|
+
sandbox: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
383
|
+
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
384
|
+
}, "strip", z.ZodTypeAny, {
|
|
385
|
+
target: HTMLElement;
|
|
386
|
+
mode: "embedded" | "iframe";
|
|
387
|
+
inputs?: Record<string, unknown> | undefined;
|
|
388
|
+
sandbox?: string[] | undefined;
|
|
389
|
+
}, {
|
|
390
|
+
target: HTMLElement;
|
|
391
|
+
mode: "embedded" | "iframe";
|
|
392
|
+
inputs?: Record<string, unknown> | undefined;
|
|
393
|
+
sandbox?: string[] | undefined;
|
|
394
|
+
}>;
|
|
395
|
+
/**
|
|
396
|
+
* Parse and validate ImageConfig from package.json patchwork field
|
|
397
|
+
*
|
|
398
|
+
* @param data - Raw data from package.json patchwork field
|
|
399
|
+
* @returns Validated ImageConfig
|
|
400
|
+
* @throws z.ZodError if validation fails
|
|
401
|
+
*/
|
|
402
|
+
declare function parseImageConfig(data: unknown): ImageConfig;
|
|
403
|
+
/**
|
|
404
|
+
* Safely parse ImageConfig, returning null on failure
|
|
405
|
+
*/
|
|
406
|
+
declare function safeParseImageConfig(data: unknown): ImageConfig | null;
|
|
407
|
+
/**
|
|
408
|
+
* Parse and validate widget manifest
|
|
409
|
+
*/
|
|
410
|
+
declare function parseManifest(data: unknown): Manifest;
|
|
411
|
+
/**
|
|
412
|
+
* Safely parse manifest, returning null on failure
|
|
413
|
+
*/
|
|
414
|
+
declare function safeParseManifest(data: unknown): Manifest | null;
|
|
415
|
+
declare const DEFAULT_IMAGE_CONFIG: ImageConfig;
|
|
416
|
+
declare const DEFAULT_CLI_IMAGE_CONFIG: ImageConfig;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Image loader - fetches and loads image packages from CDN or local
|
|
420
|
+
*
|
|
421
|
+
* Images must be installed as npm packages or available on CDN.
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Set the CDN base URL for image loading
|
|
426
|
+
*/
|
|
427
|
+
declare function setCdnBaseUrl(url: string): void;
|
|
428
|
+
/**
|
|
429
|
+
* Get the current CDN base URL
|
|
430
|
+
*/
|
|
431
|
+
declare function getCdnBaseUrl(): string;
|
|
432
|
+
interface ImagePackageJson {
|
|
433
|
+
name: string;
|
|
434
|
+
version: string;
|
|
435
|
+
main?: string;
|
|
436
|
+
dependencies?: Record<string, string>;
|
|
437
|
+
patchwork?: unknown;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Parse image specifier into name and version
|
|
441
|
+
*/
|
|
442
|
+
declare function parseImageSpec(spec: string): {
|
|
443
|
+
name: string;
|
|
444
|
+
version?: string;
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* Fetch package.json from CDN
|
|
448
|
+
*/
|
|
449
|
+
declare function fetchPackageJson(packageName: string, version?: string): Promise<ImagePackageJson>;
|
|
450
|
+
/**
|
|
451
|
+
* Load an image package
|
|
452
|
+
*
|
|
453
|
+
* Priority:
|
|
454
|
+
* 1. Try to resolve locally (require.resolve for installed packages)
|
|
455
|
+
* 2. Fetch from CDN
|
|
456
|
+
*
|
|
457
|
+
* Images must be explicitly installed or available on CDN.
|
|
458
|
+
*/
|
|
459
|
+
declare function loadImage(spec: string): Promise<LoadedImage>;
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Image registry - manages loaded images
|
|
463
|
+
*/
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Registry of loaded images
|
|
467
|
+
*/
|
|
468
|
+
declare class ImageRegistry {
|
|
469
|
+
private images;
|
|
470
|
+
private loading;
|
|
471
|
+
/**
|
|
472
|
+
* Get a loaded image by spec
|
|
473
|
+
*/
|
|
474
|
+
get(spec: string): LoadedImage | undefined;
|
|
475
|
+
/**
|
|
476
|
+
* Check if an image is loaded
|
|
477
|
+
*/
|
|
478
|
+
has(spec: string): boolean;
|
|
479
|
+
/**
|
|
480
|
+
* Load an image (or return cached)
|
|
481
|
+
*/
|
|
482
|
+
load(spec: string): Promise<LoadedImage>;
|
|
483
|
+
/**
|
|
484
|
+
* Preload an image
|
|
485
|
+
*/
|
|
486
|
+
preload(spec: string): Promise<void>;
|
|
487
|
+
/**
|
|
488
|
+
* Clear a specific image from cache
|
|
489
|
+
*/
|
|
490
|
+
clear(spec: string): void;
|
|
491
|
+
/**
|
|
492
|
+
* Clear all cached images
|
|
493
|
+
*/
|
|
494
|
+
clearAll(): void;
|
|
495
|
+
/**
|
|
496
|
+
* Get all loaded image names
|
|
497
|
+
*/
|
|
498
|
+
getLoadedNames(): string[];
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Get the global image registry
|
|
502
|
+
*/
|
|
503
|
+
declare function getImageRegistry(): ImageRegistry;
|
|
504
|
+
/**
|
|
505
|
+
* Create a new isolated image registry
|
|
506
|
+
*/
|
|
507
|
+
declare function createImageRegistry(): ImageRegistry;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* CDN transform - converts bare imports to CDN URLs (esm.sh)
|
|
511
|
+
*/
|
|
512
|
+
|
|
513
|
+
interface CdnTransformOptions {
|
|
514
|
+
/** Map of package names to versions */
|
|
515
|
+
packages?: Record<string, string>;
|
|
516
|
+
/** Additional external packages */
|
|
517
|
+
external?: string[];
|
|
518
|
+
/** Use bundled versions from esm.sh (adds ?bundle) */
|
|
519
|
+
bundle?: boolean;
|
|
520
|
+
/** Packages to inject from window globals instead of CDN */
|
|
521
|
+
globals?: Record<string, string>;
|
|
522
|
+
/** Dependency version overrides for CDN URLs (e.g., { react: '18' }) */
|
|
523
|
+
deps?: Record<string, string>;
|
|
524
|
+
/** Import path aliases (e.g., { '@/components/ui/*': '@packagedcn/react' }) */
|
|
525
|
+
aliases?: Record<string, string>;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Create an esbuild plugin that transforms bare imports to CDN URLs
|
|
529
|
+
* and injects globals for specified packages (like React)
|
|
530
|
+
*/
|
|
531
|
+
declare function cdnTransformPlugin(options?: CdnTransformOptions): Plugin;
|
|
532
|
+
/**
|
|
533
|
+
* Generate import map for CDN dependencies
|
|
534
|
+
*/
|
|
535
|
+
declare function generateImportMap(packages: Record<string, string>): Record<string, string>;
|
|
536
|
+
|
|
537
|
+
interface VFSPluginOptions {
|
|
538
|
+
aliases?: Record<string, string>;
|
|
539
|
+
}
|
|
540
|
+
declare function vfsPlugin(project: VirtualProject, options?: VFSPluginOptions): Plugin;
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* File statistics matching Node.js fs.Stats subset
|
|
544
|
+
*/
|
|
545
|
+
interface FileStats {
|
|
546
|
+
size: number;
|
|
547
|
+
mtime: Date;
|
|
548
|
+
isFile(): boolean;
|
|
549
|
+
isDirectory(): boolean;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Directory entry matching Node.js fs.Dirent
|
|
553
|
+
*/
|
|
554
|
+
interface DirEntry {
|
|
555
|
+
name: string;
|
|
556
|
+
isFile(): boolean;
|
|
557
|
+
isDirectory(): boolean;
|
|
558
|
+
}
|
|
559
|
+
type WatchEventType = "create" | "update" | "delete";
|
|
560
|
+
type WatchCallback = (event: WatchEventType, path: string) => void;
|
|
561
|
+
/**
|
|
562
|
+
* FSProvider - Node.js fs/promises compatible interface
|
|
563
|
+
* All paths are relative to provider root
|
|
564
|
+
*/
|
|
565
|
+
interface FSProvider {
|
|
566
|
+
readFile(path: string, encoding?: "utf8" | "base64"): Promise<string>;
|
|
567
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
568
|
+
unlink(path: string): Promise<void>;
|
|
569
|
+
stat(path: string): Promise<FileStats>;
|
|
570
|
+
mkdir(path: string, options?: {
|
|
571
|
+
recursive?: boolean;
|
|
572
|
+
}): Promise<void>;
|
|
573
|
+
readdir(path: string): Promise<DirEntry[]>;
|
|
574
|
+
rmdir(path: string, options?: {
|
|
575
|
+
recursive?: boolean;
|
|
576
|
+
}): Promise<void>;
|
|
577
|
+
exists(path: string): Promise<boolean>;
|
|
578
|
+
watch?(path: string, callback: WatchCallback): () => void;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Change record for sync operations
|
|
582
|
+
*/
|
|
583
|
+
interface ChangeRecord {
|
|
584
|
+
path: string;
|
|
585
|
+
type: WatchEventType;
|
|
586
|
+
mtime: Date;
|
|
587
|
+
checksum?: string;
|
|
588
|
+
}
|
|
589
|
+
type ConflictStrategy = "local-wins" | "remote-wins" | "newest-wins" | "manual";
|
|
590
|
+
interface SyncResult {
|
|
591
|
+
pushed: number;
|
|
592
|
+
pulled: number;
|
|
593
|
+
conflicts: ConflictRecord[];
|
|
594
|
+
}
|
|
595
|
+
interface ConflictRecord {
|
|
596
|
+
path: string;
|
|
597
|
+
localMtime: Date;
|
|
598
|
+
remoteMtime: Date;
|
|
599
|
+
resolved?: "local" | "remote";
|
|
600
|
+
}
|
|
601
|
+
type SyncStatus = "idle" | "syncing" | "error";
|
|
602
|
+
type SyncEventType = "change" | "conflict" | "error" | "status";
|
|
603
|
+
type SyncEventCallback<T = unknown> = (data: T) => void;
|
|
604
|
+
|
|
605
|
+
declare class IndexedDBBackend implements FSProvider {
|
|
606
|
+
private prefix;
|
|
607
|
+
constructor(prefix?: string);
|
|
608
|
+
private key;
|
|
609
|
+
readFile(path: string): Promise<string>;
|
|
610
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
611
|
+
unlink(path: string): Promise<void>;
|
|
612
|
+
stat(path: string): Promise<FileStats>;
|
|
613
|
+
mkdir(path: string, options?: {
|
|
614
|
+
recursive?: boolean;
|
|
615
|
+
}): Promise<void>;
|
|
616
|
+
readdir(path: string): Promise<DirEntry[]>;
|
|
617
|
+
rmdir(path: string, options?: {
|
|
618
|
+
recursive?: boolean;
|
|
619
|
+
}): Promise<void>;
|
|
620
|
+
exists(path: string): Promise<boolean>;
|
|
621
|
+
private dirExists;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
interface HttpBackendConfig {
|
|
625
|
+
baseUrl: string;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* HTTP-based FSProvider for connecting to remote servers (e.g., stitchery)
|
|
629
|
+
*/
|
|
630
|
+
declare class HttpBackend implements FSProvider {
|
|
631
|
+
private config;
|
|
632
|
+
constructor(config: HttpBackendConfig);
|
|
633
|
+
readFile(path: string): Promise<string>;
|
|
634
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
635
|
+
unlink(path: string): Promise<void>;
|
|
636
|
+
stat(path: string): Promise<FileStats>;
|
|
637
|
+
mkdir(path: string, options?: {
|
|
638
|
+
recursive?: boolean;
|
|
639
|
+
}): Promise<void>;
|
|
640
|
+
readdir(path: string): Promise<DirEntry[]>;
|
|
641
|
+
rmdir(path: string, options?: {
|
|
642
|
+
recursive?: boolean;
|
|
643
|
+
}): Promise<void>;
|
|
644
|
+
exists(path: string): Promise<boolean>;
|
|
645
|
+
watch(path: string, callback: WatchCallback): () => void;
|
|
646
|
+
private startWatch;
|
|
647
|
+
private url;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
declare function createProjectFromFiles(files: VirtualFile[], id?: string): VirtualProject;
|
|
651
|
+
declare function resolveEntry(files: Map<string, VirtualFile>): string;
|
|
652
|
+
declare function detectMainFile(language?: string): string;
|
|
653
|
+
declare function createSingleFileProject(content: string, entry?: string, id?: string): VirtualProject;
|
|
654
|
+
|
|
655
|
+
interface VFSStoreOptions {
|
|
656
|
+
root?: string;
|
|
657
|
+
sync?: boolean;
|
|
658
|
+
conflictStrategy?: ConflictStrategy;
|
|
659
|
+
autoSyncIntervalMs?: number;
|
|
660
|
+
}
|
|
661
|
+
declare class VFSStore {
|
|
662
|
+
private provider;
|
|
663
|
+
private local?;
|
|
664
|
+
private syncEngine?;
|
|
665
|
+
private root;
|
|
666
|
+
constructor(provider: FSProvider, options?: VFSStoreOptions);
|
|
667
|
+
readFile(path: string, encoding?: "utf8" | "base64"): Promise<string>;
|
|
668
|
+
writeFile(path: string, content: string): Promise<void>;
|
|
669
|
+
unlink(path: string): Promise<void>;
|
|
670
|
+
stat(path: string): Promise<FileStats>;
|
|
671
|
+
mkdir(path: string, options?: {
|
|
672
|
+
recursive?: boolean;
|
|
673
|
+
}): Promise<void>;
|
|
674
|
+
readdir(path: string): Promise<DirEntry[]>;
|
|
675
|
+
rmdir(path: string, options?: {
|
|
676
|
+
recursive?: boolean;
|
|
677
|
+
}): Promise<void>;
|
|
678
|
+
exists(path: string): Promise<boolean>;
|
|
679
|
+
listFiles(prefix?: string): Promise<string[]>;
|
|
680
|
+
loadProject(id: string): Promise<VirtualProject | null>;
|
|
681
|
+
saveProject(project: VirtualProject): Promise<void>;
|
|
682
|
+
sync(): Promise<SyncResult>;
|
|
683
|
+
on<T extends SyncEventType>(event: T, callback: SyncEventCallback<T extends "change" ? ChangeRecord : T extends "conflict" ? ConflictRecord : T extends "error" ? Error : SyncStatus>): () => void;
|
|
684
|
+
private remotePath;
|
|
685
|
+
private walkFiles;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Embedded mount mode - mounts widgets directly in the DOM
|
|
690
|
+
*
|
|
691
|
+
* For trusted widgets that need full window access.
|
|
692
|
+
*/
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Mount a widget in embedded mode (direct DOM injection)
|
|
696
|
+
*/
|
|
697
|
+
declare function mountEmbedded(widget: CompiledWidget, options: MountOptions, image: LoadedImage | null, proxy: ServiceProxy): Promise<MountedWidget>;
|
|
698
|
+
/**
|
|
699
|
+
* Hot reload an embedded widget
|
|
700
|
+
*/
|
|
701
|
+
declare function reloadEmbedded(mounted: MountedWidget, widget: CompiledWidget, image: LoadedImage | null, proxy: ServiceProxy): Promise<MountedWidget>;
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Iframe mount mode - mounts widgets in sandboxed iframes
|
|
705
|
+
*
|
|
706
|
+
* For untrusted widgets that need isolation.
|
|
707
|
+
*/
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Development sandbox attributes - includes allow-same-origin
|
|
711
|
+
*
|
|
712
|
+
* allow-same-origin is required when:
|
|
713
|
+
* - Fetching modules from the parent origin (e.g., /_local-packages/ in dev)
|
|
714
|
+
* - Using import maps that reference parent-relative URLs
|
|
715
|
+
* - Accessing the parent's CDN proxy
|
|
716
|
+
*
|
|
717
|
+
* Note: This does NOT allow the iframe to access parent's DOM or cookies,
|
|
718
|
+
* but it does allow same-origin network requests.
|
|
719
|
+
*
|
|
720
|
+
* WARNING: Combining allow-scripts + allow-same-origin allows the iframe to
|
|
721
|
+
* escape its sandbox. Only use in development or when hosting on a separate subdomain.
|
|
722
|
+
*/
|
|
723
|
+
declare const DEV_SANDBOX: string[];
|
|
724
|
+
/**
|
|
725
|
+
* Mount a widget in iframe mode (sandboxed)
|
|
726
|
+
*/
|
|
727
|
+
declare function mountIframe(widget: CompiledWidget, options: MountOptions, image: LoadedImage | null, proxy: ServiceProxy): Promise<MountedWidget>;
|
|
728
|
+
/**
|
|
729
|
+
* Hot reload an iframe widget
|
|
730
|
+
*/
|
|
731
|
+
declare function reloadIframe(mounted: MountedWidget, widget: CompiledWidget, image: LoadedImage | null, proxy: ServiceProxy): Promise<MountedWidget>;
|
|
732
|
+
/**
|
|
733
|
+
* Dispose the shared bridge (call on app shutdown)
|
|
734
|
+
*/
|
|
735
|
+
declare function disposeIframeBridge(): void;
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Service bridge - handles communication between widgets and service proxy
|
|
739
|
+
*/
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Create a service proxy that calls the backend via HTTP
|
|
743
|
+
*/
|
|
744
|
+
declare function createHttpServiceProxy(proxyUrl: string): ServiceProxy;
|
|
745
|
+
/**
|
|
746
|
+
* Creates a proxy that enables fluent method chaining for dynamic field access.
|
|
747
|
+
*
|
|
748
|
+
* This allows arbitrary nested property access that resolves to a callable function,
|
|
749
|
+
* supporting patterns like `proxy.foo()`, `proxy.foo.bar()`, `proxy.bar.baz.qux()`.
|
|
750
|
+
*
|
|
751
|
+
* Used to create global namespace objects that proxy calls to a service backend.
|
|
752
|
+
*/
|
|
753
|
+
declare function createFieldAccessProxy<T = unknown>(namespace: string, handler: (namespace: string, methodPath: string, ...args: T[]) => Promise<unknown>): Record<string, (...args: T[]) => Promise<unknown>>;
|
|
754
|
+
/**
|
|
755
|
+
* Create namespace globals that proxy calls to a service proxy
|
|
756
|
+
*
|
|
757
|
+
* Creates dynamic proxy objects for each namespace that support arbitrary
|
|
758
|
+
* nested method calls. This replaces the old static method registration.
|
|
759
|
+
*
|
|
760
|
+
* @param services - Array of service names (e.g., ['git', 'github'])
|
|
761
|
+
* @param proxy - The service proxy to forward calls to
|
|
762
|
+
* @returns Record of namespace names to proxy objects
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* ```typescript
|
|
766
|
+
* const namespaces = generateNamespaceGlobals(['git', 'github'], proxy);
|
|
767
|
+
* // namespaces.git.status() calls proxy.call('git', 'status', [])
|
|
768
|
+
* // namespaces.github.repos.list_for_user({ username: 'x' })
|
|
769
|
+
* // calls proxy.call('github', 'repos.list_for_user', [{ username: 'x' }])
|
|
770
|
+
* ```
|
|
771
|
+
*/
|
|
772
|
+
declare function generateNamespaceGlobals(services: string[], proxy: ServiceProxy): Record<string, unknown>;
|
|
773
|
+
/**
|
|
774
|
+
* Inject namespace globals into a window object
|
|
775
|
+
*/
|
|
776
|
+
declare function injectNamespaceGlobals(target: Window | typeof globalThis, namespaces: Record<string, unknown>): void;
|
|
777
|
+
/**
|
|
778
|
+
* Remove namespace globals from a window object
|
|
779
|
+
*/
|
|
780
|
+
declare function removeNamespaceGlobals(target: Window | typeof globalThis, namespaceNames: string[]): void;
|
|
781
|
+
/**
|
|
782
|
+
* Extract unique namespace names from services array
|
|
783
|
+
*/
|
|
784
|
+
declare function extractNamespaces(services: string[]): string[];
|
|
785
|
+
/**
|
|
786
|
+
* Parent-side bridge for iframe communication
|
|
787
|
+
*
|
|
788
|
+
* Listens for postMessage events from iframes and proxies service calls.
|
|
789
|
+
*/
|
|
790
|
+
declare class ParentBridge {
|
|
791
|
+
private proxy;
|
|
792
|
+
private pendingCalls;
|
|
793
|
+
private iframes;
|
|
794
|
+
private messageHandler;
|
|
795
|
+
constructor(proxy: ServiceProxy);
|
|
796
|
+
/**
|
|
797
|
+
* Register an iframe to receive messages from
|
|
798
|
+
*/
|
|
799
|
+
registerIframe(iframe: HTMLIFrameElement): void;
|
|
800
|
+
/**
|
|
801
|
+
* Unregister an iframe
|
|
802
|
+
*/
|
|
803
|
+
unregisterIframe(iframe: HTMLIFrameElement): void;
|
|
804
|
+
/**
|
|
805
|
+
* Handle incoming messages from iframes
|
|
806
|
+
*/
|
|
807
|
+
private handleMessage;
|
|
808
|
+
/**
|
|
809
|
+
* Dispose the bridge
|
|
810
|
+
*/
|
|
811
|
+
dispose(): void;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Child-side bridge for iframe communication
|
|
815
|
+
*
|
|
816
|
+
* Creates a service proxy that sends postMessage to parent.
|
|
817
|
+
*/
|
|
818
|
+
declare function createIframeServiceProxy(): ServiceProxy;
|
|
819
|
+
/**
|
|
820
|
+
* Generate the bridge script to inject into iframes
|
|
821
|
+
*
|
|
822
|
+
* Creates a self-contained script that sets up:
|
|
823
|
+
* 1. Message handling for service results from parent
|
|
824
|
+
* 2. Dynamic proxy objects for each namespace that support arbitrary nested calls
|
|
825
|
+
*/
|
|
826
|
+
declare function generateIframeBridgeScript(services: string[]): string;
|
|
827
|
+
|
|
828
|
+
export { type BridgeMessage, type BridgeMessageType, type CdnTransformOptions, type ChangeRecord, type CompileOptions, CompileOptionsSchema, type CompiledWidget, type Compiler, type CompilerOptions, DEFAULT_CLI_IMAGE_CONFIG, DEFAULT_IMAGE_CONFIG, DEV_SANDBOX, EsbuildConfigSchema, type GlobalInterfaceDefinition, HttpBackend, type HttpBackendConfig, type ImageConfig$1 as ImageConfig, ImageConfigSchema, type ImageMountFn, ImageRegistry, IndexedDBBackend, type InputSpec, InputSpecSchema, type LoadedImage, type Manifest$1 as Manifest, ManifestSchema, type MountMode, MountModeSchema, type MountOptions, MountOptionsSchema, type MountedWidget, ParentBridge, type Platform, PlatformSchema, type ServiceCallHandler, type ServiceCallPayload, type ServiceProxy, type ServiceResultPayload, type VFSPluginOptions, VFSStore, type VFSStoreOptions, type VirtualFile, type VirtualProject, cdnTransformPlugin, createCompiler, createFieldAccessProxy, createHttpServiceProxy, createIframeServiceProxy, createImageRegistry, createProjectFromFiles, createSingleFileProject, detectMainFile, disposeIframeBridge, extractNamespaces, fetchPackageJson, generateIframeBridgeScript, generateImportMap, generateNamespaceGlobals, getCdnBaseUrl, getImageRegistry, injectNamespaceGlobals, loadImage, mountEmbedded, mountIframe, parseImageConfig, parseImageSpec, parseManifest, reloadEmbedded, reloadIframe, removeNamespaceGlobals, resolveEntry, safeParseImageConfig, safeParseManifest, setCdnBaseUrl, vfsPlugin };
|