@aws-amplify/datastore 4.0.12 → 4.0.13-push-notification-dryrun.43

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 (111) hide show
  1. package/lib/datastore/datastore.d.ts +29 -3
  2. package/lib/datastore/datastore.js +308 -147
  3. package/lib/datastore/datastore.js.map +1 -1
  4. package/lib/predicates/index.d.ts +77 -7
  5. package/lib/predicates/index.js +142 -122
  6. package/lib/predicates/index.js.map +1 -1
  7. package/lib/predicates/next.d.ts +51 -10
  8. package/lib/predicates/next.js +111 -91
  9. package/lib/predicates/next.js.map +1 -1
  10. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +28 -30
  11. package/lib/storage/adapter/AsyncStorageAdapter.js +135 -532
  12. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  13. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  14. package/lib/storage/adapter/IndexedDBAdapter.d.ts +28 -29
  15. package/lib/storage/adapter/IndexedDBAdapter.js +490 -885
  16. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  17. package/lib/storage/adapter/StorageAdapterBase.d.ts +134 -0
  18. package/lib/storage/adapter/StorageAdapterBase.js +439 -0
  19. package/lib/storage/adapter/StorageAdapterBase.js.map +1 -0
  20. package/lib/storage/relationship.d.ts +9 -0
  21. package/lib/storage/relationship.js +9 -0
  22. package/lib/storage/relationship.js.map +1 -1
  23. package/lib/storage/storage.d.ts +1 -1
  24. package/lib/storage/storage.js +4 -3
  25. package/lib/storage/storage.js.map +1 -1
  26. package/lib/sync/index.d.ts +15 -1
  27. package/lib/sync/index.js +80 -13
  28. package/lib/sync/index.js.map +1 -1
  29. package/lib/sync/outbox.js +14 -7
  30. package/lib/sync/outbox.js.map +1 -1
  31. package/lib/sync/processors/mutation.d.ts +10 -1
  32. package/lib/sync/processors/mutation.js +33 -12
  33. package/lib/sync/processors/mutation.js.map +1 -1
  34. package/lib/sync/processors/subscription.d.ts +7 -1
  35. package/lib/sync/processors/subscription.js +196 -135
  36. package/lib/sync/processors/subscription.js.map +1 -1
  37. package/lib/sync/processors/sync.d.ts +1 -1
  38. package/lib/sync/processors/sync.js.map +1 -1
  39. package/lib/sync/utils.d.ts +66 -2
  40. package/lib/sync/utils.js +264 -16
  41. package/lib/sync/utils.js.map +1 -1
  42. package/lib/types.d.ts +9 -1
  43. package/lib/types.js.map +1 -1
  44. package/lib/util.d.ts +16 -0
  45. package/lib/util.js +31 -2
  46. package/lib/util.js.map +1 -1
  47. package/lib-esm/datastore/datastore.d.ts +29 -3
  48. package/lib-esm/datastore/datastore.js +310 -149
  49. package/lib-esm/datastore/datastore.js.map +1 -1
  50. package/lib-esm/predicates/index.d.ts +77 -7
  51. package/lib-esm/predicates/index.js +143 -123
  52. package/lib-esm/predicates/index.js.map +1 -1
  53. package/lib-esm/predicates/next.d.ts +51 -10
  54. package/lib-esm/predicates/next.js +111 -91
  55. package/lib-esm/predicates/next.js.map +1 -1
  56. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +28 -30
  57. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +138 -535
  58. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  59. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  60. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +28 -29
  61. package/lib-esm/storage/adapter/IndexedDBAdapter.js +489 -884
  62. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  63. package/lib-esm/storage/adapter/StorageAdapterBase.d.ts +134 -0
  64. package/lib-esm/storage/adapter/StorageAdapterBase.js +437 -0
  65. package/lib-esm/storage/adapter/StorageAdapterBase.js.map +1 -0
  66. package/lib-esm/storage/relationship.d.ts +9 -0
  67. package/lib-esm/storage/relationship.js +9 -0
  68. package/lib-esm/storage/relationship.js.map +1 -1
  69. package/lib-esm/storage/storage.d.ts +1 -1
  70. package/lib-esm/storage/storage.js +4 -3
  71. package/lib-esm/storage/storage.js.map +1 -1
  72. package/lib-esm/sync/index.d.ts +15 -1
  73. package/lib-esm/sync/index.js +82 -15
  74. package/lib-esm/sync/index.js.map +1 -1
  75. package/lib-esm/sync/outbox.js +14 -7
  76. package/lib-esm/sync/outbox.js.map +1 -1
  77. package/lib-esm/sync/processors/mutation.d.ts +10 -1
  78. package/lib-esm/sync/processors/mutation.js +33 -12
  79. package/lib-esm/sync/processors/mutation.js.map +1 -1
  80. package/lib-esm/sync/processors/subscription.d.ts +7 -1
  81. package/lib-esm/sync/processors/subscription.js +197 -136
  82. package/lib-esm/sync/processors/subscription.js.map +1 -1
  83. package/lib-esm/sync/processors/sync.d.ts +1 -1
  84. package/lib-esm/sync/processors/sync.js.map +1 -1
  85. package/lib-esm/sync/utils.d.ts +66 -2
  86. package/lib-esm/sync/utils.js +261 -18
  87. package/lib-esm/sync/utils.js.map +1 -1
  88. package/lib-esm/types.d.ts +9 -1
  89. package/lib-esm/types.js.map +1 -1
  90. package/lib-esm/util.d.ts +16 -0
  91. package/lib-esm/util.js +32 -3
  92. package/lib-esm/util.js.map +1 -1
  93. package/package.json +12 -11
  94. package/src/datastore/datastore.ts +288 -159
  95. package/src/predicates/index.ts +145 -175
  96. package/src/predicates/next.ts +114 -81
  97. package/src/storage/adapter/AsyncStorageAdapter.ts +97 -563
  98. package/src/storage/adapter/AsyncStorageDatabase.ts +2 -2
  99. package/src/storage/adapter/IndexedDBAdapter.ts +318 -770
  100. package/src/storage/adapter/StorageAdapterBase.ts +545 -0
  101. package/src/storage/relationship.ts +9 -0
  102. package/src/storage/storage.ts +12 -9
  103. package/src/sync/index.ts +108 -20
  104. package/src/sync/outbox.ts +17 -11
  105. package/src/sync/processors/mutation.ts +35 -4
  106. package/src/sync/processors/subscription.ts +124 -10
  107. package/src/sync/processors/sync.ts +4 -1
  108. package/src/sync/utils.ts +285 -15
  109. package/src/types.ts +15 -2
  110. package/src/util.ts +40 -1
  111. package/CHANGELOG.md +0 -904
