@aprovan/patchwork 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/.eslintrc.json +22 -0
  2. package/.github/workflows/publish.yml +41 -0
  3. package/.prettierignore +17 -0
  4. package/LICENSE +373 -0
  5. package/README.md +15 -0
  6. package/apps/chat/.utcp_config.json +14 -0
  7. package/apps/chat/.working/widgets/27060b91-a2a5-4272-b243-6eb904bd4070/main.tsx +107 -0
  8. package/apps/chat/index.html +17 -0
  9. package/apps/chat/node_modules/.bin/autoprefixer +17 -0
  10. package/apps/chat/node_modules/.bin/browserslist +17 -0
  11. package/apps/chat/node_modules/.bin/conc +17 -0
  12. package/apps/chat/node_modules/.bin/concurrently +17 -0
  13. package/apps/chat/node_modules/.bin/copilot-proxy +17 -0
  14. package/apps/chat/node_modules/.bin/jiti +17 -0
  15. package/apps/chat/node_modules/.bin/tailwind +17 -0
  16. package/apps/chat/node_modules/.bin/tailwindcss +17 -0
  17. package/apps/chat/node_modules/.bin/tsc +17 -0
  18. package/apps/chat/node_modules/.bin/tsserver +17 -0
  19. package/apps/chat/node_modules/.bin/tsx +17 -0
  20. package/apps/chat/node_modules/.bin/vite +17 -0
  21. package/apps/chat/package.json +55 -0
  22. package/apps/chat/postcss.config.js +6 -0
  23. package/apps/chat/src/App.tsx +7 -0
  24. package/apps/chat/src/components/ui/avatar.tsx +48 -0
  25. package/apps/chat/src/components/ui/badge.tsx +36 -0
  26. package/apps/chat/src/components/ui/button.tsx +56 -0
  27. package/apps/chat/src/components/ui/card.tsx +86 -0
  28. package/apps/chat/src/components/ui/collapsible.tsx +9 -0
  29. package/apps/chat/src/components/ui/dialog.tsx +60 -0
  30. package/apps/chat/src/components/ui/input.tsx +25 -0
  31. package/apps/chat/src/components/ui/scroll-area.tsx +46 -0
  32. package/apps/chat/src/index.css +190 -0
  33. package/apps/chat/src/lib/utils.ts +6 -0
  34. package/apps/chat/src/main.tsx +10 -0
  35. package/apps/chat/src/pages/ChatPage.tsx +460 -0
  36. package/apps/chat/tailwind.config.js +71 -0
  37. package/apps/chat/tsconfig.json +25 -0
  38. package/apps/chat/vite.config.ts +26 -0
  39. package/package.json +35 -0
  40. package/packages/bobbin/node_modules/.bin/esbuild +14 -0
  41. package/packages/bobbin/node_modules/.bin/jiti +17 -0
  42. package/packages/bobbin/node_modules/.bin/tsc +17 -0
  43. package/packages/bobbin/node_modules/.bin/tsserver +17 -0
  44. package/packages/bobbin/node_modules/.bin/tsup +17 -0
  45. package/packages/bobbin/node_modules/.bin/tsup-node +17 -0
  46. package/packages/bobbin/node_modules/.bin/tsx +17 -0
  47. package/packages/bobbin/package.json +30 -0
  48. package/packages/bobbin/src/Bobbin.tsx +89 -0
  49. package/packages/bobbin/src/components/EditPanel/EditPanel.tsx +376 -0
  50. package/packages/bobbin/src/components/EditPanel/controls/ColorPicker.tsx +138 -0
  51. package/packages/bobbin/src/components/EditPanel/controls/QuickSelectDropdown.tsx +142 -0
  52. package/packages/bobbin/src/components/EditPanel/controls/SliderInput.tsx +94 -0
  53. package/packages/bobbin/src/components/EditPanel/controls/SpacingControl.tsx +285 -0
  54. package/packages/bobbin/src/components/EditPanel/controls/ToggleGroup.tsx +37 -0
  55. package/packages/bobbin/src/components/EditPanel/controls/TokenDropdown.tsx +33 -0
  56. package/packages/bobbin/src/components/EditPanel/sections/AnnotationSection.tsx +136 -0
  57. package/packages/bobbin/src/components/EditPanel/sections/BackgroundSection.tsx +79 -0
  58. package/packages/bobbin/src/components/EditPanel/sections/EffectsSection.tsx +85 -0
  59. package/packages/bobbin/src/components/EditPanel/sections/LayoutSection.tsx +224 -0
  60. package/packages/bobbin/src/components/EditPanel/sections/SectionWrapper.tsx +57 -0
  61. package/packages/bobbin/src/components/EditPanel/sections/SizeSection.tsx +166 -0
  62. package/packages/bobbin/src/components/EditPanel/sections/SpacingSection.tsx +69 -0
  63. package/packages/bobbin/src/components/EditPanel/sections/TypographySection.tsx +148 -0
  64. package/packages/bobbin/src/components/Inspector/Inspector.tsx +221 -0
  65. package/packages/bobbin/src/components/Overlay/ControlHandles.tsx +572 -0
  66. package/packages/bobbin/src/components/Overlay/MarginPaddingOverlay.tsx +229 -0
  67. package/packages/bobbin/src/components/Overlay/SelectionOverlay.tsx +73 -0
  68. package/packages/bobbin/src/components/Pill/Pill.tsx +155 -0
  69. package/packages/bobbin/src/components/ThemeToggle/ThemeToggle.tsx +72 -0
  70. package/packages/bobbin/src/core/changeSerializer.ts +139 -0
  71. package/packages/bobbin/src/core/useBobbin.ts +399 -0
  72. package/packages/bobbin/src/core/useChangeTracker.ts +186 -0
  73. package/packages/bobbin/src/core/useClipboard.ts +21 -0
  74. package/packages/bobbin/src/core/useElementSelection.ts +146 -0
  75. package/packages/bobbin/src/index.ts +46 -0
  76. package/packages/bobbin/src/tokens/borders.ts +19 -0
  77. package/packages/bobbin/src/tokens/colors.ts +150 -0
  78. package/packages/bobbin/src/tokens/index.ts +37 -0
  79. package/packages/bobbin/src/tokens/shadows.ts +10 -0
  80. package/packages/bobbin/src/tokens/spacing.ts +37 -0
  81. package/packages/bobbin/src/tokens/typography.ts +51 -0
  82. package/packages/bobbin/src/types.ts +157 -0
  83. package/packages/bobbin/src/utils/animation.ts +40 -0
  84. package/packages/bobbin/src/utils/dom.ts +36 -0
  85. package/packages/bobbin/src/utils/selectors.ts +76 -0
  86. package/packages/bobbin/tsconfig.json +10 -0
  87. package/packages/bobbin/tsup.config.ts +10 -0
  88. package/packages/compiler/node_modules/.bin/esbuild +17 -0
  89. package/packages/compiler/node_modules/.bin/jiti +17 -0
  90. package/packages/compiler/node_modules/.bin/tsc +17 -0
  91. package/packages/compiler/node_modules/.bin/tsserver +17 -0
  92. package/packages/compiler/node_modules/.bin/tsup +17 -0
  93. package/packages/compiler/node_modules/.bin/tsup-node +17 -0
  94. package/packages/compiler/node_modules/.bin/tsx +17 -0
  95. package/packages/compiler/package.json +38 -0
  96. package/packages/compiler/src/compiler.ts +258 -0
  97. package/packages/compiler/src/images/index.ts +13 -0
  98. package/packages/compiler/src/images/loader.ts +234 -0
  99. package/packages/compiler/src/images/registry.ts +112 -0
  100. package/packages/compiler/src/index.ts +141 -0
  101. package/packages/compiler/src/mount/bridge.ts +399 -0
  102. package/packages/compiler/src/mount/embedded.ts +306 -0
  103. package/packages/compiler/src/mount/iframe.ts +433 -0
  104. package/packages/compiler/src/mount/index.ts +18 -0
  105. package/packages/compiler/src/schemas.ts +169 -0
  106. package/packages/compiler/src/transforms/cdn.ts +411 -0
  107. package/packages/compiler/src/transforms/index.ts +4 -0
  108. package/packages/compiler/src/transforms/vfs.ts +138 -0
  109. package/packages/compiler/src/types.ts +233 -0
  110. package/packages/compiler/src/vfs/backends/indexeddb.ts +66 -0
  111. package/packages/compiler/src/vfs/backends/local-fs.ts +41 -0
  112. package/packages/compiler/src/vfs/backends/s3.ts +60 -0
  113. package/packages/compiler/src/vfs/index.ts +11 -0
  114. package/packages/compiler/src/vfs/project.ts +56 -0
  115. package/packages/compiler/src/vfs/store.ts +53 -0
  116. package/packages/compiler/src/vfs/types.ts +20 -0
  117. package/packages/compiler/tsconfig.json +8 -0
  118. package/packages/compiler/tsup.config.ts +14 -0
  119. package/packages/editor/node_modules/.bin/jiti +17 -0
  120. package/packages/editor/node_modules/.bin/tsc +17 -0
  121. package/packages/editor/node_modules/.bin/tsserver +17 -0
  122. package/packages/editor/node_modules/.bin/tsup +17 -0
  123. package/packages/editor/node_modules/.bin/tsup-node +17 -0
  124. package/packages/editor/node_modules/.bin/tsx +17 -0
  125. package/packages/editor/package.json +45 -0
  126. package/packages/editor/src/components/CodeBlockExtension.tsx +190 -0
  127. package/packages/editor/src/components/CodePreview.tsx +344 -0
  128. package/packages/editor/src/components/MarkdownEditor.tsx +270 -0
  129. package/packages/editor/src/components/ServicesInspector.tsx +118 -0
  130. package/packages/editor/src/components/edit/EditHistory.tsx +89 -0
  131. package/packages/editor/src/components/edit/EditModal.tsx +236 -0
  132. package/packages/editor/src/components/edit/FileTree.tsx +144 -0
  133. package/packages/editor/src/components/edit/api.ts +100 -0
  134. package/packages/editor/src/components/edit/index.ts +6 -0
  135. package/packages/editor/src/components/edit/types.ts +53 -0
  136. package/packages/editor/src/components/edit/useEditSession.ts +164 -0
  137. package/packages/editor/src/components/index.ts +5 -0
  138. package/packages/editor/src/index.ts +72 -0
  139. package/packages/editor/src/lib/code-extractor.ts +210 -0
  140. package/packages/editor/src/lib/diff.ts +308 -0
  141. package/packages/editor/src/lib/index.ts +4 -0
  142. package/packages/editor/src/lib/utils.ts +6 -0
  143. package/packages/editor/src/lib/vfs.ts +106 -0
  144. package/packages/editor/tsconfig.json +10 -0
  145. package/packages/editor/tsup.config.ts +10 -0
  146. package/packages/images/ink/node_modules/.bin/jiti +17 -0
  147. package/packages/images/ink/node_modules/.bin/tsc +17 -0
  148. package/packages/images/ink/node_modules/.bin/tsserver +17 -0
  149. package/packages/images/ink/node_modules/.bin/tsup +17 -0
  150. package/packages/images/ink/node_modules/.bin/tsup-node +17 -0
  151. package/packages/images/ink/node_modules/.bin/tsx +17 -0
  152. package/packages/images/ink/package.json +53 -0
  153. package/packages/images/ink/src/index.ts +48 -0
  154. package/packages/images/ink/src/runner.ts +331 -0
  155. package/packages/images/ink/src/setup.ts +123 -0
  156. package/packages/images/ink/tsconfig.json +10 -0
  157. package/packages/images/ink/tsup.config.ts +11 -0
  158. package/packages/images/shadcn/node_modules/.bin/jiti +17 -0
  159. package/packages/images/shadcn/node_modules/.bin/tsc +17 -0
  160. package/packages/images/shadcn/node_modules/.bin/tsserver +17 -0
  161. package/packages/images/shadcn/node_modules/.bin/tsup +17 -0
  162. package/packages/images/shadcn/node_modules/.bin/tsup-node +17 -0
  163. package/packages/images/shadcn/node_modules/.bin/tsx +17 -0
  164. package/packages/images/shadcn/package.json +82 -0
  165. package/packages/images/shadcn/src/html.ts +341 -0
  166. package/packages/images/shadcn/src/index.ts +37 -0
  167. package/packages/images/shadcn/src/setup.ts +287 -0
  168. package/packages/images/shadcn/tsconfig.json +9 -0
  169. package/packages/images/shadcn/tsup.config.ts +13 -0
  170. package/packages/images/vanilla/node_modules/.bin/jiti +17 -0
  171. package/packages/images/vanilla/node_modules/.bin/tsc +17 -0
  172. package/packages/images/vanilla/node_modules/.bin/tsserver +17 -0
  173. package/packages/images/vanilla/node_modules/.bin/tsup +17 -0
  174. package/packages/images/vanilla/node_modules/.bin/tsup-node +17 -0
  175. package/packages/images/vanilla/node_modules/.bin/tsx +17 -0
  176. package/packages/images/vanilla/package.json +35 -0
  177. package/packages/images/vanilla/src/index.ts +7 -0
  178. package/packages/images/vanilla/src/setup.ts +6 -0
  179. package/packages/images/vanilla/tsconfig.json +9 -0
  180. package/packages/images/vanilla/tsup.config.ts +10 -0
  181. package/packages/patchwork/node_modules/.bin/jiti +17 -0
  182. package/packages/patchwork/node_modules/.bin/tsc +17 -0
  183. package/packages/patchwork/node_modules/.bin/tsserver +17 -0
  184. package/packages/patchwork/node_modules/.bin/tsup +17 -0
  185. package/packages/patchwork/node_modules/.bin/tsup-node +17 -0
  186. package/packages/patchwork/node_modules/.bin/tsx +17 -0
  187. package/packages/patchwork/package.json +27 -0
  188. package/packages/patchwork/src/index.ts +15 -0
  189. package/packages/patchwork/src/services/index.ts +11 -0
  190. package/packages/patchwork/src/services/proxy.ts +213 -0
  191. package/packages/patchwork/src/services/types.ts +28 -0
  192. package/packages/patchwork/src/types.ts +116 -0
  193. package/packages/patchwork/tsconfig.json +8 -0
  194. package/packages/patchwork/tsup.config.ts +14 -0
  195. package/packages/stitchery/node_modules/.bin/jiti +17 -0
  196. package/packages/stitchery/node_modules/.bin/tsc +17 -0
  197. package/packages/stitchery/node_modules/.bin/tsserver +17 -0
  198. package/packages/stitchery/node_modules/.bin/tsup +17 -0
  199. package/packages/stitchery/node_modules/.bin/tsup-node +17 -0
  200. package/packages/stitchery/node_modules/.bin/tsx +17 -0
  201. package/packages/stitchery/package.json +40 -0
  202. package/packages/stitchery/src/cli.ts +116 -0
  203. package/packages/stitchery/src/index.ts +16 -0
  204. package/packages/stitchery/src/prompts.ts +326 -0
  205. package/packages/stitchery/src/server/index.ts +365 -0
  206. package/packages/stitchery/src/server/local-packages.ts +91 -0
  207. package/packages/stitchery/src/server/routes.ts +122 -0
  208. package/packages/stitchery/src/server/services.ts +382 -0
  209. package/packages/stitchery/src/server/vfs-routes.ts +142 -0
  210. package/packages/stitchery/src/types.ts +59 -0
  211. package/packages/stitchery/tsconfig.json +13 -0
  212. package/packages/stitchery/tsup.config.ts +15 -0
  213. package/packages/utcp/node_modules/.bin/jiti +17 -0
  214. package/packages/utcp/node_modules/.bin/tsc +17 -0
  215. package/packages/utcp/node_modules/.bin/tsserver +17 -0
  216. package/packages/utcp/node_modules/.bin/tsup +17 -0
  217. package/packages/utcp/node_modules/.bin/tsup-node +17 -0
  218. package/packages/utcp/node_modules/.bin/tsx +17 -0
  219. package/packages/utcp/package.json +38 -0
  220. package/packages/utcp/src/index.ts +153 -0
  221. package/packages/utcp/tsconfig.json +8 -0
  222. package/packages/utcp/tsup.config.ts +12 -0
  223. package/pnpm-workspace.yaml +3 -0
  224. package/tsconfig.json +18 -0
  225. package/turbo.json +23 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Image loader - fetches and loads image packages from CDN or local
