@dinoconfig/js-sdk 1.0.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.
@@ -0,0 +1,86 @@
1
+ import { CacheConfig, CacheOptions, CacheStats } from './cache.types';
2
+ /**
3
+ * Multi-layer cache manager.
4
+ * Provides a unified interface for caching with L1 (memory) and L2 (storage) layers.
5
+ *
6
+ * @class CacheManager
7
+ * @example
8
+ * ```typescript
9
+ * const cache = new CacheManager({
10
+ * enabled: true,
11
+ * ttl: 60000,
12
+ * maxSize: 1000,
13
+ * storage: 'localStorage',
14
+ * });
15
+ *
16
+ * // Get with automatic fallback through layers
17
+ * const value = await cache.get('key');
18
+ *
19
+ * // Set (writes to both layers)
20
+ * await cache.set('key', 'value');
21
+ *
22
+ * // Invalidate
23
+ * cache.invalidate('brand:.*');
24
+ * ```
25
+ */
26
+ export declare class CacheManager {
27
+ private config;
28
+ private memoryCache;
29
+ private storageCache?;
30
+ constructor(config: CacheConfig);
31
+ /**
32
+ * Get a value from cache.
33
+ * Checks L1 (memory) first, then L2 (storage) if available.
34
+ *
35
+ * @param {string} key - Cache key
36
+ * @returns {Promise<T | null>} Cached value or null if not found
37
+ */
38
+ get<T>(key: string): Promise<T | null>;
39
+ /**
40
+ * Set a value in cache.
41
+ * Writes to both L1 (memory) and L2 (storage) if available.
42
+ *
43
+ * @param {string} key - Cache key
44
+ * @param {T} value - Value to cache
45
+ * @param {CacheOptions} options - Optional cache options
46
+ */
47
+ set<T>(key: string, value: T, options?: CacheOptions): Promise<void>;
48
+ /**
49
+ * Delete a value from cache.
50
+ * Removes from both L1 and L2.
51
+ *
52
+ * @param {string} key - Cache key
53
+ */
54
+ delete(key: string): Promise<void>;
55
+ /**
56
+ * Clear all cache entries.
57
+ */
58
+ clear(): Promise<void>;
59
+ /**
60
+ * Invalidate entries matching a pattern.
61
+ *
62
+ * @param {string} pattern - Regex pattern to match keys
63
+ */
64
+ invalidate(pattern?: string): Promise<void>;
65
+ /**
66
+ * Check if a key exists in cache.
67
+ *
68
+ * @param {string} key - Cache key
69
+ * @returns {boolean} True if key exists and is not expired
70
+ */
71
+ has(key: string): boolean;
72
+ /**
73
+ * Get cache statistics.
74
+ *
75
+ * @returns {CacheStats} Cache statistics
76
+ */
77
+ getStats(): CacheStats;
78
+ /**
79
+ * Prefetch a value into cache.
80
+ * This is a convenience method for warming the cache.
81
+ *
82
+ * @param {string} key - Cache key
83
+ * @param {() => Promise<T>} fetcher - Function to fetch the value if not cached
84
+ */
85
+ prefetch<T>(key: string, fetcher: () => Promise<T>): Promise<T>;
86
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @fileoverview Type definitions for the cache layer.
3
+ * @module @dinoconfig/dinoconfig-js-sdk/cache/types
4
+ */
5
+ /**
6
+ * Configuration options for the cache layer.
7
+ *
8
+ * @interface CacheConfig
9
+ * @example
10
+ * ```typescript
11
+ * const cacheConfig: CacheConfig = {
12
+ * enabled: true,
13
+ * ttl: 60000, // 1 minute
14
+ * maxSize: 1000,
15
+ * storage: 'localStorage',
16
+ * staleWhileRevalidate: true,
17
+ * };
18
+ * ```
19
+ */
20
+ export interface CacheConfig {
21
+ /**
22
+ * Whether caching is enabled.
23
+ * @default false
24
+ */
25
+ enabled: boolean;
26
+ /**
27
+ * Time-to-live in milliseconds.
28
+ * How long cached entries remain valid.
29
+ * @default 60000 (1 minute)
30
+ */
31
+ ttl: number;
32
+ /**
33
+ * Maximum number of entries in memory cache.
34
+ * @default 1000
35
+ */
36
+ maxSize: number;
37
+ /**
38
+ * Storage backend for L2 cache.
39
+ * - 'memory': Only use in-memory cache (L1)
40
+ * - 'localStorage': Use localStorage for persistent cache (L2)
41
+ * - 'indexedDB': Use IndexedDB for persistent cache (L2)
42
+ * @default undefined (memory only)
43
+ */
44
+ storage?: 'memory' | 'localStorage' | 'indexedDB';
45
+ /**
46
+ * Whether to return stale data while fetching fresh data in background.
47
+ * @default false
48
+ */
49
+ staleWhileRevalidate?: boolean;
50
+ }
51
+ /**
52
+ * A cached entry with metadata.
53
+ *
54
+ * @interface CacheEntry
55
+ * @typeParam T - The type of the cached value
56
+ */
57
+ export interface CacheEntry<T = any> {
58
+ /**
59
+ * The cached value.
60
+ */
61
+ value: T;
62
+ /**
63
+ * Timestamp when the entry was created.
64
+ */
65
+ timestamp: number;
66
+ /**
67
+ * Timestamp when the entry expires.
68
+ */
69
+ expiresAt: number;
70
+ /**
71
+ * Optional version number for cache invalidation.
72
+ */
73
+ version?: number;
74
+ }
75
+ /**
76
+ * Options for cache operations.
77
+ */
78
+ export interface CacheOptions {
79
+ /**
80
+ * Custom TTL for this specific operation.
81
+ * Overrides the default TTL from cache configuration.
82
+ */
83
+ ttl?: number;
84
+ }
85
+ /**
86
+ * Cache statistics.
87
+ */
88
+ export interface CacheStats {
89
+ /**
90
+ * Number of cache hits.
91
+ */
92
+ hits: number;
93
+ /**
94
+ * Number of cache misses.
95
+ */
96
+ misses: number;
97
+ /**
98
+ * Number of entries currently in cache.
99
+ */
100
+ size: number;
101
+ /**
102
+ * Cache hit rate (0-1).
103
+ */
104
+ hitRate: number;
105
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Cache layer exports.
3
+ * @module @dinoconfig/dinoconfig-js-sdk/cache
4
+ */
5
+ export { CacheManager } from './cache-manager';
6
+ export { MemoryCache } from './memory-cache';
7
+ export { StorageCache } from './storage-cache';
8
+ export type { CacheConfig, CacheEntry, CacheOptions, CacheStats, } from './cache.types';
@@ -0,0 +1,86 @@
1
+ import { CacheOptions } from './cache.types';
2
+ /**
3
+ * In-memory cache implementation.
4
+ * Provides fast, synchronous access to cached values.
5
+ *
6
+ * @class MemoryCache
7
+ * @example
8
+ * ```typescript
9
+ * const cache = new MemoryCache({ ttl: 60000, maxSize: 1000 });
10
+ *
11
+ * await cache.set('key', 'value');
12
+ * const value = await cache.get('key'); // 'value'
13
+ * ```
14
+ */
15
+ export declare class MemoryCache {
16
+ private ttl;
17
+ private maxSize;
18
+ private cache;
19
+ private hits;
20
+ private misses;
21
+ constructor(ttl: number, maxSize: number);
22
+ /**
23
+ * Get a value from the cache.
24
+ *
25
+ * @param {string} key - Cache key
26
+ * @returns {T | null} Cached value or null if not found/expired
27
+ */
28
+ get<T>(key: string): T | null;
29
+ /**
30
+ * Set a value in the cache.
31
+ *
32
+ * @param {string} key - Cache key
33
+ * @param {T} value - Value to cache
34
+ * @param {CacheOptions} options - Optional cache options
35
+ */
36
+ set<T>(key: string, value: T, options?: CacheOptions): void;
37
+ /**
38
+ * Delete a value from the cache.
39
+ *
40
+ * @param {string} key - Cache key
41
+ */
42
+ delete(key: string): void;
43
+ /**
44
+ * Clear all entries from the cache.
45
+ */
46
+ clear(): void;
47
+ /**
48
+ * Invalidate entries matching a pattern.
49
+ *
50
+ * @param {string} pattern - Regex pattern to match keys
51
+ */
52
+ invalidate(pattern: string): void;
53
+ /**
54
+ * Check if an entry exists and is not expired.
55
+ *
56
+ * @param {string} key - Cache key
57
+ * @returns {boolean} True if entry exists and is valid
58
+ */
59
+ has(key: string): boolean;
60
+ /**
61
+ * Get cache statistics.
62
+ *
63
+ * @returns {CacheStats} Cache statistics
64
+ */
65
+ getStats(): {
66
+ hits: number;
67
+ misses: number;
68
+ size: number;
69
+ hitRate: number;
70
+ };
71
+ /**
72
+ * Check if an entry is expired.
73
+ *
74
+ * @private
75
+ * @param {CacheEntry} entry - Cache entry
76
+ * @returns {boolean} True if expired
77
+ */
78
+ private isExpired;
79
+ /**
80
+ * Evict the oldest entry from the cache.
81
+ * Uses LRU-like strategy based on expiration time.
82
+ *
83
+ * @private
84
+ */
85
+ private evictOldest;
86
+ }
@@ -0,0 +1,58 @@
1
+ import { CacheOptions } from './cache.types';
2
+ /**
3
+ * Storage cache implementation.
4
+ * Provides persistent caching using browser storage APIs.
5
+ *
6
+ * @class StorageCache
7
+ * @example
8
+ * ```typescript
9
+ * const cache = new StorageCache('localStorage');
10
+ *
11
+ * await cache.set('key', 'value');
12
+ * const value = await cache.get('key'); // 'value'
13
+ * ```
14
+ */
15
+ export declare class StorageCache {
16
+ private adapter;
17
+ private prefix;
18
+ constructor(storageType: 'localStorage' | 'indexedDB');
19
+ /**
20
+ * Get a value from storage cache.
21
+ *
22
+ * @param {string} key - Cache key
23
+ * @returns {Promise<T | null>} Cached value or null if not found/expired
24
+ */
25
+ get<T>(key: string): Promise<T | null>;
26
+ /**
27
+ * Set a value in storage cache.
28
+ *
29
+ * @param {string} key - Cache key
30
+ * @param {T} value - Value to cache
31
+ * @param {CacheOptions} options - Optional cache options
32
+ */
33
+ set<T>(key: string, value: T, options?: CacheOptions): Promise<void>;
34
+ /**
35
+ * Delete a value from storage cache.
36
+ *
37
+ * @param {string} key - Cache key
38
+ */
39
+ delete(key: string): Promise<void>;
40
+ /**
41
+ * Clear all entries from storage cache.
42
+ */
43
+ clear(): Promise<void>;
44
+ /**
45
+ * Invalidate entries matching a pattern.
46
+ *
47
+ * @param {string} pattern - Regex pattern to match keys
48
+ */
49
+ invalidate(pattern: string): Promise<void>;
50
+ /**
51
+ * Check if an entry is expired.
52
+ *
53
+ * @private
54
+ * @param {CacheEntry} entry - Cache entry
55
+ * @returns {boolean} True if expired
56
+ */
57
+ private isExpired;
58
+ }
@@ -0,0 +1,111 @@
1
+ import { HttpClient } from './http-client';
2
+ import { ApiResponse, RequestOptions } from './types';
3
+ import { CacheManager } from './cache/cache-manager';
4
+ /**
5
+ * Full configuration data returned by the API.
6
+ * @template T - The shape of the configuration values (defaults to Record<string, unknown>)
7
+ */
8
+ export interface ConfigData<T = Record<string, unknown>> {
9
+ readonly name: string;
10
+ readonly description?: string;
11
+ readonly values: Readonly<T>;
12
+ readonly version: number;
13
+ readonly keys: readonly string[];
14
+ readonly createdAt: Date;
15
+ readonly updatedAt?: Date;
16
+ }
17
+ /**
18
+ * Configuration API class for interacting with DinoConfig configurations.
19
+ *
20
+ * This class provides methods to retrieve configuration values from the
21
+ * DinoConfig API. It handles request formatting, error handling, response
22
+ * parsing, and caching automatically.
23
+ *
24
+ * @class ConfigAPI
25
+ * @example
26
+ * ```typescript
27
+ * const dinoconfig = await dinoconfigApi({ apiKey: 'dino_...' });
28
+ *
29
+ * // Get entire config
30
+ * const config = await dinoconfig.configs.get('MyBrand', 'AppSettings');
31
+ * console.log('All values:', config.data.values);
32
+ *
33
+ * // Get single value (shorthand)
34
+ * const theme = await dinoconfig.configs.getValue('MyBrand.AppSettings.theme');
35
+ * console.log('Theme:', theme.data);
36
+ * ```
37
+ */
38
+ export declare class ConfigAPI {
39
+ private readonly httpClient;
40
+ private readonly cacheManager?;
41
+ constructor(httpClient: HttpClient, cacheManager?: CacheManager | undefined);
42
+ /**
43
+ * Retrieves an entire configuration with all its values.
44
+ *
45
+ * @template T - The shape of the configuration values for type safety
46
+ * @example
47
+ * ```typescript
48
+ * // Shorthand: get('Brand.Config')
49
+ * const config = await dinoconfig.configs.get('Acme.AppSettings');
50
+ *
51
+ * // Full params: get(brand, config)
52
+ * const config = await dinoconfig.configs.get('Acme', 'AppSettings');
53
+ * console.log(config.data.values);
54
+ *
55
+ * // With generated types for full type safety
56
+ * import { DinoConfig } from './types/dinoconfig';
57
+ * const config = await dinoconfig.configs.get<DinoConfig.Acme.AppSettings>('Acme', 'AppSettings');
58
+ * config.data.values.theme; // fully typed!
59
+ * ```
60
+ */
61
+ get<T = Record<string, unknown>>(path: string, options?: RequestOptions): Promise<ApiResponse<ConfigData<T>>>;
62
+ get<T = Record<string, unknown>>(brandName: string, configName: string, options?: RequestOptions): Promise<ApiResponse<ConfigData<T>>>;
63
+ /**
64
+ * Retrieves a specific configuration value from DinoConfig.
65
+ *
66
+ * @template T - The expected type of the value for type safety
67
+ * @example
68
+ * ```typescript
69
+ * // Shorthand: getValue('Brand.Config.Key')
70
+ * const response = await dinoconfig.configs.getValue('Acme.AppSettings.theme');
71
+ *
72
+ * // Full params: getValue(brand, config, key)
73
+ * const response = await dinoconfig.configs.getValue('Acme', 'AppSettings', 'theme');
74
+ * console.log('Theme:', response.data);
75
+ *
76
+ * // With type parameter for type safety
77
+ * const theme = await dinoconfig.configs.getValue<string>('Acme', 'AppSettings', 'theme');
78
+ * const maxUsers = await dinoconfig.configs.getValue<number>('Acme', 'AppSettings', 'maxUsers');
79
+ * ```
80
+ */
81
+ getValue<T = unknown>(path: string, options?: RequestOptions): Promise<ApiResponse<T>>;
82
+ getValue<T = unknown>(brandName: string, configName: string, keyName: string, options?: RequestOptions): Promise<ApiResponse<T>>;
83
+ /**
84
+ * Parses arguments for the get() method.
85
+ */
86
+ private parseConfigArgs;
87
+ /**
88
+ * Parses arguments for the getValue() method.
89
+ */
90
+ private parseValueArgs;
91
+ /**
92
+ * Parses a dot-notation path into components.
93
+ */
94
+ private parsePath;
95
+ /**
96
+ * Builds the URL for fetching an entire config.
97
+ */
98
+ private buildConfigUrl;
99
+ /**
100
+ * Builds the URL for fetching a single value.
101
+ */
102
+ private buildValueUrl;
103
+ /**
104
+ * URL-encodes a path segment.
105
+ */
106
+ private encode;
107
+ /**
108
+ * Transforms the backend response to the public ConfigData shape.
109
+ */
110
+ private transformConfigResponse;
111
+ }
@@ -0,0 +1,140 @@
1
+ import { ConfigAPI } from './config-api';
2
+ import { DiscoveryAPI } from './discovery-api';
3
+ import { DinoConfigSDKConfig } from './types';
4
+ import { CacheStats } from './cache/cache.types';
5
+ /**
6
+ * Cache API interface.
7
+ */
8
+ export interface CacheAPI {
9
+ /**
10
+ * Get a value from cache.
11
+ */
12
+ get<T>(key: string): Promise<T | null>;
13
+ /**
14
+ * Set a value in cache.
15
+ */
16
+ set<T>(key: string, value: T, options?: {
17
+ ttl?: number;
18
+ }): Promise<void>;
19
+ /**
20
+ * Delete a value from cache.
21
+ */
22
+ delete(key: string): Promise<void>;
23
+ /**
24
+ * Clear all cache entries.
25
+ */
26
+ clear(): Promise<void>;
27
+ /**
28
+ * Invalidate entries matching a pattern.
29
+ */
30
+ invalidate(pattern?: string): Promise<void>;
31
+ /**
32
+ * Prefetch a value into cache.
33
+ */
34
+ prefetch<T>(key: string, fetcher: () => Promise<T>): Promise<T>;
35
+ /**
36
+ * Get cache statistics.
37
+ */
38
+ getStats(): CacheStats;
39
+ }
40
+ /**
41
+ * DinoConfig SDK instance interface.
42
+ * Provides access to all SDK APIs through a unified interface.
43
+ *
44
+ * @interface DinoConfigInstance
45
+ * @property {ConfigAPI} configs - API for retrieving configuration values
46
+ * @property {DiscoveryAPI} discovery - API for discovering brands, configs, and schemas
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const dinoconfig = await dinoconfigApi({ apiKey: 'dino_...' });
51
+ *
52
+ * // Get entire config
53
+ * const config = await dinoconfig.configs.get('Brand.Config');
54
+ *
55
+ * // Get single value
56
+ * const value = await dinoconfig.configs.getValue('Brand.Config.Key');
57
+ *
58
+ * // Discovery
59
+ * const brands = await dinoconfig.discovery.listBrands();
60
+ *
61
+ * // Cache management
62
+ * await dinoconfig.cache.invalidate('brand:.*');
63
+ * ```
64
+ */
65
+ export interface DinoConfigInstance {
66
+ /**
67
+ * Configuration API for retrieving config values.
68
+ *
69
+ * Methods:
70
+ * - `get(path)` or `get(brand, config)` - Get entire config
71
+ * - `getValue(path)` or `getValue(brand, config, key)` - Get single value
72
+ *
73
+ * @see {@link ConfigAPI}
74
+ */
75
+ configs: ConfigAPI;
76
+ /**
77
+ * Discovery API for exploring available brands, configs, and schemas.
78
+ *
79
+ * Methods:
80
+ * - `listBrands()` - List all accessible brands
81
+ * - `listConfigs(brand)` - List configs for a brand
82
+ * - `getSchema(brand, config)` - Get config schema
83
+ * - `introspect()` - Full introspection of all data
84
+ *
85
+ * @see {@link DiscoveryAPI}
86
+ */
87
+ discovery: DiscoveryAPI;
88
+ /**
89
+ * Cache API for managing the cache layer.
90
+ *
91
+ * @see {@link CacheAPI}
92
+ */
93
+ cache: CacheAPI;
94
+ }
95
+ /**
96
+ * Creates and initializes a new DinoConfig SDK instance.
97
+ *
98
+ * This is the main entry point for using the DinoConfig SDK.
99
+ *
100
+ * @async
101
+ * @function dinoconfigApi
102
+ * @param {DinoConfigSDKConfig} config - Configuration options
103
+ * @param {string} config.apiKey - Your DinoConfig API key
104
+ * @param {string} [config.baseUrl='http://localhost:3000'] - API base URL
105
+ * @param {number} [config.timeout=10000] - Request timeout in milliseconds
106
+ * @returns {Promise<DinoConfigInstance>} Initialized SDK instance
107
+ * @throws {Error} If API key exchange fails or network error occurs
108
+ *
109
+ * @example Basic usage
110
+ * ```typescript
111
+ * import { dinoconfigApi } from '@dinoconfig/dinoconfig-js-sdk';
112
+ *
113
+ * const dinoconfig = await dinoconfigApi({
114
+ * apiKey: 'dino_your-api-key-here'
115
+ * });
116
+ *
117
+ * // Get config value
118
+ * const response = await dinoconfig.configs.getValue('Brand.Config.Key');
119
+ * console.log(response.data);
120
+ * ```
121
+ *
122
+ * @example With all options
123
+ * ```typescript
124
+ * const dinoconfig = await dinoconfigApi({
125
+ * apiKey: process.env.DINOCONFIG_API_KEY!,
126
+ * baseUrl: 'https://api.dinoconfig.com',
127
+ * timeout: 15000
128
+ * });
129
+ * ```
130
+ *
131
+ * @example Error handling
132
+ * ```typescript
133
+ * try {
134
+ * const dinoconfig = await dinoconfigApi({ apiKey: '...' });
135
+ * } catch (error) {
136
+ * console.error('Failed to initialize:', error);
137
+ * }
138
+ * ```
139
+ */
140
+ export declare function dinoconfigApi(config: DinoConfigSDKConfig): Promise<DinoConfigInstance>;