dynim-react 1.0.120 → 1.0.123
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/DynimProvider.d.ts +2 -23
- package/dist/DynimProvider.d.ts.map +1 -1
- package/dist/DynimProvider.js +119 -158
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/DynimProvider.d.ts
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DynimProvider -
|
|
2
|
+
* DynimProvider - Bundle renderer and shared context provider
|
|
3
3
|
*
|
|
4
4
|
* Handles:
|
|
5
5
|
* - Loading tenant bundles
|
|
6
|
-
* -
|
|
6
|
+
* - Delegating builder operations to standalone script (window.dynim)
|
|
7
7
|
* - Shared context for bundles to access React, packages, etc.
|
|
8
8
|
*/
|
|
9
9
|
import { type ReactNode } from 'react';
|
|
10
|
-
import type { CodeMessage, Checkpoint, RestoreResult } from 'dynim-core';
|
|
11
10
|
/**
|
|
12
11
|
* Returns the current session token. Works from plain JS (no hooks needed).
|
|
13
12
|
* Used by generated API clients to authenticate requests to the clientserver.
|
|
14
13
|
*/
|
|
15
14
|
export declare function getSessionToken(): Promise<string | null>;
|
|
16
15
|
export interface DynimConfig {
|
|
17
|
-
/** Function to fetch a session token for authentication */
|
|
18
|
-
getSession?: () => Promise<{
|
|
19
|
-
token: string;
|
|
20
|
-
refreshToken?: string;
|
|
21
|
-
cssVersion?: string | null;
|
|
22
|
-
}>;
|
|
23
16
|
/** Called when an error occurs */
|
|
24
17
|
onError?: (error: Event | Error) => void;
|
|
25
18
|
/** NPM packages to expose to bundles (e.g., { 'react-router-dom': ReactRouterDOM }) */
|
|
@@ -36,20 +29,6 @@ export interface DynimContextValue {
|
|
|
36
29
|
exitBuilder: () => void;
|
|
37
30
|
/** Whether builder/edit mode is active */
|
|
38
31
|
isEditing: boolean;
|
|
39
|
-
/** Send a code edit request to AI */
|
|
40
|
-
sendCode: (query: string) => Promise<void>;
|
|
41
|
-
/** Save current edits */
|
|
42
|
-
saveCode: () => Promise<void>;
|
|
43
|
-
/** Abandon/discard current edits */
|
|
44
|
-
abandonCode: () => Promise<void>;
|
|
45
|
-
/** Get active checkpoints for the project */
|
|
46
|
-
getCheckpoints: () => Promise<Checkpoint[]>;
|
|
47
|
-
/** Restore to a specific checkpoint (reloads bundle on success) */
|
|
48
|
-
restoreCheckpoint: (checkpointId: string) => Promise<RestoreResult>;
|
|
49
|
-
/** Whether a checkpoint restore is in progress */
|
|
50
|
-
isRestoring: boolean;
|
|
51
|
-
/** Current code message state (thinking, edits, etc.) */
|
|
52
|
-
codeMessage: CodeMessage;
|
|
53
32
|
/** Whether a bundle is currently loaded */
|
|
54
33
|
isBundleLoaded: boolean;
|
|
55
34
|
/** Whether bundle is loading */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DynimProvider.d.ts","sourceRoot":"","sources":["../src/DynimProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAc,EASZ,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DynimProvider.d.ts","sourceRoot":"","sources":["../src/DynimProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAc,EASZ,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAoBf;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAG9D;AA6ED,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,KAAK,IAAI,CAAC;IACzC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,qBAAqB;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,cAAc,EAAE,OAAO,CAAC;IACxB,gCAAgC;IAChC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,MAAW,GACZ,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,CAsalC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C"}
|
package/dist/DynimProvider.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* DynimProvider -
|
|
3
|
+
* DynimProvider - Bundle renderer and shared context provider
|
|
4
4
|
*
|
|
5
5
|
* Handles:
|
|
6
6
|
* - Loading tenant bundles
|
|
7
|
-
* -
|
|
7
|
+
* - Delegating builder operations to standalone script (window.dynim)
|
|
8
8
|
* - Shared context for bundles to access React, packages, etc.
|
|
9
9
|
*/
|
|
10
10
|
import React, { createContext, useContext, useEffect, useRef, useCallback, useMemo, useState, Component, } from 'react';
|
|
11
11
|
import ReactDOM from 'react-dom';
|
|
12
|
-
import {
|
|
12
|
+
import { createCodeClient, createBundleLoader, createCSSLoader, BundleNotFoundError, BundleAuthError, } from 'dynim-core';
|
|
13
13
|
import { createSharedContext, updateSharedContext, isSharedContextReady } from './inference/sharedContext';
|
|
14
14
|
import { generateThemeCSS } from './theme';
|
|
15
15
|
// Module-level token resolver — set by DynimProvider on mount.
|
|
@@ -74,34 +74,30 @@ const DynimContext = createContext(null);
|
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
76
|
export function DynimProvider({ children, config = {}, }) {
|
|
77
|
-
const builderRef = useRef(null);
|
|
78
77
|
const codeClientRef = useRef(null);
|
|
79
78
|
const bundleLoaderRef = useRef(null);
|
|
80
79
|
const cssLoaderRef = useRef(null);
|
|
81
|
-
// Track when we're exiting to prevent auto-load from re-triggering
|
|
82
|
-
const isExitingRef = useRef(false);
|
|
83
80
|
const hasAttemptedInitialLoadRef = useRef(false);
|
|
84
|
-
|
|
81
|
+
// Delegate session management to the standalone SDK (window.dynim).
|
|
82
|
+
// The standalone script owns auth via identify() → HMAC → session token.
|
|
83
|
+
const getSessionRef = useRef(() => {
|
|
84
|
+
const dynim = window.dynim;
|
|
85
|
+
if (dynim?.getSession) {
|
|
86
|
+
return dynim.getSession();
|
|
87
|
+
}
|
|
88
|
+
return Promise.resolve(null);
|
|
89
|
+
});
|
|
85
90
|
const [isEditing, setIsEditing] = useState(false);
|
|
86
91
|
const [isBundleLoaded, setIsBundleLoaded] = useState(false);
|
|
87
92
|
const [isBundleLoading, setIsBundleLoading] = useState(false);
|
|
88
93
|
const [isInitialLoadComplete, setIsInitialLoadComplete] = useState(false);
|
|
89
94
|
const [TenantApp, setTenantApp] = useState(null);
|
|
90
95
|
const [bundleError, setBundleError] = useState(null);
|
|
91
|
-
const [isRestoring, setIsRestoring] = useState(false);
|
|
92
|
-
const [codeMessage, setCodeMessage] = useState({
|
|
93
|
-
thinking: '',
|
|
94
|
-
text: '',
|
|
95
|
-
status: 'idle',
|
|
96
|
-
bundleReady: false,
|
|
97
|
-
bundleError: undefined,
|
|
98
|
-
});
|
|
99
96
|
// Cached auth token
|
|
100
97
|
const cachedTokenRef = useRef(null);
|
|
101
98
|
const tokenPromiseRef = useRef(null);
|
|
102
|
-
// Bundle
|
|
103
|
-
const [
|
|
104
|
-
const pendingBundleProjectIdRef = useRef(null);
|
|
99
|
+
// Bundle reset counter (incremented when loadBundle succeeds)
|
|
100
|
+
const [bundleResetKey, setBundleResetKey] = useState(0);
|
|
105
101
|
// Theme state (fetched from API per project)
|
|
106
102
|
const [theme, setTheme] = useState(null);
|
|
107
103
|
const hasAttemptedThemeLoadRef = useRef(false);
|
|
@@ -137,7 +133,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
137
133
|
// Get auth token (cached after first call).
|
|
138
134
|
// Also registered as the module-level resolver so non-React code (API clients) can call getSessionToken().
|
|
139
135
|
const getAuthToken = useCallback(async () => {
|
|
140
|
-
const
|
|
136
|
+
const getSession = getSessionRef.current;
|
|
141
137
|
// Return cached token if available
|
|
142
138
|
if (cachedTokenRef.current)
|
|
143
139
|
return cachedTokenRef.current;
|
|
@@ -148,6 +144,8 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
148
144
|
tokenPromiseRef.current = (async () => {
|
|
149
145
|
try {
|
|
150
146
|
const session = await getSession();
|
|
147
|
+
if (!session)
|
|
148
|
+
return null;
|
|
151
149
|
cachedTokenRef.current = session.token;
|
|
152
150
|
// Sync token and CSS version to code-client (bundleLoader uses this getAuthToken,
|
|
153
151
|
// not code-client's internal getValidToken, so we need to sync both here)
|
|
@@ -177,51 +175,78 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
177
175
|
}, [getAuthToken]);
|
|
178
176
|
// Initialize code client (only once on mount)
|
|
179
177
|
useEffect(() => {
|
|
180
|
-
const { getSession, onError } = configRef.current;
|
|
181
178
|
codeClientRef.current = createCodeClient({
|
|
182
|
-
getSession
|
|
183
|
-
|
|
179
|
+
getSession: async () => {
|
|
180
|
+
const session = await getSessionRef.current?.();
|
|
181
|
+
if (!session)
|
|
182
|
+
throw new Error('Not authenticated');
|
|
183
|
+
return session;
|
|
184
|
+
},
|
|
184
185
|
onError: (error) => {
|
|
185
186
|
console.error('[DynimProvider] Code error:', error);
|
|
186
187
|
configRef.current.onError?.(error);
|
|
187
188
|
},
|
|
188
189
|
});
|
|
190
|
+
// Sync token when standalone SDK authenticates
|
|
191
|
+
const onIdentified = async () => {
|
|
192
|
+
const session = await getSessionRef.current?.();
|
|
193
|
+
if (session && codeClientRef.current) {
|
|
194
|
+
codeClientRef.current.setSessionToken(session.token, session.refreshToken);
|
|
195
|
+
if (session.cssVersion !== undefined) {
|
|
196
|
+
codeClientRef.current.setCSSVersion(session.cssVersion ?? null);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
window.addEventListener('dynim:identified', onIdentified);
|
|
201
|
+
return () => window.removeEventListener('dynim:identified', onIdentified);
|
|
189
202
|
}, []);
|
|
190
203
|
// Load bundle ref
|
|
191
204
|
const loadBundleRef = useRef(null);
|
|
192
|
-
//
|
|
205
|
+
// Clean up CSS link element on unmount
|
|
193
206
|
useEffect(() => {
|
|
194
|
-
const { getSession } = configRef.current;
|
|
195
|
-
builderRef.current = createBuilder({
|
|
196
|
-
getSession,
|
|
197
|
-
codeClient: codeClientRef.current ?? undefined,
|
|
198
|
-
onExitStart: () => {
|
|
199
|
-
isExitingRef.current = true;
|
|
200
|
-
isBuilderActiveRef.current = false;
|
|
201
|
-
codeClientRef.current?.abort();
|
|
202
|
-
codeClientRef.current?.resetMessage();
|
|
203
|
-
},
|
|
204
|
-
loadBundle: (bundleUrl) => {
|
|
205
|
-
// Note: isExitingRef is already set by onExitStart for the exit flow.
|
|
206
|
-
// Don't set it here — this callback is also used by checkpoint restore
|
|
207
|
-
// while the builder is still active.
|
|
208
|
-
return loadBundleRef.current?.(bundleUrl) ?? Promise.resolve();
|
|
209
|
-
},
|
|
210
|
-
onEnter: () => {
|
|
211
|
-
isExitingRef.current = false;
|
|
212
|
-
isBuilderActiveRef.current = true;
|
|
213
|
-
setIsEditing(true);
|
|
214
|
-
},
|
|
215
|
-
onExit: () => {
|
|
216
|
-
setIsEditing(false);
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
207
|
return () => {
|
|
220
|
-
builderRef.current?.destroy();
|
|
221
|
-
// Clean up CSS link element on unmount
|
|
222
208
|
cssLoaderRef.current?.unload();
|
|
223
209
|
};
|
|
224
210
|
}, []);
|
|
211
|
+
// Listen to DOM events from standalone script for bundle loading
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
const handlers = [
|
|
214
|
+
['dynim:bundle-ready', () => {
|
|
215
|
+
const bundleUrl = `/api/code/bundle?temp=true&_t=${Date.now()}`;
|
|
216
|
+
loadBundleRef.current?.(bundleUrl, true);
|
|
217
|
+
}],
|
|
218
|
+
['dynim:bundle-saved', ((e) => {
|
|
219
|
+
const detail = e.detail;
|
|
220
|
+
if (detail?.cssVersion && codeClientRef.current) {
|
|
221
|
+
codeClientRef.current.setCSSVersion(detail.cssVersion);
|
|
222
|
+
}
|
|
223
|
+
loadBundleRef.current?.('/api/code/bundle', true);
|
|
224
|
+
})],
|
|
225
|
+
['dynim:bundle-abandoned', () => {
|
|
226
|
+
loadBundleRef.current?.('/api/code/bundle', true);
|
|
227
|
+
}],
|
|
228
|
+
['dynim:load-bundle', ((e) => {
|
|
229
|
+
const detail = e.detail;
|
|
230
|
+
if (detail?.bundleUrl) {
|
|
231
|
+
loadBundleRef.current?.(detail.bundleUrl);
|
|
232
|
+
}
|
|
233
|
+
})],
|
|
234
|
+
['dynim:enter', () => {
|
|
235
|
+
setIsEditing(true);
|
|
236
|
+
}],
|
|
237
|
+
['dynim:exit', () => {
|
|
238
|
+
setIsEditing(false);
|
|
239
|
+
}],
|
|
240
|
+
];
|
|
241
|
+
for (const [event, handler] of handlers) {
|
|
242
|
+
window.addEventListener(event, handler);
|
|
243
|
+
}
|
|
244
|
+
return () => {
|
|
245
|
+
for (const [event, handler] of handlers) {
|
|
246
|
+
window.removeEventListener(event, handler);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}, []);
|
|
225
250
|
// Get bundle loader
|
|
226
251
|
const getBundleLoader = useCallback(() => {
|
|
227
252
|
if (!bundleLoaderRef.current) {
|
|
@@ -263,6 +288,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
263
288
|
const { App, cleanup } = await loader.load(bundleUrl);
|
|
264
289
|
setTenantApp(() => App);
|
|
265
290
|
setIsBundleLoaded(true);
|
|
291
|
+
setBundleResetKey(k => k + 1);
|
|
266
292
|
cleanup();
|
|
267
293
|
// Load CSS alongside JS bundle
|
|
268
294
|
if (loadCSS) {
|
|
@@ -302,8 +328,6 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
302
328
|
const fetchTheme = useCallback(async () => {
|
|
303
329
|
if (hasAttemptedThemeLoadRef.current)
|
|
304
330
|
return;
|
|
305
|
-
if (!configRef.current.getSession)
|
|
306
|
-
return;
|
|
307
331
|
hasAttemptedThemeLoadRef.current = true;
|
|
308
332
|
try {
|
|
309
333
|
const token = await getAuthToken();
|
|
@@ -325,137 +349,74 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
325
349
|
console.warn('[DynimProvider] Failed to fetch theme:', error);
|
|
326
350
|
}
|
|
327
351
|
}, [getAuthToken]);
|
|
328
|
-
// Auto-load saved bundle
|
|
352
|
+
// Auto-load saved bundle once the standalone SDK has authenticated.
|
|
353
|
+
// Listens for 'dynim:identified' (user called window.dynim.identify()).
|
|
354
|
+
// If the SDK is never loaded or identify is never called, children render immediately.
|
|
329
355
|
useEffect(() => {
|
|
330
|
-
|
|
331
|
-
return;
|
|
332
|
-
hasAttemptedInitialLoadRef.current = true;
|
|
333
|
-
const { getSession } = configRef.current;
|
|
334
|
-
// No auth configured = skip bundle load
|
|
335
|
-
if (!getSession) {
|
|
336
|
-
setIsInitialLoadComplete(true);
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
// Load bundle with the provided token
|
|
356
|
+
let unmounted = false;
|
|
340
357
|
const doInitialLoad = async () => {
|
|
358
|
+
if (hasAttemptedInitialLoadRef.current || unmounted)
|
|
359
|
+
return;
|
|
360
|
+
hasAttemptedInitialLoadRef.current = true;
|
|
341
361
|
try {
|
|
342
362
|
await loadBundleRef.current?.('/api/code/bundle');
|
|
343
363
|
}
|
|
344
364
|
catch (error) {
|
|
345
|
-
// Errors handled in loadBundle (404 = no bundle, etc.)
|
|
346
365
|
console.log('[DynimProvider] Initial bundle load:', error.message);
|
|
347
366
|
}
|
|
348
367
|
finally {
|
|
349
|
-
|
|
368
|
+
if (!unmounted)
|
|
369
|
+
setIsInitialLoadComplete(true);
|
|
350
370
|
}
|
|
371
|
+
// Prefetch theme after 3s delay (non-blocking)
|
|
372
|
+
setTimeout(() => fetchTheme(), 3000);
|
|
351
373
|
};
|
|
352
|
-
doInitialLoad();
|
|
353
|
-
//
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
// (bundleReady alone stays true, so subsequent events wouldn't trigger re-render)
|
|
365
|
-
useEffect(() => {
|
|
366
|
-
if (codeMessage.bundleReady && codeMessage.projectId) {
|
|
367
|
-
if (isBuilderActiveRef.current && !isExitingRef.current) {
|
|
368
|
-
pendingBundleProjectIdRef.current = codeMessage.projectId;
|
|
369
|
-
setBundleLoadSignal(s => s + 1);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}, [codeMessage.bundleReady, codeMessage.projectId, codeMessage.bundleSequence]);
|
|
373
|
-
// Load temp bundle on signal (JS + CSS with cache busting)
|
|
374
|
-
useEffect(() => {
|
|
375
|
-
if (bundleLoadSignal === 0)
|
|
376
|
-
return;
|
|
377
|
-
const projectId = pendingBundleProjectIdRef.current;
|
|
378
|
-
if (!projectId || isExitingRef.current) {
|
|
379
|
-
pendingBundleProjectIdRef.current = null;
|
|
380
|
-
return;
|
|
374
|
+
const onIdentified = () => doInitialLoad();
|
|
375
|
+
// If already identified (SDK loaded before React), load immediately
|
|
376
|
+
const dynim = window.dynim;
|
|
377
|
+
if (dynim?.getSession) {
|
|
378
|
+
dynim.getSession().then((session) => {
|
|
379
|
+
if (session) {
|
|
380
|
+
doInitialLoad();
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
window.addEventListener('dynim:identified', onIdentified, { once: true });
|
|
384
|
+
}
|
|
385
|
+
});
|
|
381
386
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
loadBundleRef.current?.(bundleUrl, true); // true = also load CSS
|
|
385
|
-
pendingBundleProjectIdRef.current = null;
|
|
386
|
-
}, [bundleLoadSignal]);
|
|
387
|
-
// Public methods
|
|
388
|
-
const enterBuilder = useCallback(() => {
|
|
389
|
-
if (builderRef.current && !builderRef.current.isActive()) {
|
|
390
|
-
builderRef.current.enter();
|
|
391
|
-
// Fetch theme lazily when entering builder
|
|
392
|
-
fetchTheme();
|
|
387
|
+
else {
|
|
388
|
+
window.addEventListener('dynim:identified', onIdentified, { once: true });
|
|
393
389
|
}
|
|
390
|
+
// If no SDK at all, show children after a short timeout
|
|
391
|
+
const fallbackTimeout = setTimeout(() => {
|
|
392
|
+
if (!hasAttemptedInitialLoadRef.current && !unmounted) {
|
|
393
|
+
hasAttemptedInitialLoadRef.current = true;
|
|
394
|
+
setIsInitialLoadComplete(true);
|
|
395
|
+
}
|
|
396
|
+
}, 3000);
|
|
397
|
+
return () => {
|
|
398
|
+
unmounted = true;
|
|
399
|
+
clearTimeout(fallbackTimeout);
|
|
400
|
+
window.removeEventListener('dynim:identified', onIdentified);
|
|
401
|
+
};
|
|
394
402
|
}, [fetchTheme]);
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
}, []);
|
|
400
|
-
const sendCode = useCallback(async (query) => {
|
|
401
|
-
await codeClientRef.current?.sendCode(query);
|
|
402
|
-
}, []);
|
|
403
|
-
const saveCode = useCallback(async () => {
|
|
404
|
-
// saveCode updates cssVersion internally in code-client
|
|
405
|
-
await codeClientRef.current?.saveCode();
|
|
406
|
-
// Load saved bundle - CSS will use new version from code-client
|
|
407
|
-
await loadSavedBundle();
|
|
408
|
-
}, [loadSavedBundle]);
|
|
409
|
-
const abandonCode = useCallback(async () => {
|
|
410
|
-
await codeClientRef.current?.abandonCode();
|
|
411
|
-
// Load saved bundle - cssVersion state unchanged, will use existing version
|
|
412
|
-
await loadSavedBundle();
|
|
413
|
-
}, [loadSavedBundle]);
|
|
414
|
-
const getCheckpoints = useCallback(async () => {
|
|
415
|
-
return codeClientRef.current?.getCheckpoints() ?? [];
|
|
403
|
+
// Public methods — always delegate to window.dynim (standalone script)
|
|
404
|
+
const enterBuilder = useCallback(() => {
|
|
405
|
+
window.dynim?.enterBuilder();
|
|
416
406
|
}, []);
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
throw new Error('Code client not initialized');
|
|
420
|
-
}
|
|
421
|
-
setIsRestoring(true);
|
|
422
|
-
try {
|
|
423
|
-
const result = await codeClientRef.current.restoreCheckpoint(checkpointId);
|
|
424
|
-
// Reload bundle + CSS on success (loadBundle handles CSS when loadCSS=true)
|
|
425
|
-
if (result.bundle_ready) {
|
|
426
|
-
const bundleUrl = `/api/code/bundle?temp=true&_t=${Date.now()}`;
|
|
427
|
-
await loadBundleRef.current?.(bundleUrl, true);
|
|
428
|
-
}
|
|
429
|
-
return result;
|
|
430
|
-
}
|
|
431
|
-
finally {
|
|
432
|
-
setIsRestoring(false);
|
|
433
|
-
}
|
|
407
|
+
const exitBuilder = useCallback(() => {
|
|
408
|
+
window.dynim?.exitBuilder();
|
|
434
409
|
}, []);
|
|
435
410
|
const contextValue = useMemo(() => ({
|
|
436
411
|
enterBuilder,
|
|
437
412
|
exitBuilder,
|
|
438
413
|
isEditing,
|
|
439
|
-
sendCode,
|
|
440
|
-
saveCode,
|
|
441
|
-
abandonCode,
|
|
442
|
-
getCheckpoints,
|
|
443
|
-
restoreCheckpoint,
|
|
444
|
-
isRestoring,
|
|
445
|
-
codeMessage,
|
|
446
414
|
isBundleLoaded,
|
|
447
415
|
isBundleLoading,
|
|
448
416
|
}), [
|
|
449
417
|
enterBuilder,
|
|
450
418
|
exitBuilder,
|
|
451
419
|
isEditing,
|
|
452
|
-
sendCode,
|
|
453
|
-
saveCode,
|
|
454
|
-
abandonCode,
|
|
455
|
-
getCheckpoints,
|
|
456
|
-
restoreCheckpoint,
|
|
457
|
-
isRestoring,
|
|
458
|
-
codeMessage,
|
|
459
420
|
isBundleLoaded,
|
|
460
421
|
isBundleLoading,
|
|
461
422
|
]);
|
|
@@ -473,7 +434,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
473
434
|
}, children: ["Bundle error: ", bundleError.message] }), children] }));
|
|
474
435
|
}
|
|
475
436
|
if (TenantApp) {
|
|
476
|
-
return (_jsx(BundleErrorBoundary, { resetKey:
|
|
437
|
+
return (_jsx(BundleErrorBoundary, { resetKey: bundleResetKey, onError: (error) => configRef.current.onError?.(error), children: _jsx(TenantApp, {}) }));
|
|
477
438
|
}
|
|
478
439
|
return children;
|
|
479
440
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -14,5 +14,5 @@ export { DynimProvider, useDynim, getSessionToken } from './DynimProvider';
|
|
|
14
14
|
export type { DynimConfig, DynimContextValue, DynimProviderProps } from './DynimProvider';
|
|
15
15
|
export { defaultTheme } from './theme';
|
|
16
16
|
export type { DynimTheme } from './theme';
|
|
17
|
-
export type { CodeMessage, CodeEdit,
|
|
17
|
+
export type { CodeMessage, CodeEdit, ConnectionRequest } from 'dynim-core';
|
|
18
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1F,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG1F,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dynim-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.123",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dev": "tsc --watch"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"dynim-core": "^1.0.
|
|
30
|
+
"dynim-core": "^1.0.97"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=17.0.0",
|