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

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