@aws-amplify/datastore 3.12.12 → 3.12.13-custom-pk.1
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/aws-amplify-datastore.js +1854 -965
- package/dist/aws-amplify-datastore.js.map +1 -1
- package/dist/aws-amplify-datastore.min.js +7 -7
- package/dist/aws-amplify-datastore.min.js.map +1 -1
- package/lib/datastore/datastore.d.ts +13 -16
- package/lib/datastore/datastore.js +130 -63
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.d.ts +3 -19
- package/lib/predicates/index.d.ts +3 -2
- package/lib/predicates/index.js +12 -2
- package/lib/predicates/index.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +4 -3
- package/lib/storage/adapter/AsyncStorageAdapter.js +354 -203
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +14 -4
- package/lib/storage/adapter/AsyncStorageDatabase.js +65 -28
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +5 -4
- package/lib/storage/adapter/IndexedDBAdapter.js +389 -267
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/index.d.ts +1 -1
- package/lib/storage/storage.d.ts +1 -1
- package/lib/storage/storage.js +92 -27
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/index.d.ts +21 -4
- package/lib/sync/index.js +13 -11
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.d.ts +3 -3
- package/lib/sync/merger.js +7 -6
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.d.ts +2 -2
- package/lib/sync/outbox.js +11 -9
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/mutation.js +60 -42
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.d.ts +3 -2
- package/lib/sync/utils.js +61 -8
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.d.ts +64 -25
- package/lib/types.js +10 -1
- package/lib/types.js.map +1 -1
- package/lib/util.d.ts +56 -24
- package/lib/util.js +334 -170
- package/lib/util.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +13 -16
- package/lib-esm/datastore/datastore.js +132 -65
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +3 -19
- package/lib-esm/predicates/index.d.ts +3 -2
- package/lib-esm/predicates/index.js +13 -3
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +4 -3
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +355 -204
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +14 -4
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +66 -29
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +5 -4
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +390 -268
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/index.d.ts +1 -1
- package/lib-esm/storage/storage.d.ts +1 -1
- package/lib-esm/storage/storage.js +92 -27
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/index.d.ts +21 -4
- package/lib-esm/sync/index.js +15 -13
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.d.ts +3 -3
- package/lib-esm/sync/merger.js +7 -6
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.d.ts +2 -2
- package/lib-esm/sync/outbox.js +12 -10
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/mutation.js +61 -43
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +3 -2
- package/lib-esm/sync/utils.js +62 -10
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +64 -25
- package/lib-esm/types.js +9 -2
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +56 -24
- package/lib-esm/util.js +334 -170
- package/lib-esm/util.js.map +1 -1
- package/package.json +7 -7
- package/src/datastore/datastore.ts +253 -113
- package/src/predicates/index.ts +32 -10
- package/src/storage/adapter/AsyncStorageAdapter.ts +309 -93
- package/src/storage/adapter/AsyncStorageDatabase.ts +74 -26
- package/src/storage/adapter/IndexedDBAdapter.ts +319 -136
- package/src/storage/adapter/index.ts +1 -1
- package/src/storage/storage.ts +68 -21
- package/src/sync/index.ts +41 -26
- package/src/sync/merger.ts +14 -4
- package/src/sync/outbox.ts +21 -8
- package/src/sync/processors/mutation.ts +49 -45
- package/src/sync/processors/subscription.ts +0 -1
- package/src/sync/processors/sync.ts +1 -3
- package/src/sync/utils.ts +69 -12
- package/src/types.ts +181 -29
- package/src/util.ts +415 -176
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
GraphQLScalarType,
|
|
30
30
|
InternalSchema,
|
|
31
31
|
isGraphQLScalarType,
|
|
32
|
+
isSchemaModelWithAttributes,
|
|
32
33
|
ModelFieldType,
|
|
33
34
|
ModelInit,
|
|
34
35
|
ModelInstanceMetadata,
|
|
@@ -57,10 +58,16 @@ import {
|
|
|
57
58
|
isNonModelFieldType,
|
|
58
59
|
isModelFieldType,
|
|
59
60
|
ObserveQueryOptions,
|
|
61
|
+
ManagedIdentifier,
|
|
62
|
+
PersistentModelMetaData,
|
|
63
|
+
IdentifierFieldOrIdentifierObject,
|
|
64
|
+
__modelMeta__,
|
|
65
|
+
isIdentifierObject,
|
|
60
66
|
AmplifyContext,
|
|
61
67
|
} from '../types';
|
|
62
68
|
import {
|
|
63
69
|
DATASTORE,
|
|
70
|
+
errorMessages,
|
|
64
71
|
establishRelationAndKeys,
|
|
65
72
|
exhaustiveCheck,
|
|
66
73
|
isModelConstructor,
|
|
@@ -73,9 +80,14 @@ import {
|
|
|
73
80
|
registerNonModelClass,
|
|
74
81
|
sortCompareFunction,
|
|
75
82
|
DeferredCallbackResolver,
|
|
83
|
+
extractPrimaryKeyFieldNames,
|
|
84
|
+
extractPrimaryKeysAndValues,
|
|
85
|
+
isIdManaged,
|
|
86
|
+
isIdOptionallyManaged,
|
|
76
87
|
validatePredicate,
|
|
77
88
|
mergePatches,
|
|
78
89
|
} from '../util';
|
|
90
|
+
import { getIdentifierValue } from '../sync/utils';
|
|
79
91
|
|
|
80
92
|
setAutoFreeze(true);
|
|
81
93
|
enablePatches();
|
|
@@ -85,11 +97,16 @@ const logger = new Logger('DataStore');
|
|
|
85
97
|
const ulid = monotonicUlidFactory(Date.now());
|
|
86
98
|
const { isNode } = JS.browserOrNode();
|
|
87
99
|
|
|
100
|
+
type SettingMetaData = {
|
|
101
|
+
identifier: ManagedIdentifier<Setting, 'id'>;
|
|
102
|
+
readOnlyFields: never;
|
|
103
|
+
};
|
|
88
104
|
declare class Setting {
|
|
89
|
-
|
|
105
|
+
public readonly [__modelMeta__]: SettingMetaData;
|
|
106
|
+
constructor(init: ModelInit<Setting, SettingMetaData>);
|
|
90
107
|
static copyOf(
|
|
91
108
|
src: Setting,
|
|
92
|
-
mutator: (draft: MutableModel<Setting>) => void | Setting
|
|
109
|
+
mutator: (draft: MutableModel<Setting, SettingMetaData>) => void | Setting
|
|
93
110
|
): Setting;
|
|
94
111
|
public readonly id: string;
|
|
95
112
|
public readonly key: string;
|
|
@@ -266,16 +283,15 @@ const createTypeClasses: (
|
|
|
266
283
|
|
|
267
284
|
export declare type ModelInstanceCreator = typeof modelInstanceCreator;
|
|
268
285
|
|
|
269
|
-
const instancesMetadata = new WeakSet<
|
|
270
|
-
|
|
271
|
-
>(
|
|
272
|
-
function modelInstanceCreator<T extends PersistentModel = PersistentModel>(
|
|
286
|
+
const instancesMetadata = new WeakSet<ModelInit<unknown, unknown>>();
|
|
287
|
+
|
|
288
|
+
function modelInstanceCreator<T extends PersistentModel>(
|
|
273
289
|
modelConstructor: PersistentModelConstructor<T>,
|
|
274
|
-
init:
|
|
290
|
+
init: Partial<T>
|
|
275
291
|
): T {
|
|
276
292
|
instancesMetadata.add(init);
|
|
277
293
|
|
|
278
|
-
return
|
|
294
|
+
return new modelConstructor(<ModelInit<T, PersistentModelMetaData<T>>>init);
|
|
279
295
|
}
|
|
280
296
|
|
|
281
297
|
const validateModelFields =
|
|
@@ -293,6 +309,14 @@ const validateModelFields =
|
|
|
293
309
|
throw new Error(`Field ${name} is required`);
|
|
294
310
|
}
|
|
295
311
|
|
|
312
|
+
if (isSchemaModelWithAttributes(modelDefinition) && !isIdManaged(modelDefinition)) {
|
|
313
|
+
const keys = extractPrimaryKeyFieldNames(modelDefinition);
|
|
314
|
+
if (keys.includes(k) && v === '') {
|
|
315
|
+
logger.error(errorMessages.idEmptyString, { k, value: v });
|
|
316
|
+
throw new Error(errorMessages.idEmptyString);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
296
320
|
if (isGraphQLScalarType(type)) {
|
|
297
321
|
const jsType = GraphQLScalarType.getJSType(type);
|
|
298
322
|
const validateScalar = GraphQLScalarType.getValidationFunction(type);
|
|
@@ -403,7 +427,7 @@ const castInstanceType = (
|
|
|
403
427
|
return v;
|
|
404
428
|
};
|
|
405
429
|
|
|
406
|
-
const initializeInstance = <T>(
|
|
430
|
+
const initializeInstance = <T extends PersistentModel>(
|
|
407
431
|
init: ModelInit<T>,
|
|
408
432
|
modelDefinition: SchemaModel | SchemaNonModel,
|
|
409
433
|
draft: Draft<T & ModelInstanceMetadata>
|
|
@@ -427,31 +451,39 @@ const createModelClass = <T extends PersistentModel>(
|
|
|
427
451
|
(draft: Draft<T & ModelInstanceMetadata>) => {
|
|
428
452
|
initializeInstance(init, modelDefinition, draft);
|
|
429
453
|
|
|
454
|
+
// model is initialized inside a DataStore component (e.g. by Sync Engine, Storage Engine, etc.)
|
|
455
|
+
const isInternallyInitialized = instancesMetadata.has(init);
|
|
456
|
+
|
|
430
457
|
const modelInstanceMetadata: ModelInstanceMetadata =
|
|
431
|
-
|
|
458
|
+
isInternallyInitialized
|
|
432
459
|
? <ModelInstanceMetadata>(<unknown>init)
|
|
433
460
|
: <ModelInstanceMetadata>{};
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (
|
|
461
|
+
|
|
462
|
+
type ModelWithIDIdentifier = { id: string };
|
|
463
|
+
|
|
464
|
+
const { id: _id } =
|
|
465
|
+
modelInstanceMetadata as unknown as ModelWithIDIdentifier;
|
|
466
|
+
|
|
467
|
+
if (isIdManaged(modelDefinition)) {
|
|
468
|
+
const isInternalModel = _id !== null && _id !== undefined;
|
|
469
|
+
|
|
470
|
+
const id = isInternalModel
|
|
471
|
+
? _id
|
|
472
|
+
: modelDefinition.syncable
|
|
473
|
+
? uuid4()
|
|
474
|
+
: ulid();
|
|
475
|
+
|
|
476
|
+
(<ModelWithIDIdentifier>(<unknown>draft)).id = id;
|
|
477
|
+
} else if (isIdOptionallyManaged(modelDefinition)) {
|
|
478
|
+
// only auto-populate if the id was not provided
|
|
479
|
+
(<ModelWithIDIdentifier>(<unknown>draft)).id = draft.id || uuid4();
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (!isInternallyInitialized) {
|
|
451
483
|
checkReadOnlyPropertyOnCreate(draft, modelDefinition);
|
|
452
484
|
}
|
|
453
485
|
|
|
454
|
-
|
|
486
|
+
const { _version, _lastChangedAt, _deleted } = modelInstanceMetadata;
|
|
455
487
|
|
|
456
488
|
if (modelDefinition.syncable) {
|
|
457
489
|
draft._version = _version;
|
|
@@ -476,8 +508,12 @@ const createModelClass = <T extends PersistentModel>(
|
|
|
476
508
|
const model = produce(
|
|
477
509
|
source,
|
|
478
510
|
draft => {
|
|
479
|
-
fn(<MutableModel<T>>
|
|
480
|
-
|
|
511
|
+
fn(<MutableModel<T>>draft);
|
|
512
|
+
|
|
513
|
+
const keyNames = extractPrimaryKeyFieldNames(modelDefinition);
|
|
514
|
+
// Keys are immutable
|
|
515
|
+
keyNames.forEach(key => ((draft as Object)[key] = source[key]));
|
|
516
|
+
|
|
481
517
|
const modelValidator = validateModelFields(modelDefinition);
|
|
482
518
|
Object.entries(draft).forEach(([k, v]) => {
|
|
483
519
|
const parsedValue = castInstanceType(modelDefinition, k, v);
|
|
@@ -489,6 +525,7 @@ const createModelClass = <T extends PersistentModel>(
|
|
|
489
525
|
);
|
|
490
526
|
|
|
491
527
|
const hasExistingPatches = modelPatchesMap.has(source);
|
|
528
|
+
|
|
492
529
|
if (patches.length || hasExistingPatches) {
|
|
493
530
|
if (hasExistingPatches) {
|
|
494
531
|
const [existingPatches, existingSource] = modelPatchesMap.get(source);
|
|
@@ -516,6 +553,7 @@ const createModelClass = <T extends PersistentModel>(
|
|
|
516
553
|
}
|
|
517
554
|
|
|
518
555
|
const instance = modelInstanceCreator(clazz, json);
|
|
556
|
+
|
|
519
557
|
const modelValidator = validateModelFields(modelDefinition);
|
|
520
558
|
|
|
521
559
|
Object.entries(instance).forEach(([k, v]) => {
|
|
@@ -563,7 +601,9 @@ const checkReadOnlyPropertyOnUpdate = (
|
|
|
563
601
|
});
|
|
564
602
|
};
|
|
565
603
|
|
|
566
|
-
const createNonModelClass = <T>(
|
|
604
|
+
const createNonModelClass = <T extends PersistentModel>(
|
|
605
|
+
typeDefinition: SchemaNonModel
|
|
606
|
+
) => {
|
|
567
607
|
const clazz = <NonModelTypeConstructor<T>>(<unknown>class Model {
|
|
568
608
|
constructor(init: ModelInit<T>) {
|
|
569
609
|
const instance = produce(
|
|
@@ -647,7 +687,6 @@ async function checkSchemaVersion(
|
|
|
647
687
|
const [schemaVersionSetting] = await s.query(
|
|
648
688
|
Setting,
|
|
649
689
|
ModelPredicateCreator.createFromExisting(modelDefinition, c =>
|
|
650
|
-
// @ts-ignore Argument of type '"eq"' is not assignable to parameter of type 'never'.
|
|
651
690
|
c.key('eq', SETTING_SCHEMA_VERSION)
|
|
652
691
|
),
|
|
653
692
|
{ page: 0, limit: 1 }
|
|
@@ -724,12 +763,12 @@ class DataStore {
|
|
|
724
763
|
private conflictHandler: ConflictHandler;
|
|
725
764
|
private errorHandler: (error: SyncError<PersistentModel>) => void;
|
|
726
765
|
private fullSyncInterval: number;
|
|
727
|
-
private initialized
|
|
766
|
+
private initialized?: Promise<void>;
|
|
728
767
|
private initReject: Function;
|
|
729
768
|
private initResolve: Function;
|
|
730
769
|
private maxRecordsToSync: number;
|
|
731
|
-
private storage
|
|
732
|
-
private sync
|
|
770
|
+
private storage?: Storage;
|
|
771
|
+
private sync?: SyncEngine;
|
|
733
772
|
private syncPageSize: number;
|
|
734
773
|
private syncExpressions: SyncExpression[];
|
|
735
774
|
private syncPredicates: WeakMap<SchemaModel, ModelPredicate<any>> =
|
|
@@ -839,7 +878,10 @@ class DataStore {
|
|
|
839
878
|
query: {
|
|
840
879
|
<T extends PersistentModel>(
|
|
841
880
|
modelConstructor: PersistentModelConstructor<T>,
|
|
842
|
-
|
|
881
|
+
identifier: IdentifierFieldOrIdentifierObject<
|
|
882
|
+
T,
|
|
883
|
+
PersistentModelMetaData<T>
|
|
884
|
+
>
|
|
843
885
|
): Promise<T | undefined>;
|
|
844
886
|
<T extends PersistentModel>(
|
|
845
887
|
modelConstructor: PersistentModelConstructor<T>,
|
|
@@ -848,7 +890,10 @@ class DataStore {
|
|
|
848
890
|
): Promise<T[]>;
|
|
849
891
|
} = async <T extends PersistentModel>(
|
|
850
892
|
modelConstructor: PersistentModelConstructor<T>,
|
|
851
|
-
|
|
893
|
+
identifierOrCriteria?:
|
|
894
|
+
| IdentifierFieldOrIdentifierObject<T, PersistentModelMetaData<T>>
|
|
895
|
+
| ProducerModelPredicate<T>
|
|
896
|
+
| typeof PredicateAll,
|
|
852
897
|
paginationProducer?: ProducerPaginationInput<T>
|
|
853
898
|
): Promise<T | T[] | undefined> => {
|
|
854
899
|
await this.start();
|
|
@@ -862,28 +907,44 @@ class DataStore {
|
|
|
862
907
|
throw new Error(msg);
|
|
863
908
|
}
|
|
864
909
|
|
|
865
|
-
if (typeof
|
|
910
|
+
if (typeof identifierOrCriteria === 'string') {
|
|
866
911
|
if (paginationProducer !== undefined) {
|
|
867
912
|
logger.warn('Pagination is ignored when querying by id');
|
|
868
913
|
}
|
|
869
914
|
}
|
|
870
915
|
|
|
871
916
|
const modelDefinition = getModelDefinition(modelConstructor);
|
|
917
|
+
const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
|
|
918
|
+
|
|
872
919
|
let predicate: ModelPredicate<T>;
|
|
873
920
|
|
|
874
|
-
if (isQueryOne(
|
|
875
|
-
|
|
921
|
+
if (isQueryOne(identifierOrCriteria)) {
|
|
922
|
+
if (keyFields.length > 1) {
|
|
923
|
+
const msg = errorMessages.queryByPkWithCompositeKeyPresent;
|
|
924
|
+
logger.error(msg, { keyFields });
|
|
925
|
+
|
|
926
|
+
throw new Error(msg);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
predicate = ModelPredicateCreator.createForSingleField<T>(
|
|
876
930
|
modelDefinition,
|
|
877
|
-
|
|
931
|
+
keyFields[0],
|
|
932
|
+
identifierOrCriteria
|
|
878
933
|
);
|
|
879
934
|
} else {
|
|
880
|
-
|
|
935
|
+
// Object is being queried using object literal syntax
|
|
936
|
+
if (isIdentifierObject(<T>identifierOrCriteria, modelDefinition)) {
|
|
937
|
+
predicate = ModelPredicateCreator.createForPk<T>(
|
|
938
|
+
modelDefinition,
|
|
939
|
+
<T>identifierOrCriteria
|
|
940
|
+
);
|
|
941
|
+
} else if (isPredicatesAll(identifierOrCriteria)) {
|
|
881
942
|
// Predicates.ALL means "all records", so no predicate (undefined)
|
|
882
943
|
predicate = undefined;
|
|
883
944
|
} else {
|
|
884
945
|
predicate = ModelPredicateCreator.createFromExisting(
|
|
885
946
|
modelDefinition,
|
|
886
|
-
|
|
947
|
+
<any>identifierOrCriteria
|
|
887
948
|
);
|
|
888
949
|
}
|
|
889
950
|
}
|
|
@@ -913,7 +974,11 @@ class DataStore {
|
|
|
913
974
|
pagination
|
|
914
975
|
);
|
|
915
976
|
|
|
916
|
-
|
|
977
|
+
const returnOne =
|
|
978
|
+
isQueryOne(identifierOrCriteria) ||
|
|
979
|
+
isIdentifierObject(identifierOrCriteria, modelDefinition);
|
|
980
|
+
|
|
981
|
+
return returnOne ? result[0] : result;
|
|
917
982
|
};
|
|
918
983
|
|
|
919
984
|
save = async <T extends PersistentModel>(
|
|
@@ -926,7 +991,7 @@ class DataStore {
|
|
|
926
991
|
// Allows us to only include changed fields for updates
|
|
927
992
|
const patchesTuple = modelPatchesMap.get(model);
|
|
928
993
|
|
|
929
|
-
const modelConstructor: PersistentModelConstructor<T> = model
|
|
994
|
+
const modelConstructor: PersistentModelConstructor<T> | undefined = model
|
|
930
995
|
? <PersistentModelConstructor<T>>model.constructor
|
|
931
996
|
: undefined;
|
|
932
997
|
|
|
@@ -941,15 +1006,15 @@ class DataStore {
|
|
|
941
1006
|
|
|
942
1007
|
const producedCondition = ModelPredicateCreator.createFromExisting(
|
|
943
1008
|
modelDefinition,
|
|
944
|
-
condition
|
|
1009
|
+
condition!
|
|
945
1010
|
);
|
|
946
1011
|
|
|
947
1012
|
const [savedModel] = await this.storage.runExclusive(async s => {
|
|
948
1013
|
await s.save(model, producedCondition, undefined, patchesTuple);
|
|
949
1014
|
|
|
950
|
-
return s.query(
|
|
1015
|
+
return s.query<T>(
|
|
951
1016
|
modelConstructor,
|
|
952
|
-
ModelPredicateCreator.
|
|
1017
|
+
ModelPredicateCreator.createForPk(modelDefinition, model)
|
|
953
1018
|
);
|
|
954
1019
|
});
|
|
955
1020
|
|
|
@@ -989,22 +1054,28 @@ class DataStore {
|
|
|
989
1054
|
};
|
|
990
1055
|
|
|
991
1056
|
delete: {
|
|
992
|
-
<T extends PersistentModel>(
|
|
993
|
-
model: T,
|
|
994
|
-
condition?: ProducerModelPredicate<T>
|
|
995
|
-
): Promise<T>;
|
|
996
1057
|
<T extends PersistentModel>(
|
|
997
1058
|
modelConstructor: PersistentModelConstructor<T>,
|
|
998
|
-
|
|
1059
|
+
identifier: IdentifierFieldOrIdentifierObject<
|
|
1060
|
+
T,
|
|
1061
|
+
PersistentModelMetaData<T>
|
|
1062
|
+
>
|
|
999
1063
|
): Promise<T[]>;
|
|
1000
1064
|
<T extends PersistentModel>(
|
|
1001
1065
|
modelConstructor: PersistentModelConstructor<T>,
|
|
1002
1066
|
condition: ProducerModelPredicate<T> | typeof PredicateAll
|
|
1003
1067
|
): Promise<T[]>;
|
|
1068
|
+
<T extends PersistentModel>(
|
|
1069
|
+
model: T,
|
|
1070
|
+
condition?: ProducerModelPredicate<T>
|
|
1071
|
+
): Promise<T>;
|
|
1004
1072
|
} = async <T extends PersistentModel>(
|
|
1005
1073
|
modelOrConstructor: T | PersistentModelConstructor<T>,
|
|
1006
|
-
|
|
1007
|
-
|
|
1074
|
+
identifierOrCriteria?:
|
|
1075
|
+
| IdentifierFieldOrIdentifierObject<T, PersistentModelMetaData<T>>
|
|
1076
|
+
| ProducerModelPredicate<T>
|
|
1077
|
+
| typeof PredicateAll
|
|
1078
|
+
): Promise<T | T[]> => {
|
|
1008
1079
|
await this.start();
|
|
1009
1080
|
|
|
1010
1081
|
let condition: ModelPredicate<T>;
|
|
@@ -1016,31 +1087,50 @@ class DataStore {
|
|
|
1016
1087
|
throw new Error(msg);
|
|
1017
1088
|
}
|
|
1018
1089
|
|
|
1019
|
-
if (isValidModelConstructor(modelOrConstructor)) {
|
|
1090
|
+
if (isValidModelConstructor<T>(modelOrConstructor)) {
|
|
1020
1091
|
const modelConstructor = modelOrConstructor;
|
|
1021
1092
|
|
|
1022
|
-
if (!
|
|
1093
|
+
if (!identifierOrCriteria) {
|
|
1023
1094
|
const msg =
|
|
1024
1095
|
'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
|
|
1025
|
-
logger.error(msg, {
|
|
1096
|
+
logger.error(msg, { identifierOrCriteria });
|
|
1026
1097
|
|
|
1027
1098
|
throw new Error(msg);
|
|
1028
1099
|
}
|
|
1029
1100
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1101
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1102
|
+
|
|
1103
|
+
if (typeof identifierOrCriteria === 'string') {
|
|
1104
|
+
const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
|
|
1105
|
+
|
|
1106
|
+
if (keyFields.length > 1) {
|
|
1107
|
+
const msg = errorMessages.deleteByPkWithCompositeKeyPresent;
|
|
1108
|
+
logger.error(msg, { keyFields });
|
|
1109
|
+
|
|
1110
|
+
throw new Error(msg);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
condition = ModelPredicateCreator.createForSingleField<T>(
|
|
1032
1114
|
getModelDefinition(modelConstructor),
|
|
1033
|
-
|
|
1115
|
+
keyFields[0],
|
|
1116
|
+
identifierOrCriteria
|
|
1034
1117
|
);
|
|
1035
1118
|
} else {
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1119
|
+
if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
|
|
1120
|
+
condition = ModelPredicateCreator.createForPk<T>(
|
|
1121
|
+
modelDefinition,
|
|
1122
|
+
<T>identifierOrCriteria
|
|
1123
|
+
);
|
|
1124
|
+
} else {
|
|
1125
|
+
condition = ModelPredicateCreator.createFromExisting(
|
|
1126
|
+
modelDefinition,
|
|
1127
|
+
/**
|
|
1128
|
+
* idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
|
|
1129
|
+
* The symbol is used only for typing purposes. e.g. see Predicates.ALL
|
|
1130
|
+
*/
|
|
1131
|
+
identifierOrCriteria as ProducerModelPredicate<T>
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1044
1134
|
|
|
1045
1135
|
if (!condition || !ModelPredicateCreator.isValidPredicate(condition)) {
|
|
1046
1136
|
const msg =
|
|
@@ -1068,22 +1158,24 @@ class DataStore {
|
|
|
1068
1158
|
|
|
1069
1159
|
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1070
1160
|
|
|
1071
|
-
const
|
|
1161
|
+
const pkPredicate = ModelPredicateCreator.createForPk<T>(
|
|
1072
1162
|
modelDefinition,
|
|
1073
|
-
model
|
|
1163
|
+
model
|
|
1074
1164
|
);
|
|
1075
1165
|
|
|
1076
|
-
if (
|
|
1077
|
-
if (typeof
|
|
1166
|
+
if (identifierOrCriteria) {
|
|
1167
|
+
if (typeof identifierOrCriteria !== 'function') {
|
|
1078
1168
|
const msg = 'Invalid criteria';
|
|
1079
|
-
logger.error(msg, {
|
|
1169
|
+
logger.error(msg, { identifierOrCriteria });
|
|
1080
1170
|
|
|
1081
1171
|
throw new Error(msg);
|
|
1082
1172
|
}
|
|
1083
1173
|
|
|
1084
|
-
condition =
|
|
1174
|
+
condition = (<ProducerModelPredicate<T>>identifierOrCriteria)(
|
|
1175
|
+
pkPredicate
|
|
1176
|
+
);
|
|
1085
1177
|
} else {
|
|
1086
|
-
condition =
|
|
1178
|
+
condition = pkPredicate;
|
|
1087
1179
|
}
|
|
1088
1180
|
|
|
1089
1181
|
const [[deleted]] = await this.storage.delete(model, condition);
|
|
@@ -1095,20 +1187,28 @@ class DataStore {
|
|
|
1095
1187
|
observe: {
|
|
1096
1188
|
(): Observable<SubscriptionMessage<PersistentModel>>;
|
|
1097
1189
|
|
|
1098
|
-
<T extends PersistentModel>(
|
|
1190
|
+
<T extends PersistentModel>(
|
|
1191
|
+
modelConstructor: PersistentModelConstructor<T>,
|
|
1192
|
+
identifier: string
|
|
1193
|
+
): Observable<SubscriptionMessage<T>>;
|
|
1099
1194
|
|
|
1100
1195
|
<T extends PersistentModel>(
|
|
1101
1196
|
modelConstructor: PersistentModelConstructor<T>,
|
|
1102
|
-
criteria?:
|
|
1197
|
+
criteria?: ProducerModelPredicate<T> | typeof PredicateAll
|
|
1103
1198
|
): Observable<SubscriptionMessage<T>>;
|
|
1104
|
-
|
|
1199
|
+
|
|
1200
|
+
<T extends PersistentModel>(model: T): Observable<SubscriptionMessage<T>>;
|
|
1201
|
+
} = <T extends PersistentModel>(
|
|
1105
1202
|
modelOrConstructor?: T | PersistentModelConstructor<T>,
|
|
1106
|
-
|
|
1203
|
+
identifierOrCriteria?:
|
|
1204
|
+
| string
|
|
1205
|
+
| ProducerModelPredicate<T>
|
|
1206
|
+
| typeof PredicateAll
|
|
1107
1207
|
): Observable<SubscriptionMessage<T>> => {
|
|
1108
1208
|
let predicate: ModelPredicate<T>;
|
|
1109
1209
|
|
|
1110
|
-
const modelConstructor: PersistentModelConstructor<T> =
|
|
1111
|
-
modelOrConstructor && isValidModelConstructor(modelOrConstructor)
|
|
1210
|
+
const modelConstructor: PersistentModelConstructor<T> | undefined =
|
|
1211
|
+
modelOrConstructor && isValidModelConstructor<T>(modelOrConstructor)
|
|
1112
1212
|
? modelOrConstructor
|
|
1113
1213
|
: undefined;
|
|
1114
1214
|
|
|
@@ -1118,10 +1218,10 @@ class DataStore {
|
|
|
1118
1218
|
model && (<Object>Object.getPrototypeOf(model)).constructor;
|
|
1119
1219
|
|
|
1120
1220
|
if (isValidModelConstructor<T>(modelConstructor)) {
|
|
1121
|
-
if (
|
|
1221
|
+
if (identifierOrCriteria) {
|
|
1122
1222
|
logger.warn('idOrCriteria is ignored when using a model instance', {
|
|
1123
1223
|
model,
|
|
1124
|
-
|
|
1224
|
+
identifierOrCriteria,
|
|
1125
1225
|
});
|
|
1126
1226
|
}
|
|
1127
1227
|
|
|
@@ -1135,9 +1235,24 @@ class DataStore {
|
|
|
1135
1235
|
}
|
|
1136
1236
|
}
|
|
1137
1237
|
|
|
1138
|
-
|
|
1238
|
+
// observe should not accept object literal syntax
|
|
1239
|
+
if (
|
|
1240
|
+
identifierOrCriteria &&
|
|
1241
|
+
modelConstructor &&
|
|
1242
|
+
isIdentifierObject(
|
|
1243
|
+
identifierOrCriteria,
|
|
1244
|
+
getModelDefinition(modelConstructor)
|
|
1245
|
+
)
|
|
1246
|
+
) {
|
|
1247
|
+
const msg = errorMessages.observeWithObjectLiteral;
|
|
1248
|
+
logger.error(msg, { objectLiteral: identifierOrCriteria });
|
|
1249
|
+
|
|
1250
|
+
throw new Error(msg);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
if (identifierOrCriteria !== undefined && modelConstructor === undefined) {
|
|
1139
1254
|
const msg = 'Cannot provide criteria without a modelConstructor';
|
|
1140
|
-
logger.error(msg,
|
|
1255
|
+
logger.error(msg, identifierOrCriteria);
|
|
1141
1256
|
throw new Error(msg);
|
|
1142
1257
|
}
|
|
1143
1258
|
|
|
@@ -1148,18 +1263,26 @@ class DataStore {
|
|
|
1148
1263
|
throw new Error(msg);
|
|
1149
1264
|
}
|
|
1150
1265
|
|
|
1151
|
-
if (typeof
|
|
1152
|
-
|
|
1266
|
+
if (typeof identifierOrCriteria === 'string') {
|
|
1267
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1268
|
+
const [keyField] = extractPrimaryKeyFieldNames(modelDefinition);
|
|
1269
|
+
|
|
1270
|
+
predicate = ModelPredicateCreator.createForSingleField<T>(
|
|
1153
1271
|
getModelDefinition(modelConstructor),
|
|
1154
|
-
|
|
1272
|
+
keyField,
|
|
1273
|
+
identifierOrCriteria
|
|
1155
1274
|
);
|
|
1156
1275
|
} else {
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1276
|
+
if (isPredicatesAll(identifierOrCriteria)) {
|
|
1277
|
+
predicate = undefined;
|
|
1278
|
+
} else {
|
|
1279
|
+
predicate =
|
|
1280
|
+
modelConstructor &&
|
|
1281
|
+
ModelPredicateCreator.createFromExisting<T>(
|
|
1282
|
+
getModelDefinition(modelConstructor),
|
|
1283
|
+
identifierOrCriteria
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1163
1286
|
}
|
|
1164
1287
|
|
|
1165
1288
|
return new Observable<SubscriptionMessage<T>>(observer => {
|
|
@@ -1181,12 +1304,18 @@ class DataStore {
|
|
|
1181
1304
|
|
|
1182
1305
|
let message = item;
|
|
1183
1306
|
|
|
1184
|
-
// as
|
|
1307
|
+
// as long as we're not dealing with a DELETE, we need to fetch a fresh
|
|
1185
1308
|
// item from storage to ensure it's fully populated.
|
|
1186
1309
|
if (item.opType !== 'DELETE') {
|
|
1310
|
+
const modelDefinition = getModelDefinition(item.model);
|
|
1311
|
+
const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
|
|
1312
|
+
const primaryKeysAndValues = extractPrimaryKeysAndValues(
|
|
1313
|
+
item.element,
|
|
1314
|
+
keyFields
|
|
1315
|
+
);
|
|
1187
1316
|
const freshElement = await this.query(
|
|
1188
1317
|
item.model,
|
|
1189
|
-
|
|
1318
|
+
primaryKeysAndValues
|
|
1190
1319
|
);
|
|
1191
1320
|
message = {
|
|
1192
1321
|
...message,
|
|
@@ -1215,7 +1344,7 @@ class DataStore {
|
|
|
1215
1344
|
criteria?: ProducerModelPredicate<T> | typeof PredicateAll,
|
|
1216
1345
|
paginationProducer?: ObserveQueryOptions<T>
|
|
1217
1346
|
): Observable<DataStoreSnapshot<T>>;
|
|
1218
|
-
} = <T extends PersistentModel
|
|
1347
|
+
} = <T extends PersistentModel>(
|
|
1219
1348
|
model: PersistentModelConstructor<T>,
|
|
1220
1349
|
criteria?: ProducerModelPredicate<T> | typeof PredicateAll,
|
|
1221
1350
|
options?: ObserveQueryOptions<T>
|
|
@@ -1254,9 +1383,12 @@ class DataStore {
|
|
|
1254
1383
|
const sortOptions = sort ? { sort } : undefined;
|
|
1255
1384
|
|
|
1256
1385
|
const modelDefinition = getModelDefinition(model);
|
|
1386
|
+
const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
|
|
1387
|
+
|
|
1257
1388
|
if (isQueryOne(criteria)) {
|
|
1258
|
-
predicate = ModelPredicateCreator.
|
|
1389
|
+
predicate = ModelPredicateCreator.createForSingleField<T>(
|
|
1259
1390
|
modelDefinition,
|
|
1391
|
+
keyFields[0],
|
|
1260
1392
|
criteria
|
|
1261
1393
|
);
|
|
1262
1394
|
} else {
|
|
@@ -1278,9 +1410,11 @@ class DataStore {
|
|
|
1278
1410
|
(async () => {
|
|
1279
1411
|
try {
|
|
1280
1412
|
// first, query and return any locally-available records
|
|
1281
|
-
(await this.query(model, criteria, sortOptions)).forEach(item =>
|
|
1282
|
-
|
|
1283
|
-
|
|
1413
|
+
(await this.query(model, criteria, sortOptions)).forEach(item => {
|
|
1414
|
+
const itemModelDefinition = getModelDefinition(model);
|
|
1415
|
+
const idOrPk = getIdentifierValue(itemModelDefinition, item);
|
|
1416
|
+
items.set(idOrPk, item);
|
|
1417
|
+
});
|
|
1284
1418
|
|
|
1285
1419
|
// Observe the model and send a stream of updates (debounced).
|
|
1286
1420
|
// We need to post-filter results instead of passing criteria through
|
|
@@ -1288,19 +1422,21 @@ class DataStore {
|
|
|
1288
1422
|
// We need to explicitly remove those items from the existing snapshot.
|
|
1289
1423
|
handle = this.observe(model).subscribe(
|
|
1290
1424
|
({ element, model, opType }) => {
|
|
1425
|
+
const itemModelDefinition = getModelDefinition(model);
|
|
1426
|
+
const idOrPk = getIdentifierValue(itemModelDefinition, element);
|
|
1291
1427
|
if (
|
|
1292
1428
|
hasPredicate &&
|
|
1293
1429
|
!validatePredicate(element, predicateGroupType, predicates)
|
|
1294
1430
|
) {
|
|
1295
1431
|
if (
|
|
1296
1432
|
opType === 'UPDATE' &&
|
|
1297
|
-
(items.has(
|
|
1433
|
+
(items.has(idOrPk) || itemsChanged.has(idOrPk))
|
|
1298
1434
|
) {
|
|
1299
1435
|
// tracking as a "deleted item" will include the item in
|
|
1300
1436
|
// page limit calculations and ensure it is removed from the
|
|
1301
1437
|
// final items collection, regardless of which collection(s)
|
|
1302
1438
|
// it is currently in. (I mean, it could be in both, right!?)
|
|
1303
|
-
deletedItemIds.push(
|
|
1439
|
+
deletedItemIds.push(idOrPk);
|
|
1304
1440
|
} else {
|
|
1305
1441
|
// ignore updates for irrelevant/filtered items.
|
|
1306
1442
|
return;
|
|
@@ -1312,9 +1448,9 @@ class DataStore {
|
|
|
1312
1448
|
// in the `mergePage` method within src/sync/merger.ts. The final state of a model instance
|
|
1313
1449
|
// depends on the LATEST record (for a given id).
|
|
1314
1450
|
if (opType === 'DELETE') {
|
|
1315
|
-
deletedItemIds.push(
|
|
1451
|
+
deletedItemIds.push(idOrPk);
|
|
1316
1452
|
} else {
|
|
1317
|
-
itemsChanged.set(
|
|
1453
|
+
itemsChanged.set(idOrPk, element);
|
|
1318
1454
|
}
|
|
1319
1455
|
|
|
1320
1456
|
const isSynced = this.sync?.getModelSyncedStatus(model) ?? false;
|
|
@@ -1356,10 +1492,14 @@ class DataStore {
|
|
|
1356
1492
|
}
|
|
1357
1493
|
|
|
1358
1494
|
items.clear();
|
|
1359
|
-
itemsArray.forEach(item =>
|
|
1495
|
+
itemsArray.forEach(item => {
|
|
1496
|
+
const itemModelDefinition = getModelDefinition(model);
|
|
1497
|
+
const idOrPk = getIdentifierValue(itemModelDefinition, item);
|
|
1498
|
+
items.set(idOrPk, item);
|
|
1499
|
+
});
|
|
1360
1500
|
|
|
1361
1501
|
// remove deleted items from the final result set
|
|
1362
|
-
deletedItemIds.forEach(
|
|
1502
|
+
deletedItemIds.forEach(idOrPk => items.delete(idOrPk));
|
|
1363
1503
|
|
|
1364
1504
|
return {
|
|
1365
1505
|
items: Array.from(items.values()),
|
|
@@ -1515,7 +1655,7 @@ class DataStore {
|
|
|
1515
1655
|
this.storageAdapter ||
|
|
1516
1656
|
undefined;
|
|
1517
1657
|
|
|
1518
|
-
this.sessionId = this.retrieveSessionId()
|
|
1658
|
+
this.sessionId = this.retrieveSessionId()!;
|
|
1519
1659
|
};
|
|
1520
1660
|
|
|
1521
1661
|
clear = async function clear() {
|
|
@@ -1549,7 +1689,7 @@ class DataStore {
|
|
|
1549
1689
|
this.syncPredicates = new WeakMap<SchemaModel, ModelPredicate<any>>();
|
|
1550
1690
|
};
|
|
1551
1691
|
|
|
1552
|
-
stop = async function stop() {
|
|
1692
|
+
stop = async function stop(this: InstanceType<typeof DataStore>) {
|
|
1553
1693
|
if (this.initialized !== undefined) {
|
|
1554
1694
|
await this.start();
|
|
1555
1695
|
}
|
|
@@ -1713,9 +1853,9 @@ class DataStore {
|
|
|
1713
1853
|
|
|
1714
1854
|
return `${sessionId}-${appSyncId}`;
|
|
1715
1855
|
}
|
|
1716
|
-
} catch {
|
|
1717
|
-
|
|
1718
|
-
|
|
1856
|
+
} catch {}
|
|
1857
|
+
|
|
1858
|
+
return undefined;
|
|
1719
1859
|
}
|
|
1720
1860
|
}
|
|
1721
1861
|
|