@qlover/fe-corekit 3.1.0 → 3.2.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/dist/index.d.ts CHANGED
@@ -6848,6 +6848,16 @@ type RequestAdapterContext = ExecutorContextInterface<RequestAdapterConfig, unkn
6848
6848
  * ```
6849
6849
  */
6850
6850
  type RequestPluginConfig = HeaderInjectorConfig & {
6851
+ /**
6852
+ * Allow empty URL
6853
+ *
6854
+ * If set to `false`, an error will be thrown when both `url` and `baseURL` are empty.
6855
+ * If set to `true` (default), the URL builder will attempt to build the URL even if they are empty.
6856
+ *
6857
+ * @since 3.1.0
6858
+ * @default `true`
6859
+ */
6860
+ allowEmptyUrl?: boolean;
6851
6861
  requestDataSerializer?: (data: unknown, config: RequestAdapterConfig & Omit<RequestPluginConfig, 'requestDataSerializer'>) => unknown;
6852
6862
  };
6853
6863
  interface RequestPluginInnerConfig {
@@ -6947,6 +6957,17 @@ declare class RequestPlugin implements LifecyclePluginInterface<RequestAdapterCo
6947
6957
  * @override
6948
6958
  */
6949
6959
  onBefore(ctx: RequestAdapterContext): void;
6960
+ protected startsWith(url: string, baseUrl: string): boolean;
6961
+ /**
6962
+ * Main request handler
6963
+ *
6964
+ * This is the core of the plugin. It merges default plugin configuration with request context configuration,
6965
+ * processes request data, builds the URL, and injects headers.
6966
+ *
6967
+ * @param config - Request configuration
6968
+ * @returns Merged configuration with processed data, built URL, and injected headers
6969
+ */
6970
+ mergeConfig(config: RequestAdapterConfig & RequestPluginConfig): RequestAdapterConfig & RequestPluginConfig;
6950
6971
  /**
6951
6972
  * Merge default plugin configuration with request context configuration
6952
6973
  *
@@ -6959,7 +6980,7 @@ declare class RequestPlugin implements LifecyclePluginInterface<RequestAdapterCo
6959
6980
  * @param contextConfig - Configuration from request context
6960
6981
  * @returns Merged configuration
6961
6982
  */
6962
- protected mergeConfig(contextConfig: RequestAdapterConfig): RequestAdapterConfig & RequestPluginConfig;
6983
+ protected createConfig(contextConfig: RequestAdapterConfig): RequestAdapterConfig & RequestPluginConfig;
6963
6984
  /**
6964
6985
  * Build the URL from the request configuration
6965
6986
  *
@@ -6967,7 +6988,7 @@ declare class RequestPlugin implements LifecyclePluginInterface<RequestAdapterCo
6967
6988
  * @returns The built URL
6968
6989
  * @throws {Error} If the built URL is empty or invalid
6969
6990
  */
6970
- protected buildUrl(config: RequestAdapterConfig): string;
6991
+ protected buildUrl(config: RequestAdapterConfig & RequestPluginConfig): string;
6971
6992
  /**
6972
6993
  * Inject default headers into request configuration
6973
6994
  *
@@ -7263,6 +7284,7 @@ declare class ResponsePlugin implements LifecyclePluginInterface<ResponsePluginC
7263
7284
  * ```
7264
7285
  */
7265
7286
  onSuccess(context: ResponsePluginContext): Promise<void>;
7287
+ handleResponse(returnValue: unknown, config: ResponsePluginConfig & RequestAdapterConfig<unknown>): Promise<RequestAdapterResponse> | undefined;
7266
7288
  /**
7267
7289
  * Validate response status
7268
7290
  *
@@ -8615,493 +8637,274 @@ declare class Base64Serializer implements SerializerIneterface<string, string> {
8615
8637
  }
8616
8638
 
8617
8639
  /**
8618
- * Interface representing an asynchronous storage mechanism.
8640
+ * Asynchronous key-value storage interface.
8641
+ *
8642
+ * Core concept:
8643
+ * Contract for a storage that performs I/O asynchronously. All methods return `Promise`s;
8644
+ * use this when the backend is async (e.g. IndexedDB, remote storage, encrypted async APIs).
8619
8645
  *
8620
- * @template Key - The type of keys used to identify stored values.
8621
- * @template ValueType - The type of values stored, defaults to unknown.
8646
+ * Main features:
8647
+ * - Key-value access: `setItem` / `getItem` / `removeItem` by key, all async
8648
+ * - Optional default on read: overload with `defaultValue` returns a fallback when key is missing
8649
+ * - Bulk clear: `clear()` removes all entries and resolves when done
8650
+ * - Optional parameters: generic `Opt` allows implementations to support expiry, scope, etc.
8622
8651
  *
8623
- * @example
8652
+ * When to use: Prefer this over sync `StorageInterface` when the underlying store is async
8653
+ * or when you want to avoid blocking the main thread.
8624
8654
  *
8655
+ * @template Key - Type of keys used to identify stored values.
8656
+ * @template ValueType - Type of values stored and retrieved.
8657
+ * @template Opt - Type of optional storage/retrieval options (e.g. expiry, scope).
8658
+ *
8659
+ * @example Basic usage
8625
8660
  * ```typescript
8626
- * const storage: AsyncStorage<string, number> = ...;
8661
+ * const storage: AsyncStorageInterface<string, number, void> = ...;
8627
8662
  * await storage.setItem('key', 123);
8628
8663
  * const value = await storage.getItem('key', 0);
8664
+ * await storage.removeItem('key');
8665
+ * await storage.clear();
8629
8666
  * ```
8630
8667
  *
8668
+ * @example Without default (returns null when missing)
8669
+ * ```typescript
8670
+ * const value = await storage.getItem('key');
8671
+ * if (value !== null) { ... }
8672
+ * ```
8631
8673
  */
