@vorplex/core 0.0.15 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/modules/changes/changes.util.d.ts +32 -16
- package/dist/modules/changes/changes.util.js +105 -99
- package/dist/modules/storage/in-memory.model.d.ts +17 -0
- package/dist/modules/storage/in-memory.model.js +35 -0
- package/dist/modules/storage/local-storage.model.d.ts +16 -0
- package/dist/modules/storage/local-storage.model.js +49 -0
- package/dist/modules/storage/storage-provider.interface.d.ts +8 -0
- package/dist/modules/storage/storage-provider.interface.js +0 -0
- package/package.json +3 -5
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,9 @@ export * from './modules/state/adaptors/array/array-adaptor.util';
|
|
|
62
62
|
export * from './modules/state/adaptors/entity/entity-adaptor.util';
|
|
63
63
|
export * from './modules/state/adaptors/entity/entity-map.type';
|
|
64
64
|
export * from './modules/state/adaptors/entity/entity.interface';
|
|
65
|
+
export * from './modules/storage/in-memory.model';
|
|
66
|
+
export * from './modules/storage/local-storage.model';
|
|
67
|
+
export * from './modules/storage/storage-provider.interface';
|
|
65
68
|
export * from './modules/string/string.util';
|
|
66
69
|
export * from './modules/subscribable/subscribable.model';
|
|
67
70
|
export * from './modules/subscribable/subscription.interface';
|
package/dist/index.js
CHANGED
|
@@ -63,6 +63,9 @@ export * from './modules/state/adaptors/array/array-adaptor.util';
|
|
|
63
63
|
export * from './modules/state/adaptors/entity/entity-adaptor.util';
|
|
64
64
|
export * from './modules/state/adaptors/entity/entity-map.type';
|
|
65
65
|
export * from './modules/state/adaptors/entity/entity.interface';
|
|
66
|
+
export * from './modules/storage/in-memory.model';
|
|
67
|
+
export * from './modules/storage/local-storage.model';
|
|
68
|
+
export * from './modules/storage/storage-provider.interface';
|
|
66
69
|
export * from './modules/string/string.util';
|
|
67
70
|
export * from './modules/subscribable/subscribable.model';
|
|
68
71
|
export * from './modules/subscribable/subscription.interface';
|
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
export type ArrayChange = Record<`$${number}` | `$${number}+`, any | typeof $Changes.deleted>;
|
|
2
|
-
export interface
|
|
2
|
+
export interface ChangeCompareResult {
|
|
3
|
+
similarities: any;
|
|
3
4
|
conflicts: any;
|
|
4
5
|
differences: any;
|
|
5
6
|
}
|
|
6
7
|
export interface ChangeRebase<T = any> {
|
|
8
|
+
/**
|
|
9
|
+
* The remote with local changes
|
|
10
|
+
*/
|
|
7
11
|
result: T;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
remote:
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Only defined when the rebase contains conflicts.
|
|
14
|
+
* Contains rebase conflicts and merge
|
|
15
|
+
*/
|
|
16
|
+
conflict?: {
|
|
17
|
+
local: ChangeCompareResult;
|
|
18
|
+
remote: ChangeCompareResult;
|
|
19
|
+
merge?: {
|
|
20
|
+
/**
|
|
21
|
+
* The source with remote and local none conflicting changes
|
|
22
|
+
*/
|
|
23
|
+
source: T;
|
|
24
|
+
/**
|
|
25
|
+
* The `.source` with remote conflict changes
|
|
26
|
+
*/
|
|
27
|
+
remote: T;
|
|
28
|
+
/**
|
|
29
|
+
* The `.source` with local conflict changes
|
|
30
|
+
*/
|
|
31
|
+
local: T;
|
|
32
|
+
/**
|
|
33
|
+
* The remote with local none conflicting changes
|
|
34
|
+
*/
|
|
35
|
+
result: T;
|
|
36
|
+
};
|
|
17
37
|
};
|
|
18
38
|
}
|
|
19
39
|
export declare class $Changes {
|
|
@@ -22,15 +42,11 @@ export declare class $Changes {
|
|
|
22
42
|
static getArrayChanges(a: any[], b: any[]): ArrayChange | undefined;
|
|
23
43
|
static getObjectChanges(a: Record<string, any>, b: Record<string, any>): Record<string, any | typeof $Changes.deleted>;
|
|
24
44
|
static get(a: any, b: any): undefined | any | Record<string, any | typeof $Changes.deleted> | ArrayChange;
|
|
25
|
-
static
|
|
26
|
-
conflicts: string[];
|
|
27
|
-
differences: string[];
|
|
28
|
-
};
|
|
29
|
-
static resolveConflicts(changesA: any, changesB: any): ChangeConflicts;
|
|
45
|
+
static compareChanges(changesA: any, changesB: any): ChangeCompareResult;
|
|
30
46
|
private static pathsOverlap;
|
|
31
47
|
static hasConflict(changesA: any, changesB: any): boolean;
|
|
32
48
|
static asValue(changes: any): any;
|
|
33
|
-
static apply(value: any, changes: any): any;
|
|
49
|
+
static apply(value: any, ...changes: any[]): any;
|
|
34
50
|
static rebase(source: any, local: any, remote: any): ChangeRebase;
|
|
35
51
|
/**
|
|
36
52
|
* Excludes specific paths from a changes object and cleans up empty containers.
|
|
@@ -107,33 +107,31 @@ export class $Changes {
|
|
|
107
107
|
return $Changes.getArrayChanges(a, b);
|
|
108
108
|
return $Changes.getObjectChanges(a, b);
|
|
109
109
|
}
|
|
110
|
-
static
|
|
110
|
+
static compareChanges(changesA, changesB) {
|
|
111
111
|
const aPaths = $Object.getPaths(changesA);
|
|
112
112
|
const bPaths = $Object.getPaths(changesB);
|
|
113
|
+
const similarities = new Set();
|
|
113
114
|
const conflicts = new Set();
|
|
114
115
|
const differences = new Set();
|
|
115
|
-
for (const aPath of aPaths) {
|
|
116
|
-
if (bPaths.some(bPath => this.pathsOverlap(aPath, bPath)))
|
|
117
|
-
conflicts.add(aPath);
|
|
118
|
-
else
|
|
119
|
-
differences.add(aPath);
|
|
120
|
-
}
|
|
121
116
|
for (const bPath of bPaths) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
let overlapped;
|
|
118
|
+
for (const aPath of aPaths) {
|
|
119
|
+
if (this.pathsOverlap(aPath, bPath)) {
|
|
120
|
+
overlapped = true;
|
|
121
|
+
const longestPath = aPath.length > bPath.length ? aPath : bPath;
|
|
122
|
+
if ($Value.equals($Value.get(changesA, longestPath), $Value.get(changesB, longestPath)))
|
|
123
|
+
similarities.add(bPath);
|
|
124
|
+
else
|
|
125
|
+
conflicts.add(bPath);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!overlapped)
|
|
125
129
|
differences.add(bPath);
|
|
126
130
|
}
|
|
127
131
|
return {
|
|
128
|
-
|
|
129
|
-
differences:
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
static resolveConflicts(changesA, changesB) {
|
|
133
|
-
const { conflicts, differences } = this.classifyPathsByOverlap(changesA, changesB);
|
|
134
|
-
return {
|
|
135
|
-
differences: $Changes.excludeChanges(changesB, conflicts),
|
|
136
|
-
conflicts: $Changes.excludeChanges(changesB, differences)
|
|
132
|
+
similarities: $Changes.excludeChanges(changesB, [...conflicts, ...differences]),
|
|
133
|
+
differences: $Changes.excludeChanges(changesB, [...similarities, ...conflicts]),
|
|
134
|
+
conflicts: $Changes.excludeChanges(changesB, [...similarities, ...differences])
|
|
137
135
|
};
|
|
138
136
|
}
|
|
139
137
|
static pathsOverlap(a, b) {
|
|
@@ -151,8 +149,11 @@ export class $Changes {
|
|
|
151
149
|
const bPaths = $Object.getPaths(changesB);
|
|
152
150
|
for (const bPath of bPaths) {
|
|
153
151
|
for (const aPath of aPaths) {
|
|
154
|
-
if (this.pathsOverlap(aPath, bPath))
|
|
155
|
-
|
|
152
|
+
if (this.pathsOverlap(aPath, bPath)) {
|
|
153
|
+
const longestPath = aPath.length > bPath.length ? aPath : bPath;
|
|
154
|
+
if (!$Value.equals($Value.get(changesA, longestPath), $Value.get(changesB, longestPath)))
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
return false;
|
|
@@ -164,7 +165,6 @@ export class $Changes {
|
|
|
164
165
|
return changes.map(item => $Changes.asValue(item));
|
|
165
166
|
}
|
|
166
167
|
if (typeof changes === 'object' && changes !== null) {
|
|
167
|
-
// cannot materialize array index changes without a base; strip them
|
|
168
168
|
if ($Changes.isArrayIndexChange(changes))
|
|
169
169
|
return undefined;
|
|
170
170
|
const result = {};
|
|
@@ -177,80 +177,86 @@ export class $Changes {
|
|
|
177
177
|
}
|
|
178
178
|
return changes;
|
|
179
179
|
}
|
|
180
|
-
static apply(value, changes) {
|
|
181
|
-
function
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
180
|
+
static apply(value, ...changes) {
|
|
181
|
+
function apply(value, changes) {
|
|
182
|
+
function applyArrayChange(originalArray, change) {
|
|
183
|
+
if (!$Changes.isArrayIndexChange(change))
|
|
184
|
+
return $Value.clone(change);
|
|
185
|
+
const result = $Value.clone(originalArray);
|
|
186
|
+
const entries = Object.entries(change)
|
|
187
|
+
.map(([k, v]) => {
|
|
188
|
+
const isInsert = k.endsWith('+');
|
|
189
|
+
const nStr = isInsert ? k.slice(1, -1) : k.slice(1);
|
|
190
|
+
return [Number.parseInt(nStr, 10), isInsert, v];
|
|
191
|
+
})
|
|
192
|
+
.filter(([i]) => !Number.isNaN(i))
|
|
193
|
+
.sort(([iA, insA, vA], [iB, insB, vB]) => {
|
|
194
|
+
const aDel = vA === $Changes.deleted;
|
|
195
|
+
const bDel = vB === $Changes.deleted;
|
|
196
|
+
// deletes first, highest -> lowest
|
|
197
|
+
if (aDel !== bDel)
|
|
198
|
+
return aDel ? -1 : 1;
|
|
199
|
+
if (aDel && bDel)
|
|
200
|
+
return iB - iA;
|
|
201
|
+
// inserts next, lowest -> highest
|
|
202
|
+
if (insA !== insB)
|
|
203
|
+
return insA ? -1 : 1;
|
|
204
|
+
if (insA && insB)
|
|
205
|
+
return iA - iB;
|
|
206
|
+
// sets last, lowest -> highest
|
|
204
207
|
return iA - iB;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
result[index] = $Changes.apply(result[index], op);
|
|
208
|
+
});
|
|
209
|
+
for (const [index, isInsert, op] of entries) {
|
|
210
|
+
if (op === $Changes.deleted) {
|
|
211
|
+
if (index >= 0 && index < result.length)
|
|
212
|
+
result.splice(index, 1);
|
|
213
|
+
}
|
|
214
|
+
else if (isInsert) {
|
|
215
|
+
const v = $Value.clone(op);
|
|
216
|
+
const idx = Math.min(Math.max(index, 0), result.length);
|
|
217
|
+
result.splice(idx, 0, v);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
if (index >= result.length)
|
|
221
|
+
result.length = index + 1;
|
|
222
|
+
result[index] = $Changes.apply(result[index], op);
|
|
223
|
+
}
|
|
222
224
|
}
|
|
225
|
+
return result;
|
|
223
226
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return value;
|
|
228
|
-
if (value == null || typeof changes !== 'object')
|
|
229
|
-
return $Changes.asValue(changes);
|
|
230
|
-
if (Array.isArray(value)) {
|
|
231
|
-
return applyArrayChange(value, changes);
|
|
232
|
-
}
|
|
233
|
-
else if (typeof value === 'object') {
|
|
234
|
-
if (Array.isArray(changes))
|
|
227
|
+
if (changes === undefined)
|
|
228
|
+
return value;
|
|
229
|
+
if (value == null || typeof changes !== 'object')
|
|
235
230
|
return $Changes.asValue(changes);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
231
|
+
if (Array.isArray(value)) {
|
|
232
|
+
return applyArrayChange(value, changes);
|
|
233
|
+
}
|
|
234
|
+
else if (typeof value === 'object') {
|
|
235
|
+
if (Array.isArray(changes))
|
|
236
|
+
return $Changes.asValue(changes);
|
|
237
|
+
const result = { ...value };
|
|
238
|
+
for (const [key, change] of Object.entries(changes)) {
|
|
239
|
+
if (change === $Changes.deleted) {
|
|
240
|
+
delete result[key];
|
|
241
|
+
}
|
|
242
|
+
else if (Array.isArray(result[key])) {
|
|
243
|
+
result[key] = applyArrayChange(result[key] || [], change);
|
|
244
|
+
}
|
|
245
|
+
else if (typeof change === 'object' && change !== null) {
|
|
246
|
+
result[key] = $Changes.apply(result[key], change);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
result[key] = change;
|
|
250
|
+
}
|
|
249
251
|
}
|
|
252
|
+
return result;
|
|
250
253
|
}
|
|
251
|
-
return
|
|
254
|
+
return $Changes.asValue(changes);
|
|
255
|
+
}
|
|
256
|
+
for (const change of changes) {
|
|
257
|
+
value = apply(value, change);
|
|
252
258
|
}
|
|
253
|
-
return
|
|
259
|
+
return value;
|
|
254
260
|
}
|
|
255
261
|
static rebase(source, local, remote) {
|
|
256
262
|
const localChanges = $Changes.get(source, local);
|
|
@@ -267,20 +273,20 @@ export class $Changes {
|
|
|
267
273
|
return { result };
|
|
268
274
|
}
|
|
269
275
|
else {
|
|
270
|
-
const localConflict = $Changes.
|
|
271
|
-
const remoteConflict = $Changes.
|
|
272
|
-
const sourceWithDifferences = $Changes.apply(
|
|
276
|
+
const localConflict = $Changes.compareChanges(remoteChanges, localChanges);
|
|
277
|
+
const remoteConflict = $Changes.compareChanges(localChanges, remoteChanges);
|
|
278
|
+
const sourceWithDifferences = $Changes.apply(source, remoteConflict.differences, localConflict.differences, remoteConflict.similarities, localConflict.similarities);
|
|
273
279
|
const mergedWithLocalDifferences = $Changes.apply(remote, localConflict.differences);
|
|
274
280
|
return {
|
|
275
|
-
|
|
281
|
+
conflict: {
|
|
276
282
|
local: localConflict,
|
|
277
283
|
remote: remoteConflict,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
+
merge: {
|
|
285
|
+
source: sourceWithDifferences,
|
|
286
|
+
remote: $Changes.apply(sourceWithDifferences, remoteConflict.conflicts),
|
|
287
|
+
local: $Changes.apply(sourceWithDifferences, localConflict.conflicts),
|
|
288
|
+
result: mergedWithLocalDifferences
|
|
289
|
+
},
|
|
284
290
|
},
|
|
285
291
|
result: $Changes.apply(mergedWithLocalDifferences, localConflict.conflicts)
|
|
286
292
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StorageProvider } from './storage-provider.interface';
|
|
2
|
+
export declare class InMemoryStorage implements StorageProvider {
|
|
3
|
+
private static storage;
|
|
4
|
+
private static getStore;
|
|
5
|
+
static get<T = any>(database: string, store: string, key: string): Promise<T | null>;
|
|
6
|
+
static set(database: string, store: string, key: string, value: any): Promise<void>;
|
|
7
|
+
static delete(database: string, store: string, key: string): Promise<void>;
|
|
8
|
+
static clear(database: string, store: string): Promise<void>;
|
|
9
|
+
static keys(database: string, store: string): Promise<string[]>;
|
|
10
|
+
static getAll<T = any>(database: string, store: string): Promise<T[]>;
|
|
11
|
+
get<T = any>(database: string, store: string, key: string): Promise<T | null>;
|
|
12
|
+
set(database: string, store: string, key: string, value: any): Promise<void>;
|
|
13
|
+
delete(database: string, store: string, key: string): Promise<void>;
|
|
14
|
+
clear(database: string, store: string): Promise<void>;
|
|
15
|
+
keys(database: string, store: string): Promise<string[]>;
|
|
16
|
+
getAll<T = any>(database: string, store: string): Promise<T[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export class InMemoryStorage {
|
|
2
|
+
static storage = new Map();
|
|
3
|
+
static getStore(database, store) {
|
|
4
|
+
if (!this.storage.has(database))
|
|
5
|
+
this.storage.set(database, new Map());
|
|
6
|
+
const db = this.storage.get(database);
|
|
7
|
+
if (!db.has(store))
|
|
8
|
+
db.set(store, new Map());
|
|
9
|
+
return db.get(store);
|
|
10
|
+
}
|
|
11
|
+
static async get(database, store, key) {
|
|
12
|
+
return this.getStore(database, store).get(key) ?? null;
|
|
13
|
+
}
|
|
14
|
+
static async set(database, store, key, value) {
|
|
15
|
+
this.getStore(database, store).set(key, value);
|
|
16
|
+
}
|
|
17
|
+
static async delete(database, store, key) {
|
|
18
|
+
this.getStore(database, store).delete(key);
|
|
19
|
+
}
|
|
20
|
+
static async clear(database, store) {
|
|
21
|
+
this.getStore(database, store).clear();
|
|
22
|
+
}
|
|
23
|
+
static async keys(database, store) {
|
|
24
|
+
return [...this.getStore(database, store).keys()];
|
|
25
|
+
}
|
|
26
|
+
static async getAll(database, store) {
|
|
27
|
+
return [...this.getStore(database, store).values()];
|
|
28
|
+
}
|
|
29
|
+
async get(database, store, key) { return InMemoryStorage.get(database, store, key); }
|
|
30
|
+
async set(database, store, key, value) { return InMemoryStorage.set(database, store, key, value); }
|
|
31
|
+
async delete(database, store, key) { return InMemoryStorage.delete(database, store, key); }
|
|
32
|
+
async clear(database, store) { return InMemoryStorage.clear(database, store); }
|
|
33
|
+
async keys(database, store) { return InMemoryStorage.keys(database, store); }
|
|
34
|
+
async getAll(database, store) { return InMemoryStorage.getAll(database, store); }
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { StorageProvider } from './storage-provider.interface';
|
|
2
|
+
export declare class LocalStorage implements StorageProvider {
|
|
3
|
+
private static key;
|
|
4
|
+
static get<T = any>(database: string, store: string, key: string): Promise<T | null>;
|
|
5
|
+
static set(database: string, store: string, key: string, value: any): Promise<void>;
|
|
6
|
+
static delete(database: string, store: string, key: string): Promise<void>;
|
|
7
|
+
static clear(database: string, store: string): Promise<void>;
|
|
8
|
+
static keys(database: string, store: string): Promise<string[]>;
|
|
9
|
+
static getAll<T = any>(database: string, store: string): Promise<T[]>;
|
|
10
|
+
get<T = any>(database: string, store: string, key: string): Promise<T | null>;
|
|
11
|
+
set(database: string, store: string, key: string, value: any): Promise<void>;
|
|
12
|
+
delete(database: string, store: string, key: string): Promise<void>;
|
|
13
|
+
clear(database: string, store: string): Promise<void>;
|
|
14
|
+
keys(database: string, store: string): Promise<string[]>;
|
|
15
|
+
getAll<T = any>(database: string, store: string): Promise<T[]>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export class LocalStorage {
|
|
2
|
+
static key(database, store, key) {
|
|
3
|
+
return `${database}:${store}:${key ?? ''}`;
|
|
4
|
+
}
|
|
5
|
+
static async get(database, store, key) {
|
|
6
|
+
const raw = localStorage.getItem(this.key(database, store, key));
|
|
7
|
+
return raw != null ? JSON.parse(raw) : null;
|
|
8
|
+
}
|
|
9
|
+
static async set(database, store, key, value) {
|
|
10
|
+
localStorage.setItem(this.key(database, store, key), JSON.stringify(value));
|
|
11
|
+
}
|
|
12
|
+
static async delete(database, store, key) {
|
|
13
|
+
localStorage.removeItem(this.key(database, store, key));
|
|
14
|
+
}
|
|
15
|
+
static async clear(database, store) {
|
|
16
|
+
const prefix = this.key(database, store);
|
|
17
|
+
for (let i = localStorage.length - 1; i >= 0; i--) {
|
|
18
|
+
const key = localStorage.key(i);
|
|
19
|
+
if (key?.startsWith(prefix))
|
|
20
|
+
localStorage.removeItem(key);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
static async keys(database, store) {
|
|
24
|
+
const prefix = this.key(database, store);
|
|
25
|
+
const result = [];
|
|
26
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
27
|
+
const key = localStorage.key(i);
|
|
28
|
+
if (key?.startsWith(prefix))
|
|
29
|
+
result.push(key.slice(prefix.length));
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
static async getAll(database, store) {
|
|
34
|
+
const prefix = this.key(database, store);
|
|
35
|
+
const result = [];
|
|
36
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
37
|
+
const key = localStorage.key(i);
|
|
38
|
+
if (key?.startsWith(prefix))
|
|
39
|
+
result.push(JSON.parse(localStorage.getItem(key)));
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
async get(database, store, key) { return LocalStorage.get(database, store, key); }
|
|
44
|
+
async set(database, store, key, value) { return LocalStorage.set(database, store, key, value); }
|
|
45
|
+
async delete(database, store, key) { return LocalStorage.delete(database, store, key); }
|
|
46
|
+
async clear(database, store) { return LocalStorage.clear(database, store); }
|
|
47
|
+
async keys(database, store) { return LocalStorage.keys(database, store); }
|
|
48
|
+
async getAll(database, store) { return LocalStorage.getAll(database, store); }
|
|
49
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface StorageProvider<TDatabase extends string = string, TStore extends string = string> {
|
|
2
|
+
get<T = any>(database: TDatabase, store: TStore, key: string): Promise<T | null>;
|
|
3
|
+
set(database: TDatabase, store: TStore, key: string, value: any): Promise<void>;
|
|
4
|
+
delete(database: TDatabase, store: TStore, key: string): Promise<void>;
|
|
5
|
+
clear(database: TDatabase, store: TStore): Promise<void>;
|
|
6
|
+
keys(database: TDatabase, store: TStore): Promise<string[]>;
|
|
7
|
+
getAll<T = any>(database: TDatabase, store: TStore): Promise<T[]>;
|
|
8
|
+
}
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vorplex/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"files": [
|
|
@@ -18,13 +18,11 @@
|
|
|
18
18
|
"tslib": "2.8.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"
|
|
22
|
-
"jest": "29.7.0",
|
|
23
|
-
"ts-jest": "29.4.5"
|
|
21
|
+
"vitest": "3.2.4"
|
|
24
22
|
},
|
|
25
23
|
"scripts": {
|
|
26
24
|
"build": "tsc -b --force tsconfig.build.json",
|
|
27
|
-
"test": "
|
|
25
|
+
"test": "vitest run",
|
|
28
26
|
"npm:publish": "pnpm publish --registry=https://registry.npmjs.org/"
|
|
29
27
|
}
|
|
30
28
|
}
|