@replanejs/react 0.8.20 → 0.9.0
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 +26 -23
- package/dist/index.cjs +151 -123
- package/dist/index.d.cts +74 -24
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +74 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -130
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -75,27 +75,32 @@ import { ErrorBoundary } from "react-error-boundary";
|
|
|
75
75
|
|
|
76
76
|
#### Client Options
|
|
77
77
|
|
|
78
|
-
The `options` prop accepts
|
|
79
|
-
|
|
80
|
-
| Option
|
|
81
|
-
|
|
|
82
|
-
| `baseUrl`
|
|
83
|
-
| `sdkKey`
|
|
84
|
-
| `context`
|
|
85
|
-
| `defaults`
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
|
|
89
|
-
|
|
78
|
+
The `options` prop accepts the following options:
|
|
79
|
+
|
|
80
|
+
| Option | Type | Required | Description |
|
|
81
|
+
| -------------------- | --------------------- | -------- | -------------------------------------------- |
|
|
82
|
+
| `baseUrl` | `string` | Yes | Replane server URL |
|
|
83
|
+
| `sdkKey` | `string` | Yes | SDK key for authentication |
|
|
84
|
+
| `context` | `Record<string, any>` | No | Default context for override evaluations |
|
|
85
|
+
| `defaults` | `Record<string, any>` | No | Default values if server is unavailable |
|
|
86
|
+
| `connectTimeoutMs` | `number` | No | SDK connection timeout (default: 5000) |
|
|
87
|
+
| `requestTimeoutMs` | `number` | No | Timeout for SSE requests (default: 2000) |
|
|
88
|
+
| `retryDelayMs` | `number` | No | Base delay between retries (default: 200) |
|
|
89
|
+
| `inactivityTimeoutMs`| `number` | No | SSE inactivity timeout (default: 30000) |
|
|
90
|
+
| `fetchFn` | `typeof fetch` | No | Custom fetch implementation |
|
|
91
|
+
| `logger` | `ReplaneLogger` | No | Custom logger (default: console) |
|
|
92
|
+
|
|
93
|
+
See [`@replanejs/sdk` documentation](https://github.com/replane-dev/replane-javascript/tree/main/packages/sdk#api) for more details.
|
|
90
94
|
|
|
91
95
|
#### 2. With pre-created client
|
|
92
96
|
|
|
93
97
|
Use this when you need more control over client lifecycle:
|
|
94
98
|
|
|
95
99
|
```tsx
|
|
96
|
-
import {
|
|
100
|
+
import { Replane } from "@replanejs/sdk";
|
|
97
101
|
|
|
98
|
-
const client =
|
|
102
|
+
const client = new Replane();
|
|
103
|
+
await client.connect({
|
|
99
104
|
baseUrl: "https://your-replane-server.com",
|
|
100
105
|
sdkKey: "your-sdk-key",
|
|
101
106
|
});
|
|
@@ -131,26 +136,24 @@ Restore a client from a snapshot obtained on the server. This is synchronous and
|
|
|
131
136
|
|
|
132
137
|
```tsx
|
|
133
138
|
// On the server
|
|
134
|
-
const serverClient =
|
|
139
|
+
const serverClient = new Replane();
|
|
140
|
+
await serverClient.connect({ baseUrl: "...", sdkKey: "..." });
|
|
135
141
|
const snapshot = serverClient.getSnapshot();
|
|
136
142
|
// Pass snapshot to client via props, context, or serialized HTML
|
|
137
143
|
|
|
138
144
|
// On the client
|
|
139
145
|
<ReplaneProvider
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
connection: {
|
|
144
|
-
baseUrl: "https://your-replane-server.com",
|
|
145
|
-
sdkKey: "your-sdk-key",
|
|
146
|
-
},
|
|
146
|
+
options={{
|
|
147
|
+
baseUrl: "https://your-replane-server.com",
|
|
148
|
+
sdkKey: "your-sdk-key",
|
|
147
149
|
}}
|
|
150
|
+
snapshot={snapshot}
|
|
148
151
|
>
|
|
149
152
|
<App />
|
|
150
153
|
</ReplaneProvider>;
|
|
151
154
|
```
|
|
152
155
|
|
|
153
|
-
The restored client is immediately available with no loading state.
|
|
156
|
+
The restored client is immediately available with no loading state. The provider will establish a connection for real-time updates in the background.
|
|
154
157
|
|
|
155
158
|
### useConfig
|
|
156
159
|
|
package/dist/index.cjs
CHANGED
|
@@ -33,7 +33,7 @@ const ReplaneContext = (0, react.createContext)(null);
|
|
|
33
33
|
|
|
34
34
|
//#endregion
|
|
35
35
|
//#region src/version.ts
|
|
36
|
-
const VERSION = "0.
|
|
36
|
+
const VERSION = "0.9.0";
|
|
37
37
|
const DEFAULT_AGENT = `replane-js-react/${VERSION}`;
|
|
38
38
|
|
|
39
39
|
//#endregion
|
|
@@ -43,7 +43,28 @@ function getCacheKey(options) {
|
|
|
43
43
|
return `${options.baseUrl}:${options.sdkKey}`;
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Creates a Replane client and connects it.
|
|
47
|
+
*/
|
|
48
|
+
async function createAndConnectClient(options) {
|
|
49
|
+
const client = new __replanejs_sdk.Replane({
|
|
50
|
+
logger: options.logger,
|
|
51
|
+
context: options.context,
|
|
52
|
+
defaults: options.defaults
|
|
53
|
+
});
|
|
54
|
+
await client.connect({
|
|
55
|
+
baseUrl: options.baseUrl,
|
|
56
|
+
sdkKey: options.sdkKey,
|
|
57
|
+
connectTimeoutMs: options.connectTimeoutMs,
|
|
58
|
+
retryDelayMs: options.retryDelayMs,
|
|
59
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
60
|
+
inactivityTimeoutMs: options.inactivityTimeoutMs,
|
|
61
|
+
fetchFn: options.fetchFn,
|
|
62
|
+
agent: options.agent ?? DEFAULT_AGENT
|
|
63
|
+
});
|
|
64
|
+
return client;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Hook to manage Replane client creation internally.
|
|
47
68
|
* Handles loading state and cleanup.
|
|
48
69
|
*/
|
|
49
70
|
function useReplaneClientInternal(options) {
|
|
@@ -58,12 +79,9 @@ function useReplaneClientInternal(options) {
|
|
|
58
79
|
let cancelled = false;
|
|
59
80
|
async function initClient() {
|
|
60
81
|
try {
|
|
61
|
-
const client = await (
|
|
62
|
-
...optionsRef.current,
|
|
63
|
-
agent: optionsRef.current.agent ?? DEFAULT_AGENT
|
|
64
|
-
});
|
|
82
|
+
const client = await createAndConnectClient(optionsRef.current);
|
|
65
83
|
if (cancelled) {
|
|
66
|
-
client.
|
|
84
|
+
client.disconnect();
|
|
67
85
|
return;
|
|
68
86
|
}
|
|
69
87
|
clientRef.current = client;
|
|
@@ -86,7 +104,7 @@ function useReplaneClientInternal(options) {
|
|
|
86
104
|
return () => {
|
|
87
105
|
cancelled = true;
|
|
88
106
|
if (clientRef.current) {
|
|
89
|
-
clientRef.current.
|
|
107
|
+
clientRef.current.disconnect();
|
|
90
108
|
clientRef.current = null;
|
|
91
109
|
}
|
|
92
110
|
};
|
|
@@ -105,10 +123,7 @@ function useReplaneClientSuspense(options) {
|
|
|
105
123
|
if (cached.result) return cached.result;
|
|
106
124
|
throw cached.promise;
|
|
107
125
|
}
|
|
108
|
-
const promise = (
|
|
109
|
-
...options,
|
|
110
|
-
agent: options.agent ?? DEFAULT_AGENT
|
|
111
|
-
}).then((client) => {
|
|
126
|
+
const promise = createAndConnectClient(options).then((client) => {
|
|
112
127
|
const entry = suspenseCache.get(cacheKey);
|
|
113
128
|
if (entry) entry.result = client;
|
|
114
129
|
return client;
|
|
@@ -129,101 +144,6 @@ function clearSuspenseCache(options) {
|
|
|
129
144
|
else suspenseCache.clear();
|
|
130
145
|
}
|
|
131
146
|
|
|
132
|
-
//#endregion
|
|
133
|
-
//#region src/hooks.ts
|
|
134
|
-
function useReplane() {
|
|
135
|
-
const context = (0, react.useContext)(ReplaneContext);
|
|
136
|
-
if (!context) throw new Error("useReplane must be used within a ReplaneProvider");
|
|
137
|
-
return context.client;
|
|
138
|
-
}
|
|
139
|
-
function useConfig(name, options) {
|
|
140
|
-
const client = useReplane();
|
|
141
|
-
const subscribe = (0, react.useCallback)((callback) => {
|
|
142
|
-
return client.subscribe(name, callback);
|
|
143
|
-
}, [client, name]);
|
|
144
|
-
const get = (0, react.useCallback)(() => {
|
|
145
|
-
return client.get(name, options);
|
|
146
|
-
}, [
|
|
147
|
-
client,
|
|
148
|
-
name,
|
|
149
|
-
options
|
|
150
|
-
]);
|
|
151
|
-
const value = (0, react.useSyncExternalStore)(subscribe, get, get);
|
|
152
|
-
return value;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Creates a typed version of useReplane hook.
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```tsx
|
|
159
|
-
* interface AppConfigs {
|
|
160
|
-
* theme: { darkMode: boolean };
|
|
161
|
-
* features: { beta: boolean };
|
|
162
|
-
* }
|
|
163
|
-
*
|
|
164
|
-
* const useAppReplane = createReplaneHook<AppConfigs>();
|
|
165
|
-
*
|
|
166
|
-
* function MyComponent() {
|
|
167
|
-
* const replane = useAppReplane();
|
|
168
|
-
* // replane.get("theme") returns { darkMode: boolean }
|
|
169
|
-
* }
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
function createReplaneHook() {
|
|
173
|
-
return function useTypedReplane() {
|
|
174
|
-
return useReplane();
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Creates a typed version of useConfig hook.
|
|
179
|
-
*
|
|
180
|
-
* @example
|
|
181
|
-
* ```tsx
|
|
182
|
-
* interface AppConfigs {
|
|
183
|
-
* theme: { darkMode: boolean };
|
|
184
|
-
* features: { beta: boolean };
|
|
185
|
-
* }
|
|
186
|
-
*
|
|
187
|
-
* const useAppConfig = createConfigHook<AppConfigs>();
|
|
188
|
-
*
|
|
189
|
-
* function MyComponent() {
|
|
190
|
-
* const theme = useAppConfig("theme");
|
|
191
|
-
* // theme is typed as { darkMode: boolean }
|
|
192
|
-
* }
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
function createConfigHook() {
|
|
196
|
-
return function useTypedConfig(name, options) {
|
|
197
|
-
return useConfig(String(name), options);
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Hook for creating stateful resources with cleanup support.
|
|
202
|
-
* Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.
|
|
203
|
-
*
|
|
204
|
-
* @param factory - Function that creates the resource
|
|
205
|
-
* @param cleanup - Function that cleans up the resource
|
|
206
|
-
* @param deps - Dependencies array (resource is recreated when these change)
|
|
207
|
-
*/
|
|
208
|
-
function useStateful(factory, cleanup, deps) {
|
|
209
|
-
const valueRef = (0, react.useRef)(null);
|
|
210
|
-
const initializedRef = (0, react.useRef)(false);
|
|
211
|
-
if (!initializedRef.current) {
|
|
212
|
-
valueRef.current = factory();
|
|
213
|
-
initializedRef.current = true;
|
|
214
|
-
}
|
|
215
|
-
(0, react.useEffect)(() => {
|
|
216
|
-
if (valueRef.current === null) valueRef.current = factory();
|
|
217
|
-
return () => {
|
|
218
|
-
if (valueRef.current !== null) {
|
|
219
|
-
cleanup(valueRef.current);
|
|
220
|
-
valueRef.current = null;
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
}, deps);
|
|
224
|
-
return valueRef.current;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
147
|
//#endregion
|
|
228
148
|
//#region src/types.ts
|
|
229
149
|
/**
|
|
@@ -239,7 +159,7 @@ function hasClient(props) {
|
|
|
239
159
|
* Internal provider component for pre-created client.
|
|
240
160
|
*/
|
|
241
161
|
function ReplaneProviderWithClient({ client, children }) {
|
|
242
|
-
const value = (0, react.useMemo)(() => ({ client }), [client]);
|
|
162
|
+
const value = (0, react.useMemo)(() => ({ replane: client }), [client]);
|
|
243
163
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReplaneContext.Provider, {
|
|
244
164
|
value,
|
|
245
165
|
children
|
|
@@ -247,24 +167,44 @@ function ReplaneProviderWithClient({ client, children }) {
|
|
|
247
167
|
}
|
|
248
168
|
/**
|
|
249
169
|
* Internal provider component for restoring client from snapshot.
|
|
250
|
-
*
|
|
170
|
+
* Creates a Replane client synchronously and connects in background.
|
|
251
171
|
*/
|
|
252
172
|
function ReplaneProviderWithSnapshot({ options, snapshot, children }) {
|
|
253
|
-
const
|
|
173
|
+
const replaneRef = (0, react.useRef)(void 0);
|
|
174
|
+
if (!replaneRef.current) replaneRef.current = new __replanejs_sdk.Replane({
|
|
254
175
|
snapshot,
|
|
255
|
-
|
|
176
|
+
logger: options.logger,
|
|
177
|
+
context: options.context,
|
|
178
|
+
defaults: options.defaults
|
|
179
|
+
});
|
|
180
|
+
(0, react.useEffect)(() => {
|
|
181
|
+
replaneRef.current.connect({
|
|
256
182
|
baseUrl: options.baseUrl,
|
|
257
183
|
sdkKey: options.sdkKey,
|
|
258
|
-
|
|
259
|
-
requestTimeoutMs: options.requestTimeoutMs,
|
|
184
|
+
connectTimeoutMs: options.connectTimeoutMs,
|
|
260
185
|
retryDelayMs: options.retryDelayMs,
|
|
186
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
261
187
|
inactivityTimeoutMs: options.inactivityTimeoutMs,
|
|
262
|
-
|
|
188
|
+
fetchFn: options.fetchFn,
|
|
263
189
|
agent: options.agent ?? DEFAULT_AGENT
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
190
|
+
}).catch((err) => {
|
|
191
|
+
(options.logger ?? console)?.error("Failed to connect Replane client", err);
|
|
192
|
+
});
|
|
193
|
+
return () => {
|
|
194
|
+
replaneRef.current.disconnect();
|
|
195
|
+
};
|
|
196
|
+
}, [
|
|
197
|
+
options.agent,
|
|
198
|
+
options.baseUrl,
|
|
199
|
+
options.connectTimeoutMs,
|
|
200
|
+
options.fetchFn,
|
|
201
|
+
options.inactivityTimeoutMs,
|
|
202
|
+
options.logger,
|
|
203
|
+
options.requestTimeoutMs,
|
|
204
|
+
options.retryDelayMs,
|
|
205
|
+
options.sdkKey
|
|
206
|
+
]);
|
|
207
|
+
const value = (0, react.useMemo)(() => ({ replane: replaneRef.current }), []);
|
|
268
208
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReplaneContext.Provider, {
|
|
269
209
|
value,
|
|
270
210
|
children
|
|
@@ -278,7 +218,7 @@ function ReplaneProviderWithOptions({ options, children, loader }) {
|
|
|
278
218
|
const state = useReplaneClientInternal(options);
|
|
279
219
|
if (state.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: loader ?? null });
|
|
280
220
|
if (state.status === "error") throw state.error;
|
|
281
|
-
const value = {
|
|
221
|
+
const value = { replane: state.client };
|
|
282
222
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReplaneContext.Provider, {
|
|
283
223
|
value,
|
|
284
224
|
children
|
|
@@ -289,20 +229,21 @@ function ReplaneProviderWithOptions({ options, children, loader }) {
|
|
|
289
229
|
*/
|
|
290
230
|
function ReplaneProviderWithSuspense({ options, children }) {
|
|
291
231
|
const client = useReplaneClientSuspense(options);
|
|
292
|
-
const value = (0, react.useMemo)(() => ({ client }), [client]);
|
|
232
|
+
const value = (0, react.useMemo)(() => ({ replane: client }), [client]);
|
|
293
233
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReplaneContext.Provider, {
|
|
294
234
|
value,
|
|
295
235
|
children
|
|
296
236
|
});
|
|
297
237
|
}
|
|
298
238
|
/**
|
|
299
|
-
* Provider component that makes a
|
|
239
|
+
* Provider component that makes a Replane client available to the component tree.
|
|
300
240
|
*
|
|
301
|
-
* Can be used in
|
|
241
|
+
* Can be used in several ways:
|
|
302
242
|
*
|
|
303
243
|
* 1. With a pre-created client:
|
|
304
244
|
* ```tsx
|
|
305
|
-
* const client =
|
|
245
|
+
* const client = new Replane({ defaults: { ... } });
|
|
246
|
+
* await client.connect({ baseUrl: '...', sdkKey: '...' });
|
|
306
247
|
* <ReplaneProvider client={client}>
|
|
307
248
|
* <App />
|
|
308
249
|
* </ReplaneProvider>
|
|
@@ -362,6 +303,93 @@ function ReplaneProvider(props) {
|
|
|
362
303
|
}
|
|
363
304
|
|
|
364
305
|
//#endregion
|
|
306
|
+
//#region src/hooks.ts
|
|
307
|
+
function useReplane() {
|
|
308
|
+
const context = (0, react.useContext)(ReplaneContext);
|
|
309
|
+
if (!context) throw new Error("useReplane must be used within a ReplaneProvider");
|
|
310
|
+
return context.replane;
|
|
311
|
+
}
|
|
312
|
+
function useConfig(name, options) {
|
|
313
|
+
const client = useReplane();
|
|
314
|
+
const subscribe = (0, react.useCallback)((callback) => {
|
|
315
|
+
return client.subscribe(name, callback);
|
|
316
|
+
}, [client, name]);
|
|
317
|
+
const get = (0, react.useCallback)(() => {
|
|
318
|
+
return client.get(name, options);
|
|
319
|
+
}, [
|
|
320
|
+
client,
|
|
321
|
+
name,
|
|
322
|
+
options
|
|
323
|
+
]);
|
|
324
|
+
const value = (0, react.useSyncExternalStore)(subscribe, get, get);
|
|
325
|
+
return value;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Creates a typed version of useReplane hook.
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```tsx
|
|
332
|
+
* interface AppConfigs {
|
|
333
|
+
* theme: { darkMode: boolean };
|
|
334
|
+
* features: { beta: boolean };
|
|
335
|
+
* }
|
|
336
|
+
*
|
|
337
|
+
* const useAppReplane = createReplaneHook<AppConfigs>();
|
|
338
|
+
*
|
|
339
|
+
* function MyComponent() {
|
|
340
|
+
* const replane = useAppReplane();
|
|
341
|
+
* // replane.get("theme") returns { darkMode: boolean }
|
|
342
|
+
* }
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
function createReplaneHook() {
|
|
346
|
+
return function useTypedReplane() {
|
|
347
|
+
return useReplane();
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Creates a typed version of useConfig hook.
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```tsx
|
|
355
|
+
* interface AppConfigs {
|
|
356
|
+
* theme: { darkMode: boolean };
|
|
357
|
+
* features: { beta: boolean };
|
|
358
|
+
* }
|
|
359
|
+
*
|
|
360
|
+
* const useAppConfig = createConfigHook<AppConfigs>();
|
|
361
|
+
*
|
|
362
|
+
* function MyComponent() {
|
|
363
|
+
* const theme = useAppConfig("theme");
|
|
364
|
+
* // theme is typed as { darkMode: boolean }
|
|
365
|
+
* }
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
function createConfigHook() {
|
|
369
|
+
return function useTypedConfig(name, options) {
|
|
370
|
+
return useConfig(String(name), options);
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
//#endregion
|
|
375
|
+
Object.defineProperty(exports, 'Replane', {
|
|
376
|
+
enumerable: true,
|
|
377
|
+
get: function () {
|
|
378
|
+
return __replanejs_sdk.Replane;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
Object.defineProperty(exports, 'ReplaneError', {
|
|
382
|
+
enumerable: true,
|
|
383
|
+
get: function () {
|
|
384
|
+
return __replanejs_sdk.ReplaneError;
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
Object.defineProperty(exports, 'ReplaneErrorCode', {
|
|
388
|
+
enumerable: true,
|
|
389
|
+
get: function () {
|
|
390
|
+
return __replanejs_sdk.ReplaneErrorCode;
|
|
391
|
+
}
|
|
392
|
+
});
|
|
365
393
|
exports.ReplaneProvider = ReplaneProvider;
|
|
366
394
|
exports.clearSuspenseCache = clearSuspenseCache;
|
|
367
395
|
exports.createConfigHook = createConfigHook;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,23 +1,80 @@
|
|
|
1
1
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
-
import { GetConfigOptions, GetReplaneSnapshotOptions,
|
|
2
|
+
import { ConnectOptions, GetConfigOptions, GetConfigOptions as GetConfigOptions$1, GetReplaneSnapshotOptions, Replane, Replane as Replane$1, ReplaneContext, ReplaneContext as ReplaneContext$1, ReplaneError, ReplaneErrorCode, ReplaneLogger, ReplaneLogger as ReplaneLogger$1, ReplaneOptions, ReplaneSnapshot, ReplaneSnapshot as ReplaneSnapshot$1, getReplaneSnapshot } from "@replanejs/sdk";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
6
6
|
type UntypedReplaneConfig = Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Combined options for ReplaneProvider.
|
|
9
|
+
* Includes both constructor options (context, logger, defaults) and connection options.
|
|
10
|
+
*/
|
|
11
|
+
interface ReplaneProviderOptions<T extends object = UntypedReplaneConfig> {
|
|
12
|
+
/**
|
|
13
|
+
* Base URL of the Replane instance (no trailing slash).
|
|
14
|
+
* @example "https://app.replane.dev"
|
|
15
|
+
*/
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
/**
|
|
18
|
+
* Project SDK key for authorization.
|
|
19
|
+
* @example "rp_XXXXXXXXX"
|
|
20
|
+
*/
|
|
21
|
+
sdkKey: string;
|
|
22
|
+
/**
|
|
23
|
+
* Default context for all config evaluations.
|
|
24
|
+
* Can be overridden per-request in `client.get()`.
|
|
25
|
+
*/
|
|
26
|
+
context?: ReplaneContext$1;
|
|
27
|
+
/**
|
|
28
|
+
* Optional logger (defaults to console).
|
|
29
|
+
*/
|
|
30
|
+
logger?: ReplaneLogger$1;
|
|
31
|
+
/**
|
|
32
|
+
* Default values to use before connection is established.
|
|
33
|
+
*/
|
|
34
|
+
defaults?: { [K in keyof T]?: T[K] };
|
|
35
|
+
/**
|
|
36
|
+
* Optional timeout in ms for the initial connection.
|
|
37
|
+
* @default 5000
|
|
38
|
+
*/
|
|
39
|
+
connectTimeoutMs?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Delay between retries in ms.
|
|
42
|
+
* @default 200
|
|
43
|
+
*/
|
|
44
|
+
retryDelayMs?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Optional timeout in ms for individual requests.
|
|
47
|
+
* @default 2000
|
|
48
|
+
*/
|
|
49
|
+
requestTimeoutMs?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Timeout in ms for SSE connection inactivity.
|
|
52
|
+
* @default 30000
|
|
53
|
+
*/
|
|
54
|
+
inactivityTimeoutMs?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Custom fetch implementation (useful for tests / polyfills).
|
|
57
|
+
*/
|
|
58
|
+
fetchFn?: typeof fetch;
|
|
59
|
+
/**
|
|
60
|
+
* Agent identifier sent in User-Agent header.
|
|
61
|
+
*/
|
|
62
|
+
agent?: string;
|
|
63
|
+
}
|
|
7
64
|
/**
|
|
8
65
|
* Props for ReplaneProvider when using a pre-created client.
|
|
9
66
|
*/
|
|
10
67
|
interface ReplaneProviderWithClientProps<T extends object = UntypedReplaneConfig> {
|
|
11
|
-
/** Pre-created
|
|
12
|
-
client:
|
|
68
|
+
/** Pre-created Replane client instance */
|
|
69
|
+
client: Replane$1<T>;
|
|
13
70
|
children: ReactNode;
|
|
14
71
|
}
|
|
15
72
|
/**
|
|
16
73
|
* Props for ReplaneProvider when letting it manage the client internally.
|
|
17
74
|
*/
|
|
18
75
|
interface ReplaneProviderWithOptionsProps<T extends object = UntypedReplaneConfig> {
|
|
19
|
-
/** Options to create or restore the
|
|
20
|
-
options:
|
|
76
|
+
/** Options to create or restore the Replane client */
|
|
77
|
+
options: ReplaneProviderOptions<T>;
|
|
21
78
|
children: ReactNode;
|
|
22
79
|
/**
|
|
23
80
|
* Optional snapshot from server-side rendering.
|
|
@@ -25,7 +82,7 @@ interface ReplaneProviderWithOptionsProps<T extends object = UntypedReplaneConfi
|
|
|
25
82
|
* instead of fetching configs from the server.
|
|
26
83
|
* The `options` will be used for live updates connection if provided.
|
|
27
84
|
*/
|
|
28
|
-
snapshot?: ReplaneSnapshot<T>;
|
|
85
|
+
snapshot?: ReplaneSnapshot$1<T>;
|
|
29
86
|
/**
|
|
30
87
|
* Optional loading component to show while the client is initializing.
|
|
31
88
|
* If not provided and suspense is false/undefined, children will not render until ready.
|
|
@@ -44,17 +101,17 @@ type ReplaneProviderProps<T extends object = UntypedReplaneConfig> = ReplaneProv
|
|
|
44
101
|
/**
|
|
45
102
|
* Type guard to check if props contain a pre-created client.
|
|
46
103
|
*/
|
|
47
|
-
|
|
48
104
|
//#endregion
|
|
49
105
|
//#region src/provider.d.ts
|
|
50
106
|
/**
|
|
51
|
-
* Provider component that makes a
|
|
107
|
+
* Provider component that makes a Replane client available to the component tree.
|
|
52
108
|
*
|
|
53
|
-
* Can be used in
|
|
109
|
+
* Can be used in several ways:
|
|
54
110
|
*
|
|
55
111
|
* 1. With a pre-created client:
|
|
56
112
|
* ```tsx
|
|
57
|
-
* const client =
|
|
113
|
+
* const client = new Replane({ defaults: { ... } });
|
|
114
|
+
* await client.connect({ baseUrl: '...', sdkKey: '...' });
|
|
58
115
|
* <ReplaneProvider client={client}>
|
|
59
116
|
* <App />
|
|
60
117
|
* </ReplaneProvider>
|
|
@@ -107,8 +164,8 @@ declare function ReplaneProvider<T extends object>(props: ReplaneProviderProps<T
|
|
|
107
164
|
//# sourceMappingURL=provider.d.ts.map
|
|
108
165
|
//#endregion
|
|
109
166
|
//#region src/hooks.d.ts
|
|
110
|
-
declare function useReplane<T extends object = UntypedReplaneConfig>():
|
|
111
|
-
declare function useConfig<T>(name: string, options?: GetConfigOptions<T>): T;
|
|
167
|
+
declare function useReplane<T extends object = UntypedReplaneConfig>(): Replane$1<T>;
|
|
168
|
+
declare function useConfig<T>(name: string, options?: GetConfigOptions$1<T>): T;
|
|
112
169
|
/**
|
|
113
170
|
* Creates a typed version of useReplane hook.
|
|
114
171
|
*
|
|
@@ -127,7 +184,7 @@ declare function useConfig<T>(name: string, options?: GetConfigOptions<T>): T;
|
|
|
127
184
|
* }
|
|
128
185
|
* ```
|
|
129
186
|
*/
|
|
130
|
-
declare function createReplaneHook<TConfigs extends object>(): () =>
|
|
187
|
+
declare function createReplaneHook<TConfigs extends object>(): () => Replane$1<TConfigs>;
|
|
131
188
|
/**
|
|
132
189
|
* Creates a typed version of useConfig hook.
|
|
133
190
|
*
|
|
@@ -146,22 +203,15 @@ declare function createReplaneHook<TConfigs extends object>(): () => ReplaneClie
|
|
|
146
203
|
* }
|
|
147
204
|
* ```
|
|
148
205
|
*/
|
|
149
|
-
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions<TConfigs[K]>) => TConfigs[K];
|
|
150
|
-
|
|
151
|
-
* Hook for creating stateful resources with cleanup support.
|
|
152
|
-
* Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.
|
|
153
|
-
*
|
|
154
|
-
* @param factory - Function that creates the resource
|
|
155
|
-
* @param cleanup - Function that cleans up the resource
|
|
156
|
-
* @param deps - Dependencies array (resource is recreated when these change)
|
|
157
|
-
*/
|
|
206
|
+
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions$1<TConfigs[K]>) => TConfigs[K];
|
|
207
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
158
208
|
//#endregion
|
|
159
209
|
//#region src/useReplaneClient.d.ts
|
|
160
210
|
/**
|
|
161
211
|
* Clear the suspense cache for a specific options configuration.
|
|
162
212
|
* Useful for testing or when you need to force re-initialization.
|
|
163
213
|
*/
|
|
164
|
-
declare function clearSuspenseCache<T extends object>(options?:
|
|
214
|
+
declare function clearSuspenseCache<T extends object>(options?: ReplaneProviderOptions<T>): void;
|
|
165
215
|
//#endregion
|
|
166
|
-
export { type GetReplaneSnapshotOptions, ReplaneProvider, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
216
|
+
export { type ConnectOptions, type GetConfigOptions, type GetReplaneSnapshotOptions, Replane, type ReplaneContext, ReplaneError, ReplaneErrorCode, type ReplaneLogger, type ReplaneOptions, ReplaneProvider, type ReplaneProviderOptions, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps, type ReplaneSnapshot, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
167
217
|
//# 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":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/provider.tsx","../src/hooks.ts","../src/useReplaneClient.ts"],"sourcesContent":[],"mappings":";;;;;KAGY,oBAAA,GAAuB;AAUnC;;;;AAmBW,UAnBM,sBAmBN,CAAA,UAAA,MAAA,GAnBgD,oBAmBhD,CAAA,CAAA;EAAa;;;;EA4BA,OAAA,EAAA,MAAA;EAUP;;;;EAEE,MAAT,EAAA,MAAA;EAAO;AACI;AAMrB;;EAAgD,OAAoB,CAAA,EAnDxD,gBAmDwD;EAAoB;;;EAGnE,MAOQ,CAAA,EAzDlB,eAyDkB;EAAC;;AAMV;EAUR,QAAA,CAAA,EAAA,QAAoB,MArEL,CAqEK,IArEA,CAqEA,CArEE,CAqEF,CAAA,EAAA;EAAwC;;;;EAErC,gBAAA,CAAA,EAAA,MAAA;;;;ACqEnC;EAA+B,YAAA,CAAA,EAAA,MAAA;EAAA;;;AAAiD;;;;ACzKhF;;EAA0B,mBAAoB,CAAA,EAAA,MAAA;EAAoB;;AAAY;EAQ9D,OAAA,CAAA,EAAA,OF6CG,KE7CM;EAAA;;;EAA4C,KAAM,CAAA,EAAA,MAAA;AAAC;AAqC5E;;;AACqC,UFiBpB,8BEjBoB,CAAA,UAAA,MAAA,GFiB8B,oBEjB9B,CAAA,CAAA;EAAO;EAuB5B,MAAA,EFJN,SEIM,CFJE,CEIF,CAAA;EAAgB,QAAA,EFHpB,SEGoB;;;;;AAGlB,UFAG,+BEAH,CAAA,UAAA,MAAA,GFAsD,oBEAtD,CAAA,CAAA;EAAgB;EACjB,OAAC,EFCH,sBEDG,CFCoB,CEDpB,CAAA;EAAC,QAAA,EFEH,SEFG;;;;ACyEf;;;EAAuF,QAAxB,CAAA,EHhElD,iBGgEkD,CHhElC,CGgEkC,CAAA;EAAsB;;;;;WH1D1E;;;;;;;;;KAUC,wCAAwC,wBAChD,+BAA+B,KAC/B,gCAAgC;;;;;;;;;;AAxGpC;AAUA;;;;;;;;;AA+CwB;AAUxB;;;;;;AAGqB;AAMrB;;;;;;;;;AAgBoB;AAUpB;;;;;;;AAEmC;;;;ACqEnC;;;;;AAAgF;;;;ACzKhF;;;;;AAA8E,iBDyK9D,eCzK8D,CAAA,UAAA,MAAA,CAAA,CAAA,KAAA,EDyKrB,oBCzKqB,CDyKA,CCzKA,CAAA,CAAA,EDyKE,kBAAA,CAAA,GAAA,CAAA,OCzKF;AAQ9E;;;iBARgB,8BAA8B,yBAAyB,UAAQ;iBAQ/D,qCAAqC,mBAAiB,KAAK;;AFZ3E;AAUA;;;;;;;;;AA+CwB;AAUxB;;;;;;AAGqB,iBErBL,iBFqBK,CAAA,iBAAA,MAAA,CAAA,CAAA,CAAA,EAAA,GAAA,GEpBgB,SFoBhB,CEpBwB,QFoBxB,CAAA;AAMrB;;;;;;;;;AAgBoB;AAUpB;;;;;;;AAEmC;iBE/BnB,8DACiC,gBACvC,aACI,mBAAiB,SAAS,QACnC,SAAS;;;;;;;;AFSe,iBGgEb,kBHhEa,CAAA,UAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EGgEkC,sBHhElC,CGgEyD,CHhEzD,CAAA,CAAA,EAAA,IAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,80 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import { GetConfigOptions, GetReplaneSnapshotOptions,
|
|
2
|
+
import { ConnectOptions, GetConfigOptions, GetConfigOptions as GetConfigOptions$1, GetReplaneSnapshotOptions, Replane, Replane as Replane$1, ReplaneContext, ReplaneContext as ReplaneContext$1, ReplaneError, ReplaneErrorCode, ReplaneLogger, ReplaneLogger as ReplaneLogger$1, ReplaneOptions, ReplaneSnapshot, ReplaneSnapshot as ReplaneSnapshot$1, getReplaneSnapshot } from "@replanejs/sdk";
|
|
3
3
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
6
6
|
type UntypedReplaneConfig = Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Combined options for ReplaneProvider.
|
|
9
|
+
* Includes both constructor options (context, logger, defaults) and connection options.
|
|
10
|
+
*/
|
|
11
|
+
interface ReplaneProviderOptions<T extends object = UntypedReplaneConfig> {
|
|
12
|
+
/**
|
|
13
|
+
* Base URL of the Replane instance (no trailing slash).
|
|
14
|
+
* @example "https://app.replane.dev"
|
|
15
|
+
*/
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
/**
|
|
18
|
+
* Project SDK key for authorization.
|
|
19
|
+
* @example "rp_XXXXXXXXX"
|
|
20
|
+
*/
|
|
21
|
+
sdkKey: string;
|
|
22
|
+
/**
|
|
23
|
+
* Default context for all config evaluations.
|
|
24
|
+
* Can be overridden per-request in `client.get()`.
|
|
25
|
+
*/
|
|
26
|
+
context?: ReplaneContext$1;
|
|
27
|
+
/**
|
|
28
|
+
* Optional logger (defaults to console).
|
|
29
|
+
*/
|
|
30
|
+
logger?: ReplaneLogger$1;
|
|
31
|
+
/**
|
|
32
|
+
* Default values to use before connection is established.
|
|
33
|
+
*/
|
|
34
|
+
defaults?: { [K in keyof T]?: T[K] };
|
|
35
|
+
/**
|
|
36
|
+
* Optional timeout in ms for the initial connection.
|
|
37
|
+
* @default 5000
|
|
38
|
+
*/
|
|
39
|
+
connectTimeoutMs?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Delay between retries in ms.
|
|
42
|
+
* @default 200
|
|
43
|
+
*/
|
|
44
|
+
retryDelayMs?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Optional timeout in ms for individual requests.
|
|
47
|
+
* @default 2000
|
|
48
|
+
*/
|
|
49
|
+
requestTimeoutMs?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Timeout in ms for SSE connection inactivity.
|
|
52
|
+
* @default 30000
|
|
53
|
+
*/
|
|
54
|
+
inactivityTimeoutMs?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Custom fetch implementation (useful for tests / polyfills).
|
|
57
|
+
*/
|
|
58
|
+
fetchFn?: typeof fetch;
|
|
59
|
+
/**
|
|
60
|
+
* Agent identifier sent in User-Agent header.
|
|
61
|
+
*/
|
|
62
|
+
agent?: string;
|
|
63
|
+
}
|
|
7
64
|
/**
|
|
8
65
|
* Props for ReplaneProvider when using a pre-created client.
|
|
9
66
|
*/
|
|
10
67
|
interface ReplaneProviderWithClientProps<T extends object = UntypedReplaneConfig> {
|
|
11
|
-
/** Pre-created
|
|
12
|
-
client:
|
|
68
|
+
/** Pre-created Replane client instance */
|
|
69
|
+
client: Replane$1<T>;
|
|
13
70
|
children: ReactNode;
|
|
14
71
|
}
|
|
15
72
|
/**
|
|
16
73
|
* Props for ReplaneProvider when letting it manage the client internally.
|
|
17
74
|
*/
|
|
18
75
|
interface ReplaneProviderWithOptionsProps<T extends object = UntypedReplaneConfig> {
|
|
19
|
-
/** Options to create or restore the
|
|
20
|
-
options:
|
|
76
|
+
/** Options to create or restore the Replane client */
|
|
77
|
+
options: ReplaneProviderOptions<T>;
|
|
21
78
|
children: ReactNode;
|
|
22
79
|
/**
|
|
23
80
|
* Optional snapshot from server-side rendering.
|
|
@@ -25,7 +82,7 @@ interface ReplaneProviderWithOptionsProps<T extends object = UntypedReplaneConfi
|
|
|
25
82
|
* instead of fetching configs from the server.
|
|
26
83
|
* The `options` will be used for live updates connection if provided.
|
|
27
84
|
*/
|
|
28
|
-
snapshot?: ReplaneSnapshot<T>;
|
|
85
|
+
snapshot?: ReplaneSnapshot$1<T>;
|
|
29
86
|
/**
|
|
30
87
|
* Optional loading component to show while the client is initializing.
|
|
31
88
|
* If not provided and suspense is false/undefined, children will not render until ready.
|
|
@@ -44,17 +101,17 @@ type ReplaneProviderProps<T extends object = UntypedReplaneConfig> = ReplaneProv
|
|
|
44
101
|
/**
|
|
45
102
|
* Type guard to check if props contain a pre-created client.
|
|
46
103
|
*/
|
|
47
|
-
|
|
48
104
|
//#endregion
|
|
49
105
|
//#region src/provider.d.ts
|
|
50
106
|
/**
|
|
51
|
-
* Provider component that makes a
|
|
107
|
+
* Provider component that makes a Replane client available to the component tree.
|
|
52
108
|
*
|
|
53
|
-
* Can be used in
|
|
109
|
+
* Can be used in several ways:
|
|
54
110
|
*
|
|
55
111
|
* 1. With a pre-created client:
|
|
56
112
|
* ```tsx
|
|
57
|
-
* const client =
|
|
113
|
+
* const client = new Replane({ defaults: { ... } });
|
|
114
|
+
* await client.connect({ baseUrl: '...', sdkKey: '...' });
|
|
58
115
|
* <ReplaneProvider client={client}>
|
|
59
116
|
* <App />
|
|
60
117
|
* </ReplaneProvider>
|
|
@@ -107,8 +164,8 @@ declare function ReplaneProvider<T extends object>(props: ReplaneProviderProps<T
|
|
|
107
164
|
//# sourceMappingURL=provider.d.ts.map
|
|
108
165
|
//#endregion
|
|
109
166
|
//#region src/hooks.d.ts
|
|
110
|
-
declare function useReplane<T extends object = UntypedReplaneConfig>():
|
|
111
|
-
declare function useConfig<T>(name: string, options?: GetConfigOptions<T>): T;
|
|
167
|
+
declare function useReplane<T extends object = UntypedReplaneConfig>(): Replane$1<T>;
|
|
168
|
+
declare function useConfig<T>(name: string, options?: GetConfigOptions$1<T>): T;
|
|
112
169
|
/**
|
|
113
170
|
* Creates a typed version of useReplane hook.
|
|
114
171
|
*
|
|
@@ -127,7 +184,7 @@ declare function useConfig<T>(name: string, options?: GetConfigOptions<T>): T;
|
|
|
127
184
|
* }
|
|
128
185
|
* ```
|
|
129
186
|
*/
|
|
130
|
-
declare function createReplaneHook<TConfigs extends object>(): () =>
|
|
187
|
+
declare function createReplaneHook<TConfigs extends object>(): () => Replane$1<TConfigs>;
|
|
131
188
|
/**
|
|
132
189
|
* Creates a typed version of useConfig hook.
|
|
133
190
|
*
|
|
@@ -146,22 +203,15 @@ declare function createReplaneHook<TConfigs extends object>(): () => ReplaneClie
|
|
|
146
203
|
* }
|
|
147
204
|
* ```
|
|
148
205
|
*/
|
|
149
|
-
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions<TConfigs[K]>) => TConfigs[K];
|
|
150
|
-
|
|
151
|
-
* Hook for creating stateful resources with cleanup support.
|
|
152
|
-
* Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.
|
|
153
|
-
*
|
|
154
|
-
* @param factory - Function that creates the resource
|
|
155
|
-
* @param cleanup - Function that cleans up the resource
|
|
156
|
-
* @param deps - Dependencies array (resource is recreated when these change)
|
|
157
|
-
*/
|
|
206
|
+
declare function createConfigHook<TConfigs extends object>(): <K extends keyof TConfigs>(name: K, options?: GetConfigOptions$1<TConfigs[K]>) => TConfigs[K];
|
|
207
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
158
208
|
//#endregion
|
|
159
209
|
//#region src/useReplaneClient.d.ts
|
|
160
210
|
/**
|
|
161
211
|
* Clear the suspense cache for a specific options configuration.
|
|
162
212
|
* Useful for testing or when you need to force re-initialization.
|
|
163
213
|
*/
|
|
164
|
-
declare function clearSuspenseCache<T extends object>(options?:
|
|
214
|
+
declare function clearSuspenseCache<T extends object>(options?: ReplaneProviderOptions<T>): void;
|
|
165
215
|
//#endregion
|
|
166
|
-
export { type GetReplaneSnapshotOptions, ReplaneProvider, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
216
|
+
export { type ConnectOptions, type GetConfigOptions, type GetReplaneSnapshotOptions, Replane, type ReplaneContext, ReplaneError, ReplaneErrorCode, type ReplaneLogger, type ReplaneOptions, ReplaneProvider, type ReplaneProviderOptions, type ReplaneProviderProps, type ReplaneProviderWithClientProps, type ReplaneProviderWithOptionsProps, type ReplaneSnapshot, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
167
217
|
//# 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":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/provider.tsx","../src/hooks.ts","../src/useReplaneClient.ts"],"sourcesContent":[],"mappings":";;;;;KAGY,oBAAA,GAAuB;AAUnC;;;;AAmBW,UAnBM,sBAmBN,CAAA,UAAA,MAAA,GAnBgD,oBAmBhD,CAAA,CAAA;EAAa;;;;EA4BA,OAAA,EAAA,MAAA;EAUP;;;;EAEE,MAAT,EAAA,MAAA;EAAO;AACI;AAMrB;;EAAgD,OAAoB,CAAA,EAnDxD,gBAmDwD;EAAoB;;;EAGnE,MAOQ,CAAA,EAzDlB,eAyDkB;EAAC;;AAMV;EAUR,QAAA,CAAA,EAAA,QAAoB,MArEL,CAqEK,IArEA,CAqEA,CArEE,CAqEF,CAAA,EAAA;EAAwC;;;;EAErC,gBAAA,CAAA,EAAA,MAAA;;;;ACqEnC;EAA+B,YAAA,CAAA,EAAA,MAAA;EAAA;;;AAAiD;;;;ACzKhF;;EAA0B,mBAAoB,CAAA,EAAA,MAAA;EAAoB;;AAAY;EAQ9D,OAAA,CAAA,EAAA,OF6CG,KE7CM;EAAA;;;EAA4C,KAAM,CAAA,EAAA,MAAA;AAAC;AAqC5E;;;AACqC,UFiBpB,8BEjBoB,CAAA,UAAA,MAAA,GFiB8B,oBEjB9B,CAAA,CAAA;EAAO;EAuB5B,MAAA,EFJN,SEIM,CFJE,CEIF,CAAA;EAAgB,QAAA,EFHpB,SEGoB;;;;;AAGlB,UFAG,+BEAH,CAAA,UAAA,MAAA,GFAsD,oBEAtD,CAAA,CAAA;EAAgB;EACjB,OAAC,EFCH,sBEDG,CFCoB,CEDpB,CAAA;EAAC,QAAA,EFEH,SEFG;;;;ACyEf;;;EAAuF,QAAxB,CAAA,EHhElD,iBGgEkD,CHhElC,CGgEkC,CAAA;EAAsB;;;;;WH1D1E;;;;;;;;;KAUC,wCAAwC,wBAChD,+BAA+B,KAC/B,gCAAgC;;;;;;;;;;AAxGpC;AAUA;;;;;;;;;AA+CwB;AAUxB;;;;;;AAGqB;AAMrB;;;;;;;;;AAgBoB;AAUpB;;;;;;;AAEmC;;;;ACqEnC;;;;;AAAgF;;;;ACzKhF;;;;;AAA8E,iBDyK9D,eCzK8D,CAAA,UAAA,MAAA,CAAA,CAAA,KAAA,EDyKrB,oBCzKqB,CDyKA,CCzKA,CAAA,CAAA,EDyKE,kBAAA,CAAA,GAAA,CAAA,OCzKF;AAQ9E;;;iBARgB,8BAA8B,yBAAyB,UAAQ;iBAQ/D,qCAAqC,mBAAiB,KAAK;;AFZ3E;AAUA;;;;;;;;;AA+CwB;AAUxB;;;;;;AAGqB,iBErBL,iBFqBK,CAAA,iBAAA,MAAA,CAAA,CAAA,CAAA,EAAA,GAAA,GEpBgB,SFoBhB,CEpBwB,QFoBxB,CAAA;AAMrB;;;;;;;;;AAgBoB;AAUpB;;;;;;;AAEmC;iBE/BnB,8DACiC,gBACvC,aACI,mBAAiB,SAAS,QACnC,SAAS;;;;;;;;AFSe,iBGgEb,kBHhEa,CAAA,UAAA,MAAA,CAAA,CAAA,OAAA,CAAA,EGgEkC,sBHhElC,CGgEyD,CHhEzD,CAAA,CAAA,EAAA,IAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { Replane, Replane as Replane$1, ReplaneError, ReplaneErrorCode, getReplaneSnapshot } from "@replanejs/sdk";
|
|
6
6
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
7
7
|
|
|
8
8
|
//#region src/context.ts
|
|
9
|
-
const ReplaneContext = createContext(null);
|
|
9
|
+
const ReplaneContext$1 = createContext(null);
|
|
10
10
|
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region src/version.ts
|
|
13
|
-
const VERSION = "0.
|
|
13
|
+
const VERSION = "0.9.0";
|
|
14
14
|
const DEFAULT_AGENT = `replane-js-react/${VERSION}`;
|
|
15
15
|
|
|
16
16
|
//#endregion
|
|
@@ -20,7 +20,28 @@ function getCacheKey(options) {
|
|
|
20
20
|
return `${options.baseUrl}:${options.sdkKey}`;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Creates a Replane client and connects it.
|
|
24
|
+
*/
|
|
25
|
+
async function createAndConnectClient(options) {
|
|
26
|
+
const client = new Replane$1({
|
|
27
|
+
logger: options.logger,
|
|
28
|
+
context: options.context,
|
|
29
|
+
defaults: options.defaults
|
|
30
|
+
});
|
|
31
|
+
await client.connect({
|
|
32
|
+
baseUrl: options.baseUrl,
|
|
33
|
+
sdkKey: options.sdkKey,
|
|
34
|
+
connectTimeoutMs: options.connectTimeoutMs,
|
|
35
|
+
retryDelayMs: options.retryDelayMs,
|
|
36
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
37
|
+
inactivityTimeoutMs: options.inactivityTimeoutMs,
|
|
38
|
+
fetchFn: options.fetchFn,
|
|
39
|
+
agent: options.agent ?? DEFAULT_AGENT
|
|
40
|
+
});
|
|
41
|
+
return client;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Hook to manage Replane client creation internally.
|
|
24
45
|
* Handles loading state and cleanup.
|
|
25
46
|
*/
|
|
26
47
|
function useReplaneClientInternal(options) {
|
|
@@ -35,12 +56,9 @@ function useReplaneClientInternal(options) {
|
|
|
35
56
|
let cancelled = false;
|
|
36
57
|
async function initClient() {
|
|
37
58
|
try {
|
|
38
|
-
const client = await
|
|
39
|
-
...optionsRef.current,
|
|
40
|
-
agent: optionsRef.current.agent ?? DEFAULT_AGENT
|
|
41
|
-
});
|
|
59
|
+
const client = await createAndConnectClient(optionsRef.current);
|
|
42
60
|
if (cancelled) {
|
|
43
|
-
client.
|
|
61
|
+
client.disconnect();
|
|
44
62
|
return;
|
|
45
63
|
}
|
|
46
64
|
clientRef.current = client;
|
|
@@ -63,7 +81,7 @@ function useReplaneClientInternal(options) {
|
|
|
63
81
|
return () => {
|
|
64
82
|
cancelled = true;
|
|
65
83
|
if (clientRef.current) {
|
|
66
|
-
clientRef.current.
|
|
84
|
+
clientRef.current.disconnect();
|
|
67
85
|
clientRef.current = null;
|
|
68
86
|
}
|
|
69
87
|
};
|
|
@@ -82,10 +100,7 @@ function useReplaneClientSuspense(options) {
|
|
|
82
100
|
if (cached.result) return cached.result;
|
|
83
101
|
throw cached.promise;
|
|
84
102
|
}
|
|
85
|
-
const promise =
|
|
86
|
-
...options,
|
|
87
|
-
agent: options.agent ?? DEFAULT_AGENT
|
|
88
|
-
}).then((client) => {
|
|
103
|
+
const promise = createAndConnectClient(options).then((client) => {
|
|
89
104
|
const entry = suspenseCache.get(cacheKey);
|
|
90
105
|
if (entry) entry.result = client;
|
|
91
106
|
return client;
|
|
@@ -106,101 +121,6 @@ function clearSuspenseCache(options) {
|
|
|
106
121
|
else suspenseCache.clear();
|
|
107
122
|
}
|
|
108
123
|
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region src/hooks.ts
|
|
111
|
-
function useReplane() {
|
|
112
|
-
const context = useContext(ReplaneContext);
|
|
113
|
-
if (!context) throw new Error("useReplane must be used within a ReplaneProvider");
|
|
114
|
-
return context.client;
|
|
115
|
-
}
|
|
116
|
-
function useConfig(name, options) {
|
|
117
|
-
const client = useReplane();
|
|
118
|
-
const subscribe = useCallback((callback) => {
|
|
119
|
-
return client.subscribe(name, callback);
|
|
120
|
-
}, [client, name]);
|
|
121
|
-
const get = useCallback(() => {
|
|
122
|
-
return client.get(name, options);
|
|
123
|
-
}, [
|
|
124
|
-
client,
|
|
125
|
-
name,
|
|
126
|
-
options
|
|
127
|
-
]);
|
|
128
|
-
const value = useSyncExternalStore(subscribe, get, get);
|
|
129
|
-
return value;
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Creates a typed version of useReplane hook.
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```tsx
|
|
136
|
-
* interface AppConfigs {
|
|
137
|
-
* theme: { darkMode: boolean };
|
|
138
|
-
* features: { beta: boolean };
|
|
139
|
-
* }
|
|
140
|
-
*
|
|
141
|
-
* const useAppReplane = createReplaneHook<AppConfigs>();
|
|
142
|
-
*
|
|
143
|
-
* function MyComponent() {
|
|
144
|
-
* const replane = useAppReplane();
|
|
145
|
-
* // replane.get("theme") returns { darkMode: boolean }
|
|
146
|
-
* }
|
|
147
|
-
* ```
|
|
148
|
-
*/
|
|
149
|
-
function createReplaneHook() {
|
|
150
|
-
return function useTypedReplane() {
|
|
151
|
-
return useReplane();
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Creates a typed version of useConfig hook.
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```tsx
|
|
159
|
-
* interface AppConfigs {
|
|
160
|
-
* theme: { darkMode: boolean };
|
|
161
|
-
* features: { beta: boolean };
|
|
162
|
-
* }
|
|
163
|
-
*
|
|
164
|
-
* const useAppConfig = createConfigHook<AppConfigs>();
|
|
165
|
-
*
|
|
166
|
-
* function MyComponent() {
|
|
167
|
-
* const theme = useAppConfig("theme");
|
|
168
|
-
* // theme is typed as { darkMode: boolean }
|
|
169
|
-
* }
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
function createConfigHook() {
|
|
173
|
-
return function useTypedConfig(name, options) {
|
|
174
|
-
return useConfig(String(name), options);
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Hook for creating stateful resources with cleanup support.
|
|
179
|
-
* Unlike useMemo, this guarantees cleanup when dependencies change or on unmount.
|
|
180
|
-
*
|
|
181
|
-
* @param factory - Function that creates the resource
|
|
182
|
-
* @param cleanup - Function that cleans up the resource
|
|
183
|
-
* @param deps - Dependencies array (resource is recreated when these change)
|
|
184
|
-
*/
|
|
185
|
-
function useStateful(factory, cleanup, deps) {
|
|
186
|
-
const valueRef = useRef(null);
|
|
187
|
-
const initializedRef = useRef(false);
|
|
188
|
-
if (!initializedRef.current) {
|
|
189
|
-
valueRef.current = factory();
|
|
190
|
-
initializedRef.current = true;
|
|
191
|
-
}
|
|
192
|
-
useEffect(() => {
|
|
193
|
-
if (valueRef.current === null) valueRef.current = factory();
|
|
194
|
-
return () => {
|
|
195
|
-
if (valueRef.current !== null) {
|
|
196
|
-
cleanup(valueRef.current);
|
|
197
|
-
valueRef.current = null;
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}, deps);
|
|
201
|
-
return valueRef.current;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
124
|
//#endregion
|
|
205
125
|
//#region src/types.ts
|
|
206
126
|
/**
|
|
@@ -216,33 +136,53 @@ function hasClient(props) {
|
|
|
216
136
|
* Internal provider component for pre-created client.
|
|
217
137
|
*/
|
|
218
138
|
function ReplaneProviderWithClient({ client, children }) {
|
|
219
|
-
const value = useMemo(() => ({ client }), [client]);
|
|
220
|
-
return /* @__PURE__ */ jsx(ReplaneContext.Provider, {
|
|
139
|
+
const value = useMemo(() => ({ replane: client }), [client]);
|
|
140
|
+
return /* @__PURE__ */ jsx(ReplaneContext$1.Provider, {
|
|
221
141
|
value,
|
|
222
142
|
children
|
|
223
143
|
});
|
|
224
144
|
}
|
|
225
145
|
/**
|
|
226
146
|
* Internal provider component for restoring client from snapshot.
|
|
227
|
-
*
|
|
147
|
+
* Creates a Replane client synchronously and connects in background.
|
|
228
148
|
*/
|
|
229
149
|
function ReplaneProviderWithSnapshot({ options, snapshot, children }) {
|
|
230
|
-
const
|
|
150
|
+
const replaneRef = useRef(void 0);
|
|
151
|
+
if (!replaneRef.current) replaneRef.current = new Replane$1({
|
|
231
152
|
snapshot,
|
|
232
|
-
|
|
153
|
+
logger: options.logger,
|
|
154
|
+
context: options.context,
|
|
155
|
+
defaults: options.defaults
|
|
156
|
+
});
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
replaneRef.current.connect({
|
|
233
159
|
baseUrl: options.baseUrl,
|
|
234
160
|
sdkKey: options.sdkKey,
|
|
235
|
-
|
|
236
|
-
requestTimeoutMs: options.requestTimeoutMs,
|
|
161
|
+
connectTimeoutMs: options.connectTimeoutMs,
|
|
237
162
|
retryDelayMs: options.retryDelayMs,
|
|
163
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
238
164
|
inactivityTimeoutMs: options.inactivityTimeoutMs,
|
|
239
|
-
|
|
165
|
+
fetchFn: options.fetchFn,
|
|
240
166
|
agent: options.agent ?? DEFAULT_AGENT
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
167
|
+
}).catch((err) => {
|
|
168
|
+
(options.logger ?? console)?.error("Failed to connect Replane client", err);
|
|
169
|
+
});
|
|
170
|
+
return () => {
|
|
171
|
+
replaneRef.current.disconnect();
|
|
172
|
+
};
|
|
173
|
+
}, [
|
|
174
|
+
options.agent,
|
|
175
|
+
options.baseUrl,
|
|
176
|
+
options.connectTimeoutMs,
|
|
177
|
+
options.fetchFn,
|
|
178
|
+
options.inactivityTimeoutMs,
|
|
179
|
+
options.logger,
|
|
180
|
+
options.requestTimeoutMs,
|
|
181
|
+
options.retryDelayMs,
|
|
182
|
+
options.sdkKey
|
|
183
|
+
]);
|
|
184
|
+
const value = useMemo(() => ({ replane: replaneRef.current }), []);
|
|
185
|
+
return /* @__PURE__ */ jsx(ReplaneContext$1.Provider, {
|
|
246
186
|
value,
|
|
247
187
|
children
|
|
248
188
|
});
|
|
@@ -255,8 +195,8 @@ function ReplaneProviderWithOptions({ options, children, loader }) {
|
|
|
255
195
|
const state = useReplaneClientInternal(options);
|
|
256
196
|
if (state.status === "loading") return /* @__PURE__ */ jsx(Fragment, { children: loader ?? null });
|
|
257
197
|
if (state.status === "error") throw state.error;
|
|
258
|
-
const value = {
|
|
259
|
-
return /* @__PURE__ */ jsx(ReplaneContext.Provider, {
|
|
198
|
+
const value = { replane: state.client };
|
|
199
|
+
return /* @__PURE__ */ jsx(ReplaneContext$1.Provider, {
|
|
260
200
|
value,
|
|
261
201
|
children
|
|
262
202
|
});
|
|
@@ -266,20 +206,21 @@ function ReplaneProviderWithOptions({ options, children, loader }) {
|
|
|
266
206
|
*/
|
|
267
207
|
function ReplaneProviderWithSuspense({ options, children }) {
|
|
268
208
|
const client = useReplaneClientSuspense(options);
|
|
269
|
-
const value = useMemo(() => ({ client }), [client]);
|
|
270
|
-
return /* @__PURE__ */ jsx(ReplaneContext.Provider, {
|
|
209
|
+
const value = useMemo(() => ({ replane: client }), [client]);
|
|
210
|
+
return /* @__PURE__ */ jsx(ReplaneContext$1.Provider, {
|
|
271
211
|
value,
|
|
272
212
|
children
|
|
273
213
|
});
|
|
274
214
|
}
|
|
275
215
|
/**
|
|
276
|
-
* Provider component that makes a
|
|
216
|
+
* Provider component that makes a Replane client available to the component tree.
|
|
277
217
|
*
|
|
278
|
-
* Can be used in
|
|
218
|
+
* Can be used in several ways:
|
|
279
219
|
*
|
|
280
220
|
* 1. With a pre-created client:
|
|
281
221
|
* ```tsx
|
|
282
|
-
* const client =
|
|
222
|
+
* const client = new Replane({ defaults: { ... } });
|
|
223
|
+
* await client.connect({ baseUrl: '...', sdkKey: '...' });
|
|
283
224
|
* <ReplaneProvider client={client}>
|
|
284
225
|
* <App />
|
|
285
226
|
* </ReplaneProvider>
|
|
@@ -339,5 +280,74 @@ function ReplaneProvider(props) {
|
|
|
339
280
|
}
|
|
340
281
|
|
|
341
282
|
//#endregion
|
|
342
|
-
|
|
283
|
+
//#region src/hooks.ts
|
|
284
|
+
function useReplane() {
|
|
285
|
+
const context = useContext(ReplaneContext$1);
|
|
286
|
+
if (!context) throw new Error("useReplane must be used within a ReplaneProvider");
|
|
287
|
+
return context.replane;
|
|
288
|
+
}
|
|
289
|
+
function useConfig(name, options) {
|
|
290
|
+
const client = useReplane();
|
|
291
|
+
const subscribe = useCallback((callback) => {
|
|
292
|
+
return client.subscribe(name, callback);
|
|
293
|
+
}, [client, name]);
|
|
294
|
+
const get = useCallback(() => {
|
|
295
|
+
return client.get(name, options);
|
|
296
|
+
}, [
|
|
297
|
+
client,
|
|
298
|
+
name,
|
|
299
|
+
options
|
|
300
|
+
]);
|
|
301
|
+
const value = useSyncExternalStore(subscribe, get, get);
|
|
302
|
+
return value;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Creates a typed version of useReplane hook.
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```tsx
|
|
309
|
+
* interface AppConfigs {
|
|
310
|
+
* theme: { darkMode: boolean };
|
|
311
|
+
* features: { beta: boolean };
|
|
312
|
+
* }
|
|
313
|
+
*
|
|
314
|
+
* const useAppReplane = createReplaneHook<AppConfigs>();
|
|
315
|
+
*
|
|
316
|
+
* function MyComponent() {
|
|
317
|
+
* const replane = useAppReplane();
|
|
318
|
+
* // replane.get("theme") returns { darkMode: boolean }
|
|
319
|
+
* }
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
function createReplaneHook() {
|
|
323
|
+
return function useTypedReplane() {
|
|
324
|
+
return useReplane();
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Creates a typed version of useConfig hook.
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```tsx
|
|
332
|
+
* interface AppConfigs {
|
|
333
|
+
* theme: { darkMode: boolean };
|
|
334
|
+
* features: { beta: boolean };
|
|
335
|
+
* }
|
|
336
|
+
*
|
|
337
|
+
* const useAppConfig = createConfigHook<AppConfigs>();
|
|
338
|
+
*
|
|
339
|
+
* function MyComponent() {
|
|
340
|
+
* const theme = useAppConfig("theme");
|
|
341
|
+
* // theme is typed as { darkMode: boolean }
|
|
342
|
+
* }
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
function createConfigHook() {
|
|
346
|
+
return function useTypedConfig(name, options) {
|
|
347
|
+
return useConfig(String(name), options);
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
//#endregion
|
|
352
|
+
export { Replane, ReplaneError, ReplaneErrorCode, ReplaneProvider, clearSuspenseCache, createConfigHook, createReplaneHook, getReplaneSnapshot, useConfig, useReplane };
|
|
343
353
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["options: ReplaneClientOptions<T>","err: unknown","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/version.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","// Auto-generated - do not edit manually\nexport const VERSION = \"0.8.20\";\nexport const DEFAULT_AGENT = `replane-js-react/${VERSION}`;\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { createReplaneClient } from \"@replanejs/sdk\";\nimport type { ReplaneClient, ReplaneClientOptions } from \"@replanejs/sdk\";\nimport { DEFAULT_AGENT } from \"./version\";\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>({\n ...optionsRef.current,\n agent: optionsRef.current.agent ?? DEFAULT_AGENT,\n });\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>({\n ...options,\n agent: options.agent ?? DEFAULT_AGENT,\n })\n .then((client) => {\n const entry = suspenseCache.get(cacheKey);\n if (entry) {\n entry.result = client;\n }\n return client;\n })\n .catch((err: unknown) => {\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\";\nimport { DEFAULT_AGENT } from \"./version\";\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> & {\n snapshot: NonNullable<ReplaneProviderWithOptionsProps<T>[\"snapshot\"]>;\n}) {\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 agent: options.agent ?? DEFAULT_AGENT,\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":["ReplaneContext","options: ReplaneProviderOptions<T>","Replane","err: unknown","options?: ReplaneProviderOptions<T>","props: ReplaneProviderProps<T>","ReplaneContext","Replane","value: ReplaneContextValue<T>","props: ReplaneProviderProps<T>","ReplaneContext","name: string","options?: GetConfigOptions<T>","callback: () => void","name: K","options?: GetConfigOptions<TConfigs[K]>"],"sources":["../src/context.ts","../src/version.ts","../src/useReplaneClient.ts","../src/types.ts","../src/provider.tsx","../src/hooks.ts"],"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","// Auto-generated - do not edit manually\nexport const VERSION = \"0.9.0\";\nexport const DEFAULT_AGENT = `replane-js-react/${VERSION}`;\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { Replane } from \"@replanejs/sdk\";\nimport { DEFAULT_AGENT } from \"./version\";\nimport type { ReplaneProviderOptions } from \"./types\";\n\ntype ClientState<T extends object> =\n | { status: \"loading\"; client: null; error: null }\n | { status: \"ready\"; client: Replane<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<Replane<any>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result?: Replane<any>;\n error?: Error;\n }\n>();\n\nfunction getCacheKey<T extends object>(options: ReplaneProviderOptions<T>): string {\n return `${options.baseUrl}:${options.sdkKey}`;\n}\n\n/**\n * Creates a Replane client and connects it.\n */\nasync function createAndConnectClient<T extends object>(\n options: ReplaneProviderOptions<T>\n): Promise<Replane<T>> {\n const client = new Replane<T>({\n logger: options.logger,\n context: options.context,\n defaults: options.defaults,\n });\n\n await client.connect({\n baseUrl: options.baseUrl,\n sdkKey: options.sdkKey,\n connectTimeoutMs: options.connectTimeoutMs,\n retryDelayMs: options.retryDelayMs,\n requestTimeoutMs: options.requestTimeoutMs,\n inactivityTimeoutMs: options.inactivityTimeoutMs,\n fetchFn: options.fetchFn,\n agent: options.agent ?? DEFAULT_AGENT,\n });\n\n return client;\n}\n\ntype ErrorConstructor = new (message: string, options?: { cause?: unknown }) => Error;\n\n/**\n * Hook to manage Replane client 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: ReplaneProviderOptions<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<Replane<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 createAndConnectClient<T>(optionsRef.current);\n if (cancelled) {\n client.disconnect();\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.disconnect();\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: ReplaneProviderOptions<T>\n): Replane<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 Replane<T>;\n }\n // Still loading, throw the promise\n throw cached.promise;\n }\n\n // First time - create the promise\n const promise = createAndConnectClient<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: unknown) => {\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?: ReplaneProviderOptions<T>): void {\n if (options) {\n suspenseCache.delete(getCacheKey(options));\n } else {\n suspenseCache.clear();\n }\n}\n","import type { Replane, ReplaneSnapshot, ReplaneContext, ReplaneLogger } from \"@replanejs/sdk\";\nimport type { ReactNode } from \"react\";\n\nexport type UntypedReplaneConfig = Record<string, unknown>;\n\nexport interface ReplaneContextValue<T extends object = UntypedReplaneConfig> {\n replane: Replane<T>;\n}\n\n/**\n * Combined options for ReplaneProvider.\n * Includes both constructor options (context, logger, defaults) and connection options.\n */\nexport interface ReplaneProviderOptions<T extends object = UntypedReplaneConfig> {\n /**\n * Base URL of the Replane instance (no trailing slash).\n * @example \"https://app.replane.dev\"\n */\n baseUrl: string;\n /**\n * Project SDK key for authorization.\n * @example \"rp_XXXXXXXXX\"\n */\n sdkKey: string;\n /**\n * Default context for all config evaluations.\n * Can be overridden per-request in `client.get()`.\n */\n context?: ReplaneContext;\n /**\n * Optional logger (defaults to console).\n */\n logger?: ReplaneLogger;\n /**\n * Default values to use before connection is established.\n */\n defaults?: { [K in keyof T]?: T[K] };\n /**\n * Optional timeout in ms for the initial connection.\n * @default 5000\n */\n connectTimeoutMs?: number;\n /**\n * Delay between retries in ms.\n * @default 200\n */\n retryDelayMs?: number;\n /**\n * Optional timeout in ms for individual requests.\n * @default 2000\n */\n requestTimeoutMs?: number;\n /**\n * Timeout in ms for SSE connection inactivity.\n * @default 30000\n */\n inactivityTimeoutMs?: number;\n /**\n * Custom fetch implementation (useful for tests / polyfills).\n */\n fetchFn?: typeof fetch;\n /**\n * Agent identifier sent in User-Agent header.\n */\n agent?: string;\n}\n\n/**\n * Props for ReplaneProvider when using a pre-created client.\n */\nexport interface ReplaneProviderWithClientProps<T extends object = UntypedReplaneConfig> {\n /** Pre-created Replane client instance */\n client: Replane<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 Replane client */\n options: ReplaneProviderOptions<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 { useEffect, useMemo, useRef } from \"react\";\nimport { Replane } from \"@replanejs/sdk\";\nimport { ReplaneContext } from \"./context\";\nimport { useReplaneClientInternal, useReplaneClientSuspense } from \"./useReplaneClient\";\nimport type {\n ReplaneProviderProps,\n ReplaneProviderWithClientProps,\n ReplaneProviderWithOptionsProps,\n ReplaneContextValue,\n} from \"./types\";\nimport { hasClient } from \"./types\";\nimport { DEFAULT_AGENT } from \"./version\";\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>>(() => ({ replane: client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Internal provider component for restoring client from snapshot.\n * Creates a Replane client synchronously and connects in background.\n */\nfunction ReplaneProviderWithSnapshot<T extends object>({\n options,\n snapshot,\n children,\n}: ReplaneProviderWithOptionsProps<T> & {\n snapshot: NonNullable<ReplaneProviderWithOptionsProps<T>[\"snapshot\"]>;\n}) {\n const replaneRef = useRef<Replane<T>>(undefined as unknown as Replane<T>);\n\n if (!replaneRef.current) {\n replaneRef.current = new Replane<T>({\n snapshot,\n logger: options.logger,\n context: options.context,\n defaults: options.defaults,\n });\n }\n\n useEffect(() => {\n replaneRef.current\n .connect({\n baseUrl: options.baseUrl,\n sdkKey: options.sdkKey,\n connectTimeoutMs: options.connectTimeoutMs,\n retryDelayMs: options.retryDelayMs,\n requestTimeoutMs: options.requestTimeoutMs,\n inactivityTimeoutMs: options.inactivityTimeoutMs,\n fetchFn: options.fetchFn,\n agent: options.agent ?? DEFAULT_AGENT,\n })\n .catch((err) => {\n (options.logger ?? console)?.error(\"Failed to connect Replane client\", err);\n });\n\n return () => {\n replaneRef.current.disconnect();\n };\n }, [\n options.agent,\n options.baseUrl,\n options.connectTimeoutMs,\n options.fetchFn,\n options.inactivityTimeoutMs,\n options.logger,\n options.requestTimeoutMs,\n options.retryDelayMs,\n options.sdkKey,\n ]);\n\n const value = useMemo<ReplaneContextValue<T>>(() => ({ replane: replaneRef.current }), []);\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> = { replane: 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>>(() => ({ replane: client }), [client]);\n return <ReplaneContext.Provider value={value}>{children}</ReplaneContext.Provider>;\n}\n\n/**\n * Provider component that makes a Replane client available to the component tree.\n *\n * Can be used in several ways:\n *\n * 1. With a pre-created client:\n * ```tsx\n * const client = new Replane({ defaults: { ... } });\n * await client.connect({ baseUrl: '...', sdkKey: '...' });\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","\"use client\";\n\nimport { useCallback, useContext, useSyncExternalStore } from \"react\";\nimport { ReplaneContext } from \"./context\";\nimport type { UntypedReplaneConfig } from \"./types\";\nimport type { Replane, GetConfigOptions } from \"@replanejs/sdk\";\n\nexport function useReplane<T extends object = UntypedReplaneConfig>(): Replane<T> {\n const context = useContext(ReplaneContext);\n if (!context) {\n throw new Error(\"useReplane must be used within a ReplaneProvider\");\n }\n return context.replane as Replane<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(): Replane<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"],"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.9.0",
|
|
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.9.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@testing-library/jest-dom": "^6.9.1",
|