8632
- interface AsyncStorageInterface<Key, ValueType = unknown> {
8674
+ interface AsyncStorageInterface<Key, ValueType, Opt> {
8633
8675
  /**
8634
- * The number of items stored.
8635
- */
8636
- readonly length: number;
8637
- /**
8638
- * Asynchronously stores a value with the specified key.
8676
+ * Stores a value under the given key asynchronously.
8677
+ *
8678
+ * Overwrites any existing value for `key`. Resolves when the write has completed;
8679
+ * rejections are implementation-defined (e.g. quota, I/O errors).
8639
8680
  *
8640
- * @param key - The key to identify the stored value.
8641
- * @param value - The value to store.
8642
- * @param options - Optional parameters for storage.
8643
- * @returns A promise that resolves when the value is stored.
8681
+ * @param key - Key to identify the stored value.
8682
+ * @param value - Value to store. Serialization is implementation-defined.
8683
+ * @param options - Optional parameters for this write (e.g. `maxAge`, `scope`). Type is `Opt`.
8684
+ * @returns Promise that resolves when the value is stored, or rejects on failure.
8644
8685
  */
8645
- setItem<T>(key: Key, value: T, options?: unknown): Promise<void>;
8686
+ setItem(key: Key, value: ValueType, options?: Opt): Promise<void>;
8646
8687
  /**
8647
- * Asynchronously retrieves a value by key.
8688
+ * Retrieves the value for the given key asynchronously.
8648
8689
  *
8649
- * @param key - The key of the value to retrieve.
8650
- * @param defaultValue - The default value to return if the key is not found.
8651
- * @param options - Optional parameters for retrieval.
8652
- * @returns A promise that resolves to the value associated with the key, or the default value if not found.
8690
+ * Use this overload when the caller handles missing keys explicitly (e.g. with `null` check).
8691
+ *
8692
+ * @param key - Key of the value to retrieve.
8693
+ * @param options - Optional parameters for retrieval. Type is `Opt`.
8694
+ * @returns Promise resolving to the stored value, or `null` if the key does not exist.
8653
8695
  */
8654
- getItem<T extends ValueType>(key: Key, defaultValue?: T, options?: unknown): Promise<T | null>;
8696
+ getItem(key: Key, options?: Opt): Promise<ValueType | null>;
8655
8697
  /**
8656
- * Asynchronously removes a value by key.
8698
+ * Retrieves the value for the given key, or the default when missing.
8699
+ *
8700
+ * Use this overload when a fallback is required; the promise resolves to `ValueType` (never `null`).
8657
8701
  *
8658
- * @param key - The key of the value to remove.
8659
- * @param options - Optional parameters for removal.
8660
- * @returns A promise that resolves when the value is removed.
8702
+ * @param key - Key of the value to retrieve.
8703
+ * @param defaultValue - Value to return when the key is not found.
8704
+ * @param options - Optional parameters for retrieval. Type is `Opt`.
8705
+ * @returns Promise resolving to the stored value if present, otherwise `defaultValue`.
8661
8706
  */
8662
- removeItem(key: Key, options?: unknown): Promise<void>;
8707
+ getItem(key: Key, defaultValue: ValueType, options?: Opt): Promise<ValueType>;
8663
8708
  /**
8664
- * Asynchronously clears all stored values.
8709
+ * Removes the entry for the given key asynchronously.
8710
+ *
8711
+ * No-op if the key does not exist. Resolves when the removal has completed.
8665
8712
  *
8666
- * @returns A promise that resolves when all values are cleared.
8713
+ * @param key - Key of the value to remove.
8714
+ * @param options - Optional parameters for removal. Type is `Opt`.
8715
+ * @returns Promise that resolves when the value is removed (or when no-op completes).
8667
8716
  */
8668
- clear(): Promise<void>;
8669
- }
8670
-
8671
- interface ExpireOptions {
8717
+ removeItem(key: Key, options?: Opt): Promise<void>;
8672
8718
  /**
8673
- * Expire time
8719
+ * Removes all entries in this storage asynchronously.
8674
8720
  *
8675
- * maybe is
8676
- * - number: milliseconds
8677
- * - string: time string, like '1d', '1h', '1m', '1s'
8678
- * - object: {}
8679
- * - ...
8721
+ * Scope of "all" is implementation-defined. Resolves when the clear has completed.
8680
8722
  *
8681
- * Subclass implementation
8723
+ * @returns Promise that resolves when all values are cleared.
8682
8724
  */
8683
- expires?: unknown;
8725
+ clear(): Promise<void>;
8684
8726
  }
8685
8727
 
8686
8728
  /**
8687
- * Key-value storage interface for managing a single value with persistence support
8729
+ * Synchronous key-value storage interface.
8688
8730
  *
8689
8731
  * Core concept:
8690
- * Provides a unified interface for storing and retrieving a single value associated
8691
- * with a specific key. Supports both in-memory and persistent storage backends,
8692
- * enabling flexible storage strategies for different use cases.
8693
- *
8694
- * **v2.3.0 before this was an abstract class, now it is an interface**
8732
+ * Contract for a sync storage that maps keys to values. All operations complete immediately;
8733
+ * suitable for in-memory stores, `localStorage`/`sessionStorage` adapters, or any backend
8734
+ * that does not require async I/O.
8695
8735
  *
8696
8736
  * Main features:
8697
- * - Single value storage: Store one value per key instance
8698
- * - Key management: Retrieve the storage key associated with this instance
8699
- * - Value retrieval: Get stored value from memory or persistent storage
8700
- * - Value persistence: Save value to underlying storage backend
8701
- * - Value removal: Clear value from both memory and persistent storage
8702
- * - Options support: Flexible options parameter for storage-specific configurations
8703
- *
8704
- * Typical usage scenarios:
8705
- * - Token storage: Store authentication tokens with persistence
8706
- * - User info storage: Persist user information across sessions
8707
- * - Configuration storage: Store application settings (theme, language, etc.)
8708
- * - Session data: Manage temporary session-specific data
8709
- *
8710
- * Design decisions:
8711
- * - Returns `null` when value is not found (explicit null handling)
8712
- * - Options parameter is optional to support simple use cases
8713
- * - Generic types allow type-safe storage of any value type
8714
- * - Supports both synchronous and asynchronous storage backends through options
8715
- *
8716
- * @template Key - The type of the storage key (e.g., `string`, `number`, `symbol`)
8717
- * @template Value - The type of value to store
8718
- * @template Opt - The type of options for storage operations (defaults to `unknown`)
8719
- *
8720
- * @example Basic usage with localStorage
8721
- * ```typescript
8722
- * const tokenStorage: KeyStorageInterface<string, string> = new KeyStorage('token', {
8723
- * storage: localStorage
8724
- * });
8725
- *
8726
- * // Store token
8727
- * tokenStorage.set('abc123token');
8737
+ * - Key-value access: `setItem` / `getItem` / `removeItem` by key
8738
+ * - Optional default on read: second `getItem` overload returns a default when key is missing
8739
+ * - Bulk clear: `clear()` removes all entries
8740
+ * - Optional parameters: generic `Opt` allows implementations to support expiry, scope, etc.
8728
8741
  *
8729
- * // Retrieve token
8730
- * const token = tokenStorage.get(); // Returns 'abc123token'
8742
+ * Design note: `getItem` returns `V | null` when no default is given, to align with the
8743
+ * browser {@link Storage} API (e.g. `localStorage.getItem` returns `string | null`).
8731
8744
  *
8732
- * // Get storage key
8733
- * const key = tokenStorage.getKey(); // Returns 'token'
8745
+ * @template K - Type of keys used to identify stored values.
8746
+ * @template V - Type of values stored and retrieved.
8747
+ * @template Opt - Type of optional storage/retrieval options (e.g. expiry, scope). Defaults to `unknown`.
8734
8748
  *
8735
- * // Remove token
8736
- * tokenStorage.remove();
8737
- * ```
8738
- *
8739
- * @example User information storage
8749
+ * @example Basic usage
8740
8750
  * ```typescript
8741
- * interface User {
8742
- * id: string;
8743
- * name: string;
8744
- * email: string;
8745
- * }
8746
- *
8747
- * const userStorage: KeyStorageInterface<string, User> = new KeyStorage('user', {
8748
- * storage: localStorage
8749
- * });
8750
- *
8751
- * const user: User = {
8752
- * id: '123',
8753
- * name: 'John Doe',
8754
- * email: 'john@example.com'
8755
- * };
8756
- *
8757
- * userStorage.set(user);
8758
- * const storedUser = userStorage.get(); // Returns User object
8751
+ * const storage: StorageInterface<string, number> = ...;
8752
+ * storage.setItem('count', 42);
8753
+ * const value = storage.getItem('count', 0) ?? 0;
8754
+ * storage.removeItem('count');
8755
+ * storage.clear();
8759
8756
  * ```
8760
8757
  *
8761
- * @example With custom options
8758
+ * @example With options (e.g. expiry)
8762
8759
  * ```typescript
8763
- * interface StorageOptions {
8764
- * encrypt?: boolean;
8765
- * expires?: number;
8766
- * }
8767
- *
8768
- * const secureStorage: KeyStorageInterface<string, string, StorageOptions> =
8769
- * new KeyStorage('secret', {
8770
- * storage: localStorage,
8771
- * encrypt: true
8772
- * });
8773
- *
8774
- * secureStorage.set('sensitive-data', { encrypt: true, expires: 3600 });
8760
+ * storage.setItem('token', 'abc', { maxAge: 3600 });
8761
+ * const token = storage.getItem('token', { scope: 'session' });
8775
8762
  * ```
8776
8763
  */
8777
- interface KeyStorageInterface<Key, Value, Opt = unknown> {
8764
+ interface StorageInterface<K, V, Opt = unknown> {
8778
8765
  /**
8779
- * Get the storage key associated with this instance
8766
+ * Stores a value under the given key.
8780
8767
  *
8781
- * Returns the key that was used to initialize this storage instance.
8782
- * This key is used to identify the storage location in the underlying
8783
- * storage backend.
8768
+ * Overwrites any existing value for `key`. Implementations may use `options` for
8769
+ * behaviour such as TTL or storage scope.
8784
8770
  *
8785
- * @returns The storage key of type `Key`
8786
- *
8787
- * @example
8788
- * ```typescript
8789
- * const storage = new KeyStorage('my-key', { storage: localStorage });
8790
- * const key = storage.getKey(); // Returns 'my-key'
8791
- * ```
8771
+ * @param key - Key to identify the stored value. Must be valid for the underlying store.
8772
+ * @param value - Value to store. Serialization is implementation-defined (e.g. JSON, string-only).
8773
+ * @param options - Optional parameters for this write (e.g. `maxAge`, `scope`). Type is `Opt`.
8792
8774
  */
8793
- getKey(): Key;
8775
+ setItem(key: K, value: V, options?: Opt): void;
8794
8776
  /**
8795
- * Get the current in-memory value without accessing persistent storage
8796
- *
8797
- * Returns the value currently stored in memory. This method does not
8798
- * attempt to load from persistent storage. Use `get()` if you want
8799
- * to retrieve from persistent storage when memory value is null.
8800
- *
8801
- * Returns `null` if:
8802
- * - No value has been set yet
8803
- * - Value was removed via `remove()`
8804
- * - Value was never loaded from storage
8805
- *
8806
- * @returns The current in-memory value, or `null` if not available
8807
- *
8808
- * @example
8809
- * ```typescript
8810
- * const storage = new KeyStorage('token', { storage: localStorage });
8811
- *
8812
- * // Initially null (not loaded from storage yet)
8813
- * const memValue = storage.getValue(); // Returns null
8777
+ * Retrieves the value for the given key.
8814
8778
  *
8815
- * // After setting
8816
- * storage.set('abc123');
8817
- * const memValue2 = storage.getValue(); // Returns 'abc123'
8779
+ * Returns `null` when the key is not found, so the signature stays compatible with the
8780
+ * browser {@link Storage} API.
8818
8781
  *
8819
- * // After removal
8820
- * storage.remove();
8821
- * const memValue3 = storage.getValue(); // Returns null
8822
- * ```
8782
+ * @param key - Key of the value to retrieve.
8783
+ * @param options - Optional parameters for retrieval (e.g. scope). Type is `Opt`.
8784
+ * @returns The stored value, or `null` if the key does not exist.
8823
8785
  */
8824
- getValue(): Value | null;
8786
+ getItem(key: K, options?: Opt): V | null;
8825
8787
  /**
8826
- * Retrieve value from storage with optional configuration
8827
- *
8828
- * Retrieval strategy:
8829
- * 1. First checks in-memory value (fast path)
8830
- * 2. If memory value is null and persistent storage is available,
8831
- * loads from persistent storage and updates memory cache
8832
- * 3. Returns null if value doesn't exist in either location
8788
+ * Retrieves the value for the given key, or the default when missing.
8833
8789
  *
8834
- * The `options` parameter allows passing storage-specific configuration
8835
- * that may override default behavior (e.g., encryption settings, expiration checks).
8790
+ * Use this overload when a fallback is required so callers avoid explicit `null` checks.
8836
8791
  *
8837
- * @param options - Optional storage operation configuration
8838
- * @returns The stored value, or `null` if not found
8839
- *
8840
- * @example Basic retrieval
8841
- * ```typescript
8842
- * const storage = new KeyStorage('token', { storage: localStorage });
8843
- * storage.set('abc123');
8844
- * const token = storage.get(); // Returns 'abc123'
8845
- * ```
8846
- *
8847
- * @example With options
8848
- * ```typescript
8849
- * interface Options {
8850
- * decrypt?: boolean;
8851
- * }
8852
- *
8853
- * const storage = new KeyStorage<string, string, Options>('secret', {
8854
- * storage: localStorage
8855
- * });
8856
- *
8857
- * // Retrieve with decryption
8858
- * const value = storage.get({ decrypt: true });
8859
- * ```
8860
- *
8861
- * @example Handling null values
8862
- * ```typescript
8863
- * const storage = new KeyStorage('data', { storage: localStorage });
8864
- * const value = storage.get();
8865
- *
8866
- * if (value === null) {
8867
- * console.log('No value stored');
8868
- * } else {
8869
- * console.log('Value:', value);
8870
- * }
8871
- * ```
8792
+ * @param key - Key of the value to retrieve.
8793
+ * @param defaultValue - Value to return when the key is not found.
8794
+ * @param options - Optional parameters for retrieval. Type is `Opt`.
8795
+ * @returns The stored value if present, otherwise `defaultValue`.
8872
8796
  */
8873
- get(options?: Opt): Value | null;
8797
+ getItem(key: K, defaultValue: V, options?: Opt): V | null;
8874
8798
  /**
8875
- * Store a value with optional configuration
8876
- *
8877
- * Storage behavior:
8878
- * - Updates in-memory value immediately
8879
- * - Persists to underlying storage backend if available
8880
- * - Merges provided options with default options
8881
- * - Overwrites any existing value for this key
8882
- *
8883
- * The `options` parameter can be used to pass storage-specific settings
8884
- * such as encryption, expiration, or other backend-specific configurations.
8885
- *
8886
- * @param value - The value to store (can be any type matching `Value`)
8887
- * @param options - Optional storage operation configuration
8888
- *
8889
- * @example Basic storage
8890
- * ```typescript
8891
- * const storage = new KeyStorage('token', { storage: localStorage });
8892
- * storage.set('abc123token');
8893
- * ```
8894
- *
8895
- * @example Storing complex objects
8896
- * ```typescript
8897
- * interface User {
8898
- * id: string;
8899
- * name: string;
8900
- * }
8901
- *
8902
- * const storage = new KeyStorage<string, User>('user', {
8903
- * storage: localStorage
8904
- * });
8905
- *
8906
- * storage.set({
8907
- * id: '123',
8908
- * name: 'John Doe'
8909
- * });
8910
- * ```
8799
+ * Removes the entry for the given key.
8911
8800
  *
8912
- * @example With encryption options
8913
- * ```typescript
8914
- * interface Options {
8915
- * encrypt?: boolean;
8916
- * expires?: number;
8917
- * }
8801
+ * No-op if the key does not exist. Implementations may use `options` (e.g. scope) to
8802
+ * target a specific storage area.
8918
8803
  *
8919
- * const storage = new KeyStorage<string, string, Options>('secret', {
8920
- * storage: localStorage
8921
- * });
8922
- *
8923
- * storage.set('sensitive-data', {
8924
- * encrypt: true,
8925
- * expires: Date.now() + 3600000 // 1 hour
8926
- * });
8927
- * ```
8804
+ * @param key - Key of the value to remove.
8805
+ * @param options - Optional parameters for removal. Type is `Opt`.
8928
8806
  */
8929
- set(value: Value, options?: Opt): void;
8807
+ removeItem(key: K, options?: Opt): void;
8930
8808
  /**
8931
- * Remove the stored value from both memory and persistent storage
8932
- *
8933
- * Removal behavior:
8934
- * - Clears in-memory value (sets to `null`)
8935
- * - Removes value from persistent storage backend if available
8936
- * - Applies any options-specific removal behavior
8937
- *
8938
- * After calling `remove()`, subsequent calls to `get()` will return `null`
8939
- * until a new value is set via `set()`.
8940
- *
8941
- * @param options - Optional storage operation configuration
8942
- *
8943
- * @example Basic removal
8944
- * ```typescript
8945
- * const storage = new KeyStorage('token', { storage: localStorage });
8946
- * storage.set('abc123');
8947
- * storage.remove(); // Removes from both memory and localStorage
8948
- * const token = storage.get(); // Returns null
8949
- * ```
8950
- *
8951
- * @example With options
8952
- * ```typescript
8953
- * interface Options {
8954
- * softDelete?: boolean;
8955
- * }
8956
- *
8957
- * const storage = new KeyStorage<string, string, Options>('data', {
8958
- * storage: localStorage
8959
- * });
8960
- *
8961
- * // Remove with soft delete option
8962
- * storage.remove({ softDelete: true });
8963
- * ```
8964
- *
8965
- * @example Clearing user session
8966
- * ```typescript
8967
- * const userStorage = new KeyStorage('user', { storage: localStorage });
8809
+ * Removes all entries in this storage.
8968
8810
  *
8969
- * // User logs out
8970
- * userStorage.remove();
8971
- * ```
8811
+ * Scope of "all" is implementation-defined (e.g. may be limited to a prefix or namespace).
8972
8812
  */
8973
- remove(options?: Opt): void;
8813
+ clear(): void;
8974
8814
  }
8975
8815
 
8976
8816
  /**
8977
- * Interface representing a synchronous storage mechanism.
8817
+ * Storage interface bound to a single fixed key.
8978
8818
  *
8979
- * @template Key - The type of keys used to identify stored values.
8980
- * @template ValueType - The type of values stored, defaults to unknown.
8819
+ * Core concept:
8820
+ * A storage abstraction that only ever reads/writes one key, exposed as `key`. Callers use
8821
+ * `get`/`set`/`remove` without passing a key; useful for token storage, single preference,
8822
+ * or any "one value per instance" scenario.
8981
8823
  *
8982
- * @example
8824
+ * Main features:
8825
+ * - Fixed key: `readonly key` identifies the sole key this instance operates on
8826
+ * - Simple API: `get()` / `set(value)` / `remove()` with no key argument
8827
+ * - Optional parameters: generic `Opt` allows implementations to support expiry, scope, etc.
8828
+ *
8829
+ * When to use: Prefer this over a generic key-value interface when the semantic is "one
8830
+ * named slot" (e.g. auth token, theme, locale) and you want to avoid key typos and keep
8831
+ * API minimal.
8832
+ *
8833
+ * @template Key - Type of the fixed key (e.g. string literal `'token'` or union of known keys).
8834
+ * @template Value - Type of the value stored and retrieved.
8835
+ * @template Opt - Type of optional storage/retrieval options. Defaults to `unknown`.
8836
+ *
8837
+ * @example Basic usage (token)
8983
8838
  * ```typescript
8984
- * const storage: SyncStorage<string, number> = ...;
8985
- * storage.setItem('key', 123);
8986
- * const value = storage.getItem('key', 0);
8839
+ * const tokenStorage: KeyStorageInterface<'token', string> = ...;
8840
+ * tokenStorage.set('jwt-abc');
8841
+ * const token = tokenStorage.get();
8842
+ * tokenStorage.remove();
8843
+ * ```
8844
+ *
8845
+ * @example With options
8846
+ * ```typescript
8847
+ * tokenStorage.set('jwt-abc', { maxAge: 3600 });
8848
+ * const token = tokenStorage.get({ scope: 'session' });
8987
8849
  * ```
8988
8850
  */
8989
- interface SyncStorageInterface<Key, Opt = unknown> {
8990
- /**
8991
- * The number of items stored.
8992
- */
8993
- readonly length: number;
8851
+ interface KeyStorageInterface<Key, Value, Opt = unknown> {
8994
8852
  /**
8995
- * Stores a value with the specified key.
8853
+ * The single key this storage instance is bound to.
8996
8854
  *
8997
- * @param key - The key to identify the stored value.
8998
- * @param value - The value to store.
8999
- * @param options - Optional parameters for storage.
8855
+ * All `get`/`set`/`remove` operations act on this key. Read-only so that the binding
8856
+ * cannot change after creation.
9000
8857
  */
9001
- setItem<T>(key: Key, value: T, options?: Opt): void | unknown;
8858
+ readonly key: Key;
9002
8859
  /**
9003
- * Retrieves a value by key.
8860
+ * Reads the value for the bound key.
9004
8861
  *
9005
- * @param key - The key of the value to retrieve.
9006
- * @param defaultValue - The default value to return if the key is not found.
9007
- * @param options - Optional parameters for retrieval.
9008
- * @returns The value associated with the key, or the default value if not found.
8862
+ * @param options - Optional parameters for retrieval (e.g. scope). Type is `Opt`.
8863
+ * @returns The stored value, or `null` if no value has been set or it was removed.
9009
8864
  */
9010
- getItem<T>(key: Key, defaultValue?: T, options?: Opt): T | null;
8865
+ get(options?: Opt): Value | null;
9011
8866
  /**
9012
- * Removes a value by key.
8867
+ * Writes the value for the bound key.
9013
8868
  *
9014
- * @param key - The key of the value to remove.
9015
- * @param options - Optional parameters for removal.
9016
- */
9017
- removeItem(key: Key, options?: Opt): void;
9018
- /**
9019
- * Clears all stored values.
8869
+ * Overwrites any existing value. Implementations may use `options` for behaviour such
8870
+ * as TTL or storage scope.
8871
+ *
8872
+ * @param value - Value to store. Serialization is implementation-defined.
8873
+ * @param options - Optional parameters for this write (e.g. `maxAge`, `scope`). Type is `Opt`.
9020
8874
  */
9021
- clear(): void;
8875
+ set(value: Value, options?: Opt): void;
9022
8876
  /**
9023
- * Get the raw value from the storage.
8877
+ * Removes the value for the bound key.
9024
8878
  *
9025
- * 通过这个方法可以获取到内部原始的值
8879
+ * No-op if the key is already absent. Implementations may use `options` (e.g. scope)
8880
+ * to target a specific storage area.
9026
8881
  *
9027
- * @param value - The value to get the raw value from.
9028
- * @returns The raw value.
8882
+ * @param options - Optional parameters for removal. Type is `Opt`.
9029
8883
  */
9030
- getRawValue?<T>(value: unknown, defaultValue?: T, options?: Opt): T | null;
8884
+ remove(options?: Opt): void;
9031
8885
  }
9032
8886
 
9033
- interface KeyStorageOptions<Key, Sopt = unknown> extends ExpireOptions {
9034
- /**
9035
- * Persistent storage
9036
- */
9037
- storage?: SyncStorageInterface<Key, Sopt>;
9038
- }
9039
- /**
9040
- * KeyStorage is a storage that can be used to store a single value.
9041
- *
9042
- * Typical usage scenario: need to store a value and need to persist it:
9043
- *
9044
- * - token storage
9045
- * - user info storage
9046
- * - page theme, language
9047
- * - ...
9048
- *
9049
- * And support for data encryption, there are times when reporting errors in the local data can easily be tampered with, this time you can use encryption to protect the data!
9050
- *
9051
- * @since 1.5.0
9052
- *
9053
- * @example basic usage
9054
- *
9055
- * use localStorage as storage, persist the value
9056
- *
9057
- * ```typescript
9058
- * const tokenStorage = new KeyStorage('token', localStorage);
9059
- *
9060
- * tokenStorage.get(); // get from localStorage
9061
- * tokenStorage.set('token-123123123'); // set to localStorage
9062
- * tokenStorage.remove(); // remove from localStorage
9063
- * ```
9064
- *
9065
- * @example with encrypt
9066
- * ```typescript
9067
- * const tokenStorage = new KeyStorage('token', localStorage, {
9068
- * encrypt: new Encryptor(new AESCipher('1234567890'))
9069
- * });
9070
- *
9071
- * tokenStorage.get(); // get from localStorage
9072
- * tokenStorage.set('token-123123123'); // set to localStorage
9073
- * tokenStorage.remove(); // remove from localStorage
9074
- * ```
9075
- */
9076
- declare class KeyStorage<Key, Value, Opt extends KeyStorageOptions<Key> = KeyStorageOptions<Key>> implements KeyStorageInterface<Key, Value, Opt> {
9077
- readonly key: Key;
9078
- protected options: Opt;
9079
- protected value: Value | null;
9080
- constructor(key: Key, options?: Opt);
9081
- protected mergeOptions(options?: Opt): Opt;
9082
- /**
9083
- * @override
9084
- */
9085
- getKey(): Key;
9086
- /**
9087
- * @override
9088
- */
9089
- getValue(): Value | null;
8887
+ declare class KeyStorage<K, V, Opt = unknown> implements KeyStorageInterface<K, V, Opt> {
8888
+ readonly key: K;
8889
+ protected readonly storage?: StorageInterface<K, V, Opt> | undefined;
8890
+ protected value: V | undefined | null;
8891
+ constructor(key: K, storage?: StorageInterface<K, V, Opt> | undefined);
9090
8892
  /**
9091
8893
  * @override
9092
8894
  */
9093
- get(options?: Opt): Value | null;
8895
+ get(options?: Opt): V | null;
9094
8896
  /**
9095
8897
  * @override
9096
8898
  */
9097
- set(token: Value, options?: Opt): void;
8899
+ set(value: V, options?: Opt): void;
9098
8900
  /**
9099
8901
  * @override
9100
8902
  */
9101
8903
  remove(options?: Opt): void;
9102
8904
  }
9103
8905
 
9104
- interface ObjectStorageOptions extends ExpireOptions {
8906
+ interface ObjectStorageOptions {
8907
+ expires?: number;
9105
8908
  }
9106
8909
  /**
9107
8910
  * Storage value wrapper with expiration support
@@ -9169,7 +8972,7 @@ type StorageValue<Key, ValueType> = {
9169
8972
  *
9170
8973
  * @since 1.5.0
9171
8974
  */
9172
- declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOptions = ObjectStorageOptions> implements SyncStorageInterface<Key, Opt> {
8975
+ declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOptions = ObjectStorageOptions> implements StorageInterface<Key, ValueType, Opt> {
9173
8976
  /**
9174
8977
  * Serializer for data transformation
9175
8978
  *
@@ -9178,7 +8981,7 @@ declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOp
9178
8981
  * Main function: Serialize/deserialize storage values
9179
8982
  * Main purpose: Support type-safe storage operations
9180
8983
  */
9181
- protected readonly serializer?: SerializerIneterface<unknown, ValueType> | undefined;
8984
+ protected readonly serializer?: SerializerIneterface<ValueType, string> | undefined;
9182
8985
  /**
9183
8986
  * In-memory storage map for fast data access
9184
8987
  *
@@ -9211,11 +9014,10 @@ declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOp
9211
9014
  * Main function: Serialize/deserialize storage values
9212
9015
  * Main purpose: Support type-safe storage operations
9213
9016
  */
9214
- serializer?: SerializerIneterface<unknown, ValueType> | undefined);
9017
+ serializer?: SerializerIneterface<ValueType, string> | undefined);
9215
9018
  /**
9216
9019
  * Gets the number of items stored in the memory cache
9217
9020
  *
9218
- * @override
9219
9021
  * @returns The number of stored items in memory
9220
9022
  *
9221
9023
  * @example
@@ -9247,7 +9049,7 @@ declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOp
9247
9049
  * storage.setItem('session', sessionData, Date.now() + 3600000);
9248
9050
  * ```
9249
9051
  */
9250
- setItem<T>(key: Key, value: T, options?: ObjectStorageOptions): unknown;
9052
+ setItem<T>(key: Key, value: T, options?: ObjectStorageOptions): ValueType;
9251
9053
  /**
9252
9054
  * Retrieves a stored value by key with fallback strategy
9253
9055
  *
@@ -9277,11 +9079,8 @@ declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOp
9277
9079
  * const config = storage.getItem<AppConfig>('app-config');
9278
9080
  * ```
9279
9081
  */
9280
- getItem<T>(key: Key, defaultValue?: T): T | null;
9281
- /**
9282
- * @override
9283
- */
9284
- getRawValue<T>(value: unknown, defaultValue?: T): T | null;
9082
+ getItem(key: Key, defaultValue?: unknown): ValueType | null;
9083
+ protected getRawValue<T>(value: unknown, defaultValue?: T): T | null;
9285
9084
  /**
9286
9085
  * Removes a stored item by its key from both memory and persistent storage
9287
9086
  *
@@ -9357,339 +9156,194 @@ declare class ObjectStorage<Key, ValueType = string, Opt extends ObjectStorageOp
9357
9156
  * ```
9358
9157
  */
9359
9158
  protected isStorageValue(value: unknown): value is StorageValue<Key, ValueType>;
9159
+ }
9160
+
9161
+ /**
9162
+ * Plugin contract for the storage pipeline.
9163
+ *
9164
+ * Each plugin participates in a chain: on `set`, value flows forward (e.g. serialize → encrypt → persist);
9165
+ * on `get`, value flows backward (e.g. read → decrypt → deserialize). The second argument to `get` is
9166
+ * the value produced by the previous plugin in the chain so each step can transform it.
9167
+ *
9168
+ * @template K - Key type
9169
+ * @template V - Value type
9170
+ * @template Opt - Options type passed through the chain
9171
+ */
9172
+ interface StorageExecutorPlugin<K, V, Opt> {
9360
9173
  /**
9361
- * Gets the serializer instance
9174
+ * Transform or read value in the get pipeline. Receives `valueFromPrevious` from the next plugin
9175
+ * in the chain (e.g. raw string from storage, then decrypted, then deserialized).
9362
9176
  *
9363
- * Significance: Provides access to the serialization logic
9364
- * Core idea: Expose serializer for advanced use cases
9365
- * Main function: Return the serializer instance
9366
- * Main purpose: Enable direct access to serialization when needed
9177
+ * @param key - Storage key
9178
+ * @param valueFromPrevious - Value from the previous step in the reverse chain; first call gets `defaultValue`
9179
+ * @param options - Optional options forwarded to the chain
9180
+ * @returns Transformed value, or `undefined` to keep current pipeline value
9181
+ */
9182
+ get(key: K, valueFromPrevious: unknown, options?: Opt): V | undefined | null;
9183
+ /**
9184
+ * Transform or persist value in the set pipeline. May return the transformed value for the next plugin.
9367
9185
  *
9368
- * @returns The serializer instance
9186
+ * @param key - Storage key
9187
+ * @param value - Value from the previous step (or initial value)
9188
+ * @param options - Optional options forwarded to the chain
9189
+ * @returns Transformed value for the next plugin, or `undefined` if this step does not change the value
9190
+ */
9191
+ set(key: K, value: V, options?: Opt): unknown;
9192
+ /** Optional: remove item for this key. Only storage plugins typically implement this. */
9193
+ remove?(key?: K, options?: Opt): void;
9194
+ /** Optional: clear all data. Only storage plugins typically implement this. */
9195
+ clear?(): void;
9196
+ /**
9197
+ * When `'storage'`, this plugin reads from a backing store. On `getItem`, once the first
9198
+ * storage (from tail) returns a value, no further storage plugins are used for get; only
9199
+ * `'pipe'` plugins keep transforming the value. When `'pipe'` or omitted, the plugin only
9200
+ * transforms (e.g. serialize, encrypt).
9201
+ *
9202
+ * @example type=storage use first storage
9369
9203
  *
9370
- * @example
9371
9204
  * ```typescript
9372
- * const serializer = storage.getSerializer();
9373
- * if (serializer) {
9374
- * // Direct access to serializer
9375
- * }
9205
+ * const executor = new StorageExecutor([jsonSerializer, aesEncryptor, sessionStorage, localStorage]);
9206
+ * executor.setItem('key', { a: 1 }); // { a: 1 } → serialize → encrypt → sessionStorage → localStorage
9207
+ * executor.getItem('key'); // localStorage decrypt → deserialize → { a: 1 }
9376
9208
  * ```
9377
9209
  */
9378
- getSerializer(): SerializerIneterface<unknown, ValueType> | undefined;
9210
+ type?: 'storage' | string;
9379
9211
  }
9380
-
9381
9212
  /**
9382
- * Pipe processor type definition
9213
+ * Executes a pipeline of storage plugins, implementing `StorageInterface`.
9383
9214
  *
9384
- * Significance: Define the type of components that can be used for data processing pipelines
9385
- * Core idea: Unify the type definition of different processors, supporting data transformation and intermediate storage
9386
- * Main function: Provide type-safe pipeline components
9387
- * Main purpose: Support serialization, encryption, intermediate storage, and other data processing operations
9388
- */
9389
- type PipeType<Key> = SerializerIneterface<unknown, unknown> | EncryptorInterface<unknown, unknown> | SyncStorageInterface<Key, unknown>;
9390
- /**
9391
- * Pipe value definition, containing the pipe processor and its type identifier
9392
- *
9393
- * Significance: Pre-determine the pipe type to avoid runtime type checks
9394
- * Core idea: Bind the pipe processor with its type to improve execution efficiency
9395
- * Main function: Store the pipe processor and its type information
9396
- * Main purpose: Optimize pipe execution performance, simplify type judgment logic
9397
- */
9398
- type PipeValue<Key> = {
9399
- type: 'serialize';
9400
- pipe: SerializerIneterface<unknown, unknown>;
9401
- } | {
9402
- type: 'encrypt';
9403
- pipe: EncryptorInterface<unknown, unknown>;
9404
- } | {
9405
- type: 'storage';
9406
- pipe: SyncStorageInterface<Key, unknown>;
9407
- };
9408
-
9409
- /**
9410
- * Pipe argument type for storage initialization
9411
- *
9412
- * Accepts either a typed pipe or a pipe value wrapper.
9413
- *
9414
- * @template Key - Type of storage keys
9415
- */
9416
- type PipeArg<Key> = PipeType<Key> | PipeValue<Key>;
9417
- /**
9418
- * Synchronous storage implementation with pipeline support
9419
- *
9420
- * Core concept:
9421
- * Provides a flexible storage abstraction with a pipeline architecture that
9422
- * allows chaining multiple transformations (serialization, encryption, intermediate
9423
- * storage) before data reaches the final storage backend.
9215
+ * Core concept: values flow through plugins in order on `set` (e.g. serialize encrypt → storage),
9216
+ * and in reverse order on `get` (storage decrypt deserialize). Each plugin receives the value
9217
+ * from the previous step and may return a transformed value for the next.
9424
9218
  *
9425
9219
  * Main features:
9426
- * - Pipeline architecture: Chain multiple data transformations
9427
- * - Serialization: Convert objects to strings (JSON, Base64, etc.)
9428
- * - Encryption: Secure data before storage
9429
- * - Intermediate storage: Multi-layer storage support
9430
- * - Custom transformations: Extensible pipe system
9431
- *
9432
- * - Automatic pipe detection: Identifies pipe types by interface
9433
- * - Serializer: Has `serialize()` and `deserialize()` methods
9434
- * - Encryptor: Has `encrypt()` and `decrypt()` methods
9435
- * - Storage: Has `setItem()`, `getItem()`, `removeItem()`, `clear()` methods
9436
- * - No manual type specification needed
9437
- *
9438
- * - Bidirectional processing: Handles both storage and retrieval
9439
- * - setItem: Forward pipeline (value → serialize → encrypt → store)
9440
- * - getItem: Reverse pipeline (retrieve → decrypt → deserialize → value)
9441
- * - Maintains data integrity through the pipeline
9442
- *
9443
- * - Multi-layer storage: Support for intermediate storage layers
9444
- * - Primary storage: Final storage backend
9445
- * - Intermediate storage: Additional storage layers in pipeline
9446
- * - Fallback mechanism: Try intermediate storage if primary fails
9447
- *
9448
- * Pipeline execution order:
9449
- *
9450
- * **setItem (forward):**
9451
- * 1. Original value
9452
- * 2. Serialize (if serializer in pipeline)
9453
- * 3. Encrypt (if encryptor in pipeline)
9454
- * 4. Store in intermediate storage (if storage in pipeline)
9455
- * 5. Store in primary storage
9456
- *
9457
- * **getItem (reverse):**
9458
- * 1. Retrieve from primary storage
9459
- * 2. If not found, try intermediate storage layers (reversed order)
9460
- * 3. Decrypt (if encryptor in pipeline)
9461
- * 4. Deserialize (if serializer in pipeline)
9462
- * 5. Return final value
9463
- *
9464
- * @template Key - Type of storage keys (typically `string`)
9465
- * @template Opt - Type of storage options (optional)
9466
- *
9467
- * @example Basic usage with JSON serialization
9468
- * ```typescript
9469
- * import { SyncStorage, JSONSerializer } from '@qlover/fe-corekit';
9470
- *
9471
- * const storage = new SyncStorage(
9472
- * localStorage,
9473
- * new JSONSerializer()
9474
- * );
9220
+ * - **setItem**: Iterates plugins forward; each `set` may return a new value (e.g. serialized/encrypted) for the next
9221
+ * - **getItem**: Iterates plugins backward. **When there are multiple storage plugins, only the value from the
9222
+ * last storage (the one at the end of the plugin array) is used for reading; all other storage plugins are
9223
+ * skipped and their values are ignored.** Pipe plugins (serializer, encryptor, etc.) still transform the
9224
+ * value as usual.
9225
+ * - **removeItem** / **clear**: Delegated to all plugins that implement `remove` / `clear`
9475
9226
  *
9476
- * // Store object (automatically serialized to JSON)
9477
- * storage.setItem('user', { id: 1, name: 'John' });
9227
+ * @template K - Key type
9228
+ * @template V - Value type (after serialization/encryption may differ internally)
9229
+ * @template Opt - Options type
9478
9230
  *
9479
- * // Retrieve object (automatically deserialized from JSON)
9480
- * const user = storage.getItem('user');
9481
- * console.log(user); // { id: 1, name: 'John' }
9482
- * ```
9483
- *
9484
- * @example With encryption
9231
+ * @example Single storage backend
9485
9232
  * ```typescript
9486
- * import { SyncStorage, JSONSerializer, AESEncryptor } from '@qlover/fe-corekit';
9487
- *
9488
- * const storage = new SyncStorage(
9489
- * localStorage,
9490
- * [
9491
- * new JSONSerializer(), // First: serialize to JSON
9492
- * new AESEncryptor('key') // Then: encrypt JSON string
9493
- * ]
9494
- * );
9495
- *
9496
- * // Data is serialized then encrypted before storage
9497
- * storage.setItem('sensitive', { password: 'secret' });
9498
- *
9499
- * // Data is decrypted then deserialized on retrieval
9500
- * const data = storage.getItem('sensitive');
9233
+ * const executor = new StorageExecutor(localStorage);
9234
+ * executor.setItem('key', { a: 1 });
9235
+ * executor.getItem('key');
9501
9236
  * ```
9502
9237
  *
9503
- * @example Multi-layer storage
9238
+ * @example Pipeline: serializer + encryptor + storage
9504
9239
  * ```typescript
9505
- * import { SyncStorage, JSONSerializer } from '@qlover/fe-corekit';
9506
- *
9507
- * // Create intermediate storage layer
9508
- * const memoryCache = new Map();
9509
- * const cacheStorage = {
9510
- * setItem: (k, v) => memoryCache.set(k, v),
9511
- * getItem: (k) => memoryCache.get(k) ?? null,
9512
- * removeItem: (k) => memoryCache.delete(k),
9513
- * clear: () => memoryCache.clear(),
9514
- * length: memoryCache.size
9515
- * };
9516
- *
9517
- * const storage = new SyncStorage(
9518
- * localStorage,
9519
- * [
9520
- * new JSONSerializer(),
9521
- * cacheStorage // Intermediate cache layer
9522
- * ]
9523
- * );
9524
- *
9525
- * // Data stored in both cache and localStorage
9526
- * storage.setItem('data', { value: 123 });
9527
- *
9528
- * // Retrieval tries cache first, then localStorage
9529
- * const data = storage.getItem('data');
9240
+ * const executor = new StorageExecutor([jsonSerializer, aesEncryptor, localStorage]);
9241
+ * executor.setItem('key', obj); // obj → serialize → encrypt → persist
9242
+ * executor.getItem('key'); // read decrypt → deserialize → obj
9530
9243
  * ```
9531
9244
  *
9532
- * @example Custom pipe order
9245
+ * @example Multiple storages: getItem uses only the last storage
9533
9246
  * ```typescript
9534
- * // Order matters! Pipes are applied in sequence
9535
- * const storage = new SyncStorage(
9536
- * localStorage,
9537
- * [
9538
- * new JSONSerializer(), // 1. Serialize to JSON string
9539
- * new Base64Serializer(), // 2. Encode to Base64
9540
- * new AESEncryptor('key') // 3. Encrypt the Base64 string
9541
- * ]
9542
- * );
9543
- *
9544
- * // setItem: value → JSON → Base64 → Encrypt → store
9545
- * // getItem: retrieve → Decrypt → Base64 decode → JSON parse → value
9247
+ * const executor = new StorageExecutor([sessionStorage, localStorage]);
9248
+ * executor.setItem('key', 'v'); // writes to both
9249
+ * executor.getItem('key'); // reads only from localStorage (last); sessionStorage is ignored
9546
9250
  * ```
9547
- *
9548
- * @see {@link SyncStorageInterface} for the storage interface
9549
- * @see {@link PipeType} for pipe type definitions
9550
- * @see {@link SerializerInterface} for serializer interface
9551
- * @see {@link EncryptorInterface} for encryptor interface
9552
9251
  */
9553
- declare class SyncStorage<Key, Opt = unknown> implements SyncStorageInterface<Key, Opt> {
9554
- protected readonly storage: SyncStorageInterface<Key, Opt>;
9555
- /**
9556
- * Internal pipe value list with pre-determined types
9557
- *
9558
- * Stores the processed pipeline of transformations that will be
9559
- * applied to data during storage and retrieval operations.
9560
- *
9561
- * @protected
9562
- */
9563
- protected readonly pipes: PipeValue<Key>[];
9564
- /**
9565
- * Creates a new SyncStorage instance with pipeline support
9566
- *
9567
- * @param storage - Primary storage backend (e.g., localStorage, sessionStorage)
9568
- * @param pipes - Optional pipe or array of pipes for data transformation
9569
- *
9570
- * @example Single pipe
9571
- * ```typescript
9572
- * const storage = new SyncStorage(
9573
- * localStorage,
9574
- * new JSONSerializer()
9575
- * );
9576
- * ```
9577
- *
9578
- * @example Multiple pipes
9579
- * ```typescript
9580
- * const storage = new SyncStorage(
9581
- * localStorage,
9582
- * [
9583
- * new JSONSerializer(),
9584
- * new AESEncryptor('secret-key')
9585
- * ]
9586
- * );
9587
- * ```
9588
- *
9589
- * @example No pipes (direct storage)
9590
- * ```typescript
9591
- * const storage = new SyncStorage(localStorage);
9592
- * // Data stored as-is without transformation
9593
- * ```
9594
- */
9595
- constructor(storage: SyncStorageInterface<Key, Opt>, pipes?: PipeArg<Key>[] | PipeArg<Key>);
9252
+ declare class StorageExecutor<K, V, Opt = unknown> implements StorageInterface<K, V, Opt> {
9253
+ protected plugins: StorageExecutorPlugin<K, V, Opt>[];
9596
9254
  /**
9597
- * Get the number of items in the primary storage
9255
+ * Builds the plugin list from either a single `StorageInterface` or an array whose last element
9256
+ * is the backing storage and preceding elements are transformers (e.g. serializer, encryptor).
9598
9257
  *
9599
- * Returns the count of items in the primary storage backend only.
9600
- * Does not include items in intermediate storage layers.
9601
- *
9602
- * @override
9603
- * @returns Number of items in primary storage
9604
- *
9605
- * @example
9606
- * ```typescript
9607
- * console.log(storage.length); // 5
9608
- * storage.setItem('newKey', 'value');
9609
- * console.log(storage.length); // 6
9610
- * ```
9258
+ * @param plugins - Single storage instance or tuple of `[ ...transformers, storage ]`
9611
9259
  */
9612
- get length(): number;
9260
+ constructor(plugins: StorageInterface<K, V, Opt> | [
9261
+ ...(SerializerIneterface<V> | StorageInterface<K, V, Opt> | EncryptorInterface<V, unknown> | StorageExecutorPlugin<K, V, Opt>)[],
9262
+ StorageInterface<K, V, Opt>
9263
+ ]);
9613
9264
  /**
9614
- * Store a value with pipeline processing
9615
- *
9616
- * Processes the value through the configured pipeline (serialization,
9617
- * encryption, intermediate storage) before storing in the primary storage.
9618
- *
9619
- * Pipeline execution:
9620
- * 1. Apply serialization (if configured)
9621
- * 2. Apply encryption (if configured)
9622
- * 3. Store in intermediate storage layers (if configured)
9623
- * 4. Store in primary storage
9265
+ * Writes value through the plugin chain (forward). Each plugin may return a transformed value for the next.
9624
9266
  *
9625
9267
  * @override
9626
- * @template T - Type of value to store
9627
- * @param key - Storage key
9628
- * @param value - Value to store
9629
- * @param options - Optional storage options (e.g., expiration)
9630
- *
9631
- * @example Basic storage
9632
- * ```typescript
9633
- * storage.setItem('user', { id: 1, name: 'John' });
9634
- * ```
9635
- *
9636
- * @example With options
9637
- * ```typescript
9638
- * storage.setItem('session', { token: 'abc' }, { expire: 3600 });
9639
- * ```
9640
9268
  */
9641
- setItem<T>(key: Key, value: T, options?: Opt): void;
9269
+ setItem(key: K, value: V, options?: Opt | undefined): void;
9270
+ /** @override */
9271
+ getItem(key: K, options?: Opt | undefined): V | null;
9272
+ /** @override */
9273
+ getItem(key: K, defaultValue: V, options?: Opt | undefined): V;
9642
9274
  /**
9643
- * Retrieve a value with pipeline processing
9644
- *
9645
- * Retrieves the value from storage and processes it through the pipeline
9646
- * in reverse order (decryption, deserialization) to restore the original value.
9647
- *
9648
- * Retrieval strategy:
9649
- * 1. Try to retrieve from primary storage
9650
- * 2. If not found, try intermediate storage layers (in reverse order)
9651
- * 3. Apply decryption (if configured)
9652
- * 4. Apply deserialization (if configured)
9653
- * 5. Return processed value or default
9275
+ * Removes item for the given key from all plugins that implement `remove`.
9654
9276
  *
9655
9277
  * @override
9656
- * @template T - Type of value to retrieve
9657
- * @param key - Storage key
9658
- * @param defaultValue - Default value if key not found
9659
- * @param options - Optional retrieval options
9660
- * @returns Retrieved value or default, `null` if not found and no default
9661
- *
9662
- * @example Basic retrieval
9663
- * ```typescript
9664
- * const user = storage.getItem('user');
9665
- * if (user) {
9666
- * console.log(user.name);
9667
- * }
9668
- * ```
9669
- *
9670
- * @example With default value
9671
- * ```typescript
9672
- * const config = storage.getItem('config', { theme: 'light' });
9673
- * console.log(config.theme); // 'light' if not found
9674
- * ```
9675
9278
  */
9676
- getItem<T>(key: Key, defaultValue?: T, options?: Opt): T | null;
9279
+ removeItem(key: K, options?: Opt | undefined): void;
9677
9280
  /**
9678
- * Delete data items, delete from all storage layers
9281
+ * Clears data in all plugins that implement `clear`.
9679
9282
  *
9680
9283
  * @override
9681
- * @param key - Storage key
9682
- * @param options - Delete options
9683
9284
  */
9684
- removeItem(key: Key, options?: Opt): void;
9685
- /**
9686
- * Clear all data, including storage in the pipeline
9687
-
9688
- * @override
9689
- */
9690
9285
  clear(): void;
9691
9286
  }
9692
9287
 
9288
+ /**
9289
+ * Wraps a `StorageInterface` as a `StorageExecutorPlugin` so it can participate in the pipeline.
9290
+ * Forwards `get`/`set`/`remove`/`clear` to the underlying storage.
9291
+ *
9292
+ * @template K - Key type
9293
+ * @template V - Value type
9294
+ * @template Opt - Options type
9295
+ * @param storage - The backing storage implementation
9296
+ * @returns A plugin that delegates to `storage`
9297
+ */
9298
+ declare function createStoragePluginWithStorage<K, V, Opt = unknown>(storage: StorageInterface<K, V, Opt>): StorageExecutorPlugin<K, V, Opt>;
9299
+ /**
9300
+ * Type guard: checks if the value is a serializer (has `serialize` and `deserialize` methods).
9301
+ *
9302
+ * @template V - Value type the serializer handles
9303
+ * @param plugin - Value to check
9304
+ * @returns `true` if `plugin` implements `SerializerIneterface<V>`
9305
+ */
9306
+ declare function isSerializer<V>(plugin: unknown): plugin is SerializerIneterface<V>;
9307
+ /**
9308
+ * Type guard: checks if the value is an encryptor (has `encrypt` and `decrypt` methods).
9309
+ *
9310
+ * @template V - Value type the encryptor handles
9311
+ * @template E - Encrypted result type
9312
+ * @param plugin - Value to check
9313
+ * @returns `true` if `plugin` implements `EncryptorInterface<V, E>`
9314
+ */
9315
+ declare function isEncryptor<V, E>(plugin: unknown): plugin is EncryptorInterface<V, E>;
9316
+ /**
9317
+ * Normalizes plugin input into an array of `StorageExecutorPlugin`.
9318
+ *
9319
+ * - If a single `StorageInterface` is passed, returns one plugin that wraps it.
9320
+ * - If an array is passed, maps each element: serializers and encryptors are adapted so that
9321
+ * only the pipeline value is passed to `serialize`/`deserialize`/`encrypt`/`decrypt`; storage
9322
+ * instances are wrapped; other values are treated as already-implemented plugins. Array order
9323
+ * is preserved (first plugin = first in set chain, last = storage in typical usage).
9324
+ *
9325
+ * @template K - Key type
9326
+ * @template V - Value type
9327
+ * @template Opt - Options type
9328
+ * @param plugins - Single storage or tuple `[ ...transformers, storage ]`
9329
+ * @returns Array of plugins in pipeline order
9330
+ *
9331
+ * @example
9332
+ * ```typescript
9333
+ * createStoragePlugin(localStorage);
9334
+ * // => [ wrap(localStorage) ]
9335
+ *
9336
+ * createStoragePlugin([jsonSerializer, encryptor, localStorage]);
9337
+ * // => [ adapter(serialize/deserialize), adapter(encrypt/decrypt), wrap(localStorage) ]
9338
+ * ```
9339
+ */
9340
+ declare function createStoragePlugin<K, V, Opt = unknown>(plugins: StorageInterface<K, V, Opt> | [
9341
+ ...(SerializerIneterface<V> | StorageInterface<K, V, Opt> | EncryptorInterface<V, unknown> | StorageExecutorPlugin<K, V, Opt>)[],
9342
+ StorageInterface<K, V, Opt>
9343
+ ]): StorageExecutorPlugin<K, V, Opt>[];
9344
+
9345
+ declare function isStorage<Key, Value, Opt = unknown>(storage: unknown): storage is StorageInterface<Key, Value, Opt>;
9346
+
9693
9347
  /**
9694
9348
  * Extract all possible value types from an object type
9695
9349
  *
@@ -9882,4 +9536,4 @@ type PartialDeep<T> = {
9882
9536
  [K in keyof T]?: T[K] extends object ? PartialDeep<T[K]> : T[K];
9883
9537
  };
9884
9538
 
9885
- export { ABORT_ERROR_ID, AbortError, Aborter, type AborterConfig, type AborterConfigExtractor, type AborterId, type AborterInterface, AborterPlugin, type AborterPluginOptions, type AsyncStorageInterface, Base64Serializer, BasePluginExecutor, DEFAULT_HOOK_ON_BEFORE, DEFAULT_HOOK_ON_ERROR, DEFAULT_HOOK_ON_EXEC, DEFAULT_HOOK_ON_FINALLY, DEFAULT_HOOK_ON_SUCCESS, EXECUTOR_ASYNC_ERROR, EXECUTOR_ERROR_NAME, EXECUTOR_SYNC_ERROR, type EncryptorInterface, type ExecutorAsyncTask, ExecutorContextImpl, type ExecutorContextInterface, ExecutorError, type ExecutorErrorType, type ExecutorHookRuntimesInterface, type ExecutorInterface, type ExecutorPluginInterface, type ExecutorPluginNameType, type ExecutorSyncTask, type ExecutorTask, type ExpireOptions, type HeaderInjectorConfig, type HeaderInjectorInterface, type HookRuntimes, type HttpMethodType, HttpMethods, type Intersection, JSONSerializer, type JSONSerializerOptions, KeyStorage, type KeyStorageInterface, type KeyStorageOptions, type LifecycleErrorResult, type LifecycleExecResult, LifecycleExecutor, type LifecyclePluginInterface, LifecycleSyncExecutor, type LifecycleSyncPluginInterface, ObjectStorage, type ObjectStorageOptions, type PartialDeep, type PipeArg, type PluginExecutorConfig, RETRY_ERROR_ID, RequestAdapterAxios, type RequestAdapterConfig, type RequestAdapterContext, RequestAdapterFetch, type RequestAdapterFetchConfig, type RequestAdapterInterface, type RequestAdapterResponse, RequestExecutor, type RequestExecutorInterface, RequestHeaderInjector, RequestPlugin, type RequestPluginConfig, type RequestPluginInnerConfig, type ResponseParser, type ResponseParsers, ResponsePlugin, type ResponsePluginConfig, type ResponsePluginContext, RetryPlugin, type SerializerIneterface, SimpleUrlBuilder, type StorageValue, SyncStorage, type SyncStorageInterface, type UrlBuilderInterface, type ValueOf, appendHeaders, createAbortPromise, hasObjectKey, hasObjectKeyWithValue, isAbortError, isAbsoluteUrl, isAsString, isRequestAdapterResponse, normalizeHookNames, raceWithAbort, runPluginHook, runPluginsHookAsync, runPluginsHookSync, runPluginsHooksAsync, runPluginsHooksSync };
9539
+ export { ABORT_ERROR_ID, AbortError, Aborter, type AborterConfig, type AborterConfigExtractor, type AborterId, type AborterInterface, AborterPlugin, type AborterPluginOptions, type AsyncStorageInterface, Base64Serializer, BasePluginExecutor, DEFAULT_HOOK_ON_BEFORE, DEFAULT_HOOK_ON_ERROR, DEFAULT_HOOK_ON_EXEC, DEFAULT_HOOK_ON_FINALLY, DEFAULT_HOOK_ON_SUCCESS, EXECUTOR_ASYNC_ERROR, EXECUTOR_ERROR_NAME, EXECUTOR_SYNC_ERROR, type EncryptorInterface, type ExecutorAsyncTask, ExecutorContextImpl, type ExecutorContextInterface, ExecutorError, type ExecutorErrorType, type ExecutorHookRuntimesInterface, type ExecutorInterface, type ExecutorPluginInterface, type ExecutorPluginNameType, type ExecutorSyncTask, type ExecutorTask, type HeaderInjectorConfig, type HeaderInjectorInterface, type HookRuntimes, type HttpMethodType, HttpMethods, type Intersection, JSONSerializer, type JSONSerializerOptions, KeyStorage, type KeyStorageInterface, type LifecycleErrorResult, type LifecycleExecResult, LifecycleExecutor, type LifecyclePluginInterface, LifecycleSyncExecutor, type LifecycleSyncPluginInterface, ObjectStorage, type ObjectStorageOptions, type PartialDeep, type PluginExecutorConfig, RETRY_ERROR_ID, RequestAdapterAxios, type RequestAdapterConfig, type RequestAdapterContext, RequestAdapterFetch, type RequestAdapterFetchConfig, type RequestAdapterInterface, type RequestAdapterResponse, RequestExecutor, type RequestExecutorInterface, RequestHeaderInjector, RequestPlugin, type RequestPluginConfig, type RequestPluginInnerConfig, type ResponseParser, type ResponseParsers, ResponsePlugin, type ResponsePluginConfig, type ResponsePluginContext, RetryPlugin, type SerializerIneterface, SimpleUrlBuilder, StorageExecutor, type StorageExecutorPlugin, type StorageInterface, type StorageValue, type UrlBuilderInterface, type ValueOf, appendHeaders, createAbortPromise, createStoragePlugin, createStoragePluginWithStorage, hasObjectKey, hasObjectKeyWithValue, isAbortError, isAbsoluteUrl, isAsString, isEncryptor, isRequestAdapterResponse, isSerializer, isStorage, normalizeHookNames, raceWithAbort, runPluginHook, runPluginsHookAsync, runPluginsHookSync, runPluginsHooksAsync, runPluginsHooksSync };