@@ -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,111 +363,363 @@ 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) { return types_1.isPredicateObj(p) && p.field === key && p.operator === 'eq'; });
511
- predicateObj && keyValues.push(predicateObj.operand);
512
- };
513
- try {
514
- for (var keyPath_1 = tslib_1.__values(keyPath), keyPath_1_1 = keyPath_1.next(); !keyPath_1_1.done; keyPath_1_1 = keyPath_1.next()) {
515
- var key = keyPath_1_1.value;
516
- _loop_1(key);
517
- }
518
- }
519
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
520
- finally {
521
- try {
522
- if (keyPath_1_1 && !keyPath_1_1.done && (_a = keyPath_1.return)) _a.call(keyPath_1);
523
- }
524
- finally { if (e_3) throw e_3.error; }
525
- }
526
- return keyValues.length === keyPath.length ? keyValues : undefined;
527
- };
528
- /**
529
- * Tries to generate an index fetcher for the given predicates. Assumes
530
- * that the given predicate conditions are contained by an AND group and
531
- * should therefore all match a single record.
532
- *
533
- * @param storeName The table to query.
534
- * @param predicates The predicates to try to AND together.
535
- * @param transaction
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
+ //#region platform-specific helper methods
583
+ IndexedDBAdapter.prototype.checkPrivate = function () {
584
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
585
+ var isPrivate;
586
+ return tslib_1.__generator(this, function (_a) {
587
+ switch (_a.label) {
588
+ case 0: return [4 /*yield*/, util_1.isPrivateMode().then(function (isPrivate) {
589
+ return isPrivate;
590
+ })];
591
+ case 1:
592
+ isPrivate = _a.sent();
593
+ if (isPrivate) {
594
+ logger.error("IndexedDB not supported in this browser's private mode");
595
+ return [2 /*return*/, Promise.reject("IndexedDB not supported in this browser's private mode")];
596
+ }
597
+ else {
598
+ return [2 /*return*/, Promise.resolve()];
599
+ }
600
+ return [2 /*return*/];
601
+ }
602
+ });
603
+ });
604
+ };
605
+ /**
606
+ * Whether the browser's implementation of IndexedDB is coercing single-field
607
+ * indexes to a scalar key.
608
+ *
609
+ * If this returns `true`, we need to treat indexes containing a single field
610
+ * as scalars.
611
+ *
612
+ * See PR description for reference:
613
+ * https://github.com/aws-amplify/amplify-js/pull/10527
614
+ */
615
+ IndexedDBAdapter.prototype.setSafariCompatabilityMode = function () {
616
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
617
+ var _a;
618
+ return tslib_1.__generator(this, function (_b) {
619
+ switch (_b.label) {
620
+ case 0:
621
+ _a = this;
622
+ return [4 /*yield*/, util_1.isSafariCompatabilityMode()];
623
+ case 1:
624
+ _a.safariCompatabilityMode = _b.sent();
625
+ if (this.safariCompatabilityMode === true) {
626
+ logger.debug('IndexedDB Adapter is running in Safari Compatability Mode');
627
+ }
628
+ return [2 /*return*/];
629
+ }
630
+ });
631
+ });
632
+ };
633
+ IndexedDBAdapter.prototype.getNamespaceAndModelFromStorename = function (storeName) {
634
+ var _a = tslib_1.__read(storeName.split('_')), namespaceName = _a[0], modelNameArr = _a.slice(1);
635
+ return {
636
+ namespaceName: namespaceName,
637
+ modelName: modelNameArr.join('_'),
638
+ };
639
+ };
640
+ IndexedDBAdapter.prototype.createObjectStoreForModel = function (db, namespaceName, storeName, modelName) {
641
+ var store = db.createObjectStore(storeName, {
642
+ autoIncrement: true,
643
+ });
644
+ var indexes = this.schema.namespaces[namespaceName].relationships[modelName].indexes;
645
+ indexes.forEach(function (_a) {
646
+ var _b = tslib_1.__read(_a, 3), idxName = _b[0], keyPath = _b[1], options = _b[2];
647
+ store.createIndex(idxName, keyPath, options);
648
+ });
649
+ return store;
650
+ };
651
+ IndexedDBAdapter.prototype.getByKey = function (storeName, keyValue) {
652
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
653
+ return tslib_1.__generator(this, function (_a) {
654
+ switch (_a.label) {
655
+ case 0: return [4 /*yield*/, this._get(storeName, keyValue)];
656
+ case 1: return [2 /*return*/, _a.sent()];
657
+ }
658
+ });
659
+ });
660
+ };
661
+ IndexedDBAdapter.prototype.getAll = function (storeName) {
662
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
663
+ return tslib_1.__generator(this, function (_a) {
664
+ switch (_a.label) {
665
+ case 0: return [4 /*yield*/, this.db.getAll(storeName)];
666
+ case 1: return [2 /*return*/, _a.sent()];
667
+ }
668
+ });
669
+ });
670
+ };
671
+ /**
672
+ * Tries to generate an index fetcher for the given predicates. Assumes
673
+ * that the given predicate conditions are contained by an AND group and
674
+ * should therefore all match a single record.
675
+ *
676
+ * @param storeName The table to query.
677
+ * @param predicates The predicates to try to AND together.
678
+ * @param transaction
536
679
  */
