@replanejs/svelte 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/ReplaneProvider.svelte +22 -0
- package/dist/ReplaneProvider.svelte.d.ts +12 -0
- package/dist/ReplaneProvider.svelte.d.ts.map +1 -0
- package/dist/ReplaneProviderAsync.svelte +84 -0
- package/dist/ReplaneProviderAsync.svelte.d.ts +21 -0
- package/dist/ReplaneProviderAsync.svelte.d.ts.map +1 -0
- package/dist/context.d.ts +18 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +35 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/stores.d.ts +76 -0
- package/dist/stores.d.ts.map +1 -0
- package/dist/stores.js +95 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dmitry Tilyupo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,22 @@
|
|
|
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()}
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
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}
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReplaneClient } from "@replanejs/sdk";
|
|
2
|
+
import type { ReplaneContextValue } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Set the Replane client in Svelte context.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare function setReplaneContext<T extends object>(client: ReplaneClient<T>): void;
|
|
8
|
+
/**
|
|
9
|
+
* Get the Replane context from Svelte context.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function getReplaneContext<T extends object = any>(): ReplaneContextValue<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Check if Replane context is available.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasReplaneContext(): boolean;
|
|
18
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAInD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAGlF;AAED;;;GAGG;AAEH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG,KAAK,mBAAmB,CAAC,CAAC,CAAC,CAMlF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getContext, setContext } from "svelte";
|
|
2
|
+
const REPLANE_CONTEXT_KEY = Symbol("replane");
|
|
3
|
+
/**
|
|
4
|
+
* Set the Replane client in Svelte context.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export function setReplaneContext(client) {
|
|
8
|
+
const value = { client };
|
|
9
|
+
setContext(REPLANE_CONTEXT_KEY, value);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the Replane context from Svelte context.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
export function getReplaneContext() {
|
|
17
|
+
const context = getContext(REPLANE_CONTEXT_KEY);
|
|
18
|
+
if (!context) {
|
|
19
|
+
throw new Error("useReplane must be used within a ReplaneProvider");
|
|
20
|
+
}
|
|
21
|
+
return context;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if Replane context is available.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export function hasReplaneContext() {
|
|
28
|
+
try {
|
|
29
|
+
const context = getContext(REPLANE_CONTEXT_KEY);
|
|
30
|
+
return context !== undefined;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as ReplaneProvider } from "./ReplaneProvider.svelte";
|
|
2
|
+
export { default as ReplaneProviderAsync } from "./ReplaneProviderAsync.svelte";
|
|
3
|
+
export { useReplane, useConfig, createConfigStore } from "./stores";
|
|
4
|
+
export { setReplaneContext, getReplaneContext, hasReplaneContext } from "./context";
|
|
5
|
+
export type { ReplaneContextValue, ReplaneProviderProps, ReplaneProviderWithClientProps, ReplaneProviderWithOptionsProps, ReplaneProviderWithSnapshotProps, UseConfigOptions, } from "./types";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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";
|
|
6
|
+
// Context utilities (for advanced use cases)
|
|
7
|
+
export { setReplaneContext, getReplaneContext, hasReplaneContext } from "./context";
|
package/dist/stores.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type Readable } from "svelte/store";
|
|
2
|
+
import type { ReplaneClient } from "@replanejs/sdk";
|
|
3
|
+
import type { ReplaneContextValue, UseConfigOptions } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Get the Replane context containing the client.
|
|
6
|
+
*
|
|
7
|
+
* Must be called during component initialization (in the script section, not in event handlers).
|
|
8
|
+
*
|
|
9
|
+
* @returns The Replane context with the client
|
|
10
|
+
* @throws Error if called outside a ReplaneProvider
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```svelte
|
|
14
|
+
* <script>
|
|
15
|
+
* import { useReplane } from '@replanejs/svelte';
|
|
16
|
+
*
|
|
17
|
+
* const { client } = useReplane();
|
|
18
|
+
* // Use client directly: client.get('configName')
|
|
19
|
+
* </script>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function useReplane<T extends object = any>(): ReplaneContextValue<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Create a reactive store for a specific config value.
|
|
25
|
+
*
|
|
26
|
+
* Must be called during component initialization (in the script section, not in event handlers).
|
|
27
|
+
* The returned store will automatically update when the config value changes on the server.
|
|
28
|
+
*
|
|
29
|
+
* @param name - The name of the config to subscribe to
|
|
30
|
+
* @param options - Optional context for override evaluation
|
|
31
|
+
* @returns A Svelte readable store containing the config value
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```svelte
|
|
35
|
+
* <script>
|
|
36
|
+
* import { useConfig } from '@replanejs/svelte';
|
|
37
|
+
*
|
|
38
|
+
* const featureEnabled = useConfig<boolean>('featureEnabled');
|
|
39
|
+
* const greeting = useConfig<string>('greeting', {
|
|
40
|
+
* context: { userId: '123' }
|
|
41
|
+
* });
|
|
42
|
+
* </script>
|
|
43
|
+
*
|
|
44
|
+
* {#if $featureEnabled}
|
|
45
|
+
* <p>{$greeting}</p>
|
|
46
|
+
* {/if}
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function useConfig<T>(name: string, options?: UseConfigOptions): Readable<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Create a reactive store for a config value using a pre-existing client.
|
|
52
|
+
*
|
|
53
|
+
* This is useful when you have direct access to a client and don't want to
|
|
54
|
+
* use the context-based approach.
|
|
55
|
+
*
|
|
56
|
+
* @param client - The Replane client to use
|
|
57
|
+
* @param name - The name of the config to subscribe to
|
|
58
|
+
* @param options - Optional context for override evaluation
|
|
59
|
+
* @returns A Svelte readable store containing the config value
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```svelte
|
|
63
|
+
* <script>
|
|
64
|
+
* import { createConfigStore } from '@replanejs/svelte';
|
|
65
|
+
* import { client } from './replane-client';
|
|
66
|
+
*
|
|
67
|
+
* const featureEnabled = createConfigStore<boolean>(client, 'featureEnabled');
|
|
68
|
+
* </script>
|
|
69
|
+
*
|
|
70
|
+
* {#if $featureEnabled}
|
|
71
|
+
* <p>Feature is enabled!</p>
|
|
72
|
+
* {/if}
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function createConfigStore<T, C extends object = any>(client: ReplaneClient<C>, name: string, options?: UseConfigOptions): Readable<T>;
|
|
76
|
+
//# sourceMappingURL=stores.d.ts.map
|
|
@@ -0,0 +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,GAAG,GAAG,KAAK,mBAAmB,CAAC,CAAC,CAAC,CAE3E;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,GAAG,GAAG,EACzD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAAC,CAAC,CAAC,CAOb"}
|
package/dist/stores.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { readable } from "svelte/store";
|
|
2
|
+
import { getReplaneContext } from "./context";
|
|
3
|
+
/**
|
|
4
|
+
* Get the Replane context containing the client.
|
|
5
|
+
*
|
|
6
|
+
* Must be called during component initialization (in the script section, not in event handlers).
|
|
7
|
+
*
|
|
8
|
+
* @returns The Replane context with the client
|
|
9
|
+
* @throws Error if called outside a ReplaneProvider
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```svelte
|
|
13
|
+
* <script>
|
|
14
|
+
* import { useReplane } from '@replanejs/svelte';
|
|
15
|
+
*
|
|
16
|
+
* const { client } = useReplane();
|
|
17
|
+
* // Use client directly: client.get('configName')
|
|
18
|
+
* </script>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
export function useReplane() {
|
|
23
|
+
return getReplaneContext();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a reactive store for a specific config value.
|
|
27
|
+
*
|
|
28
|
+
* Must be called during component initialization (in the script section, not in event handlers).
|
|
29
|
+
* The returned store will automatically update when the config value changes on the server.
|
|
30
|
+
*
|
|
31
|
+
* @param name - The name of the config to subscribe to
|
|
32
|
+
* @param options - Optional context for override evaluation
|
|
33
|
+
* @returns A Svelte readable store containing the config value
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```svelte
|
|
37
|
+
* <script>
|
|
38
|
+
* import { useConfig } from '@replanejs/svelte';
|
|
39
|
+
*
|
|
40
|
+
* const featureEnabled = useConfig<boolean>('featureEnabled');
|
|
41
|
+
* const greeting = useConfig<string>('greeting', {
|
|
42
|
+
* context: { userId: '123' }
|
|
43
|
+
* });
|
|
44
|
+
* </script>
|
|
45
|
+
*
|
|
46
|
+
* {#if $featureEnabled}
|
|
47
|
+
* <p>{$greeting}</p>
|
|
48
|
+
* {/if}
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function useConfig(name, options) {
|
|
52
|
+
const { client } = getReplaneContext();
|
|
53
|
+
return readable(client.get(name, options), (set) => {
|
|
54
|
+
// Subscribe to config changes
|
|
55
|
+
const unsubscribe = client.subscribe(name, () => {
|
|
56
|
+
set(client.get(name, options));
|
|
57
|
+
});
|
|
58
|
+
// Return cleanup function
|
|
59
|
+
return unsubscribe;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create a reactive store for a config value using a pre-existing client.
|
|
64
|
+
*
|
|
65
|
+
* This is useful when you have direct access to a client and don't want to
|
|
66
|
+
* use the context-based approach.
|
|
67
|
+
*
|
|
68
|
+
* @param client - The Replane client to use
|
|
69
|
+
* @param name - The name of the config to subscribe to
|
|
70
|
+
* @param options - Optional context for override evaluation
|
|
71
|
+
* @returns A Svelte readable store containing the config value
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```svelte
|
|
75
|
+
* <script>
|
|
76
|
+
* import { createConfigStore } from '@replanejs/svelte';
|
|
77
|
+
* import { client } from './replane-client';
|
|
78
|
+
*
|
|
79
|
+
* const featureEnabled = createConfigStore<boolean>(client, 'featureEnabled');
|
|
80
|
+
* </script>
|
|
81
|
+
*
|
|
82
|
+
* {#if $featureEnabled}
|
|
83
|
+
* <p>Feature is enabled!</p>
|
|
84
|
+
* {/if}
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
+
export function createConfigStore(client, name, options) {
|
|
89
|
+
return readable(client.get(name, options), (set) => {
|
|
90
|
+
const unsubscribe = client.subscribe(name, () => {
|
|
91
|
+
set(client.get(name, options));
|
|
92
|
+
});
|
|
93
|
+
return unsubscribe;
|
|
94
|
+
});
|
|
95
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ReplaneClient, ReplaneClientOptions, ReplaneSnapshot } from "@replanejs/sdk";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
/**
|
|
4
|
+
* Context value containing the Replane client
|
|
5
|
+
*/
|
|
6
|
+
export interface ReplaneContextValue<T extends object = any> {
|
|
7
|
+
client: ReplaneClient<T>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Props for ReplaneProvider when using a pre-created client.
|
|
11
|
+
*/
|
|
12
|
+
export interface ReplaneProviderWithClientProps<T extends object = any> {
|
|
13
|
+
/** Pre-created ReplaneClient instance */
|
|
14
|
+
client: ReplaneClient<T>;
|
|
15
|
+
/** Children snippet */
|
|
16
|
+
children: Snippet;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Props for ReplaneProvider when letting it manage the client internally.
|
|
20
|
+
*/
|
|
21
|
+
export interface ReplaneProviderWithOptionsProps<T extends object = any> {
|
|
22
|
+
/** Options to create the ReplaneClient */
|
|
23
|
+
options: ReplaneClientOptions<T>;
|
|
24
|
+
/** Children snippet */
|
|
25
|
+
children: Snippet;
|
|
26
|
+
/**
|
|
27
|
+
* Optional loading snippet to show while the client is initializing.
|
|
28
|
+
* If not provided, children will not render until ready.
|
|
29
|
+
*/
|
|
30
|
+
loader?: Snippet;
|
|
31
|
+
/**
|
|
32
|
+
* Callback when client initialization fails.
|
|
33
|
+
*/
|
|
34
|
+
onError?: (error: Error) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Props for ReplaneProvider when restoring from a snapshot (SSR/hydration).
|
|
38
|
+
*/
|
|
39
|
+
export interface ReplaneProviderWithSnapshotProps<T extends object = 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 object = any> = ReplaneProviderWithClientProps<T> | ReplaneProviderWithOptionsProps<T> | ReplaneProviderWithSnapshotProps<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Type guard to check if props contain a pre-created client.
|
|
57
|
+
*/
|
|
58
|
+
export declare function hasClient<T extends object>(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 object>(props: ReplaneProviderProps<T>): props is ReplaneProviderWithOptionsProps<T>;
|
|
63
|
+
/**
|
|
64
|
+
* Type guard to check if props contain a snapshot.
|
|
65
|
+
*/
|
|
66
|
+
export declare function hasSnapshot<T extends object>(props: ReplaneProviderProps<T>): props is ReplaneProviderWithSnapshotProps<T>;
|
|
67
|
+
/**
|
|
68
|
+
* Options for useConfig
|
|
69
|
+
*/
|
|
70
|
+
export interface UseConfigOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Context for override evaluation (merged with client-level context).
|
|
73
|
+
*/
|
|
74
|
+
context?: Record<string, string | number | boolean | null>;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +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,GAAG,GAAG;IACzD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;CAC1B;AAED;;GAEG;AAEH,MAAM,WAAW,8BAA8B,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG;IACpE,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,GAAG,GAAG;IACrE,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,GAAG,GAAG;IACtE,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,GAAG,GAAG,IACnD,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,EACxC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC7B,KAAK,IAAI,8BAA8B,CAAC,CAAC,CAAC,CAE5C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC7B,KAAK,IAAI,+BAA+B,CAAC,CAAC,CAAC,CAE7C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC1C,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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guard to check if props contain a pre-created client.
|
|
3
|
+
*/
|
|
4
|
+
export function hasClient(props) {
|
|
5
|
+
return "client" in props && props.client !== undefined;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Type guard to check if props contain options.
|
|
9
|
+
*/
|
|
10
|
+
export function hasOptions(props) {
|
|
11
|
+
return "options" in props && props.options !== undefined;
|
|
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
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@replanejs/svelte",
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "Svelte SDK for Replane - feature flags and remote configuration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"svelte": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"svelte": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"keywords": [
|
|
20
|
+
"replane",
|
|
21
|
+
"svelte",
|
|
22
|
+
"feature-flags",
|
|
23
|
+
"remote-config",
|
|
24
|
+
"configuration",
|
|
25
|
+
"sdk"
|
|
26
|
+
],
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/replane-dev/replane-javascript",
|
|
32
|
+
"directory": "packages/svelte"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/replane-dev/replane-javascript/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/replane-dev/replane-javascript#readme",
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"svelte": ">=4.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@replanejs/sdk": "0.7.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@sveltejs/package": "^2.3.10",
|
|
46
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
47
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
48
|
+
"@testing-library/svelte": "^5.2.6",
|
|
49
|
+
"@types/node": "^22.19.3",
|
|
50
|
+
"bumpp": "^10.1.0",
|
|
51
|
+
"jsdom": "^27.3.0",
|
|
52
|
+
"svelte": "^5.0.0",
|
|
53
|
+
"svelte-check": "^4.1.4",
|
|
54
|
+
"typescript": "^5.4.0",
|
|
55
|
+
"vite": "^6.0.0",
|
|
56
|
+
"vitest": "^3.2.4"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "svelte-package -i src -o dist",
|
|
66
|
+
"dev": "svelte-package -i src -o dist --watch",
|
|
67
|
+
"typecheck": "svelte-check --tsconfig ./tsconfig.json",
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"test:watch": "vitest",
|
|
70
|
+
"release": "pnpm run build && bumpp && npm publish"
|
|
71
|
+
}
|
|
72
|
+
}
|