@aws-amplify/datastore 3.7.3 → 3.7.4-custom-pk.86

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 (137) hide show
  1. package/CHANGELOG.md +144 -17
  2. package/README.md +154 -0
  3. package/dist/aws-amplify-datastore.js +3740 -1599
  4. package/dist/aws-amplify-datastore.js.map +1 -1
  5. package/dist/aws-amplify-datastore.min.js +25 -95
  6. package/dist/aws-amplify-datastore.min.js.map +1 -1
  7. package/lib/authModeStrategies/multiAuthStrategy.d.ts +2 -2
  8. package/lib/authModeStrategies/multiAuthStrategy.js +32 -26
  9. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  10. package/lib/datastore/datastore.d.ts +17 -16
  11. package/lib/datastore/datastore.js +291 -83
  12. package/lib/datastore/datastore.js.map +1 -1
  13. package/lib/index.d.ts +3 -19
  14. package/lib/predicates/index.d.ts +3 -2
  15. package/lib/predicates/index.js +12 -2
  16. package/lib/predicates/index.js.map +1 -1
  17. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
  18. package/lib/storage/adapter/AsyncStorageAdapter.js +361 -193
  19. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  20. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
  21. package/lib/storage/adapter/AsyncStorageDatabase.js +59 -28
  22. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  23. package/lib/storage/adapter/InMemoryStore.js +2 -2
  24. package/lib/storage/adapter/InMemoryStore.js.map +1 -1
  25. package/lib/storage/adapter/IndexedDBAdapter.d.ts +7 -2
  26. package/lib/storage/adapter/IndexedDBAdapter.js +454 -252
  27. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  28. package/lib/storage/adapter/index.d.ts +1 -1
  29. package/lib/storage/storage.d.ts +3 -3
  30. package/lib/storage/storage.js +106 -28
  31. package/lib/storage/storage.js.map +1 -1
  32. package/lib/sync/index.d.ts +23 -7
  33. package/lib/sync/index.js +18 -17
  34. package/lib/sync/index.js.map +1 -1
  35. package/lib/sync/merger.d.ts +3 -3
  36. package/lib/sync/merger.js +8 -6
  37. package/lib/sync/merger.js.map +1 -1
  38. package/lib/sync/outbox.d.ts +2 -2
  39. package/lib/sync/outbox.js +12 -9
  40. package/lib/sync/outbox.js.map +1 -1
  41. package/lib/sync/processors/errorMaps.d.ts +17 -0
  42. package/lib/sync/processors/errorMaps.js +125 -0
  43. package/lib/sync/processors/errorMaps.js.map +1 -0
  44. package/lib/sync/processors/mutation.d.ts +22 -4
  45. package/lib/sync/processors/mutation.js +119 -51
  46. package/lib/sync/processors/mutation.js.map +1 -1
  47. package/lib/sync/processors/subscription.d.ts +4 -2
  48. package/lib/sync/processors/subscription.js +76 -41
  49. package/lib/sync/processors/subscription.js.map +1 -1
  50. package/lib/sync/processors/sync.d.ts +4 -2
  51. package/lib/sync/processors/sync.js +62 -27
  52. package/lib/sync/processors/sync.js.map +1 -1
  53. package/lib/sync/utils.d.ts +3 -2
  54. package/lib/sync/utils.js +58 -7
  55. package/lib/sync/utils.js.map +1 -1
  56. package/lib/types.d.ts +90 -34
  57. package/lib/types.js +31 -2
  58. package/lib/types.js.map +1 -1
  59. package/lib/util.d.ts +48 -33
  60. package/lib/util.js +219 -57
  61. package/lib/util.js.map +1 -1
  62. package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +2 -2
  63. package/lib-esm/authModeStrategies/multiAuthStrategy.js +32 -26
  64. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  65. package/lib-esm/datastore/datastore.d.ts +17 -16
  66. package/lib-esm/datastore/datastore.js +293 -85
  67. package/lib-esm/datastore/datastore.js.map +1 -1
  68. package/lib-esm/index.d.ts +3 -19
  69. package/lib-esm/predicates/index.d.ts +3 -2
  70. package/lib-esm/predicates/index.js +13 -3
  71. package/lib-esm/predicates/index.js.map +1 -1
  72. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
  73. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +361 -193
  74. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  75. package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
  76. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +60 -29
  77. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  78. package/lib-esm/storage/adapter/InMemoryStore.js +2 -2
  79. package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
  80. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +7 -2
  81. package/lib-esm/storage/adapter/IndexedDBAdapter.js +454 -252
  82. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  83. package/lib-esm/storage/adapter/index.d.ts +1 -1
  84. package/lib-esm/storage/storage.d.ts +3 -3
  85. package/lib-esm/storage/storage.js +106 -28
  86. package/lib-esm/storage/storage.js.map +1 -1
  87. package/lib-esm/sync/index.d.ts +23 -7
  88. package/lib-esm/sync/index.js +20 -19
  89. package/lib-esm/sync/index.js.map +1 -1
  90. package/lib-esm/sync/merger.d.ts +3 -3
  91. package/lib-esm/sync/merger.js +8 -6
  92. package/lib-esm/sync/merger.js.map +1 -1
  93. package/lib-esm/sync/outbox.d.ts +2 -2
  94. package/lib-esm/sync/outbox.js +13 -10
  95. package/lib-esm/sync/outbox.js.map +1 -1
  96. package/lib-esm/sync/processors/errorMaps.d.ts +17 -0
  97. package/lib-esm/sync/processors/errorMaps.js +119 -0
  98. package/lib-esm/sync/processors/errorMaps.js.map +1 -0
  99. package/lib-esm/sync/processors/mutation.d.ts +22 -4
  100. package/lib-esm/sync/processors/mutation.js +122 -54
  101. package/lib-esm/sync/processors/mutation.js.map +1 -1
  102. package/lib-esm/sync/processors/subscription.d.ts +4 -2
  103. package/lib-esm/sync/processors/subscription.js +77 -42
  104. package/lib-esm/sync/processors/subscription.js.map +1 -1
  105. package/lib-esm/sync/processors/sync.d.ts +4 -2
  106. package/lib-esm/sync/processors/sync.js +62 -27
  107. package/lib-esm/sync/processors/sync.js.map +1 -1
  108. package/lib-esm/sync/utils.d.ts +3 -2
  109. package/lib-esm/sync/utils.js +58 -8
  110. package/lib-esm/sync/utils.js.map +1 -1
  111. package/lib-esm/types.d.ts +90 -34
  112. package/lib-esm/types.js +29 -3
  113. package/lib-esm/types.js.map +1 -1
  114. package/lib-esm/util.d.ts +48 -33
  115. package/lib-esm/util.js +207 -54
  116. package/lib-esm/util.js.map +1 -1
  117. package/package.json +10 -9
  118. package/src/authModeStrategies/multiAuthStrategy.ts +24 -21
  119. package/src/datastore/datastore.ts +448 -148
  120. package/src/predicates/index.ts +32 -10
  121. package/src/storage/adapter/AsyncStorageAdapter.ts +305 -78
  122. package/src/storage/adapter/AsyncStorageDatabase.ts +65 -26
  123. package/src/storage/adapter/InMemoryStore.ts +2 -2
  124. package/src/storage/adapter/IndexedDBAdapter.ts +344 -101
  125. package/src/storage/adapter/index.ts +1 -1
  126. package/src/storage/storage.ts +85 -24
  127. package/src/sync/index.ts +74 -58
  128. package/src/sync/merger.ts +16 -4
  129. package/src/sync/outbox.ts +22 -8
  130. package/src/sync/processors/errorMaps.ts +93 -0
  131. package/src/sync/processors/mutation.ts +143 -84
  132. package/src/sync/processors/subscription.ts +67 -36
  133. package/src/sync/processors/sync.ts +37 -12
  134. package/src/sync/utils.ts +67 -16
  135. package/src/types.ts +252 -50
  136. package/src/util.ts +256 -42
  137. package/ssr/package.json +1 -1
