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