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.
@@ -1,25 +1,18 @@
1
1
  /**
2
- * DynimProvider - Single provider for all Dynim functionality
2
+ * DynimProvider - Bundle renderer and shared context provider
3
3
  *
4
4
  * Handles:
5
5
  * - Loading tenant bundles
6
- * - Visual builder UI (when user has edit permissions)
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;AAWf,OAAO,KAAK,EAIV,WAAW,EACX,UAAU,EACV,aAAa,EAGd,MAAM,YAAY,CAAC;AAOpB;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAG9D;AA6ED,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC,CAAC;IACH,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,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,yBAAyB;IACzB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,oCAAoC;IACpC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5C,mEAAmE;IACnE,iBAAiB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACpE,kDAAkD;IAClD,WAAW,EAAE,OAAO,CAAC;IACrB,yDAAyD;IACzD,WAAW,EAAE,WAAW,CAAC;IACzB,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,CA0elC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C"}
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"}
@@ -1,15 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /**
3
- * DynimProvider - Single provider for all Dynim functionality
3
+ * DynimProvider - Bundle renderer and shared context provider
4
4
  *
5
5
  * Handles:
6
6
  * - Loading tenant bundles
7
- * - Visual builder UI (when user has edit permissions)
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 { createBuilderClient, createBuilder, createCodeClient, createBundleLoader, createCSSLoader, BundleNotFoundError, BundleAuthError, } from 'dynim-core';
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
- const isBuilderActiveRef = useRef(false);
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 load signal
104
- const [bundleLoadSignal, setBundleLoadSignal] = useState(0);
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 { getSession } = configRef.current;
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
- // Initialize builder (only once on mount)
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
- // Initialize builder client (only once on mount)
206
+ // Listen to DOM events from standalone script for bundle loading
227
207
  useEffect(() => {
228
- const { getSession } = configRef.current;
229
- builderClientRef.current = createBuilderClient({
230
- getSession,
231
- onError: (error) => {
232
- console.error('[DynimProvider] Error:', error);
233
- configRef.current.onError?.(error);
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 on mount if auth is available
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
- if (hasAttemptedInitialLoadRef.current)
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
- setIsInitialLoadComplete(true);
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
- // Prefetch theme after 3s delay (non-blocking, so it's ready when builder opens)
366
- const themeTimeout = setTimeout(() => {
367
- fetchTheme();
368
- }, 3000);
369
- return () => clearTimeout(themeTimeout);
370
- }, [fetchTheme]);
371
- // Load saved bundle (JS + CSS with versioned URL)
372
- const loadSavedBundle = useCallback(async () => {
373
- await loadBundle('/api/code/bundle', true);
374
- }, [loadBundle]);
375
- // Watch for bundleReady - use bundleSequence to detect new bundles
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
- // Load JS bundle with cache busting
395
- const bundleUrl = `/api/code/bundle?temp=true&_t=${Date.now()}`;
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
- const exitBuilder = useCallback(() => {
408
- if (builderRef.current && builderRef.current.isActive()) {
409
- builderRef.current.exit();
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 restoreCheckpoint = useCallback(async (checkpointId) => {
430
- if (!codeClientRef.current) {
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: codeMessage.bundleSequence ?? 0, onError: (error) => configRef.current.onError?.(error), children: _jsx(TenantApp, {}) }));
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, Checkpoint, RestoreResult, ConnectionRequest, Message } from 'dynim-core';
17
+ export type { CodeMessage, CodeEdit, ConnectionRequest } from 'dynim-core';
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -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,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
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.119",
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.93"
30
+ "dynim-core": "^1.0.96"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "react": ">=17.0.0",