@replanejs/react 0.7.8 → 0.8.1
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/README.md +61 -53
- package/dist/index.cjs +0 -6
- package/dist/index.d.cts +4 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# @replanejs/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@replanejs/react)
|
|
4
|
+
[](https://github.com/replane-dev/replane-javascript/blob/main/LICENSE)
|
|
5
|
+
[](https://github.com/orgs/replane-dev/discussions)
|
|
6
|
+
|
|
7
|
+
React SDK for [Replane](https://github.com/replane-dev/replane) - feature flags and remote configuration.
|
|
4
8
|
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
@@ -20,14 +24,14 @@ yarn add @replanejs/react
|
|
|
20
24
|
## Quick Start
|
|
21
25
|
|
|
22
26
|
```tsx
|
|
23
|
-
import { ReplaneProvider, useConfig } from
|
|
27
|
+
import { ReplaneProvider, useConfig } from "@replanejs/react";
|
|
24
28
|
|
|
25
29
|
function App() {
|
|
26
30
|
return (
|
|
27
31
|
<ReplaneProvider
|
|
28
32
|
options={{
|
|
29
|
-
baseUrl:
|
|
30
|
-
sdkKey:
|
|
33
|
+
baseUrl: "https://your-replane-server.com",
|
|
34
|
+
sdkKey: "your-sdk-key",
|
|
31
35
|
}}
|
|
32
36
|
loader={<div>Loading...</div>}
|
|
33
37
|
>
|
|
@@ -37,13 +41,9 @@ function App() {
|
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
function MyComponent() {
|
|
40
|
-
const isFeatureEnabled = useConfig<boolean>(
|
|
44
|
+
const isFeatureEnabled = useConfig<boolean>("feature-flag-name");
|
|
41
45
|
|
|
42
|
-
return
|
|
43
|
-
<div>
|
|
44
|
-
{isFeatureEnabled ? 'Feature is enabled!' : 'Feature is disabled'}
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
46
|
+
return <div>{isFeatureEnabled ? "Feature is enabled!" : "Feature is disabled"}</div>;
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -58,19 +58,19 @@ Provider component that makes the Replane client available to your component tre
|
|
|
58
58
|
The provider creates and manages the client internally. Use an Error Boundary to handle initialization errors:
|
|
59
59
|
|
|
60
60
|
```tsx
|
|
61
|
-
import { ErrorBoundary } from
|
|
61
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
62
62
|
|
|
63
63
|
<ErrorBoundary fallback={<div>Failed to load configuration</div>}>
|
|
64
64
|
<ReplaneProvider
|
|
65
65
|
options={{
|
|
66
|
-
baseUrl:
|
|
67
|
-
sdkKey:
|
|
66
|
+
baseUrl: "https://your-replane-server.com",
|
|
67
|
+
sdkKey: "your-sdk-key",
|
|
68
68
|
}}
|
|
69
69
|
loader={<LoadingSpinner />}
|
|
70
70
|
>
|
|
71
71
|
<App />
|
|
72
72
|
</ReplaneProvider>
|
|
73
|
-
</ErrorBoundary
|
|
73
|
+
</ErrorBoundary>;
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
#### 2. With pre-created client
|
|
@@ -78,16 +78,16 @@ import { ErrorBoundary } from 'react-error-boundary';
|
|
|
78
78
|
Use this when you need more control over client lifecycle:
|
|
79
79
|
|
|
80
80
|
```tsx
|
|
81
|
-
import { createReplaneClient } from
|
|
81
|
+
import { createReplaneClient } from "@replanejs/sdk";
|
|
82
82
|
|
|
83
83
|
const client = await createReplaneClient({
|
|
84
|
-
baseUrl:
|
|
85
|
-
sdkKey:
|
|
84
|
+
baseUrl: "https://your-replane-server.com",
|
|
85
|
+
sdkKey: "your-sdk-key",
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
<ReplaneProvider client={client}>
|
|
89
89
|
<App />
|
|
90
|
-
</ReplaneProvider
|
|
90
|
+
</ReplaneProvider>;
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
#### 3. With Suspense
|
|
@@ -99,8 +99,8 @@ Integrates with React Suspense for loading states:
|
|
|
99
99
|
<Suspense fallback={<LoadingSpinner />}>
|
|
100
100
|
<ReplaneProvider
|
|
101
101
|
options={{
|
|
102
|
-
baseUrl:
|
|
103
|
-
sdkKey:
|
|
102
|
+
baseUrl: "https://your-replane-server.com",
|
|
103
|
+
sdkKey: "your-sdk-key",
|
|
104
104
|
}}
|
|
105
105
|
suspense
|
|
106
106
|
>
|
|
@@ -116,7 +116,7 @@ Restore a client from a snapshot obtained on the server. This is synchronous and
|
|
|
116
116
|
|
|
117
117
|
```tsx
|
|
118
118
|
// On the server
|
|
119
|
-
const serverClient = await createReplaneClient({ baseUrl:
|
|
119
|
+
const serverClient = await createReplaneClient({ baseUrl: "...", sdkKey: "..." });
|
|
120
120
|
const snapshot = serverClient.getSnapshot();
|
|
121
121
|
// Pass snapshot to client via props, context, or serialized HTML
|
|
122
122
|
|
|
@@ -126,13 +126,13 @@ const snapshot = serverClient.getSnapshot();
|
|
|
126
126
|
snapshot,
|
|
127
127
|
// Optional: connect for live updates
|
|
128
128
|
connection: {
|
|
129
|
-
baseUrl:
|
|
130
|
-
sdkKey:
|
|
129
|
+
baseUrl: "https://your-replane-server.com",
|
|
130
|
+
sdkKey: "your-sdk-key",
|
|
131
131
|
},
|
|
132
132
|
}}
|
|
133
133
|
>
|
|
134
134
|
<App />
|
|
135
|
-
</ReplaneProvider
|
|
135
|
+
</ReplaneProvider>;
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
The restored client is immediately available with no loading state. If `connection` is provided, it will establish a connection for real-time updates in the background.
|
|
@@ -144,17 +144,21 @@ Hook to retrieve a configuration value. Automatically subscribes to updates and
|
|
|
144
144
|
```tsx
|
|
145
145
|
function MyComponent() {
|
|
146
146
|
// Basic usage
|
|
147
|
-
const theme = useConfig<string>(
|
|
147
|
+
const theme = useConfig<string>("theme");
|
|
148
148
|
|
|
149
149
|
// With evaluation context
|
|
150
|
-
const discount = useConfig<number>(
|
|
150
|
+
const discount = useConfig<number>("discount-percentage", {
|
|
151
151
|
context: {
|
|
152
|
-
userId:
|
|
152
|
+
userId: "123",
|
|
153
153
|
isPremium: true,
|
|
154
154
|
},
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
-
return
|
|
157
|
+
return (
|
|
158
|
+
<div>
|
|
159
|
+
Theme: {theme}, Discount: {discount}%
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
158
162
|
}
|
|
159
163
|
```
|
|
160
164
|
|
|
@@ -168,7 +172,7 @@ function MyComponent() {
|
|
|
168
172
|
|
|
169
173
|
const handleClick = () => {
|
|
170
174
|
// Access replane methods directly
|
|
171
|
-
const value = replane.get(
|
|
175
|
+
const value = replane.get("some-config");
|
|
172
176
|
console.log(value);
|
|
173
177
|
};
|
|
174
178
|
|
|
@@ -181,7 +185,7 @@ function MyComponent() {
|
|
|
181
185
|
Factory function to create a typed version of `useReplane`. Returns a hook that provides the typed client directly:
|
|
182
186
|
|
|
183
187
|
```tsx
|
|
184
|
-
import { createReplaneHook } from
|
|
188
|
+
import { createReplaneHook } from "@replanejs/react";
|
|
185
189
|
|
|
186
190
|
// Define your config types
|
|
187
191
|
interface AppConfigs {
|
|
@@ -197,10 +201,10 @@ function MyComponent() {
|
|
|
197
201
|
const replane = useAppReplane();
|
|
198
202
|
|
|
199
203
|
// replane.get is now typed - autocomplete works!
|
|
200
|
-
const theme = replane.get(
|
|
204
|
+
const theme = replane.get("theme");
|
|
201
205
|
// ^? { darkMode: boolean; primaryColor: string }
|
|
202
206
|
|
|
203
|
-
return <div>Dark mode: {theme.darkMode ?
|
|
207
|
+
return <div>Dark mode: {theme.darkMode ? "on" : "off"}</div>;
|
|
204
208
|
}
|
|
205
209
|
```
|
|
206
210
|
|
|
@@ -209,7 +213,7 @@ function MyComponent() {
|
|
|
209
213
|
Factory function to create a typed version of `useConfig`. This provides autocomplete for config names and type inference for values:
|
|
210
214
|
|
|
211
215
|
```tsx
|
|
212
|
-
import { createConfigHook } from
|
|
216
|
+
import { createConfigHook } from "@replanejs/react";
|
|
213
217
|
|
|
214
218
|
// Define your config types
|
|
215
219
|
interface AppConfigs {
|
|
@@ -223,24 +227,24 @@ const useAppConfig = createConfigHook<AppConfigs>();
|
|
|
223
227
|
|
|
224
228
|
function MyComponent() {
|
|
225
229
|
// Autocomplete for config names, automatic type inference
|
|
226
|
-
const theme = useAppConfig(
|
|
230
|
+
const theme = useAppConfig("theme");
|
|
227
231
|
// ^? { darkMode: boolean; primaryColor: string }
|
|
228
232
|
|
|
229
|
-
const features = useAppConfig(
|
|
233
|
+
const features = useAppConfig("features");
|
|
230
234
|
// ^? { beta: boolean; analytics: boolean }
|
|
231
235
|
|
|
232
|
-
const maxItems = useAppConfig(
|
|
236
|
+
const maxItems = useAppConfig("maxItems");
|
|
233
237
|
// ^? number
|
|
234
238
|
|
|
235
239
|
// With context override
|
|
236
|
-
const premiumFeatures = useAppConfig(
|
|
237
|
-
context: { userId:
|
|
240
|
+
const premiumFeatures = useAppConfig("features", {
|
|
241
|
+
context: { userId: "123", plan: "premium" },
|
|
238
242
|
});
|
|
239
243
|
|
|
240
244
|
return (
|
|
241
245
|
<div>
|
|
242
|
-
<p>Dark mode: {theme.darkMode ?
|
|
243
|
-
<p>Beta enabled: {features.beta ?
|
|
246
|
+
<p>Dark mode: {theme.darkMode ? "on" : "off"}</p>
|
|
247
|
+
<p>Beta enabled: {features.beta ? "yes" : "no"}</p>
|
|
244
248
|
<p>Max items: {maxItems}</p>
|
|
245
249
|
</div>
|
|
246
250
|
);
|
|
@@ -252,12 +256,12 @@ function MyComponent() {
|
|
|
252
256
|
Utility function to clear the suspense cache. Useful for testing or forcing re-initialization:
|
|
253
257
|
|
|
254
258
|
```tsx
|
|
255
|
-
import { clearSuspenseCache } from
|
|
259
|
+
import { clearSuspenseCache } from "@replanejs/react";
|
|
256
260
|
|
|
257
261
|
// Clear cache for specific options
|
|
258
262
|
clearSuspenseCache({
|
|
259
|
-
baseUrl:
|
|
260
|
-
sdkKey:
|
|
263
|
+
baseUrl: "https://your-replane-server.com",
|
|
264
|
+
sdkKey: "your-sdk-key",
|
|
261
265
|
});
|
|
262
266
|
|
|
263
267
|
// Clear entire cache
|
|
@@ -271,16 +275,16 @@ The SDK is fully typed. For the best TypeScript experience, use the hook factory
|
|
|
271
275
|
```tsx
|
|
272
276
|
// Define all your config types in one interface
|
|
273
277
|
interface AppConfigs {
|
|
274
|
-
|
|
278
|
+
"theme-config": {
|
|
275
279
|
darkMode: boolean;
|
|
276
280
|
primaryColor: string;
|
|
277
281
|
};
|
|
278
|
-
|
|
282
|
+
"feature-flags": {
|
|
279
283
|
newUI: boolean;
|
|
280
284
|
beta: boolean;
|
|
281
285
|
};
|
|
282
|
-
|
|
283
|
-
|
|
286
|
+
"max-items": number;
|
|
287
|
+
"welcome-message": string;
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
// Create typed hooks once
|
|
@@ -289,7 +293,7 @@ const useAppConfig = createConfigHook<AppConfigs>();
|
|
|
289
293
|
|
|
290
294
|
// Use throughout your app with full type safety
|
|
291
295
|
function Settings() {
|
|
292
|
-
const theme = useAppConfig(
|
|
296
|
+
const theme = useAppConfig("theme-config");
|
|
293
297
|
// ^? { darkMode: boolean; primaryColor: string }
|
|
294
298
|
|
|
295
299
|
const replane = useAppReplane();
|
|
@@ -298,7 +302,7 @@ function Settings() {
|
|
|
298
302
|
|
|
299
303
|
return (
|
|
300
304
|
<div style={{ color: theme.primaryColor }}>
|
|
301
|
-
Dark mode: {theme.darkMode ?
|
|
305
|
+
Dark mode: {theme.darkMode ? "enabled" : "disabled"}
|
|
302
306
|
</div>
|
|
303
307
|
);
|
|
304
308
|
}
|
|
@@ -309,7 +313,7 @@ function Settings() {
|
|
|
309
313
|
The provider throws errors during rendering so they can be caught by React Error Boundaries:
|
|
310
314
|
|
|
311
315
|
```tsx
|
|
312
|
-
import { Component, ReactNode } from
|
|
316
|
+
import { Component, ReactNode } from "react";
|
|
313
317
|
|
|
314
318
|
class ErrorBoundary extends Component<
|
|
315
319
|
{ children: ReactNode; fallback: ReactNode },
|
|
@@ -334,13 +338,13 @@ class ErrorBoundary extends Component<
|
|
|
334
338
|
<ReplaneProvider options={options} loader={<Loading />}>
|
|
335
339
|
<App />
|
|
336
340
|
</ReplaneProvider>
|
|
337
|
-
</ErrorBoundary
|
|
341
|
+
</ErrorBoundary>;
|
|
338
342
|
```
|
|
339
343
|
|
|
340
344
|
Or use a library like `react-error-boundary`:
|
|
341
345
|
|
|
342
346
|
```tsx
|
|
343
|
-
import { ErrorBoundary } from
|
|
347
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
344
348
|
|
|
345
349
|
<ErrorBoundary
|
|
346
350
|
fallbackRender={({ error, resetErrorBoundary }) => (
|
|
@@ -354,9 +358,13 @@ import { ErrorBoundary } from 'react-error-boundary';
|
|
|
354
358
|
<ReplaneProvider options={options} loader={<Loading />}>
|
|
355
359
|
<App />
|
|
356
360
|
</ReplaneProvider>
|
|
357
|
-
</ErrorBoundary
|
|
361
|
+
</ErrorBoundary>;
|
|
358
362
|
```
|
|
359
363
|
|
|
364
|
+
## Community
|
|
365
|
+
|
|
366
|
+
Have questions or want to discuss Replane? Join the conversation in [GitHub Discussions](https://github.com/orgs/replane-dev/discussions).
|
|
367
|
+
|
|
360
368
|
## License
|
|
361
369
|
|
|
362
370
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -348,12 +348,6 @@ function ReplaneProvider(props) {
|
|
|
348
348
|
|
|
349
349
|
//#endregion
|
|
350
350
|
exports.ReplaneProvider = ReplaneProvider;
|
|
351
|
-
Object.defineProperty(exports, 'clearSnapshotCache', {
|
|
352
|
-
enumerable: true,
|
|
353
|
-
get: function () {
|
|
354
|
-
return __replanejs_sdk.clearSnapshotCache;
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
351
|
exports.clearSuspenseCache = clearSuspenseCache;
|
|
358
352
|
exports.createConfigHook = createConfigHook;
|
|
359
353
|
exports.createReplaneHook = createReplaneHook;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
-
import { GetConfigOptions, GetReplaneSnapshotOptions, ReplaneClient, ReplaneClientOptions, ReplaneSnapshot,
|
|
2
|
+
import { GetConfigOptions, GetReplaneSnapshotOptions, ReplaneClient, ReplaneClientOptions, ReplaneSnapshot, getReplaneSnapshot } from "@replanejs/sdk";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
@@ -108,7 +108,7 @@ declare function ReplaneProvider<T extends object>(props: ReplaneProviderProps<T
|
|
|
108
108
|
//#endregion
|
|
109
109
|
//#region src/hooks.d.ts
|
|
110
110
|
declare function useReplane<T extends object = UntypedReplaneConfig>(): ReplaneClient<T>;
|
|
111
|
-
declare function useConfig<T>(name: string, options?: GetConfigOptions): T;
|
|
111
|
+
declare function useConfig<T>(name: string, options?: GetConfigOptions<T>): T;
|
|
112
112
|
/**
|
|
113
113
|
* Creates a typed version of useReplane hook.
|
|
114
114
|
*
|
|
@@ -146,7 +146,7 @@ declare function createReplaneHook<TConfigs extends object>(): () => ReplaneClie
|
|
|
146
146
|
* }
|
|
147
147
|
* ```
|
|
148
148
|
*/
|
|
149
|
-
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions) => TConfigs[K];
|
|
149
|
+
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions<TConfigs[K]>) => TConfigs[K];
|
|
150
150
|
/**
|
|
151
151
|
* Hook for creating stateful resources with cleanup support.
|
|
152
152
|
* Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.
|
|
@@ -163,5 +163,5 @@ declare function createConfigHook<TConfigs extends object>(): <K extends keyof T
|
|
|
163
163
|
*/
|
|
164
164
|
declare function clearSuspenseCache<T extends object>(options?: ReplaneClientOptions<T>): void;
|
|
165
165
|
//#endregion
|
|
166
|
-
export { type GetReplaneSnapshotOptions, ReplaneProvider, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps,
|
|
166
|
+
export { type GetReplaneSnapshotOptions, ReplaneProvider, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
167
167
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/provider.tsx","../src/hooks.ts","../src/useReplaneClient.ts"],"sourcesContent":[],"mappings":";;;;;KAOY,oBAAA,GAAuB;AASnC;;;AAEwB,UAFP,8BAEO,CAAA,UAAA,MAAA,GAF2C,oBAE3C,CAAA,CAAA;EAAC;EAAF,MACX,EADF,aACE,CADY,CACZ,CAAA;EAAS,QAAA,EAAT,SAAS;AAMrB;;;;AAEW,UAFM,+BAEN,CAAA,UAAA,MAAA,GAFyD,oBAEzD,CAAA,CAAA;EAAoB;EACV,OAOQ,EARlB,oBAQkB,CARG,CAQH,CAAA;EAAC,QAAjB,EAPD,SAOC;EAAe;AAMR;AAUpB;;;;EACoC,QAAhC,CAAA,EAjBS,eAiBT,CAjByB,CAiBzB,CAAA;EAA8B;;AACC;;;WAZxB;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/provider.tsx","../src/hooks.ts","../src/useReplaneClient.ts"],"sourcesContent":[],"mappings":";;;;;KAOY,oBAAA,GAAuB;AASnC;;;AAEwB,UAFP,8BAEO,CAAA,UAAA,MAAA,GAF2C,oBAE3C,CAAA,CAAA;EAAC;EAAF,MACX,EADF,aACE,CADY,CACZ,CAAA;EAAS,QAAA,EAAT,SAAS;AAMrB;;;;AAEW,UAFM,+BAEN,CAAA,UAAA,MAAA,GAFyD,oBAEzD,CAAA,CAAA;EAAoB;EACV,OAOQ,EARlB,oBAQkB,CARG,CAQH,CAAA;EAAC,QAAjB,EAPD,SAOC;EAAe;AAMR;AAUpB;;;;EACoC,QAAhC,CAAA,EAjBS,eAiBT,CAjByB,CAiBzB,CAAA;EAA8B;;AACC;;;WAZxB;EC4GK;;;;;AAAgE;;;KDlGpE,wCAAwC,wBAChD,+BAA+B,KAC/B,gCAAgC;AE9CpC;;;;;;;;;;AFAA;AASA;;;;;;AAGqB;AAMrB;;;;;;;;;AAgBoB;AAUpB;;;;;;;AAEmC;;;;ACgGnC;;;;;AAAgF;;;;AC9IhF;;;;;AAAoF;AAQpF;;;;;AAA4E;AAqC5E;;AACmD,iBDgGnC,eChGmC,CAAA,UAAA,MAAA,CAAA,CAAA,KAAA,EDgGM,oBChGN,CDgG2B,CChG3B,CAAA,CAAA,EDgG6B,kBAAA,CAAA,GAAA,CAAA,OChG7B;;;;iBA9CnC,8BAA8B,yBAAyB,cAAc;iBAQrE,qCAAqC,iBAAiB,KAAK;;AFR3E;AASA;;;;;;AAGqB;AAMrB;;;;;;;;;AAgBoB,iBEWJ,iBFXI,CAAA,iBAAA,MAAA,CAAA,CAAA,CAAA,EAAA,GAAA,GEYiB,aFZjB,CEY+B,QFZ/B,CAAA;AAUpB;;;;;;;AAEmC;;;;ACgGnC;;;;;AAAgF;;iBCzEhE,8DACiC,gBACvC,aACI,iBAAiB,SAAS,QACnC,SAAS;;AAzEd;;;;;AAAoF;AAQpF;;;;;;;AFsCoC,iBGyEpB,kBHzEoB,CAAA,UAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EGyE2B,oBHzE3B,CGyEgD,CHzEhD,CAAA,CAAA,EAAA,IAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import { GetConfigOptions, GetReplaneSnapshotOptions, ReplaneClient, ReplaneClientOptions, ReplaneSnapshot,
|
|
2
|
+
import { GetConfigOptions, GetReplaneSnapshotOptions, ReplaneClient, ReplaneClientOptions, ReplaneSnapshot, getReplaneSnapshot } from "@replanejs/sdk";
|
|
3
3
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
@@ -108,7 +108,7 @@ declare function ReplaneProvider<T extends object>(props: ReplaneProviderProps<T
|
|
|
108
108
|
//#endregion
|
|
109
109
|
//#region src/hooks.d.ts
|
|
110
110
|
declare function useReplane<T extends object = UntypedReplaneConfig>(): ReplaneClient<T>;
|
|
111
|
-
declare function useConfig<T>(name: string, options?: GetConfigOptions): T;
|
|
111
|
+
declare function useConfig<T>(name: string, options?: GetConfigOptions<T>): T;
|
|
112
112
|
/**
|
|
113
113
|
* Creates a typed version of useReplane hook.
|
|
114
114
|
*
|
|
@@ -146,7 +146,7 @@ declare function createReplaneHook<TConfigs extends object>(): () => ReplaneClie
|
|
|
146
146
|
* }
|
|
147
147
|
* ```
|
|
148
148
|
*/
|
|
149
|
-
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions) => TConfigs[K];
|
|
149
|
+
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions<TConfigs[K]>) => TConfigs[K];
|
|
150
150
|
/**
|
|
151
151
|
* Hook for creating stateful resources with cleanup support.
|
|
152
152
|
* Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.
|
|
@@ -163,5 +163,5 @@ declare function createConfigHook<TConfigs extends object>(): <K extends keyof T
|
|
|
163
163
|
*/
|
|
164
164
|
declare function clearSuspenseCache<T extends object>(options?: ReplaneClientOptions<T>): void;
|
|
165
165
|
//#endregion
|
|
166
|
-
export { type GetReplaneSnapshotOptions, ReplaneProvider, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps,
|
|
166
|
+
export { type GetReplaneSnapshotOptions, ReplaneProvider, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
167
167
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/provider.tsx","../src/hooks.ts","../src/useReplaneClient.ts"],"sourcesContent":[],"mappings":";;;;;KAOY,oBAAA,GAAuB;AASnC;;;AAEwB,UAFP,8BAEO,CAAA,UAAA,MAAA,GAF2C,oBAE3C,CAAA,CAAA;EAAC;EAAF,MACX,EADF,aACE,CADY,CACZ,CAAA;EAAS,QAAA,EAAT,SAAS;AAMrB;;;;AAEW,UAFM,+BAEN,CAAA,UAAA,MAAA,GAFyD,oBAEzD,CAAA,CAAA;EAAoB;EACV,OAOQ,EARlB,oBAQkB,CARG,CAQH,CAAA;EAAC,QAAjB,EAPD,SAOC;EAAe;AAMR;AAUpB;;;;EACoC,QAAhC,CAAA,EAjBS,eAiBT,CAjByB,CAiBzB,CAAA;EAA8B;;AACC;;;WAZxB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/provider.tsx","../src/hooks.ts","../src/useReplaneClient.ts"],"sourcesContent":[],"mappings":";;;;;KAOY,oBAAA,GAAuB;AASnC;;;AAEwB,UAFP,8BAEO,CAAA,UAAA,MAAA,GAF2C,oBAE3C,CAAA,CAAA;EAAC;EAAF,MACX,EADF,aACE,CADY,CACZ,CAAA;EAAS,QAAA,EAAT,SAAS;AAMrB;;;;AAEW,UAFM,+BAEN,CAAA,UAAA,MAAA,GAFyD,oBAEzD,CAAA,CAAA;EAAoB;EACV,OAOQ,EARlB,oBAQkB,CARG,CAQH,CAAA;EAAC,QAAjB,EAPD,SAOC;EAAe;AAMR;AAUpB;;;;EACoC,QAAhC,CAAA,EAjBS,eAiBT,CAjByB,CAiBzB,CAAA;EAA8B;;AACC;;;WAZxB;EC4GK;;;;;AAAgE;;;KDlGpE,wCAAwC,wBAChD,+BAA+B,KAC/B,gCAAgC;AE9CpC;;;;;;;;;;AFAA;AASA;;;;;;AAGqB;AAMrB;;;;;;;;;AAgBoB;AAUpB;;;;;;;AAEmC;;;;ACgGnC;;;;;AAAgF;;;;AC9IhF;;;;;AAAoF;AAQpF;;;;;AAA4E;AAqC5E;;AACmD,iBDgGnC,eChGmC,CAAA,UAAA,MAAA,CAAA,CAAA,KAAA,EDgGM,oBChGN,CDgG2B,CChG3B,CAAA,CAAA,EDgG6B,kBAAA,CAAA,GAAA,CAAA,OChG7B;;;;iBA9CnC,8BAA8B,yBAAyB,cAAc;iBAQrE,qCAAqC,iBAAiB,KAAK;;AFR3E;AASA;;;;;;AAGqB;AAMrB;;;;;;;;;AAgBoB,iBEWJ,iBFXI,CAAA,iBAAA,MAAA,CAAA,CAAA,CAAA,EAAA,GAAA,GEYiB,aFZjB,CEY+B,QFZ/B,CAAA;AAUpB;;;;;;;AAEmC;;;;ACgGnC;;;;;AAAgF;;iBCzEhE,8DACiC,gBACvC,aACI,iBAAiB,SAAS,QACnC,SAAS;;AAzEd;;;;;AAAoF;AAQpF;;;;;;;AFsCoC,iBGyEpB,kBHzEoB,CAAA,UAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EGyE2B,oBHzE3B,CGyEgD,CHzEhD,CAAA,CAAA,EAAA,IAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { createReplaneClient, getReplaneSnapshot, restoreReplaneClient } from "@replanejs/sdk";
|
|
3
3
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/context.ts
|
|
@@ -324,5 +324,5 @@ function ReplaneProvider(props) {
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
//#endregion
|
|
327
|
-
export { ReplaneProvider,
|
|
327
|
+
export { ReplaneProvider, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
328
328
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["options: ReplaneClientOptions<T>","options?: ReplaneClientOptions<T>","name: string","options?: GetConfigOptions","callback: () => void","name: K","factory: () => T","cleanup: (value: T) => void","deps: React.DependencyList","props: ReplaneProviderProps<T>","value: ReplaneContextValue<T>","props: ReplaneProviderProps<T>"],"sources":["../src/context.ts","../src/useReplaneClient.ts","../src/hooks.ts","../src/types.ts","../src/provider.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { ReplaneContextValue } from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const ReplaneContext = createContext<ReplaneContextValue<any> | null>(null);\n","import { useEffect, useRef, useState } from \"react\";\nimport { createReplaneClient } from \"@replanejs/sdk\";\nimport type { ReplaneClient, ReplaneClientOptions } from \"@replanejs/sdk\";\n\ntype ClientState<T extends object> =\n | { status: \"loading\"; client: null; error: null }\n | { status: \"ready\"; client: ReplaneClient<T>; error: null }\n | { status: \"error\"; client: null; error: Error };\n\n// Cache for suspense promise tracking\nconst suspenseCache = new Map<\n string,\n {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n promise: Promise<ReplaneClient<any>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result?: ReplaneClient<any>;\n error?: Error;\n }\n>();\n\nfunction getCacheKey<T extends object>(options: ReplaneClientOptions<T>): string {\n return `${options.baseUrl}:${options.sdkKey}`;\n}\n\ntype ErrorConstructor = new (message: string, options?: { cause?: unknown }) => Error;\n\n/**\n * Hook to manage ReplaneClient creation internally.\n * Handles loading state and cleanup.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useReplaneClientInternal<T extends object = any>(\n options: ReplaneClientOptions<T>\n): ClientState<T> {\n const [state, setState] = useState<ClientState<T>>({\n status: \"loading\",\n client: null,\n error: null,\n });\n const clientRef = useRef<ReplaneClient<T> | null>(null);\n const optionsRef = useRef(options);\n\n useEffect(() => {\n let cancelled = false;\n\n async function initClient() {\n try {\n const client = await createReplaneClient<T>(optionsRef.current);\n if (cancelled) {\n client.close();\n return;\n }\n clientRef.current = client;\n setState({ status: \"ready\", client, error: null });\n } catch (err) {\n if (cancelled) return;\n const error =\n err instanceof Error ? err : new (Error as ErrorConstructor)(String(err), { cause: err });\n setState({ status: \"error\", client: null, error });\n }\n }\n\n initClient();\n\n return () => {\n cancelled = true;\n if (clientRef.current) {\n clientRef.current.close();\n clientRef.current = null;\n }\n };\n }, []);\n\n return state;\n}\n\n/**\n * Hook for Suspense-based client creation.\n * Throws a promise while loading, throws error on failure.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useReplaneClientSuspense<T extends object = any>(\n options: ReplaneClientOptions<T>\n): ReplaneClient<T> {\n const cacheKey = getCacheKey(options);\n const cached = suspenseCache.get(cacheKey);\n\n if (cached) {\n if (cached.error) {\n throw cached.error;\n }\n if (cached.result) {\n return cached.result as ReplaneClient<T>;\n }\n // Still loading, throw the promise\n throw cached.promise;\n }\n\n // First time - create the promise\n const promise = createReplaneClient<T>(options)\n .then((client) => {\n const entry = suspenseCache.get(cacheKey);\n if (entry) {\n entry.result = client;\n }\n return client;\n })\n .catch((err) => {\n const entry = suspenseCache.get(cacheKey);\n if (entry) {\n entry.error = err instanceof Error ? err : new Error(String(err));\n }\n throw err;\n });\n\n suspenseCache.set(cacheKey, { promise });\n throw promise;\n}\n\n/**\n * Clear the suspense cache for a specific options configuration.\n * Useful for testing or when you need to force re-initialization.\n */\nexport function clearSuspenseCache<T extends object>(options?: ReplaneClientOptions<T>): void {\n if (options) {\n suspenseCache.delete(getCacheKey(options));\n } else {\n suspenseCache.clear();\n }\n}\n","import { useCallback, useContext, useEffect, useRef, useSyncExternalStore } from \"react\";\nimport { ReplaneContext } from \"./context\";\nimport type { UntypedReplaneConfig } from \"./types\";\nimport type { ReplaneClient, GetConfigOptions } from \"@replanejs/sdk\";\n\nexport function useReplane<T extends object = UntypedReplaneConfig>(): ReplaneClient<T> {\n const context = useContext(ReplaneContext);\n if (!context) {\n throw new Error(\"useReplane must be used within a ReplaneProvider\");\n }\n return context.client as ReplaneClient<T>;\n}\n\nexport function useConfig<T>(name: string, options?: GetConfigOptions): T {\n const client = useReplane();\n\n const subscribe = useCallback(\n (callback: () => void) => {\n return client.subscribe(name, callback);\n },\n [client, name]\n );\n\n const get = useCallback(() => {\n return client.get(name, options) as T;\n }, [client, name, options]);\n\n const value = useSyncExternalStore(subscribe, get, get);\n\n return value;\n}\n\n/**\n * Creates a typed version of useReplane hook.\n *\n * @example\n * ```tsx\n * interface AppConfigs {\n * theme: { darkMode: boolean };\n * features: { beta: boolean };\n * }\n *\n * const useAppReplane = createReplaneHook<AppConfigs>();\n *\n * function MyComponent() {\n * const replane = useAppReplane();\n * // replane.get(\"theme\") returns { darkMode: boolean }\n * }\n * ```\n */\nexport function createReplaneHook<TConfigs extends object>() {\n return function useTypedReplane(): ReplaneClient<TConfigs> {\n return useReplane<TConfigs>();\n };\n}\n\n/**\n * Creates a typed version of useConfig hook.\n *\n * @example\n * ```tsx\n * interface AppConfigs {\n * theme: { darkMode: boolean };\n * features: { beta: boolean };\n * }\n *\n * const useAppConfig = createConfigHook<AppConfigs>();\n *\n * function MyComponent() {\n * const theme = useAppConfig(\"theme\");\n * // theme is typed as { darkMode: boolean }\n * }\n * ```\n */\nexport function createConfigHook<TConfigs extends object>() {\n return function useTypedConfig<K extends keyof TConfigs>(\n name: K,\n options?: GetConfigOptions\n ): TConfigs[K] {\n return useConfig<TConfigs[K]>(String(name), options);\n };\n}\n\n/**\n * Hook for creating stateful resources with cleanup support.\n * Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.\n *\n * @param factory - Function that creates the resource\n * @param cleanup - Function that cleans up the resource\n * @param deps - Dependencies array (resource is recreated when these change)\n */\nexport function useStateful<T>(\n factory: () => T,\n cleanup: (value: T) => void,\n deps: React.DependencyList\n): T {\n const valueRef = useRef<T | null>(null);\n const initializedRef = useRef(false);\n\n // Create initial value synchronously on first render\n if (!initializedRef.current) {\n valueRef.current = factory();\n initializedRef.current = true;\n }\n\n useEffect(() => {\n // On mount or deps change, we may need to recreate\n // If this is not the initial mount, recreate the value\n if (valueRef.current === null) {\n valueRef.current = factory();\n }\n\n return () => {\n if (valueRef.current !== null) {\n cleanup(valueRef.current);\n valueRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n return valueRef.current as T;\n}\n","import type {\n ReplaneClient,\n ReplaneClientOptions,\n ReplaneSnapshot,\n} from \"@replanejs/sdk\";\nimport type { ReactNode } from \"react\";\n\nexport type UntypedReplaneConfig = Record<string, unknown>;\n\nexport interface ReplaneContextValue<T extends object = UntypedReplaneConfig> {\n client: ReplaneClient<T>;\n}\n\n/**\n * Props for ReplaneProvider when using a pre-created client.\n */\nexport interface ReplaneProviderWithClientProps<T extends object = UntypedReplaneConfig> {\n /** Pre-created ReplaneClient instance */\n client: ReplaneClient<T>;\n children: ReactNode;\n}\n\n/**\n * Props for ReplaneProvider when letting it manage the client internally.\n */\nexport interface ReplaneProviderWithOptionsProps<T extends object = UntypedReplaneConfig> {\n /** Options to create or restore the ReplaneClient */\n options: ReplaneClientOptions<T>;\n children: ReactNode;\n /**\n * Optional snapshot from server-side rendering.\n * When provided, the client will be restored from the snapshot synchronously\n * instead of fetching configs from the server.\n * The `options` will be used for live updates connection if provided.\n */\n snapshot?: ReplaneSnapshot<T>;\n /**\n * Optional loading component to show while the client is initializing.\n * If not provided and suspense is false/undefined, children will not render until ready.\n * Ignored when snapshot is provided (restoration is synchronous).\n */\n loader?: ReactNode;\n /**\n * If true, uses React Suspense for loading state.\n * The provider will throw a promise that Suspense can catch.\n * Ignored when snapshot is provided (restoration is synchronous).\n * @default false\n */\n suspense?: boolean;\n}\n\nexport type ReplaneProviderProps<T extends object = UntypedReplaneConfig> =\n | ReplaneProviderWithClientProps<T>\n | ReplaneProviderWithOptionsProps<T>;\n\n/**\n * Type guard to check if props contain a pre-created client.\n */\nexport function hasClient<T extends object>(\n props: ReplaneProviderProps<T>\n): props is ReplaneProviderWithClientProps<T> {\n return \"client\" in props && props.client !== undefined;\n}\n\n/**\n * Type guard to check if props contain options (with or without snapshot).\n */\nexport function hasOptions<T extends object>(\n props: ReplaneProviderProps<T>\n): props is ReplaneProviderWithOptionsProps<T> {\n return \"options\" in props && props.options !== undefined;\n}\n","import { useMemo } from \"react\";\nimport { restoreReplaneClient } from \"@replanejs/sdk\";\nimport { ReplaneContext } from \"./context\";\nimport { useReplaneClientInternal, useReplaneClientSuspense } from \"./useReplaneClient\";\nimport { useStateful } from \"./hooks\";\nimport type {\n ReplaneProviderProps,\n ReplaneProviderWithClientProps,\n ReplaneProviderWithOptionsProps,\n ReplaneContextValue,\n} from \"./types\";\nimport { hasClient } from \"./types\";\n\n/**\n * Internal provider component for pre-created client.\n */\nfunction ReplaneProviderWithClient<T extends object>({\n client,\n children,\n}: ReplaneProviderWithClientProps<T>) {\n const value = useMemo<ReplaneContextValue<T>>(() => ({ client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for restoring client from snapshot.\n * Uses restoreReplaneClient which is synchronous.\n */\nfunction ReplaneProviderWithSnapshot<T extends object>({\n options,\n snapshot,\n children,\n}: ReplaneProviderWithOptionsProps<T> & { snapshot: NonNullable<ReplaneProviderWithOptionsProps<T>[\"snapshot\"]> }) {\n const client = useStateful(\n () =>\n restoreReplaneClient<T>({\n snapshot,\n connection: {\n baseUrl: options.baseUrl,\n sdkKey: options.sdkKey,\n fetchFn: options.fetchFn,\n requestTimeoutMs: options.requestTimeoutMs,\n retryDelayMs: options.retryDelayMs,\n inactivityTimeoutMs: options.inactivityTimeoutMs,\n logger: options.logger,\n },\n context: options.context,\n }),\n (c) => c.close(),\n [snapshot, options]\n );\n const value = useMemo<ReplaneContextValue<T>>(() => ({ client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for options-based client creation (non-suspense).\n * Throws errors during rendering so they can be caught by Error Boundaries.\n */\nfunction ReplaneProviderWithOptions<T extends object>({\n options,\n children,\n loader,\n}: ReplaneProviderWithOptionsProps<T>) {\n const state = useReplaneClientInternal<T>(options);\n\n if (state.status === \"loading\") {\n return <>{loader ?? null}</>;\n }\n\n if (state.status === \"error\") {\n // Throw error during render so it can be caught by Error Boundary\n throw state.error;\n }\n\n const value: ReplaneContextValue<T> = { client: state.client };\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for options-based client creation with Suspense.\n */\nfunction ReplaneProviderWithSuspense<T extends object>({\n options,\n children,\n}: ReplaneProviderWithOptionsProps<T>) {\n const client = useReplaneClientSuspense<T>(options);\n const value = useMemo<ReplaneContextValue<T>>(() => ({ client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Provider component that makes a ReplaneClient available to the component tree.\n *\n * Can be used in three ways:\n *\n * 1. With a pre-created client:\n * ```tsx\n * const client = await createReplaneClient({ ... });\n * <ReplaneProvider client={client}>\n * <App />\n * </ReplaneProvider>\n * ```\n *\n * 2. With options (client managed internally):\n * ```tsx\n * <ErrorBoundary fallback={<ErrorMessage />}>\n * <ReplaneProvider\n * options={{ baseUrl: '...', sdkKey: '...' }}\n * loader={<LoadingSpinner />}\n * >\n * <App />\n * </ReplaneProvider>\n * </ErrorBoundary>\n * ```\n *\n * 3. With Suspense:\n * ```tsx\n * <ErrorBoundary fallback={<ErrorMessage />}>\n * <Suspense fallback={<LoadingSpinner />}>\n * <ReplaneProvider\n * options={{ baseUrl: '...', sdkKey: '...' }}\n * suspense\n * >\n * <App />\n * </ReplaneProvider>\n * </Suspense>\n * </ErrorBoundary>\n * ```\n *\n * 4. With a snapshot (for SSR/hydration):\n * ```tsx\n * // On the server, get a snapshot from the client\n * const snapshot = serverClient.getSnapshot();\n *\n * // On the client, restore from the snapshot with live updates\n * <ReplaneProvider\n * options={{ baseUrl: '...', sdkKey: '...' }}\n * snapshot={snapshot}\n * >\n * <App />\n * </ReplaneProvider>\n * ```\n *\n * Errors during client initialization are thrown during rendering,\n * allowing them to be caught by React Error Boundaries.\n */\nexport function ReplaneProvider<T extends object>(props: ReplaneProviderProps<T>) {\n if (hasClient(props)) {\n return <ReplaneProviderWithClient {...props} />;\n }\n\n // Has options - check if snapshot is provided\n if (props.snapshot) {\n return <ReplaneProviderWithSnapshot {...props} snapshot={props.snapshot} />;\n }\n\n if (props.suspense) {\n return <ReplaneProviderWithSuspense {...props} />;\n }\n\n return <ReplaneProviderWithOptions {...props} />;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["options: ReplaneClientOptions<T>","options?: ReplaneClientOptions<T>","name: string","options?: GetConfigOptions<T>","callback: () => void","name: K","options?: GetConfigOptions<TConfigs[K]>","factory: () => T","cleanup: (value: T) => void","deps: React.DependencyList","props: ReplaneProviderProps<T>","value: ReplaneContextValue<T>","props: ReplaneProviderProps<T>"],"sources":["../src/context.ts","../src/useReplaneClient.ts","../src/hooks.ts","../src/types.ts","../src/provider.tsx"],"sourcesContent":["'use client';\n\nimport { createContext } from \"react\";\nimport type { ReplaneContextValue } from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const ReplaneContext = createContext<ReplaneContextValue<any> | null>(null);\n","'use client';\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { createReplaneClient } from \"@replanejs/sdk\";\nimport type { ReplaneClient, ReplaneClientOptions } from \"@replanejs/sdk\";\n\ntype ClientState<T extends object> =\n | { status: \"loading\"; client: null; error: null }\n | { status: \"ready\"; client: ReplaneClient<T>; error: null }\n | { status: \"error\"; client: null; error: Error };\n\n// Cache for suspense promise tracking\nconst suspenseCache = new Map<\n string,\n {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n promise: Promise<ReplaneClient<any>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result?: ReplaneClient<any>;\n error?: Error;\n }\n>();\n\nfunction getCacheKey<T extends object>(options: ReplaneClientOptions<T>): string {\n return `${options.baseUrl}:${options.sdkKey}`;\n}\n\ntype ErrorConstructor = new (message: string, options?: { cause?: unknown }) => Error;\n\n/**\n * Hook to manage ReplaneClient creation internally.\n * Handles loading state and cleanup.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useReplaneClientInternal<T extends object = any>(\n options: ReplaneClientOptions<T>\n): ClientState<T> {\n const [state, setState] = useState<ClientState<T>>({\n status: \"loading\",\n client: null,\n error: null,\n });\n const clientRef = useRef<ReplaneClient<T> | null>(null);\n const optionsRef = useRef(options);\n\n useEffect(() => {\n let cancelled = false;\n\n async function initClient() {\n try {\n const client = await createReplaneClient<T>(optionsRef.current);\n if (cancelled) {\n client.close();\n return;\n }\n clientRef.current = client;\n setState({ status: \"ready\", client, error: null });\n } catch (err) {\n if (cancelled) return;\n const error =\n err instanceof Error ? err : new (Error as ErrorConstructor)(String(err), { cause: err });\n setState({ status: \"error\", client: null, error });\n }\n }\n\n initClient();\n\n return () => {\n cancelled = true;\n if (clientRef.current) {\n clientRef.current.close();\n clientRef.current = null;\n }\n };\n }, []);\n\n return state;\n}\n\n/**\n * Hook for Suspense-based client creation.\n * Throws a promise while loading, throws error on failure.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useReplaneClientSuspense<T extends object = any>(\n options: ReplaneClientOptions<T>\n): ReplaneClient<T> {\n const cacheKey = getCacheKey(options);\n const cached = suspenseCache.get(cacheKey);\n\n if (cached) {\n if (cached.error) {\n throw cached.error;\n }\n if (cached.result) {\n return cached.result as ReplaneClient<T>;\n }\n // Still loading, throw the promise\n throw cached.promise;\n }\n\n // First time - create the promise\n const promise = createReplaneClient<T>(options)\n .then((client) => {\n const entry = suspenseCache.get(cacheKey);\n if (entry) {\n entry.result = client;\n }\n return client;\n })\n .catch((err) => {\n const entry = suspenseCache.get(cacheKey);\n if (entry) {\n entry.error = err instanceof Error ? err : new Error(String(err));\n }\n throw err;\n });\n\n suspenseCache.set(cacheKey, { promise });\n throw promise;\n}\n\n/**\n * Clear the suspense cache for a specific options configuration.\n * Useful for testing or when you need to force re-initialization.\n */\nexport function clearSuspenseCache<T extends object>(options?: ReplaneClientOptions<T>): void {\n if (options) {\n suspenseCache.delete(getCacheKey(options));\n } else {\n suspenseCache.clear();\n }\n}\n","'use client';\n\nimport { useCallback, useContext, useEffect, useRef, useSyncExternalStore } from \"react\";\nimport { ReplaneContext } from \"./context\";\nimport type { UntypedReplaneConfig } from \"./types\";\nimport type { ReplaneClient, GetConfigOptions } from \"@replanejs/sdk\";\n\nexport function useReplane<T extends object = UntypedReplaneConfig>(): ReplaneClient<T> {\n const context = useContext(ReplaneContext);\n if (!context) {\n throw new Error(\"useReplane must be used within a ReplaneProvider\");\n }\n return context.client as ReplaneClient<T>;\n}\n\nexport function useConfig<T>(name: string, options?: GetConfigOptions<T>): T {\n const client = useReplane();\n\n const subscribe = useCallback(\n (callback: () => void) => {\n return client.subscribe(name, callback);\n },\n [client, name]\n );\n\n const get = useCallback(() => {\n return client.get(name, options) as T;\n }, [client, name, options]);\n\n const value = useSyncExternalStore(subscribe, get, get);\n\n return value;\n}\n\n/**\n * Creates a typed version of useReplane hook.\n *\n * @example\n * ```tsx\n * interface AppConfigs {\n * theme: { darkMode: boolean };\n * features: { beta: boolean };\n * }\n *\n * const useAppReplane = createReplaneHook<AppConfigs>();\n *\n * function MyComponent() {\n * const replane = useAppReplane();\n * // replane.get(\"theme\") returns { darkMode: boolean }\n * }\n * ```\n */\nexport function createReplaneHook<TConfigs extends object>() {\n return function useTypedReplane(): ReplaneClient<TConfigs> {\n return useReplane<TConfigs>();\n };\n}\n\n/**\n * Creates a typed version of useConfig hook.\n *\n * @example\n * ```tsx\n * interface AppConfigs {\n * theme: { darkMode: boolean };\n * features: { beta: boolean };\n * }\n *\n * const useAppConfig = createConfigHook<AppConfigs>();\n *\n * function MyComponent() {\n * const theme = useAppConfig(\"theme\");\n * // theme is typed as { darkMode: boolean }\n * }\n * ```\n */\nexport function createConfigHook<TConfigs extends object>() {\n return function useTypedConfig<K extends keyof TConfigs>(\n name: K,\n options?: GetConfigOptions<TConfigs[K]>\n ): TConfigs[K] {\n return useConfig<TConfigs[K]>(String(name), options);\n };\n}\n\n/**\n * Hook for creating stateful resources with cleanup support.\n * Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.\n *\n * @param factory - Function that creates the resource\n * @param cleanup - Function that cleans up the resource\n * @param deps - Dependencies array (resource is recreated when these change)\n */\nexport function useStateful<T>(\n factory: () => T,\n cleanup: (value: T) => void,\n deps: React.DependencyList\n): T {\n const valueRef = useRef<T | null>(null);\n const initializedRef = useRef(false);\n\n // Create initial value synchronously on first render\n if (!initializedRef.current) {\n valueRef.current = factory();\n initializedRef.current = true;\n }\n\n useEffect(() => {\n // On mount or deps change, we may need to recreate\n // If this is not the initial mount, recreate the value\n if (valueRef.current === null) {\n valueRef.current = factory();\n }\n\n return () => {\n if (valueRef.current !== null) {\n cleanup(valueRef.current);\n valueRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n return valueRef.current as T;\n}\n","import type {\n ReplaneClient,\n ReplaneClientOptions,\n ReplaneSnapshot,\n} from \"@replanejs/sdk\";\nimport type { ReactNode } from \"react\";\n\nexport type UntypedReplaneConfig = Record<string, unknown>;\n\nexport interface ReplaneContextValue<T extends object = UntypedReplaneConfig> {\n client: ReplaneClient<T>;\n}\n\n/**\n * Props for ReplaneProvider when using a pre-created client.\n */\nexport interface ReplaneProviderWithClientProps<T extends object = UntypedReplaneConfig> {\n /** Pre-created ReplaneClient instance */\n client: ReplaneClient<T>;\n children: ReactNode;\n}\n\n/**\n * Props for ReplaneProvider when letting it manage the client internally.\n */\nexport interface ReplaneProviderWithOptionsProps<T extends object = UntypedReplaneConfig> {\n /** Options to create or restore the ReplaneClient */\n options: ReplaneClientOptions<T>;\n children: ReactNode;\n /**\n * Optional snapshot from server-side rendering.\n * When provided, the client will be restored from the snapshot synchronously\n * instead of fetching configs from the server.\n * The `options` will be used for live updates connection if provided.\n */\n snapshot?: ReplaneSnapshot<T>;\n /**\n * Optional loading component to show while the client is initializing.\n * If not provided and suspense is false/undefined, children will not render until ready.\n * Ignored when snapshot is provided (restoration is synchronous).\n */\n loader?: ReactNode;\n /**\n * If true, uses React Suspense for loading state.\n * The provider will throw a promise that Suspense can catch.\n * Ignored when snapshot is provided (restoration is synchronous).\n * @default false\n */\n suspense?: boolean;\n}\n\nexport type ReplaneProviderProps<T extends object = UntypedReplaneConfig> =\n | ReplaneProviderWithClientProps<T>\n | ReplaneProviderWithOptionsProps<T>;\n\n/**\n * Type guard to check if props contain a pre-created client.\n */\nexport function hasClient<T extends object>(\n props: ReplaneProviderProps<T>\n): props is ReplaneProviderWithClientProps<T> {\n return \"client\" in props && props.client !== undefined;\n}\n\n/**\n * Type guard to check if props contain options (with or without snapshot).\n */\nexport function hasOptions<T extends object>(\n props: ReplaneProviderProps<T>\n): props is ReplaneProviderWithOptionsProps<T> {\n return \"options\" in props && props.options !== undefined;\n}\n","'use client';\n\nimport { useMemo } from \"react\";\nimport { restoreReplaneClient } from \"@replanejs/sdk\";\nimport { ReplaneContext } from \"./context\";\nimport { useReplaneClientInternal, useReplaneClientSuspense } from \"./useReplaneClient\";\nimport { useStateful } from \"./hooks\";\nimport type {\n ReplaneProviderProps,\n ReplaneProviderWithClientProps,\n ReplaneProviderWithOptionsProps,\n ReplaneContextValue,\n} from \"./types\";\nimport { hasClient } from \"./types\";\n\n/**\n * Internal provider component for pre-created client.\n */\nfunction ReplaneProviderWithClient<T extends object>({\n client,\n children,\n}: ReplaneProviderWithClientProps<T>) {\n const value = useMemo<ReplaneContextValue<T>>(() => ({ client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for restoring client from snapshot.\n * Uses restoreReplaneClient which is synchronous.\n */\nfunction ReplaneProviderWithSnapshot<T extends object>({\n options,\n snapshot,\n children,\n}: ReplaneProviderWithOptionsProps<T> & { snapshot: NonNullable<ReplaneProviderWithOptionsProps<T>[\"snapshot\"]> }) {\n const client = useStateful(\n () =>\n restoreReplaneClient<T>({\n snapshot,\n connection: {\n baseUrl: options.baseUrl,\n sdkKey: options.sdkKey,\n fetchFn: options.fetchFn,\n requestTimeoutMs: options.requestTimeoutMs,\n retryDelayMs: options.retryDelayMs,\n inactivityTimeoutMs: options.inactivityTimeoutMs,\n logger: options.logger,\n },\n context: options.context,\n }),\n (c) => c.close(),\n [snapshot, options]\n );\n const value = useMemo<ReplaneContextValue<T>>(() => ({ client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for options-based client creation (non-suspense).\n * Throws errors during rendering so they can be caught by Error Boundaries.\n */\nfunction ReplaneProviderWithOptions<T extends object>({\n options,\n children,\n loader,\n}: ReplaneProviderWithOptionsProps<T>) {\n const state = useReplaneClientInternal<T>(options);\n\n if (state.status === \"loading\") {\n return <>{loader ?? null}</>;\n }\n\n if (state.status === \"error\") {\n // Throw error during render so it can be caught by Error Boundary\n throw state.error;\n }\n\n const value: ReplaneContextValue<T> = { client: state.client };\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for options-based client creation with Suspense.\n */\nfunction ReplaneProviderWithSuspense<T extends object>({\n options,\n children,\n}: ReplaneProviderWithOptionsProps<T>) {\n const client = useReplaneClientSuspense<T>(options);\n const value = useMemo<ReplaneContextValue<T>>(() => ({ client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Provider component that makes a ReplaneClient available to the component tree.\n *\n * Can be used in three ways:\n *\n * 1. With a pre-created client:\n * ```tsx\n * const client = await createReplaneClient({ ... });\n * <ReplaneProvider client={client}>\n * <App />\n * </ReplaneProvider>\n * ```\n *\n * 2. With options (client managed internally):\n * ```tsx\n * <ErrorBoundary fallback={<ErrorMessage />}>\n * <ReplaneProvider\n * options={{ baseUrl: '...', sdkKey: '...' }}\n * loader={<LoadingSpinner />}\n * >\n * <App />\n * </ReplaneProvider>\n * </ErrorBoundary>\n * ```\n *\n * 3. With Suspense:\n * ```tsx\n * <ErrorBoundary fallback={<ErrorMessage />}>\n * <Suspense fallback={<LoadingSpinner />}>\n * <ReplaneProvider\n * options={{ baseUrl: '...', sdkKey: '...' }}\n * suspense\n * >\n * <App />\n * </ReplaneProvider>\n * </Suspense>\n * </ErrorBoundary>\n * ```\n *\n * 4. With a snapshot (for SSR/hydration):\n * ```tsx\n * // On the server, get a snapshot from the client\n * const snapshot = serverClient.getSnapshot();\n *\n * // On the client, restore from the snapshot with live updates\n * <ReplaneProvider\n * options={{ baseUrl: '...', sdkKey: '...' }}\n * snapshot={snapshot}\n * >\n * <App />\n * </ReplaneProvider>\n * ```\n *\n * Errors during client initialization are thrown during rendering,\n * allowing them to be caught by React Error Boundaries.\n */\nexport function ReplaneProvider<T extends object>(props: ReplaneProviderProps<T>) {\n if (hasClient(props)) {\n return <ReplaneProviderWithClient {...props} />;\n }\n\n // Has options - check if snapshot is provided\n if (props.snapshot) {\n return <ReplaneProviderWithSnapshot {...props} snapshot={props.snapshot} />;\n }\n\n if (props.suspense) {\n return <ReplaneProviderWithSuspense {...props} />;\n }\n\n return <ReplaneProviderWithOptions {...props} />;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replanejs/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "React SDK for Replane - feature flags and remote configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"react": ">=18.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@replanejs/sdk": "^0.
|
|
43
|
+
"@replanejs/sdk": "^0.8.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@testing-library/jest-dom": "^6.9.1",
|