@@ -58,6 +58,7 @@ import { ModelPredicateCreator, ModelSortPredicateCreator, } from '../../predica
58
58
  import { isPredicateObj, OpType, QueryOne, } from '../../types';
59
59
  import { exhaustiveCheck, getIndex, getIndexFromAssociation, isModelConstructor, traverseModel, validatePredicate, sortCompareFunction, } from '../../util';
60
60
  var logger = new Logger('DataStore');
61
+ var DEFAULT_PRIMARY_KEY_SEPARATOR = '#';
61
62
  var AsyncStorageAdapter = /** @class */ (function () {
62
63
  function AsyncStorageAdapter() {
63
64
  }
@@ -70,6 +71,45 @@ var AsyncStorageAdapter = /** @class */ (function () {
70
71
  var storeName = namespace + "_" + modelName;
71
72
  return storeName;
72
73
  };
74
+ // Returns primary keys for a model
75
+ AsyncStorageAdapter.prototype.getIndexKeys = function (namespaceName, modelName) {
76
+ var _a;
77
+ var namespace = this.schema.namespaces[namespaceName];
78
+ var keyPath = (_a = namespace === null || namespace === void 0 ? void 0 : namespace.keys[modelName]) === null || _a === void 0 ? void 0 : _a.primaryKey;
79
+ if (keyPath) {
80
+ return keyPath;
81
+ }
82
+ return ['id'];
83
+ };
84
+ // Retrieves concatenated primary key values from a model
85
+ AsyncStorageAdapter.prototype.getIndexKeyValuesPath = function (model) {
86
+ var modelConstructor = Object.getPrototypeOf(model)
87
+ .constructor;
88
+ var namespaceName = this.namespaceResolver(modelConstructor);
89
+ var keys = this.getIndexKeys(namespaceName, modelConstructor.name);
90
+ // Retrieve key values from model
91
+ var keyValues = keys.map(function (field) { return model[field]; });
92
+ // Return concatenated key values
93
+ return keyValues.join(DEFAULT_PRIMARY_KEY_SEPARATOR);
94
+ };
95
+ // Retrieves concatenated primary key values from a model
96
+ AsyncStorageAdapter.prototype.getIndexKeyValues = function (model) {
97
+ var modelConstructor = Object.getPrototypeOf(model)
98
+ .constructor;
99
+ var namespaceName = this.namespaceResolver(modelConstructor);
100
+ var keys = this.getIndexKeys(namespaceName, modelConstructor.name);
101
+ // Retrieve key values from model
102
+ return keys.map(function (field) { return model[field]; });
103
+ };
104
+ AsyncStorageAdapter.prototype.keysEqual = function (keysA, keysB) {
105
+ if (keysA.length !== keysB.length) {
106
+ return false;
107
+ }
108
+ if (keysA.length === 1) {
109
+ return keysA[0] === keysB[0];
110
+ }
111
+ return keysA.every(function (key, idx) { return key === keysB[idx]; });
112
+ };
73
113
  AsyncStorageAdapter.prototype.setUp = function (theSchema, namespaceResolver, modelInstanceCreator, getModelConstructorByModelName) {
74
114
  return __awaiter(this, void 0, void 0, function () {
75
115
  var error_1;
@@ -115,7 +155,7 @@ var AsyncStorageAdapter = /** @class */ (function () {
115
155
  AsyncStorageAdapter.prototype.save = function (model, condition) {
116
156
  var e_1, _a;
117
157
  return __awaiter(this, void 0, void 0, function () {
118
- var modelConstructor, storeName, connectedModels, namespaceName, set, connectionStoreNames, fromDB, predicates, predicateObjs, type, isValid, msg, result, connectionStoreNames_1, connectionStoreNames_1_1, resItem, storeName_1, item, instance, id, fromDB_1, opType, e_1_1;
158
+ var modelConstructor, storeName, namespaceName, connectedModels, set, connectionStoreNames, keyValuesPath, fromDB, predicates, predicateObjs, type, isValid, msg, result, connectionStoreNames_1, connectionStoreNames_1_1, resItem, storeName_1, item, instance, keys, itemKeyValues, itemKeyValuesPath, fromDB_1, opType, modelKeyValues, keysEqual, e_1_1;
119
159
  var _this = this;
120
160
  return __generator(this, function (_b) {
121
161
  switch (_b.label) {
@@ -123,16 +163,18 @@ var AsyncStorageAdapter = /** @class */ (function () {
123
163
  modelConstructor = Object.getPrototypeOf(model)
124
164
  .constructor;
125
165
  storeName = this.getStorenameForModel(modelConstructor);
126
- connectedModels = traverseModel(modelConstructor.name, model, this.schema.namespaces[this.namespaceResolver(modelConstructor)], this.modelInstanceCreator, this.getModelConstructorByModelName);
127
166
  namespaceName = this.namespaceResolver(modelConstructor);
167
+ connectedModels = traverseModel(modelConstructor.name, model, this.schema.namespaces[namespaceName], this.modelInstanceCreator, this.getModelConstructorByModelName);
128
168
  set = new Set();
129
169
  connectionStoreNames = Object.values(connectedModels).map(function (_a) {
130
170
  var modelName = _a.modelName, item = _a.item, instance = _a.instance;
131
171
  var storeName = _this.getStorename(namespaceName, modelName);
132
172
  set.add(storeName);
133
- return { storeName: storeName, item: item, instance: instance };
173
+ var keys = _this.getIndexKeys(namespaceName, modelName);
174
+ return { storeName: storeName, item: item, instance: instance, keys: keys };
134
175
  });
135
- return [4 /*yield*/, this.db.get(model.id, storeName)];
176
+ keyValuesPath = this.getIndexKeyValuesPath(model);
177
+ return [4 /*yield*/, this.db.get(keyValuesPath, storeName)];
136
178
  case 1:
137
179
  fromDB = _b.sent();
138
180
  if (condition && fromDB) {
@@ -155,14 +197,17 @@ var AsyncStorageAdapter = /** @class */ (function () {
155
197
  case 4:
156
198
  if (!(connectionStoreNames_1_1 = _b.sent(), !connectionStoreNames_1_1.done)) return [3 /*break*/, 8];
157
199
  resItem = connectionStoreNames_1_1.value;
158
- storeName_1 = resItem.storeName, item = resItem.item, instance = resItem.instance;
159
- id = item.id;
160
- return [4 /*yield*/, this.db.get(id, storeName_1)];
200
+ storeName_1 = resItem.storeName, item = resItem.item, instance = resItem.instance, keys = resItem.keys;
201
+ itemKeyValues = keys.map(function (key) { return item[key]; });
202
+ itemKeyValuesPath = itemKeyValues.join(DEFAULT_PRIMARY_KEY_SEPARATOR);
203
+ return [4 /*yield*/, this.db.get(itemKeyValuesPath, storeName_1)];
161
204
  case 5:
162
205
  fromDB_1 = _b.sent();
163
206
  opType = fromDB_1 ? OpType.UPDATE : OpType.INSERT;
164
- if (!(id === model.id || opType === OpType.INSERT)) return [3 /*break*/, 7];
165
- return [4 /*yield*/, this.db.save(item, storeName_1)];
207
+ modelKeyValues = this.getIndexKeyValues(model);
208
+ keysEqual = this.keysEqual(itemKeyValues, modelKeyValues);
209
+ if (!(keysEqual || opType === OpType.INSERT)) return [3 /*break*/, 7];
210
+ return [4 /*yield*/, this.db.save(item, storeName_1, keys, itemKeyValuesPath)];
166
211
  case 6:
167
212
  _b.sent();
168
213
  result.push([instance, opType]);
@@ -194,7 +239,7 @@ var AsyncStorageAdapter = /** @class */ (function () {
194
239
  var records_1, records_1_1, records_2, records_2_1;
195
240
  var e_2, _a, e_3, _b, e_4, _c;
196
241
  return __awaiter(this, void 0, void 0, function () {
197
- var namespace, relations, connectionStoreNames, modelConstructor, relations_1, relations_1_1, relation, fieldName, modelName, targetName, relationType, storeName, modelConstructor_1, _d, recordItem, getByfield, connectionRecord, e_3_1, recordItem, connectionRecord, e_4_1, e_2_1;
242
+ var namespace, relations, connectionStoreNames, modelConstructor, relations_1, relations_1_1, relation, fieldName, modelName, targetName, targetNames, relationType, storeName, modelConstructor_1, _d, recordItem, getByFields, allPresent, keys, connectionRecord, getByfield, key, connectionRecord, e_3_1, recordItem, allPresent, keys, connectionRecord, key, connectionRecord, e_4_1, e_2_1;
198
243
  var _this = this;
199
244
  return __generator(this, function (_e) {
200
245
  switch (_e.label) {
@@ -213,121 +258,171 @@ var AsyncStorageAdapter = /** @class */ (function () {
213
258
  }
214
259
  _e.label = 1;
215
260
  case 1:
216
- _e.trys.push([1, 34, 35, 40]);
261
+ _e.trys.push([1, 38, 39, 44]);
217
262
  relations_1 = __asyncValues(relations);
218
263
  _e.label = 2;
219
264
  case 2: return [4 /*yield*/, relations_1.next()];
220
265
  case 3:
221
- if (!(relations_1_1 = _e.sent(), !relations_1_1.done)) return [3 /*break*/, 33];
266
+ if (!(relations_1_1 = _e.sent(), !relations_1_1.done)) return [3 /*break*/, 37];
222
267
  relation = relations_1_1.value;
223
- fieldName = relation.fieldName, modelName = relation.modelName, targetName = relation.targetName, relationType = relation.relationType;
268
+ fieldName = relation.fieldName, modelName = relation.modelName, targetName = relation.targetName, targetNames = relation.targetNames, relationType = relation.relationType;
224
269
  storeName = this.getStorename(namespaceName, modelName);
225
270
  modelConstructor_1 = this.getModelConstructorByModelName(namespaceName, modelName);
226
271
  _d = relationType;
227
272
  switch (_d) {
228
273
  case 'HAS_ONE': return [3 /*break*/, 4];
229
- case 'BELONGS_TO': return [3 /*break*/, 17];
230
- case 'HAS_MANY': return [3 /*break*/, 30];
274
+ case 'BELONGS_TO': return [3 /*break*/, 19];
275
+ case 'HAS_MANY': return [3 /*break*/, 34];
231
276
  }
232
- return [3 /*break*/, 31];
277
+ return [3 /*break*/, 35];
233
278
  case 4:
234
- _e.trys.push([4, 10, 11, 16]);
279
+ _e.trys.push([4, 12, 13, 18]);
235
280
  records_1 = __asyncValues(records);
236
281
  _e.label = 5;
237
282
  case 5: return [4 /*yield*/, records_1.next()];
238
283
  case 6:
239
- if (!(records_1_1 = _e.sent(), !records_1_1.done)) return [3 /*break*/, 9];
284
+ if (!(records_1_1 = _e.sent(), !records_1_1.done)) return [3 /*break*/, 11];
240
285
  recordItem = records_1_1.value;
241
- getByfield = recordItem[targetName] ? targetName : fieldName;
242
- if (!recordItem[getByfield])
243
- return [3 /*break*/, 9];
244
- return [4 /*yield*/, this.db.get(recordItem[getByfield], storeName)];
286
+ if (!(targetNames === null || targetNames === void 0 ? void 0 : targetNames.length)) return [3 /*break*/, 8];
287
+ getByFields = [];
288
+ allPresent = void 0;
289
+ // iterate through all targetnames to make sure they are all present in the recordItem
290
+ allPresent = targetNames.every(function (targetName) {
291
+ return recordItem[targetName] != null;
292
+ });
293
+ if (!allPresent) {
294
+ return [3 /*break*/, 11];
295
+ }
296
+ getByFields = targetNames;
297
+ keys = getByFields
298
+ .map(function (getByField) { return recordItem[getByField]; })
299
+ .join(DEFAULT_PRIMARY_KEY_SEPARATOR);
300
+ return [4 /*yield*/, this.db.get(keys, storeName)];
245
301
  case 7:
246
302
  connectionRecord = _e.sent();
247
303
  recordItem[fieldName] =
248
304
  connectionRecord &&
249
305
  this.modelInstanceCreator(modelConstructor_1, connectionRecord);
250
- _e.label = 8;
251
- case 8: return [3 /*break*/, 5];
252
- case 9: return [3 /*break*/, 16];
253
- case 10:
306
+ return [3 /*break*/, 10];
307
+ case 8:
308
+ getByfield = recordItem[targetName]
309
+ ? targetName
310
+ : fieldName;
311
+ if (!recordItem[getByfield])
312
+ return [3 /*break*/, 11];
313
+ key = recordItem[getByfield];
314
+ return [4 /*yield*/, this.db.get(key, storeName)];
315
+ case 9:
316
+ connectionRecord = _e.sent();
317
+ recordItem[fieldName] =
318
+ connectionRecord &&
319
+ this.modelInstanceCreator(modelConstructor_1, connectionRecord);
320
+ _e.label = 10;
321
+ case 10: return [3 /*break*/, 5];
322
+ case 11: return [3 /*break*/, 18];
323
+ case 12:
254
324
  e_3_1 = _e.sent();
255
325
  e_3 = { error: e_3_1 };
256
- return [3 /*break*/, 16];
257
- case 11:
258
- _e.trys.push([11, , 14, 15]);
259
- if (!(records_1_1 && !records_1_1.done && (_b = records_1.return))) return [3 /*break*/, 13];
326
+ return [3 /*break*/, 18];
327
+ case 13:
328
+ _e.trys.push([13, , 16, 17]);
329
+ if (!(records_1_1 && !records_1_1.done && (_b = records_1.return))) return [3 /*break*/, 15];
260
330
  return [4 /*yield*/, _b.call(records_1)];
261
- case 12:
262
- _e.sent();
263
- _e.label = 13;
264
- case 13: return [3 /*break*/, 15];
265
331
  case 14:
332
+ _e.sent();
333
+ _e.label = 15;
334
+ case 15: return [3 /*break*/, 17];
335
+ case 16:
266
336
  if (e_3) throw e_3.error;
267
337
  return [7 /*endfinally*/];
268
- case 15: return [7 /*endfinally*/];
269
- case 16: return [3 /*break*/, 32];
270
- case 17:
271
- _e.trys.push([17, 23, 24, 29]);
272
- records_2 = __asyncValues(records);
273
- _e.label = 18;
274
- case 18: return [4 /*yield*/, records_2.next()];
338
+ case 17: return [7 /*endfinally*/];
339
+ case 18: return [3 /*break*/, 36];
275
340
  case 19:
276
- if (!(records_2_1 = _e.sent(), !records_2_1.done)) return [3 /*break*/, 22];
341
+ _e.trys.push([19, 27, 28, 33]);
342
+ records_2 = __asyncValues(records);
343
+ _e.label = 20;
344
+ case 20: return [4 /*yield*/, records_2.next()];
345
+ case 21:
346
+ if (!(records_2_1 = _e.sent(), !records_2_1.done)) return [3 /*break*/, 26];
277
347
  recordItem = records_2_1.value;
278
- if (!recordItem[targetName]) return [3 /*break*/, 21];
279
- return [4 /*yield*/, this.db.get(recordItem[targetName], storeName)];
280
- case 20:
348
+ if (!(targetNames === null || targetNames === void 0 ? void 0 : targetNames.length)) return [3 /*break*/, 23];
349
+ allPresent = void 0;
350
+ // iterate through all targetnames to make sure they are all present in the recordItem
351
+ allPresent = targetNames.every(function (targetName) {
352
+ return recordItem[targetName] != null;
353
+ });
354
+ // If not present, there is not yet a connected record
355
+ if (!allPresent) {
356
+ return [3 /*break*/, 26];
357
+ }
358
+ keys = targetNames
359
+ .map(function (targetName) { return recordItem[targetName]; })
360
+ .join(DEFAULT_PRIMARY_KEY_SEPARATOR);
361
+ return [4 /*yield*/, this.db.get(keys, storeName)];
362
+ case 22:
281
363
  connectionRecord = _e.sent();
282
364
  recordItem[fieldName] =
283
365
  connectionRecord &&
284
366
  this.modelInstanceCreator(modelConstructor_1, connectionRecord);
285
- delete recordItem[targetName];
286
- _e.label = 21;
287
- case 21: return [3 /*break*/, 18];
288
- case 22: return [3 /*break*/, 29];
367
+ targetNames === null || targetNames === void 0 ? void 0 : targetNames.map(function (targetName) {
368
+ delete recordItem[targetName];
369
+ });
370
+ return [3 /*break*/, 25];
289
371
  case 23:
372
+ if (!recordItem[targetName]) return [3 /*break*/, 25];
373
+ key = recordItem[targetName];
374
+ return [4 /*yield*/, this.db.get(key, storeName)];
375
+ case 24:
376
+ connectionRecord = _e.sent();
377
+ recordItem[fieldName] =
378
+ connectionRecord &&
379
+ this.modelInstanceCreator(modelConstructor_1, connectionRecord);
380
+ delete recordItem[targetName];
381
+ _e.label = 25;
382
+ case 25: return [3 /*break*/, 20];
383
+ case 26: return [3 /*break*/, 33];
384
+ case 27:
290
385
  e_4_1 = _e.sent();
291
386
  e_4 = { error: e_4_1 };
292
- return [3 /*break*/, 29];
293
- case 24:
294
- _e.trys.push([24, , 27, 28]);
295
- if (!(records_2_1 && !records_2_1.done && (_c = records_2.return))) return [3 /*break*/, 26];
387
+ return [3 /*break*/, 33];
388
+ case 28:
389
+ _e.trys.push([28, , 31, 32]);
390
+ if (!(records_2_1 && !records_2_1.done && (_c = records_2.return))) return [3 /*break*/, 30];
296
391
  return [4 /*yield*/, _c.call(records_2)];
297
- case 25:
392
+ case 29:
298
393
  _e.sent();
299
- _e.label = 26;
300
- case 26: return [3 /*break*/, 28];
301
- case 27:
394
+ _e.label = 30;
395
+ case 30: return [3 /*break*/, 32];
396
+ case 31:
302
397
  if (e_4) throw e_4.error;
303
398
  return [7 /*endfinally*/];
304
- case 28: return [7 /*endfinally*/];
305
- case 29: return [3 /*break*/, 32];
306
- case 30:
399
+ case 32: return [7 /*endfinally*/];
400
+ case 33: return [3 /*break*/, 36];
401
+ case 34:
307
402
  // TODO: Lazy loading
308
- return [3 /*break*/, 32];
309
- case 31:
403
+ return [3 /*break*/, 36];
404
+ case 35:
310
405
  exhaustiveCheck(relationType);
311
- return [3 /*break*/, 32];
312
- case 32: return [3 /*break*/, 2];
313
- case 33: return [3 /*break*/, 40];
314
- case 34:
406
+ return [3 /*break*/, 36];
407
+ case 36: return [3 /*break*/, 2];
408
+ case 37: return [3 /*break*/, 44];
409
+ case 38:
315
410
  e_2_1 = _e.sent();
316
411
  e_2 = { error: e_2_1 };
317
- return [3 /*break*/, 40];
318
- case 35:
319
- _e.trys.push([35, , 38, 39]);
320
- if (!(relations_1_1 && !relations_1_1.done && (_a = relations_1.return))) return [3 /*break*/, 37];
412
+ return [3 /*break*/, 44];
413
+ case 39:
414
+ _e.trys.push([39, , 42, 43]);
415
+ if (!(relations_1_1 && !relations_1_1.done && (_a = relations_1.return))) return [3 /*break*/, 41];
321
416
  return [4 /*yield*/, _a.call(relations_1)];
322
- case 36:
417
+ case 40:
323
418
  _e.sent();
324
- _e.label = 37;
325
- case 37: return [3 /*break*/, 39];
326
- case 38:
419
+ _e.label = 41;
420
+ case 41: return [3 /*break*/, 43];
421
+ case 42:
327
422
  if (e_2) throw e_2.error;
328
423
  return [7 /*endfinally*/];
329
- case 39: return [7 /*endfinally*/];
330
- case 40: return [2 /*return*/, records.map(function (record) {
424
+ case 43: return [7 /*endfinally*/];
425
+ case 44: return [2 /*return*/, records.map(function (record) {
331
426
  return _this.modelInstanceCreator(modelConstructor, record);
332
427
  })];
333
428
  }
@@ -336,7 +431,7 @@ var AsyncStorageAdapter = /** @class */ (function () {
336
431
  };
337
432
  AsyncStorageAdapter.prototype.query = function (modelConstructor, predicate, pagination) {
338
433
  return __awaiter(this, void 0, void 0, function () {
339
- var storeName, namespaceName, predicates, queryById, hasSort, hasPagination, records;
434
+ var storeName, namespaceName, predicates, keys, queryByKey, hasSort, hasPagination, records;
340
435
  var _this = this;
341
436
  return __generator(this, function (_a) {
342
437
  switch (_a.label) {
@@ -344,7 +439,8 @@ var AsyncStorageAdapter = /** @class */ (function () {
344
439
  storeName = this.getStorenameForModel(modelConstructor);
345
440
  namespaceName = this.namespaceResolver(modelConstructor);
346
441
  predicates = predicate && ModelPredicateCreator.getPredicates(predicate);
347
- queryById = predicates && this.idFromPredicate(predicates);
442
+ keys = this.getIndexKeys(namespaceName, modelConstructor.name);
443
+ queryByKey = predicates && this.keyValueFromPredicate(predicates, keys);
348
444
  hasSort = pagination && pagination.sort;
349
445
  hasPagination = pagination && pagination.limit;
350
446
  return [4 /*yield*/, (function () { return __awaiter(_this, void 0, void 0, function () {
@@ -352,8 +448,8 @@ var AsyncStorageAdapter = /** @class */ (function () {
352
448
  return __generator(this, function (_a) {
353
449
  switch (_a.label) {
354
450
  case 0:
355
- if (!queryById) return [3 /*break*/, 2];
356
- return [4 /*yield*/, this.getById(storeName, queryById)];
451
+ if (!queryByKey) return [3 /*break*/, 2];
452
+ return [4 /*yield*/, this.getByKey(storeName, queryByKey)];
357
453
  case 1:
358
454
  record = _a.sent();
359
455
  return [2 /*return*/, record ? [record] : []];
@@ -381,12 +477,12 @@ var AsyncStorageAdapter = /** @class */ (function () {
381
477
  });
382
478
  });
383
479
  };
384
- AsyncStorageAdapter.prototype.getById = function (storeName, id) {
480
+ AsyncStorageAdapter.prototype.getByKey = function (storeName, keyValuePath) {
385
481
  return __awaiter(this, void 0, void 0, function () {
386
482
  var record;
387
483
  return __generator(this, function (_a) {
388
484
  switch (_a.label) {
389
- case 0: return [4 /*yield*/, this.db.get(id, storeName)];
485
+ case 0: return [4 /*yield*/, this.db.get(keyValuePath, storeName)];
390
486
  case 1:
391
487
  record = _a.sent();
392
488
  return [2 /*return*/, record];
@@ -404,11 +500,33 @@ var AsyncStorageAdapter = /** @class */ (function () {
404
500
  });
405
501
  });
406
502
  };
407
- AsyncStorageAdapter.prototype.idFromPredicate = function (predicates) {
503
+ AsyncStorageAdapter.prototype.keyValueFromPredicate = function (predicates, keys) {
504
+ var e_5, _a;
408
505
  var predicateObjs = predicates.predicates;
409
- var idPredicate = predicateObjs.length === 1 &&
410
- predicateObjs.find(function (p) { return isPredicateObj(p) && p.field === 'id' && p.operator === 'eq'; });
411
- return idPredicate && idPredicate.operand;
506
+ if (predicateObjs.length !== keys.length) {
507
+ return;
508
+ }
509
+ var keyValues = [];
510
+ var _loop_1 = function (key) {
511
+ var predicateObj = predicateObjs.find(function (p) { return isPredicateObj(p) && p.field === key && p.operator === 'eq'; });
512
+ predicateObj && keyValues.push(predicateObj.operand);
513
+ };
514
+ try {
515
+ for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
516
+ var key = keys_1_1.value;
517
+ _loop_1(key);
518
+ }
519
+ }
520
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
521
+ finally {
522
+ try {
523
+ if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
524
+ }
525
+ finally { if (e_5) throw e_5.error; }
526
+ }
527
+ return keyValues.length === keys.length
528
+ ? keyValues.join(DEFAULT_PRIMARY_KEY_SEPARATOR)
529
+ : undefined;
412
530
  };
413
531
  AsyncStorageAdapter.prototype.filterOnPredicate = function (storeName, predicates) {
414
532
  return __awaiter(this, void 0, void 0, function () {
@@ -462,7 +580,7 @@ var AsyncStorageAdapter = /** @class */ (function () {
462
580
  };
463
581
  AsyncStorageAdapter.prototype.delete = function (modelOrModelConstructor, condition) {
464
582
  return __awaiter(this, void 0, void 0, function () {
465
- var deleteQueue, modelConstructor, nameSpace, models, relations, deletedModels, deletedModels, model, modelConstructor, nameSpace, storeName, fromDB, msg, predicates, predicateObjs, type, isValid, msg, relations, relations, deletedModels;
583
+ var deleteQueue, modelConstructor, nameSpace, models, relations, deletedModels, deletedModels, model, modelConstructor, namespaceName, storeName, keyValuePath, fromDB, msg, predicates, predicateObjs, type, isValid, msg, relations, relations, deletedModels;
466
584
  return __generator(this, function (_a) {
467
585
  switch (_a.label) {
468
586
  case 0:
@@ -503,10 +621,11 @@ var AsyncStorageAdapter = /** @class */ (function () {
503
621
  model = modelOrModelConstructor;
504
622
  modelConstructor = Object.getPrototypeOf(model)
505
623
  .constructor;
506
- nameSpace = this.namespaceResolver(modelConstructor);
624
+ namespaceName = this.namespaceResolver(modelConstructor);
507
625
  storeName = this.getStorenameForModel(modelConstructor);
508
626
  if (!condition) return [3 /*break*/, 11];
509
- return [4 /*yield*/, this.db.get(model.id, storeName)];
627
+ keyValuePath = this.getIndexKeyValuesPath(model);
628
+ return [4 /*yield*/, this.db.get(keyValuePath, storeName)];
510
629
  case 9:
511
630
  fromDB = _a.sent();
512
631
  if (fromDB === undefined) {
@@ -522,16 +641,14 @@ var AsyncStorageAdapter = /** @class */ (function () {
522
641
  logger.error(msg, { model: fromDB, condition: predicateObjs });
523
642
  throw new Error(msg);
524
643
  }
525
- relations = this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
526
- .relationTypes;
527
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, nameSpace, deleteQueue)];
644
+ relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
645
+ return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
528
646
  case 10:
529
647
  _a.sent();
530
648
  return [3 /*break*/, 13];
531
649
  case 11:
532
- relations = this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
533
- .relationTypes;
534
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, nameSpace, deleteQueue)];
650
+ relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
651
+ return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
535
652
  case 12:
536
653
  _a.sent();
537
654
  _a.label = 13;
@@ -550,9 +667,9 @@ var AsyncStorageAdapter = /** @class */ (function () {
550
667
  };
551
668
  AsyncStorageAdapter.prototype.deleteItem = function (deleteQueue) {
552
669
  var deleteQueue_1, deleteQueue_1_1;
553
- var e_5, _a, e_6, _b;
670
+ var e_6, _a, e_7, _b;
554
671
  return __awaiter(this, void 0, void 0, function () {
555
- var deleteItem, storeName, items, items_1, items_1_1, item, id, e_6_1, e_5_1;
672
+ var deleteItem, storeName, items, items_1, items_1_1, item, keyValuesPath, e_7_1, e_6_1;
556
673
  return __generator(this, function (_c) {
557
674
  switch (_c.label) {
558
675
  case 0:
@@ -575,16 +692,16 @@ var AsyncStorageAdapter = /** @class */ (function () {
575
692
  item = items_1_1.value;
576
693
  if (!item) return [3 /*break*/, 7];
577
694
  if (!(typeof item === 'object')) return [3 /*break*/, 7];
578
- id = item['id'];
579
- return [4 /*yield*/, this.db.delete(id, storeName)];
695
+ keyValuesPath = this.getIndexKeyValuesPath(item);
696
+ return [4 /*yield*/, this.db.delete(keyValuesPath, storeName)];
580
697
  case 6:
581
698
  _c.sent();
582
699
  _c.label = 7;
583
700
  case 7: return [3 /*break*/, 4];
584
701
  case 8: return [3 /*break*/, 15];
585
702
  case 9:
586
- e_6_1 = _c.sent();
587
- e_6 = { error: e_6_1 };
703
+ e_7_1 = _c.sent();
704
+ e_7 = { error: e_7_1 };
588
705
  return [3 /*break*/, 15];
589
706
  case 10:
590
707
  _c.trys.push([10, , 13, 14]);
@@ -595,14 +712,14 @@ var AsyncStorageAdapter = /** @class */ (function () {
595
712
  _c.label = 12;
596
713
  case 12: return [3 /*break*/, 14];
597
714
  case 13:
598
- if (e_6) throw e_6.error;
715
+ if (e_7) throw e_7.error;
599
716
  return [7 /*endfinally*/];
600
717
  case 14: return [7 /*endfinally*/];
601
718
  case 15: return [3 /*break*/, 1];
602
719
  case 16: return [3 /*break*/, 23];
603
720
  case 17:
604
- e_5_1 = _c.sent();
605
- e_5 = { error: e_5_1 };
721
+ e_6_1 = _c.sent();
722
+ e_6 = { error: e_6_1 };
606
723
  return [3 /*break*/, 23];
607
724
  case 18:
608
725
  _c.trys.push([18, , 21, 22]);
@@ -613,7 +730,7 @@ var AsyncStorageAdapter = /** @class */ (function () {
613
730
  _c.label = 20;
614
731
  case 20: return [3 /*break*/, 22];
615
732
  case 21:
616
- if (e_5) throw e_5.error;
733
+ if (e_6) throw e_6.error;
617
734
  return [7 /*endfinally*/];
618
735
  case 22: return [7 /*endfinally*/];
619
736
  case 23: return [2 /*return*/];
@@ -631,21 +748,21 @@ var AsyncStorageAdapter = /** @class */ (function () {
631
748
  */
632
749
  AsyncStorageAdapter.prototype.deleteTraverse = function (relations, models, srcModel, nameSpace, deleteQueue) {
633
750
  var relations_2, relations_2_1, models_1, models_1_1, models_2, models_2_1;
634
- var e_7, _a, e_8, _b, e_9, _c;
751
+ var e_8, _a, e_9, _b, e_10, _c;
635
752
  return __awaiter(this, void 0, void 0, function () {
636
- var rel, relationType, modelName, targetName, storeName, index, _d, model, hasOneIndex, hasOneCustomField, value, allRecords, recordToDelete, e_8_1, model, allRecords, childrenArray, e_9_1, e_7_1;
753
+ var rel, relationType, modelName, targetName, targetNames, associatedWith, storeName, index, _d, model, hasOneIndex_1, hasConnectedModelFields, keyValuesPath, values_1, allRecords, recordToDelete, hasOneIndex_2, hasOneCustomField, keyValuesPath, value_1, allRecords, recordToDelete, e_9_1, model, keyValues, allRecords, indices, childrenArray, e_10_1, e_8_1;
637
754
  var _this = this;
638
755
  return __generator(this, function (_e) {
639
756
  switch (_e.label) {
640
757
  case 0:
641
- _e.trys.push([0, 35, 36, 41]);
758
+ _e.trys.push([0, 38, 39, 44]);
642
759
  relations_2 = __asyncValues(relations);
643
760
  _e.label = 1;
644
761
  case 1: return [4 /*yield*/, relations_2.next()];
645
762
  case 2:
646
- if (!(relations_2_1 = _e.sent(), !relations_2_1.done)) return [3 /*break*/, 34];
763
+ if (!(relations_2_1 = _e.sent(), !relations_2_1.done)) return [3 /*break*/, 37];
647
764
  rel = relations_2_1.value;
648
- relationType = rel.relationType, modelName = rel.modelName, targetName = rel.targetName;
765
+ relationType = rel.relationType, modelName = rel.modelName, targetName = rel.targetName, targetNames = rel.targetNames, associatedWith = rel.associatedWith;
649
766
  storeName = this.getStorename(nameSpace, modelName);
650
767
  index = getIndex(this.schema.namespaces[nameSpace].relationships[modelName]
651
768
  .relationTypes, srcModel) ||
@@ -656,112 +773,159 @@ var AsyncStorageAdapter = /** @class */ (function () {
656
773
  _d = relationType;
657
774
  switch (_d) {
658
775
  case 'HAS_ONE': return [3 /*break*/, 3];
659
- case 'HAS_MANY': return [3 /*break*/, 17];
660
- case 'BELONGS_TO': return [3 /*break*/, 31];
776
+ case 'HAS_MANY': return [3 /*break*/, 20];
777
+ case 'BELONGS_TO': return [3 /*break*/, 34];
661
778
  }
662
- return [3 /*break*/, 32];
779
+ return [3 /*break*/, 35];
663
780
  case 3:
664
- _e.trys.push([3, 10, 11, 16]);
781
+ _e.trys.push([3, 13, 14, 19]);
665
782
  models_1 = __asyncValues(models);
666
783
  _e.label = 4;
667
784
  case 4: return [4 /*yield*/, models_1.next()];
668
785
  case 5:
669
- if (!(models_1_1 = _e.sent(), !models_1_1.done)) return [3 /*break*/, 9];
786
+ if (!(models_1_1 = _e.sent(), !models_1_1.done)) return [3 /*break*/, 12];
670
787
  model = models_1_1.value;
671
- hasOneIndex = index || 'byId';
672
- hasOneCustomField = targetName in model;
673
- value = hasOneCustomField ? model[targetName] : model.id;
674
- if (!value)
675
- return [3 /*break*/, 9];
788
+ if (!(targetNames && (targetNames === null || targetNames === void 0 ? void 0 : targetNames.length))) return [3 /*break*/, 8];
789
+ hasOneIndex_1 = index || associatedWith;
790
+ hasConnectedModelFields = targetNames.every(function (targetName) {
791
+ return model.hasOwnProperty(targetName);
792
+ });
793
+ keyValuesPath = this.getIndexKeyValuesPath(model);
794
+ if (hasConnectedModelFields) {
795
+ // Values will be that of the child model
796
+ values_1 = targetNames.map(function (targetName) { return model[targetName]; });
797
+ }
798
+ else {
799
+ // values will be that of the parent model
800
+ values_1 = keyValuesPath;
801
+ }
802
+ if (values_1.length === 0)
803
+ return [3 /*break*/, 12];
676
804
  return [4 /*yield*/, this.db.getAll(storeName)];
677
805
  case 6:
678
806
  allRecords = _e.sent();
679
- recordToDelete = allRecords.filter(function (childItem) { return childItem[hasOneIndex] === value; });
807
+ recordToDelete = void 0;
808
+ // values === targetNames
809
+ if (hasConnectedModelFields) {
810
+ /**
811
+ * Retrieve record by finding the record where all
812
+ * targetNames are present on the connected model
813
+ */
814
+ recordToDelete = allRecords.filter(function (childItem) {
815
+ return values_1.every(function (value) { return childItem[value] != null; });
816
+ });
817
+ }
818
+ else {
819
+ // values === keyValuePath
820
+ recordToDelete = allRecords.filter(function (childItem) { return childItem[hasOneIndex_1] === values_1; });
821
+ }
680
822
  return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
681
823
  .relationTypes, recordToDelete, modelName, nameSpace, deleteQueue)];
682
824
  case 7:
683
825
  _e.sent();
684
- _e.label = 8;
685
- case 8: return [3 /*break*/, 4];
686
- case 9: return [3 /*break*/, 16];
826
+ return [3 /*break*/, 11];
827
+ case 8:
828
+ hasOneIndex_2 = index || associatedWith;
829
+ hasOneCustomField = targetName in model;
830
+ keyValuesPath = this.getIndexKeyValuesPath(model);
831
+ value_1 = hasOneCustomField
832
+ ? model[targetName]
833
+ : keyValuesPath;
834
+ if (!value_1)
835
+ return [3 /*break*/, 12];
836
+ return [4 /*yield*/, this.db.getAll(storeName)];
837
+ case 9:
838
+ allRecords = _e.sent();
839
+ recordToDelete = allRecords.filter(function (childItem) { return childItem[hasOneIndex_2] === value_1; });
840
+ return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
841
+ .relationTypes, recordToDelete, modelName, nameSpace, deleteQueue)];
687
842
  case 10:
688
- e_8_1 = _e.sent();
689
- e_8 = { error: e_8_1 };
690
- return [3 /*break*/, 16];
691
- case 11:
692
- _e.trys.push([11, , 14, 15]);
693
- if (!(models_1_1 && !models_1_1.done && (_b = models_1.return))) return [3 /*break*/, 13];
694
- return [4 /*yield*/, _b.call(models_1)];
695
- case 12:
696
843
  _e.sent();
697
- _e.label = 13;
698
- case 13: return [3 /*break*/, 15];
844
+ _e.label = 11;
845
+ case 11: return [3 /*break*/, 4];
846
+ case 12: return [3 /*break*/, 19];
847
+ case 13:
848
+ e_9_1 = _e.sent();
849
+ e_9 = { error: e_9_1 };
850
+ return [3 /*break*/, 19];
699
851
  case 14:
700
- if (e_8) throw e_8.error;
701
- return [7 /*endfinally*/];
702
- case 15: return [7 /*endfinally*/];
703
- case 16: return [3 /*break*/, 33];
852
+ _e.trys.push([14, , 17, 18]);
853
+ if (!(models_1_1 && !models_1_1.done && (_b = models_1.return))) return [3 /*break*/, 16];
854
+ return [4 /*yield*/, _b.call(models_1)];
855
+ case 15:
856
+ _e.sent();
857
+ _e.label = 16;
858
+ case 16: return [3 /*break*/, 18];
704
859
  case 17:
705
- _e.trys.push([17, 24, 25, 30]);
860
+ if (e_9) throw e_9.error;
861
+ return [7 /*endfinally*/];
862
+ case 18: return [7 /*endfinally*/];
863
+ case 19: return [3 /*break*/, 36];
864
+ case 20:
865
+ _e.trys.push([20, 27, 28, 33]);
706
866
  models_2 = __asyncValues(models);
707
- _e.label = 18;
708
- case 18: return [4 /*yield*/, models_2.next()];
709
- case 19:
710
- if (!(models_2_1 = _e.sent(), !models_2_1.done)) return [3 /*break*/, 23];
867
+ _e.label = 21;
868
+ case 21: return [4 /*yield*/, models_2.next()];
869
+ case 22:
870
+ if (!(models_2_1 = _e.sent(), !models_2_1.done)) return [3 /*break*/, 26];
711
871
  model = models_2_1.value;
872
+ keyValues = this.getIndexKeyValues(model);
712
873
  return [4 /*yield*/, this.db.getAll(storeName)];
713
- case 20:
874
+ case 23:
714
875
  allRecords = _e.sent();
715
- childrenArray = allRecords.filter(function (childItem) { return childItem[index] === model.id; });
876
+ indices = index.split('-');
877
+ childrenArray = allRecords.filter(function (childItem) {
878
+ return indices.every(function (index) { return keyValues.includes(childItem[index]); });
879
+ });
716
880
  return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
717
881
  .relationTypes, childrenArray, modelName, nameSpace, deleteQueue)];
718
- case 21:
719
- _e.sent();
720
- _e.label = 22;
721
- case 22: return [3 /*break*/, 18];
722
- case 23: return [3 /*break*/, 30];
723
882
  case 24:
724
- e_9_1 = _e.sent();
725
- e_9 = { error: e_9_1 };
726
- return [3 /*break*/, 30];
727
- case 25:
728
- _e.trys.push([25, , 28, 29]);
729
- if (!(models_2_1 && !models_2_1.done && (_c = models_2.return))) return [3 /*break*/, 27];
730
- return [4 /*yield*/, _c.call(models_2)];
731
- case 26:
732
883
  _e.sent();
733
- _e.label = 27;
734
- case 27: return [3 /*break*/, 29];
884
+ _e.label = 25;
885
+ case 25: return [3 /*break*/, 21];
886
+ case 26: return [3 /*break*/, 33];
887
+ case 27:
888
+ e_10_1 = _e.sent();
889
+ e_10 = { error: e_10_1 };
890
+ return [3 /*break*/, 33];
735
891
  case 28:
736
- if (e_9) throw e_9.error;
892
+ _e.trys.push([28, , 31, 32]);
893
+ if (!(models_2_1 && !models_2_1.done && (_c = models_2.return))) return [3 /*break*/, 30];
894
+ return [4 /*yield*/, _c.call(models_2)];
895
+ case 29:
896
+ _e.sent();
897
+ _e.label = 30;
898
+ case 30: return [3 /*break*/, 32];
899
+ case 31:
900
+ if (e_10) throw e_10.error;
737
901
  return [7 /*endfinally*/];
738
- case 29: return [7 /*endfinally*/];
739
- case 30: return [3 /*break*/, 33];
740
- case 31:
902
+ case 32: return [7 /*endfinally*/];
903
+ case 33: return [3 /*break*/, 36];
904
+ case 34:
741
905
  // Intentionally blank
742
- return [3 /*break*/, 33];
743
- case 32:
744
- exhaustiveCheck(relationType);
745
- return [3 /*break*/, 33];
746
- case 33: return [3 /*break*/, 1];
747
- case 34: return [3 /*break*/, 41];
906
+ return [3 /*break*/, 36];
748
907
  case 35:
749
- e_7_1 = _e.sent();
750
- e_7 = { error: e_7_1 };
751
- return [3 /*break*/, 41];
752
- case 36:
753
- _e.trys.push([36, , 39, 40]);
754
- if (!(relations_2_1 && !relations_2_1.done && (_a = relations_2.return))) return [3 /*break*/, 38];
908
+ exhaustiveCheck(relationType);
909
+ return [3 /*break*/, 36];
910
+ case 36: return [3 /*break*/, 1];
911
+ case 37: return [3 /*break*/, 44];
912
+ case 38:
913
+ e_8_1 = _e.sent();
914
+ e_8 = { error: e_8_1 };
915
+ return [3 /*break*/, 44];
916
+ case 39:
917
+ _e.trys.push([39, , 42, 43]);
918
+ if (!(relations_2_1 && !relations_2_1.done && (_a = relations_2.return))) return [3 /*break*/, 41];
755
919
  return [4 /*yield*/, _a.call(relations_2)];
756
- case 37:
920
+ case 40:
757
921
  _e.sent();
758
- _e.label = 38;
759
- case 38: return [3 /*break*/, 40];
760
- case 39:
761
- if (e_7) throw e_7.error;
922
+ _e.label = 41;
923
+ case 41: return [3 /*break*/, 43];
924
+ case 42:
925
+ if (e_8) throw e_8.error;
762
926
  return [7 /*endfinally*/];
763
- case 40: return [7 /*endfinally*/];
764
- case 41:
927
+ case 43: return [7 /*endfinally*/];
928
+ case 44:
765
929
  deleteQueue.push({
766
930
  storeName: this.getStorename(nameSpace, srcModel),
767
931
  items: models.map(function (record) {
@@ -789,21 +953,25 @@ var AsyncStorageAdapter = /** @class */ (function () {
789
953
  };
790
954
  AsyncStorageAdapter.prototype.batchSave = function (modelConstructor, items) {
791
955
  return __awaiter(this, void 0, void 0, function () {
792
- var modelName, namespaceName, storeName, batch, _loop_1, this_1, items_2, items_2_1, item;
793
- var e_10, _a;
956
+ var modelName, namespaceName, storeName, keys, batch, _loop_2, this_1, items_2, items_2_1, item;
957
+ var e_11, _a;
958
+ var _this = this;
794
959
  return __generator(this, function (_b) {
795
960
  switch (_b.label) {
796
961
  case 0:
797
962
  modelName = modelConstructor.name;
798
963
  namespaceName = this.namespaceResolver(modelConstructor);
799
964
  storeName = this.getStorename(namespaceName, modelName);
965
+ keys = this.getIndexKeys(namespaceName, modelName);
800
966
  batch = [];
801
- _loop_1 = function (item) {
802
- var id = item.id;
803
- var connectedModels = traverseModel(modelConstructor.name, this_1.modelInstanceCreator(modelConstructor, item), this_1.schema.namespaces[this_1.namespaceResolver(modelConstructor)], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
967
+ _loop_2 = function (item) {
968
+ var model = this_1.modelInstanceCreator(modelConstructor, item);
969
+ var connectedModels = traverseModel(modelName, model, this_1.schema.namespaces[namespaceName], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
970
+ var keyValuesPath = this_1.getIndexKeyValuesPath(model);
804
971
  var instance = connectedModels.find(function (_a) {
805
972
  var instance = _a.instance;
806
- return instance.id === id;
973
+ var instanceKeyValuesPath = _this.getIndexKeyValuesPath(instance);
974
+ return _this.keysEqual([instanceKeyValuesPath], [keyValuesPath]);
807
975
  }).instance;
808
976
  batch.push(instance);
809
977
  };
@@ -811,17 +979,17 @@ var AsyncStorageAdapter = /** @class */ (function () {
811
979
  try {
812
980
  for (items_2 = __values(items), items_2_1 = items_2.next(); !items_2_1.done; items_2_1 = items_2.next()) {
813
981
  item = items_2_1.value;
814
- _loop_1(item);
982
+ _loop_2(item);
815
983
  }
816
984
  }
817
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
985
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
818
986
  finally {
819
987
  try {
820
988
  if (items_2_1 && !items_2_1.done && (_a = items_2.return)) _a.call(items_2);
821
989
  }
822
- finally { if (e_10) throw e_10.error; }
990
+ finally { if (e_11) throw e_11.error; }
823
991
  }
824
- return [4 /*yield*/, this.db.batchSave(storeName, batch)];
992
+ return [4 /*yield*/, this.db.batchSave(storeName, batch, keys)];
825
993
  case 1: return [2 /*return*/, _b.sent()];
826
994
  }
827
995
  });