@aws-amplify/datastore 3.14.4 → 3.14.5-unstable.4

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.
Files changed (178) hide show
  1. package/CHANGELOG.md +0 -8
  2. package/lib/authModeStrategies/defaultAuthStrategy.d.ts +2 -0
  3. package/lib/authModeStrategies/index.d.ts +2 -0
  4. package/lib/authModeStrategies/multiAuthStrategy.d.ts +13 -0
  5. package/lib/authModeStrategies/multiAuthStrategy.js +6 -64
  6. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  7. package/lib/datastore/datastore.d.ts +207 -0
  8. package/lib/datastore/datastore.js +703 -297
  9. package/lib/datastore/datastore.js.map +1 -1
  10. package/lib/index.d.ts +16 -0
  11. package/lib/index.js +6 -4
  12. package/lib/index.js.map +1 -1
  13. package/lib/predicates/index.d.ts +30 -0
  14. package/lib/predicates/index.js +127 -6
  15. package/lib/predicates/index.js.map +1 -1
  16. package/lib/predicates/next.d.ts +301 -0
  17. package/lib/predicates/next.js +816 -0
  18. package/lib/predicates/next.js.map +1 -0
  19. package/lib/predicates/sort.d.ts +8 -0
  20. package/lib/predicates/sort.js +10 -4
  21. package/lib/predicates/sort.js.map +1 -1
  22. package/lib/ssr/index.d.ts +3 -0
  23. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +42 -0
  24. package/lib/storage/adapter/AsyncStorageAdapter.js +141 -382
  25. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  26. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +39 -0
  27. package/lib/storage/adapter/AsyncStorageDatabase.js +37 -98
  28. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  29. package/lib/storage/adapter/InMemoryStore.d.ts +11 -0
  30. package/lib/storage/adapter/InMemoryStore.js +16 -67
  31. package/lib/storage/adapter/InMemoryStore.js.map +1 -1
  32. package/lib/storage/adapter/InMemoryStore.native.d.ts +1 -0
  33. package/lib/storage/adapter/InMemoryStore.native.js +2 -4
  34. package/lib/storage/adapter/InMemoryStore.native.js.map +1 -1
  35. package/lib/storage/adapter/IndexedDBAdapter.d.ts +61 -0
  36. package/lib/storage/adapter/IndexedDBAdapter.js +275 -419
  37. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  38. package/lib/storage/adapter/getDefaultAdapter/index.d.ts +3 -0
  39. package/lib/storage/adapter/getDefaultAdapter/index.js +3 -5
  40. package/lib/storage/adapter/getDefaultAdapter/index.js.map +1 -1
  41. package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +3 -0
  42. package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -4
  43. package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +1 -1
  44. package/lib/storage/adapter/index.d.ts +9 -0
  45. package/lib/storage/relationship.d.ts +140 -0
  46. package/lib/storage/relationship.js +335 -0
  47. package/lib/storage/relationship.js.map +1 -0
  48. package/lib/storage/storage.d.ts +50 -0
  49. package/lib/storage/storage.js +72 -143
  50. package/lib/storage/storage.js.map +1 -1
  51. package/lib/sync/datastoreConnectivity.d.ts +16 -0
  52. package/lib/sync/datastoreConnectivity.js +6 -55
  53. package/lib/sync/datastoreConnectivity.js.map +1 -1
  54. package/lib/sync/datastoreReachability/index.d.ts +3 -0
  55. package/lib/sync/datastoreReachability/index.native.d.ts +3 -0
  56. package/lib/sync/datastoreReachability/index.native.js +2 -4
  57. package/lib/sync/datastoreReachability/index.native.js.map +1 -1
  58. package/lib/sync/index.d.ts +89 -0
  59. package/lib/sync/index.js +49 -124
  60. package/lib/sync/index.js.map +1 -1
  61. package/lib/sync/merger.d.ts +17 -0
  62. package/lib/sync/merger.js +8 -74
  63. package/lib/sync/merger.js.map +1 -1
  64. package/lib/sync/outbox.d.ts +27 -0
  65. package/lib/sync/outbox.js +24 -97
  66. package/lib/sync/outbox.js.map +1 -1
  67. package/lib/sync/processors/errorMaps.d.ts +17 -0
  68. package/lib/sync/processors/errorMaps.js +5 -35
  69. package/lib/sync/processors/errorMaps.js.map +1 -1
  70. package/lib/sync/processors/mutation.d.ts +58 -0
  71. package/lib/sync/processors/mutation.js +47 -131
  72. package/lib/sync/processors/mutation.js.map +1 -1
  73. package/lib/sync/processors/subscription.d.ts +33 -0
  74. package/lib/sync/processors/subscription.js +29 -102
  75. package/lib/sync/processors/subscription.js.map +1 -1
  76. package/lib/sync/processors/sync.d.ts +28 -0
  77. package/lib/sync/processors/sync.js +26 -102
  78. package/lib/sync/processors/sync.js.map +1 -1
  79. package/lib/sync/utils.d.ts +42 -0
  80. package/lib/sync/utils.js +40 -103
  81. package/lib/sync/utils.js.map +1 -1
  82. package/lib/types.d.ts +554 -0
  83. package/lib/types.js +9 -39
  84. package/lib/types.js.map +1 -1
  85. package/lib/util.d.ts +189 -0
  86. package/lib/util.js +192 -188
  87. package/lib/util.js.map +1 -1
  88. package/lib-esm/authModeStrategies/multiAuthStrategy.js +2 -57
  89. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  90. package/lib-esm/datastore/datastore.d.ts +59 -8
  91. package/lib-esm/datastore/datastore.js +642 -234
  92. package/lib-esm/datastore/datastore.js.map +1 -1
  93. package/lib-esm/index.d.ts +3 -2
  94. package/lib-esm/index.js +2 -1
  95. package/lib-esm/index.js.map +1 -1
  96. package/lib-esm/predicates/index.d.ts +16 -2
  97. package/lib-esm/predicates/index.js +128 -7
  98. package/lib-esm/predicates/index.js.map +1 -1
  99. package/lib-esm/predicates/next.d.ts +301 -0
  100. package/lib-esm/predicates/next.js +812 -0
  101. package/lib-esm/predicates/next.js.map +1 -0
  102. package/lib-esm/predicates/sort.js +10 -4
  103. package/lib-esm/predicates/sort.js.map +1 -1
  104. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +2 -1
  105. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +112 -350
  106. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  107. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +7 -68
  108. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  109. package/lib-esm/storage/adapter/InMemoryStore.d.ts +1 -1
  110. package/lib-esm/storage/adapter/InMemoryStore.js +1 -52
  111. package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
  112. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +4 -2
  113. package/lib-esm/storage/adapter/IndexedDBAdapter.js +230 -367
  114. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  115. package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +1 -1
  116. package/lib-esm/storage/relationship.d.ts +140 -0
  117. package/lib-esm/storage/relationship.js +333 -0
  118. package/lib-esm/storage/relationship.js.map +1 -0
  119. package/lib-esm/storage/storage.d.ts +7 -6
  120. package/lib-esm/storage/storage.js +33 -101
  121. package/lib-esm/storage/storage.js.map +1 -1
  122. package/lib-esm/sync/datastoreConnectivity.js +1 -47
  123. package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
  124. package/lib-esm/sync/index.js +4 -76
  125. package/lib-esm/sync/index.js.map +1 -1
  126. package/lib-esm/sync/merger.js +1 -67
  127. package/lib-esm/sync/merger.js.map +1 -1
  128. package/lib-esm/sync/outbox.js +1 -74
  129. package/lib-esm/sync/outbox.js.map +1 -1
  130. package/lib-esm/sync/processors/errorMaps.js +2 -32
  131. package/lib-esm/sync/processors/errorMaps.js.map +1 -1
  132. package/lib-esm/sync/processors/mutation.js +12 -93
  133. package/lib-esm/sync/processors/mutation.js.map +1 -1
  134. package/lib-esm/sync/processors/subscription.js +6 -69
  135. package/lib-esm/sync/processors/subscription.js.map +1 -1
  136. package/lib-esm/sync/processors/sync.js +2 -75
  137. package/lib-esm/sync/processors/sync.js.map +1 -1
  138. package/lib-esm/sync/utils.d.ts +1 -1
  139. package/lib-esm/sync/utils.js +32 -95
  140. package/lib-esm/sync/utils.js.map +1 -1
  141. package/lib-esm/types.d.ts +63 -10
  142. package/lib-esm/types.js +7 -38
  143. package/lib-esm/types.js.map +1 -1
  144. package/lib-esm/util.d.ts +39 -6
  145. package/lib-esm/util.js +171 -171
  146. package/lib-esm/util.js.map +1 -1
  147. package/package.json +21 -14
  148. package/src/authModeStrategies/multiAuthStrategy.ts +2 -2
  149. package/src/datastore/datastore.ts +699 -206
  150. package/src/index.ts +4 -0
  151. package/src/predicates/index.ts +143 -17
  152. package/src/predicates/next.ts +967 -0
  153. package/src/predicates/sort.ts +8 -2
  154. package/src/storage/adapter/AsyncStorageAdapter.ts +59 -181
  155. package/src/storage/adapter/AsyncStorageDatabase.ts +16 -15
  156. package/src/storage/adapter/InMemoryStore.ts +5 -2
  157. package/src/storage/adapter/IndexedDBAdapter.ts +169 -192
  158. package/src/storage/adapter/getDefaultAdapter/index.ts +2 -2
  159. package/src/storage/relationship.ts +272 -0
  160. package/src/storage/storage.ts +56 -37
  161. package/src/sync/datastoreConnectivity.ts +4 -4
  162. package/src/sync/index.ts +22 -28
  163. package/src/sync/merger.ts +1 -1
  164. package/src/sync/outbox.ts +6 -6
  165. package/src/sync/processors/errorMaps.ts +1 -1
  166. package/src/sync/processors/mutation.ts +23 -19
  167. package/src/sync/processors/subscription.ts +20 -16
  168. package/src/sync/processors/sync.ts +17 -17
  169. package/src/sync/utils.ts +42 -48
  170. package/src/types.ts +128 -16
  171. package/src/util.ts +108 -150
  172. package/build.js +0 -5
  173. package/dist/aws-amplify-datastore.js +0 -92787
  174. package/dist/aws-amplify-datastore.js.map +0 -1
  175. package/dist/aws-amplify-datastore.min.js +0 -66
  176. package/dist/aws-amplify-datastore.min.js.map +0 -1
  177. package/index.js +0 -7
  178. package/webpack.config.dev.js +0 -6
