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