@replanejs/svelte 0.7.4 → 0.7.6
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 +137 -111
- package/dist/ReplaneContext.svelte +120 -0
- package/dist/ReplaneContext.svelte.d.ts +6 -0
- package/dist/ReplaneContext.svelte.d.ts.map +1 -0
- package/dist/context.js +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/stores.d.ts +78 -13
- package/dist/stores.d.ts.map +1 -1
- package/dist/stores.js +85 -12
- package/dist/types.d.ts +19 -37
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -7
- package/package.json +2 -2
- package/dist/ReplaneProvider.svelte +0 -22
- package/dist/ReplaneProvider.svelte.d.ts +0 -12
- package/dist/ReplaneProvider.svelte.d.ts.map +0 -1
- package/dist/ReplaneProviderAsync.svelte +0 -84
- package/dist/ReplaneProviderAsync.svelte.d.ts +0 -21
- package/dist/ReplaneProviderAsync.svelte.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -6,23 +6,14 @@ Svelte SDK for [Replane](https://github.com/replane-dev/replane-javascript) - fe
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @replanejs/svelte
|
|
9
|
-
# or
|
|
10
|
-
pnpm add @replanejs/svelte
|
|
11
|
-
# or
|
|
12
|
-
yarn add @replanejs/svelte
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
## Requirements
|
|
16
|
-
|
|
17
|
-
- Svelte 4.0.0 or higher (Svelte 5 supported)
|
|
18
|
-
- Node.js 18.0.0 or higher
|
|
19
|
-
|
|
20
11
|
## Quick Start
|
|
21
12
|
|
|
22
13
|
```svelte
|
|
23
14
|
<script>
|
|
24
|
-
import {
|
|
25
|
-
import { createReplaneClient } from '@replanejs/
|
|
15
|
+
import { ReplaneContext, config } from '@replanejs/svelte';
|
|
16
|
+
import { createReplaneClient } from '@replanejs/svelte';
|
|
26
17
|
|
|
27
18
|
const client = await createReplaneClient({
|
|
28
19
|
baseUrl: 'https://your-replane-server.com',
|
|
@@ -30,20 +21,20 @@ yarn add @replanejs/svelte
|
|
|
30
21
|
});
|
|
31
22
|
</script>
|
|
32
23
|
|
|
33
|
-
<
|
|
24
|
+
<ReplaneContext {client}>
|
|
34
25
|
<MyComponent />
|
|
35
|
-
</
|
|
26
|
+
</ReplaneContext>
|
|
36
27
|
```
|
|
37
28
|
|
|
38
29
|
```svelte
|
|
39
30
|
<!-- MyComponent.svelte -->
|
|
40
31
|
<script>
|
|
41
|
-
import {
|
|
32
|
+
import { config } from '@replanejs/svelte';
|
|
42
33
|
|
|
43
|
-
const
|
|
34
|
+
const feature = config<boolean>('feature-flag-name');
|
|
44
35
|
</script>
|
|
45
36
|
|
|
46
|
-
{#if $
|
|
37
|
+
{#if $feature}
|
|
47
38
|
<p>Feature is enabled!</p>
|
|
48
39
|
{:else}
|
|
49
40
|
<p>Feature is disabled</p>
|
|
@@ -52,173 +43,209 @@ yarn add @replanejs/svelte
|
|
|
52
43
|
|
|
53
44
|
## API
|
|
54
45
|
|
|
55
|
-
###
|
|
46
|
+
### config
|
|
56
47
|
|
|
57
|
-
|
|
48
|
+
Create a reactive store for a specific config value. Similar to `readable()` or `derived()`.
|
|
58
49
|
|
|
59
50
|
```svelte
|
|
60
51
|
<script>
|
|
61
|
-
import {
|
|
62
|
-
import { createReplaneClient } from '@replanejs/sdk';
|
|
52
|
+
import { config } from '@replanejs/svelte';
|
|
63
53
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
// Returns a Svelte readable store
|
|
55
|
+
const featureEnabled = config<boolean>('featureEnabled');
|
|
56
|
+
|
|
57
|
+
// With evaluation context
|
|
58
|
+
const greeting = config<string>('greeting', {
|
|
59
|
+
context: { userId: '123', isPremium: true }
|
|
67
60
|
});
|
|
68
61
|
</script>
|
|
69
62
|
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
63
|
+
{#if $featureEnabled}
|
|
64
|
+
<p>{$greeting}</p>
|
|
65
|
+
{/if}
|
|
73
66
|
```
|
|
74
67
|
|
|
75
|
-
###
|
|
68
|
+
### getReplane
|
|
76
69
|
|
|
77
|
-
|
|
70
|
+
Get direct access to the Replane client from context.
|
|
78
71
|
|
|
79
72
|
```svelte
|
|
80
73
|
<script>
|
|
81
|
-
import {
|
|
74
|
+
import { getReplane } from '@replanejs/svelte';
|
|
82
75
|
|
|
83
|
-
const
|
|
84
|
-
baseUrl: 'https://your-replane-server.com',
|
|
85
|
-
sdkKey: 'your-sdk-key',
|
|
86
|
-
};
|
|
76
|
+
const { client } = getReplane();
|
|
87
77
|
|
|
88
|
-
function
|
|
89
|
-
|
|
78
|
+
function handleClick() {
|
|
79
|
+
const value = client.get('some-config');
|
|
80
|
+
console.log(value);
|
|
90
81
|
}
|
|
91
82
|
</script>
|
|
92
83
|
|
|
93
|
-
<
|
|
94
|
-
<App />
|
|
95
|
-
|
|
96
|
-
{#snippet loader()}
|
|
97
|
-
<p>Loading configuration...</p>
|
|
98
|
-
{/snippet}
|
|
99
|
-
</ReplaneProviderAsync>
|
|
84
|
+
<button onclick={handleClick}>Get Config</button>
|
|
100
85
|
```
|
|
101
86
|
|
|
102
|
-
###
|
|
103
|
-
|
|
104
|
-
Create a reactive store for a specific config value. The store automatically updates when the config value changes on the server.
|
|
87
|
+
### configFrom
|
|
105
88
|
|
|
106
|
-
|
|
89
|
+
Create a reactive store from a client directly (without context).
|
|
107
90
|
|
|
108
91
|
```svelte
|
|
109
92
|
<script>
|
|
110
|
-
import {
|
|
111
|
-
|
|
112
|
-
// Basic usage - returns a Svelte readable store
|
|
113
|
-
const featureEnabled = useConfig<boolean>('featureEnabled');
|
|
93
|
+
import { configFrom } from '@replanejs/svelte';
|
|
94
|
+
import { client } from './replane-client';
|
|
114
95
|
|
|
115
|
-
|
|
116
|
-
const greeting = useConfig<string>('greeting', {
|
|
117
|
-
context: { userId: '123', isPremium: true }
|
|
118
|
-
});
|
|
96
|
+
const featureEnabled = configFrom<boolean>(client, 'featureEnabled');
|
|
119
97
|
</script>
|
|
120
98
|
|
|
121
99
|
{#if $featureEnabled}
|
|
122
|
-
<p>
|
|
100
|
+
<p>Feature is enabled!</p>
|
|
123
101
|
{/if}
|
|
124
102
|
```
|
|
125
103
|
|
|
126
|
-
###
|
|
104
|
+
### ReplaneContext
|
|
127
105
|
|
|
128
|
-
|
|
106
|
+
Context component that makes the Replane client available to your component tree.
|
|
107
|
+
|
|
108
|
+
Can be used in three ways:
|
|
109
|
+
|
|
110
|
+
**1. With a pre-created client:**
|
|
129
111
|
|
|
130
112
|
```svelte
|
|
131
113
|
<script>
|
|
132
|
-
import {
|
|
133
|
-
|
|
134
|
-
const { client } = useReplane();
|
|
114
|
+
import { ReplaneContext, createReplaneClient } from '@replanejs/svelte';
|
|
135
115
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
116
|
+
const client = await createReplaneClient({
|
|
117
|
+
baseUrl: 'https://your-replane-server.com',
|
|
118
|
+
sdkKey: 'your-sdk-key',
|
|
119
|
+
});
|
|
141
120
|
</script>
|
|
142
121
|
|
|
143
|
-
<
|
|
122
|
+
<ReplaneContext {client}>
|
|
123
|
+
<App />
|
|
124
|
+
</ReplaneContext>
|
|
144
125
|
```
|
|
145
126
|
|
|
146
|
-
|
|
127
|
+
**2. With options (client managed internally):**
|
|
128
|
+
|
|
129
|
+
```svelte
|
|
130
|
+
<script>
|
|
131
|
+
import { ReplaneContext } from '@replanejs/svelte';
|
|
147
132
|
|
|
148
|
-
|
|
133
|
+
const options = {
|
|
134
|
+
baseUrl: 'https://your-replane-server.com',
|
|
135
|
+
sdkKey: 'your-sdk-key',
|
|
136
|
+
};
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
<svelte:boundary onerror={(e) => console.error(e)}>
|
|
140
|
+
<ReplaneContext {options}>
|
|
141
|
+
<App />
|
|
142
|
+
|
|
143
|
+
{#snippet loader()}
|
|
144
|
+
<p>Loading...</p>
|
|
145
|
+
{/snippet}
|
|
146
|
+
</ReplaneContext>
|
|
147
|
+
|
|
148
|
+
{#snippet failed(error)}
|
|
149
|
+
<p>Error: {error.message}</p>
|
|
150
|
+
{/snippet}
|
|
151
|
+
</svelte:boundary>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**3. With a snapshot (for SSR/hydration):**
|
|
149
155
|
|
|
150
156
|
```svelte
|
|
151
157
|
<script>
|
|
152
|
-
import {
|
|
153
|
-
import { client } from './replane-client';
|
|
158
|
+
import { ReplaneContext } from '@replanejs/svelte';
|
|
154
159
|
|
|
155
|
-
|
|
160
|
+
let { data, children } = $props();
|
|
156
161
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
162
|
+
const options = {
|
|
163
|
+
baseUrl: import.meta.env.VITE_REPLANE_BASE_URL,
|
|
164
|
+
sdkKey: import.meta.env.VITE_REPLANE_SDK_KEY,
|
|
165
|
+
};
|
|
161
166
|
</script>
|
|
162
167
|
|
|
163
|
-
{
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
<ReplaneContext {options} snapshot={data.replaneSnapshot}>
|
|
169
|
+
{@render children()}
|
|
170
|
+
</ReplaneContext>
|
|
166
171
|
```
|
|
167
172
|
|
|
168
|
-
##
|
|
173
|
+
## Typed Stores
|
|
174
|
+
|
|
175
|
+
For better type safety, create typed versions of the store functions:
|
|
169
176
|
|
|
170
|
-
|
|
177
|
+
```ts
|
|
178
|
+
// $lib/replane/index.ts
|
|
179
|
+
import { createTypedConfig, createTypedReplane } from '@replanejs/svelte';
|
|
180
|
+
|
|
181
|
+
interface AppConfigs {
|
|
182
|
+
theme: { darkMode: boolean; primaryColor: string };
|
|
183
|
+
features: { betaEnabled: boolean };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const appConfig = createTypedConfig<AppConfigs>();
|
|
187
|
+
export const getAppReplane = createTypedReplane<AppConfigs>();
|
|
188
|
+
```
|
|
171
189
|
|
|
172
190
|
```svelte
|
|
173
191
|
<script lang="ts">
|
|
174
|
-
import {
|
|
175
|
-
|
|
176
|
-
interface MyConfigs {
|
|
177
|
-
theme: 'light' | 'dark';
|
|
178
|
-
maxItems: number;
|
|
179
|
-
features: {
|
|
180
|
-
analytics: boolean;
|
|
181
|
-
notifications: boolean;
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Type-safe stores
|
|
186
|
-
const theme = useConfig<MyConfigs['theme']>('theme');
|
|
187
|
-
const maxItems = useConfig<MyConfigs['maxItems']>('maxItems');
|
|
192
|
+
import { appConfig } from '$lib/replane';
|
|
188
193
|
|
|
189
|
-
//
|
|
190
|
-
const
|
|
194
|
+
// Config names autocomplete, values are fully typed
|
|
195
|
+
const theme = appConfig("theme");
|
|
196
|
+
// $theme is { darkMode: boolean; primaryColor: string }
|
|
191
197
|
</script>
|
|
192
198
|
|
|
193
|
-
<
|
|
199
|
+
<div style:color={$theme.primaryColor}>
|
|
200
|
+
{$theme.darkMode ? "Dark" : "Light"}
|
|
201
|
+
</div>
|
|
194
202
|
```
|
|
195
203
|
|
|
196
|
-
##
|
|
204
|
+
## SSR / SvelteKit
|
|
205
|
+
|
|
206
|
+
For server-side rendering, fetch configs on the server and restore on the client:
|
|
197
207
|
|
|
198
|
-
|
|
208
|
+
```ts
|
|
209
|
+
// src/routes/+layout.server.ts
|
|
210
|
+
import { getReplaneSnapshot } from '@replanejs/svelte';
|
|
211
|
+
|
|
212
|
+
export async function load() {
|
|
213
|
+
const snapshot = await getReplaneSnapshot({
|
|
214
|
+
baseUrl: import.meta.env.REPLANE_BASE_URL,
|
|
215
|
+
sdkKey: import.meta.env.REPLANE_SDK_KEY,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
return { replaneSnapshot: snapshot };
|
|
219
|
+
}
|
|
220
|
+
```
|
|
199
221
|
|
|
200
222
|
```svelte
|
|
201
|
-
|
|
202
|
-
|
|
223
|
+
<!-- src/routes/+layout.svelte -->
|
|
224
|
+
<script lang="ts">
|
|
225
|
+
import { ReplaneContext } from '@replanejs/svelte';
|
|
203
226
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
227
|
+
let { data, children } = $props();
|
|
228
|
+
|
|
229
|
+
const options = {
|
|
230
|
+
baseUrl: import.meta.env.VITE_REPLANE_BASE_URL,
|
|
231
|
+
sdkKey: import.meta.env.VITE_REPLANE_SDK_KEY,
|
|
232
|
+
};
|
|
209
233
|
</script>
|
|
234
|
+
|
|
235
|
+
<ReplaneContext {options} snapshot={data.replaneSnapshot}>
|
|
236
|
+
{@render children()}
|
|
237
|
+
</ReplaneContext>
|
|
210
238
|
```
|
|
211
239
|
|
|
212
240
|
## Realtime Updates
|
|
213
241
|
|
|
214
|
-
All stores
|
|
242
|
+
All stores automatically subscribe to realtime updates via SSE. When a config changes on the server, the store updates automatically.
|
|
215
243
|
|
|
216
244
|
```svelte
|
|
217
245
|
<script>
|
|
218
|
-
import {
|
|
246
|
+
import { config } from '@replanejs/svelte';
|
|
219
247
|
|
|
220
|
-
|
|
221
|
-
const maintenanceMode = useConfig<boolean>('maintenance-mode');
|
|
248
|
+
const maintenanceMode = config<boolean>('maintenance-mode');
|
|
222
249
|
</script>
|
|
223
250
|
|
|
224
251
|
{#if $maintenanceMode}
|
|
@@ -229,4 +256,3 @@ All stores created with `useConfig` or `createConfigStore` automatically subscri
|
|
|
229
256
|
## License
|
|
230
257
|
|
|
231
258
|
MIT
|
|
232
|
-
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { ReplaneClient } from "@replanejs/sdk";
|
|
3
|
+
import type {
|
|
4
|
+
ReplaneContextProps,
|
|
5
|
+
ReplaneContextWithClientProps,
|
|
6
|
+
ReplaneContextWithOptionsProps,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
ReplaneContextProps,
|
|
11
|
+
ReplaneContextWithClientProps,
|
|
12
|
+
ReplaneContextWithOptionsProps,
|
|
13
|
+
};
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import { createReplaneClient, restoreReplaneClient } from "@replanejs/sdk";
|
|
18
|
+
import { setReplaneContext } from "./context";
|
|
19
|
+
import { hasClient } from "./types";
|
|
20
|
+
|
|
21
|
+
let props: ReplaneContextProps = $props();
|
|
22
|
+
|
|
23
|
+
type ClientState =
|
|
24
|
+
| { status: "loading"; client: null; error: null }
|
|
25
|
+
| { status: "ready"; client: ReplaneClient<any>; error: null }
|
|
26
|
+
| { status: "error"; client: null; error: Error };
|
|
27
|
+
|
|
28
|
+
let state = $state<ClientState>({ status: "loading", client: null, error: null });
|
|
29
|
+
let clientRef: ReplaneClient<any> | null = null;
|
|
30
|
+
let cancelled = false;
|
|
31
|
+
|
|
32
|
+
// Handle client initialization based on props
|
|
33
|
+
$effect(() => {
|
|
34
|
+
cancelled = false;
|
|
35
|
+
|
|
36
|
+
if (hasClient(props)) {
|
|
37
|
+
// Pre-created client - use directly
|
|
38
|
+
state = { status: "ready", client: props.client, error: null };
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Options-based initialization
|
|
43
|
+
const { options, snapshot } = props;
|
|
44
|
+
|
|
45
|
+
if (snapshot) {
|
|
46
|
+
// Restore from snapshot synchronously
|
|
47
|
+
try {
|
|
48
|
+
const client = restoreReplaneClient({
|
|
49
|
+
snapshot,
|
|
50
|
+
connection: {
|
|
51
|
+
baseUrl: options.baseUrl,
|
|
52
|
+
sdkKey: options.sdkKey,
|
|
53
|
+
fetchFn: options.fetchFn,
|
|
54
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
55
|
+
retryDelayMs: options.retryDelayMs,
|
|
56
|
+
inactivityTimeoutMs: options.inactivityTimeoutMs,
|
|
57
|
+
logger: options.logger,
|
|
58
|
+
},
|
|
59
|
+
context: options.context,
|
|
60
|
+
});
|
|
61
|
+
clientRef = client;
|
|
62
|
+
state = { status: "ready", client, error: null };
|
|
63
|
+
} catch (err) {
|
|
64
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
65
|
+
state = { status: "error", client: null, error };
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Async client creation
|
|
71
|
+
state = { status: "loading", client: null, error: null };
|
|
72
|
+
|
|
73
|
+
createReplaneClient(options)
|
|
74
|
+
.then((client) => {
|
|
75
|
+
if (cancelled) {
|
|
76
|
+
client.close();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
clientRef = client;
|
|
80
|
+
state = { status: "ready", client, error: null };
|
|
81
|
+
})
|
|
82
|
+
.catch((err) => {
|
|
83
|
+
if (cancelled) return;
|
|
84
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
85
|
+
state = { status: "error", client: null, error };
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
cancelled = true;
|
|
90
|
+
// Only close client if we created it (not pre-created)
|
|
91
|
+
if (clientRef && !hasClient(props)) {
|
|
92
|
+
clientRef.close();
|
|
93
|
+
clientRef = null;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Set context when client is ready
|
|
99
|
+
$effect(() => {
|
|
100
|
+
if (state.status === "ready" && state.client) {
|
|
101
|
+
setReplaneContext(state.client);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Get children and loader from props
|
|
106
|
+
const children = $derived(props.children);
|
|
107
|
+
const loader = $derived(hasClient(props) ? undefined : props.loader);
|
|
108
|
+
</script>
|
|
109
|
+
|
|
110
|
+
{#if state.status === "loading"}
|
|
111
|
+
{#if loader}
|
|
112
|
+
{@render loader()}
|
|
113
|
+
{/if}
|
|
114
|
+
{:else if state.status === "error"}
|
|
115
|
+
{(() => {
|
|
116
|
+
throw state.error;
|
|
117
|
+
})()}
|
|
118
|
+
{:else if state.status === "ready"}
|
|
119
|
+
{@render children()}
|
|
120
|
+
{/if}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ReplaneContextProps, ReplaneContextWithClientProps, ReplaneContextWithOptionsProps } from "./types";
|
|
2
|
+
export type { ReplaneContextProps, ReplaneContextWithClientProps, ReplaneContextWithOptionsProps, };
|
|
3
|
+
declare const ReplaneContext: import("svelte").Component<ReplaneContextProps, {}, "">;
|
|
4
|
+
type ReplaneContext = ReturnType<typeof ReplaneContext>;
|
|
5
|
+
export default ReplaneContext;
|
|
6
|
+
//# sourceMappingURL=ReplaneContext.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReplaneContext.svelte.d.ts","sourceRoot":"","sources":["../src/ReplaneContext.svelte.ts"],"names":[],"mappings":"AAIE,OAAO,KAAK,EACV,mBAAmB,EACnB,6BAA6B,EAC7B,8BAA8B,EAC/B,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,mBAAmB,EACnB,6BAA6B,EAC7B,8BAA8B,GAC/B,CAAC;AAqHJ,QAAA,MAAM,cAAc,yDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
package/dist/context.js
CHANGED
|
@@ -16,7 +16,7 @@ export function setReplaneContext(client) {
|
|
|
16
16
|
export function getReplaneContext() {
|
|
17
17
|
const context = getContext(REPLANE_CONTEXT_KEY);
|
|
18
18
|
if (!context) {
|
|
19
|
-
throw new Error("
|
|
19
|
+
throw new Error("getReplane() must be used within a ReplaneProvider");
|
|
20
20
|
}
|
|
21
21
|
return context;
|
|
22
22
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export {
|
|
3
|
-
export { useReplane, useConfig, createConfigStore } from "./stores";
|
|
1
|
+
export { default as ReplaneContext } from "./ReplaneContext.svelte";
|
|
2
|
+
export { getReplane, config, configFrom, createTypedReplane, createTypedConfig } from "./stores";
|
|
4
3
|
export { setReplaneContext, getReplaneContext, hasReplaneContext } from "./context";
|
|
5
|
-
export
|
|
4
|
+
export { createReplaneClient, createInMemoryReplaneClient, restoreReplaneClient, getReplaneSnapshot, clearSnapshotCache, ReplaneError, ReplaneErrorCode, } from "@replanejs/sdk";
|
|
5
|
+
export type { ReplaneClient, ReplaneClientOptions, ReplaneSnapshot, ReplaneLogger, GetConfigOptions, RestoreReplaneClientOptions, GetReplaneSnapshotOptions, } from "@replanejs/sdk";
|
|
6
|
+
export type { ReplaneContextValue, ReplaneContextProps, ReplaneContextWithClientProps, ReplaneContextWithOptionsProps, ConfigOptions, } from "./types";
|
|
7
|
+
export { hasClient, hasOptions } from "./types";
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGjG,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGpF,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,6BAA6B,EAC7B,8BAA8B,EAC9B,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Components
|
|
2
|
-
export { default as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export { useReplane, useConfig, createConfigStore } from "./stores";
|
|
2
|
+
export { default as ReplaneContext } from "./ReplaneContext.svelte";
|
|
3
|
+
// Stores
|
|
4
|
+
export { getReplane, config, configFrom, createTypedReplane, createTypedConfig } from "./stores";
|
|
6
5
|
// Context utilities (for advanced use cases)
|
|
7
6
|
export { setReplaneContext, getReplaneContext, hasReplaneContext } from "./context";
|
|
7
|
+
// Re-export from SDK for convenience
|
|
8
|
+
export { createReplaneClient, createInMemoryReplaneClient, restoreReplaneClient, getReplaneSnapshot, clearSnapshotCache, ReplaneError, ReplaneErrorCode, } from "@replanejs/sdk";
|
|
9
|
+
// Type guards
|
|
10
|
+
export { hasClient, hasOptions } from "./types";
|
package/dist/stores.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Readable } from "svelte/store";
|
|
2
2
|
import type { ReplaneClient } from "@replanejs/sdk";
|
|
3
|
-
import type { ReplaneContextValue,
|
|
3
|
+
import type { ReplaneContextValue, ConfigOptions } from "./types";
|
|
4
4
|
/**
|
|
5
5
|
* Get the Replane context containing the client.
|
|
6
6
|
*
|
|
@@ -12,14 +12,14 @@ import type { ReplaneContextValue, UseConfigOptions } from "./types";
|
|
|
12
12
|
* @example
|
|
13
13
|
* ```svelte
|
|
14
14
|
* <script>
|
|
15
|
-
* import {
|
|
15
|
+
* import { getReplane } from '@replanejs/svelte';
|
|
16
16
|
*
|
|
17
|
-
* const { client } =
|
|
18
|
-
* //
|
|
17
|
+
* const { client } = getReplane();
|
|
18
|
+
* // Access client directly: client.get('configName')
|
|
19
19
|
* </script>
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function getReplane<T extends Record<string, unknown> = any>(): ReplaneContextValue<T>;
|
|
23
23
|
/**
|
|
24
24
|
* Create a reactive store for a specific config value.
|
|
25
25
|
*
|
|
@@ -33,10 +33,10 @@ export declare function useReplane<T extends Record<string, unknown> = any>(): R
|
|
|
33
33
|
* @example
|
|
34
34
|
* ```svelte
|
|
35
35
|
* <script>
|
|
36
|
-
* import {
|
|
36
|
+
* import { config } from '@replanejs/svelte';
|
|
37
37
|
*
|
|
38
|
-
* const featureEnabled =
|
|
39
|
-
* const greeting =
|
|
38
|
+
* const featureEnabled = config<boolean>('featureEnabled');
|
|
39
|
+
* const greeting = config<string>('greeting', {
|
|
40
40
|
* context: { userId: '123' }
|
|
41
41
|
* });
|
|
42
42
|
* </script>
|
|
@@ -46,12 +46,12 @@ export declare function useReplane<T extends Record<string, unknown> = any>(): R
|
|
|
46
46
|
* {/if}
|
|
47
47
|
* ```
|
|
48
48
|
*/
|
|
49
|
-
export declare function
|
|
49
|
+
export declare function config<T>(name: string, options?: ConfigOptions): Readable<T>;
|
|
50
50
|
/**
|
|
51
51
|
* Create a reactive store for a config value using a pre-existing client.
|
|
52
52
|
*
|
|
53
53
|
* This is useful when you have direct access to a client and don't want to
|
|
54
|
-
* use the context-based approach.
|
|
54
|
+
* use the context-based approach. Similar to readable() or derived().
|
|
55
55
|
*
|
|
56
56
|
* @param client - The Replane client to use
|
|
57
57
|
* @param name - The name of the config to subscribe to
|
|
@@ -61,10 +61,10 @@ export declare function useConfig<T>(name: string, options?: UseConfigOptions):
|
|
|
61
61
|
* @example
|
|
62
62
|
* ```svelte
|
|
63
63
|
* <script>
|
|
64
|
-
* import {
|
|
64
|
+
* import { configFrom } from '@replanejs/svelte';
|
|
65
65
|
* import { client } from './replane-client';
|
|
66
66
|
*
|
|
67
|
-
* const featureEnabled =
|
|
67
|
+
* const featureEnabled = configFrom<boolean>(client, 'featureEnabled');
|
|
68
68
|
* </script>
|
|
69
69
|
*
|
|
70
70
|
* {#if $featureEnabled}
|
|
@@ -72,5 +72,70 @@ export declare function useConfig<T>(name: string, options?: UseConfigOptions):
|
|
|
72
72
|
* {/if}
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
|
-
export declare function
|
|
75
|
+
export declare function configFrom<T, C extends Record<string, unknown> = any>(client: ReplaneClient<C>, name: string, options?: ConfigOptions): Readable<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Creates a typed version of getReplane().
|
|
78
|
+
*
|
|
79
|
+
* By creating typed accessors once and importing them throughout your app,
|
|
80
|
+
* you get full type safety and autocomplete for config names and values.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* // $lib/replane/index.ts
|
|
85
|
+
* import { createTypedReplane } from '@replanejs/svelte';
|
|
86
|
+
*
|
|
87
|
+
* interface AppConfigs {
|
|
88
|
+
* theme: { darkMode: boolean };
|
|
89
|
+
* features: { beta: boolean };
|
|
90
|
+
* }
|
|
91
|
+
*
|
|
92
|
+
* export const getAppReplane = createTypedReplane<AppConfigs>();
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```svelte
|
|
97
|
+
* <script>
|
|
98
|
+
* import { getAppReplane } from './lib/replane';
|
|
99
|
+
*
|
|
100
|
+
* const { client } = getAppReplane();
|
|
101
|
+
* const theme = client.get("theme"); // fully typed
|
|
102
|
+
* </script>
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function createTypedReplane<TConfigs extends Record<string, unknown>>(): () => ReplaneContextValue<TConfigs>;
|
|
106
|
+
/**
|
|
107
|
+
* Creates a typed version of config().
|
|
108
|
+
*
|
|
109
|
+
* By creating typed accessors once and importing them throughout your app,
|
|
110
|
+
* you get full type safety and autocomplete for config names and values.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* // $lib/replane/index.ts
|
|
115
|
+
* import { createTypedConfig } from '@replanejs/svelte';
|
|
116
|
+
*
|
|
117
|
+
* interface AppConfigs {
|
|
118
|
+
* theme: { darkMode: boolean; primaryColor: string };
|
|
119
|
+
* features: { beta: boolean; maxItems: number };
|
|
120
|
+
* }
|
|
121
|
+
*
|
|
122
|
+
* export const appConfig = createTypedConfig<AppConfigs>();
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```svelte
|
|
127
|
+
* <script>
|
|
128
|
+
* import { appConfig } from './lib/replane';
|
|
129
|
+
*
|
|
130
|
+
* // Config names autocomplete, return values are fully typed
|
|
131
|
+
* const theme = appConfig("theme");
|
|
132
|
+
* // $theme is typed as { darkMode: boolean; primaryColor: string }
|
|
133
|
+
* </script>
|
|
134
|
+
*
|
|
135
|
+
* <div style:color={$theme.primaryColor}>
|
|
136
|
+
* {$theme.darkMode ? "Dark" : "Light"}
|
|
137
|
+
* </div>
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
export declare function createTypedConfig<TConfigs extends Record<string, unknown>>(): <K extends keyof TConfigs>(name: K, options?: ConfigOptions) => Readable<TConfigs[K]>;
|
|
76
141
|
//# sourceMappingURL=stores.d.ts.map
|
package/dist/stores.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE;;;;;;;;;;;;;;;;;GAiBG;AAEH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,KAAK,mBAAmB,CAAC,CAAC,CAAC,CAE5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,CAY5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,EACnE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,aAAa,GACtB,QAAQ,CAAC,CAAC,CAAC,CAOb;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WACrD,mBAAmB,CAAC,QAAQ,CAAC,CAGlD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MACvD,CAAC,SAAS,MAAM,QAAQ,EACvC,MAAM,CAAC,EACP,UAAU,aAAa,KACtB,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAGzB"}
|
package/dist/stores.js
CHANGED
|
@@ -11,15 +11,15 @@ import { getReplaneContext } from "./context";
|
|
|
11
11
|
* @example
|
|
12
12
|
* ```svelte
|
|
13
13
|
* <script>
|
|
14
|
-
* import {
|
|
14
|
+
* import { getReplane } from '@replanejs/svelte';
|
|
15
15
|
*
|
|
16
|
-
* const { client } =
|
|
17
|
-
* //
|
|
16
|
+
* const { client } = getReplane();
|
|
17
|
+
* // Access client directly: client.get('configName')
|
|
18
18
|
* </script>
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
export function
|
|
22
|
+
export function getReplane() {
|
|
23
23
|
return getReplaneContext();
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
@@ -35,10 +35,10 @@ export function useReplane() {
|
|
|
35
35
|
* @example
|
|
36
36
|
* ```svelte
|
|
37
37
|
* <script>
|
|
38
|
-
* import {
|
|
38
|
+
* import { config } from '@replanejs/svelte';
|
|
39
39
|
*
|
|
40
|
-
* const featureEnabled =
|
|
41
|
-
* const greeting =
|
|
40
|
+
* const featureEnabled = config<boolean>('featureEnabled');
|
|
41
|
+
* const greeting = config<string>('greeting', {
|
|
42
42
|
* context: { userId: '123' }
|
|
43
43
|
* });
|
|
44
44
|
* </script>
|
|
@@ -48,7 +48,7 @@ export function useReplane() {
|
|
|
48
48
|
* {/if}
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
|
-
export function
|
|
51
|
+
export function config(name, options) {
|
|
52
52
|
const { client } = getReplaneContext();
|
|
53
53
|
return readable(client.get(name, options), (set) => {
|
|
54
54
|
// Subscribe to config changes
|
|
@@ -63,7 +63,7 @@ export function useConfig(name, options) {
|
|
|
63
63
|
* Create a reactive store for a config value using a pre-existing client.
|
|
64
64
|
*
|
|
65
65
|
* This is useful when you have direct access to a client and don't want to
|
|
66
|
-
* use the context-based approach.
|
|
66
|
+
* use the context-based approach. Similar to readable() or derived().
|
|
67
67
|
*
|
|
68
68
|
* @param client - The Replane client to use
|
|
69
69
|
* @param name - The name of the config to subscribe to
|
|
@@ -73,10 +73,10 @@ export function useConfig(name, options) {
|
|
|
73
73
|
* @example
|
|
74
74
|
* ```svelte
|
|
75
75
|
* <script>
|
|
76
|
-
* import {
|
|
76
|
+
* import { configFrom } from '@replanejs/svelte';
|
|
77
77
|
* import { client } from './replane-client';
|
|
78
78
|
*
|
|
79
|
-
* const featureEnabled =
|
|
79
|
+
* const featureEnabled = configFrom<boolean>(client, 'featureEnabled');
|
|
80
80
|
* </script>
|
|
81
81
|
*
|
|
82
82
|
* {#if $featureEnabled}
|
|
@@ -85,7 +85,7 @@ export function useConfig(name, options) {
|
|
|
85
85
|
* ```
|
|
86
86
|
*/
|
|
87
87
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
-
export function
|
|
88
|
+
export function configFrom(client, name, options) {
|
|
89
89
|
return readable(client.get(name, options), (set) => {
|
|
90
90
|
const unsubscribe = client.subscribe(name, () => {
|
|
91
91
|
set(client.get(name, options));
|
|
@@ -93,3 +93,76 @@ export function createConfigStore(client, name, options) {
|
|
|
93
93
|
return unsubscribe;
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Creates a typed version of getReplane().
|
|
98
|
+
*
|
|
99
|
+
* By creating typed accessors once and importing them throughout your app,
|
|
100
|
+
* you get full type safety and autocomplete for config names and values.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* // $lib/replane/index.ts
|
|
105
|
+
* import { createTypedReplane } from '@replanejs/svelte';
|
|
106
|
+
*
|
|
107
|
+
* interface AppConfigs {
|
|
108
|
+
* theme: { darkMode: boolean };
|
|
109
|
+
* features: { beta: boolean };
|
|
110
|
+
* }
|
|
111
|
+
*
|
|
112
|
+
* export const getAppReplane = createTypedReplane<AppConfigs>();
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```svelte
|
|
117
|
+
* <script>
|
|
118
|
+
* import { getAppReplane } from './lib/replane';
|
|
119
|
+
*
|
|
120
|
+
* const { client } = getAppReplane();
|
|
121
|
+
* const theme = client.get("theme"); // fully typed
|
|
122
|
+
* </script>
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export function createTypedReplane() {
|
|
126
|
+
return function () {
|
|
127
|
+
return getReplane();
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Creates a typed version of config().
|
|
132
|
+
*
|
|
133
|
+
* By creating typed accessors once and importing them throughout your app,
|
|
134
|
+
* you get full type safety and autocomplete for config names and values.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* // $lib/replane/index.ts
|
|
139
|
+
* import { createTypedConfig } from '@replanejs/svelte';
|
|
140
|
+
*
|
|
141
|
+
* interface AppConfigs {
|
|
142
|
+
* theme: { darkMode: boolean; primaryColor: string };
|
|
143
|
+
* features: { beta: boolean; maxItems: number };
|
|
144
|
+
* }
|
|
145
|
+
*
|
|
146
|
+
* export const appConfig = createTypedConfig<AppConfigs>();
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```svelte
|
|
151
|
+
* <script>
|
|
152
|
+
* import { appConfig } from './lib/replane';
|
|
153
|
+
*
|
|
154
|
+
* // Config names autocomplete, return values are fully typed
|
|
155
|
+
* const theme = appConfig("theme");
|
|
156
|
+
* // $theme is typed as { darkMode: boolean; primaryColor: string }
|
|
157
|
+
* </script>
|
|
158
|
+
*
|
|
159
|
+
* <div style:color={$theme.primaryColor}>
|
|
160
|
+
* {$theme.darkMode ? "Dark" : "Light"}
|
|
161
|
+
* </div>
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function createTypedConfig() {
|
|
165
|
+
return function (name, options) {
|
|
166
|
+
return config(String(name), options);
|
|
167
|
+
};
|
|
168
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -7,67 +7,49 @@ export interface ReplaneContextValue<T extends Record<string, unknown> = any> {
|
|
|
7
7
|
client: ReplaneClient<T>;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Props for
|
|
10
|
+
* Props for ReplaneContext when using a pre-created client.
|
|
11
11
|
*/
|
|
12
|
-
export interface
|
|
12
|
+
export interface ReplaneContextWithClientProps<T extends Record<string, unknown> = any> {
|
|
13
13
|
/** Pre-created ReplaneClient instance */
|
|
14
14
|
client: ReplaneClient<T>;
|
|
15
15
|
/** Children snippet */
|
|
16
16
|
children: Snippet;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* Props for
|
|
19
|
+
* Props for ReplaneContext when letting it manage the client internally.
|
|
20
20
|
*/
|
|
21
|
-
export interface
|
|
22
|
-
/** Options to create the ReplaneClient */
|
|
21
|
+
export interface ReplaneContextWithOptionsProps<T extends Record<string, unknown> = any> {
|
|
22
|
+
/** Options to create or restore the ReplaneClient */
|
|
23
23
|
options: ReplaneClientOptions<T>;
|
|
24
24
|
/** Children snippet */
|
|
25
25
|
children: Snippet;
|
|
26
|
+
/**
|
|
27
|
+
* Optional snapshot from server-side rendering.
|
|
28
|
+
* When provided, the client will be restored from the snapshot synchronously
|
|
29
|
+
* instead of fetching configs from the server.
|
|
30
|
+
* The `options` will be used for live updates connection if provided.
|
|
31
|
+
*/
|
|
32
|
+
snapshot?: ReplaneSnapshot<T>;
|
|
26
33
|
/**
|
|
27
34
|
* Optional loading snippet to show while the client is initializing.
|
|
28
35
|
* If not provided, children will not render until ready.
|
|
36
|
+
* Ignored when snapshot is provided (restoration is synchronous).
|
|
29
37
|
*/
|
|
30
38
|
loader?: Snippet;
|
|
31
|
-
/**
|
|
32
|
-
* Callback when client initialization fails.
|
|
33
|
-
*/
|
|
34
|
-
onError?: (error: Error) => void;
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
* Props for ReplaneProvider when restoring from a snapshot (SSR/hydration).
|
|
38
|
-
*/
|
|
39
|
-
export interface ReplaneProviderWithSnapshotProps<T extends Record<string, unknown> = any> {
|
|
40
|
-
/** Snapshot from server-side rendering */
|
|
41
|
-
snapshot: ReplaneSnapshot<T>;
|
|
42
|
-
/** Optional connection options for live updates */
|
|
43
|
-
connection?: {
|
|
44
|
-
baseUrl: string;
|
|
45
|
-
sdkKey: string;
|
|
46
|
-
fetchFn?: typeof fetch;
|
|
47
|
-
requestTimeoutMs?: number;
|
|
48
|
-
retryDelayMs?: number;
|
|
49
|
-
inactivityTimeoutMs?: number;
|
|
50
|
-
};
|
|
51
|
-
/** Children snippet */
|
|
52
|
-
children: Snippet;
|
|
53
|
-
}
|
|
54
|
-
export type ReplaneProviderProps<T extends Record<string, unknown> = any> = ReplaneProviderWithClientProps<T> | ReplaneProviderWithOptionsProps<T> | ReplaneProviderWithSnapshotProps<T>;
|
|
40
|
+
export type ReplaneContextProps<T extends Record<string, unknown> = any> = ReplaneContextWithClientProps<T> | ReplaneContextWithOptionsProps<T>;
|
|
55
41
|
/**
|
|
56
42
|
* Type guard to check if props contain a pre-created client.
|
|
57
43
|
*/
|
|
58
|
-
export declare function hasClient<T extends Record<string, unknown>>(props:
|
|
59
|
-
/**
|
|
60
|
-
* Type guard to check if props contain options.
|
|
61
|
-
*/
|
|
62
|
-
export declare function hasOptions<T extends Record<string, unknown>>(props: ReplaneProviderProps<T>): props is ReplaneProviderWithOptionsProps<T>;
|
|
44
|
+
export declare function hasClient<T extends Record<string, unknown>>(props: ReplaneContextProps<T>): props is ReplaneContextWithClientProps<T>;
|
|
63
45
|
/**
|
|
64
|
-
* Type guard to check if props contain
|
|
46
|
+
* Type guard to check if props contain options (with or without snapshot).
|
|
65
47
|
*/
|
|
66
|
-
export declare function
|
|
48
|
+
export declare function hasOptions<T extends Record<string, unknown>>(props: ReplaneContextProps<T>): props is ReplaneContextWithOptionsProps<T>;
|
|
67
49
|
/**
|
|
68
|
-
* Options for
|
|
50
|
+
* Options for config()
|
|
69
51
|
*/
|
|
70
|
-
export interface
|
|
52
|
+
export interface ConfigOptions {
|
|
71
53
|
/**
|
|
72
54
|
* Context for override evaluation (merged with client-level context).
|
|
73
55
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;GAEG;AAEH,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IAC1E,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAC1B;AAED;;GAEG;AAEH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC;;GAEG;AAEH,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IAC1E,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAC1B;AAED;;GAEG;AAEH,MAAM,WAAW,6BAA6B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IACpF,yCAAyC;IACzC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACzB,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AAEH,MAAM,WAAW,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IACrF,qDAAqD;IACrD,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACjC,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAGD,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,IACnE,6BAA6B,CAAC,CAAC,CAAC,GAChC,8BAA8B,CAAC,CAAC,CAAC,CAAC;AAEtC;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC5B,KAAK,IAAI,6BAA6B,CAAC,CAAC,CAAC,CAE3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC5B,KAAK,IAAI,8BAA8B,CAAC,CAAC,CAAC,CAE5C;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D"}
|
package/dist/types.js
CHANGED
|
@@ -5,14 +5,8 @@ export function hasClient(props) {
|
|
|
5
5
|
return "client" in props && props.client !== undefined;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Type guard to check if props contain options.
|
|
8
|
+
* Type guard to check if props contain options (with or without snapshot).
|
|
9
9
|
*/
|
|
10
10
|
export function hasOptions(props) {
|
|
11
11
|
return "options" in props && props.options !== undefined;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Type guard to check if props contain a snapshot.
|
|
15
|
-
*/
|
|
16
|
-
export function hasSnapshot(props) {
|
|
17
|
-
return "snapshot" in props && props.snapshot !== undefined;
|
|
18
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replanejs/svelte",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "Svelte SDK for Replane - feature flags and remote configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"svelte": ">=4.0.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@replanejs/sdk": "^0.7.
|
|
42
|
+
"@replanejs/sdk": "^0.7.6"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@sveltejs/package": "^2.3.10",
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import type { ReplaneClient } from "@replanejs/sdk";
|
|
3
|
-
import type { Snippet } from "svelte";
|
|
4
|
-
|
|
5
|
-
export interface ReplaneProviderProps {
|
|
6
|
-
/** Pre-created ReplaneClient instance */
|
|
7
|
-
client: ReplaneClient<any>;
|
|
8
|
-
/** Children snippet */
|
|
9
|
-
children: Snippet;
|
|
10
|
-
}
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<script lang="ts">
|
|
14
|
-
import { setReplaneContext } from "./context";
|
|
15
|
-
|
|
16
|
-
let { client, children }: ReplaneProviderProps = $props();
|
|
17
|
-
|
|
18
|
-
// Set the client in context
|
|
19
|
-
setReplaneContext(client);
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
{@render children()}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ReplaneClient } from "@replanejs/sdk";
|
|
2
|
-
import type { Snippet } from "svelte";
|
|
3
|
-
export interface ReplaneProviderProps {
|
|
4
|
-
/** Pre-created ReplaneClient instance */
|
|
5
|
-
client: ReplaneClient<any>;
|
|
6
|
-
/** Children snippet */
|
|
7
|
-
children: Snippet;
|
|
8
|
-
}
|
|
9
|
-
declare const ReplaneProvider: import("svelte").Component<ReplaneProviderProps, {}, "">;
|
|
10
|
-
type ReplaneProvider = ReturnType<typeof ReplaneProvider>;
|
|
11
|
-
export default ReplaneProvider;
|
|
12
|
-
//# sourceMappingURL=ReplaneProvider.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReplaneProvider.svelte.d.ts","sourceRoot":"","sources":["../src/ReplaneProvider.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC3B,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAoBH,QAAA,MAAM,eAAe,0DAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import type { ReplaneClientOptions } from "@replanejs/sdk";
|
|
3
|
-
import type { Snippet } from "svelte";
|
|
4
|
-
|
|
5
|
-
export interface ReplaneProviderAsyncProps {
|
|
6
|
-
/** Options to create the ReplaneClient */
|
|
7
|
-
options: ReplaneClientOptions<any>;
|
|
8
|
-
/** Children snippet */
|
|
9
|
-
children: Snippet;
|
|
10
|
-
/**
|
|
11
|
-
* Optional loading snippet to show while the client is initializing.
|
|
12
|
-
* If not provided, nothing will render until ready.
|
|
13
|
-
*/
|
|
14
|
-
loader?: Snippet;
|
|
15
|
-
/**
|
|
16
|
-
* Callback when client initialization fails.
|
|
17
|
-
*/
|
|
18
|
-
onError?: (error: Error) => void;
|
|
19
|
-
}
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<script lang="ts">
|
|
23
|
-
import { createReplaneClient, type ReplaneClient } from "@replanejs/sdk";
|
|
24
|
-
import { setReplaneContext } from "./context";
|
|
25
|
-
|
|
26
|
-
let { options, children, loader, onError }: ReplaneProviderAsyncProps = $props();
|
|
27
|
-
|
|
28
|
-
type ClientState =
|
|
29
|
-
| { status: "loading"; client: null; error: null }
|
|
30
|
-
| { status: "ready"; client: ReplaneClient<any>; error: null }
|
|
31
|
-
| { status: "error"; client: null; error: Error };
|
|
32
|
-
|
|
33
|
-
let state = $state<ClientState>({ status: "loading", client: null, error: null });
|
|
34
|
-
let clientRef: ReplaneClient<any> | null = null;
|
|
35
|
-
let cancelled = false;
|
|
36
|
-
|
|
37
|
-
// Initialize the client
|
|
38
|
-
$effect(() => {
|
|
39
|
-
cancelled = false;
|
|
40
|
-
|
|
41
|
-
createReplaneClient(options)
|
|
42
|
-
.then((client) => {
|
|
43
|
-
if (cancelled) {
|
|
44
|
-
client.close();
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
clientRef = client;
|
|
48
|
-
state = { status: "ready", client, error: null };
|
|
49
|
-
})
|
|
50
|
-
.catch((err) => {
|
|
51
|
-
if (cancelled) return;
|
|
52
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
53
|
-
state = { status: "error", client: null, error };
|
|
54
|
-
onError?.(error);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
return () => {
|
|
58
|
-
cancelled = true;
|
|
59
|
-
if (clientRef) {
|
|
60
|
-
clientRef.close();
|
|
61
|
-
clientRef = null;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Set context when client is ready
|
|
67
|
-
$effect(() => {
|
|
68
|
-
if (state.status === "ready" && state.client) {
|
|
69
|
-
setReplaneContext(state.client);
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
</script>
|
|
73
|
-
|
|
74
|
-
{#if state.status === "loading"}
|
|
75
|
-
{#if loader}
|
|
76
|
-
{@render loader()}
|
|
77
|
-
{/if}
|
|
78
|
-
{:else if state.status === "error"}
|
|
79
|
-
{#if loader}
|
|
80
|
-
{@render loader()}
|
|
81
|
-
{/if}
|
|
82
|
-
{:else if state.status === "ready"}
|
|
83
|
-
{@render children()}
|
|
84
|
-
{/if}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { ReplaneClientOptions } from "@replanejs/sdk";
|
|
2
|
-
import type { Snippet } from "svelte";
|
|
3
|
-
export interface ReplaneProviderAsyncProps {
|
|
4
|
-
/** Options to create the ReplaneClient */
|
|
5
|
-
options: ReplaneClientOptions<any>;
|
|
6
|
-
/** Children snippet */
|
|
7
|
-
children: Snippet;
|
|
8
|
-
/**
|
|
9
|
-
* Optional loading snippet to show while the client is initializing.
|
|
10
|
-
* If not provided, nothing will render until ready.
|
|
11
|
-
*/
|
|
12
|
-
loader?: Snippet;
|
|
13
|
-
/**
|
|
14
|
-
* Callback when client initialization fails.
|
|
15
|
-
*/
|
|
16
|
-
onError?: (error: Error) => void;
|
|
17
|
-
}
|
|
18
|
-
declare const ReplaneProviderAsync: import("svelte").Component<ReplaneProviderAsyncProps, {}, "">;
|
|
19
|
-
type ReplaneProviderAsync = ReturnType<typeof ReplaneProviderAsync>;
|
|
20
|
-
export default ReplaneProviderAsync;
|
|
21
|
-
//# sourceMappingURL=ReplaneProviderAsync.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReplaneProviderAsync.svelte.d.ts","sourceRoot":"","sources":["../src/ReplaneProviderAsync.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,yBAAyB;IACxC,0CAA0C;IAC1C,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACnC,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AA0EH,QAAA,MAAM,oBAAoB,+DAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
|