537
680
  IndexedDBAdapter.prototype.matchingIndexQueries = function (storeName, predicates, transaction) {
538
- var e_4, _a, e_5, _b;
681
+ var e_6, _a, e_7, _b;
539
682
  var _this = this;
540
683
  // could be expanded later to include `exec()` and a `cardinality` estimate?
541
684
  var queries = [];
542
685
  var predicateIndex = new Map();
543
686
  try {
544
- for (var predicates_2 = tslib_1.__values(predicates), predicates_2_1 = predicates_2.next(); !predicates_2_1.done; predicates_2_1 = predicates_2.next()) {
545
- var predicate = predicates_2_1.value;
687
+ for (var predicates_1 = tslib_1.__values(predicates), predicates_1_1 = predicates_1.next(); !predicates_1_1.done; predicates_1_1 = predicates_1.next()) {
688
+ var predicate = predicates_1_1.value;
546
689
  predicateIndex.set(String(predicate.field), predicate);
547
690
  }
548
691
  }
549
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
692
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
550
693
  finally {
551
694
  try {
552
- if (predicates_2_1 && !predicates_2_1.done && (_a = predicates_2.return)) _a.call(predicates_2);
695
+ if (predicates_1_1 && !predicates_1_1.done && (_a = predicates_1.return)) _a.call(predicates_1);
553
696
  }
554
- finally { if (e_4) throw e_4.error; }
697
+ finally { if (e_6) throw e_6.error; }
555
698
  }
556
699
  var store = transaction.objectStore(storeName);
557
700
  var _loop_2 = function (name_1) {
558
- var e_6, _a;
701
+ var e_8, _a;
559
702
  var idx = store.index(name_1);
560
703
  var keypath = Array.isArray(idx.keyPath) ? idx.keyPath : [idx.keyPath];
561
704
  var matchingPredicateValues = [];
562
705
  try {
563
- 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()) {
706
+ 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()) {
564
707
  var field = keypath_1_1.value;
565
708
  var p = predicateIndex.get(field);
566
- if (p) {
567
- matchingPredicateValues.push(String(p.operand));
709
+ if (p && p.operand !== null && p.operand !== undefined) {
710
+ matchingPredicateValues.push(p.operand);
568
711
  }
569
712
  else {
570
713
  break;
571
714
  }
572
715
  }
573
716
  }
574
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
717
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
575
718
  finally {
576
719
  try {
577
720
  if (keypath_1_1 && !keypath_1_1.done && (_a = keypath_1.return)) _a.call(keypath_1);
578
721
  }
579
- finally { if (e_6) throw e_6.error; }
722
+ finally { if (e_8) throw e_8.error; }
580
723
  }
581
724
  // if we have a matching predicate field for each component of this index,
582
725
  // we can build a query for it. otherwise, we can't.
@@ -598,12 +741,12 @@ var IndexedDBAdapter = /** @class */ (function () {
598
741
  _loop_2(name_1);
599
742
  }
600
743
  }
601
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
744
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
602
745
  finally {
603
746
  try {
604
747
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
605
748
  }
606
- finally { if (e_5) throw e_5.error; }
749
+ finally { if (e_7) throw e_7.error; }
607
750
  }
608
751
  return queries;
609
752
  };
@@ -692,8 +835,8 @@ var IndexedDBAdapter = /** @class */ (function () {
692
835
  };
693
836
  IndexedDBAdapter.prototype.filterOnPredicate = function (storeName, predicates) {
694
837
  return tslib_1.__awaiter(this, void 0, void 0, function () {
695
- 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;
696
- var e_7, _b, e_8, _c;
838
+ 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;
839
+ var e_9, _b, e_10, _c;
697
840
  return tslib_1.__generator(this, function (_d) {
698
841
  switch (_d.label) {
699
842
  case 0:
@@ -725,18 +868,18 @@ var IndexedDBAdapter = /** @class */ (function () {
725
868
  case 6:
726
869
  resultGroup = _d.sent();
727
870
  try {
728
- 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()) {
871
+ 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()) {
729
872
  item = resultGroup_1_1.value;
730
873
  distinctificationString = JSON.stringify(item);
731
874
  distinctResults.set(distinctificationString, item);
732
875
  }
733
876
  }
734
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
877
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
735
878
  finally {
736
879
  try {
737
880
  if (resultGroup_1_1 && !resultGroup_1_1.done && (_c = resultGroup_1.return)) _c.call(resultGroup_1);
738
881
  }
739
- finally { if (e_8) throw e_8.error; }
882
+ finally { if (e_10) throw e_10.error; }
740
883
  }
741
884
  _d.label = 7;
742
885
  case 7:
@@ -744,14 +887,14 @@ var IndexedDBAdapter = /** @class */ (function () {
744
887
  return [3 /*break*/, 5];
745
888
  case 8: return [3 /*break*/, 11];
746
889
  case 9:
747
- e_7_1 = _d.sent();
748
- e_7 = { error: e_7_1 };
890
+ e_9_1 = _d.sent();
891
+ e_9 = { error: e_9_1 };
749
892
  return [3 /*break*/, 11];
750
893
  case 10:
751
894
  try {
752
895
  if (indexedQueries_1_1 && !indexedQueries_1_1.done && (_b = indexedQueries_1.return)) _b.call(indexedQueries_1);
753
896
  }
754
- finally { if (e_7) throw e_7.error; }
897
+ finally { if (e_9) throw e_9.error; }
755
898
  return [7 /*endfinally*/];
756
899
  case 11:
757
900
  // we could conceivably check for special conditions and return early here.
@@ -823,545 +966,7 @@ var IndexedDBAdapter = /** @class */ (function () {
823
966
  });
824
967
  });
825
968
  };
826
- IndexedDBAdapter.prototype.queryOne = function (modelConstructor, firstOrLast) {
827
- if (firstOrLast === void 0) { firstOrLast = types_1.QueryOne.FIRST; }
828
- return tslib_1.__awaiter(this, void 0, void 0, function () {
829
- var storeName, cursor, result;
830
- return tslib_1.__generator(this, function (_a) {
831
- switch (_a.label) {
832
- case 0: return [4 /*yield*/, this.checkPrivate()];
833
- case 1:
834
- _a.sent();
835
- storeName = this.getStorenameForModel(modelConstructor);
836
- return [4 /*yield*/, this.db
837
- .transaction([storeName], 'readonly')
838
- .objectStore(storeName)
839
- .openCursor(undefined, firstOrLast === types_1.QueryOne.FIRST ? 'next' : 'prev')];
840
- case 2:
841
- cursor = _a.sent();
842
- result = cursor ? cursor.value : undefined;
843
- return [2 /*return*/, result && this.modelInstanceCreator(modelConstructor, result)];
844
- }
845
- });
846
- });
847
- };
848
- IndexedDBAdapter.prototype.delete = function (modelOrModelConstructor, condition) {
849
- return tslib_1.__awaiter(this, void 0, void 0, function () {
850
- 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;
851
- return tslib_1.__generator(this, function (_b) {
852
- switch (_b.label) {
853
- case 0: return [4 /*yield*/, this.checkPrivate()];
854
- case 1:
855
- _b.sent();
856
- deleteQueue = [];
857
- if (!util_1.isModelConstructor(modelOrModelConstructor)) return [3 /*break*/, 9];
858
- modelConstructor = modelOrModelConstructor;
859
- nameSpace = this.namespaceResolver(modelConstructor);
860
- storeName = this.getStorenameForModel(modelConstructor);
861
- return [4 /*yield*/, this.query(modelConstructor, condition)];
862
- case 2:
863
- models = _b.sent();
864
- relations = this.schema.namespaces[nameSpace].relationships[modelConstructor.name]
865
- .relationTypes;
866
- if (!(condition !== undefined)) return [3 /*break*/, 5];
867
- return [4 /*yield*/, this.deleteTraverse(relations, models, modelConstructor.name, nameSpace, deleteQueue)];
868
- case 3:
869
- _b.sent();
870
- return [4 /*yield*/, this.deleteItem(deleteQueue)];
871
- case 4:
872
- _b.sent();
873
- deletedModels = deleteQueue.reduce(function (acc, _a) {
874
- var items = _a.items;
875
- return acc.concat(items);
876
- }, []);
877
- return [2 /*return*/, [models, deletedModels]];
878
- case 5: return [4 /*yield*/, this.deleteTraverse(relations, models, modelConstructor.name, nameSpace, deleteQueue)];
879
- case 6:
880
- _b.sent();
881
- // Delete all
882
- return [4 /*yield*/, this.db
883
- .transaction([storeName], 'readwrite')
884
- .objectStore(storeName)
885
- .clear()];
886
- case 7:
887
- // Delete all
888
- _b.sent();
889
- deletedModels = deleteQueue.reduce(function (acc, _a) {
890
- var items = _a.items;
891
- return acc.concat(items);
892
- }, []);
893
- return [2 /*return*/, [models, deletedModels]];
894
- case 8: return [3 /*break*/, 17];
895
- case 9:
896
- model = modelOrModelConstructor;
897
- modelConstructor = Object.getPrototypeOf(model)
898
- .constructor;
899
- namespaceName = this.namespaceResolver(modelConstructor);
900
- storeName = this.getStorenameForModel(modelConstructor);
901
- if (!condition) return [3 /*break*/, 13];
902
- tx = this.db.transaction([storeName], 'readwrite');
903
- store = tx.objectStore(storeName);
904
- keyValues = this.getIndexKeyValuesFromModel(model);
905
- return [4 /*yield*/, this._get(store, keyValues)];
906
- case 10:
907
- fromDB = _b.sent();
908
- if (fromDB === undefined) {
909
- msg = 'Model instance not found in storage';
910
- logger.warn(msg, { model: model });
911
- return [2 /*return*/, [[model], []]];
912
- }
913
- predicates = predicates_1.ModelPredicateCreator.getPredicates(condition);
914
- _a = predicates, predicateObjs = _a.predicates, type = _a.type;
915
- isValid = util_1.validatePredicate(fromDB, type, predicateObjs);
916
- if (!isValid) {
917
- msg = 'Conditional update failed';
918
- logger.error(msg, { model: fromDB, condition: predicateObjs });
919
- throw new Error(msg);
920
- }
921
- return [4 /*yield*/, tx.done];
922
- case 11:
923
- _b.sent();
924
- relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
925
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
926
- case 12:
927
- _b.sent();
928
- return [3 /*break*/, 15];
929
- case 13:
930
- relations = this.schema.namespaces[namespaceName].relationships[modelConstructor.name].relationTypes;
931
- return [4 /*yield*/, this.deleteTraverse(relations, [model], modelConstructor.name, namespaceName, deleteQueue)];
932
- case 14:
933
- _b.sent();
934
- _b.label = 15;
935
- case 15: return [4 /*yield*/, this.deleteItem(deleteQueue)];
936
- case 16:
937
- _b.sent();
938
- deletedModels = deleteQueue.reduce(function (acc, _a) {
939
- var items = _a.items;
940
- return acc.concat(items);
941
- }, []);
942
- return [2 /*return*/, [[model], deletedModels]];
943
- case 17: return [2 /*return*/];
944
- }
945
- });
946
- });
947
- };
948
- IndexedDBAdapter.prototype.deleteItem = function (deleteQueue) {
949
- var e_9, _a, e_10, _b;
950
- return tslib_1.__awaiter(this, void 0, void 0, function () {
951
- var connectionStoreNames, tx, _c, _d, deleteItem, storeName, items, store, items_1, items_1_1, item, key, keyValues, itemKey, e_10_1, e_9_1;
952
- return tslib_1.__generator(this, function (_e) {
953
- switch (_e.label) {
954
- case 0:
955
- connectionStoreNames = deleteQueue.map(function (_a) {
956
- var storeName = _a.storeName;
957
- return storeName;
958
- });
959
- tx = this.db.transaction(tslib_1.__spread(connectionStoreNames), 'readwrite');
960
- _e.label = 1;
961
- case 1:
962
- _e.trys.push([1, 22, 23, 28]);
963
- _c = tslib_1.__asyncValues(deleteQueue);
964
- _e.label = 2;
965
- case 2: return [4 /*yield*/, _c.next()];
966
- case 3:
967
- if (!(_d = _e.sent(), !_d.done)) return [3 /*break*/, 21];
968
- deleteItem = _d.value;
969
- storeName = deleteItem.storeName, items = deleteItem.items;
970
- store = tx.objectStore(storeName);
971
- _e.label = 4;
972
- case 4:
973
- _e.trys.push([4, 14, 15, 20]);
974
- items_1 = tslib_1.__asyncValues(items);
975
- _e.label = 5;
976
- case 5: return [4 /*yield*/, items_1.next()];
977
- case 6:
978
- if (!(items_1_1 = _e.sent(), !items_1_1.done)) return [3 /*break*/, 13];
979
- item = items_1_1.value;
980
- if (!item) return [3 /*break*/, 12];
981
- key = void 0;
982
- if (!(typeof item === 'object')) return [3 /*break*/, 8];
983
- keyValues = this.getIndexKeyValuesFromModel(item);
984
- return [4 /*yield*/, store
985
- .index('byPk')
986
- .getKey(this.canonicalKeyPath(keyValues))];
987
- case 7:
988
- key = _e.sent();
989
- return [3 /*break*/, 10];
990
- case 8:
991
- itemKey = item.toString();
992
- return [4 /*yield*/, store.index('byPk').getKey(itemKey)];
993
- case 9:
994
- key = _e.sent();
995
- _e.label = 10;
996
- case 10:
997
- if (!(key !== undefined)) return [3 /*break*/, 12];
998
- return [4 /*yield*/, store.delete(key)];
999
- case 11:
1000
- _e.sent();
1001
- _e.label = 12;
1002
- case 12: return [3 /*break*/, 5];
1003
- case 13: return [3 /*break*/, 20];
1004
- case 14:
1005
- e_10_1 = _e.sent();
1006
- e_10 = { error: e_10_1 };
1007
- return [3 /*break*/, 20];
1008
- case 15:
1009
- _e.trys.push([15, , 18, 19]);
1010
- if (!(items_1_1 && !items_1_1.done && (_b = items_1.return))) return [3 /*break*/, 17];
1011
- return [4 /*yield*/, _b.call(items_1)];
1012
- case 16:
1013
- _e.sent();
1014
- _e.label = 17;
1015
- case 17: return [3 /*break*/, 19];
1016
- case 18:
1017
- if (e_10) throw e_10.error;
1018
- return [7 /*endfinally*/];
1019
- case 19: return [7 /*endfinally*/];
1020
- case 20: return [3 /*break*/, 2];
1021
- case 21: return [3 /*break*/, 28];
1022
- case 22:
1023
- e_9_1 = _e.sent();
1024
- e_9 = { error: e_9_1 };
1025
- return [3 /*break*/, 28];
1026
- case 23:
1027
- _e.trys.push([23, , 26, 27]);
1028
- if (!(_d && !_d.done && (_a = _c.return))) return [3 /*break*/, 25];
1029
- return [4 /*yield*/, _a.call(_c)];
1030
- case 24:
1031
- _e.sent();
1032
- _e.label = 25;
1033
- case 25: return [3 /*break*/, 27];
1034
- case 26:
1035
- if (e_9) throw e_9.error;
1036
- return [7 /*endfinally*/];
1037
- case 27: return [7 /*endfinally*/];
1038
- case 28: return [2 /*return*/];
1039
- }
1040
- });
1041
- });
1042
- };
1043
- IndexedDBAdapter.prototype.deleteTraverse = function (relations, models, srcModel, nameSpace, deleteQueue) {
1044
- var relations_1, relations_1_1, models_1, models_1_1, models_2, models_2_1;
1045
- var e_11, _a, e_12, _b, e_13, _c;
1046
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1047
- 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;
1048
- var _this = this;
1049
- return tslib_1.__generator(this, function (_f) {
1050
- switch (_f.label) {
1051
- case 0:
1052
- _f.trys.push([0, 42, 43, 48]);
1053
- relations_1 = tslib_1.__asyncValues(relations);
1054
- _f.label = 1;
1055
- case 1: return [4 /*yield*/, relations_1.next()];
1056
- case 2:
1057
- if (!(relations_1_1 = _f.sent(), !relations_1_1.done)) return [3 /*break*/, 41];
1058
- rel = relations_1_1.value;
1059
- relationType = rel.relationType, modelName = rel.modelName, targetName = rel.targetName, targetNames = rel.targetNames, associatedWith = rel.associatedWith;
1060
- storeName = util_1.getStorename(nameSpace, modelName);
1061
- _d = relationType;
1062
- switch (_d) {
1063
- case 'HAS_ONE': return [3 /*break*/, 3];
1064
- case 'HAS_MANY': return [3 /*break*/, 23];
1065
- case 'BELONGS_TO': return [3 /*break*/, 38];
1066
- }
1067
- return [3 /*break*/, 39];
1068
- case 3:
1069
- _f.trys.push([3, 16, 17, 22]);
1070
- models_1 = tslib_1.__asyncValues(models);
1071
- _f.label = 4;
1072
- case 4: return [4 /*yield*/, models_1.next()];
1073
- case 5:
1074
- if (!(models_1_1 = _f.sent(), !models_1_1.done)) return [3 /*break*/, 15];
1075
- model = models_1_1.value;
1076
- hasOneIndex = 'byPk';
1077
- if (!(targetNames === null || targetNames === void 0 ? void 0 : targetNames.length)) return [3 /*break*/, 8];
1078
- values = targetNames
1079
- .filter(function (targetName) { var _a; return (_a = model[targetName]) !== null && _a !== void 0 ? _a : false; })
1080
- .map(function (targetName) { return model[targetName]; });
1081
- if (values.length === 0)
1082
- return [3 /*break*/, 15];
1083
- return [4 /*yield*/, this.db
1084
- .transaction(storeName, 'readwrite')
1085
- .objectStore(storeName)
1086
- .index(hasOneIndex)
1087
- .get(this.canonicalKeyPath(values))];
1088
- case 6:
1089
- recordToDelete = (_f.sent());
1090
- return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1091
- .relationTypes, recordToDelete ? [recordToDelete] : [], modelName, nameSpace, deleteQueue)];
1092
- case 7:
1093
- _f.sent();
1094
- return [3 /*break*/, 15];
1095
- case 8:
1096
- index = void 0;
1097
- values = void 0;
1098
- if (targetName && targetName in model) {
1099
- index = hasOneIndex;
1100
- value = model[targetName];
1101
- if (value === null)
1102
- return [3 /*break*/, 15];
1103
- values = [value];
1104
- }
1105
- else {
1106
- // backwards compatability for older versions of codegen that did not emit targetName for HAS_ONE relations
1107
- // TODO: can we deprecate this? it's been ~2 years since codegen started including targetName for HAS_ONE
1108
- // If we deprecate, we'll need to re-gen the MIPR in __tests__/schema.ts > newSchema
1109
- // otherwise some unit tests will fail
1110
- index = util_1.getIndex(this.schema.namespaces[nameSpace].relationships[modelName]
1111
- .relationTypes, srcModel);
1112
- values = this.getIndexKeyValuesFromModel(model);
1113
- }
1114
- if (!values || !index)
1115
- return [3 /*break*/, 15];
1116
- return [4 /*yield*/, this.db
1117
- .transaction(storeName, 'readwrite')
1118
- .objectStore(storeName)
1119
- .index(index)
1120
- .get(this.canonicalKeyPath(values))];
1121
- case 9:
1122
- recordToDelete = (_f.sent());
1123
- if (!recordToDelete) return [3 /*break*/, 11];
1124
- return [4 /*yield*/, this.load(nameSpace, modelName, [recordToDelete])];
1125
- case 10:
1126
- _e = _f.sent();
1127
- return [3 /*break*/, 12];
1128
- case 11:
1129
- _e = [];
1130
- _f.label = 12;
1131
- case 12:
1132
- modelsToDelete = _e;
1133
- return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1134
- .relationTypes, modelsToDelete, modelName, nameSpace, deleteQueue)];
1135
- case 13:
1136
- _f.sent();
1137
- _f.label = 14;
1138
- case 14: return [3 /*break*/, 4];
1139
- case 15: return [3 /*break*/, 22];
1140
- case 16:
1141
- e_12_1 = _f.sent();
1142
- e_12 = { error: e_12_1 };
1143
- return [3 /*break*/, 22];
1144
- case 17:
1145
- _f.trys.push([17, , 20, 21]);
1146
- if (!(models_1_1 && !models_1_1.done && (_b = models_1.return))) return [3 /*break*/, 19];
1147
- return [4 /*yield*/, _b.call(models_1)];
1148
- case 18:
1149
- _f.sent();
1150
- _f.label = 19;
1151
- case 19: return [3 /*break*/, 21];
1152
- case 20:
1153
- if (e_12) throw e_12.error;
1154
- return [7 /*endfinally*/];
1155
- case 21: return [7 /*endfinally*/];
1156
- case 22: return [3 /*break*/, 40];
1157
- case 23:
1158
- _f.trys.push([23, 31, 32, 37]);
1159
- models_2 = tslib_1.__asyncValues(models);
1160
- _f.label = 24;
1161
- case 24: return [4 /*yield*/, models_2.next()];
1162
- case 25:
1163
- if (!(models_2_1 = _f.sent(), !models_2_1.done)) return [3 /*break*/, 30];
1164
- model = models_2_1.value;
1165
- index =
1166
- // explicit bi-directional @hasMany and @manyToMany
1167
- util_1.getIndex(this.schema.namespaces[nameSpace].relationships[modelName]
1168
- .relationTypes, srcModel) ||
1169
- // uni and/or implicit @hasMany
1170
- util_1.getIndexFromAssociation(this.schema.namespaces[nameSpace].relationships[modelName]
1171
- .indexes, associatedWith);
1172
- keyValues = this.getIndexKeyValuesFromModel(model);
1173
- return [4 /*yield*/, this.db
1174
- .transaction(storeName, 'readwrite')
1175
- .objectStore(storeName)
1176
- .index(index)
1177
- .getAll(this.canonicalKeyPath(keyValues))];
1178
- case 26:
1179
- childRecords = _f.sent();
1180
- return [4 /*yield*/, this.load(nameSpace, modelName, childRecords)];
1181
- case 27:
1182
- childModels = _f.sent();
1183
- return [4 /*yield*/, this.deleteTraverse(this.schema.namespaces[nameSpace].relationships[modelName]
1184
- .relationTypes, childModels, modelName, nameSpace, deleteQueue)];
1185
- case 28:
1186
- _f.sent();
1187
- _f.label = 29;
1188
- case 29: return [3 /*break*/, 24];
1189
- case 30: return [3 /*break*/, 37];
1190
- case 31:
1191
- e_13_1 = _f.sent();
1192
- e_13 = { error: e_13_1 };
1193
- return [3 /*break*/, 37];
1194
- case 32:
1195
- _f.trys.push([32, , 35, 36]);
1196
- if (!(models_2_1 && !models_2_1.done && (_c = models_2.return))) return [3 /*break*/, 34];
1197
- return [4 /*yield*/, _c.call(models_2)];
1198
- case 33:
1199
- _f.sent();
1200
- _f.label = 34;
1201
- case 34: return [3 /*break*/, 36];
1202
- case 35:
1203
- if (e_13) throw e_13.error;
1204
- return [7 /*endfinally*/];
1205
- case 36: return [7 /*endfinally*/];
1206
- case 37: return [3 /*break*/, 40];
1207
- case 38:
1208
- // Intentionally blank
1209
- return [3 /*break*/, 40];
1210
- case 39: throw new Error("Invalid relation type " + relationType);
1211
- case 40: return [3 /*break*/, 1];
1212
- case 41: return [3 /*break*/, 48];
1213
- case 42:
1214
- e_11_1 = _f.sent();
1215
- e_11 = { error: e_11_1 };
1216
- return [3 /*break*/, 48];
1217
- case 43:
1218
- _f.trys.push([43, , 46, 47]);
1219
- if (!(relations_1_1 && !relations_1_1.done && (_a = relations_1.return))) return [3 /*break*/, 45];
1220
- return [4 /*yield*/, _a.call(relations_1)];
1221
- case 44:
1222
- _f.sent();
1223
- _f.label = 45;
1224
- case 45: return [3 /*break*/, 47];
1225
- case 46:
1226
- if (e_11) throw e_11.error;
1227
- return [7 /*endfinally*/];
1228
- case 47: return [7 /*endfinally*/];
1229
- case 48:
1230
- deleteQueue.push({
1231
- storeName: util_1.getStorename(nameSpace, srcModel),
1232
- items: models.map(function (record) {
1233
- return _this.modelInstanceCreator(_this.getModelConstructorByModelName(nameSpace, srcModel), record);
1234
- }),
1235
- });
1236
- return [2 /*return*/];
1237
- }
1238
- });
1239
- });
1240
- };
1241
- IndexedDBAdapter.prototype.clear = function () {
1242
- var _a;
1243
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1244
- return tslib_1.__generator(this, function (_b) {
1245
- switch (_b.label) {
1246
- case 0: return [4 /*yield*/, this.checkPrivate()];
1247
- case 1:
1248
- _b.sent();
1249
- (_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
1250
- return [4 /*yield*/, idb.deleteDB(this.dbName)];
1251
- case 2:
1252
- _b.sent();
1253
- this.db = undefined;
1254
- this.initPromise = undefined;
1255
- return [2 /*return*/];
1256
- }
1257
- });
1258
- });
1259
- };
1260
- IndexedDBAdapter.prototype.batchSave = function (modelConstructor, items) {
1261
- return tslib_1.__awaiter(this, void 0, void 0, function () {
1262
- var result, storeName, txn, store, _loop_3, this_1, items_2, items_2_1, item, e_14_1;
1263
- var e_14, _a;
1264
- var _this = this;
1265
- return tslib_1.__generator(this, function (_b) {
1266
- switch (_b.label) {
1267
- case 0:
1268
- if (items.length === 0) {
1269
- return [2 /*return*/, []];
1270
- }
1271
- return [4 /*yield*/, this.checkPrivate()];
1272
- case 1:
1273
- _b.sent();
1274
- result = [];
1275
- storeName = this.getStorenameForModel(modelConstructor);
1276
- txn = this.db.transaction(storeName, 'readwrite');
1277
- store = txn.store;
1278
- _loop_3 = function (item) {
1279
- var namespaceName, modelName, model, connectedModels, keyValues, _deleted, index, key, instance;
1280
- return tslib_1.__generator(this, function (_a) {
1281
- switch (_a.label) {
1282
- case 0:
1283
- namespaceName = this_1.namespaceResolver(modelConstructor);
1284
- modelName = modelConstructor.name;
1285
- model = this_1.modelInstanceCreator(modelConstructor, item);
1286
- connectedModels = util_1.traverseModel(modelName, model, this_1.schema.namespaces[namespaceName], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
1287
- keyValues = this_1.getIndexKeyValuesFromModel(model);
1288
- _deleted = item._deleted;
1289
- index = store.index('byPk');
1290
- return [4 /*yield*/, index.getKey(this_1.canonicalKeyPath(keyValues))];
1291
- case 1:
1292
- key = _a.sent();
1293
- if (!!_deleted) return [3 /*break*/, 3];
1294
- instance = connectedModels.find(function (_a) {
1295
- var instance = _a.instance;
1296
- var instanceKeyValues = _this.getIndexKeyValuesFromModel(instance);
1297
- return util_1.keysEqual(instanceKeyValues, keyValues);
1298
- }).instance;
1299
- result.push([
1300
- instance,
1301
- key ? types_1.OpType.UPDATE : types_1.OpType.INSERT,
1302
- ]);
1303
- return [4 /*yield*/, store.put(instance, key)];
1304
- case 2:
1305
- _a.sent();
1306
- return [3 /*break*/, 5];
1307
- case 3:
1308
- result.push([item, types_1.OpType.DELETE]);
1309
- if (!key) return [3 /*break*/, 5];
1310
- return [4 /*yield*/, store.delete(key)];
1311
- case 4:
1312
- _a.sent();
1313
- _a.label = 5;
1314
- case 5: return [2 /*return*/];
1315
- }
1316
- });
1317
- };
1318
- this_1 = this;
1319
- _b.label = 2;
1320
- case 2:
1321
- _b.trys.push([2, 7, 8, 9]);
1322
- items_2 = tslib_1.__values(items), items_2_1 = items_2.next();
1323
- _b.label = 3;
1324
- case 3:
1325
- if (!!items_2_1.done) return [3 /*break*/, 6];
1326
- item = items_2_1.value;
1327
- return [5 /*yield**/, _loop_3(item)];
1328
- case 4:
1329
- _b.sent();
1330
- _b.label = 5;
1331
- case 5:
1332
- items_2_1 = items_2.next();
1333
- return [3 /*break*/, 3];
1334
- case 6: return [3 /*break*/, 9];
1335
- case 7:
1336
- e_14_1 = _b.sent();
1337
- e_14 = { error: e_14_1 };
1338
- return [3 /*break*/, 9];
1339
- case 8:
1340
- try {
1341
- if (items_2_1 && !items_2_1.done && (_a = items_2.return)) _a.call(items_2);
1342
- }
1343
- finally { if (e_14) throw e_14.error; }
1344
- return [7 /*endfinally*/];
1345
- case 9: return [4 /*yield*/, txn.done];
1346
- case 10:
1347
- _b.sent();
1348
- return [2 /*return*/, result];
1349
- }
1350
- });
1351
- });
1352
- };
1353
- IndexedDBAdapter.prototype.createObjectStoreForModel = function (db, namespaceName, storeName, modelName) {
1354
- var store = db.createObjectStore(storeName, {
1355
- autoIncrement: true,
1356
- });
1357
- var indexes = this.schema.namespaces[namespaceName].relationships[modelName].indexes;
1358
- indexes.forEach(function (_a) {
1359
- var _b = tslib_1.__read(_a, 3), idxName = _b[0], keyPath = _b[1], options = _b[2];
1360
- store.createIndex(idxName, keyPath, options);
1361
- });
1362
- return store;
1363
- };
1364
969
  return IndexedDBAdapter;
1365
- }());
970
+ }(StorageAdapterBase_1.StorageAdapterBase));
1366
971
  exports.default = new IndexedDBAdapter();
1367
972
  //# sourceMappingURL=IndexedDBAdapter.js.map