dynim-react 1.0.33 → 1.0.35

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.
@@ -57,13 +57,13 @@ export function DynimProvider({ children, config = {}, }) {
57
57
  // Theme state (fetched from API per project)
58
58
  const [theme, setTheme] = useState(null);
59
59
  const hasAttemptedThemeLoadRef = useRef(false);
60
- // Keep config callbacks in refs
61
- const configCallbacksRef = useRef({ onError: config.onError });
62
- configCallbacksRef.current = { onError: config.onError };
63
- // Set up shared context for bundles
60
+ // Keep config in ref to avoid re-triggering effects on every render
61
+ const configRef = useRef(config);
62
+ configRef.current = config;
63
+ // Set up shared context for bundles (only once on mount)
64
64
  useEffect(() => {
65
65
  if (!isSharedRegistryReady()) {
66
- const { packages = {}, hooks = {}, contexts = {} } = config;
66
+ const { packages = {}, hooks = {}, contexts = {} } = configRef.current;
67
67
  createSharedContext({
68
68
  React,
69
69
  ReactDOM,
@@ -75,14 +75,14 @@ export function DynimProvider({ children, config = {}, }) {
75
75
  contexts,
76
76
  });
77
77
  }
78
- }, [config]);
78
+ }, []);
79
79
  // Get auth token
80
80
  const getAuthToken = useCallback(async () => {
81
81
  if (cachedTokenRef.current)
82
82
  return cachedTokenRef.current;
83
83
  if (tokenPromiseRef.current)
84
84
  return tokenPromiseRef.current;
85
- const { getSession } = config;
85
+ const { getSession } = configRef.current;
86
86
  if (getSession) {
87
87
  tokenPromiseRef.current = (async () => {
88
88
  try {
@@ -100,24 +100,24 @@ export function DynimProvider({ children, config = {}, }) {
100
100
  return tokenPromiseRef.current;
101
101
  }
102
102
  return null;
103
- }, [config]);
104
- // Initialize code client
103
+ }, []);
104
+ // Initialize code client (only once on mount)
105
105
  useEffect(() => {
106
- const { getSession, onError } = config;
106
+ const { getSession, onError } = configRef.current;
107
107
  codeClientRef.current = createCodeClient({
108
108
  getSession,
109
109
  onMessageUpdate: setCodeMessage,
110
110
  onError: (error) => {
111
111
  console.error('[DynimProvider] Code error:', error);
112
- onError?.(error);
112
+ configRef.current.onError?.(error);
113
113
  },
114
114
  });
115
- }, [config]);
115
+ }, []);
116
116
  // Load bundle ref
117
117
  const loadBundleRef = useRef(null);
118
- // Initialize builder
118
+ // Initialize builder (only once on mount)
119
119
  useEffect(() => {
120
- const { getSession } = config;
120
+ const { getSession } = configRef.current;
121
121
  builderRef.current = createBuilder({
122
122
  getSession,
123
123
  codeClient: codeClientRef.current ?? undefined,
@@ -143,18 +143,18 @@ export function DynimProvider({ children, config = {}, }) {
143
143
  return () => {
144
144
  builderRef.current?.destroy();
145
145
  };
146
- }, [config]);
147
- // Initialize builder client
146
+ }, []);
147
+ // Initialize builder client (only once on mount)
148
148
  useEffect(() => {
149
- const { getSession, onError } = config;
149
+ const { getSession } = configRef.current;
150
150
  builderClientRef.current = createBuilderClient({
151
151
  getSession,
152
152
  onError: (error) => {
153
153
  console.error('[DynimProvider] Error:', error);
154
- onError?.(error);
154
+ configRef.current.onError?.(error);
155
155
  },
156
156
  });
157
- }, [config]);
157
+ }, []);
158
158
  // Get bundle loader
159
159
  const getBundleLoader = useCallback(() => {
160
160
  if (!bundleLoaderRef.current) {
@@ -163,7 +163,7 @@ export function DynimProvider({ children, config = {}, }) {
163
163
  includeCredentials: true,
164
164
  onError: (error) => {
165
165
  console.error('[DynimProvider] Bundle load failed:', error);
166
- configCallbacksRef.current.onError?.(error);
166
+ configRef.current.onError?.(error);
167
167
  },
168
168
  });
169
169
  }
@@ -198,17 +198,17 @@ export function DynimProvider({ children, config = {}, }) {
198
198
  useEffect(() => {
199
199
  loadBundleRef.current = loadBundle;
200
200
  }, [loadBundle]);
201
- // Prefetch auth token
201
+ // Prefetch auth token (only once on mount)
202
202
  useEffect(() => {
203
- if (config.getSession) {
203
+ if (configRef.current.getSession) {
204
204
  getAuthToken();
205
205
  }
206
- }, []);
207
- // Fetch theme from API (per project)
206
+ }, [getAuthToken]);
207
+ // Fetch theme from API (per project, only once)
208
208
  useEffect(() => {
209
209
  if (hasAttemptedThemeLoadRef.current)
210
210
  return;
211
- if (!config.getSession)
211
+ if (!configRef.current.getSession)
212
212
  return;
213
213
  hasAttemptedThemeLoadRef.current = true;
214
214
  const fetchTheme = async () => {
@@ -233,12 +233,12 @@ export function DynimProvider({ children, config = {}, }) {
233
233
  }
234
234
  };
235
235
  fetchTheme();
236
- }, [config.getSession, getAuthToken]);
236
+ }, [getAuthToken]);
237
237
  // Auto-load bundle on mount (only if we can get a valid auth token)
238
238
  useEffect(() => {
239
239
  if (hasAttemptedInitialLoadRef.current)
240
240
  return;
241
- if (!config.getSession) {
241
+ if (!configRef.current.getSession) {
242
242
  setIsInitialLoadComplete(true);
243
243
  return;
244
244
  }
@@ -265,7 +265,7 @@ export function DynimProvider({ children, config = {}, }) {
265
265
  }
266
266
  };
267
267
  doInitialLoad();
268
- }, [config.getSession, getAuthToken]);
268
+ }, [getAuthToken]);
269
269
  // Load saved bundle
270
270
  const loadSavedBundle = useCallback(async () => {
271
271
  await loadBundle('/api/code/bundle');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dynim-react",
3
- "version": "1.0.33",
3
+ "version": "1.0.35",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",