@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
@@ -42,17 +42,6 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
42
42
  function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
43
43
  function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
44
44
  };
45
- var __values = (this && this.__values) || function(o) {
46
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
47
- if (m) return m.call(o);
48
- if (o && typeof o.length === "number") return {
49
- next: function () {
50
- if (o && i >= o.length) o = void 0;
51
- return { value: o && o[i++], done: !o };
52
- }
53
- };
54
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
55
- };
56
45
  var __read = (this && this.__read) || function (o, n) {
57
46
  var m = typeof Symbol === "function" && o[Symbol.iterator];
58
47
  if (!m) return o;
@@ -69,6 +58,17 @@ var __read = (this && this.__read) || function (o, n) {
69
58
  }
70
59
  return ar;
71
60
  };
61
+ var __values = (this && this.__values) || function(o) {
62
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
63
+ if (m) return m.call(o);
64
+ if (o && typeof o.length === "number") return {
65
+ next: function () {
66
+ if (o && i >= o.length) o = void 0;
67
+ return { value: o && o[i++], done: !o };
68
+ }
69
+ };
70
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
71
+ };
72
72
  var __spread = (this && this.__spread) || function () {
73
73
  for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
74
74
  return ar;
@@ -123,6 +123,36 @@ var IndexedDBAdapter = /** @class */ (function () {
123
123
  var storeName = namespace + "_" + modelName;
124
124
  return storeName;
125
125
  };
126
+ IndexedDBAdapter.prototype.getNamespaceAndModelFromStorename = function (storeName) {
127
+ var _a = __read(storeName.split('_')), namespaceName = _a[0], modelNameArr = _a.slice(1);
128
+ return {
129
+ namespaceName: namespaceName,
130
+ modelName: modelNameArr.join('_'),
131
+ };
132
+ };
133
+ IndexedDBAdapter.prototype.getIndexKeyPath = function (namespaceName, modelName) {
134
+ var _a;
135
+ var namespace = this.schema.namespaces[namespaceName];
136
+ var keyPath = (_a = namespace === null || namespace === void 0 ? void 0 : namespace.keys[modelName]) === null || _a === void 0 ? void 0 : _a.primaryKey;
137
+ if (keyPath) {
138
+ return keyPath;
139
+ }
140
+ return ['id'];
141
+ };
142
+ IndexedDBAdapter.prototype.getIndexKeyValues = function (model) {
143
+ var modelConstructor = Object.getPrototypeOf(model)
144
+ .constructor;
145
+ var namespaceName = this.namespaceResolver(modelConstructor);
146
+ var keys = this.getIndexKeyPath(namespaceName, modelConstructor.name);
147
+ var keyValues = keys.map(function (field) { return model[field]; });
148
+ return keyValues;
149
+ };
150
+ IndexedDBAdapter.prototype.keysEqual = function (keysA, keysB) {
151
+ if (keysA.length !== keysB.length) {
152
+ return false;
153
+ }
154
+ return keysA.every(function (key, idx) { return key === keysB[idx]; });
155
+ };
126
156
  IndexedDBAdapter.prototype.setUp = function (theSchema, namespaceResolver, modelInstanceCreator, getModelConstructorByModelName, sessionId) {
127
157
  return __awaiter(this, void 0, void 0, function () {
128
158
  var VERSION, _a, error_1;
@@ -154,40 +184,35 @@ var IndexedDBAdapter = /** @class */ (function () {
154
184
  case 5:
155
185
  _b.trys.push([5, 8, , 9]);
156
186
  if (!!this.db) return [3 /*break*/, 7];
157
- VERSION = 2;
187
+ VERSION = 3;
158
188
  _a = this;
159
189
  return [4 /*yield*/, idb.openDB(this.dbName, VERSION, {
160
190
  upgrade: function (db, oldVersion, newVersion, txn) { return __awaiter(_this, void 0, void 0, function () {
161
- var _a, _b, storeName, origStore, tmpName, newStore, cursor, count, e_1_1, error_2;
162
- var e_1, _c;
191
+ var _a, _b, storeName, origStore, tmpName, newStore, origIndexNames, origIndexNames_1, origIndexNames_1_1, idxName, idx, keyPath_1, unique, _c, namespaceName, modelName, keyPath, cursor, count, e_1_1, error_2;
192
+ var e_1, _d, e_2, _e;
163
193
  var _this = this;
164
- return __generator(this, function (_d) {
165
- switch (_d.label) {
194
+ return __generator(this, function (_f) {
195
+ switch (_f.label) {
166
196
  case 0:
167
197
  if (oldVersion === 0) {
168
198
  Object.keys(theSchema.namespaces).forEach(function (namespaceName) {
169
199
  var namespace = theSchema.namespaces[namespaceName];
170
200
  Object.keys(namespace.models).forEach(function (modelName) {
171
201
  var storeName = _this.getStorename(namespaceName, modelName);
172
- var store = db.createObjectStore(storeName, {
173
- autoIncrement: true,
174
- });
175
- var indexes = _this.schema.namespaces[namespaceName].relationships[modelName].indexes;
176
- indexes.forEach(function (index) { return store.createIndex(index, index); });
177
- store.createIndex('byId', 'id', { unique: true });
202
+ _this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
178
203
  });
179
204
  });
180
205
  return [2 /*return*/];
181
206
  }
182
- if (!(oldVersion === 1 && newVersion === 2)) return [3 /*break*/, 16];
183
- _d.label = 1;
207
+ if (!((oldVersion === 1 || oldVersion === 2) && newVersion === 3)) return [3 /*break*/, 16];
208
+ _f.label = 1;
184
209
  case 1:
185
- _d.trys.push([1, 14, , 15]);
186
- _d.label = 2;
210
+ _f.trys.push([1, 14, , 15]);
211
+ _f.label = 2;
187
212
  case 2:
188
- _d.trys.push([2, 11, 12, 13]);
213
+ _f.trys.push([2, 11, 12, 13]);
189
214
  _a = __values(txn.objectStoreNames), _b = _a.next();
190
- _d.label = 3;
215
+ _f.label = 3;
191
216
  case 3:
192
217
  if (!!_b.done) return [3 /*break*/, 10];
193
218
  storeName = _b.value;
@@ -198,46 +223,91 @@ var IndexedDBAdapter = /** @class */ (function () {
198
223
  keyPath: undefined,
199
224
  autoIncrement: true,
200
225
  });
201
- newStore.createIndex('byId', 'id', { unique: true });
226
+ origIndexNames = Object.values(origStore.indexNames);
227
+ try {
228
+ for (origIndexNames_1 = (e_2 = void 0, __values(origIndexNames)), origIndexNames_1_1 = origIndexNames_1.next(); !origIndexNames_1_1.done; origIndexNames_1_1 = origIndexNames_1.next()) {
229
+ idxName = origIndexNames_1_1.value;
230
+ if (idxName === 'byId') {
231
+ // don't migrate this index. It'll be replaced with byPk
232
+ continue;
233
+ }
234
+ idx = origStore.index(idxName);
235
+ keyPath_1 = idx.keyPath, unique = idx.unique;
236
+ newStore.createIndex(idxName, keyPath_1, { unique: unique });
237
+ }
238
+ }
239
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
240
+ finally {
241
+ try {
242
+ if (origIndexNames_1_1 && !origIndexNames_1_1.done && (_e = origIndexNames_1.return)) _e.call(origIndexNames_1);
243
+ }
244
+ finally { if (e_2) throw e_2.error; }
245
+ }
246
+ _c = this.getNamespaceAndModelFromStorename(storeName), namespaceName = _c.namespaceName, modelName = _c.modelName;
247
+ keyPath = this.getIndexKeyPath(namespaceName, modelName);
248
+ newStore.createIndex('byPk', keyPath, { unique: true });
202
249
  return [4 /*yield*/, origStore.openCursor()];
203
250
  case 4:
204
- cursor = _d.sent();
251
+ cursor = _f.sent();
205
252
  count = 0;
206
- _d.label = 5;
253
+ _f.label = 5;
207
254
  case 5:
208
255
  if (!(cursor && cursor.value)) return [3 /*break*/, 8];
209
256
  // we don't pass key, since they are all new entries in the new store
210
257
  return [4 /*yield*/, newStore.put(cursor.value)];
211
258
  case 6:
212
259
  // we don't pass key, since they are all new entries in the new store
213
- _d.sent();
260
+ _f.sent();
214
261
  return [4 /*yield*/, cursor.continue()];
215
262
  case 7:
216
- cursor = _d.sent();
263
+ cursor = _f.sent();
217
264
  count++;
218
265
  return [3 /*break*/, 5];
219
266
  case 8:
220
267
  // delete original
221
268
  db.deleteObjectStore(tmpName);
222
269
  logger.debug(count + " " + storeName + " records migrated");
223
- _d.label = 9;
270
+ _f.label = 9;
224
271
  case 9:
225
272
  _b = _a.next();
226
273
  return [3 /*break*/, 3];
227
274
  case 10: return [3 /*break*/, 13];
228
275
  case 11:
229
- e_1_1 = _d.sent();
276
+ e_1_1 = _f.sent();
230
277
  e_1 = { error: e_1_1 };
231
278
  return [3 /*break*/, 13];
232
279
  case 12:
233
280
  try {
234
- if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
281
+ if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
235
282
  }
236
283
  finally { if (e_1) throw e_1.error; }
237
284
  return [7 /*endfinally*/];
238
- case 13: return [3 /*break*/, 15];
285
+ case 13:
286
+ // add new models created after IndexedDB, but before migration
287
+ // this case may happen when a user has not opened an app for
288
+ // some time and a new model is added during that time
289
+ Object.keys(theSchema.namespaces).forEach(function (namespaceName) {
290
+ var namespace = theSchema.namespaces[namespaceName];
291
+ var objectStoreNames = new Set(txn.objectStoreNames);
292
+ Object.keys(namespace.models)
293
+ .map(function (modelName) {
294
+ return [
295
+ modelName,
296
+ _this.getStorename(namespaceName, modelName),
297
+ ];
298
+ })
299
+ .filter(function (_a) {
300
+ var _b = __read(_a, 2), storeName = _b[1];
301
+ return !objectStoreNames.has(storeName);
302
+ })
303
+ .forEach(function (_a) {
304
+ var _b = __read(_a, 2), modelName = _b[0], storeName = _b[1];
305
+ _this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
306
+ });
307
+ });
308
+ return [3 /*break*/, 15];
239
309
  case 14:
240
- error_2 = _d.sent();
310
+ error_2 = _f.sent();
241
311
  logger.error('Error migrating IndexedDB data', error_2);
242
312
  txn.abort();
243
313
  throw error_2;
@@ -261,7 +331,7 @@ var IndexedDBAdapter = /** @class */ (function () {
261
331
  });
262
332
  });
263
333
  };
264
- IndexedDBAdapter.prototype._get = function (storeOrStoreName, id) {
334
+ IndexedDBAdapter.prototype._get = function (storeOrStoreName, keyArr) {
265
335
  return __awaiter(this, void 0, void 0, function () {
266
336
  var index, storeName, store, result;
267
337
  return __generator(this, function (_a) {
@@ -269,13 +339,13 @@ var IndexedDBAdapter = /** @class */ (function () {
269
339
  case 0:
270
340
  if (typeof storeOrStoreName === 'string') {
271
341
  storeName = storeOrStoreName;
272
- index = this.db.transaction(storeName, 'readonly').store.index('byId');
342
+ index = this.db.transaction(storeName, 'readonly').store.index('byPk');
273
343
  }
274
344
  else {
275
345
  store = storeOrStoreName;
276
- index = store.index('byId');
346
+ index = store.index('byPk');
277
347
  }
278
- return [4 /*yield*/, index.get(id)];
348
+ return [4 /*yield*/, index.get(keyArr)];
279
349
  case 1:
280
350
  result = _a.sent();
281
351
  return [2 /*return*/, result];
@@ -284,9 +354,9 @@ var IndexedDBAdapter = /** @class */ (function () {
284
354
  });
285
355
  };
286
356
  IndexedDBAdapter.prototype.save = function (model, condition) {
287
- var e_2, _a;
357
+ var e_3, _a;
288
358
  return __awaiter(this, void 0, void 0, function () {
289
- var modelConstructor, storeName, connectedModels, namespaceName, set, connectionStoreNames, tx, store, fromDB, predicates, predicateObjs, type, isValid, msg, result, connectionStoreNames_1, connectionStoreNames_1_1, resItem, storeName_1, item, instance, store_1, id, fromDB_1, opType, key, e_2_1;
359
+ var modelConstructor, storeName, namespaceName, connectedModels, set, connectionStoreNames, tx, store, keyValues, fromDB, predicates, predicateObjs, type, isValid, msg, result, connectionStoreNames_1, connectionStoreNames_1_1, resItem, storeName_1, item, instance, keys, store_1, itemKeyValues, fromDB_1, opType, modelKeyValues, keysEqual, key, e_3_1;
290
360
  var _this = this;
291
361
  return __generator(this, function (_b) {
292
362
  switch (_b.label) {
@@ -296,18 +366,20 @@ var IndexedDBAdapter = /** @class */ (function () {
296
366
  modelConstructor = Object.getPrototypeOf(model)
297
367
  .constructor;
298
368
  storeName = this.getStorenameForModel(modelConstructor);
299
- connectedModels = util_1.traverseModel(modelConstructor.name, model, this.schema.namespaces[this.namespaceResolver(modelConstructor)], this.modelInstanceCreator, this.getModelConstructorByModelName);
300
369
  namespaceName = this.namespaceResolver(modelConstructor);
370
+ connectedModels = util_1.traverseModel(modelConstructor.name, model, this.schema.namespaces[namespaceName], this.modelInstanceCreator, this.getModelConstructorByModelName);
301
371
  set = new Set();
302
372
  connectionStoreNames = Object.values(connectedModels).map(function (_a) {
303
373
  var modelName = _a.modelName, item = _a.item, instance = _a.instance;
304
374
  var storeName = _this.getStorename(namespaceName, modelName);
305
375
  set.add(storeName);
306
- return { storeName: storeName, item: item, instance: instance };
376
+ var keys = _this.getIndexKeyPath(namespaceName, modelName);
377
+ return { storeName: storeName, item: item, instance: instance, keys: keys };
307
378
  });
308
379
  tx = this.db.transaction(__spread([storeName], Array.from(set.values())), 'readwrite');
309
380
  store = tx.objectStore(storeName);
310
- return [4 /*yield*/, this._get(store, model.id)];
381
+ keyValues = this.getIndexKeyValues(model);
382
+ return [4 /*yield*/, this._get(store, keyValues)];
311
383
  case 2:
312
384
  fromDB = _b.sent();
313
385
  if (condition && fromDB) {
@@ -330,15 +402,20 @@ var IndexedDBAdapter = /** @class */ (function () {
330
402
  case 5:
331
403
  if (!(connectionStoreNames_1_1 = _b.sent(), !connectionStoreNames_1_1.done)) return [3 /*break*/, 10];
332
404
  resItem = connectionStoreNames_1_1.value;
333
- storeName_1 = resItem.storeName, item = resItem.item, instance = resItem.instance;
405
+ storeName_1 = resItem.storeName, item = resItem.item, instance = resItem.instance, keys = resItem.keys;
334
406
  store_1 = tx.objectStore(storeName_1);
335
- id = item.id;
336
- return [4 /*yield*/, this._get(store_1, id)];
407
+ itemKeyValues = keys.map(function (key) {
408
+ var value = item[key];
409
+ return value;
410
+ });
411
+ return [4 /*yield*/, this._get(store_1, itemKeyValues)];
337
412
  case 6:
338
413
  fromDB_1 = _b.sent();
339
414
  opType = fromDB_1 === undefined ? types_1.OpType.INSERT : types_1.OpType.UPDATE;
340
- if (!(id === model.id || opType === types_1.OpType.INSERT)) return [3 /*break*/, 9];
341
- return [4 /*yield*/, store_1.index('byId').getKey(item.id)];
415
+ modelKeyValues = this.getIndexKeyValues(model);
416
+ keysEqual = this.keysEqual(itemKeyValues, modelKeyValues);
417
+ if (!(keysEqual || opType === types_1.OpType.INSERT)) return [3 /*break*/, 9];
418
+ return [4 /*yield*/, store_1.index('byPk').getKey(itemKeyValues)];
342
419
  case 7:
343
420
  key = _b.sent();
344
421
  return [4 /*yield*/, store_1.put(item, key)];
@@ -349,8 +426,8 @@ var IndexedDBAdapter = /** @class */ (function () {
349
426
  case 9: return [3 /*break*/, 4];
350
427
  case 10: return [3 /*break*/, 17];
351
428
  case 11:
352
- e_2_1 = _b.sent();
353
- e_2 = { error: e_2_1 };
429
+ e_3_1 = _b.sent();
430
+ e_3 = { error: e_3_1 };
354
431
  return [3 /*break*/, 17];
355
432
  case 12:
356
433
  _b.trys.push([12, , 15, 16]);
@@ -361,7 +438,7 @@ var IndexedDBAdapter = /** @class */ (function () {
361
438
  _b.label = 14;
362
439
  case 14: return [3 /*break*/, 16];
363
440
  case 15:
364
- if (e_2) throw e_2.error;
441
+ if (e_3) throw e_3.error;
365
442
  return [7 /*endfinally*/];
366
443
  case 16: return [7 /*endfinally*/];
367
444
  case 17: return [4 /*yield*/, tx.done];
@@ -374,9 +451,9 @@ var IndexedDBAdapter = /** @class */ (function () {
374
451
  };
375
452
  IndexedDBAdapter.prototype.load = function (namespaceName, srcModelName, records) {
376
453
  var records_1, records_1_1, records_2, records_2_1;
377
- var e_3, _a, e_4, _b, e_5, _c;
454
+ var e_4, _a, e_5, _b, e_6, _c;
378
455
  return __awaiter(this, void 0, void 0, function () {
379
- var namespace, relations, connectionStoreNames, modelConstructor, tx, relations_1, relations_1_1, relation, fieldName, modelName, targetName, storeName, store, modelConstructor_1, _d, recordItem, getByfield, connectionRecord, e_4_1, recordItem, connectionRecord, e_5_1, e_3_1;
456
+ var namespace, relations, connectionStoreNames, modelConstructor, tx, relations_1, relations_1_1, relation, fieldName, modelName, targetName, targetNames, storeName, store, modelConstructor_1, _d, recordItem, getByFields, allPresent, keys, connectionRecord, getByfield, key, connectionRecord, e_5_1, recordItem, allPresent, keys, connectionRecord, key, connectionRecord, e_6_1, e_4_1;
380
457
  var _this = this;
381
458
  return __generator(this, function (_e) {
382
459
  switch (_e.label) {
@@ -396,122 +473,170 @@ var IndexedDBAdapter = /** @class */ (function () {
396
473
  tx = this.db.transaction(__spread(connectionStoreNames), 'readonly');
397
474
  _e.label = 1;
398
475
  case 1:
399
- _e.trys.push([1, 34, 35, 40]);
476
+ _e.trys.push([1, 38, 39, 44]);
400
477
  relations_1 = __asyncValues(relations);
401
478
  _e.label = 2;
402
479
  case 2: return [4 /*yield*/, relations_1.next()];
403
480
  case 3:
404
- if (!(relations_1_1 = _e.sent(), !relations_1_1.done)) return [3 /*break*/, 33];
481
+ if (!(relations_1_1 = _e.sent(), !relations_1_1.done)) return [3 /*break*/, 37];
405
482
  relation = relations_1_1.value;
406
- fieldName = relation.fieldName, modelName = relation.modelName, targetName = relation.targetName;
483
+ fieldName = relation.fieldName, modelName = relation.modelName, targetName = relation.targetName, targetNames = relation.targetNames;
407
484
  storeName = this.getStorename(namespaceName, modelName);
408
485
  store = tx.objectStore(storeName);
409
486
  modelConstructor_1 = this.getModelConstructorByModelName(namespaceName, modelName);
410
487
  _d = relation.relationType;
411
488
  switch (_d) {
412
489
  case 'HAS_ONE': return [3 /*break*/, 4];
413
- case 'BELONGS_TO': return [3 /*break*/, 17];
414
- case 'HAS_MANY': return [3 /*break*/, 30];
490
+ case 'BELONGS_TO': return [3 /*break*/, 19];
491
+ case 'HAS_MANY': return [3 /*break*/, 34];
415
492
  }
416
- return [3 /*break*/, 31];
493
+ return [3 /*break*/, 35];
417
494
  case 4:
418
- _e.trys.push([4, 10, 11, 16]);
495
+ _e.trys.push([4, 12, 13, 18]);
419
496
  records_1 = __asyncValues(records);
420
497
  _e.label = 5;
421
498
  case 5: return [4 /*yield*/, records_1.next()];
422
499
  case 6:
423
- if (!(records_1_1 = _e.sent(), !records_1_1.done)) return [3 /*break*/, 9];
500
+ if (!(records_1_1 = _e.sent(), !records_1_1.done)) return [3 /*break*/, 11];
424
501
  recordItem = records_1_1.value;
425
- getByfield = recordItem[targetName] ? targetName : fieldName;
426
- if (!recordItem[getByfield])
427
- return [3 /*break*/, 9];
428
- return [4 /*yield*/, this._get(store, recordItem[getByfield])];
502
+ if (!(targetNames === null || targetNames === void 0 ? void 0 : targetNames.length)) return [3 /*break*/, 8];
503
+ getByFields = [];
504
+ allPresent = void 0;
505
+ // iterate through all targetnames to make sure they are all present in the recordItem
506
+ allPresent = targetNames.every(function (targetName) {
507
+ return recordItem[targetName] != null;
508
+ });
509
+ if (!allPresent) {
510
+ return [3 /*break*/, 11];
511
+ }
512
+ getByFields = targetNames;
513
+ keys = getByFields.map(function (getByField) { return recordItem[getByField]; });
514
+ return [4 /*yield*/, this._get(store, keys)];
429
515
  case 7:
430
516
  connectionRecord = _e.sent();
431
517
  recordItem[fieldName] =
432
518
  connectionRecord &&
433
519
  this.modelInstanceCreator(modelConstructor_1, connectionRecord);
434
- _e.label = 8;
435
- case 8: return [3 /*break*/, 5];
436
- case 9: return [3 /*break*/, 16];
437
- case 10:
438
- e_4_1 = _e.sent();
439
- e_4 = { error: e_4_1 };
440
- return [3 /*break*/, 16];
441
- case 11:
442
- _e.trys.push([11, , 14, 15]);
443
- if (!(records_1_1 && !records_1_1.done && (_b = records_1.return))) return [3 /*break*/, 13];
444
- return [4 /*yield*/, _b.call(records_1)];
520
+ return [3 /*break*/, 10];
521
+ case 8:
522
+ getByfield = recordItem[targetName]
523
+ ? targetName
524
+ : fieldName;
525
+ // We break here, because the recordItem does not have 'team', the `getByField`
526
+ // extract the keys on the related model.
527
+ if (!recordItem[getByfield])
528
+ return [3 /*break*/, 11];
529
+ key = [recordItem[getByfield]];
530
+ return [4 /*yield*/, this._get(store, key)];
531
+ case 9:
532
+ connectionRecord = _e.sent();
533
+ recordItem[fieldName] =
534
+ connectionRecord &&
535
+ this.modelInstanceCreator(modelConstructor_1, connectionRecord);
536
+ _e.label = 10;
537
+ case 10: return [3 /*break*/, 5];
538
+ case 11: return [3 /*break*/, 18];
445
539
  case 12:
446
- _e.sent();
447
- _e.label = 13;
448
- case 13: return [3 /*break*/, 15];
540
+ e_5_1 = _e.sent();
541
+ e_5 = { error: e_5_1 };
542
+ return [3 /*break*/, 18];
543
+ case 13:
544
+ _e.trys.push([13, , 16, 17]);
545
+ if (!(records_1_1 && !records_1_1.done && (_b = records_1.return))) return [3 /*break*/, 15];
546
+ return [4 /*yield*/, _b.call(records_1)];
449
547
  case 14:
450
- if (e_4) throw e_4.error;
548
+ _e.sent();
549
+ _e.label = 15;
550
+ case 15: return [3 /*break*/, 17];
551
+ case 16:
552
+ if (e_5) throw e_5.error;
451
553
  return [7 /*endfinally*/];
452
- case 15: return [7 /*endfinally*/];
453
- case 16: return [3 /*break*/, 32];
454
- case 17:
455
- _e.trys.push([17, 23, 24, 29]);
456
- records_2 = __asyncValues(records);
457
- _e.label = 18;
458
- case 18: return [4 /*yield*/, records_2.next()];
554
+ case 17: return [7 /*endfinally*/];
555
+ case 18: return [3 /*break*/, 36];
459
556
  case 19:
460
- if (!(records_2_1 = _e.sent(), !records_2_1.done)) return [3 /*break*/, 22];
557
+ _e.trys.push([19, 27, 28, 33]);
558
+ records_2 = __asyncValues(records);
559
+ _e.label = 20;
560
+ case 20: return [4 /*yield*/, records_2.next()];
561
+ case 21:
562
+ if (!(records_2_1 = _e.sent(), !records_2_1.done)) return [3 /*break*/, 26];
461
563
  recordItem = records_2_1.value;
462
- if (!recordItem[targetName]) return [3 /*break*/, 21];
463
- return [4 /*yield*/, this._get(store, recordItem[targetName])];
464
- case 20:
564
+ if (!(targetNames === null || targetNames === void 0 ? void 0 : targetNames.length)) return [3 /*break*/, 23];
565
+ allPresent = void 0;
566
+ // iterate through all targetnames to make sure they are all present in the recordItem
567
+ allPresent = targetNames.every(function (targetName) {
568
+ return recordItem[targetName] != null;
569
+ });
570
+ // If not present, there is not yet a connected record
571
+ if (!allPresent) {
572
+ return [3 /*break*/, 26];
573
+ }
574
+ keys = targetNames.map(function (targetName) { return recordItem[targetName]; });
575
+ return [4 /*yield*/, this._get(store, keys)];
576
+ case 22:
465
577
  connectionRecord = _e.sent();
466
578
  recordItem[fieldName] =
467
579
  connectionRecord &&
468
580
  this.modelInstanceCreator(modelConstructor_1, connectionRecord);
469
- delete recordItem[targetName];
470
- _e.label = 21;
471
- case 21: return [3 /*break*/, 18];
472
- case 22: return [3 /*break*/, 29];
581
+ targetNames === null || targetNames === void 0 ? void 0 : targetNames.map(function (targetName) {
582
+ delete recordItem[targetName];
583
+ });
584
+ return [3 /*break*/, 25];
473
585
  case 23:
474
- e_5_1 = _e.sent();
475
- e_5 = { error: e_5_1 };
476
- return [3 /*break*/, 29];
586
+ if (!recordItem[targetName]) return [3 /*break*/, 25];
587
+ key = [recordItem[targetName]];
588
+ return [4 /*yield*/, this._get(store, key)];
477
589
  case 24:
478
- _e.trys.push([24, , 27, 28]);
479
- if (!(records_2_1 && !records_2_1.done && (_c = records_2.return))) return [3 /*break*/, 26];
590
+ connectionRecord = _e.sent();
591
+ recordItem[fieldName] =
592
+ connectionRecord &&
593
+ this.modelInstanceCreator(modelConstructor_1, connectionRecord);
594
+ delete recordItem[targetName];
595
+ _e.label = 25;
596
+ case 25: return [3 /*break*/, 20];
597
+ case 26: return [3 /*break*/, 33];
598
+ case 27:
599
+ e_6_1 = _e.sent();
600
+ e_6 = { error: e_6_1 };
601
+ return [3 /*break*/, 33];
602
+ case 28:
603
+ _e.trys.push([28, , 31, 32]);
604
+ if (!(records_2_1 && !records_2_1.done && (_c = records_2.return))) return [3 /*break*/, 30];
480
605
  return [4 /*yield*/, _c.call(records_2)];
481
- case 25:
606
+ case 29:
482
607
  _e.sent();
483
- _e.label = 26;
484
- case 26: return [3 /*break*/, 28];
485
- case 27:
486
- if (e_5) throw e_5.error;
608
+ _e.label = 30;
609
+ case 30: return [3 /*break*/, 32];
610
+ case 31:
611
+ if (e_6) throw e_6.error;
487
612
  return [7 /*endfinally*/];
488
- case 28: return [7 /*endfinally*/];
489
- case 29: return [3 /*break*/, 32];
490
- case 30:
613
+ case 32: return [7 /*endfinally*/];
614
+ case 33: return [3 /*break*/, 36];
615
+ case 34:
491
616
  // TODO: Lazy loading
492
- return [3 /*break*/, 32];
493
- case 31:
494
- util_1.exhaustiveCheck(relation.relationType);
495
- return [3 /*break*/, 32];
496
- case 32: return [3 /*break*/, 2];
497
- case 33: return [3 /*break*/, 40];
498
- case 34:
499
- e_3_1 = _e.sent();
500
- e_3 = { error: e_3_1 };
501
- return [3 /*break*/, 40];
617
+ return [3 /*break*/, 36];
502
618
  case 35:
503
- _e.trys.push([35, , 38, 39]);
504
- if (!(relations_1_1 && !relations_1_1.done && (_a = relations_1.return))) return [3 /*break*/, 37];
619
+ util_1.exhaustiveCheck(relation.relationType);
620
+ return [3 /*break*/, 36];
621
+ case 36: return [3 /*break*/, 2];
622
+ case 37: return [3 /*break*/, 44];
623
+ case 38:
624
+ e_4_1 = _e.sent();
625
+ e_4 = { error: e_4_1 };
626
+ return [3 /*break*/, 44];
627
+ case 39:
628
+ _e.trys.push([39, , 42, 43]);
629
+ if (!(relations_1_1 && !relations_1_1.done && (_a = relations_1.return))) return [3 /*break*/, 41];
505
630
  return [4 /*yield*/, _a.call(relations_1)];
506
- case 36:
631
+ case 40:
507
632
  _e.sent();
508
- _e.label = 37;
509
- case 37: return [3 /*break*/, 39];
510
- case 38:
511
- if (e_3) throw e_3.error;
633
+ _e.label = 41;
634
+ case 41: return [3 /*break*/, 43];
635
+ case 42:
636
+ if (e_4) throw e_4.error;
512
637
  return [7 /*endfinally*/];
513
- case 39: return [7 /*endfinally*/];
514
- case 40: return [2 /*return*/, records.map(function (record) {
638
+ case 43: return [7 /*endfinally*/];
639
+ case 44: return [2 /*return*/, records.map(function (record) {
515
640
  return _this.modelInstanceCreator(modelConstructor, record);
516
641
  })];
517
642
  }
@@ -520,7 +645,7 @@ var IndexedDBAdapter = /** @class */ (function () {
520
645
  };
521
646
  IndexedDBAdapter.prototype.query = function (modelConstructor, predicate, pagination) {
522
647
  return __awaiter(this, void 0, void 0, function () {
523
- var storeName, namespaceName, predicates, queryById, hasSort, hasPagination, records;
648
+ var storeName, namespaceName, predicates, keyPath, queryByKey, hasSort, hasPagination, records;
524
649
  var _this = this;
525
650
  return __generator(this, function (_a) {
526
651
  switch (_a.label) {
@@ -530,7 +655,8 @@ var IndexedDBAdapter = /** @class */ (function () {
530
655
  storeName = this.getStorenameForModel(modelConstructor);
531
656
  namespaceName = this.namespaceResolver(modelConstructor);
532
657
  predicates = predicate && predicates_1.ModelPredicateCreator.getPredicates(predicate);
533
- queryById = predicates && this.idFromPredicate(predicates);
658
+ keyPath = this.getIndexKeyPath(namespaceName, modelConstructor.name);
659
+ queryByKey = predicates && this.keyValueFromPredicate(predicates, keyPath);
534
660
  hasSort = pagination && pagination.sort;
535
661
  hasPagination = pagination && pagination.limit;
536
662
  return [4 /*yield*/, (function () { return __awaiter(_this, void 0, void 0, function () {
@@ -538,8 +664,8 @@ var IndexedDBAdapter = /** @class */ (function () {
538
664
  return __generator(this, function (_a) {
539
665
  switch (_a.label) {
540
666
  case 0:
541
- if (!queryById) return [3 /*break*/, 2];
542
- return [4 /*yield*/, this.getById(storeName, queryById)];
667
+ if (!queryByKey) return [3 /*break*/, 2];
668
+ return [4 /*yield*/, this.getByKey(storeName, queryByKey)];
543
669
  case 1:
544
670
  record = _a.sent();
545
671
  return [2 /*return*/, record ? [record] : []];
@@ -571,12 +697,12 @@ var IndexedDBAdapter = /** @class */ (function () {
571
697
  });
572
698
  });
573
699
  };
574
- IndexedDBAdapter.prototype.getById = function (storeName, id) {
700
+ IndexedDBAdapter.prototype.getByKey = function (storeName, keyValue) {
575
701
  return __awaiter(this, void 0, void 0, function () {
576
702
  var record;
577
703
  return __generator(this, function (_a) {
578
704
  switch (_a.label) {
579
- case 0: return [4 /*yield*/, this._get(storeName, id)];
705
+ case 0: return [4 /*yield*/, this._get(storeName, keyValue)];
580
706
  case 1:
581
707
  record = _a.sent();
582
708
  return [2 /*return*/, record];
@@ -594,11 +720,31 @@ var IndexedDBAdapter = /** @class */ (function () {
594
720
  });
595
721
  });
596
722
  };
597
- IndexedDBAdapter.prototype.idFromPredicate = function (predicates) {
723
+ IndexedDBAdapter.prototype.keyValueFromPredicate = function (predicates, keyPath) {
724
+ var e_7, _a;
598
725
  var predicateObjs = predicates.predicates;
599
- var idPredicate = predicateObjs.length === 1 &&
600
- predicateObjs.find(function (p) { return types_1.isPredicateObj(p) && p.field === 'id' && p.operator === 'eq'; });
601
- return idPredicate && idPredicate.operand;
726
+ if (predicateObjs.length !== keyPath.length) {
727
+ return;
728
+ }
729
+ var keyValues = [];
730
+ var _loop_1 = function (key) {
731
+ var predicateObj = predicateObjs.find(function (p) { return types_1.isPredicateObj(p) && p.field === key && p.operator === 'eq'; });
732
+ predicateObj && keyValues.push(predicateObj.operand);
733
+ };
734
+ try {
735
+ for (var keyPath_2 = __values(keyPath), keyPath_2_1 = keyPath_2.next(); !keyPath_2_1.done; keyPath_2_1 = keyPath_2.next()) {
736
+ var key = keyPath_2_1.value;
737
+ _loop_1(key);
738
+ }
739
+ }
740
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
741
+ finally {
742
+ try {
743
+ if (keyPath_2_1 && !keyPath_2_1.done && (_a = keyPath_2.return)) _a.call(keyPath_2);
744
+ }
745
+ finally { if (e_7) throw e_7.error; }
746
+ }
747
+ return keyValues.length === keyPath.length ? keyValues : undefined;
602
748
  };
603
749
  IndexedDBAdapter.prototype.filterOnPredicate = function (storeName, predicates) {
604
750
  return __awaiter(this, void 0, void 0, function () {
@@ -704,7 +850,7 @@ var IndexedDBAdapter = /** @class */ (function () {
704
850
  };
705
851
  IndexedDBAdapter.prototype.delete = function (modelOrModelConstructor, condition) {
706
852
  return __awaiter(this, void 0, void 0, function () {
707
- var deleteQueue, modelConstructor, nameSpace, storeName, models, relations, deletedModels, deletedModels, model, modelConstructor, nameSpace, storeName, tx, store, fromDB, msg, predicates, predicateObjs, type, isValid, msg, relations, relations, deletedModels;
853
+ var deleteQueue, modelConstructor, nameSpace, storeName, models, relations, deletedModels, deletedModels, model, modelConstructor, namespaceName, storeName, tx, store, keyValues, fromDB, msg, predicates, predicateObjs, type, isValid, msg, relations, relations, deletedModels;
708
854
  return __generator(this, function (_a) {
709
855
  switch (_a.label) {
710
856
  case 0: return [4 /*yield*/, this.checkPrivate()];
@@ -753,12 +899,13 @@ var IndexedDBAdapter = /** @class */ (function () {
753
899
  model = modelOrModelConstructor;
754
900
  modelConstructor = Object.getPrototypeOf(model)
755
901
  .constructor;
756
- nameSpace = this.namespaceResolver(modelConstructor);
902
+ namespaceName = this.namespaceResolver(modelConstructor);
757
903
  storeName = this.getStorenameForModel(modelConstructor);
758
904
  if (!condition) return [3 /*break*/, 13];
759
905
  tx = this.db.transaction([storeName], 'readwrite');
760
906
  store = tx.objectStore(storeName);
761
- return [4 /*yield*/, this._get(store, model.id)];
907
+ keyValues = this.getIndexKeyValues(model);
908
+ return [4 /*yield*/, this._get(store, keyValues)];
762
909
  case 10:
763
910
  fromDB = _a.sent();
764
911
  if (fromDB === undefined) {
@@ -777,16 +924,14 @@ var IndexedDBAdapter = /** @class */ (function () {
777
924
  return [4 /*yield*/, tx.done];
778
925
  case 11:
779
926
  _a.sent();
780
- relations = this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
781
- .relationTypes;
782
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, nameSpace, deleteQueue)];
927
+ relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
928
+ return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
783
929
  case 12:
784
930
  _a.sent();
785
931
  return [3 /*break*/, 15];
786
932
  case 13:
787
- relations = this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
788
- .relationTypes;
789
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, nameSpace, deleteQueue)];
933
+ relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
934
+ return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
790
935
  case 14:
791
936
  _a.sent();
792
937
  _a.label = 15;
@@ -805,9 +950,9 @@ var IndexedDBAdapter = /** @class */ (function () {
805
950
  };
806
951
  IndexedDBAdapter.prototype.deleteItem = function (deleteQueue) {
807
952
  var deleteQueue_1, deleteQueue_1_1;
808
- var e_6, _a, e_7, _b;
953
+ var e_8, _a, e_9, _b;
809
954
  return __awaiter(this, void 0, void 0, function () {
810
- var connectionStoreNames, tx, deleteItem, storeName, items, store, items_1, items_1_1, item, key, e_7_1, e_6_1;
955
+ var connectionStoreNames, tx, deleteItem, storeName, items, store, items_1, items_1_1, item, key, keyValues, itemKey, e_9_1, e_8_1;
811
956
  return __generator(this, function (_c) {
812
957
  switch (_c.label) {
813
958
  case 0:
@@ -839,11 +984,14 @@ var IndexedDBAdapter = /** @class */ (function () {
839
984
  if (!item) return [3 /*break*/, 12];
840
985
  key = void 0;
841
986
  if (!(typeof item === 'object')) return [3 /*break*/, 8];
842
- return [4 /*yield*/, store.index('byId').getKey(item['id'])];
987
+ keyValues = this.getIndexKeyValues(item);
988
+ return [4 /*yield*/, store.index('byPk').getKey(keyValues)];
843
989
  case 7:
844
990
  key = _c.sent();
845
991
  return [3 /*break*/, 10];
846
- case 8: return [4 /*yield*/, store.index('byId').getKey(item.toString())];
992
+ case 8:
993
+ itemKey = [item.toString()];
994
+ return [4 /*yield*/, store.index('byPk').getKey([itemKey])];
847
995
  case 9:
848
996
  key = _c.sent();
849
997
  _c.label = 10;
@@ -856,8 +1004,8 @@ var IndexedDBAdapter = /** @class */ (function () {
856
1004
  case 12: return [3 /*break*/, 5];
857
1005
  case 13: return [3 /*break*/, 20];
858
1006
  case 14:
859
- e_7_1 = _c.sent();
860
- e_7 = { error: e_7_1 };
1007
+ e_9_1 = _c.sent();
1008
+ e_9 = { error: e_9_1 };
861
1009
  return [3 /*break*/, 20];
862
1010
  case 15:
863
1011
  _c.trys.push([15, , 18, 19]);
@@ -868,14 +1016,14 @@ var IndexedDBAdapter = /** @class */ (function () {
868
1016
  _c.label = 17;
869
1017
  case 17: return [3 /*break*/, 19];
870
1018
  case 18:
871
- if (e_7) throw e_7.error;
1019
+ if (e_9) throw e_9.error;
872
1020
  return [7 /*endfinally*/];
873
1021
  case 19: return [7 /*endfinally*/];
874
1022
  case 20: return [3 /*break*/, 2];
875
1023
  case 21: return [3 /*break*/, 28];
876
1024
  case 22:
877
- e_6_1 = _c.sent();
878
- e_6 = { error: e_6_1 };
1025
+ e_8_1 = _c.sent();
1026
+ e_8 = { error: e_8_1 };
879
1027
  return [3 /*break*/, 28];
880
1028
  case 23:
881
1029
  _c.trys.push([23, , 26, 27]);
@@ -886,7 +1034,7 @@ var IndexedDBAdapter = /** @class */ (function () {
886
1034
  _c.label = 25;
887
1035
  case 25: return [3 /*break*/, 27];
888
1036
  case 26:
889
- if (e_6) throw e_6.error;
1037
+ if (e_8) throw e_8.error;
890
1038
  return [7 /*endfinally*/];
891
1039
  case 27: return [7 /*endfinally*/];
892
1040
  case 28: return [2 /*return*/];
@@ -896,21 +1044,21 @@ var IndexedDBAdapter = /** @class */ (function () {
896
1044
  };
897
1045
  IndexedDBAdapter.prototype.deleteTraverse = function (relations, models, srcModel, nameSpace, deleteQueue) {
898
1046
  var relations_2, relations_2_1, models_1, models_1_1, models_2, models_2_1;
899
- var e_8, _a, e_9, _b, e_10, _c;
1047
+ var e_10, _a, e_11, _b, e_12, _c;
900
1048
  return __awaiter(this, void 0, void 0, function () {
901
- var rel, relationType, fieldName, modelName, targetName, storeName, index, _d, model, hasOneIndex, hasOneCustomField, value, recordToDelete, e_9_1, model, childrenArray, e_10_1, e_8_1;
1049
+ var rel, relationType, fieldName, modelName, targetName, targetNames, storeName, index, _d, model, hasOneIndex, hasConnectedModelFields, keyValues, values, recordToDelete, hasOneIndex_1, hasOneCustomField, keyValues, value, recordToDelete, e_11_1, model, keyValues, childrenArray, e_12_1, e_10_1;
902
1050
  var _this = this;
903
1051
  return __generator(this, function (_e) {
904
1052
  switch (_e.label) {
905
1053
  case 0:
906
- _e.trys.push([0, 35, 36, 41]);
1054
+ _e.trys.push([0, 38, 39, 44]);
907
1055
  relations_2 = __asyncValues(relations);
908
1056
  _e.label = 1;
909
1057
  case 1: return [4 /*yield*/, relations_2.next()];
910
1058
  case 2:
911
- if (!(relations_2_1 = _e.sent(), !relations_2_1.done)) return [3 /*break*/, 34];
1059
+ if (!(relations_2_1 = _e.sent(), !relations_2_1.done)) return [3 /*break*/, 37];
912
1060
  rel = relations_2_1.value;
913
- relationType = rel.relationType, fieldName = rel.fieldName, modelName = rel.modelName, targetName = rel.targetName;
1061
+ relationType = rel.relationType, fieldName = rel.fieldName, modelName = rel.modelName, targetName = rel.targetName, targetNames = rel.targetNames;
914
1062
  storeName = this.getStorename(nameSpace, modelName);
915
1063
  index = util_1.getIndex(this.schema.namespaces[nameSpace].relationships[modelName]
916
1064
  .relationTypes, srcModel) ||
@@ -921,118 +1069,150 @@ var IndexedDBAdapter = /** @class */ (function () {
921
1069
  _d = relationType;
922
1070
  switch (_d) {
923
1071
  case 'HAS_ONE': return [3 /*break*/, 3];
924
- case 'HAS_MANY': return [3 /*break*/, 17];
925
- case 'BELONGS_TO': return [3 /*break*/, 31];
1072
+ case 'HAS_MANY': return [3 /*break*/, 20];
1073
+ case 'BELONGS_TO': return [3 /*break*/, 34];
926
1074
  }
927
- return [3 /*break*/, 32];
1075
+ return [3 /*break*/, 35];
928
1076
  case 3:
929
- _e.trys.push([3, 10, 11, 16]);
1077
+ _e.trys.push([3, 13, 14, 19]);
930
1078
  models_1 = __asyncValues(models);
931
1079
  _e.label = 4;
932
1080
  case 4: return [4 /*yield*/, models_1.next()];
933
1081
  case 5:
934
- if (!(models_1_1 = _e.sent(), !models_1_1.done)) return [3 /*break*/, 9];
1082
+ if (!(models_1_1 = _e.sent(), !models_1_1.done)) return [3 /*break*/, 12];
935
1083
  model = models_1_1.value;
936
- hasOneIndex = index || 'byId';
937
- hasOneCustomField = targetName in model;
938
- value = hasOneCustomField ? model[targetName] : model.id;
939
- if (!value)
940
- return [3 /*break*/, 9];
1084
+ hasOneIndex = index || 'byPk';
1085
+ if (!(targetNames && targetNames.length > 0)) return [3 /*break*/, 8];
1086
+ hasConnectedModelFields = targetNames.every(function (targetName) {
1087
+ return model.hasOwnProperty(targetName);
1088
+ });
1089
+ keyValues = this.getIndexKeyValues(model);
1090
+ values = [];
1091
+ if (hasConnectedModelFields) {
1092
+ // Values will be that of the child model
1093
+ values = targetNames.map(function (targetName) { return model[targetName]; });
1094
+ }
1095
+ else {
1096
+ // values will be that of the parent model
1097
+ values = keyValues;
1098
+ }
1099
+ if (values.length === 0)
1100
+ return [3 /*break*/, 12];
941
1101
  return [4 /*yield*/, this.db
942
1102
  .transaction(storeName, 'readwrite')
943
1103
  .objectStore(storeName)
944
1104
  .index(hasOneIndex)
945
- .get(value)];
1105
+ .get(values)];
946
1106
  case 6:
947
- recordToDelete = (_e.sent());
1107
+ recordToDelete = _e.sent();
948
1108
  return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
949
1109
  .relationTypes, recordToDelete ? [recordToDelete] : [], modelName, nameSpace, deleteQueue)];
950
1110
  case 7:
951
1111
  _e.sent();
952
- _e.label = 8;
953
- case 8: return [3 /*break*/, 4];
954
- case 9: return [3 /*break*/, 16];
1112
+ return [3 /*break*/, 12];
1113
+ case 8:
1114
+ hasOneIndex_1 = index || 'byPk';
1115
+ hasOneCustomField = targetName in model;
1116
+ keyValues = this.getIndexKeyValues(model);
1117
+ value = hasOneCustomField ? [model[targetName]] : keyValues;
1118
+ if (!value)
1119
+ return [3 /*break*/, 12];
1120
+ return [4 /*yield*/, this.db
1121
+ .transaction(storeName, 'readwrite')
1122
+ .objectStore(storeName)
1123
+ .index(hasOneIndex_1)
1124
+ .get(value)];
1125
+ case 9:
1126
+ recordToDelete = _e.sent();
1127
+ return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1128
+ .relationTypes, recordToDelete ? [recordToDelete] : [], modelName, nameSpace, deleteQueue)];
955
1129
  case 10:
956
- e_9_1 = _e.sent();
957
- e_9 = { error: e_9_1 };
958
- return [3 /*break*/, 16];
959
- case 11:
960
- _e.trys.push([11, , 14, 15]);
961
- if (!(models_1_1 && !models_1_1.done && (_b = models_1.return))) return [3 /*break*/, 13];
962
- return [4 /*yield*/, _b.call(models_1)];
963
- case 12:
964
1130
  _e.sent();
965
- _e.label = 13;
966
- case 13: return [3 /*break*/, 15];
1131
+ _e.label = 11;
1132
+ case 11: return [3 /*break*/, 4];
1133
+ case 12: return [3 /*break*/, 19];
1134
+ case 13:
1135
+ e_11_1 = _e.sent();
1136
+ e_11 = { error: e_11_1 };
1137
+ return [3 /*break*/, 19];
967
1138
  case 14:
968
- if (e_9) throw e_9.error;
969
- return [7 /*endfinally*/];
970
- case 15: return [7 /*endfinally*/];
971
- case 16: return [3 /*break*/, 33];
1139
+ _e.trys.push([14, , 17, 18]);
1140
+ if (!(models_1_1 && !models_1_1.done && (_b = models_1.return))) return [3 /*break*/, 16];
1141
+ return [4 /*yield*/, _b.call(models_1)];
1142
+ case 15:
1143
+ _e.sent();
1144
+ _e.label = 16;
1145
+ case 16: return [3 /*break*/, 18];
972
1146
  case 17:
973
- _e.trys.push([17, 24, 25, 30]);
1147
+ if (e_11) throw e_11.error;
1148
+ return [7 /*endfinally*/];
1149
+ case 18: return [7 /*endfinally*/];
1150
+ case 19: return [3 /*break*/, 36];
1151
+ case 20:
1152
+ _e.trys.push([20, 27, 28, 33]);
974
1153
  models_2 = __asyncValues(models);
975
- _e.label = 18;
976
- case 18: return [4 /*yield*/, models_2.next()];
977
- case 19:
978
- if (!(models_2_1 = _e.sent(), !models_2_1.done)) return [3 /*break*/, 23];
1154
+ _e.label = 21;
1155
+ case 21: return [4 /*yield*/, models_2.next()];
1156
+ case 22:
1157
+ if (!(models_2_1 = _e.sent(), !models_2_1.done)) return [3 /*break*/, 26];
979
1158
  model = models_2_1.value;
1159
+ keyValues = this.getIndexKeyValues(model);
980
1160
  return [4 /*yield*/, this.db
981
1161
  .transaction(storeName, 'readwrite')
982
1162
  .objectStore(storeName)
983
1163
  .index(index)
984
- .getAll(model['id'])];
985
- case 20:
1164
+ .getAll(keyValues)];
1165
+ case 23:
986
1166
  childrenArray = _e.sent();
987
1167
  return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
988
1168
  .relationTypes, childrenArray, modelName, nameSpace, deleteQueue)];
989
- case 21:
990
- _e.sent();
991
- _e.label = 22;
992
- case 22: return [3 /*break*/, 18];
993
- case 23: return [3 /*break*/, 30];
994
1169
  case 24:
995
- e_10_1 = _e.sent();
996
- e_10 = { error: e_10_1 };
997
- return [3 /*break*/, 30];
998
- case 25:
999
- _e.trys.push([25, , 28, 29]);
1000
- if (!(models_2_1 && !models_2_1.done && (_c = models_2.return))) return [3 /*break*/, 27];
1001
- return [4 /*yield*/, _c.call(models_2)];
1002
- case 26:
1003
1170
  _e.sent();
1004
- _e.label = 27;
1005
- case 27: return [3 /*break*/, 29];
1171
+ _e.label = 25;
1172
+ case 25: return [3 /*break*/, 21];
1173
+ case 26: return [3 /*break*/, 33];
1174
+ case 27:
1175
+ e_12_1 = _e.sent();
1176
+ e_12 = { error: e_12_1 };
1177
+ return [3 /*break*/, 33];
1006
1178
  case 28:
1007
- if (e_10) throw e_10.error;
1179
+ _e.trys.push([28, , 31, 32]);
1180
+ if (!(models_2_1 && !models_2_1.done && (_c = models_2.return))) return [3 /*break*/, 30];
1181
+ return [4 /*yield*/, _c.call(models_2)];
1182
+ case 29:
1183
+ _e.sent();
1184
+ _e.label = 30;
1185
+ case 30: return [3 /*break*/, 32];
1186
+ case 31:
1187
+ if (e_12) throw e_12.error;
1008
1188
  return [7 /*endfinally*/];
1009
- case 29: return [7 /*endfinally*/];
1010
- case 30: return [3 /*break*/, 33];
1011
- case 31:
1189
+ case 32: return [7 /*endfinally*/];
1190
+ case 33: return [3 /*break*/, 36];
1191
+ case 34:
1012
1192
  // Intentionally blank
1013
- return [3 /*break*/, 33];
1014
- case 32:
1015
- util_1.exhaustiveCheck(relationType);
1016
- return [3 /*break*/, 33];
1017
- case 33: return [3 /*break*/, 1];
1018
- case 34: return [3 /*break*/, 41];
1193
+ return [3 /*break*/, 36];
1019
1194
  case 35:
1020
- e_8_1 = _e.sent();
1021
- e_8 = { error: e_8_1 };
1022
- return [3 /*break*/, 41];
1023
- case 36:
1024
- _e.trys.push([36, , 39, 40]);
1025
- if (!(relations_2_1 && !relations_2_1.done && (_a = relations_2.return))) return [3 /*break*/, 38];
1195
+ util_1.exhaustiveCheck(relationType);
1196
+ return [3 /*break*/, 36];
1197
+ case 36: return [3 /*break*/, 1];
1198
+ case 37: return [3 /*break*/, 44];
1199
+ case 38:
1200
+ e_10_1 = _e.sent();
1201
+ e_10 = { error: e_10_1 };
1202
+ return [3 /*break*/, 44];
1203
+ case 39:
1204
+ _e.trys.push([39, , 42, 43]);
1205
+ if (!(relations_2_1 && !relations_2_1.done && (_a = relations_2.return))) return [3 /*break*/, 41];
1026
1206
  return [4 /*yield*/, _a.call(relations_2)];
1027
- case 37:
1207
+ case 40:
1028
1208
  _e.sent();
1029
- _e.label = 38;
1030
- case 38: return [3 /*break*/, 40];
1031
- case 39:
1032
- if (e_8) throw e_8.error;
1209
+ _e.label = 41;
1210
+ case 41: return [3 /*break*/, 43];
1211
+ case 42:
1212
+ if (e_10) throw e_10.error;
1033
1213
  return [7 /*endfinally*/];
1034
- case 40: return [7 /*endfinally*/];
1035
- case 41:
1214
+ case 43: return [7 /*endfinally*/];
1215
+ case 44:
1036
1216
  deleteQueue.push({
1037
1217
  storeName: this.getStorename(nameSpace, srcModel),
1038
1218
  items: models.map(function (record) {
@@ -1064,8 +1244,9 @@ var IndexedDBAdapter = /** @class */ (function () {
1064
1244
  };
1065
1245
  IndexedDBAdapter.prototype.batchSave = function (modelConstructor, items) {
1066
1246
  return __awaiter(this, void 0, void 0, function () {
1067
- var result, storeName, txn, store, _loop_1, this_1, items_2, items_2_1, item, e_11_1;
1068
- var e_11, _a;
1247
+ var result, storeName, txn, store, _loop_2, this_1, items_2, items_2_1, item, e_13_1;
1248
+ var e_13, _a;
1249
+ var _this = this;
1069
1250
  return __generator(this, function (_b) {
1070
1251
  switch (_b.label) {
1071
1252
  case 0:
@@ -1079,21 +1260,26 @@ var IndexedDBAdapter = /** @class */ (function () {
1079
1260
  storeName = this.getStorenameForModel(modelConstructor);
1080
1261
  txn = this.db.transaction(storeName, 'readwrite');
1081
1262
  store = txn.store;
1082
- _loop_1 = function (item) {
1083
- var connectedModels, id, _deleted, index, key, instance;
1263
+ _loop_2 = function (item) {
1264
+ var namespaceName, modelName, model, connectedModels, keyValues, _deleted, index, key, instance;
1084
1265
  return __generator(this, function (_a) {
1085
1266
  switch (_a.label) {
1086
1267
  case 0:
1087
- connectedModels = util_1.traverseModel(modelConstructor.name, this_1.modelInstanceCreator(modelConstructor, item), this_1.schema.namespaces[this_1.namespaceResolver(modelConstructor)], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
1088
- id = item.id, _deleted = item._deleted;
1089
- index = store.index('byId');
1090
- return [4 /*yield*/, index.getKey(id)];
1268
+ namespaceName = this_1.namespaceResolver(modelConstructor);
1269
+ modelName = modelConstructor.name;
1270
+ model = this_1.modelInstanceCreator(modelConstructor, item);
1271
+ connectedModels = util_1.traverseModel(modelName, model, this_1.schema.namespaces[namespaceName], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
1272
+ keyValues = this_1.getIndexKeyValues(model);
1273
+ _deleted = item._deleted;
1274
+ index = store.index('byPk');
1275
+ return [4 /*yield*/, index.getKey(keyValues)];
1091
1276
  case 1:
1092
1277
  key = _a.sent();
1093
1278
  if (!!_deleted) return [3 /*break*/, 3];
1094
1279
  instance = connectedModels.find(function (_a) {
1095
1280
  var instance = _a.instance;
1096
- return instance.id === id;
1281
+ var instanceKeyValues = _this.getIndexKeyValues(instance);
1282
+ return _this.keysEqual(instanceKeyValues, keyValues);
1097
1283
  }).instance;
1098
1284
  result.push([
1099
1285
  instance,
@@ -1123,7 +1309,7 @@ var IndexedDBAdapter = /** @class */ (function () {
1123
1309
  case 3:
1124
1310
  if (!!items_2_1.done) return [3 /*break*/, 6];
1125
1311
  item = items_2_1.value;
1126
- return [5 /*yield**/, _loop_1(item)];
1312
+ return [5 /*yield**/, _loop_2(item)];
1127
1313
  case 4:
1128
1314
  _b.sent();
1129
1315
  _b.label = 5;
@@ -1132,14 +1318,14 @@ var IndexedDBAdapter = /** @class */ (function () {
1132
1318
  return [3 /*break*/, 3];
1133
1319
  case 6: return [3 /*break*/, 9];
1134
1320
  case 7:
1135
- e_11_1 = _b.sent();
1136
- e_11 = { error: e_11_1 };
1321
+ e_13_1 = _b.sent();
1322
+ e_13 = { error: e_13_1 };
1137
1323
  return [3 /*break*/, 9];
1138
1324
  case 8:
1139
1325
  try {
1140
1326
  if (items_2_1 && !items_2_1.done && (_a = items_2.return)) _a.call(items_2);
1141
1327
  }
1142
- finally { if (e_11) throw e_11.error; }
1328
+ finally { if (e_13) throw e_13.error; }
1143
1329
  return [7 /*endfinally*/];
1144
1330
  case 9: return [4 /*yield*/, txn.done];
1145
1331
  case 10:
@@ -1149,6 +1335,22 @@ var IndexedDBAdapter = /** @class */ (function () {
1149
1335
  });
1150
1336
  });
1151
1337
  };
1338
+ IndexedDBAdapter.prototype.createObjectStoreForModel = function (db, namespaceName, storeName, modelName) {
1339
+ return __awaiter(this, void 0, void 0, function () {
1340
+ var store, indexes;
1341
+ return __generator(this, function (_a) {
1342
+ store = db.createObjectStore(storeName, {
1343
+ autoIncrement: true,
1344
+ });
1345
+ indexes = this.schema.namespaces[namespaceName].relationships[modelName].indexes;
1346
+ indexes.forEach(function (_a) {
1347
+ var _b = __read(_a, 3), idxName = _b[0], keyPath = _b[1], options = _b[2];
1348
+ store.createIndex(idxName, keyPath, options);
1349
+ });
1350
+ return [2 /*return*/];
1351
+ });
1352
+ });
1353
+ };
1152
1354
  return IndexedDBAdapter;
1153
1355
  }());
1154
1356
  exports.default = new IndexedDBAdapter();