@angular-libs/signal-storage 0.2.0-beta.1 → 0.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/README.md
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
# @angular-libs/signal-storage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[Docs @angular-libs/signal-storage](https://www.npmjs.com/package/@angular-libs/signal-storage)
|
|
4
|
+
|
|
5
|
+
[StackBlitz demo](https://stackblitz.com/edit/signal-storage?file=src%2Fmain.ts)
|
|
6
|
+
|
|
7
|
+
`npm install @angular-libs/signal-storage`
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
A lightweight, type-safe Angular library for reactive state management using Signals. It provides seamless syncing with **localStorage**, **sessionStorage**, **IndexedDB** (via Angular Resources), and **In-Memory** storage.
|
|
6
10
|
|
|
7
11
|
---
|
|
8
12
|
|
|
9
|
-
##
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### 💾 1. `SignalStorage` service
|
|
16
|
+
|
|
17
|
+
Perfect for lightweight, synchronous key-value storage.
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
Supports:
|
|
20
|
+
|
|
21
|
+
- `localStorage` (default)
|
|
22
|
+
- `sessionStorage`
|
|
23
|
+
- `MemoryStorage` (similar to NgRx SignalStore)
|
|
24
|
+
- Custom
|
|
12
25
|
|
|
13
26
|
```typescript
|
|
14
27
|
import { Component, inject } from '@angular/core';
|
|
@@ -23,7 +36,7 @@ interface AppState {
|
|
|
23
36
|
template: `<button (click)="toggle()">{{ theme() }}</button>`,
|
|
24
37
|
})
|
|
25
38
|
export class AppComponent {
|
|
26
|
-
private storage = inject(SignalStorage
|
|
39
|
+
private storage: SignalStorage<AppState> = inject(SignalStorage);
|
|
27
40
|
theme = this.storage.getSignal('theme', 'light');
|
|
28
41
|
|
|
29
42
|
toggle() {
|
|
@@ -32,37 +45,43 @@ export class AppComponent {
|
|
|
32
45
|
}
|
|
33
46
|
```
|
|
34
47
|
|
|
35
|
-
|
|
48
|
+
#### Changing the Sync Storage Provider
|
|
36
49
|
|
|
37
|
-
You can switch to `sessionStorage
|
|
50
|
+
You can switch to `sessionStorage`, `MemoryStorage` or custom via providers:
|
|
38
51
|
|
|
39
52
|
```typescript
|
|
40
|
-
import {
|
|
53
|
+
import { SIGNAL_STORAGE_CONFIG, MemoryStorage } from '@angular-libs/signal-storage';
|
|
41
54
|
|
|
42
55
|
// In app.config.ts
|
|
43
56
|
providers: [
|
|
44
|
-
// For
|
|
45
|
-
{
|
|
57
|
+
// For Pure Memory Storage:
|
|
58
|
+
{
|
|
59
|
+
provide: SIGNAL_STORAGE_CONFIG,
|
|
60
|
+
useValue: { storageFactory: () => new MemoryStorage() },
|
|
61
|
+
},
|
|
46
62
|
|
|
47
|
-
//
|
|
48
|
-
{
|
|
63
|
+
// For Session Storage:
|
|
64
|
+
{
|
|
65
|
+
provide: SIGNAL_STORAGE_CONFIG,
|
|
66
|
+
useValue: { storageFactory: () => window.sessionStorage },
|
|
67
|
+
},
|
|
49
68
|
];
|
|
50
69
|
```
|
|
51
70
|
|
|
52
71
|
---
|
|
53
72
|
|
|
54
|
-
|
|
73
|
+
### 💾 2. Async `SignalIndexedDB` service (IndexedDB + Angular Resources)
|
|
55
74
|
|
|
56
75
|
Ideal for larger amounts of data. It uses Angular's new `resource` API and supports automatic cross-tab synchronization.
|
|
57
76
|
|
|
58
77
|
**1. Provide the storage:**
|
|
59
78
|
|
|
60
79
|
```typescript
|
|
61
|
-
import {
|
|
80
|
+
import { provideSignalIndexedDB } from '@angular-libs/signal-storage';
|
|
62
81
|
|
|
63
82
|
// In app.config.ts
|
|
64
83
|
providers: [
|
|
65
|
-
|
|
84
|
+
provideSignalIndexedDB({ dbName: 'MyAppDb' }), // config is optional
|
|
66
85
|
];
|
|
67
86
|
```
|
|
68
87
|
|
|
@@ -70,7 +89,7 @@ providers: [
|
|
|
70
89
|
|
|
71
90
|
```typescript
|
|
72
91
|
import { Component, inject } from '@angular/core';
|
|
73
|
-
import {
|
|
92
|
+
import { SignalIndexedDB } from '@angular-libs/signal-storage';
|
|
74
93
|
|
|
75
94
|
interface AppData {
|
|
76
95
|
user: { name: string };
|
|
@@ -87,7 +106,7 @@ interface AppData {
|
|
|
87
106
|
`,
|
|
88
107
|
})
|
|
89
108
|
export class ProfileComponent {
|
|
90
|
-
private db = inject(
|
|
109
|
+
private db: SignalIndexedDB<AppData> = inject(SignalIndexedDB);
|
|
91
110
|
|
|
92
111
|
// Automatically fetches from IndexedDB as a ResourceRef
|
|
93
112
|
profile = this.db.getResource('user');
|
|
@@ -100,25 +119,23 @@ export class ProfileComponent {
|
|
|
100
119
|
|
|
101
120
|
---
|
|
102
121
|
|
|
103
|
-
|
|
122
|
+
### 🛠 3. Advanced: Multiple Storage Instances
|
|
104
123
|
|
|
105
124
|
Need `localStorage` AND `MemoryStorage` in the same app? Extend the base class:
|
|
106
125
|
|
|
107
126
|
```typescript
|
|
108
|
-
import { Injectable } from '@angular/core';
|
|
109
|
-
import { SignalStorage,
|
|
127
|
+
import { Injectable, inject, Injector } from '@angular/core';
|
|
128
|
+
import { MemoryStorage, SignalStorage, SignalIndexedDB } from '@angular-libs/signal-storage';
|
|
110
129
|
|
|
130
|
+
// Store 1
|
|
111
131
|
interface LocalState {
|
|
112
132
|
user: string;
|
|
113
133
|
}
|
|
114
134
|
|
|
115
135
|
@Injectable({ providedIn: 'root' })
|
|
116
|
-
export class LocalStore extends SignalStorage<LocalState> {
|
|
117
|
-
constructor() {
|
|
118
|
-
super(typeof window !== 'undefined' ? window.localStorage : new MemoryStorage());
|
|
119
|
-
}
|
|
120
|
-
}
|
|
136
|
+
export class LocalStore extends SignalStorage<LocalState> {}
|
|
121
137
|
|
|
138
|
+
// Store 2
|
|
122
139
|
interface TempState {
|
|
123
140
|
tempId: string;
|
|
124
141
|
}
|
|
@@ -126,38 +143,21 @@ interface TempState {
|
|
|
126
143
|
@Injectable({ providedIn: 'root' })
|
|
127
144
|
export class TempStore extends SignalStorage<TempState> {
|
|
128
145
|
constructor() {
|
|
129
|
-
super(new MemoryStorage());
|
|
146
|
+
super({ storageFactory: () => new MemoryStorage() });
|
|
130
147
|
}
|
|
131
148
|
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
The same applies for `SignalIndexedDb` if you need multiple different databases:
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
import { Injectable, Injector, inject } from '@angular/core';
|
|
138
|
-
import { SignalIndexedDb } from '@angular-libs/signal-storage';
|
|
139
149
|
|
|
150
|
+
// Store 3
|
|
140
151
|
interface UserDbState {
|
|
141
152
|
user: { name: string; email: string };
|
|
142
153
|
}
|
|
143
154
|
|
|
144
155
|
@Injectable({ providedIn: 'root' })
|
|
145
|
-
export class UserDb extends
|
|
156
|
+
export class UserDb extends SignalIndexedDB<UserDbState> {
|
|
146
157
|
constructor() {
|
|
147
158
|
super(inject(Injector), { dbName: 'UserDb', storeName: 'keyValue', version: 1 });
|
|
148
159
|
}
|
|
149
160
|
}
|
|
150
|
-
|
|
151
|
-
interface SettingsDbState {
|
|
152
|
-
settings: { theme: 'light' | 'dark' };
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
@Injectable({ providedIn: 'root' })
|
|
156
|
-
export class SettingsDb extends SignalIndexedDb<SettingsDbState> {
|
|
157
|
-
constructor() {
|
|
158
|
-
super(inject(Injector), { dbName: 'SettingsDb', storeName: 'keyValue', version: 1 });
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
---
|
|
@@ -240,14 +240,14 @@ const SIGNAL_INDEXEDDB_CONFIG = new InjectionToken('SIGNAL_INDEXEDDB_CONFIG', {
|
|
|
240
240
|
providedIn: 'root',
|
|
241
241
|
factory: () => DEFAULT_CONFIG,
|
|
242
242
|
});
|
|
243
|
-
function
|
|
243
|
+
function provideSignalIndexedDB(config) {
|
|
244
244
|
return [
|
|
245
245
|
{
|
|
246
246
|
provide: SIGNAL_INDEXEDDB_CONFIG,
|
|
247
247
|
useValue: { ...DEFAULT_CONFIG, ...config },
|
|
248
248
|
},
|
|
249
249
|
// Explicitly provide the storage instance here!
|
|
250
|
-
|
|
250
|
+
SignalIndexedDB,
|
|
251
251
|
];
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
@@ -256,7 +256,7 @@ function provideSignalIndexedDb(config) {
|
|
|
256
256
|
* Additionally, it automatically coordinates resource state changes across multiple browser tabs via BroadcastChannel.
|
|
257
257
|
*
|
|
258
258
|
* Define a strict type for the storage keys and values using the generic parameter `T`.
|
|
259
|
-
* You can configure the DB name, store name, and version using the `
|
|
259
|
+
* You can configure the DB name, store name, and version using the `provideSignalIndexedDB` provider function.
|
|
260
260
|
*
|
|
261
261
|
* @typeParam T - An interface defining the expected shape of the IndexedDB data.
|
|
262
262
|
*
|
|
@@ -270,7 +270,7 @@ function provideSignalIndexedDb(config) {
|
|
|
270
270
|
*
|
|
271
271
|
* // 2. Create a typed service
|
|
272
272
|
* @Injectable({ providedIn: 'root' })
|
|
273
|
-
* export class AppStateDb extends
|
|
273
|
+
* export class AppStateDb extends SignalIndexedDB<AppState> {}
|
|
274
274
|
*
|
|
275
275
|
* @Component({ ... })
|
|
276
276
|
* export class MyComponent {
|
|
@@ -293,7 +293,7 @@ function provideSignalIndexedDb(config) {
|
|
|
293
293
|
* }
|
|
294
294
|
* ```
|
|
295
295
|
*/
|
|
296
|
-
class
|
|
296
|
+
class SignalIndexedDB {
|
|
297
297
|
injector;
|
|
298
298
|
config;
|
|
299
299
|
dbPromise;
|
|
@@ -533,10 +533,10 @@ class SignalIndexedDb {
|
|
|
533
533
|
this.broadcastChannel.close();
|
|
534
534
|
}
|
|
535
535
|
}
|
|
536
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
537
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
536
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SignalIndexedDB, deps: [{ token: i0.Injector }, { token: SIGNAL_INDEXEDDB_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
537
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SignalIndexedDB });
|
|
538
538
|
}
|
|
539
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
539
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SignalIndexedDB, decorators: [{
|
|
540
540
|
type: Injectable
|
|
541
541
|
}], ctorParameters: () => [{ type: i0.Injector }, { type: undefined, decorators: [{
|
|
542
542
|
type: Optional
|
|
@@ -553,5 +553,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
553
553
|
* Generated bundle index. Do not edit.
|
|
554
554
|
*/
|
|
555
555
|
|
|
556
|
-
export { MemoryStorage, SIGNAL_INDEXEDDB_CONFIG, SIGNAL_STORAGE_CONFIG,
|
|
556
|
+
export { MemoryStorage, SIGNAL_INDEXEDDB_CONFIG, SIGNAL_STORAGE_CONFIG, SignalIndexedDB, SignalStorage, provideSignalIndexedDB, provideSignalStorage };
|
|
557
557
|
//# sourceMappingURL=angular-libs-signal-storage.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-libs-signal-storage.mjs","sources":["../../../../projects/angular-libs/signal-storage/src/lib/signal-storage.ts","../../../../projects/angular-libs/signal-storage/src/lib/signal-indexeddb.ts","../../../../projects/angular-libs/signal-storage/src/public-api.ts","../../../../projects/angular-libs/signal-storage/src/angular-libs-signal-storage.ts"],"sourcesContent":["import {\n signal,\n WritableSignal,\n Signal,\n Injectable,\n InjectionToken,\n Optional,\n Inject,\n} from '@angular/core';\n\nexport interface SignalStorageConfig {\n /** The channel name for BroadcastChannel sync. Default: `signal-storage-sync` */\n syncChannel: string;\n /**\n * A factory returning the Storage to use (e.g., `() => sessionStorage`).\n * Defaults to `() => localStorage` (or MemoryStorage in SSR environments).\n */\n storageFactory: () => Storage;\n}\n\nconst DEFAULT_CONFIG: SignalStorageConfig = {\n syncChannel: 'signal-storage-sync',\n storageFactory: () => (typeof window !== 'undefined' ? window.localStorage : new MemoryStorage()),\n};\n\nexport const SIGNAL_STORAGE_CONFIG = new InjectionToken<SignalStorageConfig>(\n 'SIGNAL_STORAGE_CONFIG',\n {\n providedIn: 'root',\n factory: () => DEFAULT_CONFIG,\n },\n);\n\nexport function provideSignalStorage(config?: Partial<SignalStorageConfig>) {\n return [\n {\n provide: SIGNAL_STORAGE_CONFIG,\n useValue: { ...DEFAULT_CONFIG, ...config },\n },\n SignalStorage,\n ];\n}\n\ntype SyncMessage<T> =\n | { action: 'set'; key: keyof T; value: any }\n | { action: 'remove'; key: keyof T }\n | { action: 'clear' };\n\n/**\n * A strongly-typed, reactive storage solution powered by Angular Signals.\n * It natively supports `localStorage`, `sessionStorage`, `MemoryStorage`, or any custom storage mechanism.\n * Additionally, it automatically coordinates signal state changes across multiple browser tabs via BroadcastChannel.\n *\n * Define a strict type for the storage keys and values using the generic parameter `T`.\n * You can configure the storage mechanism and sync channel using the `provideSignalStorage` provider function,\n * or by passing a configuration object directly via `useFactory` when extending the class.\n *\n * @typeParam T - An interface defining the expected shape of the storage data.\n *\n * @example\n * ```typescript\n * // 1. Define your storage shape\n * interface AppState {\n * theme: 'light' | 'dark';\n * metrics: { visits: number };\n * }\n *\n * // 2. Create a typed service\n * @Injectable({ providedIn: 'root' })\n * export class AppStateStorage extends SignalStorage<AppState> {}\n *\n * @Component({ ... })\n * export class MyComponent {\n * // 3. Inject the typed service\n * private storage = inject(AppStateStorage);\n *\n * // Reactive: A readonly Signal that auto-updates\n * readonly theme = this.storage.getSignal('theme', 'light');\n *\n * constructor() {\n * // Static: Get the current value statically (no reactivity)\n * const rawTheme = this.storage.get('theme', 'light');\n *\n * // Mutate: Sets value in memory, updates the signal, and persists to storage\n * this.storage.set('theme', 'dark');\n * }\n *\n * toggleTheme() {\n * // Mutate safely via callback\n * this.storage.update('theme', current => current === 'light' ? 'dark' : 'light');\n * }\n * }\n * ```\n */\n@Injectable()\nexport class SignalStorage<T extends Record<string, any> = {}> {\n private storage: Storage;\n private signals = new Map<keyof T, WritableSignal<any>>();\n private defaultValues = new Map<keyof T, any>();\n private channel?: BroadcastChannel;\n\n /**\n * Create a new SignalStorage instance\n * @param config The configuration for the storage and synchronization.\n */\n constructor(@Optional() @Inject(SIGNAL_STORAGE_CONFIG) config?: Partial<SignalStorageConfig>) {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n this.storage = mergedConfig.storageFactory();\n const { syncChannel } = mergedConfig;\n\n if (typeof window !== 'undefined') {\n // Seamless BroadcastChannel cross-tab sync (for ANY storage type)\n if (typeof BroadcastChannel !== 'undefined') {\n this.channel = new BroadcastChannel(syncChannel);\n this.channel.onmessage = (event: MessageEvent<SyncMessage<T>>) => {\n const data = event.data;\n\n switch (data.action) {\n case 'set':\n if (data.key) {\n this.set(data.key, data.value, false);\n }\n break;\n case 'remove':\n if (data.key) {\n this.remove(data.key, false);\n }\n break;\n case 'clear':\n this.clear(false);\n break;\n }\n };\n }\n }\n }\n /**\n * Get typed data from SignalStorage\n * @param key The key to retrieve\n * @returns The typed data or null if not found\n */\n get<K extends keyof T>(key: K): T[K] | null;\n /**\n * Get typed data from SignalStorage with a default value\n * @param key The key to retrieve\n * @param defaultValue The default value to return if key not found\n * @returns The stored data or the default value\n */\n get<K extends keyof T>(key: K, defaultValue: T[K]): T[K];\n get<K extends keyof T>(key: K, defaultValue?: T[K]): T[K] | null {\n const item = this.storage.getItem(key as string);\n if (item === null) {\n return defaultValue ?? null;\n }\n try {\n return JSON.parse(item) as T[K];\n } catch {\n return defaultValue ?? null;\n }\n }\n\n /**\n * Get a reactive Angular signal for a key\n * @param key The key to retrieve\n * @param defaultValue The default value to return if key not found\n * @returns A read-only Signal containing the stored data\n */\n getSignal<K extends keyof T>(key: K): Signal<T[K] | null>;\n getSignal<K extends keyof T>(key: K, defaultValue: T[K]): Signal<T[K]>;\n getSignal<K extends keyof T>(key: K, defaultValue?: T[K]): Signal<any> {\n if (!this.signals.has(key)) {\n if (defaultValue !== undefined) {\n this.defaultValues.set(key, defaultValue);\n }\n const initialValue = this.get(key, defaultValue as T[K]);\n this.signals.set(key, signal(initialValue));\n }\n return this.signals.get(key)!.asReadonly();\n }\n\n /**\n * Set typed data in localStorage\n * @param key The key to set\n * @param value The value to store\n * @param broadcast Whether to broadcast to other tabs\n */\n set<K extends keyof T>(key: K, value: T[K], broadcast = true): void {\n try {\n this.storage.setItem(key as string, JSON.stringify(value));\n } catch (e) {\n console.error(\n `Error saving to storage for key \"${String(key)}\". Storage quota may be exceeded.`,\n e,\n );\n }\n if (this.signals.has(key)) {\n this.signals.get(key)!.set(value);\n }\n if (broadcast) {\n this.channel?.postMessage({ action: 'set', key, value });\n }\n }\n\n /**\n * Update typed data based on current value using a callback\n * @param key The key to update\n * @param updateFn Callback function that receives the current value and returns the new value\n */\n update<K extends keyof T>(key: K, updateFn: (currentValue: T[K] | null) => T[K]): void {\n const fallback = this.defaultValues.get(key);\n const currentValue = fallback !== undefined ? this.get(key, fallback) : this.get(key);\n const newValue = updateFn(currentValue);\n this.set(key, newValue);\n }\n\n /**\n * Remove an item from localStorage\n * @param key The key to remove\n * @param broadcast Whether to broadcast the removal to other tabs\n */\n remove<K extends keyof T>(key: K, broadcast = true): void {\n this.storage.removeItem(key as string);\n if (this.signals.has(key)) {\n const def = this.defaultValues.get(key);\n this.signals.get(key)!.set(def !== undefined ? def : null);\n }\n if (broadcast) {\n this.channel?.postMessage({ action: 'remove', key });\n }\n }\n\n /**\n * Check if a key exists in localStorage\n * @param key The key to check\n * @returns true if the key exists, false otherwise\n */\n has<K extends keyof T>(key: K): boolean {\n return this.storage.getItem(key as string) !== null;\n }\n\n /**\n * Clear all localStorage\n * @param broadcast Whether to broadcast the clear to other tabs\n */\n clear(broadcast = true): void {\n this.storage.clear();\n for (const [key, sig] of this.signals.entries()) {\n const def = this.defaultValues.get(key);\n sig.set(def !== undefined ? def : null);\n }\n if (broadcast) {\n this.channel?.postMessage({ action: 'clear' });\n }\n }\n}\n\n/**\n * An in-memory implementation of the Storage interface.\n * Can be provided to SIGNAL_STORAGE_TOKEN to use SignalStorage for purely in-memory app state.\n */\nexport class MemoryStorage implements Storage {\n private data = new Map<string, string>();\n\n get length(): number {\n return this.data.size;\n }\n\n clear(): void {\n this.data.clear();\n }\n\n getItem(key: string): string | null {\n const value = this.data.get(key);\n return value === undefined ? null : value;\n }\n\n removeItem(key: string): void {\n this.data.delete(key);\n }\n\n setItem(key: string, value: string): void {\n this.data.set(key, String(value));\n }\n\n key(index: number): string | null {\n const keys = Array.from(this.data.keys());\n return keys[index] === undefined ? null : keys[index];\n }\n}\n","import {\n Injectable,\n InjectionToken,\n Injector,\n Optional,\n Inject,\n resource,\n ResourceRef,\n OnDestroy,\n} from '@angular/core';\n\nexport interface SignalIndexedDbConfig {\n /** Default: `SignalStorageDb` */\n dbName: string;\n /** Default: `keyValue` */\n storeName: string;\n /** Default: `1` */\n version: number;\n}\n\nconst DEFAULT_CONFIG: SignalIndexedDbConfig = {\n dbName: 'SignalStorageDb',\n storeName: 'keyValue',\n version: 1,\n};\n\nexport const SIGNAL_INDEXEDDB_CONFIG = new InjectionToken<SignalIndexedDbConfig>(\n 'SIGNAL_INDEXEDDB_CONFIG',\n {\n providedIn: 'root',\n factory: () => DEFAULT_CONFIG,\n },\n);\n\nexport function provideSignalIndexedDb(config?: Partial<SignalIndexedDbConfig>) {\n return [\n {\n provide: SIGNAL_INDEXEDDB_CONFIG,\n useValue: { ...DEFAULT_CONFIG, ...config },\n },\n // Explicitly provide the storage instance here!\n SignalIndexedDb,\n ];\n}\n\ntype SyncMessage<T> =\n | { action: 'set'; key: keyof T; value: any }\n | { action: 'remove'; key: keyof T }\n | { action: 'clear' };\n\n/**\n * A strongly-typed, reactive, asynchronous storage solution powered by Angular's `resource` API and IndexedDB.\n * It gracefully falls back to an in-memory map if IndexedDB is not supported (e.g. server-side rendering).\n * Additionally, it automatically coordinates resource state changes across multiple browser tabs via BroadcastChannel.\n *\n * Define a strict type for the storage keys and values using the generic parameter `T`.\n * You can configure the DB name, store name, and version using the `provideSignalIndexedDb` provider function.\n *\n * @typeParam T - An interface defining the expected shape of the IndexedDB data.\n *\n * @example\n * ```typescript\n * // 1. Define your storage shape\n * interface AppState {\n * theme: 'light' | 'dark';\n * metrics: { visits: number };\n * }\n *\n * // 2. Create a typed service\n * @Injectable({ providedIn: 'root' })\n * export class AppStateDb extends SignalIndexedDb<AppState> {}\n *\n * @Component({ ... })\n * export class MyComponent {\n * // 3. Inject the typed service\n * private db = inject(AppStateDb);\n *\n * // Reactive: Angular Resource containing the async IndexedDB data\n * readonly themeResource = this.db.getResource('theme', 'light');\n *\n * async toggleTheme() {\n * // Static: Get the current value asynchronously (no reactivity)\n * const rawTheme = await this.db.get('theme');\n *\n * // Mutate: Sets value, updates the resource, and persists to IndexedDB\n * await this.db.set('theme', 'dark');\n *\n * // Mutate safely via callback\n * await this.db.update('theme', current => current === 'light' ? 'dark' : 'light');\n * }\n * }\n * ```\n */\n@Injectable()\nexport class SignalIndexedDb<T extends Record<string, any> = {}> implements OnDestroy {\n private config: SignalIndexedDbConfig;\n private dbPromise: Promise<IDBDatabase | null>;\n private fallbackStorage = new Map<string, any>();\n private defaultValues = new Map<keyof T, any>();\n private isFallback = false;\n\n private resources = new Map<keyof T, ResourceRef<any>>();\n private broadcastChannel?: BroadcastChannel;\n\n constructor(\n private injector: Injector,\n @Optional() @Inject(SIGNAL_INDEXEDDB_CONFIG) config?: SignalIndexedDbConfig,\n ) {\n this.config = { ...DEFAULT_CONFIG, ...(config || {}) };\n this.dbPromise = this.initDB().catch((err) => {\n console.warn('IndexedDB initialization failed. Falling back to in-memory storage.', err);\n this.isFallback = true;\n return null;\n });\n\n if (typeof window !== 'undefined' && typeof BroadcastChannel !== 'undefined') {\n try {\n this.broadcastChannel = new BroadcastChannel(\n `${this.config.dbName}-${this.config.storeName}-sync`,\n );\n this.broadcastChannel.onmessage = (event: MessageEvent<SyncMessage<T>>) => {\n const data = event.data;\n\n if (data.action === 'clear') {\n if (this.isFallback) this.fallbackStorage.clear();\n this.resources.forEach((res, k) => res.value.set(this.defaultValues.get(k)));\n } else if (data.action === 'remove' && data.key) {\n if (this.isFallback) this.fallbackStorage.delete(data.key as string);\n this.resources.get(data.key)?.value.set(this.defaultValues.get(data.key));\n } else if (data.action === 'set' && data.key) {\n if (this.isFallback) this.fallbackStorage.set(data.key as string, data.value);\n this.resources.get(data.key)?.value.set(data.value);\n }\n };\n } catch {\n // Ignore broadcast channel errors inside environments that do not fully support it\n }\n }\n }\n\n private initDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n if (typeof window === 'undefined' || !window.indexedDB) {\n return reject('IndexedDB is not supported');\n }\n\n const request = indexedDB.open(this.config.dbName, this.config.version);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.config.storeName)) {\n reject(new Error(`ObjectStore '${this.config.storeName}' not found in IndexedDB.`));\n } else {\n resolve(db);\n }\n };\n\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n const db = (event.target as IDBOpenDBRequest).result;\n if (!db.objectStoreNames.contains(this.config.storeName)) {\n db.createObjectStore(this.config.storeName);\n }\n };\n });\n }\n\n /**\n * Retrieves an Angular `ResourceRef` for a specific key.\n * The resource will asynchronously load the initial value from IndexedDB.\n * Calling `set()` or `update()` on this key later will automatically update this resource's signal.\n *\n * @param key The strongly-typed key to retrieve.\n * @returns A `ResourceRef` containing the value (or undefined if not found).\n */\n getResource<K extends keyof T>(key: K): ResourceRef<T[K] | undefined>;\n getResource<K extends keyof T>(key: K, defaultValue: T[K]): ResourceRef<T[K]>;\n getResource<K extends keyof T>(key: K, defaultValue?: T[K]): ResourceRef<any> {\n if (defaultValue !== undefined && !this.defaultValues.has(key)) {\n this.defaultValues.set(key, defaultValue);\n }\n if (!this.resources.has(key)) {\n const dbResource = resource({\n defaultValue,\n loader: async () => {\n const val = await this.get(key);\n return val !== undefined ? val : this.defaultValues.get(key);\n },\n injector: this.injector,\n });\n\n this.resources.set(key, dbResource);\n }\n\n return this.resources.get(key)!;\n }\n\n /**\n * Retrieves data asynchronously from IndexedDB without creating a reactive dependency.\n * Useful for one-off reads where a Signal/Resource is not needed.\n *\n * @param key The strongly-typed key to retrieve.\n * @returns A promise resolving to the stored value, or undefined if it does not exist.\n */\n async get<K extends keyof T>(key: K): Promise<T[K] | undefined> {\n if (this.isFallback) return this.fallbackStorage.get(key as string);\n\n const db = await this.dbPromise;\n if (!db) return this.fallbackStorage.get(key as string);\n\n return new Promise((resolve, reject) => {\n try {\n const transaction = db.transaction(this.config.storeName, 'readonly');\n const store = transaction.objectStore(this.config.storeName);\n const request = store.get(key as string);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result);\n } catch (e) {\n reject(e);\n }\n });\n }\n\n /**\n * Sets data asynchronously in IndexedDB.\n * This is a reactive operation: it will automatically update any Angular `ResourceRef`\n * observing this key and broadcast the change to other open browser tabs.\n *\n * @param key The strongly-typed key to set.\n * @param value The value to store.\n */\n async set<K extends keyof T>(key: K, value: T[K]): Promise<void> {\n if (value === undefined) {\n return this.remove(key);\n }\n\n const db = await this.dbPromise;\n if (this.isFallback || !db) {\n this.fallbackStorage.set(key as string, value);\n } else {\n await new Promise<void>((resolve, reject) => {\n try {\n const request = db\n .transaction(this.config.storeName, 'readwrite')\n .objectStore(this.config.storeName)\n .put(value, key as string);\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve();\n } catch (e) {\n reject(e);\n }\n });\n }\n\n this.resources.get(key)?.value.set(value);\n this.broadcastChannel?.postMessage({ action: 'set', key, value });\n }\n\n /**\n * Safely updates a value based on its previous state.\n * Useful when deriving the next value directly from the old value.\n *\n * @param key The strongly-typed key to update.\n * @param updater A callback function that receives the current value and returns the new value.\n */\n async update<K extends keyof T>(\n key: K,\n updater: (current: T[K] | undefined) => T[K],\n ): Promise<void> {\n const current = await this.get(key);\n const newValue = updater(current);\n await this.set(key, newValue);\n }\n\n /**\n * Removes a key asynchronously from IndexedDB.\n * This operation will update the local state to undefined for the given key.\n *\n * @param key The strongly-typed key to remove.\n */\n async remove<K extends keyof T>(key: K): Promise<void> {\n const db = await this.dbPromise;\n if (this.isFallback || !db) {\n this.fallbackStorage.delete(key as string);\n } else {\n await new Promise<void>((resolve, reject) => {\n try {\n const request = db\n .transaction(this.config.storeName, 'readwrite')\n .objectStore(this.config.storeName)\n .delete(key as string);\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve();\n } catch (e) {\n reject(e);\n }\n });\n }\n\n this.resources.get(key)?.value.set(this.defaultValues.get(key));\n this.broadcastChannel?.postMessage({ action: 'remove', key });\n }\n\n /**\n * Clears the entire object store in IndexedDB.\n * This operation will reset all active resource signals to undefined.\n */\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n if (this.isFallback || !db) {\n this.fallbackStorage.clear();\n } else {\n await new Promise<void>((resolve, reject) => {\n try {\n const request = db\n .transaction(this.config.storeName, 'readwrite')\n .objectStore(this.config.storeName)\n .clear();\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve();\n } catch (e) {\n reject(e);\n }\n });\n }\n\n this.resources.forEach((res, k) => res.value.set(this.defaultValues.get(k)));\n this.broadcastChannel?.postMessage({ action: 'clear' });\n }\n\n /**\n * Gets all keys currently stored in the object store.\n *\n * @returns A promise resolving to an array of stored keys.\n */\n async keys(): Promise<string[]> {\n if (this.isFallback) return Array.from(this.fallbackStorage.keys());\n\n const db = await this.dbPromise;\n if (!db) return Array.from(this.fallbackStorage.keys());\n\n return new Promise((resolve, reject) => {\n try {\n const transaction = db.transaction(this.config.storeName, 'readonly');\n const store = transaction.objectStore(this.config.storeName);\n const request = store.getAllKeys();\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result as string[]);\n } catch (e) {\n reject(e);\n }\n });\n }\n\n ngOnDestroy(): void {\n if (this.broadcastChannel) {\n this.broadcastChannel.close();\n }\n }\n}\n","/*\n * Public API Surface of signal-storage\n */\n\nexport * from './lib/signal-storage';\nexport * from './lib/signal-indexeddb';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["DEFAULT_CONFIG"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"angular-libs-signal-storage.mjs","sources":["../../../../projects/angular-libs/signal-storage/src/lib/signal-storage.ts","../../../../projects/angular-libs/signal-storage/src/lib/signal-indexeddb.ts","../../../../projects/angular-libs/signal-storage/src/public-api.ts","../../../../projects/angular-libs/signal-storage/src/angular-libs-signal-storage.ts"],"sourcesContent":["import {\n signal,\n WritableSignal,\n Signal,\n Injectable,\n InjectionToken,\n Optional,\n Inject,\n} from '@angular/core';\n\nexport interface SignalStorageConfig {\n /** The channel name for BroadcastChannel sync. Default: `signal-storage-sync` */\n syncChannel: string;\n /**\n * A factory returning the Storage to use (e.g., `() => sessionStorage`).\n * Defaults to `() => localStorage` (or MemoryStorage in SSR environments).\n */\n storageFactory: () => Storage;\n}\n\nconst DEFAULT_CONFIG: SignalStorageConfig = {\n syncChannel: 'signal-storage-sync',\n storageFactory: () => (typeof window !== 'undefined' ? window.localStorage : new MemoryStorage()),\n};\n\nexport const SIGNAL_STORAGE_CONFIG = new InjectionToken<SignalStorageConfig>(\n 'SIGNAL_STORAGE_CONFIG',\n {\n providedIn: 'root',\n factory: () => DEFAULT_CONFIG,\n },\n);\n\nexport function provideSignalStorage(config?: Partial<SignalStorageConfig>) {\n return [\n {\n provide: SIGNAL_STORAGE_CONFIG,\n useValue: { ...DEFAULT_CONFIG, ...config },\n },\n SignalStorage,\n ];\n}\n\ntype SyncMessage<T> =\n | { action: 'set'; key: keyof T; value: any }\n | { action: 'remove'; key: keyof T }\n | { action: 'clear' };\n\n/**\n * A strongly-typed, reactive storage solution powered by Angular Signals.\n * It natively supports `localStorage`, `sessionStorage`, `MemoryStorage`, or any custom storage mechanism.\n * Additionally, it automatically coordinates signal state changes across multiple browser tabs via BroadcastChannel.\n *\n * Define a strict type for the storage keys and values using the generic parameter `T`.\n * You can configure the storage mechanism and sync channel using the `provideSignalStorage` provider function,\n * or by passing a configuration object directly via `useFactory` when extending the class.\n *\n * @typeParam T - An interface defining the expected shape of the storage data.\n *\n * @example\n * ```typescript\n * // 1. Define your storage shape\n * interface AppState {\n * theme: 'light' | 'dark';\n * metrics: { visits: number };\n * }\n *\n * // 2. Create a typed service\n * @Injectable({ providedIn: 'root' })\n * export class AppStateStorage extends SignalStorage<AppState> {}\n *\n * @Component({ ... })\n * export class MyComponent {\n * // 3. Inject the typed service\n * private storage = inject(AppStateStorage);\n *\n * // Reactive: A readonly Signal that auto-updates\n * readonly theme = this.storage.getSignal('theme', 'light');\n *\n * constructor() {\n * // Static: Get the current value statically (no reactivity)\n * const rawTheme = this.storage.get('theme', 'light');\n *\n * // Mutate: Sets value in memory, updates the signal, and persists to storage\n * this.storage.set('theme', 'dark');\n * }\n *\n * toggleTheme() {\n * // Mutate safely via callback\n * this.storage.update('theme', current => current === 'light' ? 'dark' : 'light');\n * }\n * }\n * ```\n */\n@Injectable()\nexport class SignalStorage<T extends Record<string, any> = {}> {\n private storage: Storage;\n private signals = new Map<keyof T, WritableSignal<any>>();\n private defaultValues = new Map<keyof T, any>();\n private channel?: BroadcastChannel;\n\n /**\n * Create a new SignalStorage instance\n * @param config The configuration for the storage and synchronization.\n */\n constructor(@Optional() @Inject(SIGNAL_STORAGE_CONFIG) config?: Partial<SignalStorageConfig>) {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config };\n this.storage = mergedConfig.storageFactory();\n const { syncChannel } = mergedConfig;\n\n if (typeof window !== 'undefined') {\n // Seamless BroadcastChannel cross-tab sync (for ANY storage type)\n if (typeof BroadcastChannel !== 'undefined') {\n this.channel = new BroadcastChannel(syncChannel);\n this.channel.onmessage = (event: MessageEvent<SyncMessage<T>>) => {\n const data = event.data;\n\n switch (data.action) {\n case 'set':\n if (data.key) {\n this.set(data.key, data.value, false);\n }\n break;\n case 'remove':\n if (data.key) {\n this.remove(data.key, false);\n }\n break;\n case 'clear':\n this.clear(false);\n break;\n }\n };\n }\n }\n }\n /**\n * Get typed data from SignalStorage\n * @param key The key to retrieve\n * @returns The typed data or null if not found\n */\n get<K extends keyof T>(key: K): T[K] | null;\n /**\n * Get typed data from SignalStorage with a default value\n * @param key The key to retrieve\n * @param defaultValue The default value to return if key not found\n * @returns The stored data or the default value\n */\n get<K extends keyof T>(key: K, defaultValue: T[K]): T[K];\n get<K extends keyof T>(key: K, defaultValue?: T[K]): T[K] | null {\n const item = this.storage.getItem(key as string);\n if (item === null) {\n return defaultValue ?? null;\n }\n try {\n return JSON.parse(item) as T[K];\n } catch {\n return defaultValue ?? null;\n }\n }\n\n /**\n * Get a reactive Angular signal for a key\n * @param key The key to retrieve\n * @param defaultValue The default value to return if key not found\n * @returns A read-only Signal containing the stored data\n */\n getSignal<K extends keyof T>(key: K): Signal<T[K] | null>;\n getSignal<K extends keyof T>(key: K, defaultValue: T[K]): Signal<T[K]>;\n getSignal<K extends keyof T>(key: K, defaultValue?: T[K]): Signal<any> {\n if (!this.signals.has(key)) {\n if (defaultValue !== undefined) {\n this.defaultValues.set(key, defaultValue);\n }\n const initialValue = this.get(key, defaultValue as T[K]);\n this.signals.set(key, signal(initialValue));\n }\n return this.signals.get(key)!.asReadonly();\n }\n\n /**\n * Set typed data in localStorage\n * @param key The key to set\n * @param value The value to store\n * @param broadcast Whether to broadcast to other tabs\n */\n set<K extends keyof T>(key: K, value: T[K], broadcast = true): void {\n try {\n this.storage.setItem(key as string, JSON.stringify(value));\n } catch (e) {\n console.error(\n `Error saving to storage for key \"${String(key)}\". Storage quota may be exceeded.`,\n e,\n );\n }\n if (this.signals.has(key)) {\n this.signals.get(key)!.set(value);\n }\n if (broadcast) {\n this.channel?.postMessage({ action: 'set', key, value });\n }\n }\n\n /**\n * Update typed data based on current value using a callback\n * @param key The key to update\n * @param updateFn Callback function that receives the current value and returns the new value\n */\n update<K extends keyof T>(key: K, updateFn: (currentValue: T[K] | null) => T[K]): void {\n const fallback = this.defaultValues.get(key);\n const currentValue = fallback !== undefined ? this.get(key, fallback) : this.get(key);\n const newValue = updateFn(currentValue);\n this.set(key, newValue);\n }\n\n /**\n * Remove an item from localStorage\n * @param key The key to remove\n * @param broadcast Whether to broadcast the removal to other tabs\n */\n remove<K extends keyof T>(key: K, broadcast = true): void {\n this.storage.removeItem(key as string);\n if (this.signals.has(key)) {\n const def = this.defaultValues.get(key);\n this.signals.get(key)!.set(def !== undefined ? def : null);\n }\n if (broadcast) {\n this.channel?.postMessage({ action: 'remove', key });\n }\n }\n\n /**\n * Check if a key exists in localStorage\n * @param key The key to check\n * @returns true if the key exists, false otherwise\n */\n has<K extends keyof T>(key: K): boolean {\n return this.storage.getItem(key as string) !== null;\n }\n\n /**\n * Clear all localStorage\n * @param broadcast Whether to broadcast the clear to other tabs\n */\n clear(broadcast = true): void {\n this.storage.clear();\n for (const [key, sig] of this.signals.entries()) {\n const def = this.defaultValues.get(key);\n sig.set(def !== undefined ? def : null);\n }\n if (broadcast) {\n this.channel?.postMessage({ action: 'clear' });\n }\n }\n}\n\n/**\n * An in-memory implementation of the Storage interface.\n * Can be provided to SIGNAL_STORAGE_TOKEN to use SignalStorage for purely in-memory app state.\n */\nexport class MemoryStorage implements Storage {\n private data = new Map<string, string>();\n\n get length(): number {\n return this.data.size;\n }\n\n clear(): void {\n this.data.clear();\n }\n\n getItem(key: string): string | null {\n const value = this.data.get(key);\n return value === undefined ? null : value;\n }\n\n removeItem(key: string): void {\n this.data.delete(key);\n }\n\n setItem(key: string, value: string): void {\n this.data.set(key, String(value));\n }\n\n key(index: number): string | null {\n const keys = Array.from(this.data.keys());\n return keys[index] === undefined ? null : keys[index];\n }\n}\n","import {\n Injectable,\n InjectionToken,\n Injector,\n Optional,\n Inject,\n resource,\n ResourceRef,\n OnDestroy,\n} from '@angular/core';\n\nexport interface SignalIndexedDBConfig {\n /** Default: `SignalStorageDb` */\n dbName: string;\n /** Default: `keyValue` */\n storeName: string;\n /** Default: `1` */\n version: number;\n}\n\nconst DEFAULT_CONFIG: SignalIndexedDBConfig = {\n dbName: 'SignalStorageDb',\n storeName: 'keyValue',\n version: 1,\n};\n\nexport const SIGNAL_INDEXEDDB_CONFIG = new InjectionToken<SignalIndexedDBConfig>(\n 'SIGNAL_INDEXEDDB_CONFIG',\n {\n providedIn: 'root',\n factory: () => DEFAULT_CONFIG,\n },\n);\n\nexport function provideSignalIndexedDB(config?: Partial<SignalIndexedDBConfig>) {\n return [\n {\n provide: SIGNAL_INDEXEDDB_CONFIG,\n useValue: { ...DEFAULT_CONFIG, ...config },\n },\n // Explicitly provide the storage instance here!\n SignalIndexedDB,\n ];\n}\n\ntype SyncMessage<T> =\n | { action: 'set'; key: keyof T; value: any }\n | { action: 'remove'; key: keyof T }\n | { action: 'clear' };\n\n/**\n * A strongly-typed, reactive, asynchronous storage solution powered by Angular's `resource` API and IndexedDB.\n * It gracefully falls back to an in-memory map if IndexedDB is not supported (e.g. server-side rendering).\n * Additionally, it automatically coordinates resource state changes across multiple browser tabs via BroadcastChannel.\n *\n * Define a strict type for the storage keys and values using the generic parameter `T`.\n * You can configure the DB name, store name, and version using the `provideSignalIndexedDB` provider function.\n *\n * @typeParam T - An interface defining the expected shape of the IndexedDB data.\n *\n * @example\n * ```typescript\n * // 1. Define your storage shape\n * interface AppState {\n * theme: 'light' | 'dark';\n * metrics: { visits: number };\n * }\n *\n * // 2. Create a typed service\n * @Injectable({ providedIn: 'root' })\n * export class AppStateDb extends SignalIndexedDB<AppState> {}\n *\n * @Component({ ... })\n * export class MyComponent {\n * // 3. Inject the typed service\n * private db = inject(AppStateDb);\n *\n * // Reactive: Angular Resource containing the async IndexedDB data\n * readonly themeResource = this.db.getResource('theme', 'light');\n *\n * async toggleTheme() {\n * // Static: Get the current value asynchronously (no reactivity)\n * const rawTheme = await this.db.get('theme');\n *\n * // Mutate: Sets value, updates the resource, and persists to IndexedDB\n * await this.db.set('theme', 'dark');\n *\n * // Mutate safely via callback\n * await this.db.update('theme', current => current === 'light' ? 'dark' : 'light');\n * }\n * }\n * ```\n */\n@Injectable()\nexport class SignalIndexedDB<T extends Record<string, any> = {}> implements OnDestroy {\n private config: SignalIndexedDBConfig;\n private dbPromise: Promise<IDBDatabase | null>;\n private fallbackStorage = new Map<string, any>();\n private defaultValues = new Map<keyof T, any>();\n private isFallback = false;\n\n private resources = new Map<keyof T, ResourceRef<any>>();\n private broadcastChannel?: BroadcastChannel;\n\n constructor(\n private injector: Injector,\n @Optional() @Inject(SIGNAL_INDEXEDDB_CONFIG) config?: SignalIndexedDBConfig,\n ) {\n this.config = { ...DEFAULT_CONFIG, ...(config || {}) };\n this.dbPromise = this.initDB().catch((err) => {\n console.warn('IndexedDB initialization failed. Falling back to in-memory storage.', err);\n this.isFallback = true;\n return null;\n });\n\n if (typeof window !== 'undefined' && typeof BroadcastChannel !== 'undefined') {\n try {\n this.broadcastChannel = new BroadcastChannel(\n `${this.config.dbName}-${this.config.storeName}-sync`,\n );\n this.broadcastChannel.onmessage = (event: MessageEvent<SyncMessage<T>>) => {\n const data = event.data;\n\n if (data.action === 'clear') {\n if (this.isFallback) this.fallbackStorage.clear();\n this.resources.forEach((res, k) => res.value.set(this.defaultValues.get(k)));\n } else if (data.action === 'remove' && data.key) {\n if (this.isFallback) this.fallbackStorage.delete(data.key as string);\n this.resources.get(data.key)?.value.set(this.defaultValues.get(data.key));\n } else if (data.action === 'set' && data.key) {\n if (this.isFallback) this.fallbackStorage.set(data.key as string, data.value);\n this.resources.get(data.key)?.value.set(data.value);\n }\n };\n } catch {\n // Ignore broadcast channel errors inside environments that do not fully support it\n }\n }\n }\n\n private initDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n if (typeof window === 'undefined' || !window.indexedDB) {\n return reject('IndexedDB is not supported');\n }\n\n const request = indexedDB.open(this.config.dbName, this.config.version);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.config.storeName)) {\n reject(new Error(`ObjectStore '${this.config.storeName}' not found in IndexedDB.`));\n } else {\n resolve(db);\n }\n };\n\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n const db = (event.target as IDBOpenDBRequest).result;\n if (!db.objectStoreNames.contains(this.config.storeName)) {\n db.createObjectStore(this.config.storeName);\n }\n };\n });\n }\n\n /**\n * Retrieves an Angular `ResourceRef` for a specific key.\n * The resource will asynchronously load the initial value from IndexedDB.\n * Calling `set()` or `update()` on this key later will automatically update this resource's signal.\n *\n * @param key The strongly-typed key to retrieve.\n * @returns A `ResourceRef` containing the value (or undefined if not found).\n */\n getResource<K extends keyof T>(key: K): ResourceRef<T[K] | undefined>;\n getResource<K extends keyof T>(key: K, defaultValue: T[K]): ResourceRef<T[K]>;\n getResource<K extends keyof T>(key: K, defaultValue?: T[K]): ResourceRef<any> {\n if (defaultValue !== undefined && !this.defaultValues.has(key)) {\n this.defaultValues.set(key, defaultValue);\n }\n if (!this.resources.has(key)) {\n const dbResource = resource({\n defaultValue,\n loader: async () => {\n const val = await this.get(key);\n return val !== undefined ? val : this.defaultValues.get(key);\n },\n injector: this.injector,\n });\n\n this.resources.set(key, dbResource);\n }\n\n return this.resources.get(key)!;\n }\n\n /**\n * Retrieves data asynchronously from IndexedDB without creating a reactive dependency.\n * Useful for one-off reads where a Signal/Resource is not needed.\n *\n * @param key The strongly-typed key to retrieve.\n * @returns A promise resolving to the stored value, or undefined if it does not exist.\n */\n async get<K extends keyof T>(key: K): Promise<T[K] | undefined> {\n if (this.isFallback) return this.fallbackStorage.get(key as string);\n\n const db = await this.dbPromise;\n if (!db) return this.fallbackStorage.get(key as string);\n\n return new Promise((resolve, reject) => {\n try {\n const transaction = db.transaction(this.config.storeName, 'readonly');\n const store = transaction.objectStore(this.config.storeName);\n const request = store.get(key as string);\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result);\n } catch (e) {\n reject(e);\n }\n });\n }\n\n /**\n * Sets data asynchronously in IndexedDB.\n * This is a reactive operation: it will automatically update any Angular `ResourceRef`\n * observing this key and broadcast the change to other open browser tabs.\n *\n * @param key The strongly-typed key to set.\n * @param value The value to store.\n */\n async set<K extends keyof T>(key: K, value: T[K]): Promise<void> {\n if (value === undefined) {\n return this.remove(key);\n }\n\n const db = await this.dbPromise;\n if (this.isFallback || !db) {\n this.fallbackStorage.set(key as string, value);\n } else {\n await new Promise<void>((resolve, reject) => {\n try {\n const request = db\n .transaction(this.config.storeName, 'readwrite')\n .objectStore(this.config.storeName)\n .put(value, key as string);\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve();\n } catch (e) {\n reject(e);\n }\n });\n }\n\n this.resources.get(key)?.value.set(value);\n this.broadcastChannel?.postMessage({ action: 'set', key, value });\n }\n\n /**\n * Safely updates a value based on its previous state.\n * Useful when deriving the next value directly from the old value.\n *\n * @param key The strongly-typed key to update.\n * @param updater A callback function that receives the current value and returns the new value.\n */\n async update<K extends keyof T>(\n key: K,\n updater: (current: T[K] | undefined) => T[K],\n ): Promise<void> {\n const current = await this.get(key);\n const newValue = updater(current);\n await this.set(key, newValue);\n }\n\n /**\n * Removes a key asynchronously from IndexedDB.\n * This operation will update the local state to undefined for the given key.\n *\n * @param key The strongly-typed key to remove.\n */\n async remove<K extends keyof T>(key: K): Promise<void> {\n const db = await this.dbPromise;\n if (this.isFallback || !db) {\n this.fallbackStorage.delete(key as string);\n } else {\n await new Promise<void>((resolve, reject) => {\n try {\n const request = db\n .transaction(this.config.storeName, 'readwrite')\n .objectStore(this.config.storeName)\n .delete(key as string);\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve();\n } catch (e) {\n reject(e);\n }\n });\n }\n\n this.resources.get(key)?.value.set(this.defaultValues.get(key));\n this.broadcastChannel?.postMessage({ action: 'remove', key });\n }\n\n /**\n * Clears the entire object store in IndexedDB.\n * This operation will reset all active resource signals to undefined.\n */\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n if (this.isFallback || !db) {\n this.fallbackStorage.clear();\n } else {\n await new Promise<void>((resolve, reject) => {\n try {\n const request = db\n .transaction(this.config.storeName, 'readwrite')\n .objectStore(this.config.storeName)\n .clear();\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve();\n } catch (e) {\n reject(e);\n }\n });\n }\n\n this.resources.forEach((res, k) => res.value.set(this.defaultValues.get(k)));\n this.broadcastChannel?.postMessage({ action: 'clear' });\n }\n\n /**\n * Gets all keys currently stored in the object store.\n *\n * @returns A promise resolving to an array of stored keys.\n */\n async keys(): Promise<string[]> {\n if (this.isFallback) return Array.from(this.fallbackStorage.keys());\n\n const db = await this.dbPromise;\n if (!db) return Array.from(this.fallbackStorage.keys());\n\n return new Promise((resolve, reject) => {\n try {\n const transaction = db.transaction(this.config.storeName, 'readonly');\n const store = transaction.objectStore(this.config.storeName);\n const request = store.getAllKeys();\n\n request.onerror = () => reject(request.error);\n request.onsuccess = () => resolve(request.result as string[]);\n } catch (e) {\n reject(e);\n }\n });\n }\n\n ngOnDestroy(): void {\n if (this.broadcastChannel) {\n this.broadcastChannel.close();\n }\n }\n}\n","/*\n * Public API Surface of signal-storage\n */\n\nexport * from './lib/signal-storage';\nexport * from './lib/signal-indexeddb';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["DEFAULT_CONFIG"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -142,7 +142,7 @@ declare class MemoryStorage implements Storage {
|
|
|
142
142
|
key(index: number): string | null;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
interface
|
|
145
|
+
interface SignalIndexedDBConfig {
|
|
146
146
|
/** Default: `SignalStorageDb` */
|
|
147
147
|
dbName: string;
|
|
148
148
|
/** Default: `keyValue` */
|
|
@@ -150,9 +150,9 @@ interface SignalIndexedDbConfig {
|
|
|
150
150
|
/** Default: `1` */
|
|
151
151
|
version: number;
|
|
152
152
|
}
|
|
153
|
-
declare const SIGNAL_INDEXEDDB_CONFIG: InjectionToken<
|
|
154
|
-
declare function
|
|
155
|
-
provide: InjectionToken<
|
|
153
|
+
declare const SIGNAL_INDEXEDDB_CONFIG: InjectionToken<SignalIndexedDBConfig>;
|
|
154
|
+
declare function provideSignalIndexedDB(config?: Partial<SignalIndexedDBConfig>): (typeof SignalIndexedDB | {
|
|
155
|
+
provide: InjectionToken<SignalIndexedDBConfig>;
|
|
156
156
|
useValue: {
|
|
157
157
|
dbName: string;
|
|
158
158
|
storeName: string;
|
|
@@ -165,7 +165,7 @@ declare function provideSignalIndexedDb(config?: Partial<SignalIndexedDbConfig>)
|
|
|
165
165
|
* Additionally, it automatically coordinates resource state changes across multiple browser tabs via BroadcastChannel.
|
|
166
166
|
*
|
|
167
167
|
* Define a strict type for the storage keys and values using the generic parameter `T`.
|
|
168
|
-
* You can configure the DB name, store name, and version using the `
|
|
168
|
+
* You can configure the DB name, store name, and version using the `provideSignalIndexedDB` provider function.
|
|
169
169
|
*
|
|
170
170
|
* @typeParam T - An interface defining the expected shape of the IndexedDB data.
|
|
171
171
|
*
|
|
@@ -179,7 +179,7 @@ declare function provideSignalIndexedDb(config?: Partial<SignalIndexedDbConfig>)
|
|
|
179
179
|
*
|
|
180
180
|
* // 2. Create a typed service
|
|
181
181
|
* @Injectable({ providedIn: 'root' })
|
|
182
|
-
* export class AppStateDb extends
|
|
182
|
+
* export class AppStateDb extends SignalIndexedDB<AppState> {}
|
|
183
183
|
*
|
|
184
184
|
* @Component({ ... })
|
|
185
185
|
* export class MyComponent {
|
|
@@ -202,7 +202,7 @@ declare function provideSignalIndexedDb(config?: Partial<SignalIndexedDbConfig>)
|
|
|
202
202
|
* }
|
|
203
203
|
* ```
|
|
204
204
|
*/
|
|
205
|
-
declare class
|
|
205
|
+
declare class SignalIndexedDB<T extends Record<string, any> = {}> implements OnDestroy {
|
|
206
206
|
private injector;
|
|
207
207
|
private config;
|
|
208
208
|
private dbPromise;
|
|
@@ -211,7 +211,7 @@ declare class SignalIndexedDb<T extends Record<string, any> = {}> implements OnD
|
|
|
211
211
|
private isFallback;
|
|
212
212
|
private resources;
|
|
213
213
|
private broadcastChannel?;
|
|
214
|
-
constructor(injector: Injector, config?:
|
|
214
|
+
constructor(injector: Injector, config?: SignalIndexedDBConfig);
|
|
215
215
|
private initDB;
|
|
216
216
|
/**
|
|
217
217
|
* Retrieves an Angular `ResourceRef` for a specific key.
|
|
@@ -267,9 +267,9 @@ declare class SignalIndexedDb<T extends Record<string, any> = {}> implements OnD
|
|
|
267
267
|
*/
|
|
268
268
|
keys(): Promise<string[]>;
|
|
269
269
|
ngOnDestroy(): void;
|
|
270
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<
|
|
271
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<
|
|
270
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SignalIndexedDB<any>, [null, { optional: true; }]>;
|
|
271
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SignalIndexedDB<any>>;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
export { MemoryStorage, SIGNAL_INDEXEDDB_CONFIG, SIGNAL_STORAGE_CONFIG,
|
|
275
|
-
export type {
|
|
274
|
+
export { MemoryStorage, SIGNAL_INDEXEDDB_CONFIG, SIGNAL_STORAGE_CONFIG, SignalIndexedDB, SignalStorage, provideSignalIndexedDB, provideSignalStorage };
|
|
275
|
+
export type { SignalIndexedDBConfig, SignalStorageConfig };
|