dynim-react 1.0.119 → 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 +112 -168
- 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,35 +74,30 @@ const DynimContext = createContext(null);
|
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
76
|
export function DynimProvider({ children, config = {}, }) {
|
|
77
|
-
const builderClientRef = useRef(null);
|
|
78
|
-
const builderRef = useRef(null);
|
|
79
77
|
const codeClientRef = useRef(null);
|
|
80
78
|
const bundleLoaderRef = useRef(null);
|
|
81
79
|
const cssLoaderRef = useRef(null);
|
|
82
|
-
// Track when we're exiting to prevent auto-load from re-triggering
|
|
83
|
-
const isExitingRef = useRef(false);
|
|
84
80
|
const hasAttemptedInitialLoadRef = useRef(false);
|
|
85
|
-
|
|
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
|
+
});
|
|
86
90
|
const [isEditing, setIsEditing] = useState(false);
|
|
87
91
|
const [isBundleLoaded, setIsBundleLoaded] = useState(false);
|
|
88
92
|
const [isBundleLoading, setIsBundleLoading] = useState(false);
|
|
89
93
|
const [isInitialLoadComplete, setIsInitialLoadComplete] = useState(false);
|
|
90
94
|
const [TenantApp, setTenantApp] = useState(null);
|
|
91
95
|
const [bundleError, setBundleError] = useState(null);
|
|
92
|
-
const [isRestoring, setIsRestoring] = useState(false);
|
|
93
|
-
const [codeMessage, setCodeMessage] = useState({
|
|
94
|
-
thinking: '',
|
|
95
|
-
text: '',
|
|
96
|
-
status: 'idle',
|
|
97
|
-
bundleReady: false,
|
|
98
|
-
bundleError: undefined,
|
|
99
|
-
});
|
|
100
96
|
// Cached auth token
|
|
101
97
|
const cachedTokenRef = useRef(null);
|
|
102
98
|
const tokenPromiseRef = useRef(null);
|
|
103
|
-
// Bundle
|
|
104
|
-
const [
|
|
105
|
-
const pendingBundleProjectIdRef = useRef(null);
|
|
99
|
+
// Bundle reset counter (incremented when loadBundle succeeds)
|
|
100
|
+
const [bundleResetKey, setBundleResetKey] = useState(0);
|
|
106
101
|
// Theme state (fetched from API per project)
|
|
107
102
|
const [theme, setTheme] = useState(null);
|
|
108
103
|
const hasAttemptedThemeLoadRef = useRef(false);
|
|
@@ -138,7 +133,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
138
133
|
// Get auth token (cached after first call).
|
|
139
134
|
// Also registered as the module-level resolver so non-React code (API clients) can call getSessionToken().
|
|
140
135
|
const getAuthToken = useCallback(async () => {
|
|
141
|
-
const
|
|
136
|
+
const getSession = getSessionRef.current;
|
|
142
137
|
// Return cached token if available
|
|
143
138
|
if (cachedTokenRef.current)
|
|
144
139
|
return cachedTokenRef.current;
|
|
@@ -149,6 +144,8 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
149
144
|
tokenPromiseRef.current = (async () => {
|
|
150
145
|
try {
|
|
151
146
|
const session = await getSession();
|
|
147
|
+
if (!session)
|
|
148
|
+
return null;
|
|
152
149
|
cachedTokenRef.current = session.token;
|
|
153
150
|
// Sync token and CSS version to code-client (bundleLoader uses this getAuthToken,
|
|
154
151
|
// not code-client's internal getValidToken, so we need to sync both here)
|
|
@@ -178,61 +175,72 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
178
175
|
}, [getAuthToken]);
|
|
179
176
|
// Initialize code client (only once on mount)
|
|
180
177
|
useEffect(() => {
|
|
181
|
-
const { getSession, onError } = configRef.current;
|
|
182
178
|
codeClientRef.current = createCodeClient({
|
|
183
|
-
getSession,
|
|
184
|
-
onMessageUpdate: setCodeMessage,
|
|
179
|
+
getSession: getSessionRef.current ?? undefined,
|
|
185
180
|
onError: (error) => {
|
|
186
181
|
console.error('[DynimProvider] Code error:', error);
|
|
187
182
|
configRef.current.onError?.(error);
|
|
188
183
|
},
|
|
189
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);
|
|
190
197
|
}, []);
|
|
191
198
|
// Load bundle ref
|
|
192
199
|
const loadBundleRef = useRef(null);
|
|
193
|
-
//
|
|
200
|
+
// Clean up CSS link element on unmount
|
|
194
201
|
useEffect(() => {
|
|
195
|
-
const { getSession } = configRef.current;
|
|
196
|
-
builderRef.current = createBuilder({
|
|
197
|
-
getSession,
|
|
198
|
-
codeClient: codeClientRef.current ?? undefined,
|
|
199
|
-
onExitStart: () => {
|
|
200
|
-
isExitingRef.current = true;
|
|
201
|
-
isBuilderActiveRef.current = false;
|
|
202
|
-
codeClientRef.current?.abort();
|
|
203
|
-
codeClientRef.current?.resetMessage();
|
|
204
|
-
},
|
|
205
|
-
loadBundle: (bundleUrl) => {
|
|
206
|
-
// Note: isExitingRef is already set by onExitStart for the exit flow.
|
|
207
|
-
// Don't set it here — this callback is also used by checkpoint restore
|
|
208
|
-
// while the builder is still active.
|
|
209
|
-
return loadBundleRef.current?.(bundleUrl) ?? Promise.resolve();
|
|
210
|
-
},
|
|
211
|
-
onEnter: () => {
|
|
212
|
-
isExitingRef.current = false;
|
|
213
|
-
isBuilderActiveRef.current = true;
|
|
214
|
-
setIsEditing(true);
|
|
215
|
-
},
|
|
216
|
-
onExit: () => {
|
|
217
|
-
setIsEditing(false);
|
|
218
|
-
},
|
|
219
|
-
});
|
|
220
202
|
return () => {
|
|
221
|
-
builderRef.current?.destroy();
|
|
222
|
-
// Clean up CSS link element on unmount
|
|
223
203
|
cssLoaderRef.current?.unload();
|
|
224
204
|
};
|
|
225
205
|
}, []);
|
|
226
|
-
//
|
|
206
|
+
// Listen to DOM events from standalone script for bundle loading
|
|
227
207
|
useEffect(() => {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
+
};
|
|
236
244
|
}, []);
|
|
237
245
|
// Get bundle loader
|
|
238
246
|
const getBundleLoader = useCallback(() => {
|
|
@@ -275,6 +283,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
275
283
|
const { App, cleanup } = await loader.load(bundleUrl);
|
|
276
284
|
setTenantApp(() => App);
|
|
277
285
|
setIsBundleLoaded(true);
|
|
286
|
+
setBundleResetKey(k => k + 1);
|
|
278
287
|
cleanup();
|
|
279
288
|
// Load CSS alongside JS bundle
|
|
280
289
|
if (loadCSS) {
|
|
@@ -314,8 +323,6 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
314
323
|
const fetchTheme = useCallback(async () => {
|
|
315
324
|
if (hasAttemptedThemeLoadRef.current)
|
|
316
325
|
return;
|
|
317
|
-
if (!configRef.current.getSession)
|
|
318
|
-
return;
|
|
319
326
|
hasAttemptedThemeLoadRef.current = true;
|
|
320
327
|
try {
|
|
321
328
|
const token = await getAuthToken();
|
|
@@ -337,137 +344,74 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
337
344
|
console.warn('[DynimProvider] Failed to fetch theme:', error);
|
|
338
345
|
}
|
|
339
346
|
}, [getAuthToken]);
|
|
340
|
-
// 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.
|
|
341
350
|
useEffect(() => {
|
|
342
|
-
|
|
343
|
-
return;
|
|
344
|
-
hasAttemptedInitialLoadRef.current = true;
|
|
345
|
-
const { getSession } = configRef.current;
|
|
346
|
-
// No auth configured = skip bundle load
|
|
347
|
-
if (!getSession) {
|
|
348
|
-
setIsInitialLoadComplete(true);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
// Load bundle with the provided token
|
|
351
|
+
let unmounted = false;
|
|
352
352
|
const doInitialLoad = async () => {
|
|
353
|
+
if (hasAttemptedInitialLoadRef.current || unmounted)
|
|
354
|
+
return;
|
|
355
|
+
hasAttemptedInitialLoadRef.current = true;
|
|
353
356
|
try {
|
|
354
357
|
await loadBundleRef.current?.('/api/code/bundle');
|
|
355
358
|
}
|
|
356
359
|
catch (error) {
|
|
357
|
-
// Errors handled in loadBundle (404 = no bundle, etc.)
|
|
358
360
|
console.log('[DynimProvider] Initial bundle load:', error.message);
|
|
359
361
|
}
|
|
360
362
|
finally {
|
|
361
|
-
|
|
363
|
+
if (!unmounted)
|
|
364
|
+
setIsInitialLoadComplete(true);
|
|
362
365
|
}
|
|
366
|
+
// Prefetch theme after 3s delay (non-blocking)
|
|
367
|
+
setTimeout(() => fetchTheme(), 3000);
|
|
363
368
|
};
|
|
364
|
-
doInitialLoad();
|
|
365
|
-
//
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
// (bundleReady alone stays true, so subsequent events wouldn't trigger re-render)
|
|
377
|
-
useEffect(() => {
|
|
378
|
-
if (codeMessage.bundleReady && codeMessage.projectId) {
|
|
379
|
-
if (isBuilderActiveRef.current && !isExitingRef.current) {
|
|
380
|
-
pendingBundleProjectIdRef.current = codeMessage.projectId;
|
|
381
|
-
setBundleLoadSignal(s => s + 1);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}, [codeMessage.bundleReady, codeMessage.projectId, codeMessage.bundleSequence]);
|
|
385
|
-
// Load temp bundle on signal (JS + CSS with cache busting)
|
|
386
|
-
useEffect(() => {
|
|
387
|
-
if (bundleLoadSignal === 0)
|
|
388
|
-
return;
|
|
389
|
-
const projectId = pendingBundleProjectIdRef.current;
|
|
390
|
-
if (!projectId || isExitingRef.current) {
|
|
391
|
-
pendingBundleProjectIdRef.current = null;
|
|
392
|
-
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
|
+
});
|
|
393
381
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
loadBundleRef.current?.(bundleUrl, true); // true = also load CSS
|
|
397
|
-
pendingBundleProjectIdRef.current = null;
|
|
398
|
-
}, [bundleLoadSignal]);
|
|
399
|
-
// Public methods
|
|
400
|
-
const enterBuilder = useCallback(() => {
|
|
401
|
-
if (builderRef.current && !builderRef.current.isActive()) {
|
|
402
|
-
builderRef.current.enter();
|
|
403
|
-
// Fetch theme lazily when entering builder
|
|
404
|
-
fetchTheme();
|
|
382
|
+
else {
|
|
383
|
+
window.addEventListener('dynim:identified', onIdentified, { once: true });
|
|
405
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
|
+
};
|
|
406
397
|
}, [fetchTheme]);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
}, []);
|
|
412
|
-
const sendCode = useCallback(async (query) => {
|
|
413
|
-
await codeClientRef.current?.sendCode(query);
|
|
414
|
-
}, []);
|
|
415
|
-
const saveCode = useCallback(async () => {
|
|
416
|
-
// saveCode updates cssVersion internally in code-client
|
|
417
|
-
await codeClientRef.current?.saveCode();
|
|
418
|
-
// Load saved bundle - CSS will use new version from code-client
|
|
419
|
-
await loadSavedBundle();
|
|
420
|
-
}, [loadSavedBundle]);
|
|
421
|
-
const abandonCode = useCallback(async () => {
|
|
422
|
-
await codeClientRef.current?.abandonCode();
|
|
423
|
-
// Load saved bundle - cssVersion state unchanged, will use existing version
|
|
424
|
-
await loadSavedBundle();
|
|
425
|
-
}, [loadSavedBundle]);
|
|
426
|
-
const getCheckpoints = useCallback(async () => {
|
|
427
|
-
return codeClientRef.current?.getCheckpoints() ?? [];
|
|
398
|
+
// Public methods — always delegate to window.dynim (standalone script)
|
|
399
|
+
const enterBuilder = useCallback(() => {
|
|
400
|
+
window.dynim?.enterBuilder();
|
|
428
401
|
}, []);
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
throw new Error('Code client not initialized');
|
|
432
|
-
}
|
|
433
|
-
setIsRestoring(true);
|
|
434
|
-
try {
|
|
435
|
-
const result = await codeClientRef.current.restoreCheckpoint(checkpointId);
|
|
436
|
-
// Reload bundle + CSS on success (loadBundle handles CSS when loadCSS=true)
|
|
437
|
-
if (result.bundle_ready) {
|
|
438
|
-
const bundleUrl = `/api/code/bundle?temp=true&_t=${Date.now()}`;
|
|
439
|
-
await loadBundleRef.current?.(bundleUrl, true);
|
|
440
|
-
}
|
|
441
|
-
return result;
|
|
442
|
-
}
|
|
443
|
-
finally {
|
|
444
|
-
setIsRestoring(false);
|
|
445
|
-
}
|
|
402
|
+
const exitBuilder = useCallback(() => {
|
|
403
|
+
window.dynim?.exitBuilder();
|
|
446
404
|
}, []);
|
|
447
405
|
const contextValue = useMemo(() => ({
|
|
448
406
|
enterBuilder,
|
|
449
407
|
exitBuilder,
|
|
450
408
|
isEditing,
|
|
451
|
-
sendCode,
|
|
452
|
-
saveCode,
|
|
453
|
-
abandonCode,
|
|
454
|
-
getCheckpoints,
|
|
455
|
-
restoreCheckpoint,
|
|
456
|
-
isRestoring,
|
|
457
|
-
codeMessage,
|
|
458
409
|
isBundleLoaded,
|
|
459
410
|
isBundleLoading,
|
|
460
411
|
}), [
|
|
461
412
|
enterBuilder,
|
|
462
413
|
exitBuilder,
|
|
463
414
|
isEditing,
|
|
464
|
-
sendCode,
|
|
465
|
-
saveCode,
|
|
466
|
-
abandonCode,
|
|
467
|
-
getCheckpoints,
|
|
468
|
-
restoreCheckpoint,
|
|
469
|
-
isRestoring,
|
|
470
|
-
codeMessage,
|
|
471
415
|
isBundleLoaded,
|
|
472
416
|
isBundleLoading,
|
|
473
417
|
]);
|
|
@@ -485,7 +429,7 @@ export function DynimProvider({ children, config = {}, }) {
|
|
|
485
429
|
}, children: ["Bundle error: ", bundleError.message] }), children] }));
|
|
486
430
|
}
|
|
487
431
|
if (TenantApp) {
|
|
488
|
-
return (_jsx(BundleErrorBoundary, { resetKey:
|
|
432
|
+
return (_jsx(BundleErrorBoundary, { resetKey: bundleResetKey, onError: (error) => configRef.current.onError?.(error), children: _jsx(TenantApp, {}) }));
|
|
489
433
|
}
|
|
490
434
|
return children;
|
|
491
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",
|