strata-storage 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.
- package/Readme.md +113 -0
- package/android/src/main/java/com/strata/storage/EncryptedStorage.java +65 -0
- package/android/src/main/java/com/strata/storage/SQLiteStorage.java +147 -0
- package/android/src/main/java/com/strata/storage/SharedPreferencesStorage.java +74 -0
- package/android/src/main/java/com/stratastorage/StrataStoragePlugin.java +256 -0
- package/dist/adapters/capacitor/FilesystemAdapter.d.ts +46 -0
- package/dist/adapters/capacitor/FilesystemAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/FilesystemAdapter.js +162 -0
- package/dist/adapters/capacitor/PreferencesAdapter.d.ts +46 -0
- package/dist/adapters/capacitor/PreferencesAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/PreferencesAdapter.js +162 -0
- package/dist/adapters/capacitor/SecureAdapter.d.ts +69 -0
- package/dist/adapters/capacitor/SecureAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/SecureAdapter.js +214 -0
- package/dist/adapters/capacitor/SqliteAdapter.d.ts +68 -0
- package/dist/adapters/capacitor/SqliteAdapter.d.ts.map +1 -0
- package/dist/adapters/capacitor/SqliteAdapter.js +277 -0
- package/dist/adapters/capacitor/index.d.ts +9 -0
- package/dist/adapters/capacitor/index.d.ts.map +1 -0
- package/dist/adapters/capacitor/index.js +8 -0
- package/dist/adapters/web/CacheAdapter.d.ts +91 -0
- package/dist/adapters/web/CacheAdapter.d.ts.map +1 -0
- package/dist/adapters/web/CacheAdapter.js +291 -0
- package/dist/adapters/web/CookieAdapter.d.ts +77 -0
- package/dist/adapters/web/CookieAdapter.d.ts.map +1 -0
- package/dist/adapters/web/CookieAdapter.js +260 -0
- package/dist/adapters/web/IndexedDBAdapter.d.ts +78 -0
- package/dist/adapters/web/IndexedDBAdapter.d.ts.map +1 -0
- package/dist/adapters/web/IndexedDBAdapter.js +371 -0
- package/dist/adapters/web/LocalStorageAdapter.d.ts +63 -0
- package/dist/adapters/web/LocalStorageAdapter.d.ts.map +1 -0
- package/dist/adapters/web/LocalStorageAdapter.js +238 -0
- package/dist/adapters/web/MemoryAdapter.d.ts +69 -0
- package/dist/adapters/web/MemoryAdapter.d.ts.map +1 -0
- package/dist/adapters/web/MemoryAdapter.js +165 -0
- package/dist/adapters/web/SessionStorageAdapter.d.ts +53 -0
- package/dist/adapters/web/SessionStorageAdapter.d.ts.map +1 -0
- package/dist/adapters/web/SessionStorageAdapter.js +180 -0
- package/dist/adapters/web/index.d.ts +10 -0
- package/dist/adapters/web/index.d.ts.map +1 -0
- package/dist/adapters/web/index.js +9 -0
- package/dist/core/AdapterRegistry.d.ts +52 -0
- package/dist/core/AdapterRegistry.d.ts.map +1 -0
- package/dist/core/AdapterRegistry.js +102 -0
- package/dist/core/BaseAdapter.d.ts +79 -0
- package/dist/core/BaseAdapter.d.ts.map +1 -0
- package/dist/core/BaseAdapter.js +197 -0
- package/dist/core/StorageStrategy.d.ts +55 -0
- package/dist/core/StorageStrategy.d.ts.map +1 -0
- package/dist/core/StorageStrategy.js +199 -0
- package/dist/core/Strata.d.ts +122 -0
- package/dist/core/Strata.d.ts.map +1 -0
- package/dist/core/Strata.js +568 -0
- package/dist/features/compression.d.ts +65 -0
- package/dist/features/compression.d.ts.map +1 -0
- package/dist/features/compression.js +205 -0
- package/dist/features/encryption.d.ts +68 -0
- package/dist/features/encryption.d.ts.map +1 -0
- package/dist/features/encryption.js +172 -0
- package/dist/features/migration.d.ts +17 -0
- package/dist/features/migration.d.ts.map +1 -0
- package/dist/features/migration.js +43 -0
- package/dist/features/query.d.ts +75 -0
- package/dist/features/query.d.ts.map +1 -0
- package/dist/features/query.js +305 -0
- package/dist/features/sync.d.ts +87 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +233 -0
- package/dist/features/ttl.d.ts +124 -0
- package/dist/features/ttl.d.ts.map +1 -0
- package/dist/features/ttl.js +236 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/package.json +60 -0
- package/dist/plugin/definitions.d.ts +219 -0
- package/dist/plugin/definitions.d.ts.map +1 -0
- package/dist/plugin/definitions.js +5 -0
- package/dist/plugin/index.d.ts +8 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +27 -0
- package/dist/plugin/web.d.ts +24 -0
- package/dist/plugin/web.d.ts.map +1 -0
- package/dist/plugin/web.js +35 -0
- package/dist/types/index.d.ts +558 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/utils/errors.d.ts +92 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +153 -0
- package/dist/utils/index.d.ts +105 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +329 -0
- package/ios/Plugin/KeychainStorage.swift +87 -0
- package/ios/Plugin/SQLiteStorage.swift +167 -0
- package/ios/Plugin/StrataStoragePlugin.swift +204 -0
- package/ios/Plugin/UserDefaultsStorage.swift +44 -0
- package/package.json +126 -0
- package/scripts/build.js +52 -0
- package/scripts/cli.js +60 -0
- package/scripts/configure.js +444 -0
- package/scripts/postinstall.js +33 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Adapter - In-memory storage implementation
|
|
3
|
+
* Provides fast, non-persistent storage using Map
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import type { StorageType, StorageCapabilities, StorageValue, ClearOptions, QueryCondition } from '@/types';
|
|
7
|
+
/**
|
|
8
|
+
* In-memory storage adapter using Map
|
|
9
|
+
*/
|
|
10
|
+
export declare class MemoryAdapter extends BaseAdapter {
|
|
11
|
+
readonly name: StorageType;
|
|
12
|
+
readonly capabilities: StorageCapabilities;
|
|
13
|
+
private storage;
|
|
14
|
+
private maxSize?;
|
|
15
|
+
private currentSize;
|
|
16
|
+
/**
|
|
17
|
+
* Check if adapter is available (always true for memory)
|
|
18
|
+
*/
|
|
19
|
+
isAvailable(): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize the adapter
|
|
22
|
+
*/
|
|
23
|
+
initialize(config?: {
|
|
24
|
+
maxSize?: number;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Get a value from memory
|
|
28
|
+
*/
|
|
29
|
+
get<T = unknown>(key: string): Promise<StorageValue<T> | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Set a value in memory
|
|
32
|
+
*/
|
|
33
|
+
set<T = unknown>(key: string, value: StorageValue<T>): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Remove a value from memory
|
|
36
|
+
*/
|
|
37
|
+
remove(key: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Clear memory storage
|
|
40
|
+
*/
|
|
41
|
+
clear(options?: ClearOptions): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Check if key exists
|
|
44
|
+
*/
|
|
45
|
+
has(key: string): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Get all keys
|
|
48
|
+
*/
|
|
49
|
+
keys(pattern?: string | RegExp): Promise<string[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Query implementation for memory adapter
|
|
52
|
+
*/
|
|
53
|
+
query<T = unknown>(condition: QueryCondition): Promise<Array<{
|
|
54
|
+
key: string;
|
|
55
|
+
value: T;
|
|
56
|
+
}>>;
|
|
57
|
+
/**
|
|
58
|
+
* Get current memory usage
|
|
59
|
+
*/
|
|
60
|
+
getMemoryUsage(): {
|
|
61
|
+
used: number;
|
|
62
|
+
limit?: number;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Close the adapter
|
|
66
|
+
*/
|
|
67
|
+
close(): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=MemoryAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/MemoryAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,cAAc,EACf,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAY;IACtC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAUxC;IAEF,OAAO,CAAC,OAAO,CAAwC;IACvD,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,WAAW,CAAK;IAExB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC;;OAEG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9D;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAepE;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B1E;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxC;;OAEG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAalD;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC;;OAEG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBxD;;OAEG;IACG,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAe9F;;OAEG;IACH,cAAc,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAOlD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Adapter - In-memory storage implementation
|
|
3
|
+
* Provides fast, non-persistent storage using Map
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '@/core/BaseAdapter';
|
|
6
|
+
import { deepClone } from '@/utils';
|
|
7
|
+
/**
|
|
8
|
+
* In-memory storage adapter using Map
|
|
9
|
+
*/
|
|
10
|
+
export class MemoryAdapter extends BaseAdapter {
|
|
11
|
+
name = 'memory';
|
|
12
|
+
capabilities = {
|
|
13
|
+
persistent: false,
|
|
14
|
+
synchronous: false, // We use async for consistency
|
|
15
|
+
observable: true,
|
|
16
|
+
transactional: false,
|
|
17
|
+
queryable: true,
|
|
18
|
+
maxSize: -1, // No hard limit, but configurable
|
|
19
|
+
binary: true,
|
|
20
|
+
encrypted: false, // Encryption handled by feature layer
|
|
21
|
+
crossTab: false, // Memory is per-instance
|
|
22
|
+
};
|
|
23
|
+
storage = new Map();
|
|
24
|
+
maxSize;
|
|
25
|
+
currentSize = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Check if adapter is available (always true for memory)
|
|
28
|
+
*/
|
|
29
|
+
async isAvailable() {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Initialize the adapter
|
|
34
|
+
*/
|
|
35
|
+
async initialize(config) {
|
|
36
|
+
this.maxSize = config?.maxSize;
|
|
37
|
+
this.startTTLCleanup();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get a value from memory
|
|
41
|
+
*/
|
|
42
|
+
async get(key) {
|
|
43
|
+
const value = this.storage.get(key);
|
|
44
|
+
if (!value)
|
|
45
|
+
return null;
|
|
46
|
+
// Check TTL
|
|
47
|
+
if (this.isExpired(value)) {
|
|
48
|
+
await this.remove(key);
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
// Return a deep clone to prevent external modifications
|
|
52
|
+
return deepClone(value);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Set a value in memory
|
|
56
|
+
*/
|
|
57
|
+
async set(key, value) {
|
|
58
|
+
const oldValue = this.storage.get(key);
|
|
59
|
+
const newSize = this.calculateSize(value);
|
|
60
|
+
// Check size limit if configured
|
|
61
|
+
if (this.maxSize && this.maxSize > 0) {
|
|
62
|
+
const oldSize = oldValue ? this.calculateSize(oldValue) : 0;
|
|
63
|
+
const projectedSize = this.currentSize - oldSize + newSize;
|
|
64
|
+
if (projectedSize > this.maxSize) {
|
|
65
|
+
throw new Error(`Memory storage size limit exceeded. Limit: ${this.maxSize}, Projected: ${projectedSize}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Store a deep clone to prevent external modifications
|
|
69
|
+
const clonedValue = deepClone(value);
|
|
70
|
+
this.storage.set(key, clonedValue);
|
|
71
|
+
// Update size tracking
|
|
72
|
+
if (oldValue) {
|
|
73
|
+
this.currentSize -= this.calculateSize(oldValue);
|
|
74
|
+
}
|
|
75
|
+
this.currentSize += newSize;
|
|
76
|
+
// Emit change event
|
|
77
|
+
this.emitChange(key, oldValue?.value, value.value, 'local');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Remove a value from memory
|
|
81
|
+
*/
|
|
82
|
+
async remove(key) {
|
|
83
|
+
const value = this.storage.get(key);
|
|
84
|
+
if (!value)
|
|
85
|
+
return;
|
|
86
|
+
this.storage.delete(key);
|
|
87
|
+
this.currentSize -= this.calculateSize(value);
|
|
88
|
+
// Emit change event
|
|
89
|
+
this.emitChange(key, value.value, undefined, 'local');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Clear memory storage
|
|
93
|
+
*/
|
|
94
|
+
async clear(options) {
|
|
95
|
+
if (!options || (!options.pattern && !options.tags && !options.expiredOnly)) {
|
|
96
|
+
// Clear everything
|
|
97
|
+
this.storage.clear();
|
|
98
|
+
this.currentSize = 0;
|
|
99
|
+
this.emitChange('*', undefined, undefined, 'local');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Use base implementation for filtered clear
|
|
103
|
+
await super.clear(options);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if key exists
|
|
107
|
+
*/
|
|
108
|
+
async has(key) {
|
|
109
|
+
const value = this.storage.get(key);
|
|
110
|
+
return value !== undefined && !this.isExpired(value);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get all keys
|
|
114
|
+
*/
|
|
115
|
+
async keys(pattern) {
|
|
116
|
+
const allKeys = Array.from(this.storage.keys());
|
|
117
|
+
// Remove expired entries
|
|
118
|
+
const validKeys = [];
|
|
119
|
+
for (const key of allKeys) {
|
|
120
|
+
const value = this.storage.get(key);
|
|
121
|
+
if (value && !this.isExpired(value)) {
|
|
122
|
+
validKeys.push(key);
|
|
123
|
+
}
|
|
124
|
+
else if (value) {
|
|
125
|
+
// Clean up expired entry
|
|
126
|
+
await this.remove(key);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return this.filterKeys(validKeys, pattern);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Query implementation for memory adapter
|
|
133
|
+
*/
|
|
134
|
+
async query(condition) {
|
|
135
|
+
const results = [];
|
|
136
|
+
for (const [key, item] of this.storage.entries()) {
|
|
137
|
+
if (!this.isExpired(item) && this.queryEngine.matches(item.value, condition)) {
|
|
138
|
+
results.push({
|
|
139
|
+
key,
|
|
140
|
+
value: deepClone(item.value),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return results;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get current memory usage
|
|
148
|
+
*/
|
|
149
|
+
getMemoryUsage() {
|
|
150
|
+
return {
|
|
151
|
+
used: this.currentSize,
|
|
152
|
+
limit: this.maxSize,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Close the adapter
|
|
157
|
+
*/
|
|
158
|
+
async close() {
|
|
159
|
+
if (super.close) {
|
|
160
|
+
await super.close();
|
|
161
|
+
}
|
|
162
|
+
this.storage.clear();
|
|
163
|
+
this.currentSize = 0;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionStorage Adapter - Browser sessionStorage implementation
|
|
3
|
+
* Provides session-scoped storage with 5-10MB limit
|
|
4
|
+
*/
|
|
5
|
+
import { LocalStorageAdapter } from './LocalStorageAdapter';
|
|
6
|
+
import type { StorageType, StorageCapabilities } from '@/types';
|
|
7
|
+
/**
|
|
8
|
+
* Browser sessionStorage adapter
|
|
9
|
+
* Extends LocalStorageAdapter as the API is identical
|
|
10
|
+
*/
|
|
11
|
+
export declare class SessionStorageAdapter extends LocalStorageAdapter {
|
|
12
|
+
readonly name: StorageType;
|
|
13
|
+
readonly capabilities: StorageCapabilities;
|
|
14
|
+
constructor(prefix?: string);
|
|
15
|
+
/**
|
|
16
|
+
* Check if sessionStorage is available
|
|
17
|
+
*/
|
|
18
|
+
isAvailable(): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Override all methods to use sessionStorage instead of localStorage
|
|
21
|
+
*/
|
|
22
|
+
protected getStorage(): Storage;
|
|
23
|
+
/**
|
|
24
|
+
* Get a value from sessionStorage
|
|
25
|
+
*/
|
|
26
|
+
get<T = unknown>(key: string): Promise<import('@/types').StorageValue<T> | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Set a value in sessionStorage
|
|
29
|
+
*/
|
|
30
|
+
set<T = unknown>(key: string, value: import('@/types').StorageValue<T>): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Remove a value from sessionStorage
|
|
33
|
+
*/
|
|
34
|
+
remove(key: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Clear sessionStorage
|
|
37
|
+
*/
|
|
38
|
+
clear(options?: import('@/types').ClearOptions): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Get all keys
|
|
41
|
+
*/
|
|
42
|
+
keys(pattern?: string | RegExp): Promise<string[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Get storage size
|
|
45
|
+
*/
|
|
46
|
+
size(detailed?: boolean): Promise<import('@/types').SizeInfo>;
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to storage changes
|
|
49
|
+
* Note: sessionStorage doesn't fire storage events in the same tab
|
|
50
|
+
*/
|
|
51
|
+
subscribe(_callback: import('@/types').SubscriptionCallback): import('@/types').UnsubscribeFunction;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=SessionStorageAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionStorageAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/SessionStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEhE;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAoB;IAC9C,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAUxC;gBAEU,MAAM,SAAoB;IAItC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBrC;;OAEG;IACH,SAAS,CAAC,UAAU,IAAI,OAAO;IAI/B;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAoBtF;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5F;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxC;;OAEG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBpE;;OAEG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBxD;;OAEG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,SAAS,EAAE,QAAQ,CAAC;IAoCnE;;;OAGG;IACH,SAAS,CACP,SAAS,EAAE,OAAO,SAAS,EAAE,oBAAoB,GAChD,OAAO,SAAS,EAAE,mBAAmB;CAKzC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionStorage Adapter - Browser sessionStorage implementation
|
|
3
|
+
* Provides session-scoped storage with 5-10MB limit
|
|
4
|
+
*/
|
|
5
|
+
import { LocalStorageAdapter } from './LocalStorageAdapter';
|
|
6
|
+
/**
|
|
7
|
+
* Browser sessionStorage adapter
|
|
8
|
+
* Extends LocalStorageAdapter as the API is identical
|
|
9
|
+
*/
|
|
10
|
+
export class SessionStorageAdapter extends LocalStorageAdapter {
|
|
11
|
+
name = 'sessionStorage';
|
|
12
|
+
capabilities = {
|
|
13
|
+
persistent: false, // Only for session
|
|
14
|
+
synchronous: false,
|
|
15
|
+
observable: true,
|
|
16
|
+
transactional: false,
|
|
17
|
+
queryable: true,
|
|
18
|
+
maxSize: 10 * 1024 * 1024, // Typically 5-10MB
|
|
19
|
+
binary: false,
|
|
20
|
+
encrypted: false,
|
|
21
|
+
crossTab: false, // Session storage is per-tab
|
|
22
|
+
};
|
|
23
|
+
constructor(prefix = 'strata:session:') {
|
|
24
|
+
super(prefix);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if sessionStorage is available
|
|
28
|
+
*/
|
|
29
|
+
async isAvailable() {
|
|
30
|
+
try {
|
|
31
|
+
if (typeof window === 'undefined' || !window.sessionStorage) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
// Test if we can actually use it
|
|
35
|
+
const testKey = `${this.prefix}__test__`;
|
|
36
|
+
window.sessionStorage.setItem(testKey, 'test');
|
|
37
|
+
window.sessionStorage.removeItem(testKey);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Override all methods to use sessionStorage instead of localStorage
|
|
46
|
+
*/
|
|
47
|
+
getStorage() {
|
|
48
|
+
return window.sessionStorage;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get a value from sessionStorage
|
|
52
|
+
*/
|
|
53
|
+
async get(key) {
|
|
54
|
+
try {
|
|
55
|
+
const item = window.sessionStorage.getItem(this.prefix + key);
|
|
56
|
+
if (!item)
|
|
57
|
+
return null;
|
|
58
|
+
const value = JSON.parse(item);
|
|
59
|
+
// Check TTL
|
|
60
|
+
if (this.isExpired(value)) {
|
|
61
|
+
await this.remove(key);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(`Failed to get key ${key} from sessionStorage:`, error);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Set a value in sessionStorage
|
|
73
|
+
*/
|
|
74
|
+
async set(key, value) {
|
|
75
|
+
const fullKey = this.prefix + key;
|
|
76
|
+
const oldValue = await this.get(key);
|
|
77
|
+
try {
|
|
78
|
+
const serialized = JSON.stringify(value);
|
|
79
|
+
window.sessionStorage.setItem(fullKey, serialized);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (this.isQuotaError(error)) {
|
|
83
|
+
throw new Error(`SessionStorage quota exceeded for key ${key}`);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Failed to store key ${key} in sessionStorage: ${error}`);
|
|
86
|
+
}
|
|
87
|
+
// Emit change event
|
|
88
|
+
this.emitChange(key, oldValue?.value, value.value, 'local');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Remove a value from sessionStorage
|
|
92
|
+
*/
|
|
93
|
+
async remove(key) {
|
|
94
|
+
const oldValue = await this.get(key);
|
|
95
|
+
window.sessionStorage.removeItem(this.prefix + key);
|
|
96
|
+
if (oldValue) {
|
|
97
|
+
this.emitChange(key, oldValue.value, undefined, 'local');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Clear sessionStorage
|
|
102
|
+
*/
|
|
103
|
+
async clear(options) {
|
|
104
|
+
if (!options || (!options.pattern && !options.tags && !options.expiredOnly)) {
|
|
105
|
+
// Clear all with our prefix
|
|
106
|
+
const keysToRemove = [];
|
|
107
|
+
for (let i = 0; i < window.sessionStorage.length; i++) {
|
|
108
|
+
const key = window.sessionStorage.key(i);
|
|
109
|
+
if (key?.startsWith(this.prefix)) {
|
|
110
|
+
keysToRemove.push(key);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
keysToRemove.forEach((key) => window.sessionStorage.removeItem(key));
|
|
114
|
+
this.emitChange('*', undefined, undefined, 'local');
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// Use base implementation for filtered clear
|
|
118
|
+
await super.clear(options);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get all keys
|
|
122
|
+
*/
|
|
123
|
+
async keys(pattern) {
|
|
124
|
+
const keys = [];
|
|
125
|
+
for (let i = 0; i < window.sessionStorage.length; i++) {
|
|
126
|
+
const fullKey = window.sessionStorage.key(i);
|
|
127
|
+
if (fullKey?.startsWith(this.prefix)) {
|
|
128
|
+
const key = fullKey.substring(this.prefix.length);
|
|
129
|
+
// Check if not expired
|
|
130
|
+
const value = await this.get(key);
|
|
131
|
+
if (value) {
|
|
132
|
+
keys.push(key);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return this.filterKeys(keys, pattern);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get storage size
|
|
140
|
+
*/
|
|
141
|
+
async size(detailed) {
|
|
142
|
+
let total = 0;
|
|
143
|
+
let count = 0;
|
|
144
|
+
let keySize = 0;
|
|
145
|
+
let valueSize = 0;
|
|
146
|
+
for (let i = 0; i < window.sessionStorage.length; i++) {
|
|
147
|
+
const fullKey = window.sessionStorage.key(i);
|
|
148
|
+
if (fullKey?.startsWith(this.prefix)) {
|
|
149
|
+
const item = window.sessionStorage.getItem(fullKey);
|
|
150
|
+
if (item) {
|
|
151
|
+
count++;
|
|
152
|
+
const itemSize = (fullKey.length + item.length) * 2; // UTF-16
|
|
153
|
+
total += itemSize;
|
|
154
|
+
if (detailed) {
|
|
155
|
+
keySize += fullKey.length * 2;
|
|
156
|
+
valueSize += item.length * 2;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const result = { total, count };
|
|
162
|
+
if (detailed) {
|
|
163
|
+
result.detailed = {
|
|
164
|
+
keys: keySize,
|
|
165
|
+
values: valueSize,
|
|
166
|
+
metadata: 0,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Subscribe to storage changes
|
|
173
|
+
* Note: sessionStorage doesn't fire storage events in the same tab
|
|
174
|
+
*/
|
|
175
|
+
subscribe(_callback) {
|
|
176
|
+
// For sessionStorage, we only get local changes, not cross-tab
|
|
177
|
+
// So we'll just return a no-op unsubscribe function
|
|
178
|
+
return () => { };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web storage adapters
|
|
3
|
+
*/
|
|
4
|
+
export { MemoryAdapter } from './MemoryAdapter';
|
|
5
|
+
export { LocalStorageAdapter } from './LocalStorageAdapter';
|
|
6
|
+
export { SessionStorageAdapter } from './SessionStorageAdapter';
|
|
7
|
+
export { IndexedDBAdapter } from './IndexedDBAdapter';
|
|
8
|
+
export { CookieAdapter } from './CookieAdapter';
|
|
9
|
+
export { CacheAdapter } from './CacheAdapter';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/web/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web storage adapters
|
|
3
|
+
*/
|
|
4
|
+
export { MemoryAdapter } from './MemoryAdapter';
|
|
5
|
+
export { LocalStorageAdapter } from './LocalStorageAdapter';
|
|
6
|
+
export { SessionStorageAdapter } from './SessionStorageAdapter';
|
|
7
|
+
export { IndexedDBAdapter } from './IndexedDBAdapter';
|
|
8
|
+
export { CookieAdapter } from './CookieAdapter';
|
|
9
|
+
export { CacheAdapter } from './CacheAdapter';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry for managing storage adapters
|
|
3
|
+
*/
|
|
4
|
+
import type { StorageAdapter, StorageType } from '@/types';
|
|
5
|
+
/**
|
|
6
|
+
* Adapter registry for managing storage adapters
|
|
7
|
+
*/
|
|
8
|
+
export declare class AdapterRegistry {
|
|
9
|
+
private adapters;
|
|
10
|
+
private initialized;
|
|
11
|
+
/**
|
|
12
|
+
* Register a storage adapter
|
|
13
|
+
*/
|
|
14
|
+
register(adapter: StorageAdapter): void;
|
|
15
|
+
/**
|
|
16
|
+
* Get a storage adapter by name
|
|
17
|
+
*/
|
|
18
|
+
get(name: StorageType): StorageAdapter | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Get an adapter and ensure it's initialized
|
|
21
|
+
*/
|
|
22
|
+
getInitialized(name: StorageType, config?: unknown): Promise<StorageAdapter>;
|
|
23
|
+
/**
|
|
24
|
+
* Check if an adapter is registered
|
|
25
|
+
*/
|
|
26
|
+
has(name: StorageType): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Get all registered adapter names
|
|
29
|
+
*/
|
|
30
|
+
getNames(): StorageType[];
|
|
31
|
+
/**
|
|
32
|
+
* Get all registered adapters
|
|
33
|
+
*/
|
|
34
|
+
getAll(): StorageAdapter[];
|
|
35
|
+
/**
|
|
36
|
+
* Get available adapters for current platform
|
|
37
|
+
*/
|
|
38
|
+
getAvailable(): Promise<StorageAdapter[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Unregister an adapter
|
|
41
|
+
*/
|
|
42
|
+
unregister(name: StorageType): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Clear all adapters
|
|
45
|
+
*/
|
|
46
|
+
clear(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Close all adapters
|
|
49
|
+
*/
|
|
50
|
+
closeAll(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=AdapterRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdapterRegistry.d.ts","sourceRoot":"","sources":["../../src/core/AdapterRegistry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3D;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,WAAW,CAA+B;IAElD;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIvC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS;IAIlD;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IAwBlF;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAI/B;;OAEG;IACH,QAAQ,IAAI,WAAW,EAAE;IAIzB;;OAEG;IACH,MAAM,IAAI,cAAc,EAAE;IAI1B;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAY/C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAKtC;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAYhC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry for managing storage adapters
|
|
3
|
+
*/
|
|
4
|
+
import { AdapterNotAvailableError } from '@/utils/errors';
|
|
5
|
+
/**
|
|
6
|
+
* Adapter registry for managing storage adapters
|
|
7
|
+
*/
|
|
8
|
+
export class AdapterRegistry {
|
|
9
|
+
adapters = new Map();
|
|
10
|
+
initialized = new Set();
|
|
11
|
+
/**
|
|
12
|
+
* Register a storage adapter
|
|
13
|
+
*/
|
|
14
|
+
register(adapter) {
|
|
15
|
+
this.adapters.set(adapter.name, adapter);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get a storage adapter by name
|
|
19
|
+
*/
|
|
20
|
+
get(name) {
|
|
21
|
+
return this.adapters.get(name);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get an adapter and ensure it's initialized
|
|
25
|
+
*/
|
|
26
|
+
async getInitialized(name, config) {
|
|
27
|
+
const adapter = this.get(name);
|
|
28
|
+
if (!adapter) {
|
|
29
|
+
throw new AdapterNotAvailableError(name);
|
|
30
|
+
}
|
|
31
|
+
// Check if adapter is available on current platform
|
|
32
|
+
const isAvailable = await adapter.isAvailable();
|
|
33
|
+
if (!isAvailable) {
|
|
34
|
+
throw new AdapterNotAvailableError(name, {
|
|
35
|
+
reason: 'Not available on current platform',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// Initialize if not already done
|
|
39
|
+
if (!this.initialized.has(name)) {
|
|
40
|
+
await adapter.initialize(config);
|
|
41
|
+
this.initialized.add(name);
|
|
42
|
+
}
|
|
43
|
+
return adapter;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if an adapter is registered
|
|
47
|
+
*/
|
|
48
|
+
has(name) {
|
|
49
|
+
return this.adapters.has(name);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get all registered adapter names
|
|
53
|
+
*/
|
|
54
|
+
getNames() {
|
|
55
|
+
return Array.from(this.adapters.keys());
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get all registered adapters
|
|
59
|
+
*/
|
|
60
|
+
getAll() {
|
|
61
|
+
return Array.from(this.adapters.values());
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get available adapters for current platform
|
|
65
|
+
*/
|
|
66
|
+
async getAvailable() {
|
|
67
|
+
const available = [];
|
|
68
|
+
for (const adapter of this.adapters.values()) {
|
|
69
|
+
if (await adapter.isAvailable()) {
|
|
70
|
+
available.push(adapter);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return available;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Unregister an adapter
|
|
77
|
+
*/
|
|
78
|
+
unregister(name) {
|
|
79
|
+
this.initialized.delete(name);
|
|
80
|
+
return this.adapters.delete(name);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Clear all adapters
|
|
84
|
+
*/
|
|
85
|
+
clear() {
|
|
86
|
+
this.adapters.clear();
|
|
87
|
+
this.initialized.clear();
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Close all adapters
|
|
91
|
+
*/
|
|
92
|
+
async closeAll() {
|
|
93
|
+
const promises = [];
|
|
94
|
+
for (const [name, adapter] of this.adapters) {
|
|
95
|
+
if (this.initialized.has(name) && adapter.close) {
|
|
96
|
+
promises.push(adapter.close());
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
await Promise.all(promises);
|
|
100
|
+
this.initialized.clear();
|
|
101
|
+
}
|
|
102
|
+
}
|