sandlot 0.1.2 → 0.1.4
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/README.md +138 -408
- package/dist/build-emitter.d.ts +31 -13
- package/dist/build-emitter.d.ts.map +1 -1
- package/dist/builder.d.ts +370 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/bundler.d.ts +6 -2
- package/dist/bundler.d.ts.map +1 -1
- package/dist/commands/compile.d.ts +13 -0
- package/dist/commands/compile.d.ts.map +1 -0
- package/dist/commands/index.d.ts +17 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/packages.d.ts +17 -0
- package/dist/commands/packages.d.ts.map +1 -0
- package/dist/commands/run.d.ts +40 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/types.d.ts +141 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/fs.d.ts +53 -49
- package/dist/fs.d.ts.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +300 -511
- package/dist/internal.js +161 -171
- package/dist/runner.d.ts +314 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/sandbox-manager.d.ts +45 -21
- package/dist/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox.d.ts +144 -62
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/shared-modules.d.ts +22 -3
- package/dist/shared-modules.d.ts.map +1 -1
- package/dist/shared-resources.d.ts +0 -3
- package/dist/shared-resources.d.ts.map +1 -1
- package/dist/ts-libs.d.ts +7 -20
- package/dist/ts-libs.d.ts.map +1 -1
- package/dist/typechecker.d.ts +1 -1
- package/package.json +5 -5
- package/src/build-emitter.ts +32 -29
- package/src/builder.ts +498 -0
- package/src/bundler.ts +76 -55
- package/src/commands/compile.ts +236 -0
- package/src/commands/index.ts +51 -0
- package/src/commands/packages.ts +154 -0
- package/src/commands/run.ts +245 -0
- package/src/commands/types.ts +172 -0
- package/src/fs.ts +82 -221
- package/src/index.ts +17 -12
- package/src/sandbox.ts +219 -149
- package/src/shared-modules.ts +74 -4
- package/src/shared-resources.ts +0 -3
- package/src/ts-libs.ts +19 -121
- package/src/typechecker.ts +1 -1
- package/dist/react.d.ts +0 -159
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js +0 -149
- package/src/commands.ts +0 -733
- package/src/sandbox-manager.ts +0 -409
package/src/ts-libs.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* TypeScript standard library fetcher and cache.
|
|
3
3
|
*
|
|
4
4
|
* Fetches TypeScript's lib.*.d.ts files from jsDelivr CDN and caches
|
|
5
|
-
* them in
|
|
6
|
-
*
|
|
5
|
+
* them in memory. These files provide types for built-in JavaScript APIs
|
|
6
|
+
* (Array, Number, String) and browser APIs (console, window, document).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -17,13 +17,6 @@ const TS_VERSION = "5.9.3";
|
|
|
17
17
|
*/
|
|
18
18
|
const CDN_BASE = `https://cdn.jsdelivr.net/npm/typescript@${TS_VERSION}/lib`;
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* IndexedDB database name for lib cache
|
|
22
|
-
*/
|
|
23
|
-
const DB_NAME = "ts-lib-cache";
|
|
24
|
-
const DB_VERSION = 1;
|
|
25
|
-
const STORE_NAME = "libs";
|
|
26
|
-
|
|
27
20
|
/**
|
|
28
21
|
* Default libs for browser environment with ES2020 target.
|
|
29
22
|
* These provide types for console, DOM APIs, and modern JS features.
|
|
@@ -145,74 +138,21 @@ export async function fetchAllLibs(libs: string[]): Promise<Map<string, string>>
|
|
|
145
138
|
}
|
|
146
139
|
|
|
147
140
|
/**
|
|
148
|
-
*
|
|
149
|
-
|
|
150
|
-
async function openDatabase(): Promise<IDBDatabase> {
|
|
151
|
-
return new Promise((resolve, reject) => {
|
|
152
|
-
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
153
|
-
|
|
154
|
-
request.onerror = () => reject(request.error);
|
|
155
|
-
request.onsuccess = () => resolve(request.result);
|
|
156
|
-
|
|
157
|
-
request.onupgradeneeded = (event) => {
|
|
158
|
-
const db = (event.target as IDBOpenDBRequest).result;
|
|
159
|
-
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
160
|
-
db.createObjectStore(STORE_NAME);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Promisify an IDBRequest
|
|
141
|
+
* In-memory cache for TypeScript lib files.
|
|
142
|
+
* Shared across all LibCache instances.
|
|
168
143
|
*/
|
|
169
|
-
|
|
170
|
-
return new Promise((resolve, reject) => {
|
|
171
|
-
request.onsuccess = () => resolve(request.result);
|
|
172
|
-
request.onerror = () => reject(request.error);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Cache key for the current TypeScript version
|
|
178
|
-
*/
|
|
179
|
-
function getCacheKey(): string {
|
|
180
|
-
return `libs-${TS_VERSION}`;
|
|
181
|
-
}
|
|
144
|
+
let memoryCache: Map<string, string> | null = null;
|
|
182
145
|
|
|
183
146
|
/**
|
|
184
|
-
*
|
|
185
|
-
*/
|
|
186
|
-
interface CachedLibs {
|
|
187
|
-
version: string;
|
|
188
|
-
timestamp: number;
|
|
189
|
-
libs: Record<string, string>;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* LibCache provides IndexedDB-backed caching for TypeScript lib files.
|
|
147
|
+
* LibCache provides in-memory caching for TypeScript lib files.
|
|
194
148
|
*
|
|
195
149
|
* Usage:
|
|
196
150
|
* ```ts
|
|
197
|
-
* const cache =
|
|
151
|
+
* const cache = new LibCache();
|
|
198
152
|
* const libs = await cache.getOrFetch(getDefaultBrowserLibs());
|
|
199
153
|
* ```
|
|
200
154
|
*/
|
|
201
155
|
export class LibCache {
|
|
202
|
-
private db: IDBDatabase;
|
|
203
|
-
|
|
204
|
-
private constructor(db: IDBDatabase) {
|
|
205
|
-
this.db = db;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Create and initialize a LibCache instance.
|
|
210
|
-
*/
|
|
211
|
-
static async create(): Promise<LibCache> {
|
|
212
|
-
const db = await openDatabase();
|
|
213
|
-
return new LibCache(db);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
156
|
/**
|
|
217
157
|
* Get cached libs if available, otherwise fetch from CDN and cache.
|
|
218
158
|
*
|
|
@@ -221,12 +161,11 @@ export class LibCache {
|
|
|
221
161
|
*/
|
|
222
162
|
async getOrFetch(libs: string[]): Promise<Map<string, string>> {
|
|
223
163
|
// Try to get from cache first
|
|
224
|
-
|
|
225
|
-
if (cached) {
|
|
164
|
+
if (memoryCache) {
|
|
226
165
|
// Verify all requested libs are in cache
|
|
227
|
-
const missing = libs.filter((lib) => !
|
|
166
|
+
const missing = libs.filter((lib) => !memoryCache!.has(lib));
|
|
228
167
|
if (missing.length === 0) {
|
|
229
|
-
return
|
|
168
|
+
return memoryCache;
|
|
230
169
|
}
|
|
231
170
|
// Some libs missing, fetch all and update cache
|
|
232
171
|
console.log(`Cache missing libs: ${missing.join(", ")}, fetching all...`);
|
|
@@ -238,7 +177,7 @@ export class LibCache {
|
|
|
238
177
|
console.log(`Fetched ${fetched.size} lib files`);
|
|
239
178
|
|
|
240
179
|
// Cache the results
|
|
241
|
-
|
|
180
|
+
memoryCache = fetched;
|
|
242
181
|
|
|
243
182
|
return fetched;
|
|
244
183
|
}
|
|
@@ -246,64 +185,27 @@ export class LibCache {
|
|
|
246
185
|
/**
|
|
247
186
|
* Get cached libs if available.
|
|
248
187
|
*/
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const store = tx.objectStore(STORE_NAME);
|
|
252
|
-
const key = getCacheKey();
|
|
253
|
-
|
|
254
|
-
const cached = await promisifyRequest<CachedLibs | undefined>(store.get(key));
|
|
255
|
-
if (!cached) {
|
|
256
|
-
return null;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Verify version matches
|
|
260
|
-
if (cached.version !== TS_VERSION) {
|
|
261
|
-
console.log(`Cache version mismatch: ${cached.version} vs ${TS_VERSION}`);
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return new Map(Object.entries(cached.libs));
|
|
188
|
+
get(): Map<string, string> | null {
|
|
189
|
+
return memoryCache;
|
|
266
190
|
}
|
|
267
191
|
|
|
268
192
|
/**
|
|
269
193
|
* Store libs in the cache.
|
|
270
194
|
*/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const store = tx.objectStore(STORE_NAME);
|
|
274
|
-
const key = getCacheKey();
|
|
275
|
-
|
|
276
|
-
const cached: CachedLibs = {
|
|
277
|
-
version: TS_VERSION,
|
|
278
|
-
timestamp: Date.now(),
|
|
279
|
-
libs: Object.fromEntries(libs),
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
await promisifyRequest(store.put(cached, key));
|
|
195
|
+
set(libs: Map<string, string>): void {
|
|
196
|
+
memoryCache = libs;
|
|
283
197
|
}
|
|
284
198
|
|
|
285
199
|
/**
|
|
286
200
|
* Clear all cached libs.
|
|
287
201
|
*/
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
const store = tx.objectStore(STORE_NAME);
|
|
291
|
-
await promisifyRequest(store.clear());
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Close the database connection.
|
|
296
|
-
*/
|
|
297
|
-
close(): void {
|
|
298
|
-
this.db.close();
|
|
202
|
+
clear(): void {
|
|
203
|
+
memoryCache = null;
|
|
299
204
|
}
|
|
300
205
|
}
|
|
301
206
|
|
|
302
207
|
/**
|
|
303
208
|
* Convenience function to fetch and cache libs in one call.
|
|
304
|
-
* Creates a temporary LibCache, fetches libs, and returns the result.
|
|
305
|
-
*
|
|
306
|
-
* For repeated use, prefer creating a LibCache instance directly.
|
|
307
209
|
*
|
|
308
210
|
* @param libs - Lib names to fetch (defaults to getDefaultBrowserLibs())
|
|
309
211
|
* @returns Map of lib name to content
|
|
@@ -311,10 +213,6 @@ export class LibCache {
|
|
|
311
213
|
export async function fetchAndCacheLibs(
|
|
312
214
|
libs: string[] = getDefaultBrowserLibs()
|
|
313
215
|
): Promise<Map<string, string>> {
|
|
314
|
-
const cache =
|
|
315
|
-
|
|
316
|
-
return await cache.getOrFetch(libs);
|
|
317
|
-
} finally {
|
|
318
|
-
cache.close();
|
|
319
|
-
}
|
|
216
|
+
const cache = new LibCache();
|
|
217
|
+
return cache.getOrFetch(libs);
|
|
320
218
|
}
|
package/src/typechecker.ts
CHANGED
package/dist/react.d.ts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* React-specific helpers for Sandlot
|
|
3
|
-
*
|
|
4
|
-
* These helpers simplify working with dynamically loaded React components,
|
|
5
|
-
* particularly when using the render function pattern for isolation.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```tsx
|
|
9
|
-
* import { DynamicMount } from 'sandlot/react';
|
|
10
|
-
*
|
|
11
|
-
* function App() {
|
|
12
|
-
* const [module, setModule] = useState(null);
|
|
13
|
-
*
|
|
14
|
-
* return (
|
|
15
|
-
* <DynamicMount
|
|
16
|
-
* module={module}
|
|
17
|
-
* props={{ name: "World" }}
|
|
18
|
-
* fallback={<div>Loading...</div>}
|
|
19
|
-
* />
|
|
20
|
-
* );
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
import { type ReactElement, type RefObject, type CSSProperties } from "react";
|
|
25
|
-
/**
|
|
26
|
-
* Interface for dynamic modules that use the render function pattern.
|
|
27
|
-
* Dynamic components should export a `render` function that mounts
|
|
28
|
-
* the component into a container and returns a cleanup function.
|
|
29
|
-
*/
|
|
30
|
-
export interface DynamicRenderModule<P = Record<string, unknown>> {
|
|
31
|
-
/**
|
|
32
|
-
* Mount the component into a container element
|
|
33
|
-
*
|
|
34
|
-
* @param container - The DOM element to render into
|
|
35
|
-
* @param props - Props to pass to the component
|
|
36
|
-
* @returns A cleanup function to unmount the component
|
|
37
|
-
*/
|
|
38
|
-
render: (container: HTMLElement, props?: P) => (() => void) | void;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Props for the DynamicMount component
|
|
42
|
-
*/
|
|
43
|
-
export interface DynamicMountProps<P = Record<string, unknown>> {
|
|
44
|
-
/** The loaded dynamic module with a render function */
|
|
45
|
-
module: DynamicRenderModule<P> | null | undefined;
|
|
46
|
-
/** Props to pass to the dynamic component */
|
|
47
|
-
props?: P;
|
|
48
|
-
/** Optional className for the container div */
|
|
49
|
-
className?: string;
|
|
50
|
-
/** Optional style for the container div */
|
|
51
|
-
style?: CSSProperties;
|
|
52
|
-
/** Optional id for the container div */
|
|
53
|
-
id?: string;
|
|
54
|
-
/** Content to render while module is loading (null/undefined) */
|
|
55
|
-
fallback?: ReactElement | null;
|
|
56
|
-
/** Called when the dynamic component mounts */
|
|
57
|
-
onMount?: () => void;
|
|
58
|
-
/** Called when the dynamic component unmounts */
|
|
59
|
-
onUnmount?: () => void;
|
|
60
|
-
/** Called if rendering fails */
|
|
61
|
-
onError?: (error: Error) => void;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Component that mounts a dynamic module's render function into a container.
|
|
65
|
-
* Handles cleanup automatically when the module changes or unmounts.
|
|
66
|
-
*
|
|
67
|
-
* This is the recommended way to render dynamically loaded components
|
|
68
|
-
* that use the render function pattern for React instance isolation.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```tsx
|
|
72
|
-
* import { DynamicMount } from 'sandlot/react';
|
|
73
|
-
* import { loadModule } from 'sandlot';
|
|
74
|
-
*
|
|
75
|
-
* function App() {
|
|
76
|
-
* const [module, setModule] = useState(null);
|
|
77
|
-
*
|
|
78
|
-
* const loadComponent = async (buildResult: BundleResult) => {
|
|
79
|
-
* const mod = await loadModule(buildResult);
|
|
80
|
-
* setModule(mod);
|
|
81
|
-
* };
|
|
82
|
-
*
|
|
83
|
-
* return (
|
|
84
|
-
* <div>
|
|
85
|
-
* <button onClick={loadComponent}>Load</button>
|
|
86
|
-
* <DynamicMount
|
|
87
|
-
* module={module}
|
|
88
|
-
* props={{ count: 5 }}
|
|
89
|
-
* fallback={<div>Click to load...</div>}
|
|
90
|
-
* className="dynamic-container"
|
|
91
|
-
* />
|
|
92
|
-
* </div>
|
|
93
|
-
* );
|
|
94
|
-
* }
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
export declare function DynamicMount<P = Record<string, unknown>>({ module, props, className, style, id, fallback, onMount, onUnmount, onError, }: DynamicMountProps<P>): ReactElement | null;
|
|
98
|
-
/**
|
|
99
|
-
* Result returned by useDynamicComponent hook
|
|
100
|
-
*/
|
|
101
|
-
export interface UseDynamicComponentResult {
|
|
102
|
-
/** Ref to attach to the container element */
|
|
103
|
-
containerRef: RefObject<HTMLDivElement | null>;
|
|
104
|
-
/** Whether the component is currently mounted */
|
|
105
|
-
isMounted: boolean;
|
|
106
|
-
/** Any error that occurred during mounting */
|
|
107
|
-
error: Error | null;
|
|
108
|
-
/** Manually trigger a re-render with new props */
|
|
109
|
-
update: (props?: Record<string, unknown>) => void;
|
|
110
|
-
/** Manually unmount the component */
|
|
111
|
-
unmount: () => void;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Hook for mounting dynamic modules with more control than DynamicMount.
|
|
115
|
-
* Provides access to mount state and manual control over mounting/unmounting.
|
|
116
|
-
*
|
|
117
|
-
* @param module - The dynamic module to mount
|
|
118
|
-
* @param props - Props to pass to the component
|
|
119
|
-
* @returns Object with containerRef, state, and control functions
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* ```tsx
|
|
123
|
-
* import { useDynamicComponent } from 'sandlot/react';
|
|
124
|
-
*
|
|
125
|
-
* function App() {
|
|
126
|
-
* const { containerRef, isMounted, error, unmount } = useDynamicComponent(
|
|
127
|
-
* module,
|
|
128
|
-
* { initialCount: 0 }
|
|
129
|
-
* );
|
|
130
|
-
*
|
|
131
|
-
* return (
|
|
132
|
-
* <div>
|
|
133
|
-
* <div ref={containerRef} />
|
|
134
|
-
* {isMounted && <button onClick={unmount}>Remove</button>}
|
|
135
|
-
* {error && <div>Error: {error.message}</div>}
|
|
136
|
-
* </div>
|
|
137
|
-
* );
|
|
138
|
-
* }
|
|
139
|
-
* ```
|
|
140
|
-
*/
|
|
141
|
-
export declare function useDynamicComponent<P = Record<string, unknown>>(module: DynamicRenderModule<P> | null | undefined, props?: P): UseDynamicComponentResult;
|
|
142
|
-
/**
|
|
143
|
-
* Code template for a React component's render function.
|
|
144
|
-
* This is the pattern dynamic components should follow when using
|
|
145
|
-
* the render function pattern for React instance isolation.
|
|
146
|
-
*
|
|
147
|
-
* Dynamic components import React from esm.sh and use their own
|
|
148
|
-
* ReactDOM.createRoot to mount, avoiding conflicts with the host's React.
|
|
149
|
-
*/
|
|
150
|
-
export declare const REACT_RENDER_TEMPLATE: string;
|
|
151
|
-
/**
|
|
152
|
-
* Generate render function code for a given component name.
|
|
153
|
-
* Useful for code generation tools or agents.
|
|
154
|
-
*
|
|
155
|
-
* @param componentName - The name of the component to wrap
|
|
156
|
-
* @param hasProps - Whether the component accepts props
|
|
157
|
-
*/
|
|
158
|
-
export declare function generateRenderFunction(componentName: string, hasProps?: boolean): string;
|
|
159
|
-
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAEf;;;;GAIG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9D;;;;;;OAMG;IACH,MAAM,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;CACpE;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,uDAAuD;IACvD,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD,6CAA6C;IAC7C,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wCAAwC;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,QAAQ,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,gCAAgC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACxD,MAAM,EACN,KAAK,EACL,SAAS,EACT,KAAK,EACL,EAAE,EACF,QAAe,EACf,OAAO,EACP,SAAS,EACT,OAAO,GACR,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI,CA4D5C;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,6CAA6C;IAC7C,YAAY,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC/C,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,kDAAkD;IAClD,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAClD,qCAAqC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7D,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EACjD,KAAK,CAAC,EAAE,CAAC,GACR,yBAAyB,CA8C3B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,QAe1B,CAAC;AAET;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,QAAQ,UAAO,GACd,MAAM,CAoBR"}
|
package/dist/react.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
// src/react.tsx
|
|
2
|
-
import {
|
|
3
|
-
useRef,
|
|
4
|
-
useEffect,
|
|
5
|
-
useCallback,
|
|
6
|
-
useState
|
|
7
|
-
} from "react";
|
|
8
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
9
|
-
function DynamicMount({
|
|
10
|
-
module,
|
|
11
|
-
props,
|
|
12
|
-
className,
|
|
13
|
-
style,
|
|
14
|
-
id,
|
|
15
|
-
fallback = null,
|
|
16
|
-
onMount,
|
|
17
|
-
onUnmount,
|
|
18
|
-
onError
|
|
19
|
-
}) {
|
|
20
|
-
const containerRef = useRef(null);
|
|
21
|
-
const cleanupRef = useRef(null);
|
|
22
|
-
const [error, setError] = useState(null);
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (!module || !containerRef.current)
|
|
25
|
-
return;
|
|
26
|
-
try {
|
|
27
|
-
if (cleanupRef.current) {
|
|
28
|
-
cleanupRef.current();
|
|
29
|
-
cleanupRef.current = null;
|
|
30
|
-
onUnmount?.();
|
|
31
|
-
}
|
|
32
|
-
setError(null);
|
|
33
|
-
const cleanup = module.render(containerRef.current, props);
|
|
34
|
-
cleanupRef.current = cleanup ?? null;
|
|
35
|
-
onMount?.();
|
|
36
|
-
} catch (err) {
|
|
37
|
-
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
38
|
-
setError(error2);
|
|
39
|
-
onError?.(error2);
|
|
40
|
-
}
|
|
41
|
-
return () => {
|
|
42
|
-
if (cleanupRef.current) {
|
|
43
|
-
cleanupRef.current();
|
|
44
|
-
cleanupRef.current = null;
|
|
45
|
-
onUnmount?.();
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}, [module, props, onMount, onUnmount, onError]);
|
|
49
|
-
if (!module) {
|
|
50
|
-
return fallback;
|
|
51
|
-
}
|
|
52
|
-
if (error) {
|
|
53
|
-
return /* @__PURE__ */ jsxDEV("div", {
|
|
54
|
-
style: {
|
|
55
|
-
color: "red",
|
|
56
|
-
padding: "8px",
|
|
57
|
-
border: "1px solid red",
|
|
58
|
-
borderRadius: "4px"
|
|
59
|
-
},
|
|
60
|
-
children: [
|
|
61
|
-
"Failed to render dynamic component: ",
|
|
62
|
-
error.message
|
|
63
|
-
]
|
|
64
|
-
}, undefined, true, undefined, this);
|
|
65
|
-
}
|
|
66
|
-
return /* @__PURE__ */ jsxDEV("div", {
|
|
67
|
-
ref: containerRef,
|
|
68
|
-
className,
|
|
69
|
-
style,
|
|
70
|
-
id
|
|
71
|
-
}, undefined, false, undefined, this);
|
|
72
|
-
}
|
|
73
|
-
function useDynamicComponent(module, props) {
|
|
74
|
-
const containerRef = useRef(null);
|
|
75
|
-
const cleanupRef = useRef(null);
|
|
76
|
-
const propsRef = useRef(props);
|
|
77
|
-
const [isMounted, setIsMounted] = useState(false);
|
|
78
|
-
const [error, setError] = useState(null);
|
|
79
|
-
propsRef.current = props;
|
|
80
|
-
const unmount = useCallback(() => {
|
|
81
|
-
if (cleanupRef.current) {
|
|
82
|
-
cleanupRef.current();
|
|
83
|
-
cleanupRef.current = null;
|
|
84
|
-
}
|
|
85
|
-
setIsMounted(false);
|
|
86
|
-
}, []);
|
|
87
|
-
const update = useCallback((newProps) => {
|
|
88
|
-
if (!module || !containerRef.current)
|
|
89
|
-
return;
|
|
90
|
-
try {
|
|
91
|
-
unmount();
|
|
92
|
-
setError(null);
|
|
93
|
-
const cleanup = module.render(containerRef.current, newProps ?? propsRef.current);
|
|
94
|
-
cleanupRef.current = cleanup ?? null;
|
|
95
|
-
setIsMounted(true);
|
|
96
|
-
} catch (err) {
|
|
97
|
-
setError(err instanceof Error ? err : new Error(String(err)));
|
|
98
|
-
}
|
|
99
|
-
}, [module, unmount]);
|
|
100
|
-
useEffect(() => {
|
|
101
|
-
if (module && containerRef.current) {
|
|
102
|
-
update(props);
|
|
103
|
-
}
|
|
104
|
-
return unmount;
|
|
105
|
-
}, [module, props, update, unmount]);
|
|
106
|
-
return { containerRef, isMounted, error, update, unmount };
|
|
107
|
-
}
|
|
108
|
-
var REACT_RENDER_TEMPLATE = `
|
|
109
|
-
import React from "react";
|
|
110
|
-
import { createRoot } from "react-dom/client";
|
|
111
|
-
|
|
112
|
-
// Your component here
|
|
113
|
-
function MyComponent(props) {
|
|
114
|
-
return <div>Hello {props.name}</div>;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Export a render function that mounts using esm.sh's ReactDOM
|
|
118
|
-
export function render(container, props) {
|
|
119
|
-
const root = createRoot(container);
|
|
120
|
-
root.render(<MyComponent {...props} />);
|
|
121
|
-
return () => root.unmount();
|
|
122
|
-
}
|
|
123
|
-
`.trim();
|
|
124
|
-
function generateRenderFunction(componentName, hasProps = true) {
|
|
125
|
-
if (hasProps) {
|
|
126
|
-
return `
|
|
127
|
-
// Export a render function that mounts using esm.sh's ReactDOM
|
|
128
|
-
export function render(container: HTMLElement, props?: Parameters<typeof ${componentName}>[0]) {
|
|
129
|
-
const root = createRoot(container);
|
|
130
|
-
root.render(<${componentName} {...props} />);
|
|
131
|
-
return () => root.unmount();
|
|
132
|
-
}
|
|
133
|
-
`.trim();
|
|
134
|
-
}
|
|
135
|
-
return `
|
|
136
|
-
// Export a render function that mounts using esm.sh's ReactDOM
|
|
137
|
-
export function render(container: HTMLElement) {
|
|
138
|
-
const root = createRoot(container);
|
|
139
|
-
root.render(<${componentName} />);
|
|
140
|
-
return () => root.unmount();
|
|
141
|
-
}
|
|
142
|
-
`.trim();
|
|
143
|
-
}
|
|
144
|
-
export {
|
|
145
|
-
useDynamicComponent,
|
|
146
|
-
generateRenderFunction,
|
|
147
|
-
REACT_RENDER_TEMPLATE,
|
|
148
|
-
DynamicMount
|
|
149
|
-
};
|