@aws-amplify/datastore 4.1.1 → 4.1.2

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 (26) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +52 -28
  3. package/lib/storage/adapter/AsyncStorageAdapter.js +212 -476
  4. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  5. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  6. package/lib/storage/adapter/IndexedDBAdapter.d.ts +53 -28
  7. package/lib/storage/adapter/IndexedDBAdapter.js +589 -892
  8. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  9. package/lib/storage/adapter/StorageAdapterBase.d.ts +146 -0
  10. package/lib/storage/adapter/StorageAdapterBase.js +479 -0
  11. package/lib/storage/adapter/StorageAdapterBase.js.map +1 -0
  12. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +52 -28
  13. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +215 -479
  14. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  15. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  16. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +53 -28
  17. package/lib-esm/storage/adapter/IndexedDBAdapter.js +588 -891
  18. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  19. package/lib-esm/storage/adapter/StorageAdapterBase.d.ts +146 -0
  20. package/lib-esm/storage/adapter/StorageAdapterBase.js +477 -0
  21. package/lib-esm/storage/adapter/StorageAdapterBase.js.map +1 -0
  22. package/package.json +6 -6
  23. package/src/storage/adapter/AsyncStorageAdapter.ts +239 -543
  24. package/src/storage/adapter/AsyncStorageDatabase.ts +2 -2
  25. package/src/storage/adapter/IndexedDBAdapter.ts +423 -786
  26. package/src/storage/adapter/StorageAdapterBase.ts +639 -0
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var tslib_1 = require("tslib");
4
4
  var core_1 = require("@aws-amplify/core");
5
5
  var idb = tslib_1.__importStar(require("idb"));
6
- var predicates_1 = require("../../predicates");
7
6
  var types_1 = require("../../types");
8
7
  var util_1 = require("../../util");
8
+ var StorageAdapterBase_1 = require("./StorageAdapterBase");
9
9
  var logger = new core_1.ConsoleLogger('DataStore');
10
10
  /**
11
11
  * The point after which queries composed of multiple simple OR conditions
@@ -29,12 +29,13 @@ var logger = new core_1.ConsoleLogger('DataStore');
29
29
  *
30
30
  */
31
31
  var MULTI_OR_CONDITION_SCAN_BREAKPOINT = 7;