3
+ *
4
+ * Images must be installed as npm packages or available on CDN.
5
+ */
6
+
7
+ import type { LoadedImage } from '../types.js';
8
+ import { safeParseImageConfig, DEFAULT_IMAGE_CONFIG } from '../schemas.js';
9
+
10
+ const DEFAULT_CDN_BASE = 'https://esm.sh';
11
+
12
+ // Module-level CDN base URL (can be overridden)
13
+ let cdnBaseUrl = DEFAULT_CDN_BASE;
14
+
15
+ /**
16
+ * Set the CDN base URL for image loading
17
+ */
18
+ export function setCdnBaseUrl(url: string): void {
19
+ cdnBaseUrl = url;
20
+ }
21
+
22
+ /**
23
+ * Get the current CDN base URL
24
+ */
25
+ export function getCdnBaseUrl(): string {
26
+ return cdnBaseUrl;
27
+ }
28
+
29
+ export interface ImagePackageJson {
30
+ name: string;
31
+ version: string;
32
+ main?: string;
33
+ dependencies?: Record<string, string>;
34
+ patchwork?: unknown;
35
+ }
36
+
37
+ /**
38
+ * Parse image specifier into name and version
39
+ */
40
+ export function parseImageSpec(spec: string): {
41
+ name: string;
42
+ version?: string;
43
+ } {
44
+ // Handle scoped packages (@scope/name@version)
45
+ if (spec.startsWith('@')) {
46
+ const parts = spec.split('/');
47
+ if (parts.length >= 2) {
48
+ const scope = parts[0];
49
+ const nameAndVersion = parts.slice(1).join('/');
50
+ const atIndex = nameAndVersion.lastIndexOf('@');
51
+ if (atIndex > 0) {
52
+ return {
53
+ name: `${scope}/${nameAndVersion.slice(0, atIndex)}`,
54
+ version: nameAndVersion.slice(atIndex + 1),
55
+ };
56
+ }
57
+ return { name: `${scope}/${nameAndVersion}` };
58
+ }
59
+ }
60
+
61
+ // Handle non-scoped packages
62
+ const atIndex = spec.lastIndexOf('@');
63
+ if (atIndex > 0) {
64
+ return {
65
+ name: spec.slice(0, atIndex),
66
+ version: spec.slice(atIndex + 1),
67
+ };
68
+ }
69
+ return { name: spec };
70
+ }
71
+
72
+ /**
73
+ * Fetch package.json from CDN
74
+ */
75
+ export async function fetchPackageJson(
76
+ packageName: string,
77
+ version?: string,
78
+ ): Promise<ImagePackageJson> {
79
+ const versionSuffix = version ? `@${version}` : '';
80
+ const url = `${cdnBaseUrl}/${packageName}${versionSuffix}/package.json`;
81
+
82
+ const response = await fetch(url);
83
+ if (!response.ok) {
84
+ throw new Error(
85
+ `Failed to fetch package.json for ${packageName}: ${response.statusText}`,
86
+ );
87
+ }
88
+
89
+ return response.json() as Promise<ImagePackageJson>;
90
+ }
91
+
92
+ /**
93
+ * Try to load an image package from local node_modules
94
+ *
95
+ * Uses dynamic require.resolve to find the package.json,
96
+ * then loads the setup function from the main entry.
97
+ */
98
+ async function loadLocalImage(name: string): Promise<LoadedImage | null> {
99
+ // Only works in Node.js environment
100
+ if (
101
+ typeof globalThis.require === 'undefined' &&
102
+ typeof process === 'undefined'
103
+ ) {
104
+ return null;
105
+ }
106
+
107
+ try {
108
+ // Use createRequire to get require.resolve in ESM context
109
+ const { createRequire } = await import('node:module');
110
+ const { readFile } = await import('node:fs/promises');
111
+ const { dirname, join } = await import('node:path');
112
+
113
+ // Create require from current file for resolution
114
+ const require = createRequire(import.meta.url);
115
+
116
+ // Resolve package.json path
117
+ let packageJsonPath: string;
118
+ try {
119
+ packageJsonPath = require.resolve(`${name}/package.json`);
120
+ } catch {
121
+ // Package not installed locally
122
+ return null;
123
+ }
124
+
125
+ // Read and parse package.json
126
+ const packageJsonContent = await readFile(packageJsonPath, 'utf-8');
127
+ const packageJson: ImagePackageJson = JSON.parse(packageJsonContent);
128
+
129
+ // Validate and extract patchwork config
130
+ const config =
131
+ safeParseImageConfig(packageJson.patchwork) || DEFAULT_IMAGE_CONFIG;
132
+
133
+ // Try to load setup and mount functions
134
+ let setup: LoadedImage['setup'];
135
+ let mount: LoadedImage['mount'];
136
+ const packageDir = dirname(packageJsonPath);
137
+
138
+ if (packageJson.main) {
139
+ try {
140
+ const mainPath = join(packageDir, packageJson.main);
141
+ const imageModule = await import(
142
+ /* webpackIgnore: true */ /* @vite-ignore */ mainPath
143
+ );
144
+ if (typeof imageModule.setup === 'function') {
145
+ setup = imageModule.setup;
146
+ }
147
+ if (typeof imageModule.mount === 'function') {
148
+ mount = imageModule.mount;
149
+ }
150
+ } catch {
151
+ // Setup/mount are optional
152
+ }
153
+ }
154
+
155
+ return {
156
+ name: packageJson.name,
157
+ version: packageJson.version,
158
+ config,
159
+ dependencies: packageJson.dependencies || {},
160
+ setup,
161
+ mount,
162
+ };
163
+ } catch {
164
+ // Fall back to other methods
165
+ return null;
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Load an image package
171
+ *
172
+ * Priority:
173
+ * 1. Try to resolve locally (require.resolve for installed packages)
174
+ * 2. Fetch from CDN
175
+ *
176
+ * Images must be explicitly installed or available on CDN.
177
+ */
178
+ export async function loadImage(spec: string): Promise<LoadedImage> {
179
+ const { name, version } = parseImageSpec(spec);
180
+
181
+ // Try local resolution first (for installed packages)
182
+ const localImage = await loadLocalImage(name);
183
+ if (localImage) {
184
+ return localImage;
185
+ }
186
+
187
+ // Fetch from CDN
188
+ const packageJson = await fetchPackageJson(name, version);
189
+
190
+ // Validate and extract patchwork config
191
+ const config =
192
+ safeParseImageConfig(packageJson.patchwork) || DEFAULT_IMAGE_CONFIG;
193
+
194
+ // Try to load setup/mount functions if main is specified
195
+ let setup: LoadedImage['setup'];
196
+ let mount: LoadedImage['mount'];
197
+ let moduleUrl: string | undefined;
198
+ if (packageJson.main && typeof window !== 'undefined') {
199
+ try {
200
+ const versionSuffix = version ? `@${version}` : '';
201
+ // Import with explicit main entry path so relative imports resolve correctly
202
+ // Without this, the browser treats the package name as a file and resolves
203
+ // relative imports to the wrong directory
204
+ const mainEntry = packageJson.main.startsWith('./')
205
+ ? packageJson.main.slice(2)
206
+ : packageJson.main;
207
+ const importUrl = `${cdnBaseUrl}/${name}${versionSuffix}/${mainEntry}`;
208
+ moduleUrl = importUrl;
209
+ const imageModule = await import(
210
+ /* @vite-ignore */
211
+ importUrl
212
+ );
213
+ if (typeof imageModule.setup === 'function') {
214
+ setup = imageModule.setup;
215
+ }
216
+ if (typeof imageModule.mount === 'function') {
217
+ mount = imageModule.mount;
218
+ }
219
+ } catch (err) {
220
+ // Setup/mount are optional, but log the error for debugging
221
+ console.error('[patchwork-compiler] Failed to load image module:', err);
222
+ }
223
+ }
224
+
225
+ return {
226
+ name: packageJson.name,
227
+ version: packageJson.version,
228
+ moduleUrl,
229
+ config,
230
+ dependencies: packageJson.dependencies || {},
231
+ setup,
232
+ mount,
233
+ };
234
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Image registry - manages loaded images
3
+ */
4
+
5
+ import type { LoadedImage } from '../types.js';
6
+ import { loadImage, parseImageSpec } from './loader.js';
7
+
8
+ /**
9
+ * Registry of loaded images
10
+ */
11
+ class ImageRegistry {
12
+ private images = new Map<string, LoadedImage>();
13
+ private loading = new Map<string, Promise<LoadedImage>>();
14
+
15
+ /**
16
+ * Get a loaded image by spec
17
+ */
18
+ get(spec: string): LoadedImage | undefined {
19
+ const { name } = parseImageSpec(spec);
20
+ return this.images.get(name);
21
+ }
22
+
23
+ /**
24
+ * Check if an image is loaded
25
+ */
26
+ has(spec: string): boolean {
27
+ const { name } = parseImageSpec(spec);
28
+ return this.images.has(name);
29
+ }
30
+
31
+ /**
32
+ * Load an image (or return cached)
33
+ */
34
+ async load(spec: string): Promise<LoadedImage> {
35
+ const { name } = parseImageSpec(spec);
36
+
37
+ // Return cached
38
+ const cached = this.images.get(name);
39
+ if (cached) {
40
+ return cached;
41
+ }
42
+
43
+ // Return in-progress load
44
+ const inProgress = this.loading.get(name);
45
+ if (inProgress) {
46
+ return inProgress;
47
+ }
48
+
49
+ // Start loading
50
+ const loadPromise = loadImage(spec).then((image) => {
51
+ this.images.set(name, image);
52
+ this.loading.delete(name);
53
+ return image;
54
+ });
55
+
56
+ this.loading.set(name, loadPromise);
57
+ return loadPromise;
58
+ }
59
+
60
+ /**
61
+ * Preload an image
62
+ */
63
+ async preload(spec: string): Promise<void> {
64
+ await this.load(spec);
65
+ }
66
+
67
+ /**
68
+ * Clear a specific image from cache
69
+ */
70
+ clear(spec: string): void {
71
+ const { name } = parseImageSpec(spec);
72
+ this.images.delete(name);
73
+ this.loading.delete(name);
74
+ }
75
+
76
+ /**
77
+ * Clear all cached images
78
+ */
79
+ clearAll(): void {
80
+ this.images.clear();
81
+ this.loading.clear();
82
+ }
83
+
84
+ /**
85
+ * Get all loaded image names
86
+ */
87
+ getLoadedNames(): string[] {
88
+ return Array.from(this.images.keys());
89
+ }
90
+ }
91
+
92
+ // Global singleton registry
93
+ let globalRegistry: ImageRegistry | null = null;
94
+
95
+ /**
96
+ * Get the global image registry
97
+ */
98
+ export function getImageRegistry(): ImageRegistry {
99
+ if (!globalRegistry) {
100
+ globalRegistry = new ImageRegistry();
101
+ }
102
+ return globalRegistry;
103
+ }
104
+
105
+ /**
106
+ * Create a new isolated image registry
107
+ */
108
+ export function createImageRegistry(): ImageRegistry {
109
+ return new ImageRegistry();
110
+ }
111
+
112
+ export { ImageRegistry };
@@ -0,0 +1,141 @@
1
+ /**
2
+ * @aprovan/patchwork-compiler
3
+ *
4
+ * JSX→ESM compilation, image loading, and DOM mounting for Patchwork widgets.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createCompiler } from '@aprovan/patchwork-compiler';
9
+ *
10
+ * const compiler = await createCompiler({
11
+ * image: '@aprovan/patchwork-image-shadcn',
12
+ * proxyUrl: 'http://localhost:3000/api/proxy'
13
+ * });
14
+ *
15
+ * const widget = await compiler.compile(source, manifest);
16
+ * const mounted = await compiler.mount(widget, {
17
+ * target: document.getElementById('root'),
18
+ * mode: 'embedded'
19
+ * });
20
+ *
21
+ * // Later...
22
+ * compiler.unmount(mounted);
23
+ * ```
24
+ */
25
+
26
+ // Core compiler
27
+ export { createCompiler } from './compiler.js';
28
+
29
+ // Schemas (Zod validation)
30
+ export {
31
+ // Schemas
32
+ PlatformSchema,
33
+ EsbuildConfigSchema,
34
+ ImageConfigSchema,
35
+ InputSpecSchema,
36
+ ManifestSchema,
37
+ CompileOptionsSchema,
38
+ MountModeSchema,
39
+ MountOptionsSchema,
40
+ // Parsers
41
+ parseImageConfig,
42
+ safeParseImageConfig,
43
+ parseManifest,
44
+ safeParseManifest,
45
+ // Defaults
46
+ DEFAULT_IMAGE_CONFIG,
47
+ DEFAULT_CLI_IMAGE_CONFIG,
48
+ } from './schemas.js';
49
+
50
+ // Types
51
+ export type {
52
+ // Core types
53
+ Platform,
54
+ Manifest,
55
+ InputSpec,
56
+ CompileOptions,
57
+ CompiledWidget,
58
+ MountMode,
59
+ MountOptions,
60
+ MountedWidget,
61
+ Compiler,
62
+ CompilerOptions,
63
+ // Image types
64
+ ImageConfig,
65
+ ImageMountFn,
66
+ LoadedImage,
67
+ // Service types
68
+ ServiceProxy,
69
+ ServiceCallHandler,
70
+ GlobalInterfaceDefinition,
71
+ BridgeMessage,
72
+ BridgeMessageType,
73
+ ServiceCallPayload,
74
+ ServiceResultPayload,
75
+ } from './types.js';
76
+
77
+ // Images
78
+ export {
79
+ // Registry
80
+ ImageRegistry,
81
+ getImageRegistry,
82
+ createImageRegistry,
83
+ // Loader
84
+ loadImage,
85
+ parseImageSpec,
86
+ fetchPackageJson,
87
+ setCdnBaseUrl,
88
+ getCdnBaseUrl,
89
+ } from './images/index.js';
90
+
91
+ // Transforms
92
+ export {
93
+ cdnTransformPlugin,
94
+ generateImportMap,
95
+ vfsPlugin,
96
+ } from './transforms/index.js';
97
+ export type {
98
+ CdnTransformOptions,
99
+ VFSPluginOptions,
100
+ } from './transforms/index.js';
101
+
102
+ // VFS
103
+ export {
104
+ VFSStore,
105
+ createProjectFromFiles,
106
+ createSingleFileProject,
107
+ resolveEntry,
108
+ detectMainFile,
109
+ IndexedDBBackend,
110
+ LocalFSBackend,
111
+ S3Backend,
112
+ } from './vfs/index.js';
113
+ export type {
114
+ VirtualFile,
115
+ VirtualProject,
116
+ StorageBackend,
117
+ LocalFSConfig,
118
+ S3Config,
119
+ } from './vfs/index.js';
120
+
121
+ // Mount utilities
122
+ export {
123
+ // Embedded
124
+ mountEmbedded,
125
+ reloadEmbedded,
126
+ // Iframe
127
+ mountIframe,
128
+ reloadIframe,
129
+ disposeIframeBridge,
130
+ DEV_SANDBOX,
131
+ // Bridge
132
+ createHttpServiceProxy,
133
+ createFieldAccessProxy,
134
+ generateNamespaceGlobals,
135
+ injectNamespaceGlobals,
136
+ removeNamespaceGlobals,
137
+ extractNamespaces,
138
+ ParentBridge,
139
+ createIframeServiceProxy,
140
+ generateIframeBridgeScript,
141
+ } from './mount/index.js';