dynim-react 1.0.40 → 1.0.42

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.
@@ -9,6 +9,8 @@
9
9
  import { type ReactNode } from 'react';
10
10
  import type { CodeMessage } from 'dynim-core';
11
11
  export interface DynimConfig {
12
+ /** JWT session token for authentication (avoids HTTP call on mount) */
13
+ sessionToken?: string;
12
14
  /** Function to fetch a new session when current one expires */
13
15
  getSession?: () => Promise<{
14
16
  token: string;
@@ -1 +1 @@
1
- {"version":3,"file":"DynimProvider.d.ts","sourceRoot":"","sources":["../src/DynimProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAc,EAQZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAKV,WAAW,EAEZ,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,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,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,CA0WlC;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,EAQZ,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAKV,WAAW,EAEZ,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,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,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,CAgalC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C"}
@@ -9,7 +9,7 @@ import { jsxs as _jsxs, Fragment as _Fragment, jsx as _jsx } from "react/jsx-run
9
9
  */
10
10
  import React, { createContext, useContext, useEffect, useRef, useCallback, useMemo, useState, } from 'react';
11
11
  import ReactDOM from 'react-dom';
12
- import { createBuilderClient, createBuilder, createCodeClient, createBundleLoader, BundleNotFoundError, } from 'dynim-core';
12
+ import { createBuilderClient, createBuilder, createCodeClient, createBundleLoader, BundleNotFoundError, BundleAuthError, } from 'dynim-core';
13
13
  import { createSharedContext, updateSharedContext, isSharedContextReady } from './inference/sharedContext';
14
14
  import { generateThemeCSS } from './theme';
15
15
  const DynimContext = createContext(null);
@@ -88,11 +88,17 @@ export function DynimProvider({ children, config = {}, }) {
88
88
  }, []);
89
89
  // Get auth token
90
90
  const getAuthToken = useCallback(async () => {
91
+ const { sessionToken, getSession } = configRef.current;
92
+ // Fast path: static token from config (avoids HTTP call)
93
+ if (sessionToken) {
94
+ return sessionToken;
95
+ }
96
+ // Fast path: return cached token
91
97
  if (cachedTokenRef.current)
92
98
  return cachedTokenRef.current;
99
+ // Reuse in-flight promise if one exists
93
100
  if (tokenPromiseRef.current)
94
101
  return tokenPromiseRef.current;
95
- const { getSession } = configRef.current;
96
102
  if (getSession) {
97
103
  tokenPromiseRef.current = (async () => {
98
104
  try {
@@ -198,6 +204,34 @@ export function DynimProvider({ children, config = {}, }) {
198
204
  setIsBundleLoaded(false);
199
205
  return;
200
206
  }
207
+ // 401 = token expired - refresh via getSession and retry
208
+ if (error instanceof BundleAuthError) {
209
+ cachedTokenRef.current = null; // Clear stale token
210
+ const { getSession } = configRef.current;
211
+ if (getSession) {
212
+ try {
213
+ const session = await getSession();
214
+ cachedTokenRef.current = session.token;
215
+ // Retry with fresh token
216
+ const { App, cleanup } = await loader.load(bundleUrl);
217
+ setTenantApp(() => App);
218
+ setIsBundleLoaded(true);
219
+ cleanup();
220
+ return;
221
+ }
222
+ catch (retryError) {
223
+ if (retryError instanceof BundleNotFoundError) {
224
+ setTenantApp(null);
225
+ setIsBundleLoaded(false);
226
+ return;
227
+ }
228
+ // Retry also failed - show children
229
+ }
230
+ }
231
+ setTenantApp(null);
232
+ setIsBundleLoaded(false);
233
+ return;
234
+ }
201
235
  setBundleError(error);
202
236
  }
203
237
  finally {
@@ -236,14 +270,31 @@ export function DynimProvider({ children, config = {}, }) {
236
270
  console.warn('[DynimProvider] Failed to fetch theme:', error);
237
271
  }
238
272
  }, [getAuthToken]);
239
- // Mark initial load complete immediately - no eager HTTP requests
240
- // Bundle loading happens lazily when user enters builder or when
241
- // the consuming app explicitly triggers it
273
+ // Auto-load saved bundle on mount if auth is available
242
274
  useEffect(() => {
243
- if (!hasAttemptedInitialLoadRef.current) {
244
- hasAttemptedInitialLoadRef.current = true;
275
+ if (hasAttemptedInitialLoadRef.current)
276
+ return;
277
+ hasAttemptedInitialLoadRef.current = true;
278
+ const { sessionToken, getSession } = configRef.current;
279
+ // No auth configured = skip bundle load
280
+ if (!sessionToken && !getSession) {
245
281
  setIsInitialLoadComplete(true);
282
+ return;
246
283
  }
284
+ // Load bundle with the provided token
285
+ const doInitialLoad = async () => {
286
+ try {
287
+ await loadBundleRef.current?.('/api/code/bundle');
288
+ }
289
+ catch (error) {
290
+ // Errors handled in loadBundle (404 = no bundle, etc.)
291
+ console.log('[DynimProvider] Initial bundle load:', error.message);
292
+ }
293
+ finally {
294
+ setIsInitialLoadComplete(true);
295
+ }
296
+ };
297
+ doInitialLoad();
247
298
  }, []);
248
299
  // Load saved bundle
249
300
  const loadSavedBundle = useCallback(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dynim-react",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",