dynim-react 1.0.120 → 1.0.122
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 +114 -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,CAkalC;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,73 @@ 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
|
-
onMessageUpdate: setCodeMessage,
|
|
179
|
+
getSession: getSessionRef.current ?? undefined,
|
|
184
180
|
onError: (error) => {
|
|
185
181
|
console.error('[DynimProvider] Code error:', error);
|
|
186
182
|
configRef.current.onError?.(error);
|
|
187
183
|
},
|
|
188
184
|
});
|
|
185
|
+
// Sync token when standalone SDK authenticates
|
|
186
|
+
const onIdentified = async () => {
|
|
187
|
+
const session = await getSessionRef.current?.();
|
|
188
|
+
if (session && codeClientRef.current) {
|
|
189
|
+
codeClientRef.current.setSessionToken(session.token, session.refreshToken);
|
|
190
|
+
if (session.cssVersion !== undefined) {
|
|
191
|
+
codeClientRef.current.setCSSVersion(session.cssVersion ?? null);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
window.addEventListener('dynim:identified', onIdentified);
|
|
196
|
+
return () => window.removeEventListener('dynim:identified', onIdentified);
|
|
189
197
|
}, []);
|
|
190
198
|
// Load bundle ref
|
|
191
199
|
const loadBundleRef = useRef(null);
|
|
192
|
-
//
|
|
200
|
+
// Clean up CSS link element on unmount
|
|
193
201
|
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
202
|
return () => {
|
|
220
|
-
builderRef.current?.destroy();
|
|
221
|
-
// Clean up CSS link element on unmount
|
|
222
203
|
cssLoaderRef.current?.unload();
|
|
223
204
|
};
|
|
224
205
|
}, []);
|
|
206
|
+
// Listen to DOM events from standalone script for bundle loading
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
const handlers = [
|
|
209
|
+
['dynim:bundle-ready', () => {
|
|
210
|
+
const bundleUrl = `/api/code/bundle?temp=true&_t=${Date.now()}`;
|
|
211
|
+
loadBundleRef.current?.(bundleUrl, true);
|
|
212
|
+
}],
|
|
213
|
+
['dynim:bundle-saved', ((e) => {
|
|
214
|
+
const detail = e.detail;
|
|
215
|
+
if (detail?.cssVersion && codeClientRef.current) {
|
|
216
|
+
codeClientRef.current.setCSSVersion(detail.cssVersion);
|
|
217
|
+
}
|
|
218
|
+
loadBundleRef.current?.('/api/code/bundle', true);
|
|
219
|
+
})],
|
|
220
|
+
['dynim:bundle-abandoned', () => {
|
|
221
|
+
loadBundleRef.current?.('/api/code/bundle', true);
|
|
222
|
+
}],
|
|
223
|
+
['dynim:load-bundle', ((e) => {
|
|
224
|
+
const detail = e.detail;
|
|
225
|
+
if (detail?.bundleUrl) {
|
|
226
|
+
loadBundleRef.current?.(detail.bundleUrl);
|
|
227
|
+
}
|
|
228
|
+
})],
|
|
229
|
+
['dynim:enter', () => {
|
|
230
|
+
setIsEditing(true);
|
|
231
|
+
}],
|
|
232
|
+
['dynim:exit', () => {
|
|
233
|
+
setIsEditing(false);
|
|
234
|
+
}],
|
|
235
|
+
];
|
|
236
|
+
for (const [event, handler] of handlers) {
|
|
237
|
+
window.addEventListener(event, handler);
|
|
238
|
+
}
|
|
239
|
+
return () => {
|
|
240
|
+
for (const [event, handler] of handlers) {
|
|
241
|
+
window.removeEventListener(event, handler);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}, []);
|
|
225
245
|
// Get bundle loader
|
|
226
246
|
const getBundleLoader = useCallback(() => {
|
|
227
247
|
if (!bundleLoaderRef.current) {
|
|
@@ -263,6 +283,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
263
283
|
const { App, cleanup } = await loader.load(bundleUrl);
|
|
264
284
|
setTenantApp(() => App);
|
|
265
285
|
setIsBundleLoaded(true);
|
|
286
|
+
setBundleResetKey(k => k + 1);
|
|
266
287
|
cleanup();
|
|
267
288
|
// Load CSS alongside JS bundle
|
|
268
289
|
if (loadCSS) {
|
|
@@ -302,8 +323,6 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
302
323
|
const fetchTheme = useCallback(async () => {
|
|
303
324
|
if (hasAttemptedThemeLoadRef.current)
|
|
304
325
|
return;
|
|
305
|
-
if (!configRef.current.getSession)
|
|
306
|
-
return;
|
|
307
326
|
hasAttemptedThemeLoadRef.current = true;
|
|
308
327
|
try {
|
|
309
328
|
const token = await getAuthToken();
|
|
@@ -325,137 +344,74 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
325
344
|
console.warn('[DynimProvider] Failed to fetch theme:', error);
|
|
326
345
|
}
|
|
327
346
|
}, [getAuthToken]);
|
|
328
|
-
// Auto-load saved bundle
|
|
347
|
+
// Auto-load saved bundle once the standalone SDK has authenticated.
|
|
348
|
+
// Listens for 'dynim:identified' (user called window.dynim.identify()).
|
|
349
|
+
// If the SDK is never loaded or identify is never called, children render immediately.
|
|
329
350
|
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
|
|
351
|
+
let unmounted = false;
|
|
340
352
|
const doInitialLoad = async () => {
|
|
353
|
+
if (hasAttemptedInitialLoadRef.current || unmounted)
|
|
354
|
+
return;
|
|
355
|
+
hasAttemptedInitialLoadRef.current = true;
|
|
341
356
|
try {
|
|
342
357
|
await loadBundleRef.current?.('/api/code/bundle');
|
|
343
358
|
}
|
|
344
359
|
catch (error) {
|
|
345
|
-
// Errors handled in loadBundle (404 = no bundle, etc.)
|
|
346
360
|
console.log('[DynimProvider] Initial bundle load:', error.message);
|
|
347
361
|
}
|
|
348
362
|
finally {
|
|
349
|
-
|
|
363
|
+
if (!unmounted)
|
|
364
|
+
setIsInitialLoadComplete(true);
|
|
350
365
|
}
|
|
366
|
+
// Prefetch theme after 3s delay (non-blocking)
|
|
367
|
+
setTimeout(() => fetchTheme(), 3000);
|
|
351
368
|
};
|
|
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;
|
|
369
|
+
const onIdentified = () => doInitialLoad();
|
|
370
|
+
// If already identified (SDK loaded before React), load immediately
|
|
371
|
+
const dynim = window.dynim;
|
|
372
|
+
if (dynim?.getSession) {
|
|
373
|
+
dynim.getSession().then((session) => {
|
|
374
|
+
if (session) {
|
|
375
|
+
doInitialLoad();
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
window.addEventListener('dynim:identified', onIdentified, { once: true });
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
381
|
}
|
|
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();
|
|
382
|
+
else {
|
|
383
|
+
window.addEventListener('dynim:identified', onIdentified, { once: true });
|
|
393
384
|
}
|
|
385
|
+
// If no SDK at all, show children after a short timeout
|
|
386
|
+
const fallbackTimeout = setTimeout(() => {
|
|
387
|
+
if (!hasAttemptedInitialLoadRef.current && !unmounted) {
|
|
388
|
+
hasAttemptedInitialLoadRef.current = true;
|
|
389
|
+
setIsInitialLoadComplete(true);
|
|
390
|
+
}
|
|
391
|
+
}, 3000);
|
|
392
|
+
return () => {
|
|
393
|
+
unmounted = true;
|
|
394
|
+
clearTimeout(fallbackTimeout);
|
|
395
|
+
window.removeEventListener('dynim:identified', onIdentified);
|
|
396
|
+
};
|
|
394
397
|
}, [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() ?? [];
|
|
398
|
+
// Public methods — always delegate to window.dynim (standalone script)
|
|
399
|
+
const enterBuilder = useCallback(() => {
|
|
400
|
+
window.dynim?.enterBuilder();
|
|
416
401
|
}, []);
|
|
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
|
-
}
|
|
402
|
+
const exitBuilder = useCallback(() => {
|
|
403
|
+
window.dynim?.exitBuilder();
|
|
434
404
|
}, []);
|
|
435
405
|
const contextValue = useMemo(() => ({
|
|
436
406
|
enterBuilder,
|
|
437
407
|
exitBuilder,
|
|
438
408
|
isEditing,
|
|
439
|
-
sendCode,
|
|
440
|
-
saveCode,
|
|
441
|
-
abandonCode,
|
|
442
|
-
getCheckpoints,
|
|
443
|
-
restoreCheckpoint,
|
|
444
|
-
isRestoring,
|
|
445
|
-
codeMessage,
|
|
446
409
|
isBundleLoaded,
|
|
447
410
|
isBundleLoading,
|
|
448
411
|
}), [
|
|
449
412
|
enterBuilder,
|
|
450
413
|
exitBuilder,
|
|
451
414
|
isEditing,
|
|
452
|
-
sendCode,
|
|
453
|
-
saveCode,
|
|
454
|
-
abandonCode,
|
|
455
|
-
getCheckpoints,
|
|
456
|
-
restoreCheckpoint,
|
|
457
|
-
isRestoring,
|
|
458
|
-
codeMessage,
|
|
459
415
|
isBundleLoaded,
|
|
460
416
|
isBundleLoading,
|
|
461
417
|
]);
|
|
@@ -473,7 +429,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
473
429
|
}, children: ["Bundle error: ", bundleError.message] }), children] }));
|
|
474
430
|
}
|
|
475
431
|
if (TenantApp) {
|
|
476
|
-
return (_jsx(BundleErrorBoundary, { resetKey:
|
|
432
|
+
return (_jsx(BundleErrorBoundary, { resetKey: bundleResetKey, onError: (error) => configRef.current.onError?.(error), children: _jsx(TenantApp, {}) }));
|
|
477
433
|
}
|
|
478
434
|
return children;
|
|
479
435
|
};
|
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.122",
|
|
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.96"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=17.0.0",
|