@aws-amplify/datastore 3.14.5-unstable.2 → 3.14.5
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/CHANGELOG.md +19 -0
- package/build.js +5 -0
- package/dist/aws-amplify-datastore.js +92853 -0
- package/dist/aws-amplify-datastore.js.map +1 -0
- package/dist/aws-amplify-datastore.min.js +65 -0
- package/dist/aws-amplify-datastore.min.js.map +1 -0
- package/index.js +7 -0
- package/lib/authModeStrategies/multiAuthStrategy.js +64 -6
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.js +297 -703
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.js +4 -6
- package/lib/index.js.map +1 -1
- package/lib/predicates/index.js +6 -127
- package/lib/predicates/index.js.map +1 -1
- package/lib/predicates/sort.js +4 -10
- package/lib/predicates/sort.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js +381 -138
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.js +98 -37
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.js +67 -16
- package/lib/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.native.js +4 -2
- package/lib/storage/adapter/InMemoryStore.native.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.js +420 -272
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/getDefaultAdapter/index.js +5 -3
- package/lib/storage/adapter/getDefaultAdapter/index.js.map +1 -1
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +4 -2
- package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +1 -1
- package/lib/storage/storage.js +143 -72
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/datastoreConnectivity.js +55 -6
- package/lib/sync/datastoreConnectivity.js.map +1 -1
- package/lib/sync/datastoreReachability/index.native.js +4 -2
- package/lib/sync/datastoreReachability/index.native.js.map +1 -1
- package/lib/sync/index.js +124 -49
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.js +74 -8
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.js +97 -24
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/errorMaps.js +35 -5
- package/lib/sync/processors/errorMaps.js.map +1 -1
- package/lib/sync/processors/mutation.js +131 -47
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.js +102 -29
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.js +102 -26
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.js +103 -40
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.js +39 -9
- package/lib/types.js.map +1 -1
- package/lib/util.js +188 -192
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +57 -2
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +8 -59
- package/lib-esm/datastore/datastore.js +234 -642
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +2 -3
- package/lib-esm/index.js +1 -2
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/predicates/index.d.ts +2 -16
- package/lib-esm/predicates/index.js +7 -128
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/predicates/sort.js +4 -10
- package/lib-esm/predicates/sort.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +1 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +349 -109
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +68 -7
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.d.ts +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.js +52 -1
- package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +2 -4
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +368 -227
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +1 -1
- package/lib-esm/storage/storage.d.ts +6 -7
- package/lib-esm/storage/storage.js +101 -33
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/datastoreConnectivity.js +47 -1
- package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
- package/lib-esm/sync/index.js +76 -4
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.js +67 -1
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.js +74 -1
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/errorMaps.js +32 -2
- package/lib-esm/sync/processors/errorMaps.js.map +1 -1
- package/lib-esm/sync/processors/mutation.js +93 -12
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.js +69 -6
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.js +75 -2
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +1 -1
- package/lib-esm/sync/utils.js +95 -32
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +10 -63
- package/lib-esm/types.js +38 -7
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +6 -39
- package/lib-esm/util.js +171 -171
- package/lib-esm/util.js.map +1 -1
- package/package.json +14 -21
- package/src/authModeStrategies/multiAuthStrategy.ts +2 -2
- package/src/datastore/datastore.ts +206 -699
- package/src/index.ts +0 -4
- package/src/predicates/index.ts +17 -143
- package/src/predicates/sort.ts +2 -8
- package/src/storage/adapter/AsyncStorageAdapter.ts +178 -56
- package/src/storage/adapter/AsyncStorageDatabase.ts +15 -16
- package/src/storage/adapter/InMemoryStore.ts +2 -5
- package/src/storage/adapter/IndexedDBAdapter.ts +191 -166
- package/src/storage/adapter/getDefaultAdapter/index.ts +2 -2
- package/src/storage/storage.ts +37 -56
- package/src/sync/datastoreConnectivity.ts +4 -4
- package/src/sync/index.ts +28 -22
- package/src/sync/merger.ts +1 -1
- package/src/sync/outbox.ts +6 -6
- package/src/sync/processors/errorMaps.ts +1 -1
- package/src/sync/processors/mutation.ts +19 -23
- package/src/sync/processors/subscription.ts +16 -20
- package/src/sync/processors/sync.ts +17 -17
- package/src/sync/utils.ts +48 -42
- package/src/types.ts +16 -128
- package/src/util.ts +150 -108
- package/webpack.config.dev.js +6 -0
- package/lib/authModeStrategies/defaultAuthStrategy.d.ts +0 -2
- package/lib/authModeStrategies/index.d.ts +0 -2
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +0 -13
- package/lib/datastore/datastore.d.ts +0 -207
- package/lib/index.d.ts +0 -16
- package/lib/predicates/index.d.ts +0 -30
- package/lib/predicates/next.d.ts +0 -301
- package/lib/predicates/next.js +0 -816
- package/lib/predicates/next.js.map +0 -1
- package/lib/predicates/sort.d.ts +0 -8
- package/lib/ssr/index.d.ts +0 -3
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +0 -42
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +0 -39
- package/lib/storage/adapter/InMemoryStore.d.ts +0 -11
- package/lib/storage/adapter/InMemoryStore.native.d.ts +0 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +0 -61
- package/lib/storage/adapter/getDefaultAdapter/index.d.ts +0 -3
- package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +0 -3
- package/lib/storage/adapter/index.d.ts +0 -9
- package/lib/storage/relationship.d.ts +0 -140
- package/lib/storage/relationship.js +0 -335
- package/lib/storage/relationship.js.map +0 -1
- package/lib/storage/storage.d.ts +0 -50
- package/lib/sync/datastoreConnectivity.d.ts +0 -16
- package/lib/sync/datastoreReachability/index.d.ts +0 -3
- package/lib/sync/datastoreReachability/index.native.d.ts +0 -3
- package/lib/sync/index.d.ts +0 -89
- package/lib/sync/merger.d.ts +0 -17
- package/lib/sync/outbox.d.ts +0 -27
- package/lib/sync/processors/errorMaps.d.ts +0 -17
- package/lib/sync/processors/mutation.d.ts +0 -58
- package/lib/sync/processors/subscription.d.ts +0 -33
- package/lib/sync/processors/sync.d.ts +0 -28
- package/lib/sync/utils.d.ts +0 -42
- package/lib/types.d.ts +0 -554
- package/lib/util.d.ts +0 -189
- package/lib-esm/predicates/next.d.ts +0 -301
- package/lib-esm/predicates/next.js +0 -812
- package/lib-esm/predicates/next.js.map +0 -1
- package/lib-esm/storage/relationship.d.ts +0 -140
- package/lib-esm/storage/relationship.js +0 -333
- package/lib-esm/storage/relationship.js.map +0 -1
- package/src/predicates/next.ts +0 -967
- package/src/storage/relationship.ts +0 -272
|
@@ -2,7 +2,10 @@ import { ConsoleLogger as Logger } from '@aws-amplify/core';
|
|
|
2
2
|
import AsyncStorageDatabase from './AsyncStorageDatabase';
|
|
3
3
|
import { Adapter } from './index';
|
|
4
4
|
import { ModelInstanceCreator } from '../../datastore/datastore';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ModelPredicateCreator,
|
|
7
|
+
ModelSortPredicateCreator,
|
|
8
|
+
} from '../../predicates';
|
|
6
9
|
import {
|
|
7
10
|
InternalSchema,
|
|
8
11
|
isPredicateObj,
|
|
@@ -20,13 +23,13 @@ import {
|
|
|
20
23
|
} from '../../types';
|
|
21
24
|
import {
|
|
22
25
|
DEFAULT_PRIMARY_KEY_VALUE_SEPARATOR,
|
|
26
|
+
exhaustiveCheck,
|
|
23
27
|
getIndex,
|
|
24
28
|
getIndexFromAssociation,
|
|
25
29
|
isModelConstructor,
|
|
26
30
|
traverseModel,
|
|
27
31
|
validatePredicate,
|
|
28
|
-
|
|
29
|
-
NAMESPACES,
|
|
32
|
+
sortCompareFunction,
|
|
30
33
|
keysEqual,
|
|
31
34
|
getStorename,
|
|
32
35
|
getIndexKeys,
|
|
@@ -37,21 +40,17 @@ import {
|
|
|
37
40
|
const logger = new Logger('DataStore');
|
|
38
41
|
|
|
39
42
|
export class AsyncStorageAdapter implements Adapter {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
private namespaceResolver!: NamespaceResolver;
|
|
46
|
-
private modelInstanceCreator!: ModelInstanceCreator;
|
|
47
|
-
private getModelConstructorByModelName!: (
|
|
48
|
-
namsespaceName: NAMESPACES,
|
|
43
|
+
private schema: InternalSchema;
|
|
44
|
+
private namespaceResolver: NamespaceResolver;
|
|
45
|
+
private modelInstanceCreator: ModelInstanceCreator;
|
|
46
|
+
private getModelConstructorByModelName: (
|
|
47
|
+
namsespaceName: string,
|
|
49
48
|
modelName: string
|
|
50
49
|
) => PersistentModelConstructor<any>;
|
|
51
|
-
private db
|
|
52
|
-
private initPromise
|
|
53
|
-
private resolve
|
|
54
|
-
private reject
|
|
50
|
+
private db: AsyncStorageDatabase;
|
|
51
|
+
private initPromise: Promise<void>;
|
|
52
|
+
private resolve: (value?: any) => void;
|
|
53
|
+
private reject: (value?: any) => void;
|
|
55
54
|
|
|
56
55
|
private getStorenameForModel(
|
|
57
56
|
modelConstructor: PersistentModelConstructor<any>
|
|
@@ -89,7 +88,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
89
88
|
namespaceResolver: NamespaceResolver,
|
|
90
89
|
modelInstanceCreator: ModelInstanceCreator,
|
|
91
90
|
getModelConstructorByModelName: (
|
|
92
|
-
namsespaceName:
|
|
91
|
+
namsespaceName: string,
|
|
93
92
|
modelName: string
|
|
94
93
|
) => PersistentModelConstructor<any>
|
|
95
94
|
) {
|
|
@@ -132,7 +131,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
132
131
|
model,
|
|
133
132
|
this.schema.namespaces[namespaceName],
|
|
134
133
|
this.modelInstanceCreator,
|
|
135
|
-
this.getModelConstructorByModelName
|
|
134
|
+
this.getModelConstructorByModelName
|
|
136
135
|
);
|
|
137
136
|
|
|
138
137
|
const set = new Set<string>();
|
|
@@ -153,7 +152,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
153
152
|
|
|
154
153
|
if (condition && fromDB) {
|
|
155
154
|
const predicates = ModelPredicateCreator.getPredicates(condition);
|
|
156
|
-
const { predicates: predicateObjs, type } = predicates
|
|
155
|
+
const { predicates: predicateObjs, type } = predicates;
|
|
157
156
|
|
|
158
157
|
const isValid = validatePredicate(fromDB, type, predicateObjs);
|
|
159
158
|
|
|
@@ -190,16 +189,17 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
190
189
|
result.push([instance, opType]);
|
|
191
190
|
}
|
|
192
191
|
}
|
|
192
|
+
|
|
193
193
|
return result;
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
private async load<T>(
|
|
197
|
-
namespaceName:
|
|
197
|
+
namespaceName: string,
|
|
198
198
|
srcModelName: string,
|
|
199
199
|
records: T[]
|
|
200
200
|
): Promise<T[]> {
|
|
201
201
|
const namespace = this.schema.namespaces[namespaceName];
|
|
202
|
-
const relations = namespace.relationships
|
|
202
|
+
const relations = namespace.relationships[srcModelName].relationTypes;
|
|
203
203
|
const connectionStoreNames = relations.map(({ modelName }) => {
|
|
204
204
|
return getStorename(namespaceName, modelName);
|
|
205
205
|
});
|
|
@@ -214,6 +214,111 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
214
214
|
);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
for await (const relation of relations) {
|
|
218
|
+
const { fieldName, modelName, targetName, targetNames, relationType } =
|
|
219
|
+
relation;
|
|
220
|
+
const storeName = getStorename(namespaceName, modelName);
|
|
221
|
+
const modelConstructor = this.getModelConstructorByModelName(
|
|
222
|
+
namespaceName,
|
|
223
|
+
modelName
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
switch (relationType) {
|
|
227
|
+
case 'HAS_ONE':
|
|
228
|
+
for await (const recordItem of records) {
|
|
229
|
+
// ASYNC CPK TODO: make this cleaner
|
|
230
|
+
if (targetNames?.length) {
|
|
231
|
+
let getByFields = [];
|
|
232
|
+
let allPresent;
|
|
233
|
+
// iterate through all targetnames to make sure they are all present in the recordItem
|
|
234
|
+
allPresent = targetNames.every(targetName => {
|
|
235
|
+
return recordItem[targetName] != null;
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
if (!allPresent) {
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
getByFields = targetNames as any;
|
|
243
|
+
|
|
244
|
+
// keys are the key values
|
|
245
|
+
const keys = getByFields
|
|
246
|
+
.map(getByField => recordItem[getByField])
|
|
247
|
+
.join(DEFAULT_PRIMARY_KEY_VALUE_SEPARATOR);
|
|
248
|
+
|
|
249
|
+
const connectionRecord = await this.db.get(keys, storeName);
|
|
250
|
+
|
|
251
|
+
recordItem[fieldName] =
|
|
252
|
+
connectionRecord &&
|
|
253
|
+
this.modelInstanceCreator(modelConstructor, connectionRecord);
|
|
254
|
+
} else {
|
|
255
|
+
const getByfield = recordItem[targetName]
|
|
256
|
+
? targetName
|
|
257
|
+
: fieldName;
|
|
258
|
+
if (!recordItem[getByfield]) break;
|
|
259
|
+
|
|
260
|
+
const key = recordItem[getByfield];
|
|
261
|
+
|
|
262
|
+
const connectionRecord = await this.db.get(key, storeName);
|
|
263
|
+
|
|
264
|
+
recordItem[fieldName] =
|
|
265
|
+
connectionRecord &&
|
|
266
|
+
this.modelInstanceCreator(modelConstructor, connectionRecord);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
break;
|
|
271
|
+
case 'BELONGS_TO':
|
|
272
|
+
for await (const recordItem of records) {
|
|
273
|
+
// ASYNC CPK TODO: make this cleaner
|
|
274
|
+
if (targetNames?.length) {
|
|
275
|
+
let allPresent;
|
|
276
|
+
// iterate through all targetnames to make sure they are all present in the recordItem
|
|
277
|
+
allPresent = targetNames.every(targetName => {
|
|
278
|
+
return recordItem[targetName] != null;
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// If not present, there is not yet a connected record
|
|
282
|
+
if (!allPresent) {
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const keys = targetNames
|
|
287
|
+
.map(targetName => recordItem[targetName])
|
|
288
|
+
.join(DEFAULT_PRIMARY_KEY_VALUE_SEPARATOR);
|
|
289
|
+
|
|
290
|
+
// Retrieve the connected record
|
|
291
|
+
const connectionRecord = await this.db.get(keys, storeName);
|
|
292
|
+
|
|
293
|
+
recordItem[fieldName] =
|
|
294
|
+
connectionRecord &&
|
|
295
|
+
this.modelInstanceCreator(modelConstructor, connectionRecord);
|
|
296
|
+
|
|
297
|
+
targetNames?.map(targetName => {
|
|
298
|
+
delete recordItem[targetName];
|
|
299
|
+
});
|
|
300
|
+
} else if (recordItem[targetName as any]) {
|
|
301
|
+
const key = recordItem[targetName];
|
|
302
|
+
|
|
303
|
+
const connectionRecord = await this.db.get(key, storeName);
|
|
304
|
+
|
|
305
|
+
recordItem[fieldName] =
|
|
306
|
+
connectionRecord &&
|
|
307
|
+
this.modelInstanceCreator(modelConstructor, connectionRecord);
|
|
308
|
+
delete recordItem[targetName];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
break;
|
|
313
|
+
case 'HAS_MANY':
|
|
314
|
+
// TODO: Lazy loading
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
exhaustiveCheck(relationType);
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
217
322
|
return records.map(record =>
|
|
218
323
|
this.modelInstanceCreator(modelConstructor, record)
|
|
219
324
|
);
|
|
@@ -225,9 +330,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
225
330
|
pagination?: PaginationInput<T>
|
|
226
331
|
): Promise<T[]> {
|
|
227
332
|
const storeName = this.getStorenameForModel(modelConstructor);
|
|
228
|
-
const namespaceName = this.namespaceResolver(
|
|
229
|
-
modelConstructor
|
|
230
|
-
) as NAMESPACES;
|
|
333
|
+
const namespaceName = this.namespaceResolver(modelConstructor);
|
|
231
334
|
|
|
232
335
|
const predicates =
|
|
233
336
|
predicate && ModelPredicateCreator.getPredicates(predicate);
|
|
@@ -241,7 +344,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
241
344
|
const hasSort = pagination && pagination.sort;
|
|
242
345
|
const hasPagination = pagination && pagination.limit;
|
|
243
346
|
|
|
244
|
-
const records: T[] =
|
|
347
|
+
const records: T[] = await (async () => {
|
|
245
348
|
if (queryByKey) {
|
|
246
349
|
const record = await this.getByKey(storeName, queryByKey);
|
|
247
350
|
return record ? [record] : [];
|
|
@@ -258,7 +361,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
258
361
|
}
|
|
259
362
|
|
|
260
363
|
return this.getAll(storeName);
|
|
261
|
-
})()
|
|
364
|
+
})();
|
|
262
365
|
|
|
263
366
|
return await this.load(namespaceName, modelConstructor.name, records);
|
|
264
367
|
}
|
|
@@ -287,7 +390,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
287
390
|
return;
|
|
288
391
|
}
|
|
289
392
|
|
|
290
|
-
const keyValues = []
|
|
393
|
+
const keyValues = [];
|
|
291
394
|
|
|
292
395
|
for (const key of keys) {
|
|
293
396
|
const predicateObj = predicateObjs.find(
|
|
@@ -321,7 +424,26 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
321
424
|
records: T[],
|
|
322
425
|
pagination?: PaginationInput<T>
|
|
323
426
|
): T[] {
|
|
324
|
-
|
|
427
|
+
if (pagination && records.length > 1) {
|
|
428
|
+
if (pagination.sort) {
|
|
429
|
+
const sortPredicates = ModelSortPredicateCreator.getPredicates(
|
|
430
|
+
pagination.sort
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
if (sortPredicates.length) {
|
|
434
|
+
const compareFn = sortCompareFunction(sortPredicates);
|
|
435
|
+
records.sort(compareFn);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const { page = 0, limit = 0 } = pagination;
|
|
439
|
+
const start = Math.max(0, page * limit) || 0;
|
|
440
|
+
|
|
441
|
+
const end = limit > 0 ? start + limit : records.length;
|
|
442
|
+
|
|
443
|
+
return records.slice(start, end);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return records;
|
|
325
447
|
}
|
|
326
448
|
|
|
327
449
|
async queryOne<T extends PersistentModel>(
|
|
@@ -341,15 +463,14 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
341
463
|
const deleteQueue: { storeName: string; items: T[] }[] = [];
|
|
342
464
|
|
|
343
465
|
if (isModelConstructor(modelOrModelConstructor)) {
|
|
344
|
-
const modelConstructor =
|
|
345
|
-
|
|
346
|
-
const nameSpace = this.namespaceResolver(modelConstructor) as NAMESPACES;
|
|
466
|
+
const modelConstructor = modelOrModelConstructor;
|
|
467
|
+
const nameSpace = this.namespaceResolver(modelConstructor);
|
|
347
468
|
|
|
348
469
|
// models to be deleted.
|
|
349
|
-
const models = await this.query(modelConstructor, condition
|
|
470
|
+
const models = await this.query(modelConstructor, condition);
|
|
350
471
|
// TODO: refactor this to use a function like getRelations()
|
|
351
472
|
const relations =
|
|
352
|
-
this.schema.namespaces[nameSpace].relationships
|
|
473
|
+
this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
|
|
353
474
|
.relationTypes;
|
|
354
475
|
|
|
355
476
|
if (condition !== undefined) {
|
|
@@ -388,11 +509,11 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
388
509
|
return [models, deletedModels];
|
|
389
510
|
}
|
|
390
511
|
} else {
|
|
391
|
-
const model = modelOrModelConstructor
|
|
512
|
+
const model = modelOrModelConstructor;
|
|
392
513
|
|
|
393
514
|
const modelConstructor = Object.getPrototypeOf(model)
|
|
394
515
|
.constructor as PersistentModelConstructor<T>;
|
|
395
|
-
const
|
|
516
|
+
const namespaceName = this.namespaceResolver(modelConstructor);
|
|
396
517
|
|
|
397
518
|
const storeName = this.getStorenameForModel(modelConstructor);
|
|
398
519
|
|
|
@@ -409,7 +530,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
409
530
|
}
|
|
410
531
|
|
|
411
532
|
const predicates = ModelPredicateCreator.getPredicates(condition);
|
|
412
|
-
const { predicates: predicateObjs, type } = predicates
|
|
533
|
+
const { predicates: predicateObjs, type } = predicates;
|
|
413
534
|
|
|
414
535
|
const isValid = validatePredicate(fromDB, type, predicateObjs);
|
|
415
536
|
if (!isValid) {
|
|
@@ -420,19 +541,20 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
420
541
|
}
|
|
421
542
|
|
|
422
543
|
const relations =
|
|
423
|
-
this.schema.namespaces[
|
|
544
|
+
this.schema.namespaces[namespaceName].relationships[
|
|
424
545
|
modelConstructor.name
|
|
425
546
|
].relationTypes;
|
|
547
|
+
|
|
426
548
|
await this.deleteTraverse(
|
|
427
549
|
relations,
|
|
428
550
|
[model],
|
|
429
551
|
modelConstructor.name,
|
|
430
|
-
|
|
552
|
+
namespaceName,
|
|
431
553
|
deleteQueue
|
|
432
554
|
);
|
|
433
555
|
} else {
|
|
434
556
|
const relations =
|
|
435
|
-
this.schema.namespaces[
|
|
557
|
+
this.schema.namespaces[namespaceName].relationships[
|
|
436
558
|
modelConstructor.name
|
|
437
559
|
].relationTypes;
|
|
438
560
|
|
|
@@ -440,7 +562,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
440
562
|
relations,
|
|
441
563
|
[model],
|
|
442
564
|
modelConstructor.name,
|
|
443
|
-
|
|
565
|
+
namespaceName,
|
|
444
566
|
deleteQueue
|
|
445
567
|
);
|
|
446
568
|
}
|
|
@@ -459,7 +581,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
459
581
|
private async deleteItem<T extends PersistentModel>(
|
|
460
582
|
deleteQueue?: { storeName: string; items: T[] | IDBValidKey[] }[]
|
|
461
583
|
) {
|
|
462
|
-
for await (const deleteItem of deleteQueue
|
|
584
|
+
for await (const deleteItem of deleteQueue) {
|
|
463
585
|
const { storeName, items } = deleteItem;
|
|
464
586
|
|
|
465
587
|
for await (const item of items) {
|
|
@@ -472,7 +594,6 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
472
594
|
}
|
|
473
595
|
}
|
|
474
596
|
}
|
|
475
|
-
|
|
476
597
|
/**
|
|
477
598
|
* Populates the delete Queue with all the items to delete
|
|
478
599
|
* @param relations
|
|
@@ -485,7 +606,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
485
606
|
relations: RelationType[],
|
|
486
607
|
models: T[],
|
|
487
608
|
srcModel: string,
|
|
488
|
-
nameSpace:
|
|
609
|
+
nameSpace: string,
|
|
489
610
|
deleteQueue: { storeName: string; items: T[] }[]
|
|
490
611
|
): Promise<void> {
|
|
491
612
|
for await (const rel of relations) {
|
|
@@ -500,7 +621,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
500
621
|
|
|
501
622
|
const index: string | undefined =
|
|
502
623
|
getIndex(
|
|
503
|
-
this.schema.namespaces[nameSpace].relationships
|
|
624
|
+
this.schema.namespaces[nameSpace].relationships[modelName]
|
|
504
625
|
.relationTypes,
|
|
505
626
|
srcModel
|
|
506
627
|
) ||
|
|
@@ -508,8 +629,8 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
508
629
|
// i.e. for keyName connections, attempt to find one by the
|
|
509
630
|
// associatedWith property
|
|
510
631
|
getIndexFromAssociation(
|
|
511
|
-
this.schema.namespaces[nameSpace].relationships
|
|
512
|
-
rel.associatedWith
|
|
632
|
+
this.schema.namespaces[nameSpace].relationships[modelName].indexes,
|
|
633
|
+
rel.associatedWith
|
|
513
634
|
);
|
|
514
635
|
|
|
515
636
|
switch (relationType) {
|
|
@@ -581,7 +702,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
581
702
|
}
|
|
582
703
|
|
|
583
704
|
await this.deleteTraverse<T>(
|
|
584
|
-
this.schema.namespaces[nameSpace].relationships
|
|
705
|
+
this.schema.namespaces[nameSpace].relationships[modelName]
|
|
585
706
|
.relationTypes,
|
|
586
707
|
recordToDelete,
|
|
587
708
|
modelName,
|
|
@@ -590,10 +711,10 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
590
711
|
);
|
|
591
712
|
} else {
|
|
592
713
|
const hasOneIndex = index || associatedWith;
|
|
593
|
-
const hasOneCustomField = targetName
|
|
714
|
+
const hasOneCustomField = targetName in model;
|
|
594
715
|
const keyValuesPath: string = this.getIndexKeyValuesPath(model);
|
|
595
716
|
const value = hasOneCustomField
|
|
596
|
-
? model[targetName
|
|
717
|
+
? model[targetName]
|
|
597
718
|
: keyValuesPath;
|
|
598
719
|
|
|
599
720
|
if (!value) break;
|
|
@@ -605,7 +726,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
605
726
|
) as T[];
|
|
606
727
|
|
|
607
728
|
await this.deleteTraverse<T>(
|
|
608
|
-
this.schema.namespaces[nameSpace].relationships
|
|
729
|
+
this.schema.namespaces[nameSpace].relationships[modelName]
|
|
609
730
|
.relationTypes,
|
|
610
731
|
recordToDelete,
|
|
611
732
|
modelName,
|
|
@@ -622,14 +743,14 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
622
743
|
|
|
623
744
|
const allRecords = await this.db.getAll(storeName);
|
|
624
745
|
|
|
625
|
-
const indices = index
|
|
746
|
+
const indices = index.split(IDENTIFIER_KEY_SEPARATOR);
|
|
626
747
|
|
|
627
748
|
const childrenArray = allRecords.filter(childItem =>
|
|
628
749
|
indices.every(index => keyValues.includes(childItem[index]))
|
|
629
750
|
) as T[];
|
|
630
751
|
|
|
631
752
|
await this.deleteTraverse<T>(
|
|
632
|
-
this.schema.namespaces[nameSpace].relationships
|
|
753
|
+
this.schema.namespaces[nameSpace].relationships[modelName]
|
|
633
754
|
.relationTypes,
|
|
634
755
|
childrenArray,
|
|
635
756
|
modelName,
|
|
@@ -642,7 +763,8 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
642
763
|
// Intentionally blank
|
|
643
764
|
break;
|
|
644
765
|
default:
|
|
645
|
-
|
|
766
|
+
exhaustiveCheck(relationType);
|
|
767
|
+
break;
|
|
646
768
|
}
|
|
647
769
|
}
|
|
648
770
|
|
|
@@ -660,8 +782,8 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
660
782
|
async clear(): Promise<void> {
|
|
661
783
|
await this.db.clear();
|
|
662
784
|
|
|
663
|
-
this.db = undefined
|
|
664
|
-
this.initPromise = undefined
|
|
785
|
+
this.db = undefined;
|
|
786
|
+
this.initPromise = undefined;
|
|
665
787
|
}
|
|
666
788
|
|
|
667
789
|
async batchSave<T extends PersistentModel>(
|
|
@@ -690,7 +812,7 @@ export class AsyncStorageAdapter implements Adapter {
|
|
|
690
812
|
const { instance } = connectedModels.find(({ instance }) => {
|
|
691
813
|
const instanceKeyValuesPath = this.getIndexKeyValuesPath(instance);
|
|
692
814
|
return keysEqual([instanceKeyValuesPath], [keyValuesPath]);
|
|
693
|
-
})
|
|
815
|
+
});
|
|
694
816
|
|
|
695
817
|
batch.push(instance);
|
|
696
818
|
}
|
|
@@ -50,7 +50,7 @@ class AsyncStorageDatabase {
|
|
|
50
50
|
monotonicFactoriesMap.set(storeName, monotonicUlidFactory());
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
return monotonicFactoriesMap.get(storeName)
|
|
53
|
+
return monotonicFactoriesMap.get(storeName);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
async init(): Promise<void> {
|
|
@@ -58,7 +58,7 @@ class AsyncStorageDatabase {
|
|
|
58
58
|
|
|
59
59
|
const allKeys: string[] = await this.storage.getAllKeys();
|
|
60
60
|
|
|
61
|
-
const keysForCollectionEntries
|
|
61
|
+
const keysForCollectionEntries = [];
|
|
62
62
|
|
|
63
63
|
for (const key of allKeys) {
|
|
64
64
|
const [dbName, storeName, recordType, ulidOrId, id] = key.split('::');
|
|
@@ -79,7 +79,7 @@ class AsyncStorageDatabase {
|
|
|
79
79
|
|
|
80
80
|
const item = await this.storage.getItem(oldKey);
|
|
81
81
|
|
|
82
|
-
await this.storage.setItem(newKey, item
|
|
82
|
+
await this.storage.setItem(newKey, item);
|
|
83
83
|
await this.storage.removeItem(oldKey);
|
|
84
84
|
|
|
85
85
|
ulid = newUlid;
|
|
@@ -87,7 +87,7 @@ class AsyncStorageDatabase {
|
|
|
87
87
|
ulid = ulidOrId;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
this.getCollectionIndex(storeName)
|
|
90
|
+
this.getCollectionIndex(storeName).set(id, ulid);
|
|
91
91
|
} else if (recordType === COLLECTION) {
|
|
92
92
|
keysForCollectionEntries.push(key);
|
|
93
93
|
}
|
|
@@ -108,14 +108,14 @@ class AsyncStorageDatabase {
|
|
|
108
108
|
const idxName = indexNameFromKeys(keys);
|
|
109
109
|
|
|
110
110
|
const ulid =
|
|
111
|
-
this.getCollectionIndex(storeName)
|
|
111
|
+
this.getCollectionIndex(storeName).get(idxName) ||
|
|
112
112
|
this.getMonotonicFactory(storeName)();
|
|
113
113
|
|
|
114
114
|
// Retrieve db key for item
|
|
115
115
|
const itemKey = this.getKeyForItem(storeName, keyValuesPath, ulid);
|
|
116
116
|
|
|
117
117
|
// Set key in collection index
|
|
118
|
-
this.getCollectionIndex(storeName)
|
|
118
|
+
this.getCollectionIndex(storeName).set(keyValuesPath, ulid);
|
|
119
119
|
|
|
120
120
|
// Save item in db
|
|
121
121
|
await this.storage.setItem(itemKey, JSON.stringify(item));
|
|
@@ -131,12 +131,11 @@ class AsyncStorageDatabase {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
const result: [T, OpType][] = [];
|
|
134
|
-
|
|
135
|
-
const collection = this.getCollectionIndex(storeName)!;
|
|
134
|
+
const collection = this.getCollectionIndex(storeName);
|
|
136
135
|
|
|
137
136
|
const keysToDelete = new Set<string>();
|
|
138
137
|
const keysToSave = new Set<string>();
|
|
139
|
-
const allItemsKeys
|
|
138
|
+
const allItemsKeys = [];
|
|
140
139
|
const itemsMap: Record<string, { ulid: string; model: T }> = {};
|
|
141
140
|
|
|
142
141
|
/* Populate allItemKeys, keysToDelete, and keysToSave */
|
|
@@ -253,7 +252,7 @@ class AsyncStorageDatabase {
|
|
|
253
252
|
keyValuePath: string,
|
|
254
253
|
storeName: string
|
|
255
254
|
): Promise<T> {
|
|
256
|
-
const ulid = this.getCollectionIndex(storeName)
|
|
255
|
+
const ulid = this.getCollectionIndex(storeName).get(keyValuePath);
|
|
257
256
|
const itemKey = this.getKeyForItem(storeName, keyValuePath, ulid);
|
|
258
257
|
const recordAsString = await this.storage.getItem(itemKey);
|
|
259
258
|
const record = recordAsString && JSON.parse(recordAsString);
|
|
@@ -261,19 +260,19 @@ class AsyncStorageDatabase {
|
|
|
261
260
|
}
|
|
262
261
|
|
|
263
262
|
async getOne(firstOrLast: QueryOne, storeName: string) {
|
|
264
|
-
const collection = this.getCollectionIndex(storeName)
|
|
263
|
+
const collection = this.getCollectionIndex(storeName);
|
|
265
264
|
|
|
266
265
|
const [itemId, ulid] =
|
|
267
266
|
firstOrLast === QueryOne.FIRST
|
|
268
267
|
? (() => {
|
|
269
268
|
let id: string, ulid: string;
|
|
270
269
|
for ([id, ulid] of collection) break; // Get first element of the set
|
|
271
|
-
return [id
|
|
270
|
+
return [id, ulid];
|
|
272
271
|
})()
|
|
273
272
|
: (() => {
|
|
274
273
|
let id: string, ulid: string;
|
|
275
274
|
for ([id, ulid] of collection); // Get last element of the set
|
|
276
|
-
return [id
|
|
275
|
+
return [id, ulid];
|
|
277
276
|
})();
|
|
278
277
|
const itemKey = this.getKeyForItem(storeName, itemId, ulid);
|
|
279
278
|
|
|
@@ -292,7 +291,7 @@ class AsyncStorageDatabase {
|
|
|
292
291
|
storeName: string,
|
|
293
292
|
pagination?: PaginationInput<T>
|
|
294
293
|
): Promise<T[]> {
|
|
295
|
-
const collection = this.getCollectionIndex(storeName)
|
|
294
|
+
const collection = this.getCollectionIndex(storeName);
|
|
296
295
|
|
|
297
296
|
const { page = 0, limit = 0 } = pagination || {};
|
|
298
297
|
const start = Math.max(0, page * limit) || 0;
|
|
@@ -323,9 +322,9 @@ class AsyncStorageDatabase {
|
|
|
323
322
|
}
|
|
324
323
|
|
|
325
324
|
async delete(key: string, storeName: string) {
|
|
326
|
-
const ulid = this.getCollectionIndex(storeName)
|
|
325
|
+
const ulid = this.getCollectionIndex(storeName).get(key);
|
|
327
326
|
const itemKey = this.getKeyForItem(storeName, key, ulid);
|
|
328
|
-
this.getCollectionIndex(storeName)
|
|
327
|
+
this.getCollectionIndex(storeName).delete(key);
|
|
329
328
|
await this.storage.removeItem(itemKey);
|
|
330
329
|
}
|
|
331
330
|
|
|
@@ -6,14 +6,11 @@ export class InMemoryStore {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
multiGet = async (keys: string[]) => {
|
|
9
|
-
return keys.reduce(
|
|
10
|
-
(res, k) => (res.push([k, this.db.get(k)!]), res),
|
|
11
|
-
[] as [string, string][]
|
|
12
|
-
);
|
|
9
|
+
return keys.reduce((res, k) => (res.push([k, this.db.get(k)]), res), []);
|
|
13
10
|
};
|
|
14
11
|
|
|
15
12
|
multiRemove = async (keys: string[], callback?) => {
|
|
16
|
-
keys.forEach(
|
|
13
|
+
keys.forEach(k => this.db.delete(k));
|
|
17
14
|
|
|
18
15
|
typeof callback === 'function' && callback();
|
|
19
16
|
};
|