@@ -0,0 +1,272 @@
1
+ import { isFieldAssociation, ModelFieldType, ModelMeta } from '../types';
2
+
3
+ /**
4
+ * Defines a relationship from a LOCAL model.field to a REMOTE model.field and helps
5
+ * navigate the relationship, providing a simplified peek at the relationship details
6
+ * pertinent to setting FK's and constructing join conditions.
7
+ *
8
+ * Because I mean, relationships are tough.
9
+ *
10
+ */
11
+ export class ModelRelationship<T> {
12
+ private localModel: ModelMeta<T>;
13
+ private _field: string;
14
+
15
+ /**
16
+ * @param modelDefinition The "local" model.
17
+ * @param field The "local" model field.
18
+ */
19
+ constructor(model: ModelMeta<T>, field: string) {
20
+ if (!isFieldAssociation(model.schema, field)) {
21
+ throw new Error(`${model.schema.name}.${field} is not a relationship.`);
22
+ }
23
+ this.localModel = model;
24
+ this._field = field;
25
+ }
26
+
27
+ /**
28
+ * Returns a ModelRelationship for the the given model and field if the pair
29
+ * indicates a relationship to another model. Else, returns `null`.
30
+ *
31
+ * @param model The model the relationship field exists in.
32
+ * @param field The field that may relates the local model to the remote model.
33
+ */
34
+ static from<T>(model: ModelMeta<T>, field: string) {
35
+ if (isFieldAssociation(model.schema, field)) {
36
+ return new this(model, field);
37
+ } else {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Enumerates all valid `ModelRelationship`'s on the given model.
44
+ *
45
+ * @param model The model definition to enumerate relationships of.
46
+ */
47
+ static allFrom<T>(model: ModelMeta<T>) {
48
+ const relationships: ModelRelationship<T>[] = [];
49
+ for (const field of Object.keys(model.schema.fields)) {
50
+ const relationship = ModelRelationship.from(model, field);
51
+ relationship && relationships.push(relationship);
52
+ }
53
+ return relationships;
54
+ }
55
+
56
+ private get localDefinition() {
57
+ return this.localModel.schema;
58
+ }
59
+
60
+ /**
61
+ * The virtual/computed field on the local model that should contain
62
+ * the related model.
63
+ */
64
+ get field() {
65
+ return this._field;
66
+ }
67
+
68
+ /**
69
+ * The constructor that can be used to query DataStore or create instance for
70
+ * the local model.
71
+ */
72
+ get localConstructor() {
73
+ return this.localModel.builder;
74
+ }
75
+
76
+ /**
77
+ * The name/type of the relationship the local model has with the remote model
78
+ * via the defined local model field.
79
+ */
80
+ get type() {
81
+ return this.localAssocation.connectionType;
82
+ }
83
+
84
+ /**
85
+ * Raw details about the local FK as-is from the local model's field definition in
86
+ * the schema. This field requires interpretation.
87
+ *
88
+ * @see localJoinFields
89
+ * @see localAssociatedWith
90
+ */
91
+ private get localAssocation() {
92
+ return this.localDefinition.fields[this.field].association!;
93
+ }
94
+
95
+ /**
96
+ * The field names on the local model that can be used to query or queried to match
97
+ * with instances of the remote model.
98
+ *
99
+ * Fields are returned in-order to match the order of `this.remoteKeyFields`.
100
+ */
101
+ get localJoinFields() {
102
+ /**
103
+ * This is relatively straightforward, actually.
104
+ *
105
+ * If we have explicitly stated targetNames, codegen is telling us authoritatively
106
+ * to use those fields for this relationship. The local model "points to" fields
107
+ * in the remote one.
108
+ *
109
+ * In other cases, the remote model points to this one's
110
+ */
111
+ if (this.localAssocation.targetName) {
112
+ // This case is theoretically unnecessary going forward.
113
+ return [this.localAssocation.targetName];
114
+ } else if (this.localAssocation.targetNames) {
115
+ return this.localAssocation.targetNames;
116
+ } else {
117
+ return this.localPKFields;
118
+ }
119
+ }
120
+
121
+ /**
122
+ * The field names on the local model that uniquely identify it.
123
+ *
124
+ * These fields may or may not be relevant to the join fields.
125
+ */
126
+ get localPKFields() {
127
+ return this.localModel.pkField;
128
+ }
129
+
130
+ get remoteDefinition() {
131
+ return this.remoteModelType.modelConstructor?.schema;
132
+ }
133
+
134
+ private get remoteModelType() {
135
+ return this.localDefinition.fields[this.field].type as ModelFieldType;
136
+ }
137
+
138
+ /**
139
+ * Constructor that can be used to query DataStore or create instances for
140
+ * the remote model.
141
+ */
142
+ get remoteModelConstructor() {
143
+ return this.remoteModelType.modelConstructor!.builder!;
144
+ }
145
+
146
+ /**
147
+ * The field names on the remote model that uniquely identify it.
148
+ *
149
+ * These fields may or may not be relevant to the join fields.
150
+ */
151
+ get remotePKFields() {
152
+ return this.remoteModelType.modelConstructor?.pkField || ['id'];
153
+ }
154
+
155
+ /**
156
+ * The `associatedWith` fields from the local perspective.
157
+ *
158
+ * When present, these fields indicate which fields on the remote model to use
159
+ * when looking for a remote association and/or determining the final remote
160
+ * key fields.
161
+ */
162
+ private get localAssociatedWith() {
163
+ if (
164
+ this.localAssocation.connectionType === 'HAS_MANY' ||
165
+ this.localAssocation.connectionType === 'HAS_ONE'
166
+ ) {
167
+ // This de-arraying is theoretically unnecessary going forward.
168
+ return Array.isArray(this.localAssocation.associatedWith)
169
+ ? this.localAssocation.associatedWith
170
+ : [this.localAssocation.associatedWith];
171
+ } else {
172
+ return undefined;
173
+ }
174
+ }
175
+
176
+ private get explicitRemoteAssociation() {
177
+ if (this.localAssociatedWith) {
178
+ if (this.localAssociatedWith.length === 1) {
179
+ return this.remoteDefinition!.fields[this.localAssociatedWith[0]]
180
+ ?.association;
181
+ } else {
182
+ return undefined;
183
+ }
184
+ }
185
+ }
186
+
187
+ /**
188
+ * The field names on the remote model that can used to query or queried to match
189
+ * with instances of the local model.
190
+ *
191
+ * Fields are returned in-order to match the order of `this.localKeyFields`.
192
+ */
193
+ get remoteJoinFields() {
194
+ /**
195
+ * If the local relationship explicitly names "associated with" fields, we
196
+ * need to see if this points direction to a reciprocating assocation. If it
197
+ * does, the remote assocation indicates what fields to use.
198
+ */
199
+
200
+ if (this.explicitRemoteAssociation?.targetName) {
201
+ // This case is theoretically unnecessary going forward.
202
+ return [this.explicitRemoteAssociation.targetName!];
203
+ } else if (this.explicitRemoteAssociation?.targetNames) {
204
+ return this.explicitRemoteAssociation?.targetNames!;
205
+ } else if (this.localAssociatedWith) {
206
+ return this.localAssociatedWith;
207
+ } else {
208
+ return this.remotePKFields;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Whether this relationship everything necessary to get, set, and query from
214
+ * the perspective of the local model provided at instantiation.
215
+ */
216
+ get isComplete() {
217
+ return this.localJoinFields.length > 0 && this.remoteJoinFields.length > 0;
218
+ }
219
+
220
+ /**
221
+ * Creates an FK mapper object with respect to the given related instance.
222
+ *
223
+ * E.g., if the local FK fields are `[parentId, parentName]` and point to
224
+ * `[customId, name]` on the remote model, `createLocalFKObject(remote)`
225
+ * will return:
226
+ *
227
+ * ```
228
+ * {
229
+ * parentId: remote.customId,
230
+ * parentName: remote.name
231
+ * }
232
+ * ```
233
+ *
234
+ * @param remote The remote related instance.
235
+ */
236
+ createLocalFKObject(remote: any) {
237
+ const fk = {} as Record<string, string>;
238
+ for (let i = 0; i < this.localJoinFields.length; i++) {
239
+ fk[this.localJoinFields[i]] = remote[this.remoteJoinFields[i]];
240
+ }
241
+ return fk;
242
+ }
243
+
244
+ /**
245
+ * Creates an query mapper object to help fetch the remote instance(s) or
246
+ * `null` if any of the necessary local fields are `null` or `undefined`.
247
+ *
248
+ * E.g., if the local FK fields are `[parentId, parentName]` and point to
249
+ * `[customId, name]` on the remote model, `createLocalFKObject(remote)`
250
+ * will return:
251
+ *
252
+ * ```
253
+ * {
254
+ * customId: local.parentId
255
+ * name: local.parentName
256
+ * }
257
+ * ```
258
+ *
259
+ * If the local fields are not populated, returns
260
+ *
261
+ * @param local The local instance.
262
+ */
263
+ createRemoteQueryObject(local: T) {
264
+ const query = {} as Record<string, string>;
265
+ for (let i = 0; i < this.remoteJoinFields.length; i++) {
266
+ const localValue = local[this.localJoinFields[i]];
267
+ if (localValue === null || localValue === undefined) return null;
268
+ query[this.remoteJoinFields[i]] = local[this.localJoinFields[i]];
269
+ }
270
+ return query;
271
+ }
272
+ }
@@ -25,6 +25,7 @@ import {
25
25
  STORAGE,
26
26
  validatePredicate,
27
27
  valuesEqual,
28
+ NAMESPACES,
28
29
  } from '../util';
29
30
  import { getIdentifierValue } from '../sync/utils';
30
31
  import { Adapter } from './adapter';
@@ -40,7 +41,7 @@ export type Storage = InstanceType<typeof StorageClass>;
40
41
 
41
42
  const logger = new Logger('DataStore');
42
43
  class StorageClass implements StorageFacade {
43
- private initialized: Promise<void>;
44
+ private initialized: Promise<void> | undefined;
44
45
  private readonly pushStream: {
45
46
  observable: Observable<StorageSubscriptionMessage<PersistentModel>>;
46
47
  } & Required<
@@ -51,7 +52,7 @@ class StorageClass implements StorageFacade {
51
52
  private readonly schema: InternalSchema,
52
53
  private readonly namespaceResolver: NamespaceResolver,
53
54
  private readonly getModelConstructorByModelName: (
54
- namsespaceName: string,
55
+ namsespaceName: NAMESPACES,
55
56
  modelName: string
56
57
  ) => PersistentModelConstructor<any>,
57
58
  private readonly modelInstanceCreator: ModelInstanceCreator,
@@ -59,7 +60,7 @@ class StorageClass implements StorageFacade {
59
60
  private readonly sessionId?: string
60
61
  ) {
61
62
  this.adapter = this.adapter || getDefaultAdapter();
62
- this.pushStream = new PushStream();
63
+ this.pushStream = new PushStream() as any;
63
64
  }
64
65
 
65
66
  static getNamespace() {
@@ -89,15 +90,13 @@ class StorageClass implements StorageFacade {
89
90
  reject = rej;
90
91
  });
91
92
 
92
- this.adapter
93
- .setUp(
94
- this.schema,
95
- this.namespaceResolver,
96
- this.modelInstanceCreator,
97
- this.getModelConstructorByModelName,
98
- this.sessionId
99
- )
100
- .then(resolve, reject);
93
+ this.adapter!.setUp(
94
+ this.schema,
95
+ this.namespaceResolver,
96
+ this.modelInstanceCreator,
97
+ this.getModelConstructorByModelName,
98
+ this.sessionId
99
+ ).then(resolve!, reject!);
101
100
 
102
101
  await this.initialized;
103
102
  }
@@ -109,6 +108,9 @@ class StorageClass implements StorageFacade {
109
108
  patchesTuple?: [Patch[], PersistentModel]
110
109
  ): Promise<[T, OpType.INSERT | OpType.UPDATE][]> {
111
110
  await this.init();
111
+ if (!this.adapter) {
112
+ throw new Error('Storage adapter is missing');
113
+ }
112
114
 
113
115
  const result = await this.adapter.save(model, condition);
114
116
 
@@ -152,11 +154,14 @@ class StorageClass implements StorageFacade {
152
154
  .constructor as PersistentModelConstructor<T>;
153
155
 
154
156
  this.pushStream.next({
155
- model: modelConstructor,
157
+ model: modelConstructor as any,
156
158
  opType,
157
159
  element,
158
160
  mutator,
159
- condition: ModelPredicateCreator.getPredicates(condition, false),
161
+ condition:
162
+ (condition &&
163
+ ModelPredicateCreator.getPredicates(condition, false)) ||
164
+ null,
160
165
  savedElement,
161
166
  });
162
167
  });
@@ -180,9 +185,12 @@ class StorageClass implements StorageFacade {
180
185
  mutator?: Symbol
181
186
  ): Promise<[T[], T[]]> {
182
187
  await this.init();
188
+ if (!this.adapter) {
189
+ throw new Error('Storage adapter is missing');
190
+ }
183
191
 
184
- let deleted: T[];
185
192
  let models: T[];
193
+ let deleted: T[] | undefined;
186
194
 
187
195
  [models, deleted] = await this.adapter.delete(
188
196
  modelOrModelConstructor,
@@ -216,21 +224,21 @@ class StorageClass implements StorageFacade {
216
224
  const modelConstructor = (Object.getPrototypeOf(model) as Object)
217
225
  .constructor as PersistentModelConstructor<T>;
218
226
 
219
- let theCondition: PredicatesGroup<any>;
227
+ let theCondition: PredicatesGroup<any> | undefined;
220
228
 
221
229
  if (!isModelConstructor(modelOrModelConstructor)) {
222
230
  const modelId = getIdentifierValue(modelDefinition, model);
223
231
  theCondition = modelIds.has(modelId)
224
- ? ModelPredicateCreator.getPredicates(condition, false)
232
+ ? ModelPredicateCreator.getPredicates(condition!, false)
225
233
  : undefined;
226
234
  }
227
235
 
228
236
  this.pushStream.next({
229
- model: modelConstructor,
237
+ model: modelConstructor as any,
230
238
  opType: OpType.DELETE,
231
239
  element: model,
232
240
  mutator,
233
- condition: theCondition,
241
+ condition: theCondition || null,
234
242
  });
235
243
  });
236
244
 
@@ -243,6 +251,9 @@ class StorageClass implements StorageFacade {
243
251
  pagination?: PaginationInput<T>
244
252
  ): Promise<T[]> {
245
253
  await this.init();
254
+ if (!this.adapter) {
255
+ throw new Error('Storage adapter is missing');
256
+ }
246
257
 
247
258
  return await this.adapter.query(modelConstructor, predicate, pagination);
248
259
  }
@@ -250,22 +261,24 @@ class StorageClass implements StorageFacade {
250
261
  async queryOne<T extends PersistentModel>(
251
262
  modelConstructor: PersistentModelConstructor<T>,
252
263
  firstOrLast: QueryOne = QueryOne.FIRST
253
- ): Promise<T> {
264
+ ): Promise<T | undefined> {
254
265
  await this.init();
266
+ if (!this.adapter) {
267
+ throw new Error('Storage adapter is missing');
268
+ }
255
269
 
256
- const record = await this.adapter.queryOne(modelConstructor, firstOrLast);
257
- return record;
270
+ return await this.adapter.queryOne(modelConstructor, firstOrLast);
258
271
  }
259
272
 
260
273
  observe<T extends PersistentModel>(
261
- modelConstructor?: PersistentModelConstructor<T>,
262
- predicate?: ModelPredicate<T>,
274
+ modelConstructor?: PersistentModelConstructor<T> | null,
275
+ predicate?: ModelPredicate<T> | null,
263
276
  skipOwn?: Symbol
264
277
  ): Observable<SubscriptionMessage<T>> {
265
278
  const listenToAll = !modelConstructor;
266
279
  const { predicates, type } =
267
- ModelPredicateCreator.getPredicates(predicate, false) || {};
268
- const hasPredicate = !!predicates;
280
+ (predicate && ModelPredicateCreator.getPredicates(predicate, false)) ||
281
+ {};
269
282
 
270
283
  let result = this.pushStream.observable
271
284
  .filter(({ mutator }) => {
@@ -281,7 +294,7 @@ class StorageClass implements StorageFacade {
281
294
  return false;
282
295
  }
283
296
 
284
- if (hasPredicate) {
297
+ if (!!predicates && !!type) {
285
298
  return validatePredicate(element, type, predicates);
286
299
  }
287
300
 
@@ -294,6 +307,9 @@ class StorageClass implements StorageFacade {
294
307
 
295
308
  async clear(completeObservable = true) {
296
309
  this.initialized = undefined;
310
+ if (!this.adapter) {
311
+ throw new Error('Storage adapter is missing');
312
+ }
297
313
 
298
314
  await this.adapter.clear();
299
315
 
@@ -308,6 +324,9 @@ class StorageClass implements StorageFacade {
308
324
  mutator?: Symbol
309
325
  ): Promise<[T, OpType][]> {
310
326
  await this.init();
327
+ if (!this.adapter) {
328
+ throw new Error('Storage adapter is missing');
329
+ }
311
330
 
312
331
  const result = await this.adapter.batchSave(modelConstructor, items);
313
332
 
@@ -317,7 +336,7 @@ class StorageClass implements StorageFacade {
317
336
  opType,
318
337
  element,
319
338
  mutator,
320
- condition: undefined,
339
+ condition: null,
321
340
  });
322
341
  });
323
342
 
@@ -335,7 +354,7 @@ class StorageClass implements StorageFacade {
335
354
  return null;
336
355
  }
337
356
 
338
- const [patches, source] = patchesTuple;
357
+ const [patches, source] = patchesTuple!;
339
358
  const updatedElement = {};
340
359
  // extract array of updated fields from patches
341
360
  const updatedFields = <string[]>(
@@ -349,7 +368,7 @@ class StorageClass implements StorageFacade {
349
368
  const { fields } =
350
369
  this.schema.namespaces[namespace].models[modelConstructor.name];
351
370
  const { primaryKey, compositeKeys = [] } =
352
- this.schema.namespaces[namespace].keys[modelConstructor.name];
371
+ this.schema.namespaces[namespace].keys?.[modelConstructor.name] || {};
353
372
 
354
373
  // set original values for these fields
355
374
  updatedFields.forEach((field: string) => {
@@ -440,7 +459,7 @@ class ExclusiveStorage implements StorageFacade {
440
459
  schema: InternalSchema,
441
460
  namespaceResolver: NamespaceResolver,
442
461
  getModelConstructorByModelName: (
443
- namsespaceName: string,
462
+ namsespaceName: NAMESPACES,
444
463
  modelName: string
445
464
  ) => PersistentModelConstructor<any>,
446
465
  modelInstanceCreator: ModelInstanceCreator,
@@ -491,11 +510,11 @@ class ExclusiveStorage implements StorageFacade {
491
510
  if (isModelConstructor(modelOrModelConstructor)) {
492
511
  const modelConstructor = modelOrModelConstructor;
493
512
 
494
- return storage.delete(modelConstructor, condition, mutator);
513
+ return storage.delete(modelConstructor as any, condition, mutator);
495
514
  } else {
496
515
  const model = modelOrModelConstructor;
497
516
 
498
- return storage.delete(model, condition, mutator);
517
+ return storage.delete(model as any, condition, mutator);
499
518
  }
500
519
  });
501
520
  }
@@ -513,8 +532,8 @@ class ExclusiveStorage implements StorageFacade {
513
532
  async queryOne<T extends PersistentModel>(
514
533
  modelConstructor: PersistentModelConstructor<T>,
515
534
  firstOrLast: QueryOne = QueryOne.FIRST
516
- ): Promise<T> {
517
- return this.runExclusive<T>(storage =>
535
+ ): Promise<T | undefined> {
536
+ return this.runExclusive<T | undefined>(storage =>
518
537
  storage.queryOne<T>(modelConstructor, firstOrLast)
519
538
  );
520
539
  }
@@ -524,8 +543,8 @@ class ExclusiveStorage implements StorageFacade {
524
543
  }
525
544
 
526
545
  observe<T extends PersistentModel>(
527
- modelConstructor?: PersistentModelConstructor<T>,
528
- predicate?: ModelPredicate<T>,
546
+ modelConstructor?: PersistentModelConstructor<T> | null,
547
+ predicate?: ModelPredicate<T> | null,
529
548
  skipOwn?: Symbol
530
549
  ): Observable<SubscriptionMessage<T>> {
531
550
  return this.storage.observe(modelConstructor, predicate, skipOwn);
@@ -13,9 +13,9 @@ type ConnectionStatus = {
13
13
 
14
14
  export default class DataStoreConnectivity {
15
15
  private connectionStatus: ConnectionStatus;
16
- private observer: ZenObservable.SubscriptionObserver<ConnectionStatus>;
17
- private subscription: ZenObservable.Subscription;
18
- private timeout: ReturnType<typeof setTimeout>;
16
+ private observer!: ZenObservable.SubscriptionObserver<ConnectionStatus>;
17
+ private subscription!: ZenObservable.Subscription;
18
+ private timeout!: ReturnType<typeof setTimeout>;
19
19
  constructor() {
20
20
  this.connectionStatus = {
21
21
  online: false,
@@ -26,7 +26,7 @@ export default class DataStoreConnectivity {
26
26
  if (this.observer) {
27
27
  throw new Error('Subscriber already exists');
28
28
  }
29
- return new Observable(observer => {
29
+ return new Observable((observer) => {
30
30
  this.observer = observer;
31
31
  // Will be used to forward socket connection changes, enhancing Reachability
32
32
 
package/src/sync/index.ts CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  // tslint:disable:no-duplicate-imports
33
33
  import type { __modelMeta__ } from '../types';
34
34
 
35
- import { exhaustiveCheck, getNow, SYNC, USER } from '../util';
35
+ import { getNow, SYNC, USER } from '../util';
36
36
  import DataStoreConnectivity from './datastoreConnectivity';
37
37
  import { ModelMerger } from './merger';
38
38
  import { MutationEventOutbox } from './outbox';
@@ -122,7 +122,7 @@ export class SyncEngine {
122
122
  public getModelSyncedStatus(
123
123
  modelConstructor: PersistentModelConstructor<any>
124
124
  ): boolean {
125
- return this.modelSyncedStatus.get(modelConstructor);
125
+ return this.modelSyncedStatus.get(modelConstructor)!;
126
126
  }
127
127
 
128
128
  constructor(
@@ -235,14 +235,8 @@ export class SyncEngine {
235
235
  );
236
236
  } else {
237
237
  //#region GraphQL Subscriptions
238
- [
239
- // const ctlObservable: Observable<CONTROL_MSG>
240
- ctlSubsObservable,
241
- // const dataObservable: Observable<[TransformerMutationType, SchemaModel, Readonly<{
242
- // id: string;
243
- // } & Record<string, any>>]>
244
- dataSubsObservable,
245
- ] = this.subscriptionsProcessor.start();
238
+ [ctlSubsObservable, dataSubsObservable] =
239
+ this.subscriptionsProcessor.start();
246
240
 
247
241
  try {
248
242
  await new Promise((resolve, reject) => {
@@ -362,7 +356,7 @@ export class SyncEngine {
362
356
  // TODO: extract to function
363
357
  if (!isNode) {
364
358
  subscriptions.push(
365
- dataSubsObservable.subscribe(
359
+ dataSubsObservable!.subscribe(
366
360
  ([_transformerMutationType, modelDefinition, item]) =>
367
361
  this.runningProcesses.add(async () => {
368
362
  const modelConstructor = this.userModelClasses[
@@ -421,11 +415,11 @@ export class SyncEngine {
421
415
  ] as PersistentModelConstructor<MutationEvent>;
422
416
  const modelDefinition = this.getModelDefinition(model);
423
417
  const graphQLCondition = predicateToGraphQLCondition(
424
- condition,
418
+ condition!,
425
419
  modelDefinition
426
420
  );
427
421
  const mutationEvent = createMutationInstanceFromModelOperation(
428
- namespace.relationships,
422
+ namespace.relationships!,
429
423
  this.getModelDefinition(model),
430
424
  opType,
431
425
  model,
@@ -500,7 +494,7 @@ export class SyncEngine {
500
494
  fullSyncInterval,
501
495
  lastSyncPredicate,
502
496
  }) => {
503
- const nextFullSync = lastFullSync + fullSyncInterval;
497
+ const nextFullSync = lastFullSync! + fullSyncInterval;
504
498
  const syncFrom =
505
499
  !lastFullSync || nextFullSync < currentTimeStamp
506
500
  ? 0 // perform full sync if expired
@@ -508,7 +502,7 @@ export class SyncEngine {
508
502
 
509
503
  return [
510
504
  this.schema.namespaces[namespace].models[model],
511
- [namespace, syncFrom],
505
+ [namespace, syncFrom!],
512
506
  ];
513
507
  }
514
508
  )
@@ -631,7 +625,7 @@ export class SyncEngine {
631
625
  ))
632
626
  );
633
627
 
634
- const counts = count.get(modelConstructor);
628
+ const counts = count.get(modelConstructor)!;
635
629
 
636
630
  opTypeCount.forEach(([, opType]) => {
637
631
  switch (opType) {
@@ -645,7 +639,7 @@ export class SyncEngine {
645
639
  counts.deleted++;
646
640
  break;
647
641
  default:
648
- exhaustiveCheck(opType);
642
+ throw new Error(`Invalid opType ${opType}`);
649
643
  }
650
644
  });
651
645
  });
@@ -665,10 +659,10 @@ export class SyncEngine {
665
659
 
666
660
  newestFullSyncStartedAt =
667
661
  newestFullSyncStartedAt === undefined
668
- ? lastFullSync
662
+ ? lastFullSync!
669
663
  : Math.max(
670
664
  newestFullSyncStartedAt,
671
- isFullSync ? startedAt : lastFullSync
665
+ isFullSync ? startedAt : lastFullSync!
672
666
  );
673
667
 
674
668
  modelMetadata = (
@@ -728,9 +722,9 @@ export class SyncEngine {
728
722
  });
729
723
 
730
724
  const msNextFullSync =
731
- newestFullSyncStartedAt +
732
- theInterval -
733
- (newestStartedAt + duration);
725
+ newestFullSyncStartedAt! +
726
+ theInterval! -
727
+ (newestStartedAt! + duration!);
734
728
 
735
729
  logger.debug(
736
730
  `Next fullSync in ${msNextFullSync / 1000} seconds. (${new Date(
@@ -843,7 +837,7 @@ export class SyncEngine {
843
837
  const promises = models.map(async ([namespace, model]) => {
844
838
  const modelMetadata = await this.getModelMetadata(namespace, model.name);
845
839
  const syncPredicate = ModelPredicateCreator.getPredicates(
846
- this.syncPredicates.get(model),
840
+ this.syncPredicates.get(model)!,
847
841
  false
848
842
  );
849
843
  const lastSyncPredicate = syncPredicate
@@ -855,9 +849,9 @@ export class SyncEngine {
855
849
  this.modelInstanceCreator(ModelMetadataConstructor, {
856
850
  model: model.name,
857
851
  namespace,
858
- lastSync: null,
852
+ lastSync: null!,
859
853
  fullSyncInterval,
860
- lastFullSync: null,
854
+ lastFullSync: null!,
861
855
  lastSyncPredicate,
862
856
  }),
863
857
  undefined,
@@ -875,9 +869,9 @@ export class SyncEngine {
875
869
  // perform a base sync if the syncPredicate changed in between calls to DataStore.start
876
870
  // ensures that the local store contains all the data specified by the syncExpression
877
871
  if (syncPredicateUpdated) {
878
- draft.lastSync = null;
879
- draft.lastFullSync = null;
880
- draft.lastSyncPredicate = lastSyncPredicate;
872
+ draft.lastSync = null!;
873
+ draft.lastFullSync = null!;
874
+ (draft.lastSyncPredicate as any) = lastSyncPredicate;
881
875
  }
882
876
  })
883
877
  );