@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 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 { ReplaneProvider, useConfig } from '@replanejs/svelte';
25
- import { createReplaneClient } from '@replanejs/sdk';
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
- <ReplaneProvider {client}>
24
+ <ReplaneContext {client}>
34
25
  <MyComponent />
35
- </ReplaneProvider>
26
+ </ReplaneContext>
36
27
  ```
37
28
 
38
29
  ```svelte
39
30
  <!-- MyComponent.svelte -->
40
31
  <script>
41
- import { useConfig } from '@replanejs/svelte';
32
+ import { config } from '@replanejs/svelte';
42
33
 
43
- const isFeatureEnabled = useConfig<boolean>('feature-flag-name');
34
+ const feature = config<boolean>('feature-flag-name');
44
35
  </script>
45
36
 
46
- {#if $isFeatureEnabled}
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
- ### ReplaneProvider
46
+ ### config
56
47
 
57
- Provider component that makes the Replane client available to your component tree. Use this when you have a pre-created client.
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 { ReplaneProvider } from '@replanejs/svelte';
62
- import { createReplaneClient } from '@replanejs/sdk';
52
+ import { config } from '@replanejs/svelte';
63
53
 
64
- const client = await createReplaneClient({
65
- baseUrl: 'https://your-replane-server.com',
66
- sdkKey: 'your-sdk-key',
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
- <ReplaneProvider {client}>
71
- <App />
72
- </ReplaneProvider>
63
+ {#if $featureEnabled}
64
+ <p>{$greeting}</p>
65
+ {/if}
73
66
  ```
74
67
 
75
- ### ReplaneProviderAsync
68
+ ### getReplane
76
69
 
77
- Provider component that creates and manages the client internally. Handles loading and error states.
70
+ Get direct access to the Replane client from context.
78
71
 
79
72
  ```svelte
80
73
  <script>
81
- import { ReplaneProviderAsync } from '@replanejs/svelte';
74
+ import { getReplane } from '@replanejs/svelte';
82
75
 
83
- const options = {
84
- baseUrl: 'https://your-replane-server.com',
85
- sdkKey: 'your-sdk-key',
86
- };
76
+ const { client } = getReplane();
87
77
 
88
- function handleError(error) {
89
- console.error('Failed to initialize Replane:', error);
78
+ function handleClick() {
79
+ const value = client.get('some-config');
80
+ console.log(value);
90
81
  }
91
82
  </script>
92
83
 
93
- <ReplaneProviderAsync {options} onError={handleError}>
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
- ### useConfig
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
- Must be called during component initialization (in the script section, not in event handlers).
89
+ Create a reactive store from a client directly (without context).
107
90
 
108
91
  ```svelte
109
92
  <script>
110
- import { useConfig } from '@replanejs/svelte';
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
- // With evaluation context
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>{$greeting}</p>
100
+ <p>Feature is enabled!</p>
123
101
  {/if}
124
102
  ```
125
103
 
126
- ### useReplane
104
+ ### ReplaneContext
127
105
 
128
- Get direct access to the Replane client from context.
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 { useReplane } from '@replanejs/svelte';
133
-
134
- const { client } = useReplane();
114
+ import { ReplaneContext, createReplaneClient } from '@replanejs/svelte';
135
115
 
136
- function handleClick() {
137
- // Access client methods directly
138
- const value = client.get('some-config');
139
- console.log(value);
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
- <button onclick={handleClick}>Get Config</button>
122
+ <ReplaneContext {client}>
123
+ <App />
124
+ </ReplaneContext>
144
125
  ```
145
126
 
146
- ### createConfigStore
127
+ **2. With options (client managed internally):**
128
+
129
+ ```svelte
130
+ <script>
131
+ import { ReplaneContext } from '@replanejs/svelte';
147
132
 
148
- Create a reactive store for a config value using a pre-existing client. Useful when you have direct access to a client and don't want to use the context-based approach.
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 { createConfigStore } from '@replanejs/svelte';
153
- import { client } from './replane-client';
158
+ import { ReplaneContext } from '@replanejs/svelte';
154
159
 
155
- const featureEnabled = createConfigStore<boolean>(client, 'featureEnabled');
160
+ let { data, children } = $props();
156
161
 
157
- // With context
158
- const userGreeting = createConfigStore<string>(client, 'greeting', {
159
- context: { userId: '123' }
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
- {#if $featureEnabled}
164
- <p>{$userGreeting}</p>
165
- {/if}
168
+ <ReplaneContext {options} snapshot={data.replaneSnapshot}>
169
+ {@render children()}
170
+ </ReplaneContext>
166
171
  ```
167
172
 
168
- ## TypeScript
173
+ ## Typed Stores
174
+
175
+ For better type safety, create typed versions of the store functions:
169
176
 
170
- The SDK is fully typed. You can provide type parameters to get type-safe configuration values:
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 { useConfig, useReplane } from '@replanejs/svelte';
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
- // Typed client access
190
- const { client } = useReplane<MyConfigs>();
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
- <p>Theme: {$theme}, Max items: {$maxItems}</p>
199
+ <div style:color={$theme.primaryColor}>
200
+ {$theme.darkMode ? "Dark" : "Light"}
201
+ </div>
194
202
  ```
195
203
 
196
- ## Context Utilities
204
+ ## SSR / SvelteKit
205
+
206
+ For server-side rendering, fetch configs on the server and restore on the client:
197
207
 
198
- For advanced use cases, you can directly interact with the Svelte context:
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
- <script>
202
- import { setReplaneContext, getReplaneContext, hasReplaneContext } from '@replanejs/svelte';
223
+ <!-- src/routes/+layout.svelte -->
224
+ <script lang="ts">
225
+ import { ReplaneContext } from '@replanejs/svelte';
203
226
 
204
- // Check if context exists
205
- if (hasReplaneContext()) {
206
- const { client } = getReplaneContext();
207
- // Use client...
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 created with `useConfig` or `createConfigStore` automatically subscribe to realtime updates via Server-Sent Events (SSE). When a config value changes on the server, the store updates and your component re-renders automatically.
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 { useConfig } from '@replanejs/svelte';
246
+ import { config } from '@replanejs/svelte';
219
247
 
220
- // This store will automatically update when 'maintenance-mode' changes
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("useReplane must be used within a ReplaneProvider");
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 ReplaneProvider } from "./ReplaneProvider.svelte";
2
- export { default as ReplaneProviderAsync } from "./ReplaneProviderAsync.svelte";
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 type { ReplaneContextValue, ReplaneProviderProps, ReplaneProviderWithClientProps, ReplaneProviderWithOptionsProps, ReplaneProviderWithSnapshotProps, UseConfigOptions, } from "./types";
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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGhF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGpF,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,8BAA8B,EAC9B,+BAA+B,EAC/B,gCAAgC,EAChC,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
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 ReplaneProvider } from "./ReplaneProvider.svelte";
3
- export { default as ReplaneProviderAsync } from "./ReplaneProviderAsync.svelte";
4
- // Stores and hooks
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, UseConfigOptions } from "./types";
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 { useReplane } from '@replanejs/svelte';
15
+ * import { getReplane } from '@replanejs/svelte';
16
16
  *
17
- * const { client } = useReplane();
18
- * // Use client directly: client.get('configName')
17
+ * const { client } = getReplane();
18
+ * // Access client directly: client.get('configName')
19
19
  * </script>
20
20
  * ```
21
21
  */
22
- export declare function useReplane<T extends Record<string, unknown> = any>(): ReplaneContextValue<T>;
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 { useConfig } from '@replanejs/svelte';
36
+ * import { config } from '@replanejs/svelte';
37
37
  *
38
- * const featureEnabled = useConfig<boolean>('featureEnabled');
39
- * const greeting = useConfig<string>('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 useConfig<T>(name: string, options?: UseConfigOptions): Readable<T>;
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 { createConfigStore } from '@replanejs/svelte';
64
+ * import { configFrom } from '@replanejs/svelte';
65
65
  * import { client } from './replane-client';
66
66
  *
67
- * const featureEnabled = createConfigStore<boolean>(client, '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 createConfigStore<T, C extends Record<string, unknown> = any>(client: ReplaneClient<C>, name: string, options?: UseConfigOptions): Readable<T>;
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
@@ -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,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAErE;;;;;;;;;;;;;;;;;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,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAYlF;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,EAC1E,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAAC,CAAC,CAAC,CAOb"}
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 { useReplane } from '@replanejs/svelte';
14
+ * import { getReplane } from '@replanejs/svelte';
15
15
  *
16
- * const { client } = useReplane();
17
- * // Use client directly: client.get('configName')
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 useReplane() {
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 { useConfig } from '@replanejs/svelte';
38
+ * import { config } from '@replanejs/svelte';
39
39
  *
40
- * const featureEnabled = useConfig<boolean>('featureEnabled');
41
- * const greeting = useConfig<string>('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 useConfig(name, options) {
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 { createConfigStore } from '@replanejs/svelte';
76
+ * import { configFrom } from '@replanejs/svelte';
77
77
  * import { client } from './replane-client';
78
78
  *
79
- * const featureEnabled = createConfigStore<boolean>(client, '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 createConfigStore(client, name, options) {
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 ReplaneProvider when using a pre-created client.
10
+ * Props for ReplaneContext when using a pre-created client.
11
11
  */
12
- export interface ReplaneProviderWithClientProps<T extends Record<string, unknown> = any> {
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 ReplaneProvider when letting it manage the client internally.
19
+ * Props for ReplaneContext when letting it manage the client internally.
20
20
  */
21
- export interface ReplaneProviderWithOptionsProps<T extends Record<string, unknown> = any> {
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: ReplaneProviderProps<T>): props is ReplaneProviderWithClientProps<T>;
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 a snapshot.
46
+ * Type guard to check if props contain options (with or without snapshot).
65
47
  */
66
- export declare function hasSnapshot<T extends Record<string, unknown>>(props: ReplaneProviderProps<T>): props is ReplaneProviderWithSnapshotProps<T>;
48
+ export declare function hasOptions<T extends Record<string, unknown>>(props: ReplaneContextProps<T>): props is ReplaneContextWithOptionsProps<T>;
67
49
  /**
68
- * Options for useConfig
50
+ * Options for config()
69
51
  */
70
- export interface UseConfigOptions {
52
+ export interface ConfigOptions {
71
53
  /**
72
54
  * Context for override evaluation (merged with client-level context).
73
55
  */
@@ -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,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IACrF,yCAAyC;IACzC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACzB,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AAEH,MAAM,WAAW,+BAA+B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IACtF,0CAA0C;IAC1C,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACjC,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;AAED;;GAEG;AAEH,MAAM,WAAW,gCAAgC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG;IACvF,0CAA0C;IAC1C,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7B,mDAAmD;IACnD,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAGD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,IACpE,8BAA8B,CAAC,CAAC,CAAC,GACjC,+BAA+B,CAAC,CAAC,CAAC,GAClC,gCAAgC,CAAC,CAAC,CAAC,CAAC;AAExC;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC7B,KAAK,IAAI,8BAA8B,CAAC,CAAC,CAAC,CAE5C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC7B,KAAK,IAAI,+BAA+B,CAAC,CAAC,CAAC,CAE7C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC7B,KAAK,IAAI,gCAAgC,CAAC,CAAC,CAAC,CAE9C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CAC5D"}
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.4",
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.4"
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"}