32
- var DB_NAME = 'amplify-datastore';
33
- var IndexedDBAdapter = /** @class */ (function () {
32
+ //
33
+ var DB_VERSION = 3;
34
+ var IndexedDBAdapter = /** @class */ (function (_super) {
35
+ tslib_1.__extends(IndexedDBAdapter, _super);
34
36
  function IndexedDBAdapter() {
35
- var _this = this;
36
- this.dbName = DB_NAME;
37
- this.safariCompatabilityMode = false;
37
+ var _this = _super !== null && _super.apply(this, arguments) || this;
38
+ _this.safariCompatabilityMode = false;
38
39
  /**
39
40
  * Checks the given path against the browser's IndexedDB implementation for
40
41
  * necessary compatibility transformations, applying those transforms if needed.
@@ -43,241 +44,168 @@ var IndexedDBAdapter = /** @class */ (function () {
43
44
  * @returns An array or string, depending on and given key,
44
45
  * that is ensured to be compatible with the IndexedDB implementation's nuances.
45
46
  */
46
- this.canonicalKeyPath = function (keyArr) {
47
+ _this.canonicalKeyPath = function (keyArr) {
47
48
  if (_this.safariCompatabilityMode) {
48
49
  return keyArr.length > 1 ? keyArr : keyArr[0];
49
50
  }
50
51
  return keyArr;
51
52
  };
53
+ return _this;
54
+ //#endregion
52
55
  }
53
- IndexedDBAdapter.prototype.getStorenameForModel = function (modelConstructor) {
54
- var namespace = this.namespaceResolver(modelConstructor);
55
- var modelName = modelConstructor.name;
56
- return util_1.getStorename(namespace, modelName);
57
- };
58
- // Retrieves primary key values from a model
59
- IndexedDBAdapter.prototype.getIndexKeyValuesFromModel = function (model) {
60
- var modelConstructor = Object.getPrototypeOf(model)
61
- .constructor;
62
- var namespaceName = this.namespaceResolver(modelConstructor);
63
- var keys = util_1.getIndexKeys(this.schema.namespaces[namespaceName], modelConstructor.name);
64
- return util_1.extractPrimaryKeyValues(model, keys);
65
- };
66
- IndexedDBAdapter.prototype.checkPrivate = function () {
56
+ // checks are called by StorageAdapterBase class
57
+ IndexedDBAdapter.prototype.preSetUpChecks = function () {
67
58
  return tslib_1.__awaiter(this, void 0, void 0, function () {
68
- var isPrivate;
69
59
  return tslib_1.__generator(this, function (_a) {
70
60
  switch (_a.label) {
71
- case 0: return [4 /*yield*/, util_1.isPrivateMode().then(function (isPrivate) {
72
- return isPrivate;
73
- })];
61
+ case 0: return [4 /*yield*/, this.checkPrivate()];
74
62
  case 1:
75
- isPrivate = _a.sent();
76
- if (isPrivate) {
77
- logger.error("IndexedDB not supported in this browser's private mode");
78
- return [2 /*return*/, Promise.reject("IndexedDB not supported in this browser's private mode")];
79
- }
80
- else {
81
- return [2 /*return*/, Promise.resolve()];
82
- }
63
+ _a.sent();
64
+ return [4 /*yield*/, this.setSafariCompatabilityMode()];
65
+ case 2:
66
+ _a.sent();
83
67
  return [2 /*return*/];
84
68
  }
85
69
  });
86
70
  });
87
71
  };
88
- /**
89
- * Whether the browser's implementation of IndexedDB is coercing single-field
90
- * indexes to a scalar key.
91
- *
92
- * If this returns `true`, we need to treat indexes containing a single field
93
- * as scalars.
94
- *
95
- * See PR description for reference:
96
- * https://github.com/aws-amplify/amplify-js/pull/10527
97
- */
98
- IndexedDBAdapter.prototype.setSafariCompatabilityMode = function () {
72
+ IndexedDBAdapter.prototype.preOpCheck = function () {
99
73
  return tslib_1.__awaiter(this, void 0, void 0, function () {
100
- var _a;
101
- return tslib_1.__generator(this, function (_b) {
102
- switch (_b.label) {
103
- case 0:
104
- _a = this;
105
- return [4 /*yield*/, util_1.isSafariCompatabilityMode()];
74
+ return tslib_1.__generator(this, function (_a) {
75
+ switch (_a.label) {
76
+ case 0: return [4 /*yield*/, this.checkPrivate()];
106
77
  case 1:
107
- _a.safariCompatabilityMode = _b.sent();
108
- if (this.safariCompatabilityMode === true) {
109
- logger.debug('IndexedDB Adapter is running in Safari Compatability Mode');
110
- }
78
+ _a.sent();
111
79
  return [2 /*return*/];
112
80
  }
113
81
  });
114
82
  });
115
83
  };
116
- IndexedDBAdapter.prototype.getNamespaceAndModelFromStorename = function (storeName) {
117
- var _a = tslib_1.__read(storeName.split('_')), namespaceName = _a[0], modelNameArr = _a.slice(1);
118
- return {
119
- namespaceName: namespaceName,
120
- modelName: modelNameArr.join('_'),
121
- };
122
- };
123
- IndexedDBAdapter.prototype.setUp = function (theSchema, namespaceResolver, modelInstanceCreator, getModelConstructorByModelName, sessionId) {
84
+ /**
85
+ * Initialize IndexedDB database
86
+ * Create new DB if one doesn't exist
87
+ * Upgrade outdated DB
88
+ *
89
+ * Called by `StorageAdapterBase.setUp()`
90
+ *
91
+ * @returns IDB Database instance
92
+ */
93
+ IndexedDBAdapter.prototype.initDb = function () {
124
94
  return tslib_1.__awaiter(this, void 0, void 0, function () {
125
- var VERSION, _a, error_1;
126
95
  var _this = this;
127
- return tslib_1.__generator(this, function (_b) {
128
- switch (_b.label) {
129
- case 0: return [4 /*yield*/, this.checkPrivate()];
130
- case 1:
131
- _b.sent();
132
- return [4 /*yield*/, this.setSafariCompatabilityMode()];
133
- case 2:
134
- _b.sent();
135
- if (!!this.initPromise) return [3 /*break*/, 3];
136
- this.initPromise = new Promise(function (res, rej) {
137
- _this.resolve = res;
138
- _this.reject = rej;
139
- });
140
- return [3 /*break*/, 5];
141
- case 3: return [4 /*yield*/, this.initPromise];
142
- case 4:
143
- _b.sent();
144
- _b.label = 5;
145
- case 5:
146
- if (sessionId) {
147
- this.dbName = DB_NAME + "-" + sessionId;
148
- }
149
- this.schema = theSchema;
150
- this.namespaceResolver = namespaceResolver;
151
- this.modelInstanceCreator = modelInstanceCreator;
152
- this.getModelConstructorByModelName = getModelConstructorByModelName;
153
- _b.label = 6;
154
- case 6:
155
- _b.trys.push([6, 9, , 10]);
156
- if (!!this.db) return [3 /*break*/, 8];
157
- VERSION = 3;
158
- _a = this;
159
- return [4 /*yield*/, idb.openDB(this.dbName, VERSION, {
160
- upgrade: function (db, oldVersion, newVersion, txn) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
161
- var _a, _b, storeName, origStore, tmpName, _c, namespaceName, modelName, modelInCurrentSchema, newStore, cursor, count, e_1_1, error_2;
162
- var e_1, _d;
163
- var _this = this;
164
- return tslib_1.__generator(this, function (_e) {
165
- switch (_e.label) {
166
- case 0:
167
- if (oldVersion === 0) {
168
- Object.keys(theSchema.namespaces).forEach(function (namespaceName) {
169
- var namespace = theSchema.namespaces[namespaceName];
170
- Object.keys(namespace.models).forEach(function (modelName) {
171
- var storeName = util_1.getStorename(namespaceName, modelName);
172
- _this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
173
- });
96
+ return tslib_1.__generator(this, function (_a) {
97
+ switch (_a.label) {
98
+ case 0: return [4 /*yield*/, idb.openDB(this.dbName, DB_VERSION, {
99
+ upgrade: function (db, oldVersion, newVersion, txn) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
100
+ var _a, _b, storeName, origStore, tmpName, _c, namespaceName, modelName, modelInCurrentSchema, newStore, cursor, count, e_1_1, error_1;
101
+ var e_1, _d;
102
+ var _this = this;
103
+ return tslib_1.__generator(this, function (_e) {
104
+ switch (_e.label) {
105
+ case 0:
106
+ // create new database
107
+ if (oldVersion === 0) {
108
+ Object.keys(this.schema.namespaces).forEach(function (namespaceName) {
109
+ var namespace = _this.schema.namespaces[namespaceName];
110
+ Object.keys(namespace.models).forEach(function (modelName) {
111
+ var storeName = util_1.getStorename(namespaceName, modelName);
112
+ _this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
174
113
  });
175
- return [2 /*return*/];
176
- }
177
- if (!((oldVersion === 1 || oldVersion === 2) && newVersion === 3)) return [3 /*break*/, 16];
178
- _e.label = 1;
179
- case 1:
180
- _e.trys.push([1, 14, , 15]);
181
- _e.label = 2;
182
- case 2:
183
- _e.trys.push([2, 11, 12, 13]);
184
- _a = tslib_1.__values(txn.objectStoreNames), _b = _a.next();
185
- _e.label = 3;
186
- case 3:
187
- if (!!_b.done) return [3 /*break*/, 10];
188
- storeName = _b.value;
189
- origStore = txn.objectStore(storeName);
190
- tmpName = "tmp_" + storeName;
191
- origStore.name = tmpName;
192
- _c = this.getNamespaceAndModelFromStorename(storeName), namespaceName = _c.namespaceName, modelName = _c.modelName;
193
- modelInCurrentSchema = modelName in this.schema.namespaces[namespaceName].models;
194
- if (!modelInCurrentSchema) {
195
- // delete original
196
- db.deleteObjectStore(tmpName);
197
- return [3 /*break*/, 9];
198
- }
199
- newStore = this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
200
- return [4 /*yield*/, origStore.openCursor()];
201
- case 4:
202
- cursor = _e.sent();
203
- count = 0;
204
- _e.label = 5;
205
- case 5:
206
- if (!(cursor && cursor.value)) return [3 /*break*/, 8];
207
- // we don't pass key, since they are all new entries in the new store
208
- return [4 /*yield*/, newStore.put(cursor.value)];
209
- case 6:
210
- // we don't pass key, since they are all new entries in the new store
211
- _e.sent();
212
- return [4 /*yield*/, cursor.continue()];
213
- case 7:
214
- cursor = _e.sent();
215
- count++;
216
- return [3 /*break*/, 5];
217
- case 8:
114
+ });
115
+ return [2 /*return*/];
116
+ }
117
+ if (!((oldVersion === 1 || oldVersion === 2) && newVersion === 3)) return [3 /*break*/, 16];
118
+ _e.label = 1;
119
+ case 1:
120
+ _e.trys.push([1, 14, , 15]);
121
+ _e.label = 2;
122
+ case 2:
123
+ _e.trys.push([2, 11, 12, 13]);
124
+ _a = tslib_1.__values(txn.objectStoreNames), _b = _a.next();
125
+ _e.label = 3;
126
+ case 3:
127
+ if (!!_b.done) return [3 /*break*/, 10];
128
+ storeName = _b.value;
129
+ origStore = txn.objectStore(storeName);
130
+ tmpName = "tmp_" + storeName;
131
+ origStore.name = tmpName;
132
+ _c = this.getNamespaceAndModelFromStorename(storeName), namespaceName = _c.namespaceName, modelName = _c.modelName;
133
+ modelInCurrentSchema = modelName in this.schema.namespaces[namespaceName].models;
134
+ if (!modelInCurrentSchema) {
218
135
  // delete original
219
136
  db.deleteObjectStore(tmpName);
220
- logger.debug(count + " " + storeName + " records migrated");
221
- _e.label = 9;
222
- case 9:
223
- _b = _a.next();
224
- return [3 /*break*/, 3];
225
- case 10: return [3 /*break*/, 13];
226
- case 11:
227
- e_1_1 = _e.sent();
228
- e_1 = { error: e_1_1 };
229
- return [3 /*break*/, 13];
230
- case 12:
231
- try {
232
- if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
233
- }
234
- finally { if (e_1) throw e_1.error; }
235
- return [7 /*endfinally*/];
236
- case 13:
237
- // add new models created after IndexedDB, but before migration
238
- // this case may happen when a user has not opened an app for
239
- // some time and a new model is added during that time
240
- Object.keys(theSchema.namespaces).forEach(function (namespaceName) {
241
- var namespace = theSchema.namespaces[namespaceName];
242
- var objectStoreNames = new Set(txn.objectStoreNames);
243
- Object.keys(namespace.models)
244
- .map(function (modelName) {
245
- return [
246
- modelName,
247
- util_1.getStorename(namespaceName, modelName),
248
- ];
249
- })
250
- .filter(function (_a) {
251
- var _b = tslib_1.__read(_a, 2), storeName = _b[1];
252
- return !objectStoreNames.has(storeName);
253
- })
254
- .forEach(function (_a) {
255
- var _b = tslib_1.__read(_a, 2), modelName = _b[0], storeName = _b[1];
256
- _this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
257
- });
137
+ return [3 /*break*/, 9];
138
+ }
139
+ newStore = this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
140
+ return [4 /*yield*/, origStore.openCursor()];
141
+ case 4:
142
+ cursor = _e.sent();
143
+ count = 0;
144
+ _e.label = 5;
145
+ case 5:
146
+ if (!(cursor && cursor.value)) return [3 /*break*/, 8];
147
+ // we don't pass key, since they are all new entries in the new store
148
+ return [4 /*yield*/, newStore.put(cursor.value)];
149
+ case 6:
150
+ // we don't pass key, since they are all new entries in the new store
151
+ _e.sent();
152
+ return [4 /*yield*/, cursor.continue()];
153
+ case 7:
154
+ cursor = _e.sent();
155
+ count++;
156
+ return [3 /*break*/, 5];
157
+ case 8:
158
+ // delete original
159
+ db.deleteObjectStore(tmpName);
160
+ logger.debug(count + " " + storeName + " records migrated");
161
+ _e.label = 9;
162
+ case 9:
163
+ _b = _a.next();
164
+ return [3 /*break*/, 3];
165
+ case 10: return [3 /*break*/, 13];
166
+ case 11:
167
+ e_1_1 = _e.sent();
168
+ e_1 = { error: e_1_1 };
169
+ return [3 /*break*/, 13];
170
+ case 12:
171
+ try {
172
+ if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
173
+ }
174
+ finally { if (e_1) throw e_1.error; }
175
+ return [7 /*endfinally*/];
176
+ case 13:
177
+ // add new models created after IndexedDB, but before migration
178
+ // this case may happen when a user has not opened an app for
179
+ // some time and a new model is added during that time
180
+ Object.keys(this.schema.namespaces).forEach(function (namespaceName) {
181
+ var namespace = _this.schema.namespaces[namespaceName];
182
+ var objectStoreNames = new Set(txn.objectStoreNames);
183
+ Object.keys(namespace.models)
184
+ .map(function (modelName) {
185
+ return [modelName, util_1.getStorename(namespaceName, modelName)];
186
+ })
187
+ .filter(function (_a) {
188
+ var _b = tslib_1.__read(_a, 2), storeName = _b[1];
189
+ return !objectStoreNames.has(storeName);
190
+ })
191
+ .forEach(function (_a) {
192
+ var _b = tslib_1.__read(_a, 2), modelName = _b[0], storeName = _b[1];
193
+ _this.createObjectStoreForModel(db, namespaceName, storeName, modelName);
258
194
  });
259
- return [3 /*break*/, 15];
260
- case 14:
261
- error_2 = _e.sent();
262
- logger.error('Error migrating IndexedDB data', error_2);
263
- txn.abort();
264
- throw error_2;
265
- case 15: return [2 /*return*/];
266
- case 16: return [2 /*return*/];
267
- }
268
- });
269
- }); },
270
- })];
271
- case 7:
272
- _a.db = _b.sent();
273
- this.resolve();
274
- _b.label = 8;
275
- case 8: return [3 /*break*/, 10];
276
- case 9:
277
- error_1 = _b.sent();
278
- this.reject(error_1);
279
- return [3 /*break*/, 10];
280
- case 10: return [2 /*return*/];
195
+ });
196
+ return [3 /*break*/, 15];
197
+ case 14:
198
+ error_1 = _e.sent();
199
+ logger.error('Error migrating IndexedDB data', error_1);
200
+ txn.abort();
201
+ throw error_1;
202
+ case 15: return [2 /*return*/];
203
+ case 16: return [2 /*return*/];
204
+ }
205
+ });
206
+ }); },
207
+ })];
208
+ case 1: return [2 /*return*/, _a.sent()];
281
209
  }
282
210
  });
283
211
  });
@@ -304,45 +232,41 @@ var IndexedDBAdapter = /** @class */ (function () {
304
232
  });
305
233
  });
306
234
  };
235
+ IndexedDBAdapter.prototype.clear = function () {
236
+ var _a;
237
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
238
+ return tslib_1.__generator(this, function (_b) {
239
+ switch (_b.label) {
240
+ case 0: return [4 /*yield*/, this.checkPrivate()];
241
+ case 1:
242
+ _b.sent();
243
+ (_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
244
+ return [4 /*yield*/, idb.deleteDB(this.dbName)];
245
+ case 2:
246
+ _b.sent();
247
+ this.db = undefined;
248
+ this.initPromise = undefined;
249
+ return [2 /*return*/];
250
+ }
251
+ });
252
+ });
253
+ };
307
254
  IndexedDBAdapter.prototype.save = function (model, condition) {
308
255
  var e_2, _a;
309
256
  return tslib_1.__awaiter(this, void 0, void 0, function () {
310
- var modelConstructor, storeName, namespaceName, connectedModels, set, connectionStoreNames, tx, store, keyValues, fromDB, predicates, _b, predicateObjs, type, isValid, msg, result, connectionStoreNames_1, connectionStoreNames_1_1, resItem, storeName_1, item, instance, keys, store_1, itemKeyValues, fromDB_1, opType, modelKeyValues, key, e_2_1;
311
- var _this = this;
257
+ var _b, storeName, set, connectionStoreNames, modelKeyValues, tx, store, fromDB, result, connectionStoreNames_1, connectionStoreNames_1_1, resItem, storeName_1, item, instance, keys, store_1, itemKeyValues, fromDB_1, opType, key, e_2_1;
312
258
  return tslib_1.__generator(this, function (_c) {
313
259
  switch (_c.label) {
314
260
  case 0: return [4 /*yield*/, this.checkPrivate()];
315
261
  case 1:
316
262
  _c.sent();
317
- modelConstructor = Object.getPrototypeOf(model)
318
- .constructor;
319
- storeName = this.getStorenameForModel(modelConstructor);
320
- namespaceName = this.namespaceResolver(modelConstructor);
321
- connectedModels = util_1.traverseModel(modelConstructor.name, model, this.schema.namespaces[namespaceName], this.modelInstanceCreator, this.getModelConstructorByModelName);
322
- set = new Set();
323
- connectionStoreNames = Object.values(connectedModels).map(function (_a) {
324
- var modelName = _a.modelName, item = _a.item, instance = _a.instance;
325
- var storeName = util_1.getStorename(namespaceName, modelName);
326
- set.add(storeName);
327
- var keys = util_1.getIndexKeys(_this.schema.namespaces[namespaceName], modelName);
328
- return { storeName: storeName, item: item, instance: instance, keys: keys };
329
- });
263
+ _b = this.saveMetadata(model), storeName = _b.storeName, set = _b.set, connectionStoreNames = _b.connectionStoreNames, modelKeyValues = _b.modelKeyValues;
330
264
  tx = this.db.transaction(tslib_1.__spread([storeName], Array.from(set.values())), 'readwrite');
331
265
  store = tx.objectStore(storeName);
332
- keyValues = this.getIndexKeyValuesFromModel(model);
333
- return [4 /*yield*/, this._get(store, keyValues)];
266
+ return [4 /*yield*/, this._get(store, modelKeyValues)];
334
267
  case 2:
335
268
  fromDB = _c.sent();
336
- if (condition && fromDB) {
337
- predicates = predicates_1.ModelPredicateCreator.getPredicates(condition);
338
- _b = predicates || {}, predicateObjs = _b.predicates, type = _b.type;
339
- isValid = util_1.validatePredicate(fromDB, type, predicateObjs);
340
- if (!isValid) {
341
- msg = 'Conditional update failed';
342
- logger.error(msg, { model: fromDB, condition: predicateObjs });
343
- throw new Error(msg);
344
- }
345
- }
269
+ this.validateSaveCondition(condition, fromDB);
346
270
  result = [];
347
271
  _c.label = 3;
348
272
  case 3:
@@ -355,15 +279,11 @@ var IndexedDBAdapter = /** @class */ (function () {
355
279
  resItem = connectionStoreNames_1_1.value;
356
280
  storeName_1 = resItem.storeName, item = resItem.item, instance = resItem.instance, keys = resItem.keys;
357
281
  store_1 = tx.objectStore(storeName_1);
358
- itemKeyValues = keys.map(function (key) {
359
- var value = item[key];
360
- return value;
361
- });
282
+ itemKeyValues = keys.map(function (key) { return item[key]; });
362
283
  return [4 /*yield*/, this._get(store_1, itemKeyValues)];
363
284
  case 6:
364
285
  fromDB_1 = _c.sent();
365
- opType = fromDB_1 === undefined ? types_1.OpType.INSERT : types_1.OpType.UPDATE;
366
- modelKeyValues = this.getIndexKeyValuesFromModel(model);
286
+ opType = fromDB_1 ? types_1.OpType.UPDATE : types_1.OpType.INSERT;
367
287
  if (!(util_1.keysEqual(itemKeyValues, modelKeyValues) ||
368
288
  opType === types_1.OpType.INSERT)) return [3 /*break*/, 9];
369
289
  return [4 /*yield*/, store_1
@@ -402,45 +322,16 @@ var IndexedDBAdapter = /** @class */ (function () {
402
322
  });
403
323
  });
404
324
  };
405
- IndexedDBAdapter.prototype.load = function (namespaceName, srcModelName, records) {
406
- return tslib_1.__awaiter(this, void 0, void 0, function () {
407
- var namespace, relations, connectionStoreNames, modelConstructor;
408
- var _this = this;
409
- return tslib_1.__generator(this, function (_a) {
410
- namespace = this.schema.namespaces[namespaceName];
411
- relations = namespace.relationships[srcModelName].relationTypes;
412
- connectionStoreNames = relations.map(function (_a) {
413
- var modelName = _a.modelName;
414
- return util_1.getStorename(namespaceName, modelName);
415
- });
416
- modelConstructor = this.getModelConstructorByModelName(namespaceName, srcModelName);
417
- if (connectionStoreNames.length === 0) {
418
- return [2 /*return*/, records.map(function (record) {
419
- return _this.modelInstanceCreator(modelConstructor, record);
420
- })];
421
- }
422
- return [2 /*return*/, records.map(function (record) {
423
- return _this.modelInstanceCreator(modelConstructor, record);
424
- })];
425
- });
426
- });
427
- };
428
325
  IndexedDBAdapter.prototype.query = function (modelConstructor, predicate, pagination) {
429
326
  return tslib_1.__awaiter(this, void 0, void 0, function () {
430
- var storeName, namespaceName, predicates, keyPath, queryByKey, hasSort, hasPagination, records;
327
+ var _a, storeName, namespaceName, queryByKey, predicates, hasSort, hasPagination, records;
431
328
  var _this = this;
432
- return tslib_1.__generator(this, function (_a) {
433
- switch (_a.label) {
329
+ return tslib_1.__generator(this, function (_b) {
330
+ switch (_b.label) {
434
331
  case 0: return [4 /*yield*/, this.checkPrivate()];
435
332
  case 1:
436
- _a.sent();
437
- storeName = this.getStorenameForModel(modelConstructor);
438
- namespaceName = this.namespaceResolver(modelConstructor);
439
- predicates = predicate && predicates_1.ModelPredicateCreator.getPredicates(predicate);
440
- keyPath = util_1.getIndexKeys(this.schema.namespaces[namespaceName], modelConstructor.name);
441
- queryByKey = predicates && this.keyValueFromPredicate(predicates, keyPath);
442
- hasSort = pagination && pagination.sort;
443
- hasPagination = pagination && pagination.limit;
333
+ _b.sent();
334
+ _a = this.queryMetadata(modelConstructor, predicate, pagination), storeName = _a.storeName, namespaceName = _a.namespaceName, queryByKey = _a.queryByKey, predicates = _a.predicates, hasSort = _a.hasSort, hasPagination = _a.hasPagination;
444
335
  return [4 /*yield*/, (function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
445
336
  var record, filtered, all;
446
337
  return tslib_1.__generator(this, function (_a) {
@@ -472,105 +363,449 @@ var IndexedDBAdapter = /** @class */ (function () {
472
363
  });
473
364
  }); })()];
474
365
  case 2:
475
- records = (_a.sent());
366
+ records = (_b.sent());
476
367
  return [4 /*yield*/, this.load(namespaceName, modelConstructor.name, records)];
477
- case 3: return [2 /*return*/, _a.sent()];
368
+ case 3: return [2 /*return*/, _b.sent()];
478
369
  }
479
370
  });
480
371
  });
481
372
  };
482
- IndexedDBAdapter.prototype.getByKey = function (storeName, keyValue) {
373
+ IndexedDBAdapter.prototype.queryOne = function (modelConstructor, firstOrLast) {
374
+ if (firstOrLast === void 0) { firstOrLast = types_1.QueryOne.FIRST; }
483
375
  return tslib_1.__awaiter(this, void 0, void 0, function () {
376
+ var storeName, cursor, result;
484
377
  return tslib_1.__generator(this, function (_a) {
485
378
  switch (_a.label) {
486
- case 0: return [4 /*yield*/, this._get(storeName, keyValue)];
487
- case 1: return [2 /*return*/, _a.sent()];
379
+ case 0: return [4 /*yield*/, this.checkPrivate()];
380
+ case 1:
381
+ _a.sent();
382
+ storeName = this.getStorenameForModel(modelConstructor);
383
+ return [4 /*yield*/, this.db
384
+ .transaction([storeName], 'readonly')
385
+ .objectStore(storeName)
386
+ .openCursor(undefined, firstOrLast === types_1.QueryOne.FIRST ? 'next' : 'prev')];
387
+ case 2:
388
+ cursor = _a.sent();
389
+ result = cursor ? cursor.value : undefined;
390
+ return [2 /*return*/, result && this.modelInstanceCreator(modelConstructor, result)];
488
391
  }
489
392
  });
490
393
  });
491
394
  };
492
- IndexedDBAdapter.prototype.getAll = function (storeName) {
395
+ IndexedDBAdapter.prototype.batchSave = function (modelConstructor, items) {
493
396
  return tslib_1.__awaiter(this, void 0, void 0, function () {
494
- return tslib_1.__generator(this, function (_a) {
495
- switch (_a.label) {
496
- case 0: return [4 /*yield*/, this.db.getAll(storeName)];
497
- case 1: return [2 /*return*/, _a.sent()];
397
+ var modelName, namespaceName, storeName, result, txn, store, _loop_1, this_1, items_1, items_1_1, item, e_3_1;
398
+ var e_3, _a;
399
+ var _this = this;
400
+ return tslib_1.__generator(this, function (_b) {
401
+ switch (_b.label) {
402
+ case 0: return [4 /*yield*/, this.checkPrivate()];
403
+ case 1:
404
+ _b.sent();
405
+ if (items.length === 0) {
406
+ return [2 /*return*/, []];
407
+ }
408
+ modelName = modelConstructor.name;
409
+ namespaceName = this.namespaceResolver(modelConstructor);
410
+ storeName = this.getStorenameForModel(modelConstructor);
411
+ result = [];
412
+ txn = this.db.transaction(storeName, 'readwrite');
413
+ store = txn.store;
414
+ _loop_1 = function (item) {
415
+ var model, connectedModels, keyValues, _deleted, index, key, instance;
416
+ return tslib_1.__generator(this, function (_a) {
417
+ switch (_a.label) {
418
+ case 0:
419
+ model = this_1.modelInstanceCreator(modelConstructor, item);
420
+ connectedModels = util_1.traverseModel(modelName, model, this_1.schema.namespaces[namespaceName], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
421
+ keyValues = this_1.getIndexKeyValuesFromModel(model);
422
+ _deleted = item._deleted;
423
+ index = store.index('byPk');
424
+ return [4 /*yield*/, index.getKey(this_1.canonicalKeyPath(keyValues))];
425
+ case 1:
426
+ key = _a.sent();
427
+ if (!!_deleted) return [3 /*break*/, 3];
428
+ instance = connectedModels.find(function (_a) {
429
+ var instance = _a.instance;
430
+ var instanceKeyValues = _this.getIndexKeyValuesFromModel(instance);
431
+ return util_1.keysEqual(instanceKeyValues, keyValues);
432
+ }).instance;
433
+ result.push([
434
+ instance,
435
+ key ? types_1.OpType.UPDATE : types_1.OpType.INSERT,
436
+ ]);
437
+ return [4 /*yield*/, store.put(instance, key)];
438
+ case 2:
439
+ _a.sent();
440
+ return [3 /*break*/, 5];
441
+ case 3:
442
+ result.push([item, types_1.OpType.DELETE]);
443
+ if (!key) return [3 /*break*/, 5];
444
+ return [4 /*yield*/, store.delete(key)];
445
+ case 4:
446
+ _a.sent();
447
+ _a.label = 5;
448
+ case 5: return [2 /*return*/];
449
+ }
450
+ });
451
+ };
452
+ this_1 = this;
453
+ _b.label = 2;
454
+ case 2:
455
+ _b.trys.push([2, 7, 8, 9]);
456
+ items_1 = tslib_1.__values(items), items_1_1 = items_1.next();
457
+ _b.label = 3;
458
+ case 3:
459
+ if (!!items_1_1.done) return [3 /*break*/, 6];
460
+ item = items_1_1.value;
461
+ return [5 /*yield**/, _loop_1(item)];
462
+ case 4:
463
+ _b.sent();
464
+ _b.label = 5;
465
+ case 5:
466
+ items_1_1 = items_1.next();
467
+ return [3 /*break*/, 3];
468
+ case 6: return [3 /*break*/, 9];
469
+ case 7:
470
+ e_3_1 = _b.sent();
471
+ e_3 = { error: e_3_1 };
472
+ return [3 /*break*/, 9];
473
+ case 8:
474
+ try {
475
+ if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
476
+ }
477
+ finally { if (e_3) throw e_3.error; }
478
+ return [7 /*endfinally*/];
479
+ case 9: return [4 /*yield*/, txn.done];
480
+ case 10:
481
+ _b.sent();
482
+ return [2 /*return*/, result];
498
483
  }
499
484
  });
500
485
  });
501
486
  };
502
- IndexedDBAdapter.prototype.keyValueFromPredicate = function (predicates, keyPath) {
503
- var e_3, _a;
504
- var predicateObjs = predicates.predicates;
505
- if (predicateObjs.length !== keyPath.length) {
506
- return;
507
- }
508
- var keyValues = [];
509
- var _loop_1 = function (key) {
510
- var predicateObj = predicateObjs.find(function (p) {
511
- // it's a relevant predicate object only if it's an equality
512
- // operation for a key field from the key:
513
- return types_1.isPredicateObj(p) &&
514
- p.field === key &&
515
- p.operator === 'eq' &&
516
- // it's only valid if it's not nullish.
517
- // (IDB will throw a fit if it's nullish.)
518
- p.operand !== null &&
519
- p.operand !== undefined;
520
- });
521
- predicateObj && keyValues.push(predicateObj.operand);
522
- };
523
- try {
524
- for (var keyPath_1 = tslib_1.__values(keyPath), keyPath_1_1 = keyPath_1.next(); !keyPath_1_1.done; keyPath_1_1 = keyPath_1.next()) {
525
- var key = keyPath_1_1.value;
526
- _loop_1(key);
527
- }
528
- }
529
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
530
- finally {
531
- try {
532
- if (keyPath_1_1 && !keyPath_1_1.done && (_a = keyPath_1.return)) _a.call(keyPath_1);
533
- }
534
- finally { if (e_3) throw e_3.error; }
535
- }
536
- return keyValues.length === keyPath.length ? keyValues : undefined;
537
- };
538
- /**
539
- * Tries to generate an index fetcher for the given predicates. Assumes
540
- * that the given predicate conditions are contained by an AND group and
541
- * should therefore all match a single record.
542
- *
543
- * @param storeName The table to query.
544
- * @param predicates The predicates to try to AND together.
487
+ IndexedDBAdapter.prototype.deleteItem = function (deleteQueue) {
488
+ var e_4, _a, e_5, _b;
489
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
490
+ var connectionStoreNames, tx, _c, _d, deleteItem, storeName, items, store, items_2, items_2_1, item, key, keyValues, itemKey, e_5_1, e_4_1;
491
+ return tslib_1.__generator(this, function (_e) {
492
+ switch (_e.label) {
493
+ case 0:
494
+ connectionStoreNames = deleteQueue.map(function (_a) {
495
+ var storeName = _a.storeName;
496
+ return storeName;
497
+ });
498
+ tx = this.db.transaction(tslib_1.__spread(connectionStoreNames), 'readwrite');
499
+ _e.label = 1;
500
+ case 1:
501
+ _e.trys.push([1, 22, 23, 28]);
502
+ _c = tslib_1.__asyncValues(deleteQueue);
503
+ _e.label = 2;
504
+ case 2: return [4 /*yield*/, _c.next()];
505
+ case 3:
506
+ if (!(_d = _e.sent(), !_d.done)) return [3 /*break*/, 21];
507
+ deleteItem = _d.value;
508
+ storeName = deleteItem.storeName, items = deleteItem.items;
509
+ store = tx.objectStore(storeName);
510
+ _e.label = 4;
511
+ case 4:
512
+ _e.trys.push([4, 14, 15, 20]);
513
+ items_2 = tslib_1.__asyncValues(items);
514
+ _e.label = 5;
515
+ case 5: return [4 /*yield*/, items_2.next()];
516
+ case 6:
517
+ if (!(items_2_1 = _e.sent(), !items_2_1.done)) return [3 /*break*/, 13];
518
+ item = items_2_1.value;
519
+ if (!item) return [3 /*break*/, 12];
520
+ key = void 0;
521
+ if (!(typeof item === 'object')) return [3 /*break*/, 8];
522
+ keyValues = this.getIndexKeyValuesFromModel(item);
523
+ return [4 /*yield*/, store
524
+ .index('byPk')
525
+ .getKey(this.canonicalKeyPath(keyValues))];
526
+ case 7:
527
+ key = _e.sent();
528
+ return [3 /*break*/, 10];
529
+ case 8:
530
+ itemKey = item.toString();
531
+ return [4 /*yield*/, store.index('byPk').getKey(itemKey)];
532
+ case 9:
533
+ key = _e.sent();
534
+ _e.label = 10;
535
+ case 10:
536
+ if (!(key !== undefined)) return [3 /*break*/, 12];
537
+ return [4 /*yield*/, store.delete(key)];
538
+ case 11:
539
+ _e.sent();
540
+ _e.label = 12;
541
+ case 12: return [3 /*break*/, 5];
542
+ case 13: return [3 /*break*/, 20];
543
+ case 14:
544
+ e_5_1 = _e.sent();
545
+ e_5 = { error: e_5_1 };
546
+ return [3 /*break*/, 20];
547
+ case 15:
548
+ _e.trys.push([15, , 18, 19]);
549
+ if (!(items_2_1 && !items_2_1.done && (_b = items_2.return))) return [3 /*break*/, 17];
550
+ return [4 /*yield*/, _b.call(items_2)];
551
+ case 16:
552
+ _e.sent();
553
+ _e.label = 17;
554
+ case 17: return [3 /*break*/, 19];
555
+ case 18:
556
+ if (e_5) throw e_5.error;
557
+ return [7 /*endfinally*/];
558
+ case 19: return [7 /*endfinally*/];
559
+ case 20: return [3 /*break*/, 2];
560
+ case 21: return [3 /*break*/, 28];
561
+ case 22:
562
+ e_4_1 = _e.sent();
563
+ e_4 = { error: e_4_1 };
564
+ return [3 /*break*/, 28];
565
+ case 23:
566
+ _e.trys.push([23, , 26, 27]);
567
+ if (!(_d && !_d.done && (_a = _c.return))) return [3 /*break*/, 25];
568
+ return [4 /*yield*/, _a.call(_c)];
569
+ case 24:
570
+ _e.sent();
571
+ _e.label = 25;
572
+ case 25: return [3 /*break*/, 27];
573
+ case 26:
574
+ if (e_4) throw e_4.error;
575
+ return [7 /*endfinally*/];
576
+ case 27: return [7 /*endfinally*/];
577
+ case 28: return [2 /*return*/];
578
+ }
579
+ });
580
+ });
581
+ };
582
+ /**
583
+ * Gets related Has One record for `model`
584
+ *
585
+ * @param model
586
+ * @param srcModel
587
+ * @param namespace
588
+ * @param rel
589
+ * @returns
590
+ */
591
+ IndexedDBAdapter.prototype.getHasOneChild = function (model, srcModel, namespace, rel) {
592
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
593
+ var hasOneIndex, modelName, targetNames, storeName, values, recordToDelete;
594
+ return tslib_1.__generator(this, function (_a) {
595
+ switch (_a.label) {
596
+ case 0:
597
+ hasOneIndex = 'byPk';
598
+ modelName = rel.modelName, targetNames = rel.targetNames;
599
+ storeName = util_1.getStorename(namespace, modelName);
600
+ values = targetNames
601
+ .filter(function (targetName) { var _a; return (_a = model[targetName]) !== null && _a !== void 0 ? _a : false; })
602
+ .map(function (targetName) { return model[targetName]; });
603
+ if (values.length === 0)
604
+ return [2 /*return*/];
605
+ return [4 /*yield*/, this.db
606
+ .transaction(storeName, 'readwrite')
607
+ .objectStore(storeName)
608
+ .index(hasOneIndex)
609
+ .get(this.canonicalKeyPath(values))];
610
+ case 1:
611
+ recordToDelete = (_a.sent());
612
+ return [2 /*return*/, recordToDelete];
613
+ }
614
+ });
615
+ });
616
+ };
617
+ /**
618
+ * Backwards compatability for pre-CPK codegen
619
+ * TODO - deprecate this in v6; will need to re-gen MIPR for older unit
620
+ * tests that hit this path
621
+ */
622
+ IndexedDBAdapter.prototype.getHasOneChildLegacy = function (model, srcModel, namespace, rel) {
623
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
624
+ var hasOneIndex, modelName, targetName, storeName, index, values, value, recordToDelete;
625
+ return tslib_1.__generator(this, function (_a) {
626
+ switch (_a.label) {
627
+ case 0:
628
+ hasOneIndex = 'byPk';
629
+ modelName = rel.modelName, targetName = rel.targetName;
630
+ storeName = util_1.getStorename(namespace, modelName);
631
+ if (targetName && targetName in model) {
632
+ index = hasOneIndex;
633
+ value = model[targetName];
634
+ if (value === null) {
635
+ return [2 /*return*/];
636
+ }
637
+ values = [value];
638
+ }
639
+ else {
640
+ // backwards compatability for older versions of codegen that did not emit targetName for HAS_ONE relations
641
+ index = util_1.getIndex(this.schema.namespaces[namespace].relationships[modelName]
642
+ .relationTypes, srcModel);
643
+ values = this.getIndexKeyValuesFromModel(model);
644
+ }
645
+ if (!values || !index)
646
+ return [2 /*return*/];
647
+ return [4 /*yield*/, this.db
648
+ .transaction(storeName, 'readwrite')
649
+ .objectStore(storeName)
650
+ .index(index)
651
+ .get(this.canonicalKeyPath(values))];
652
+ case 1:
653
+ recordToDelete = (_a.sent());
654
+ return [2 /*return*/, recordToDelete];
655
+ }
656
+ });
657
+ });
658
+ };
659
+ /**
660
+ * Gets related Has Many records by given `storeName`, `index`, and `keyValues`
661
+ *
662
+ * @param storeName
663
+ * @param index
664
+ * @param keyValues
665
+ * @returns
666
+ */
667
+ IndexedDBAdapter.prototype.getHasManyChildren = function (storeName, index, keyValues) {
668
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
669
+ var childRecords;
670
+ return tslib_1.__generator(this, function (_a) {
671
+ switch (_a.label) {
672
+ case 0: return [4 /*yield*/, this.db
673
+ .transaction(storeName, 'readwrite')
674
+ .objectStore(storeName)
675
+ .index(index)
676
+ .getAll(this.canonicalKeyPath(keyValues))];
677
+ case 1:
678
+ childRecords = _a.sent();
679
+ return [2 /*return*/, childRecords];
680
+ }
681
+ });
682
+ });
683
+ };
684
+ //#region platform-specific helper methods
685
+ IndexedDBAdapter.prototype.checkPrivate = function () {
686
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
687
+ var isPrivate;
688
+ return tslib_1.__generator(this, function (_a) {
689
+ switch (_a.label) {
690
+ case 0: return [4 /*yield*/, util_1.isPrivateMode().then(function (isPrivate) {
691
+ return isPrivate;
692
+ })];
693
+ case 1:
694
+ isPrivate = _a.sent();
695
+ if (isPrivate) {
696
+ logger.error("IndexedDB not supported in this browser's private mode");
697
+ return [2 /*return*/, Promise.reject("IndexedDB not supported in this browser's private mode")];
698
+ }
699
+ else {
700
+ return [2 /*return*/, Promise.resolve()];
701
+ }
702
+ return [2 /*return*/];
703
+ }
704
+ });
705
+ });
706
+ };
707
+ /**
708
+ * Whether the browser's implementation of IndexedDB is coercing single-field
709
+ * indexes to a scalar key.
710
+ *
711
+ * If this returns `true`, we need to treat indexes containing a single field
712
+ * as scalars.
713
+ *
714
+ * See PR description for reference:
715
+ * https://github.com/aws-amplify/amplify-js/pull/10527
716
+ */
717
+ IndexedDBAdapter.prototype.setSafariCompatabilityMode = function () {
718
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
719
+ var _a;
720
+ return tslib_1.__generator(this, function (_b) {
721
+ switch (_b.label) {
722
+ case 0:
723
+ _a = this;
724
+ return [4 /*yield*/, util_1.isSafariCompatabilityMode()];
725
+ case 1:
726
+ _a.safariCompatabilityMode = _b.sent();
727
+ if (this.safariCompatabilityMode === true) {
728
+ logger.debug('IndexedDB Adapter is running in Safari Compatability Mode');
729
+ }
730
+ return [2 /*return*/];
731
+ }
732
+ });
733
+ });
734
+ };
735
+ IndexedDBAdapter.prototype.getNamespaceAndModelFromStorename = function (storeName) {
736
+ var _a = tslib_1.__read(storeName.split('_')), namespaceName = _a[0], modelNameArr = _a.slice(1);
737
+ return {
738
+ namespaceName: namespaceName,
739
+ modelName: modelNameArr.join('_'),
740
+ };
741
+ };
742
+ IndexedDBAdapter.prototype.createObjectStoreForModel = function (db, namespaceName, storeName, modelName) {
743
+ var store = db.createObjectStore(storeName, {
744
+ autoIncrement: true,
745
+ });
746
+ var indexes = this.schema.namespaces[namespaceName].relationships[modelName].indexes;
747
+ indexes.forEach(function (_a) {
748
+ var _b = tslib_1.__read(_a, 3), idxName = _b[0], keyPath = _b[1], options = _b[2];
749
+ store.createIndex(idxName, keyPath, options);
750
+ });
751
+ return store;
752
+ };
753
+ IndexedDBAdapter.prototype.getByKey = function (storeName, keyValue) {
754
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
755
+ return tslib_1.__generator(this, function (_a) {
756
+ switch (_a.label) {
757
+ case 0: return [4 /*yield*/, this._get(storeName, keyValue)];
758
+ case 1: return [2 /*return*/, _a.sent()];
759
+ }
760
+ });
761
+ });
762
+ };
763
+ IndexedDBAdapter.prototype.getAll = function (storeName) {
764
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
765
+ return tslib_1.__generator(this, function (_a) {
766
+ switch (_a.label) {
767
+ case 0: return [4 /*yield*/, this.db.getAll(storeName)];
768
+ case 1: return [2 /*return*/, _a.sent()];
769
+ }
770
+ });
771
+ });
772
+ };
773
+ /**
774
+ * Tries to generate an index fetcher for the given predicates. Assumes
775
+ * that the given predicate conditions are contained by an AND group and
776
+ * should therefore all match a single record.
777
+ *
778
+ * @param storeName The table to query.
779
+ * @param predicates The predicates to try to AND together.
545
780
  * @param transaction
546
781
  */
547
782
  IndexedDBAdapter.prototype.matchingIndexQueries = function (storeName, predicates, transaction) {
548
- var e_4, _a, e_5, _b;
783
+ var e_6, _a, e_7, _b;
549
784
  var _this = this;
550
785
  // could be expanded later to include `exec()` and a `cardinality` estimate?
551
786
  var queries = [];
552
787
  var predicateIndex = new Map();
553
788
  try {
554
- for (var predicates_2 = tslib_1.__values(predicates), predicates_2_1 = predicates_2.next(); !predicates_2_1.done; predicates_2_1 = predicates_2.next()) {
555
- var predicate = predicates_2_1.value;
789
+ for (var predicates_1 = tslib_1.__values(predicates), predicates_1_1 = predicates_1.next(); !predicates_1_1.done; predicates_1_1 = predicates_1.next()) {
790
+ var predicate = predicates_1_1.value;
556
791
  predicateIndex.set(String(predicate.field), predicate);
557
792
  }
558
793
  }
559
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
794
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
560
795
  finally {
561
796
  try {
562
- if (predicates_2_1 && !predicates_2_1.done && (_a = predicates_2.return)) _a.call(predicates_2);
797
+ if (predicates_1_1 && !predicates_1_1.done && (_a = predicates_1.return)) _a.call(predicates_1);
563
798
  }
564
- finally { if (e_4) throw e_4.error; }
799
+ finally { if (e_6) throw e_6.error; }
565
800
  }
566
801
  var store = transaction.objectStore(storeName);
567
802
  var _loop_2 = function (name_1) {
568
- var e_6, _a;
803
+ var e_8, _a;
569
804
  var idx = store.index(name_1);
570
805
  var keypath = Array.isArray(idx.keyPath) ? idx.keyPath : [idx.keyPath];
571
806
  var matchingPredicateValues = [];
572
807
  try {
573
- for (var keypath_1 = (e_6 = void 0, tslib_1.__values(keypath)), keypath_1_1 = keypath_1.next(); !keypath_1_1.done; keypath_1_1 = keypath_1.next()) {
808
+ for (var keypath_1 = (e_8 = void 0, tslib_1.__values(keypath)), keypath_1_1 = keypath_1.next(); !keypath_1_1.done; keypath_1_1 = keypath_1.next()) {
574
809
  var field = keypath_1_1.value;
575
810
  var p = predicateIndex.get(field);
576
811
  if (p && p.operand !== null && p.operand !== undefined) {
@@ -581,12 +816,12 @@ var IndexedDBAdapter = /** @class */ (function () {
581
816
  }
582
817
  }
583
818
  }
584
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
819
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
585
820
  finally {
586
821
  try {
587
822
  if (keypath_1_1 && !keypath_1_1.done && (_a = keypath_1.return)) _a.call(keypath_1);
588
823
  }
589
- finally { if (e_6) throw e_6.error; }
824
+ finally { if (e_8) throw e_8.error; }
590
825
  }
591
826
  // if we have a matching predicate field for each component of this index,
592
827
  // we can build a query for it. otherwise, we can't.
@@ -608,12 +843,12 @@ var IndexedDBAdapter = /** @class */ (function () {
608
843
  _loop_2(name_1);
609
844
  }
610
845
  }
611
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
846
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
612
847
  finally {
613
848
  try {
614
849
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
615
850
  }
616
- finally { if (e_5) throw e_5.error; }
851
+ finally { if (e_7) throw e_7.error; }
617
852
  }
618
853
  return queries;
619
854
  };
@@ -702,8 +937,8 @@ var IndexedDBAdapter = /** @class */ (function () {
702
937
  };
703
938
  IndexedDBAdapter.prototype.filterOnPredicate = function (storeName, predicates) {
704
939
  return tslib_1.__awaiter(this, void 0, void 0, function () {
705
- var predicateObjs, type, _a, groupType, indexedQueries, candidateResults, distinctResults, indexedQueries_1, indexedQueries_1_1, query, resultGroup, resultGroup_1, resultGroup_1_1, item, distinctificationString, e_7_1, filtered;
706
- var e_7, _b, e_8, _c;
940
+ var predicateObjs, type, _a, groupType, indexedQueries, candidateResults, distinctResults, indexedQueries_1, indexedQueries_1_1, query, resultGroup, resultGroup_1, resultGroup_1_1, item, distinctificationString, e_9_1, filtered;
941
+ var e_9, _b, e_10, _c;
707
942
  return tslib_1.__generator(this, function (_d) {
708
943
  switch (_d.label) {
709
944
  case 0:
@@ -735,18 +970,18 @@ var IndexedDBAdapter = /** @class */ (function () {
735
970
  case 6:
736
971
  resultGroup = _d.sent();
737
972
  try {
738
- for (resultGroup_1 = (e_8 = void 0, tslib_1.__values(resultGroup)), resultGroup_1_1 = resultGroup_1.next(); !resultGroup_1_1.done; resultGroup_1_1 = resultGroup_1.next()) {
973
+ for (resultGroup_1 = (e_10 = void 0, tslib_1.__values(resultGroup)), resultGroup_1_1 = resultGroup_1.next(); !resultGroup_1_1.done; resultGroup_1_1 = resultGroup_1.next()) {
739
974
  item = resultGroup_1_1.value;
740
975
  distinctificationString = JSON.stringify(item);
741
976
  distinctResults.set(distinctificationString, item);
742
977
  }
743
978
  }
744
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
979
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
745
980
  finally {
746
981
  try {
747
982
  if (resultGroup_1_1 && !resultGroup_1_1.done && (_c = resultGroup_1.return)) _c.call(resultGroup_1);
748
983
  }
749
- finally { if (e_8) throw e_8.error; }
984
+ finally { if (e_10) throw e_10.error; }
750
985
  }
751
986
  _d.label = 7;
752
987
  case 7:
@@ -754,14 +989,14 @@ var IndexedDBAdapter = /** @class */ (function () {
754
989
  return [3 /*break*/, 5];
755
990
  case 8: return [3 /*break*/, 11];
756
991
  case 9:
757
- e_7_1 = _d.sent();
758
- e_7 = { error: e_7_1 };
992
+ e_9_1 = _d.sent();
993
+ e_9 = { error: e_9_1 };
759
994
  return [3 /*break*/, 11];
760
995
  case 10:
761
996
  try {
762
997
  if (indexedQueries_1_1 && !indexedQueries_1_1.done && (_b = indexedQueries_1.return)) _b.call(indexedQueries_1);
763
998
  }
764
- finally { if (e_7) throw e_7.error; }
999
+ finally { if (e_9) throw e_9.error; }
765
1000
  return [7 /*endfinally*/];
766
1001
  case 11:
767
1002
  // we could conceivably check for special conditions and return early here.
@@ -833,545 +1068,7 @@ var IndexedDBAdapter = /** @class */ (function () {
833
1068
  });
834
1069
  });
835
1070
  };
836
- IndexedDBAdapter.prototype.queryOne = function (modelConstructor, firstOrLast) {
837
- if (firstOrLast === void 0) { firstOrLast = types_1.QueryOne.FIRST; }
838
- return tslib_1.__awaiter(this, void 0, void 0, function () {
839
- var storeName, cursor, result;
840
- return tslib_1.__generator(this, function (_a) {
841
- switch (_a.label) {
842
- case 0: return [4 /*yield*/, this.checkPrivate()];
843
- case 1:
844
- _a.sent();
845
- storeName = this.getStorenameForModel(modelConstructor);
846
- return [4 /*yield*/, this.db
847
- .transaction([storeName], 'readonly')
848
- .objectStore(storeName)
849
- .openCursor(undefined, firstOrLast === types_1.QueryOne.FIRST ? 'next' : 'prev')];
850
- case 2:
851
- cursor = _a.sent();
852
- result = cursor ? cursor.value : undefined;
853
- return [2 /*return*/, result && this.modelInstanceCreator(modelConstructor, result)];
854
- }
855
- });
856
- });
857
- };
858
- IndexedDBAdapter.prototype.delete = function (modelOrModelConstructor, condition) {
859
- return tslib_1.__awaiter(this, void 0, void 0, function () {
860
- var deleteQueue, modelConstructor, nameSpace, storeName, models, relations, deletedModels, deletedModels, model, modelConstructor, namespaceName, storeName, tx, store, keyValues, fromDB, msg, predicates, _a, predicateObjs, type, isValid, msg, relations, relations, deletedModels;
861
- return tslib_1.__generator(this, function (_b) {
862
- switch (_b.label) {
863
- case 0: return [4 /*yield*/, this.checkPrivate()];
864
- case 1:
865
- _b.sent();
866
- deleteQueue = [];
867
- if (!util_1.isModelConstructor(modelOrModelConstructor)) return [3 /*break*/, 9];
868
- modelConstructor = modelOrModelConstructor;
869
- nameSpace = this.namespaceResolver(modelConstructor);
870
- storeName = this.getStorenameForModel(modelConstructor);
871
- return [4 /*yield*/, this.query(modelConstructor, condition)];
872
- case 2:
873
- models = _b.sent();
874
- relations = this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
875
- .relationTypes;
876
- if (!(condition !== undefined)) return [3 /*break*/, 5];
877
- return [4 /*yield*/, this.deleteTraverse(relations, models, modelConstructor.name, nameSpace, deleteQueue)];
878
- case 3:
879
- _b.sent();
880
- return [4 /*yield*/, this.deleteItem(deleteQueue)];
881
- case 4:
882
- _b.sent();
883
- deletedModels = deleteQueue.reduce(function (acc, _a) {
884
- var items = _a.items;
885
- return acc.concat(items);
886
- }, []);
887
- return [2 /*return*/, [models, deletedModels]];
888
- case 5: return [4 /*yield*/, this.deleteTraverse(relations, models, modelConstructor.name, nameSpace, deleteQueue)];
889
- case 6:
890
- _b.sent();
891
- // Delete all
892
- return [4 /*yield*/, this.db
893
- .transaction([storeName], 'readwrite')
894
- .objectStore(storeName)
895
- .clear()];
896
- case 7:
897
- // Delete all
898
- _b.sent();
899
- deletedModels = deleteQueue.reduce(function (acc, _a) {
900
- var items = _a.items;
901
- return acc.concat(items);
902
- }, []);
903
- return [2 /*return*/, [models, deletedModels]];
904
- case 8: return [3 /*break*/, 17];
905
- case 9:
906
- model = modelOrModelConstructor;
907
- modelConstructor = Object.getPrototypeOf(model)
908
- .constructor;
909
- namespaceName = this.namespaceResolver(modelConstructor);
910
- storeName = this.getStorenameForModel(modelConstructor);
911
- if (!condition) return [3 /*break*/, 13];
912
- tx = this.db.transaction([storeName], 'readwrite');
913
- store = tx.objectStore(storeName);
914
- keyValues = this.getIndexKeyValuesFromModel(model);
915
- return [4 /*yield*/, this._get(store, keyValues)];
916
- case 10:
917
- fromDB = _b.sent();
918
- if (fromDB === undefined) {
919
- msg = 'Model instance not found in storage';
920
- logger.warn(msg, { model: model });
921
- return [2 /*return*/, [[model], []]];
922
- }
923
- predicates = predicates_1.ModelPredicateCreator.getPredicates(condition);
924
- _a = predicates, predicateObjs = _a.predicates, type = _a.type;
925
- isValid = util_1.validatePredicate(fromDB, type, predicateObjs);
926
- if (!isValid) {
927
- msg = 'Conditional update failed';
928
- logger.error(msg, { model: fromDB, condition: predicateObjs });
929
- throw new Error(msg);
930
- }
931
- return [4 /*yield*/, tx.done];
932
- case 11:
933
- _b.sent();
934
- relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
935
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
936
- case 12:
937
- _b.sent();
938
- return [3 /*break*/, 15];
939
- case 13:
940
- relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
941
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
942
- case 14:
943
- _b.sent();
944
- _b.label = 15;
945
- case 15: return [4 /*yield*/, this.deleteItem(deleteQueue)];
946
- case 16:
947
- _b.sent();
948
- deletedModels = deleteQueue.reduce(function (acc, _a) {
949
- var items = _a.items;
950
- return acc.concat(items);
951
- }, []);
952
- return [2 /*return*/, [[model], deletedModels]];
953
- case 17: return [2 /*return*/];
954
- }
955
- });
956
- });
957
- };
958
- IndexedDBAdapter.prototype.deleteItem = function (deleteQueue) {
959
- var e_9, _a, e_10, _b;
960
- return tslib_1.__awaiter(this, void 0, void 0, function () {
961
- var connectionStoreNames, tx, _c, _d, deleteItem, storeName, items, store, items_1, items_1_1, item, key, keyValues, itemKey, e_10_1, e_9_1;
962
- return tslib_1.__generator(this, function (_e) {
963
- switch (_e.label) {
964
- case 0:
965
- connectionStoreNames = deleteQueue.map(function (_a) {
966
- var storeName = _a.storeName;
967
- return storeName;
968
- });
969
- tx = this.db.transaction(tslib_1.__spread(connectionStoreNames), 'readwrite');
970
- _e.label = 1;
971
- case 1:
972
- _e.trys.push([1, 22, 23, 28]);
973
- _c = tslib_1.__asyncValues(deleteQueue);
974
- _e.label = 2;
975
- case 2: return [4 /*yield*/, _c.next()];
976
- case 3:
977
- if (!(_d = _e.sent(), !_d.done)) return [3 /*break*/, 21];
978
- deleteItem = _d.value;
979
- storeName = deleteItem.storeName, items = deleteItem.items;
980
- store = tx.objectStore(storeName);
981
- _e.label = 4;
982
- case 4:
983
- _e.trys.push([4, 14, 15, 20]);
984
- items_1 = tslib_1.__asyncValues(items);
985
- _e.label = 5;
986
- case 5: return [4 /*yield*/, items_1.next()];
987
- case 6:
988
- if (!(items_1_1 = _e.sent(), !items_1_1.done)) return [3 /*break*/, 13];
989
- item = items_1_1.value;
990
- if (!item) return [3 /*break*/, 12];
991
- key = void 0;
992
- if (!(typeof item === 'object')) return [3 /*break*/, 8];
993
- keyValues = this.getIndexKeyValuesFromModel(item);
994
- return [4 /*yield*/, store
995
- .index('byPk')
996
- .getKey(this.canonicalKeyPath(keyValues))];
997
- case 7:
998
- key = _e.sent();
999
- return [3 /*break*/, 10];
1000
- case 8:
1001
- itemKey = item.toString();
1002
- return [4 /*yield*/, store.index('byPk').getKey(itemKey)];
1003
- case 9:
1004
- key = _e.sent();
1005
- _e.label = 10;
1006
- case 10:
1007
- if (!(key !== undefined)) return [3 /*break*/, 12];
1008
- return [4 /*yield*/, store.delete(key)];
1009
- case 11:
1010
- _e.sent();
1011
- _e.label = 12;
1012
- case 12: return [3 /*break*/, 5];
1013
- case 13: return [3 /*break*/, 20];
1014
- case 14:
1015
- e_10_1 = _e.sent();
1016
- e_10 = { error: e_10_1 };
1017
- return [3 /*break*/, 20];
1018
- case 15:
1019
- _e.trys.push([15, , 18, 19]);
1020
- if (!(items_1_1 && !items_1_1.done && (_b = items_1.return))) return [3 /*break*/, 17];
1021
- return [4 /*yield*/, _b.call(items_1)];
1022
- case 16:
1023
- _e.sent();
1024
- _e.label = 17;
1025
- case 17: return [3 /*break*/, 19];
1026
- case 18:
1027
- if (e_10) throw e_10.error;
1028
- return [7 /*endfinally*/];
1029
- case 19: return [7 /*endfinally*/];
1030
- case 20: return [3 /*break*/, 2];
1031
- case 21: return [3 /*break*/, 28];
1032
- case 22:
1033
- e_9_1 = _e.sent();
1034
- e_9 = { error: e_9_1 };
1035
- return [3 /*break*/, 28];
1036
- case 23:
1037
- _e.trys.push([23, , 26, 27]);
1038
- if (!(_d && !_d.done && (_a = _c.return))) return [3 /*break*/, 25];
1039
- return [4 /*yield*/, _a.call(_c)];
1040
- case 24:
1041
- _e.sent();
1042
- _e.label = 25;
1043
- case 25: return [3 /*break*/, 27];
1044
- case 26:
1045
- if (e_9) throw e_9.error;
1046
- return [7 /*endfinally*/];
1047
- case 27: return [7 /*endfinally*/];
1048
- case 28: return [2 /*return*/];
1049
- }
1050
- });
1051
- });
1052
- };
1053
- IndexedDBAdapter.prototype.deleteTraverse = function (relations, models, srcModel, nameSpace, deleteQueue) {
1054
- var relations_1, relations_1_1, models_1, models_1_1, models_2, models_2_1;
1055
- var e_11, _a, e_12, _b, e_13, _c;
1056
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1057
- var rel, relationType, modelName, targetName, targetNames, associatedWith, storeName, _d, model, hasOneIndex, values, recordToDelete, index, values, value, recordToDelete, modelsToDelete, _e, e_12_1, model, index, keyValues, childRecords, childModels, e_13_1, e_11_1;
1058
- var _this = this;
1059
- return tslib_1.__generator(this, function (_f) {
1060
- switch (_f.label) {
1061
- case 0:
1062
- _f.trys.push([0, 42, 43, 48]);
1063
- relations_1 = tslib_1.__asyncValues(relations);
1064
- _f.label = 1;
1065
- case 1: return [4 /*yield*/, relations_1.next()];
1066
- case 2:
1067
- if (!(relations_1_1 = _f.sent(), !relations_1_1.done)) return [3 /*break*/, 41];
1068
- rel = relations_1_1.value;
1069
- relationType = rel.relationType, modelName = rel.modelName, targetName = rel.targetName, targetNames = rel.targetNames, associatedWith = rel.associatedWith;
1070
- storeName = util_1.getStorename(nameSpace, modelName);
1071
- _d = relationType;
1072
- switch (_d) {
1073
- case 'HAS_ONE': return [3 /*break*/, 3];
1074
- case 'HAS_MANY': return [3 /*break*/, 23];
1075
- case 'BELONGS_TO': return [3 /*break*/, 38];
1076
- }
1077
- return [3 /*break*/, 39];
1078
- case 3:
1079
- _f.trys.push([3, 16, 17, 22]);
1080
- models_1 = tslib_1.__asyncValues(models);
1081
- _f.label = 4;
1082
- case 4: return [4 /*yield*/, models_1.next()];
1083
- case 5:
1084
- if (!(models_1_1 = _f.sent(), !models_1_1.done)) return [3 /*break*/, 15];
1085
- model = models_1_1.value;
1086
- hasOneIndex = 'byPk';
1087
- if (!(targetNames === null || targetNames === void 0 ? void 0 : targetNames.length)) return [3 /*break*/, 8];
1088
- values = targetNames
1089
- .filter(function (targetName) { var _a; return (_a = model[targetName]) !== null && _a !== void 0 ? _a : false; })
1090
- .map(function (targetName) { return model[targetName]; });
1091
- if (values.length === 0)
1092
- return [3 /*break*/, 15];
1093
- return [4 /*yield*/, this.db
1094
- .transaction(storeName, 'readwrite')
1095
- .objectStore(storeName)
1096
- .index(hasOneIndex)
1097
- .get(this.canonicalKeyPath(values))];
1098
- case 6:
1099
- recordToDelete = (_f.sent());
1100
- return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1101
- .relationTypes, recordToDelete ? [recordToDelete] : [], modelName, nameSpace, deleteQueue)];
1102
- case 7:
1103
- _f.sent();
1104
- return [3 /*break*/, 15];
1105
- case 8:
1106
- index = void 0;
1107
- values = void 0;
1108
- if (targetName && targetName in model) {
1109
- index = hasOneIndex;
1110
- value = model[targetName];
1111
- if (value === null)
1112
- return [3 /*break*/, 15];
1113
- values = [value];
1114
- }
1115
- else {
1116
- // backwards compatability for older versions of codegen that did not emit targetName for HAS_ONE relations
1117
- // TODO: can we deprecate this? it's been ~2 years since codegen started including targetName for HAS_ONE
1118
- // If we deprecate, we'll need to re-gen the MIPR in __tests__/schema.ts > newSchema
1119
- // otherwise some unit tests will fail
1120
- index = util_1.getIndex(this.schema.namespaces[nameSpace].relationships[modelName]
1121
- .relationTypes, srcModel);
1122
- values = this.getIndexKeyValuesFromModel(model);
1123
- }
1124
- if (!values || !index)
1125
- return [3 /*break*/, 15];
1126
- return [4 /*yield*/, this.db
1127
- .transaction(storeName, 'readwrite')
1128
- .objectStore(storeName)
1129
- .index(index)
1130
- .get(this.canonicalKeyPath(values))];
1131
- case 9:
1132
- recordToDelete = (_f.sent());
1133
- if (!recordToDelete) return [3 /*break*/, 11];
1134
- return [4 /*yield*/, this.load(nameSpace, modelName, [recordToDelete])];
1135
- case 10:
1136
- _e = _f.sent();
1137
- return [3 /*break*/, 12];
1138
- case 11:
1139
- _e = [];
1140
- _f.label = 12;
1141
- case 12:
1142
- modelsToDelete = _e;
1143
- return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1144
- .relationTypes, modelsToDelete, modelName, nameSpace, deleteQueue)];
1145
- case 13:
1146
- _f.sent();
1147
- _f.label = 14;
1148
- case 14: return [3 /*break*/, 4];
1149
- case 15: return [3 /*break*/, 22];
1150
- case 16:
1151
- e_12_1 = _f.sent();
1152
- e_12 = { error: e_12_1 };
1153
- return [3 /*break*/, 22];
1154
- case 17:
1155
- _f.trys.push([17, , 20, 21]);
1156
- if (!(models_1_1 && !models_1_1.done && (_b = models_1.return))) return [3 /*break*/, 19];
1157
- return [4 /*yield*/, _b.call(models_1)];
1158
- case 18:
1159
- _f.sent();
1160
- _f.label = 19;
1161
- case 19: return [3 /*break*/, 21];
1162
- case 20:
1163
- if (e_12) throw e_12.error;
1164
- return [7 /*endfinally*/];
1165
- case 21: return [7 /*endfinally*/];
1166
- case 22: return [3 /*break*/, 40];
1167
- case 23:
1168
- _f.trys.push([23, 31, 32, 37]);
1169
- models_2 = tslib_1.__asyncValues(models);
1170
- _f.label = 24;
1171
- case 24: return [4 /*yield*/, models_2.next()];
1172
- case 25:
1173
- if (!(models_2_1 = _f.sent(), !models_2_1.done)) return [3 /*break*/, 30];
1174
- model = models_2_1.value;
1175
- index =
1176
- // explicit bi-directional @hasMany and @manyToMany
1177
- util_1.getIndex(this.schema.namespaces[nameSpace].relationships[modelName]
1178
- .relationTypes, srcModel) ||
1179
- // uni and/or implicit @hasMany
1180
- util_1.getIndexFromAssociation(this.schema.namespaces[nameSpace].relationships[modelName]
1181
- .indexes, associatedWith);
1182
- keyValues = this.getIndexKeyValuesFromModel(model);
1183
- return [4 /*yield*/, this.db
1184
- .transaction(storeName, 'readwrite')
1185
- .objectStore(storeName)
1186
- .index(index)
1187
- .getAll(this.canonicalKeyPath(keyValues))];
1188
- case 26:
1189
- childRecords = _f.sent();
1190
- return [4 /*yield*/, this.load(nameSpace, modelName, childRecords)];
1191
- case 27:
1192
- childModels = _f.sent();
1193
- return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1194
- .relationTypes, childModels, modelName, nameSpace, deleteQueue)];
1195
- case 28:
1196
- _f.sent();
1197
- _f.label = 29;
1198
- case 29: return [3 /*break*/, 24];
1199
- case 30: return [3 /*break*/, 37];
1200
- case 31:
1201
- e_13_1 = _f.sent();
1202
- e_13 = { error: e_13_1 };
1203
- return [3 /*break*/, 37];
1204
- case 32:
1205
- _f.trys.push([32, , 35, 36]);
1206
- if (!(models_2_1 && !models_2_1.done && (_c = models_2.return))) return [3 /*break*/, 34];
1207
- return [4 /*yield*/, _c.call(models_2)];
1208
- case 33:
1209
- _f.sent();
1210
- _f.label = 34;
1211
- case 34: return [3 /*break*/, 36];
1212
- case 35:
1213
- if (e_13) throw e_13.error;
1214
- return [7 /*endfinally*/];
1215
- case 36: return [7 /*endfinally*/];
1216
- case 37: return [3 /*break*/, 40];
1217
- case 38:
1218
- // Intentionally blank
1219
- return [3 /*break*/, 40];
1220
- case 39: throw new Error("Invalid relation type " + relationType);
1221
- case 40: return [3 /*break*/, 1];
1222
- case 41: return [3 /*break*/, 48];
1223
- case 42:
1224
- e_11_1 = _f.sent();
1225
- e_11 = { error: e_11_1 };
1226
- return [3 /*break*/, 48];
1227
- case 43:
1228
- _f.trys.push([43, , 46, 47]);
1229
- if (!(relations_1_1 && !relations_1_1.done && (_a = relations_1.return))) return [3 /*break*/, 45];
1230
- return [4 /*yield*/, _a.call(relations_1)];
1231
- case 44:
1232
- _f.sent();
1233
- _f.label = 45;
1234
- case 45: return [3 /*break*/, 47];
1235
- case 46:
1236
- if (e_11) throw e_11.error;
1237
- return [7 /*endfinally*/];
1238
- case 47: return [7 /*endfinally*/];
1239
- case 48:
1240
- deleteQueue.push({
1241
- storeName: util_1.getStorename(nameSpace, srcModel),
1242
- items: models.map(function (record) {
1243
- return _this.modelInstanceCreator(_this.getModelConstructorByModelName(nameSpace, srcModel), record);
1244
- }),
1245
- });
1246
- return [2 /*return*/];
1247
- }
1248
- });
1249
- });
1250
- };
1251
- IndexedDBAdapter.prototype.clear = function () {
1252
- var _a;
1253
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1254
- return tslib_1.__generator(this, function (_b) {
1255
- switch (_b.label) {
1256
- case 0: return [4 /*yield*/, this.checkPrivate()];
1257
- case 1:
1258
- _b.sent();
1259
- (_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
1260
- return [4 /*yield*/, idb.deleteDB(this.dbName)];
1261
- case 2:
1262
- _b.sent();
1263
- this.db = undefined;
1264
- this.initPromise = undefined;
1265
- return [2 /*return*/];
1266
- }
1267
- });
1268
- });
1269
- };
1270
- IndexedDBAdapter.prototype.batchSave = function (modelConstructor, items) {
1271
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1272
- var result, storeName, txn, store, _loop_3, this_1, items_2, items_2_1, item, e_14_1;
1273
- var e_14, _a;
1274
- var _this = this;
1275
- return tslib_1.__generator(this, function (_b) {
1276
- switch (_b.label) {
1277
- case 0:
1278
- if (items.length === 0) {
1279
- return [2 /*return*/, []];
1280
- }
1281
- return [4 /*yield*/, this.checkPrivate()];
1282
- case 1:
1283
- _b.sent();
1284
- result = [];
1285
- storeName = this.getStorenameForModel(modelConstructor);
1286
- txn = this.db.transaction(storeName, 'readwrite');
1287
- store = txn.store;
1288
- _loop_3 = function (item) {
1289
- var namespaceName, modelName, model, connectedModels, keyValues, _deleted, index, key, instance;
1290
- return tslib_1.__generator(this, function (_a) {
1291
- switch (_a.label) {
1292
- case 0:
1293
- namespaceName = this_1.namespaceResolver(modelConstructor);
1294
- modelName = modelConstructor.name;
1295
- model = this_1.modelInstanceCreator(modelConstructor, item);
1296
- connectedModels = util_1.traverseModel(modelName, model, this_1.schema.namespaces[namespaceName], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
1297
- keyValues = this_1.getIndexKeyValuesFromModel(model);
1298
- _deleted = item._deleted;
1299
- index = store.index('byPk');
1300
- return [4 /*yield*/, index.getKey(this_1.canonicalKeyPath(keyValues))];
1301
- case 1:
1302
- key = _a.sent();
1303
- if (!!_deleted) return [3 /*break*/, 3];
1304
- instance = connectedModels.find(function (_a) {
1305
- var instance = _a.instance;
1306
- var instanceKeyValues = _this.getIndexKeyValuesFromModel(instance);
1307
- return util_1.keysEqual(instanceKeyValues, keyValues);
1308
- }).instance;
1309
- result.push([
1310
- instance,
1311
- key ? types_1.OpType.UPDATE : types_1.OpType.INSERT,
1312
- ]);
1313
- return [4 /*yield*/, store.put(instance, key)];
1314
- case 2:
1315
- _a.sent();
1316
- return [3 /*break*/, 5];
1317
- case 3:
1318
- result.push([item, types_1.OpType.DELETE]);
1319
- if (!key) return [3 /*break*/, 5];
1320
- return [4 /*yield*/, store.delete(key)];
1321
- case 4:
1322
- _a.sent();
1323
- _a.label = 5;
1324
- case 5: return [2 /*return*/];
1325
- }
1326
- });
1327
- };
1328
- this_1 = this;
1329
- _b.label = 2;
1330
- case 2:
1331
- _b.trys.push([2, 7, 8, 9]);
1332
- items_2 = tslib_1.__values(items), items_2_1 = items_2.next();
1333
- _b.label = 3;
1334
- case 3:
1335
- if (!!items_2_1.done) return [3 /*break*/, 6];
1336
- item = items_2_1.value;
1337
- return [5 /*yield**/, _loop_3(item)];
1338
- case 4:
1339
- _b.sent();
1340
- _b.label = 5;
1341
- case 5:
1342
- items_2_1 = items_2.next();
1343
- return [3 /*break*/, 3];
1344
- case 6: return [3 /*break*/, 9];
1345
- case 7:
1346
- e_14_1 = _b.sent();
1347
- e_14 = { error: e_14_1 };
1348
- return [3 /*break*/, 9];
1349
- case 8:
1350
- try {
1351
- if (items_2_1 && !items_2_1.done && (_a = items_2.return)) _a.call(items_2);
1352
- }
1353
- finally { if (e_14) throw e_14.error; }
1354
- return [7 /*endfinally*/];
1355
- case 9: return [4 /*yield*/, txn.done];
1356
- case 10:
1357
- _b.sent();
1358
- return [2 /*return*/, result];
1359
- }
1360
- });
1361
- });
1362
- };
1363
- IndexedDBAdapter.prototype.createObjectStoreForModel = function (db, namespaceName, storeName, modelName) {
1364
- var store = db.createObjectStore(storeName, {
1365
- autoIncrement: true,
1366
- });
1367
- var indexes = this.schema.namespaces[namespaceName].relationships[modelName].indexes;
1368
- indexes.forEach(function (_a) {
1369
- var _b = tslib_1.__read(_a, 3), idxName = _b[0], keyPath = _b[1], options = _b[2];
1370
- store.createIndex(idxName, keyPath, options);
1371
- });
1372
- return store;
1373
- };
1374
1071
  return IndexedDBAdapter;
1375
- }());
1072
+ }(StorageAdapterBase_1.StorageAdapterBase));
1376
1073
  exports.default = new IndexedDBAdapter();
1377
1074
  //# sourceMappingURL=IndexedDBAdapter.js.map