@smplkit/sdk 1.2.2 → 1.2.4

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/dist/index.d.cts CHANGED
@@ -46,11 +46,12 @@ declare class SharedWebSocket {
46
46
  }
47
47
 
48
48
  /**
49
- * Config resource — management-plane model with runtime connect support.
49
+ * Config resource — management-plane model.
50
50
  *
51
51
  * Instances are returned by {@link ConfigClient} methods and provide
52
- * management-plane operations (`update`, `setValues`, `setValue`) as well
53
- * as the {@link connect} entry point for runtime value resolution.
52
+ * management-plane operations (`update`, `setValues`, `setValue`).
53
+ * Prescriptive value access is via `client.config.getValue()` after
54
+ * `client.connect()`.
54
55
  */
55
56
  /**
56
57
  * Internal type used by {@link ConfigClient}. Not part of the public API.
@@ -69,8 +70,7 @@ interface ConfigUpdatePayload {
69
70
  * A configuration resource fetched from the smplkit Config service.
70
71
  *
71
72
  * Instances are returned by {@link ConfigClient} methods and provide
72
- * management-plane operations as well as the {@link connect} entry point
73
- * for runtime value resolution.
73
+ * management-plane operations (update, setValues, setValue).
74
74
  */
75
75
  declare class Config {
76
76
  /** UUID of the config. */
@@ -190,6 +190,19 @@ interface GetConfigOptions {
190
190
  id?: string;
191
191
  }
192
192
 
193
+ /** Describes a single config value change detected on refresh. */
194
+ interface ConfigChangeEvent {
195
+ /** The config key that changed. */
196
+ configKey: string;
197
+ /** The item key within the config that changed. */
198
+ itemKey: string;
199
+ /** The previous value (null if the key was absent). */
200
+ oldValue: unknown;
201
+ /** The updated value (null if the key was removed). */
202
+ newValue: unknown;
203
+ /** How the change was delivered. */
204
+ source: "websocket" | "manual";
205
+ }
193
206
  /**
194
207
  * Client for the smplkit Config API (management plane).
195
208
  *
@@ -214,6 +227,7 @@ declare class ConfigClient {
214
227
  } | null;
215
228
  private _configCache;
216
229
  private _connected;
230
+ private _listeners;
217
231
  /** @internal */
218
232
  constructor(apiKey: string, timeout?: number);
219
233
  /**
@@ -258,6 +272,45 @@ declare class ConfigClient {
258
272
  * @throws {SmplNotConnectedError} If connect() has not been called.
259
273
  */
260
274
  getValue(configKey: string, itemKey?: string, defaultValue?: unknown): unknown;
275
+ /**
276
+ * Return a config value as a string, or `defaultValue` if absent or not a string.
277
+ *
278
+ * @throws {SmplNotConnectedError} If connect() has not been called.
279
+ */
280
+ getString(configKey: string, itemKey: string, defaultValue?: string | null): string | null;
281
+ /**
282
+ * Return a config value as a number, or `defaultValue` if absent or not a number.
283
+ *
284
+ * @throws {SmplNotConnectedError} If connect() has not been called.
285
+ */
286
+ getInt(configKey: string, itemKey: string, defaultValue?: number | null): number | null;
287
+ /**
288
+ * Return a config value as a boolean, or `defaultValue` if absent or not a boolean.
289
+ *
290
+ * @throws {SmplNotConnectedError} If connect() has not been called.
291
+ */
292
+ getBool(configKey: string, itemKey: string, defaultValue?: boolean | null): boolean | null;
293
+ /**
294
+ * Re-fetch all configs, re-resolve values, and update the cache.
295
+ *
296
+ * Fires change listeners for any values that differ from the previous cache.
297
+ *
298
+ * @throws {SmplNotConnectedError} If connect() has not been called.
299
+ */
300
+ refresh(): Promise<void>;
301
+ /**
302
+ * Register a listener that fires when a config value changes (on refresh).
303
+ *
304
+ * @param callback - Called with a {@link ConfigChangeEvent} on each change.
305
+ * @param options.configKey - If provided, only fire for changes to this config.
306
+ * @param options.itemKey - If provided, only fire for changes to this item key.
307
+ */
308
+ onChange(callback: (event: ConfigChangeEvent) => void, options?: {
309
+ configKey?: string;
310
+ itemKey?: string;
311
+ }): void;
312
+ /** @internal */
313
+ private _diffAndFire;
261
314
  /**
262
315
  * Internal: PUT a full config update and return the updated model.
263
316
  *
@@ -725,175 +778,6 @@ declare class SmplClient {
725
778
  close(): void;
726
779
  }
727
780
 
728
- /**
729
- * Deep-merge resolution algorithm for config inheritance chains.
730
- *
731
- * Mirrors the Python SDK's `_resolver.py` (ADR-024 §2.5–2.6).
732
- */
733
- /** A single entry in a config inheritance chain (child-to-root ordering). */
734
- interface ChainConfig {
735
- /** Config UUID. */
736
- id: string;
737
- /** Base key-value pairs (unwrapped from typed item definitions). */
738
- items: Record<string, unknown>;
739
- /**
740
- * Per-environment overrides.
741
- * Each entry is `{ values: { key: value, ... } }` — values are already
742
- * unwrapped from the server's `{ value: raw }` wrapper by the client layer.
743
- */
744
- environments: Record<string, unknown>;
745
- }
746
-
747
- /**
748
- * Types for the config runtime plane.
749
- */
750
- /** Describes a single value change pushed by the server or detected on refresh. */
751
- interface ConfigChangeEvent {
752
- /** The config key that changed. */
753
- key: string;
754
- /** The previous value (null if the key was absent). */
755
- oldValue: unknown;
756
- /** The updated value (null if the key was removed). */
757
- newValue: unknown;
758
- /** How the change was delivered. */
759
- source: "websocket" | "poll" | "manual";
760
- }
761
- /** Diagnostic statistics for a {@link ConfigRuntime} instance. */
762
- interface ConfigStats {
763
- /**
764
- * Total number of HTTP fetches performed, including the initial connect
765
- * and any reconnection re-syncs or manual refreshes. Incremented by the
766
- * chain length (number of configs fetched) on each fetch.
767
- */
768
- fetchCount: number;
769
- /** ISO-8601 timestamp of the most recent fetch, or null if none yet. */
770
- lastFetchAt: string | null;
771
- }
772
- /** WebSocket connection status. */
773
- type ConnectionStatus = "connected" | "connecting" | "disconnected";
774
- /** Options for {@link Config.connect}. */
775
- interface ConnectOptions {
776
- /**
777
- * Maximum milliseconds to wait for the initial fetch.
778
- * @default 30000
779
- */
780
- timeout?: number;
781
- }
782
-
783
- /**
784
- * ConfigRuntime — runtime-plane value resolution with WebSocket updates.
785
- *
786
- * Holds a fully resolved local cache of config values for a specific
787
- * environment. All value-access methods are synchronous (local reads);
788
- * only {@link refresh} and {@link close} are async.
789
- *
790
- * A background WebSocket connection is maintained for real-time updates.
791
- * If the WebSocket fails, the runtime operates in cache-only mode and
792
- * reconnects automatically with exponential backoff.
793
- */
794
-
795
- /** @internal Options for constructing a ConfigRuntime. */
796
- interface ConfigRuntimeOptions {
797
- configKey: string;
798
- configId: string;
799
- environment: string;
800
- chain: ChainConfig[];
801
- apiKey: string;
802
- baseUrl: string;
803
- fetchChain: (() => Promise<ChainConfig[]>) | null;
804
- sharedWs?: SharedWebSocket | null;
805
- }
806
- /**
807
- * Runtime configuration handle for a specific environment.
808
- *
809
- * Obtained by calling {@link Config.connect}. All value-access methods
810
- * are synchronous and served entirely from a local in-process cache.
811
- * The cache is populated eagerly on construction and kept current via
812
- * a background WebSocket connection.
813
- */
814
- declare class ConfigRuntime {
815
- private _cache;
816
- private _chain;
817
- private _fetchCount;
818
- private _lastFetchAt;
819
- private _closed;
820
- private _listeners;
821
- private readonly _environment;
822
- private readonly _fetchChain;
823
- private _sharedWs;
824
- /** @internal */
825
- constructor(options: ConfigRuntimeOptions);
826
- /**
827
- * Return the resolved value for `key`, or `defaultValue` if absent.
828
- *
829
- * @param key - The config key to look up.
830
- * @param defaultValue - Returned when the key is not present (default: null).
831
- */
832
- get(key: string, defaultValue?: unknown): unknown;
833
- /**
834
- * Return the value as a string, or `defaultValue` if absent or not a string.
835
- */
836
- getString(key: string, defaultValue?: string | null): string | null;
837
- /**
838
- * Return the value as a number, or `defaultValue` if absent or not a number.
839
- */
840
- getInt(key: string, defaultValue?: number | null): number | null;
841
- /**
842
- * Return the value as a boolean, or `defaultValue` if absent or not a boolean.
843
- */
844
- getBool(key: string, defaultValue?: boolean | null): boolean | null;
845
- /**
846
- * Return whether `key` is present in the resolved configuration.
847
- */
848
- exists(key: string): boolean;
849
- /**
850
- * Return a shallow copy of the full resolved configuration.
851
- */
852
- getAll(): Record<string, unknown>;
853
- /**
854
- * Register a listener that fires when a config value changes.
855
- *
856
- * @param callback - Called with a {@link ConfigChangeEvent} on each change.
857
- * @param options.key - If provided, the listener fires only for this key.
858
- * If omitted, the listener fires for all changes.
859
- */
860
- onChange(callback: (event: ConfigChangeEvent) => void, options?: {
861
- key?: string;
862
- }): void;
863
- /**
864
- * Return diagnostic statistics for this runtime.
865
- */
866
- stats(): ConfigStats;
867
- /**
868
- * Return the current WebSocket connection status.
869
- */
870
- connectionStatus(): ConnectionStatus;
871
- /**
872
- * Force a manual refresh of the cached configuration.
873
- *
874
- * Re-fetches the full config chain via HTTP, re-resolves values, updates
875
- * the local cache, and fires listeners for any detected changes.
876
- *
877
- * @throws {Error} If no `fetchChain` function was provided on construction.
878
- */
879
- refresh(): Promise<void>;
880
- /**
881
- * Close the runtime connection.
882
- *
883
- * Unregisters from the shared WebSocket. Safe to call multiple times.
884
- */
885
- close(): Promise<void>;
886
- /**
887
- * Async dispose support for `await using` (TypeScript 5.2+).
888
- */
889
- [Symbol.asyncDispose](): Promise<void>;
890
- private _handleConfigChanged;
891
- private _handleConfigDeleted;
892
- private _applyChanges;
893
- private _diffAndFire;
894
- private _fireListeners;
895
- }
896
-
897
781
  /**
898
782
  * Structured SDK error types.
899
783
  *
@@ -934,4 +818,4 @@ declare class SmplValidationError extends SmplError {
934
818
  constructor(message: string, statusCode?: number, responseBody?: string);
935
819
  }
936
820
 
937
- export { BoolFlagHandle, Config, type ConfigChangeEvent, ConfigClient, ConfigRuntime, type ConfigStats, type ConnectOptions, type ConnectionStatus, Context, ContextType, type CreateConfigOptions, Flag, FlagChangeEvent, FlagStats, type FlagType, FlagsClient, type GetConfigOptions, JsonFlagHandle, NumberFlagHandle, Rule, SharedWebSocket, SmplClient, type SmplClientOptions, SmplConflictError, SmplConnectionError, SmplError, SmplNotConnectedError, SmplNotFoundError, SmplTimeoutError, SmplValidationError, StringFlagHandle };
821
+ export { BoolFlagHandle, Config, type ConfigChangeEvent, ConfigClient, Context, ContextType, type CreateConfigOptions, Flag, FlagChangeEvent, FlagStats, type FlagType, FlagsClient, type GetConfigOptions, JsonFlagHandle, NumberFlagHandle, Rule, SharedWebSocket, SmplClient, type SmplClientOptions, SmplConflictError, SmplConnectionError, SmplError, SmplNotConnectedError, SmplNotFoundError, SmplTimeoutError, SmplValidationError, StringFlagHandle };
package/dist/index.d.ts CHANGED
@@ -46,11 +46,12 @@ declare class SharedWebSocket {
46
46
  }
47
47
 
48
48
  /**
49
- * Config resource — management-plane model with runtime connect support.
49
+ * Config resource — management-plane model.
50
50
  *
51
51
  * Instances are returned by {@link ConfigClient} methods and provide
52
- * management-plane operations (`update`, `setValues`, `setValue`) as well
53
- * as the {@link connect} entry point for runtime value resolution.
52
+ * management-plane operations (`update`, `setValues`, `setValue`).
53
+ * Prescriptive value access is via `client.config.getValue()` after
54
+ * `client.connect()`.
54
55
  */
55
56
  /**
56
57
  * Internal type used by {@link ConfigClient}. Not part of the public API.
@@ -69,8 +70,7 @@ interface ConfigUpdatePayload {
69
70
  * A configuration resource fetched from the smplkit Config service.
70
71
  *
71
72
  * Instances are returned by {@link ConfigClient} methods and provide
72
- * management-plane operations as well as the {@link connect} entry point
73
- * for runtime value resolution.
73
+ * management-plane operations (update, setValues, setValue).
74
74
  */
75
75
  declare class Config {
76
76
  /** UUID of the config. */
@@ -190,6 +190,19 @@ interface GetConfigOptions {
190
190
  id?: string;
191
191
  }
192
192
 
193
+ /** Describes a single config value change detected on refresh. */
194
+ interface ConfigChangeEvent {
195
+ /** The config key that changed. */
196
+ configKey: string;
197
+ /** The item key within the config that changed. */
198
+ itemKey: string;
199
+ /** The previous value (null if the key was absent). */
200
+ oldValue: unknown;
201
+ /** The updated value (null if the key was removed). */
202
+ newValue: unknown;
203
+ /** How the change was delivered. */
204
+ source: "websocket" | "manual";
205
+ }
193
206
  /**
194
207
  * Client for the smplkit Config API (management plane).
195
208
  *
@@ -214,6 +227,7 @@ declare class ConfigClient {
214
227
  } | null;
215
228
  private _configCache;
216
229
  private _connected;
230
+ private _listeners;
217
231
  /** @internal */
218
232
  constructor(apiKey: string, timeout?: number);
219
233
  /**
@@ -258,6 +272,45 @@ declare class ConfigClient {
258
272
  * @throws {SmplNotConnectedError} If connect() has not been called.
259
273
  */
260
274
  getValue(configKey: string, itemKey?: string, defaultValue?: unknown): unknown;
275
+ /**
276
+ * Return a config value as a string, or `defaultValue` if absent or not a string.
277
+ *
278
+ * @throws {SmplNotConnectedError} If connect() has not been called.
279
+ */
280
+ getString(configKey: string, itemKey: string, defaultValue?: string | null): string | null;
281
+ /**
282
+ * Return a config value as a number, or `defaultValue` if absent or not a number.
283
+ *
284
+ * @throws {SmplNotConnectedError} If connect() has not been called.
285
+ */
286
+ getInt(configKey: string, itemKey: string, defaultValue?: number | null): number | null;
287
+ /**
288
+ * Return a config value as a boolean, or `defaultValue` if absent or not a boolean.
289
+ *
290
+ * @throws {SmplNotConnectedError} If connect() has not been called.
291
+ */
292
+ getBool(configKey: string, itemKey: string, defaultValue?: boolean | null): boolean | null;
293
+ /**
294
+ * Re-fetch all configs, re-resolve values, and update the cache.
295
+ *
296
+ * Fires change listeners for any values that differ from the previous cache.
297
+ *
298
+ * @throws {SmplNotConnectedError} If connect() has not been called.
299
+ */
300
+ refresh(): Promise<void>;
301
+ /**
302
+ * Register a listener that fires when a config value changes (on refresh).
303
+ *
304
+ * @param callback - Called with a {@link ConfigChangeEvent} on each change.
305
+ * @param options.configKey - If provided, only fire for changes to this config.
306
+ * @param options.itemKey - If provided, only fire for changes to this item key.
307
+ */
308
+ onChange(callback: (event: ConfigChangeEvent) => void, options?: {
309
+ configKey?: string;
310
+ itemKey?: string;
311
+ }): void;
312
+ /** @internal */
313
+ private _diffAndFire;
261
314
  /**
262
315
  * Internal: PUT a full config update and return the updated model.
263
316
  *
@@ -725,175 +778,6 @@ declare class SmplClient {
725
778
  close(): void;
726
779
  }
727
780
 
728
- /**
729
- * Deep-merge resolution algorithm for config inheritance chains.
730
- *
731
- * Mirrors the Python SDK's `_resolver.py` (ADR-024 §2.5–2.6).
732
- */
733
- /** A single entry in a config inheritance chain (child-to-root ordering). */
734
- interface ChainConfig {
735
- /** Config UUID. */
736
- id: string;
737
- /** Base key-value pairs (unwrapped from typed item definitions). */
738
- items: Record<string, unknown>;
739
- /**
740
- * Per-environment overrides.
741
- * Each entry is `{ values: { key: value, ... } }` — values are already
742
- * unwrapped from the server's `{ value: raw }` wrapper by the client layer.
743
- */
744
- environments: Record<string, unknown>;
745
- }
746
-
747
- /**
748
- * Types for the config runtime plane.
749
- */
750
- /** Describes a single value change pushed by the server or detected on refresh. */
751
- interface ConfigChangeEvent {
752
- /** The config key that changed. */
753
- key: string;
754
- /** The previous value (null if the key was absent). */
755
- oldValue: unknown;
756
- /** The updated value (null if the key was removed). */
757
- newValue: unknown;
758
- /** How the change was delivered. */
759
- source: "websocket" | "poll" | "manual";
760
- }
761
- /** Diagnostic statistics for a {@link ConfigRuntime} instance. */
762
- interface ConfigStats {
763
- /**
764
- * Total number of HTTP fetches performed, including the initial connect
765
- * and any reconnection re-syncs or manual refreshes. Incremented by the
766
- * chain length (number of configs fetched) on each fetch.
767
- */
768
- fetchCount: number;
769
- /** ISO-8601 timestamp of the most recent fetch, or null if none yet. */
770
- lastFetchAt: string | null;
771
- }
772
- /** WebSocket connection status. */
773
- type ConnectionStatus = "connected" | "connecting" | "disconnected";
774
- /** Options for {@link Config.connect}. */
775
- interface ConnectOptions {
776
- /**
777
- * Maximum milliseconds to wait for the initial fetch.
778
- * @default 30000
779
- */
780
- timeout?: number;
781
- }
782
-
783
- /**
784
- * ConfigRuntime — runtime-plane value resolution with WebSocket updates.
785
- *
786
- * Holds a fully resolved local cache of config values for a specific
787
- * environment. All value-access methods are synchronous (local reads);
788
- * only {@link refresh} and {@link close} are async.
789
- *
790
- * A background WebSocket connection is maintained for real-time updates.
791
- * If the WebSocket fails, the runtime operates in cache-only mode and
792
- * reconnects automatically with exponential backoff.
793
- */
794
-
795
- /** @internal Options for constructing a ConfigRuntime. */
796
- interface ConfigRuntimeOptions {
797
- configKey: string;
798
- configId: string;
799
- environment: string;
800
- chain: ChainConfig[];
801
- apiKey: string;
802
- baseUrl: string;
803
- fetchChain: (() => Promise<ChainConfig[]>) | null;
804
- sharedWs?: SharedWebSocket | null;
805
- }
806
- /**
807
- * Runtime configuration handle for a specific environment.
808
- *
809
- * Obtained by calling {@link Config.connect}. All value-access methods
810
- * are synchronous and served entirely from a local in-process cache.
811
- * The cache is populated eagerly on construction and kept current via
812
- * a background WebSocket connection.
813
- */
814
- declare class ConfigRuntime {
815
- private _cache;
816
- private _chain;
817
- private _fetchCount;
818
- private _lastFetchAt;
819
- private _closed;
820
- private _listeners;
821
- private readonly _environment;
822
- private readonly _fetchChain;
823
- private _sharedWs;
824
- /** @internal */
825
- constructor(options: ConfigRuntimeOptions);
826
- /**
827
- * Return the resolved value for `key`, or `defaultValue` if absent.
828
- *
829
- * @param key - The config key to look up.
830
- * @param defaultValue - Returned when the key is not present (default: null).
831
- */
832
- get(key: string, defaultValue?: unknown): unknown;
833
- /**
834
- * Return the value as a string, or `defaultValue` if absent or not a string.
835
- */
836
- getString(key: string, defaultValue?: string | null): string | null;
837
- /**
838
- * Return the value as a number, or `defaultValue` if absent or not a number.
839
- */
840
- getInt(key: string, defaultValue?: number | null): number | null;
841
- /**
842
- * Return the value as a boolean, or `defaultValue` if absent or not a boolean.
843
- */
844
- getBool(key: string, defaultValue?: boolean | null): boolean | null;
845
- /**
846
- * Return whether `key` is present in the resolved configuration.
847
- */
848
- exists(key: string): boolean;
849
- /**
850
- * Return a shallow copy of the full resolved configuration.
851
- */
852
- getAll(): Record<string, unknown>;
853
- /**
854
- * Register a listener that fires when a config value changes.
855
- *
856
- * @param callback - Called with a {@link ConfigChangeEvent} on each change.
857
- * @param options.key - If provided, the listener fires only for this key.
858
- * If omitted, the listener fires for all changes.
859
- */
860
- onChange(callback: (event: ConfigChangeEvent) => void, options?: {
861
- key?: string;
862
- }): void;
863
- /**
864
- * Return diagnostic statistics for this runtime.
865
- */
866
- stats(): ConfigStats;
867
- /**
868
- * Return the current WebSocket connection status.
869
- */
870
- connectionStatus(): ConnectionStatus;
871
- /**
872
- * Force a manual refresh of the cached configuration.
873
- *
874
- * Re-fetches the full config chain via HTTP, re-resolves values, updates
875
- * the local cache, and fires listeners for any detected changes.
876
- *
877
- * @throws {Error} If no `fetchChain` function was provided on construction.
878
- */
879
- refresh(): Promise<void>;
880
- /**
881
- * Close the runtime connection.
882
- *
883
- * Unregisters from the shared WebSocket. Safe to call multiple times.
884
- */
885
- close(): Promise<void>;
886
- /**
887
- * Async dispose support for `await using` (TypeScript 5.2+).
888
- */
889
- [Symbol.asyncDispose](): Promise<void>;
890
- private _handleConfigChanged;
891
- private _handleConfigDeleted;
892
- private _applyChanges;
893
- private _diffAndFire;
894
- private _fireListeners;
895
- }
896
-
897
781
  /**
898
782
  * Structured SDK error types.
899
783
  *
@@ -934,4 +818,4 @@ declare class SmplValidationError extends SmplError {
934
818
  constructor(message: string, statusCode?: number, responseBody?: string);
935
819
  }
936
820
 
937
- export { BoolFlagHandle, Config, type ConfigChangeEvent, ConfigClient, ConfigRuntime, type ConfigStats, type ConnectOptions, type ConnectionStatus, Context, ContextType, type CreateConfigOptions, Flag, FlagChangeEvent, FlagStats, type FlagType, FlagsClient, type GetConfigOptions, JsonFlagHandle, NumberFlagHandle, Rule, SharedWebSocket, SmplClient, type SmplClientOptions, SmplConflictError, SmplConnectionError, SmplError, SmplNotConnectedError, SmplNotFoundError, SmplTimeoutError, SmplValidationError, StringFlagHandle };
821
+ export { BoolFlagHandle, Config, type ConfigChangeEvent, ConfigClient, Context, ContextType, type CreateConfigOptions, Flag, FlagChangeEvent, FlagStats, type FlagType, FlagsClient, type GetConfigOptions, JsonFlagHandle, NumberFlagHandle, Rule, SharedWebSocket, SmplClient, type SmplClientOptions, SmplConflictError, SmplConnectionError, SmplError, SmplNotConnectedError, SmplNotFoundError, SmplTimeoutError, SmplValidationError, StringFlagHandle };