@aws-amplify/datastore 5.0.1-api-v6-models.c1977f8.0 → 5.0.1-api-v6-models.891fe0d.0
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.
- package/lib/authModeStrategies/defaultAuthStrategy.js +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.js +29 -105
- package/lib/datastore/datastore.js +887 -1370
- package/lib/index.js +1 -1
- package/lib/predicates/index.js +53 -102
- package/lib/predicates/next.js +310 -557
- package/lib/predicates/sort.js +24 -27
- package/lib/ssr/index.js +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js +115 -449
- package/lib/storage/adapter/AsyncStorageDatabase.js +215 -480
- package/lib/storage/adapter/InMemoryStore.js +27 -101
- package/lib/storage/adapter/InMemoryStore.native.js +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.js +441 -1002
- package/lib/storage/adapter/StorageAdapterBase.js +177 -396
- package/lib/storage/adapter/getDefaultAdapter/index.js +5 -6
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -2
- package/lib/storage/relationship.js +174 -260
- package/lib/storage/storage.js +244 -507
- package/lib/sync/datastoreConnectivity.js +29 -84
- package/lib/sync/datastoreReachability/index.js +1 -1
- package/lib/sync/datastoreReachability/index.native.js +2 -2
- package/lib/sync/index.js +512 -885
- package/lib/sync/merger.js +30 -133
- package/lib/sync/outbox.js +147 -302
- package/lib/sync/processors/errorMaps.js +30 -80
- package/lib/sync/processors/mutation.js +331 -579
- package/lib/sync/processors/subscription.js +268 -428
- package/lib/sync/processors/sync.js +276 -464
- package/lib/sync/utils.js +248 -393
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.js +16 -58
- package/lib/util.js +335 -575
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +27 -103
- package/lib-esm/datastore/datastore.js +874 -1359
- package/lib-esm/index.js +6 -6
- package/lib-esm/predicates/index.js +54 -104
- package/lib-esm/predicates/next.js +306 -555
- package/lib-esm/predicates/sort.js +24 -27
- package/lib-esm/ssr/index.js +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -446
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -477
- package/lib-esm/storage/adapter/InMemoryStore.js +27 -102
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +436 -997
- package/lib-esm/storage/adapter/StorageAdapterBase.js +172 -392
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -3
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -1
- package/lib-esm/storage/relationship.js +173 -260
- package/lib-esm/storage/storage.js +236 -499
- package/lib-esm/sync/datastoreConnectivity.js +26 -82
- package/lib-esm/sync/datastoreReachability/index.js +1 -1
- package/lib-esm/sync/datastoreReachability/index.native.js +1 -1
- package/lib-esm/sync/index.js +498 -872
- package/lib-esm/sync/merger.js +28 -131
- package/lib-esm/sync/outbox.js +143 -298
- package/lib-esm/sync/processors/errorMaps.js +32 -82
- package/lib-esm/sync/processors/mutation.js +324 -572
- package/lib-esm/sync/processors/subscription.js +258 -418
- package/lib-esm/sync/processors/sync.js +269 -457
- package/lib-esm/sync/utils.js +245 -390
- package/lib-esm/tsconfig.tsbuildinfo +1 -1
- package/lib-esm/types.js +16 -59
- package/lib-esm/util.js +335 -577
- package/package.json +12 -12
- package/src/datastore/datastore.ts +4 -3
- package/src/storage/adapter/getDefaultAdapter/index.ts +1 -3
- package/src/sync/processors/mutation.ts +1 -1
- package/src/sync/processors/sync.ts +1 -1
- package/src/sync/utils.ts +1 -1
- package/src/util.ts +44 -6
|
@@ -1,156 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __assign = (this && this.__assign) || function () {
|
|
18
|
-
__assign = Object.assign || function(t) {
|
|
19
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
-
s = arguments[i];
|
|
21
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
-
t[p] = s[p];
|
|
23
|
-
}
|
|
24
|
-
return t;
|
|
25
|
-
};
|
|
26
|
-
return __assign.apply(this, arguments);
|
|
27
|
-
};
|
|
28
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
29
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
30
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
31
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
32
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
33
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
38
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
39
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
40
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
41
|
-
function step(op) {
|
|
42
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
43
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
44
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
45
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
46
|
-
switch (op[0]) {
|
|
47
|
-
case 0: case 1: t = op; break;
|
|
48
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
49
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
50
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
51
|
-
default:
|
|
52
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
53
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
54
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
55
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
56
|
-
if (t[2]) _.ops.pop();
|
|
57
|
-
_.trys.pop(); continue;
|
|
58
|
-
}
|
|
59
|
-
op = body.call(thisArg, _);
|
|
60
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
61
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
65
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
66
|
-
var m = o[Symbol.asyncIterator], i;
|
|
67
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
68
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
69
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
70
|
-
};
|
|
71
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
72
|
-
var t = {};
|
|
73
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
74
|
-
t[p] = s[p];
|
|
75
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
76
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
77
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
78
|
-
t[p[i]] = s[p[i]];
|
|
79
|
-
}
|
|
80
|
-
return t;
|
|
81
|
-
};
|
|
82
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
83
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
84
|
-
if (!m) return o;
|
|
85
|
-
var i = m.call(o), r, ar = [], e;
|
|
86
|
-
try {
|
|
87
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
88
|
-
}
|
|
89
|
-
catch (error) { e = { error: error }; }
|
|
90
|
-
finally {
|
|
91
|
-
try {
|
|
92
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
93
|
-
}
|
|
94
|
-
finally { if (e) throw e.error; }
|
|
95
|
-
}
|
|
96
|
-
return ar;
|
|
97
|
-
};
|
|
98
|
-
var __values = (this && this.__values) || function(o) {
|
|
99
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
100
|
-
if (m) return m.call(o);
|
|
101
|
-
if (o && typeof o.length === "number") return {
|
|
102
|
-
next: function () {
|
|
103
|
-
if (o && i >= o.length) o = void 0;
|
|
104
|
-
return { value: o && o[i++], done: !o };
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
108
|
-
};
|
|
109
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
110
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
111
|
-
if (ar || !(i in from)) {
|
|
112
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
113
|
-
ar[i] = from[i];
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
117
|
-
};
|
|
118
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
119
3
|
exports.DataStore = exports.initSchema = exports.DataStoreClass = exports.AsyncCollection = exports.AsyncItem = exports.getAttachment = exports.attached = exports.syncClasses = void 0;
|
|
120
4
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
121
5
|
// SPDX-License-Identifier: Apache-2.0
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
6
|
+
const internals_1 = require("@aws-amplify/api/internals");
|
|
7
|
+
const core_1 = require("@aws-amplify/core");
|
|
8
|
+
const immer_1 = require("immer");
|
|
9
|
+
const utils_1 = require("@aws-amplify/core/internals/utils");
|
|
10
|
+
const rxjs_1 = require("rxjs");
|
|
11
|
+
const authModeStrategies_1 = require("../authModeStrategies");
|
|
12
|
+
const predicates_1 = require("../predicates");
|
|
13
|
+
const storage_1 = require("../storage/storage");
|
|
14
|
+
const relationship_1 = require("../storage/relationship");
|
|
15
|
+
const sync_1 = require("../sync");
|
|
16
|
+
const types_1 = require("../types");
|
|
17
|
+
const util_1 = require("../util");
|
|
18
|
+
const next_1 = require("../predicates/next");
|
|
19
|
+
const utils_2 = require("../sync/utils");
|
|
20
|
+
const utils_3 = require("@aws-amplify/core/internals/utils");
|
|
137
21
|
(0, immer_1.setAutoFreeze)(true);
|
|
138
22
|
(0, immer_1.enablePatches)();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
23
|
+
const logger = new core_1.ConsoleLogger('DataStore');
|
|
24
|
+
const ulid = (0, util_1.monotonicUlidFactory)(Date.now());
|
|
25
|
+
const SETTING_SCHEMA_VERSION = 'schemaVersion';
|
|
26
|
+
let schema;
|
|
27
|
+
const modelNamespaceMap = new WeakMap();
|
|
144
28
|
/**
|
|
145
29
|
* Stores data for crafting the correct update mutation input for a model.
|
|
146
30
|
*
|
|
147
31
|
* - `Patch[]` - array of changed fields and metadata.
|
|
148
32
|
* - `PersistentModel` - the source model, used for diffing object-type fields.
|
|
149
33
|
*/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
34
|
+
const modelPatchesMap = new WeakMap();
|
|
35
|
+
const getModelDefinition = (modelConstructor) => {
|
|
36
|
+
const namespace = modelNamespaceMap.get(modelConstructor);
|
|
37
|
+
const definition = namespace
|
|
154
38
|
? schema.namespaces[namespace].models[modelConstructor.name]
|
|
155
39
|
: undefined;
|
|
156
40
|
return definition;
|
|
@@ -161,13 +45,13 @@ var getModelDefinition = function (modelConstructor) {
|
|
|
161
45
|
*
|
|
162
46
|
* @param obj The object to test.
|
|
163
47
|
*/
|
|
164
|
-
|
|
48
|
+
const isValidModelConstructor = (obj) => {
|
|
165
49
|
return (0, util_1.isModelConstructor)(obj) && modelNamespaceMap.has(obj);
|
|
166
50
|
};
|
|
167
|
-
|
|
168
|
-
|
|
51
|
+
const namespaceResolver = modelConstructor => {
|
|
52
|
+
const resolver = modelNamespaceMap.get(modelConstructor);
|
|
169
53
|
if (!resolver) {
|
|
170
|
-
throw new Error(
|
|
54
|
+
throw new Error(`Namespace Resolver for '${modelConstructor.name}' not found! This is probably a bug in '@amplify-js/datastore'.`);
|
|
171
55
|
}
|
|
172
56
|
return resolver;
|
|
173
57
|
};
|
|
@@ -190,13 +74,13 @@ var namespaceResolver = function (modelConstructor) {
|
|
|
190
74
|
*
|
|
191
75
|
* @param modelConstructor The model the predicate will query.
|
|
192
76
|
*/
|
|
193
|
-
|
|
77
|
+
const buildSeedPredicate = (modelConstructor) => {
|
|
194
78
|
if (!modelConstructor)
|
|
195
79
|
throw new Error('Missing modelConstructor');
|
|
196
|
-
|
|
80
|
+
const modelSchema = getModelDefinition(modelConstructor);
|
|
197
81
|
if (!modelSchema)
|
|
198
82
|
throw new Error('Missing modelSchema');
|
|
199
|
-
|
|
83
|
+
const pks = (0, util_1.extractPrimaryKeyFieldNames)(modelSchema);
|
|
200
84
|
if (!pks)
|
|
201
85
|
throw new Error('Could not determine PK');
|
|
202
86
|
return (0, next_1.recursivePredicateFor)({
|
|
@@ -205,13 +89,13 @@ var buildSeedPredicate = function (modelConstructor) {
|
|
|
205
89
|
pkField: pks,
|
|
206
90
|
});
|
|
207
91
|
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
92
|
+
let userClasses;
|
|
93
|
+
let dataStoreClasses;
|
|
94
|
+
let storageClasses;
|
|
211
95
|
/**
|
|
212
96
|
* Maps a model to its related models for memoization/immutability.
|
|
213
97
|
*/
|
|
214
|
-
|
|
98
|
+
const modelInstanceAssociationsMap = new WeakMap();
|
|
215
99
|
/**
|
|
216
100
|
* Describes whether and to what a model is attached for lazy loading purposes.
|
|
217
101
|
*/
|
|
@@ -239,7 +123,7 @@ var ModelAttachment;
|
|
|
239
123
|
* If `Deatched`, the model's lazy properties will only ever return properties
|
|
240
124
|
* from memory provided at construction time.
|
|
241
125
|
*/
|
|
242
|
-
|
|
126
|
+
const attachedModelInstances = new WeakMap();
|
|
243
127
|
/**
|
|
244
128
|
* Registers a model instance against a data source (DataStore, API, or
|
|
245
129
|
* Detached/None).
|
|
@@ -253,7 +137,7 @@ var attachedModelInstances = new WeakMap();
|
|
|
253
137
|
*/
|
|
254
138
|
function attached(result, attachment) {
|
|
255
139
|
if (Array.isArray(result)) {
|
|
256
|
-
result.map(
|
|
140
|
+
result.map(record => attached(record, attachment));
|
|
257
141
|
}
|
|
258
142
|
else {
|
|
259
143
|
result && attachedModelInstances.set(result, attachment);
|
|
@@ -268,70 +152,66 @@ exports.attached = attached;
|
|
|
268
152
|
*
|
|
269
153
|
* @param instance A model instance
|
|
270
154
|
*/
|
|
271
|
-
|
|
155
|
+
const getAttachment = (instance) => {
|
|
272
156
|
return attachedModelInstances.has(instance)
|
|
273
157
|
? attachedModelInstances.get(instance)
|
|
274
158
|
: ModelAttachment.Detached;
|
|
275
159
|
};
|
|
276
160
|
exports.getAttachment = getAttachment;
|
|
277
|
-
|
|
278
|
-
var _a;
|
|
161
|
+
const initSchema = (userSchema) => {
|
|
279
162
|
if (schema !== undefined) {
|
|
280
163
|
console.warn('The schema has already been initialized');
|
|
281
164
|
return userClasses;
|
|
282
165
|
}
|
|
283
166
|
logger.log('validating schema', { schema: userSchema });
|
|
284
167
|
checkSchemaCodegenVersion(userSchema.codegenVersion);
|
|
285
|
-
|
|
168
|
+
const internalUserNamespace = {
|
|
169
|
+
name: util_1.USER,
|
|
170
|
+
...userSchema,
|
|
171
|
+
};
|
|
286
172
|
logger.log('DataStore', 'Init models');
|
|
287
173
|
userClasses = createTypeClasses(internalUserNamespace);
|
|
288
174
|
logger.log('DataStore', 'Models initialized');
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
175
|
+
const dataStoreNamespace = getNamespace();
|
|
176
|
+
const storageNamespace = storage_1.ExclusiveStorage.getNamespace();
|
|
177
|
+
const syncNamespace = sync_1.SyncEngine.getNamespace();
|
|
292
178
|
dataStoreClasses = createTypeClasses(dataStoreNamespace);
|
|
293
179
|
storageClasses = createTypeClasses(storageNamespace);
|
|
294
180
|
exports.syncClasses = createTypeClasses(syncNamespace);
|
|
295
181
|
schema = {
|
|
296
|
-
namespaces:
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
182
|
+
namespaces: {
|
|
183
|
+
[dataStoreNamespace.name]: dataStoreNamespace,
|
|
184
|
+
[internalUserNamespace.name]: internalUserNamespace,
|
|
185
|
+
[storageNamespace.name]: storageNamespace,
|
|
186
|
+
[syncNamespace.name]: syncNamespace,
|
|
187
|
+
},
|
|
302
188
|
version: userSchema.version,
|
|
303
189
|
codegenVersion: userSchema.codegenVersion,
|
|
304
190
|
};
|
|
305
|
-
Object.keys(schema.namespaces).forEach(
|
|
306
|
-
|
|
307
|
-
var _b = __read((0, util_1.establishRelationAndKeys)(schema.namespaces[namespace]), 2), relations = _b[0], keys = _b[1];
|
|
191
|
+
Object.keys(schema.namespaces).forEach(namespace => {
|
|
192
|
+
const [relations, keys] = (0, util_1.establishRelationAndKeys)(schema.namespaces[namespace]);
|
|
308
193
|
schema.namespaces[namespace].relationships = relations;
|
|
309
194
|
schema.namespaces[namespace].keys = keys;
|
|
310
|
-
|
|
311
|
-
Object.values(schema.namespaces[namespace].models).forEach(
|
|
312
|
-
|
|
313
|
-
var connectedModels = [];
|
|
195
|
+
const modelAssociations = new Map();
|
|
196
|
+
Object.values(schema.namespaces[namespace].models).forEach(model => {
|
|
197
|
+
const connectedModels = [];
|
|
314
198
|
Object.values(model.fields)
|
|
315
|
-
.filter(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
})
|
|
320
|
-
.forEach(function (field) {
|
|
321
|
-
return connectedModels.push(field.type.model);
|
|
322
|
-
});
|
|
199
|
+
.filter(field => field.association &&
|
|
200
|
+
field.association.connectionType === 'BELONGS_TO' &&
|
|
201
|
+
field.type.model !== model.name)
|
|
202
|
+
.forEach(field => connectedModels.push(field.type.model));
|
|
323
203
|
modelAssociations.set(model.name, connectedModels);
|
|
324
204
|
// Precompute model info (such as pk fields) so that downstream schema consumers
|
|
325
205
|
// (such as predicate builders) don't have to reach back into "DataStore" space
|
|
326
206
|
// to go looking for it.
|
|
327
|
-
Object.values(model.fields).forEach(
|
|
328
|
-
|
|
207
|
+
Object.values(model.fields).forEach(field => {
|
|
208
|
+
const relatedModel = userClasses[field.type.model];
|
|
329
209
|
if ((0, util_1.isModelConstructor)(relatedModel)) {
|
|
330
210
|
Object.defineProperty(field.type, 'modelConstructor', {
|
|
331
|
-
get:
|
|
332
|
-
|
|
211
|
+
get: () => {
|
|
212
|
+
const relatedModelDefinition = getModelDefinition(relatedModel);
|
|
333
213
|
if (!relatedModelDefinition)
|
|
334
|
-
throw new Error(
|
|
214
|
+
throw new Error(`Could not find model definition for ${relatedModel.name}`);
|
|
335
215
|
return {
|
|
336
216
|
builder: relatedModel,
|
|
337
217
|
schema: relatedModelDefinition,
|
|
@@ -344,44 +224,27 @@ var initSchema = function (userSchema) {
|
|
|
344
224
|
// compatibility with legacy/pre-PK codegen for lazy loading to inject
|
|
345
225
|
// index fields into the model definition.
|
|
346
226
|
// definition.cloudFields = { ...definition.fields };
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
for (
|
|
351
|
-
|
|
352
|
-
try {
|
|
353
|
-
for (var _c = (e_3 = void 0, __values(index[1])), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
354
|
-
var indexField = _d.value;
|
|
355
|
-
indexFields.add(indexField);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
359
|
-
finally {
|
|
360
|
-
try {
|
|
361
|
-
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
|
|
362
|
-
}
|
|
363
|
-
finally { if (e_3) throw e_3.error; }
|
|
364
|
-
}
|
|
227
|
+
const indexes = schema.namespaces[namespace].relationships[model.name].indexes;
|
|
228
|
+
const indexFields = new Set();
|
|
229
|
+
for (const index of indexes) {
|
|
230
|
+
for (const indexField of index[1]) {
|
|
231
|
+
indexFields.add(indexField);
|
|
365
232
|
}
|
|
366
233
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
type: 'ID',
|
|
379
|
-
isArray: false,
|
|
380
|
-
},
|
|
381
|
-
]; }))), model.fields);
|
|
234
|
+
model.allFields = {
|
|
235
|
+
...Object.fromEntries([...indexFields.values()].map(name => [
|
|
236
|
+
name,
|
|
237
|
+
{
|
|
238
|
+
name,
|
|
239
|
+
type: 'ID',
|
|
240
|
+
isArray: false,
|
|
241
|
+
},
|
|
242
|
+
])),
|
|
243
|
+
...model.fields,
|
|
244
|
+
};
|
|
382
245
|
});
|
|
383
|
-
|
|
384
|
-
|
|
246
|
+
const result = new Map();
|
|
247
|
+
let count = 1000;
|
|
385
248
|
while (true && count > 0) {
|
|
386
249
|
if (modelAssociations.size === 0) {
|
|
387
250
|
break;
|
|
@@ -390,23 +253,13 @@ var initSchema = function (userSchema) {
|
|
|
390
253
|
if (count === 0) {
|
|
391
254
|
throw new Error('Models are not topologically sortable. Please verify your schema.');
|
|
392
255
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (parents === null || parents === void 0 ? void 0 : parents.every(function (x) { return result.has(x); })) {
|
|
398
|
-
result.set(modelName, parents);
|
|
399
|
-
}
|
|
256
|
+
for (const modelName of Array.from(modelAssociations.keys())) {
|
|
257
|
+
const parents = modelAssociations.get(modelName);
|
|
258
|
+
if (parents?.every(x => result.has(x))) {
|
|
259
|
+
result.set(modelName, parents);
|
|
400
260
|
}
|
|
401
261
|
}
|
|
402
|
-
|
|
403
|
-
finally {
|
|
404
|
-
try {
|
|
405
|
-
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
406
|
-
}
|
|
407
|
-
finally { if (e_1) throw e_1.error; }
|
|
408
|
-
}
|
|
409
|
-
Array.from(result.keys()).forEach(function (x) { return modelAssociations.delete(x); });
|
|
262
|
+
Array.from(result.keys()).forEach(x => modelAssociations.delete(x));
|
|
410
263
|
}
|
|
411
264
|
schema.namespaces[namespace].modelTopologicalOrdering = result;
|
|
412
265
|
});
|
|
@@ -422,9 +275,9 @@ exports.initSchema = initSchema;
|
|
|
422
275
|
* Currently this only needs to be called in `start()` and `clear()` because
|
|
423
276
|
* all other functions will call start first.
|
|
424
277
|
*/
|
|
425
|
-
|
|
278
|
+
const checkSchemaInitialized = () => {
|
|
426
279
|
if (schema === undefined) {
|
|
427
|
-
|
|
280
|
+
const message = 'Schema is not initialized. DataStore will not function as expected. This could happen if you have multiple versions of DataStore installed. Please see https://docs.amplify.aws/lib/troubleshooting/upgrading/q/platform/js/#check-for-duplicate-versions';
|
|
428
281
|
logger.error(message);
|
|
429
282
|
throw new Error(message);
|
|
430
283
|
}
|
|
@@ -447,36 +300,34 @@ var checkSchemaInitialized = function () {
|
|
|
447
300
|
*
|
|
448
301
|
* @param codegenVersion schema codegenVersion
|
|
449
302
|
*/
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
303
|
+
const checkSchemaCodegenVersion = (codegenVersion) => {
|
|
304
|
+
const majorVersion = 3;
|
|
305
|
+
const minorVersion = 2;
|
|
306
|
+
let isValid = false;
|
|
454
307
|
try {
|
|
455
|
-
|
|
456
|
-
|
|
308
|
+
const versionParts = codegenVersion.split('.');
|
|
309
|
+
const [major, minor, patch, patchrevision] = versionParts;
|
|
457
310
|
isValid = Number(major) === majorVersion && Number(minor) >= minorVersion;
|
|
458
311
|
}
|
|
459
312
|
catch (err) {
|
|
460
|
-
console.log(
|
|
313
|
+
console.log(`Error parsing codegen version: ${codegenVersion}\n${err}`);
|
|
461
314
|
}
|
|
462
315
|
if (!isValid) {
|
|
463
|
-
|
|
316
|
+
const message = `Models were generated with an unsupported version of codegen. Codegen artifacts are from ${codegenVersion || 'an unknown version'}, whereas ^${majorVersion}.${minorVersion}.0 is required. ` +
|
|
464
317
|
"Update to the latest CLI and run 'amplify codegen models'.";
|
|
465
318
|
logger.error(message);
|
|
466
319
|
throw new Error(message);
|
|
467
320
|
}
|
|
468
321
|
};
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
Object.entries(namespace.models).forEach(
|
|
472
|
-
|
|
473
|
-
var clazz = createModelClass(modelDefinition);
|
|
322
|
+
const createTypeClasses = namespace => {
|
|
323
|
+
const classes = {};
|
|
324
|
+
Object.entries(namespace.models).forEach(([modelName, modelDefinition]) => {
|
|
325
|
+
const clazz = createModelClass(modelDefinition);
|
|
474
326
|
classes[modelName] = clazz;
|
|
475
327
|
modelNamespaceMap.set(clazz, namespace.name);
|
|
476
328
|
});
|
|
477
|
-
Object.entries(namespace.nonModels || {}).forEach(
|
|
478
|
-
|
|
479
|
-
var clazz = createNonModelClass(typeDefinition);
|
|
329
|
+
Object.entries(namespace.nonModels || {}).forEach(([typeName, typeDefinition]) => {
|
|
330
|
+
const clazz = createNonModelClass(typeDefinition);
|
|
480
331
|
classes[typeName] = clazz;
|
|
481
332
|
});
|
|
482
333
|
return classes;
|
|
@@ -486,37 +337,37 @@ var createTypeClasses = function (namespace) {
|
|
|
486
337
|
* the model visible to the consuming app -- in case the app doesn't have
|
|
487
338
|
* metadata fields (_version, _deleted, etc.) exposed on the model itself.
|
|
488
339
|
*/
|
|
489
|
-
|
|
340
|
+
const instancesMetadata = new WeakSet();
|
|
490
341
|
function modelInstanceCreator(modelConstructor, init) {
|
|
491
342
|
instancesMetadata.add(init);
|
|
492
343
|
return new modelConstructor(init);
|
|
493
344
|
}
|
|
494
|
-
|
|
495
|
-
|
|
345
|
+
const validateModelFields = (modelDefinition) => (k, v) => {
|
|
346
|
+
const fieldDefinition = modelDefinition.fields[k];
|
|
496
347
|
if (fieldDefinition !== undefined) {
|
|
497
|
-
|
|
498
|
-
|
|
348
|
+
const { type, isRequired, isArrayNullable, name, isArray } = fieldDefinition;
|
|
349
|
+
const timestamps = (0, types_1.isSchemaModelWithAttributes)(modelDefinition)
|
|
499
350
|
? (0, util_1.getTimestampFields)(modelDefinition)
|
|
500
351
|
: {};
|
|
501
|
-
|
|
502
|
-
if (((!isArray &&
|
|
352
|
+
const isTimestampField = !!timestamps[name];
|
|
353
|
+
if (((!isArray && isRequired) || (isArray && !isArrayNullable)) &&
|
|
503
354
|
!isTimestampField &&
|
|
504
355
|
(v === null || v === undefined)) {
|
|
505
|
-
throw new Error(
|
|
356
|
+
throw new Error(`Field ${name} is required`);
|
|
506
357
|
}
|
|
507
358
|
if ((0, types_1.isSchemaModelWithAttributes)(modelDefinition) &&
|
|
508
359
|
!(0, util_1.isIdManaged)(modelDefinition)) {
|
|
509
|
-
|
|
360
|
+
const keys = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
510
361
|
if (keys.includes(k) && v === '') {
|
|
511
|
-
logger.error(util_1.errorMessages.idEmptyString, { k
|
|
362
|
+
logger.error(util_1.errorMessages.idEmptyString, { k, value: v });
|
|
512
363
|
throw new Error(util_1.errorMessages.idEmptyString);
|
|
513
364
|
}
|
|
514
365
|
}
|
|
515
|
-
if ((0, types_1.isGraphQLScalarType)(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
if (
|
|
519
|
-
if (typeof v ===
|
|
366
|
+
if ((0, types_1.isGraphQLScalarType)(type)) {
|
|
367
|
+
const jsType = types_1.GraphQLScalarType.getJSType(type);
|
|
368
|
+
const validateScalar = types_1.GraphQLScalarType.getValidationFunction(type);
|
|
369
|
+
if (type === 'AWSJSON') {
|
|
370
|
+
if (typeof v === jsType) {
|
|
520
371
|
return;
|
|
521
372
|
}
|
|
522
373
|
if (typeof v === 'string') {
|
|
@@ -525,96 +376,94 @@ var validateModelFields = function (modelDefinition) { return function (k, v) {
|
|
|
525
376
|
return;
|
|
526
377
|
}
|
|
527
378
|
catch (error) {
|
|
528
|
-
throw new Error(
|
|
379
|
+
throw new Error(`Field ${name} is an invalid JSON object. ${v}`);
|
|
529
380
|
}
|
|
530
381
|
}
|
|
531
382
|
}
|
|
532
383
|
if (isArray) {
|
|
533
|
-
|
|
534
|
-
if (!
|
|
535
|
-
errorTypeText =
|
|
384
|
+
let errorTypeText = jsType;
|
|
385
|
+
if (!isRequired) {
|
|
386
|
+
errorTypeText = `${jsType} | null | undefined`;
|
|
536
387
|
}
|
|
537
388
|
if (!Array.isArray(v) && !isArrayNullable) {
|
|
538
|
-
throw new Error(
|
|
389
|
+
throw new Error(`Field ${name} should be of type [${errorTypeText}], ${typeof v} received. ${v}`);
|
|
539
390
|
}
|
|
540
391
|
if (!(0, util_1.isNullOrUndefined)(v) &&
|
|
541
|
-
v.some(
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
var elemTypes = v
|
|
545
|
-
.map(function (e) { return (e === null ? 'null' : typeof e); })
|
|
392
|
+
v.some(e => (0, util_1.isNullOrUndefined)(e) ? isRequired : typeof e !== jsType)) {
|
|
393
|
+
const elemTypes = v
|
|
394
|
+
.map(e => (e === null ? 'null' : typeof e))
|
|
546
395
|
.join(',');
|
|
547
|
-
throw new Error(
|
|
396
|
+
throw new Error(`All elements in the ${name} array should be of type ${errorTypeText}, [${elemTypes}] received. ${v}`);
|
|
548
397
|
}
|
|
549
|
-
if (
|
|
550
|
-
|
|
398
|
+
if (validateScalar && !(0, util_1.isNullOrUndefined)(v)) {
|
|
399
|
+
const validationStatus = v.map(e => {
|
|
551
400
|
if (!(0, util_1.isNullOrUndefined)(e)) {
|
|
552
|
-
return
|
|
401
|
+
return validateScalar(e);
|
|
553
402
|
}
|
|
554
|
-
else if ((0, util_1.isNullOrUndefined)(e) && !
|
|
403
|
+
else if ((0, util_1.isNullOrUndefined)(e) && !isRequired) {
|
|
555
404
|
return true;
|
|
556
405
|
}
|
|
557
406
|
else {
|
|
558
407
|
return false;
|
|
559
408
|
}
|
|
560
409
|
});
|
|
561
|
-
if (!validationStatus.every(
|
|
562
|
-
throw new Error(
|
|
410
|
+
if (!validationStatus.every(s => s)) {
|
|
411
|
+
throw new Error(`All elements in the ${name} array should be of type ${type}, validation failed for one or more elements. ${v}`);
|
|
563
412
|
}
|
|
564
413
|
}
|
|
565
414
|
}
|
|
566
|
-
else if (!
|
|
415
|
+
else if (!isRequired && v === undefined) {
|
|
567
416
|
return;
|
|
568
417
|
}
|
|
569
|
-
else if (typeof v !==
|
|
570
|
-
throw new Error(
|
|
418
|
+
else if (typeof v !== jsType && v !== null) {
|
|
419
|
+
throw new Error(`Field ${name} should be of type ${jsType}, ${typeof v} received. ${v}`);
|
|
571
420
|
}
|
|
572
421
|
else if (!(0, util_1.isNullOrUndefined)(v) &&
|
|
573
|
-
|
|
574
|
-
!
|
|
422
|
+
validateScalar &&
|
|
423
|
+
!validateScalar(v) // TODO: why never, TS ... why ...
|
|
575
424
|
) {
|
|
576
|
-
throw new Error(
|
|
425
|
+
throw new Error(`Field ${name} should be of type ${type}, validation failed. ${v}`);
|
|
577
426
|
}
|
|
578
427
|
}
|
|
579
|
-
else if ((0, types_1.isNonModelFieldType)(
|
|
428
|
+
else if ((0, types_1.isNonModelFieldType)(type)) {
|
|
580
429
|
// do not check non model fields if undefined or null
|
|
581
430
|
if (!(0, util_1.isNullOrUndefined)(v)) {
|
|
582
|
-
|
|
583
|
-
|
|
431
|
+
const subNonModelDefinition = schema.namespaces.user.nonModels[type.nonModel];
|
|
432
|
+
const modelValidator = validateModelFields(subNonModelDefinition);
|
|
584
433
|
if (isArray) {
|
|
585
|
-
|
|
586
|
-
if (!
|
|
587
|
-
errorTypeText =
|
|
434
|
+
let errorTypeText = type.nonModel;
|
|
435
|
+
if (!isRequired) {
|
|
436
|
+
errorTypeText = `${type.nonModel} | null | undefined`;
|
|
588
437
|
}
|
|
589
438
|
if (!Array.isArray(v)) {
|
|
590
|
-
throw new Error(
|
|
439
|
+
throw new Error(`Field ${name} should be of type [${errorTypeText}], ${typeof v} received. ${v}`);
|
|
591
440
|
}
|
|
592
|
-
v.forEach(
|
|
593
|
-
if (((0, util_1.isNullOrUndefined)(item) &&
|
|
441
|
+
v.forEach(item => {
|
|
442
|
+
if (((0, util_1.isNullOrUndefined)(item) && isRequired) ||
|
|
594
443
|
(typeof item !== 'object' && typeof item !== 'undefined')) {
|
|
595
|
-
throw new Error(
|
|
444
|
+
throw new Error(`All elements in the ${name} array should be of type ${type.nonModel}, [${typeof item}] received. ${item}`);
|
|
596
445
|
}
|
|
597
446
|
if (!(0, util_1.isNullOrUndefined)(item)) {
|
|
598
|
-
Object.keys(
|
|
599
|
-
|
|
447
|
+
Object.keys(subNonModelDefinition.fields).forEach(subKey => {
|
|
448
|
+
modelValidator(subKey, item[subKey]);
|
|
600
449
|
});
|
|
601
450
|
}
|
|
602
451
|
});
|
|
603
452
|
}
|
|
604
453
|
else {
|
|
605
454
|
if (typeof v !== 'object') {
|
|
606
|
-
throw new Error(
|
|
455
|
+
throw new Error(`Field ${name} should be of type ${type.nonModel}, ${typeof v} recieved. ${v}`);
|
|
607
456
|
}
|
|
608
|
-
Object.keys(
|
|
609
|
-
|
|
457
|
+
Object.keys(subNonModelDefinition.fields).forEach(subKey => {
|
|
458
|
+
modelValidator(subKey, v[subKey]);
|
|
610
459
|
});
|
|
611
460
|
}
|
|
612
461
|
}
|
|
613
462
|
}
|
|
614
463
|
}
|
|
615
|
-
};
|
|
616
|
-
|
|
617
|
-
|
|
464
|
+
};
|
|
465
|
+
const castInstanceType = (modelDefinition, k, v) => {
|
|
466
|
+
const { isArray, type } = modelDefinition.fields[k] || {};
|
|
618
467
|
// attempt to parse stringified JSON
|
|
619
468
|
if (typeof v === 'string' &&
|
|
620
469
|
(isArray ||
|
|
@@ -624,7 +473,7 @@ var castInstanceType = function (modelDefinition, k, v) {
|
|
|
624
473
|
try {
|
|
625
474
|
return JSON.parse(v);
|
|
626
475
|
}
|
|
627
|
-
catch
|
|
476
|
+
catch {
|
|
628
477
|
// if JSON is invalid, don't throw and let modelValidator handle it
|
|
629
478
|
}
|
|
630
479
|
}
|
|
@@ -639,7 +488,7 @@ var castInstanceType = function (modelDefinition, k, v) {
|
|
|
639
488
|
* an instance of a Model. This can be used for determining which fields to
|
|
640
489
|
* send to the cloud durnig a CREATE mutation.
|
|
641
490
|
*/
|
|
642
|
-
|
|
491
|
+
const initPatches = new WeakMap();
|
|
643
492
|
/**
|
|
644
493
|
* Attempts to apply type-aware, casted field values from a given `init`
|
|
645
494
|
* object to the given `draft`.
|
|
@@ -648,11 +497,10 @@ var initPatches = new WeakMap();
|
|
|
648
497
|
* @param modelDefinition The definition describing the target object shape.
|
|
649
498
|
* @param draft The draft to apply field values to.
|
|
650
499
|
*/
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
Object.entries(init).forEach(
|
|
654
|
-
|
|
655
|
-
var parsedValue = castInstanceType(modelDefinition, k, v);
|
|
500
|
+
const initializeInstance = (init, modelDefinition, draft) => {
|
|
501
|
+
const modelValidator = validateModelFields(modelDefinition);
|
|
502
|
+
Object.entries(init).forEach(([k, v]) => {
|
|
503
|
+
const parsedValue = castInstanceType(modelDefinition, k, v);
|
|
656
504
|
modelValidator(k, parsedValue);
|
|
657
505
|
draft[k] = parsedValue;
|
|
658
506
|
});
|
|
@@ -676,42 +524,30 @@ var initializeInstance = function (init, modelDefinition, draft) {
|
|
|
676
524
|
* @param modelDefinition Definition for the draft. Used to discover all fields.
|
|
677
525
|
* @param draft The instance draft to apply normalizations to.
|
|
678
526
|
*/
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
var k = _c.value;
|
|
684
|
-
if (draft[k] === undefined)
|
|
685
|
-
draft[k] = null;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
689
|
-
finally {
|
|
690
|
-
try {
|
|
691
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
692
|
-
}
|
|
693
|
-
finally { if (e_4) throw e_4.error; }
|
|
527
|
+
const normalize = (modelDefinition, draft) => {
|
|
528
|
+
for (const k of Object.keys(modelDefinition.fields)) {
|
|
529
|
+
if (draft[k] === undefined)
|
|
530
|
+
draft[k] = null;
|
|
694
531
|
}
|
|
695
532
|
};
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
function Model(init) {
|
|
533
|
+
const createModelClass = (modelDefinition) => {
|
|
534
|
+
const clazz = class Model {
|
|
535
|
+
constructor(init) {
|
|
700
536
|
// we create a base instance first so we can distinguish which fields were explicitly
|
|
701
537
|
// set by customer code versus those set by normalization. only those fields
|
|
702
538
|
// which are explicitly set by customers should be part of create mutations.
|
|
703
|
-
|
|
704
|
-
|
|
539
|
+
let patches = [];
|
|
540
|
+
const baseInstance = (0, immer_1.produce)(this, (draft) => {
|
|
705
541
|
initializeInstance(init, modelDefinition, draft);
|
|
706
542
|
// model is initialized inside a DataStore component (e.g. by Sync Engine, Storage Engine, etc.)
|
|
707
|
-
|
|
708
|
-
|
|
543
|
+
const isInternallyInitialized = instancesMetadata.has(init);
|
|
544
|
+
const modelInstanceMetadata = isInternallyInitialized
|
|
709
545
|
? init
|
|
710
546
|
: {};
|
|
711
|
-
|
|
547
|
+
const { id: _id } = modelInstanceMetadata;
|
|
712
548
|
if ((0, util_1.isIdManaged)(modelDefinition)) {
|
|
713
|
-
|
|
714
|
-
|
|
549
|
+
const isInternalModel = _id !== null && _id !== undefined;
|
|
550
|
+
const id = isInternalModel
|
|
715
551
|
? _id
|
|
716
552
|
: modelDefinition.syncable
|
|
717
553
|
? (0, utils_1.amplifyUuid)()
|
|
@@ -726,55 +562,52 @@ var createModelClass = function (modelDefinition) {
|
|
|
726
562
|
if (!isInternallyInitialized) {
|
|
727
563
|
checkReadOnlyPropertyOnCreate(draft, modelDefinition);
|
|
728
564
|
}
|
|
729
|
-
|
|
565
|
+
const { _version, _lastChangedAt, _deleted } = modelInstanceMetadata;
|
|
730
566
|
if (modelDefinition.syncable) {
|
|
731
567
|
draft._version = _version;
|
|
732
568
|
draft._lastChangedAt = _lastChangedAt;
|
|
733
569
|
draft._deleted = _deleted;
|
|
734
570
|
}
|
|
735
|
-
},
|
|
571
|
+
}, p => (patches = p));
|
|
736
572
|
// now that we have a list of patches that encapsulate the explicit, customer-provided
|
|
737
573
|
// fields, we can normalize. patches from normalization are ignored, because the changes
|
|
738
574
|
// are only create to provide a consistent view of the data for fields pre/post sync
|
|
739
575
|
// where possible. (not all fields can be normalized pre-sync, because they're generally
|
|
740
576
|
// "cloud managed" fields, like createdAt and updatedAt.)
|
|
741
|
-
|
|
742
|
-
return normalize(modelDefinition, draft);
|
|
743
|
-
});
|
|
577
|
+
const normalized = (0, immer_1.produce)(baseInstance, (draft) => normalize(modelDefinition, draft));
|
|
744
578
|
initPatches.set(normalized, patches);
|
|
745
579
|
return normalized;
|
|
746
580
|
}
|
|
747
|
-
|
|
748
|
-
|
|
581
|
+
static copyOf(source, fn) {
|
|
582
|
+
const modelConstructor = Object.getPrototypeOf(source || {}).constructor;
|
|
749
583
|
if (!isValidModelConstructor(modelConstructor)) {
|
|
750
|
-
|
|
751
|
-
logger.error(msg, { source
|
|
584
|
+
const msg = 'The source object is not a valid model';
|
|
585
|
+
logger.error(msg, { source });
|
|
752
586
|
throw new Error(msg);
|
|
753
587
|
}
|
|
754
|
-
|
|
755
|
-
|
|
588
|
+
let patches = [];
|
|
589
|
+
const model = (0, immer_1.produce)(source, draft => {
|
|
756
590
|
fn(draft);
|
|
757
|
-
|
|
591
|
+
const keyNames = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
758
592
|
// Keys are immutable
|
|
759
|
-
keyNames.forEach(
|
|
593
|
+
keyNames.forEach(key => {
|
|
760
594
|
if (draft[key] !== source[key]) {
|
|
761
|
-
logger.warn(
|
|
595
|
+
logger.warn(`copyOf() does not update PK fields. The '${key}' update is being ignored.`, { source });
|
|
762
596
|
}
|
|
763
597
|
draft[key] = source[key];
|
|
764
598
|
});
|
|
765
|
-
|
|
766
|
-
Object.entries(draft).forEach(
|
|
767
|
-
|
|
768
|
-
var parsedValue = castInstanceType(modelDefinition, k, v);
|
|
599
|
+
const modelValidator = validateModelFields(modelDefinition);
|
|
600
|
+
Object.entries(draft).forEach(([k, v]) => {
|
|
601
|
+
const parsedValue = castInstanceType(modelDefinition, k, v);
|
|
769
602
|
modelValidator(k, parsedValue);
|
|
770
603
|
});
|
|
771
604
|
normalize(modelDefinition, draft);
|
|
772
|
-
},
|
|
773
|
-
|
|
605
|
+
}, p => (patches = p));
|
|
606
|
+
const hasExistingPatches = modelPatchesMap.has(source);
|
|
774
607
|
if (patches.length || hasExistingPatches) {
|
|
775
608
|
if (hasExistingPatches) {
|
|
776
|
-
|
|
777
|
-
|
|
609
|
+
const [existingPatches, existingSource] = modelPatchesMap.get(source);
|
|
610
|
+
const mergedPatches = (0, util_1.mergePatches)(existingSource, existingPatches, patches);
|
|
778
611
|
modelPatchesMap.set(model, [mergedPatches, existingSource]);
|
|
779
612
|
checkReadOnlyPropertyOnUpdate(mergedPatches, modelDefinition);
|
|
780
613
|
}
|
|
@@ -793,38 +626,35 @@ var createModelClass = function (modelDefinition) {
|
|
|
793
626
|
modelPatchesMap.set(model, [[], source]);
|
|
794
627
|
}
|
|
795
628
|
return attached(model, ModelAttachment.DataStore);
|
|
796
|
-
}
|
|
629
|
+
}
|
|
797
630
|
// "private" method (that's hidden via `Setting`) for `withSSRContext` to use
|
|
798
631
|
// to gain access to `modelInstanceCreator` and `clazz` for persisting IDs from server to client.
|
|
799
|
-
|
|
800
|
-
var _this = this;
|
|
632
|
+
static fromJSON(json) {
|
|
801
633
|
if (Array.isArray(json)) {
|
|
802
|
-
return json.map(
|
|
634
|
+
return json.map(init => this.fromJSON(init));
|
|
803
635
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
Object.entries(instance).forEach(
|
|
807
|
-
var _b = __read(_a, 2), k = _b[0], v = _b[1];
|
|
636
|
+
const instance = modelInstanceCreator(clazz, json);
|
|
637
|
+
const modelValidator = validateModelFields(modelDefinition);
|
|
638
|
+
Object.entries(instance).forEach(([k, v]) => {
|
|
808
639
|
modelValidator(k, v);
|
|
809
640
|
});
|
|
810
641
|
return attached(instance, ModelAttachment.DataStore);
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
}());
|
|
642
|
+
}
|
|
643
|
+
};
|
|
814
644
|
clazz[immer_1.immerable] = true;
|
|
815
645
|
Object.defineProperty(clazz, 'name', { value: modelDefinition.name });
|
|
816
646
|
// Add getters/setters for relationship fields.
|
|
817
647
|
// getter - for lazy loading
|
|
818
648
|
// setter - for FK management
|
|
819
|
-
|
|
649
|
+
const allModelRelationships = relationship_1.ModelRelationship.allFrom({
|
|
820
650
|
builder: clazz,
|
|
821
651
|
schema: modelDefinition,
|
|
822
652
|
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
823
653
|
});
|
|
824
|
-
|
|
825
|
-
|
|
654
|
+
for (const relationship of allModelRelationships) {
|
|
655
|
+
const field = relationship.field;
|
|
826
656
|
Object.defineProperty(clazz.prototype, modelDefinition.fields[field].name, {
|
|
827
|
-
set
|
|
657
|
+
set(model) {
|
|
828
658
|
if (!(typeof model === 'object' || typeof model === 'undefined'))
|
|
829
659
|
return;
|
|
830
660
|
// if model is undefined or null, the connection should be removed
|
|
@@ -833,39 +663,38 @@ var createModelClass = function (modelDefinition) {
|
|
|
833
663
|
// selection set. Nested entitites lack version field and can not be validated
|
|
834
664
|
// TODO: explore a more reliable method to solve this
|
|
835
665
|
if (model.hasOwnProperty('_version')) {
|
|
836
|
-
|
|
666
|
+
const modelConstructor = Object.getPrototypeOf(model || {})
|
|
837
667
|
.constructor;
|
|
838
668
|
if (!isValidModelConstructor(modelConstructor)) {
|
|
839
|
-
|
|
840
|
-
logger.error(msg, { model
|
|
669
|
+
const msg = `Value passed to ${modelDefinition.name}.${field} is not a valid instance of a model`;
|
|
670
|
+
logger.error(msg, { model });
|
|
841
671
|
throw new Error(msg);
|
|
842
672
|
}
|
|
843
673
|
if (modelConstructor.name.toLowerCase() !==
|
|
844
674
|
relationship.remoteModelConstructor.name.toLowerCase()) {
|
|
845
|
-
|
|
846
|
-
logger.error(msg, { model
|
|
675
|
+
const msg = `Value passed to ${modelDefinition.name}.${field} is not an instance of ${relationship.remoteModelConstructor.name}`;
|
|
676
|
+
logger.error(msg, { model });
|
|
847
677
|
throw new Error(msg);
|
|
848
678
|
}
|
|
849
679
|
}
|
|
850
680
|
}
|
|
851
681
|
// if the relationship can be managed automagically, set the FK's
|
|
852
682
|
if (relationship.isComplete) {
|
|
853
|
-
for (
|
|
683
|
+
for (let i = 0; i < relationship.localJoinFields.length; i++) {
|
|
854
684
|
this[relationship.localJoinFields[i]] =
|
|
855
|
-
model
|
|
685
|
+
model?.[relationship.remoteJoinFields[i]];
|
|
856
686
|
}
|
|
857
|
-
|
|
687
|
+
const instanceMemos = modelInstanceAssociationsMap.has(this)
|
|
858
688
|
? modelInstanceAssociationsMap.get(this)
|
|
859
689
|
: modelInstanceAssociationsMap.set(this, {}).get(this);
|
|
860
690
|
instanceMemos[field] = model || undefined;
|
|
861
691
|
}
|
|
862
692
|
},
|
|
863
|
-
get
|
|
864
|
-
var _this = this;
|
|
693
|
+
get() {
|
|
865
694
|
/**
|
|
866
695
|
* Bucket for holding related models instances specific to `this` instance.
|
|
867
696
|
*/
|
|
868
|
-
|
|
697
|
+
const instanceMemos = modelInstanceAssociationsMap.has(this)
|
|
869
698
|
? modelInstanceAssociationsMap.get(this)
|
|
870
699
|
: modelInstanceAssociationsMap.set(this, {}).get(this);
|
|
871
700
|
// if the memos already has a result for this field, we'll use it.
|
|
@@ -879,14 +708,12 @@ var createModelClass = function (modelDefinition) {
|
|
|
879
708
|
// of the relationship metadata, we DO NOT AWAIT resolution. we want to
|
|
880
709
|
// drop the promise into the memo's synchronously, eliminating the chance
|
|
881
710
|
// for a race.
|
|
882
|
-
|
|
883
|
-
return
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
return q[field].eq(_this[relationship.localJoinFields[index]]);
|
|
887
|
-
});
|
|
711
|
+
const resultPromise = instance.query(relationship.remoteModelConstructor, base => base.and(q => {
|
|
712
|
+
return relationship.remoteJoinFields.map((field, index) => {
|
|
713
|
+
// TODO: anything we can use instead of `any` here?
|
|
714
|
+
return q[field].eq(this[relationship.localJoinFields[index]]);
|
|
888
715
|
});
|
|
889
|
-
});
|
|
716
|
+
}));
|
|
890
717
|
// results in hand, how we return them to the caller depends on the relationship type.
|
|
891
718
|
if (relationship.type === 'HAS_MANY') {
|
|
892
719
|
// collections should support async iteration, even though we don't
|
|
@@ -897,10 +724,13 @@ var createModelClass = function (modelDefinition) {
|
|
|
897
724
|
// non-collections should only ever return 1 value *or nothing*.
|
|
898
725
|
// if we have more than 1 record, something's amiss. it's not our job
|
|
899
726
|
// pick a result for the customer. it's our job to say "something's wrong."
|
|
900
|
-
instanceMemos[field] = resultPromise.then(
|
|
727
|
+
instanceMemos[field] = resultPromise.then(rows => {
|
|
901
728
|
if (rows.length > 1) {
|
|
902
729
|
// should never happen for a HAS_ONE or BELONGS_TO.
|
|
903
|
-
|
|
730
|
+
const err = new Error(`
|
|
731
|
+
Data integrity error.
|
|
732
|
+
Too many records found for a HAS_ONE/BELONGS_TO field '${modelDefinition.name}.${field}'
|
|
733
|
+
`);
|
|
904
734
|
console.error(err);
|
|
905
735
|
throw err;
|
|
906
736
|
}
|
|
@@ -925,40 +755,22 @@ var createModelClass = function (modelDefinition) {
|
|
|
925
755
|
return instanceMemos[field];
|
|
926
756
|
},
|
|
927
757
|
});
|
|
928
|
-
};
|
|
929
|
-
try {
|
|
930
|
-
for (var allModelRelationships_1 = __values(allModelRelationships), allModelRelationships_1_1 = allModelRelationships_1.next(); !allModelRelationships_1_1.done; allModelRelationships_1_1 = allModelRelationships_1.next()) {
|
|
931
|
-
var relationship = allModelRelationships_1_1.value;
|
|
932
|
-
_loop_1(relationship);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
936
|
-
finally {
|
|
937
|
-
try {
|
|
938
|
-
if (allModelRelationships_1_1 && !allModelRelationships_1_1.done && (_a = allModelRelationships_1.return)) _a.call(allModelRelationships_1);
|
|
939
|
-
}
|
|
940
|
-
finally { if (e_5) throw e_5.error; }
|
|
941
758
|
}
|
|
942
759
|
return clazz;
|
|
943
760
|
};
|
|
944
761
|
/**
|
|
945
762
|
* An eventually loaded related model instance.
|
|
946
763
|
*/
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
function AsyncItem() {
|
|
950
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
951
|
-
}
|
|
952
|
-
return AsyncItem;
|
|
953
|
-
}(Promise));
|
|
764
|
+
class AsyncItem extends Promise {
|
|
765
|
+
}
|
|
954
766
|
exports.AsyncItem = AsyncItem;
|
|
955
767
|
/**
|
|
956
768
|
* A collection of related model instances.
|
|
957
769
|
*
|
|
958
770
|
* This collection can be async-iterated or turned directly into an array using `toArray()`.
|
|
959
771
|
*/
|
|
960
|
-
|
|
961
|
-
|
|
772
|
+
class AsyncCollection {
|
|
773
|
+
constructor(values) {
|
|
962
774
|
this.values = values;
|
|
963
775
|
}
|
|
964
776
|
/**
|
|
@@ -972,39 +784,28 @@ var AsyncCollection = /** @class */ (function () {
|
|
|
972
784
|
*
|
|
973
785
|
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of
|
|
974
786
|
*/
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
var index = 0;
|
|
787
|
+
[Symbol.asyncIterator]() {
|
|
788
|
+
let values;
|
|
789
|
+
let index = 0;
|
|
979
790
|
return {
|
|
980
|
-
next:
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
index++;
|
|
997
|
-
return [2 /*return*/, result];
|
|
998
|
-
}
|
|
999
|
-
return [2 /*return*/, {
|
|
1000
|
-
value: null,
|
|
1001
|
-
done: true,
|
|
1002
|
-
}];
|
|
1003
|
-
}
|
|
1004
|
-
});
|
|
1005
|
-
}); },
|
|
791
|
+
next: async () => {
|
|
792
|
+
if (!values)
|
|
793
|
+
values = await this.values;
|
|
794
|
+
if (index < values.length) {
|
|
795
|
+
const result = {
|
|
796
|
+
value: values[index],
|
|
797
|
+
done: false,
|
|
798
|
+
};
|
|
799
|
+
index++;
|
|
800
|
+
return result;
|
|
801
|
+
}
|
|
802
|
+
return {
|
|
803
|
+
value: null,
|
|
804
|
+
done: true,
|
|
805
|
+
};
|
|
806
|
+
},
|
|
1006
807
|
};
|
|
1007
|
-
}
|
|
808
|
+
}
|
|
1008
809
|
/**
|
|
1009
810
|
* Turns the collection into an array, up to the amount specified in `max` param.
|
|
1010
811
|
*
|
|
@@ -1013,97 +814,51 @@ var AsyncCollection = /** @class */ (function () {
|
|
|
1013
814
|
* const first100 = await collection.toArray({max: 100});
|
|
1014
815
|
* ```
|
|
1015
816
|
*/
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
case 2: return [4 /*yield*/, _h.next()];
|
|
1032
|
-
case 3:
|
|
1033
|
-
if (!(_j = _k.sent(), _b = _j.done, !_b)) return [3 /*break*/, 5];
|
|
1034
|
-
_d = _j.value;
|
|
1035
|
-
_g = false;
|
|
1036
|
-
try {
|
|
1037
|
-
element = _d;
|
|
1038
|
-
if (i < max) {
|
|
1039
|
-
output.push(element);
|
|
1040
|
-
i++;
|
|
1041
|
-
}
|
|
1042
|
-
else {
|
|
1043
|
-
return [3 /*break*/, 5];
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
finally {
|
|
1047
|
-
_g = true;
|
|
1048
|
-
}
|
|
1049
|
-
_k.label = 4;
|
|
1050
|
-
case 4: return [3 /*break*/, 2];
|
|
1051
|
-
case 5: return [3 /*break*/, 12];
|
|
1052
|
-
case 6:
|
|
1053
|
-
e_6_1 = _k.sent();
|
|
1054
|
-
e_6 = { error: e_6_1 };
|
|
1055
|
-
return [3 /*break*/, 12];
|
|
1056
|
-
case 7:
|
|
1057
|
-
_k.trys.push([7, , 10, 11]);
|
|
1058
|
-
if (!(!_g && !_b && (_c = _h.return))) return [3 /*break*/, 9];
|
|
1059
|
-
return [4 /*yield*/, _c.call(_h)];
|
|
1060
|
-
case 8:
|
|
1061
|
-
_k.sent();
|
|
1062
|
-
_k.label = 9;
|
|
1063
|
-
case 9: return [3 /*break*/, 11];
|
|
1064
|
-
case 10:
|
|
1065
|
-
if (e_6) throw e_6.error;
|
|
1066
|
-
return [7 /*endfinally*/];
|
|
1067
|
-
case 11: return [7 /*endfinally*/];
|
|
1068
|
-
case 12: return [2 /*return*/, output];
|
|
1069
|
-
}
|
|
1070
|
-
});
|
|
1071
|
-
});
|
|
1072
|
-
};
|
|
1073
|
-
return AsyncCollection;
|
|
1074
|
-
}());
|
|
817
|
+
async toArray({ max = Number.MAX_SAFE_INTEGER, } = {}) {
|
|
818
|
+
const output = [];
|
|
819
|
+
let i = 0;
|
|
820
|
+
for await (const element of this) {
|
|
821
|
+
if (i < max) {
|
|
822
|
+
output.push(element);
|
|
823
|
+
i++;
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
break;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return output;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
1075
832
|
exports.AsyncCollection = AsyncCollection;
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
modelKeys.forEach(
|
|
833
|
+
const checkReadOnlyPropertyOnCreate = (draft, modelDefinition) => {
|
|
834
|
+
const modelKeys = Object.keys(draft);
|
|
835
|
+
const { fields } = modelDefinition;
|
|
836
|
+
modelKeys.forEach(key => {
|
|
1080
837
|
if (fields[key] && fields[key].isReadOnly) {
|
|
1081
|
-
throw new Error(
|
|
838
|
+
throw new Error(`${key} is read-only.`);
|
|
1082
839
|
}
|
|
1083
840
|
});
|
|
1084
841
|
};
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
patchArray.forEach(
|
|
1089
|
-
var _b = __read(_a, 2), key = _b[0], val = _b[1];
|
|
842
|
+
const checkReadOnlyPropertyOnUpdate = (patches, modelDefinition) => {
|
|
843
|
+
const patchArray = patches.map(p => [p.path[0], p.value]);
|
|
844
|
+
const { fields } = modelDefinition;
|
|
845
|
+
patchArray.forEach(([key, val]) => {
|
|
1090
846
|
if (!val || !fields[key])
|
|
1091
847
|
return;
|
|
1092
848
|
if (fields[key].isReadOnly) {
|
|
1093
|
-
throw new Error(
|
|
849
|
+
throw new Error(`${key} is read-only.`);
|
|
1094
850
|
}
|
|
1095
851
|
});
|
|
1096
852
|
};
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
853
|
+
const createNonModelClass = (typeDefinition) => {
|
|
854
|
+
const clazz = class Model {
|
|
855
|
+
constructor(init) {
|
|
856
|
+
const instance = (0, immer_1.produce)(this, (draft) => {
|
|
1101
857
|
initializeInstance(init, typeDefinition, draft);
|
|
1102
858
|
});
|
|
1103
859
|
return instance;
|
|
1104
860
|
}
|
|
1105
|
-
|
|
1106
|
-
}());
|
|
861
|
+
};
|
|
1107
862
|
clazz[immer_1.immerable] = true;
|
|
1108
863
|
Object.defineProperty(clazz, 'name', { value: typeDefinition.name });
|
|
1109
864
|
(0, util_1.registerNonModelClass)(clazz);
|
|
@@ -1113,15 +868,15 @@ function isQueryOne(obj) {
|
|
|
1113
868
|
return typeof obj === 'string';
|
|
1114
869
|
}
|
|
1115
870
|
function defaultConflictHandler(conflictData) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
return modelInstanceCreator(modelConstructor,
|
|
871
|
+
const { localModel, modelConstructor, remoteModel } = conflictData;
|
|
872
|
+
const { _version } = remoteModel;
|
|
873
|
+
return modelInstanceCreator(modelConstructor, { ...localModel, _version });
|
|
1119
874
|
}
|
|
1120
875
|
function defaultErrorHandler(error) {
|
|
1121
876
|
logger.warn(error);
|
|
1122
877
|
}
|
|
1123
878
|
function getModelConstructorByModelName(namespaceName, modelName) {
|
|
1124
|
-
|
|
879
|
+
let result;
|
|
1125
880
|
switch (namespaceName) {
|
|
1126
881
|
case util_1.DATASTORE:
|
|
1127
882
|
result = dataStoreClasses[modelName];
|
|
@@ -1136,13 +891,13 @@ function getModelConstructorByModelName(namespaceName, modelName) {
|
|
|
1136
891
|
result = storageClasses[modelName];
|
|
1137
892
|
break;
|
|
1138
893
|
default:
|
|
1139
|
-
throw new Error(
|
|
894
|
+
throw new Error(`Invalid namespace: ${namespaceName}`);
|
|
1140
895
|
}
|
|
1141
896
|
if (isValidModelConstructor(result)) {
|
|
1142
897
|
return result;
|
|
1143
898
|
}
|
|
1144
899
|
else {
|
|
1145
|
-
|
|
900
|
+
const msg = `Model name is not valid for namespace. modelName: ${modelName}, namespace: ${namespaceName}`;
|
|
1146
901
|
logger.error(msg);
|
|
1147
902
|
throw new Error(msg);
|
|
1148
903
|
}
|
|
@@ -1159,54 +914,31 @@ function getModelConstructorByModelName(namespaceName, modelName) {
|
|
|
1159
914
|
* @param storage Storage adapter containing the metadata.
|
|
1160
915
|
* @param version The expected schema version.
|
|
1161
916
|
*/
|
|
1162
|
-
function checkSchemaVersion(storage, version) {
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
switch (_b.label) {
|
|
1175
|
-
case 0: return [4 /*yield*/, s.query(Setting, predicates_1.ModelPredicateCreator.createFromAST(modelDefinition, {
|
|
1176
|
-
and: { key: { eq: SETTING_SCHEMA_VERSION } },
|
|
1177
|
-
}), { page: 0, limit: 1 })];
|
|
1178
|
-
case 1:
|
|
1179
|
-
_a = __read.apply(void 0, [_b.sent(), 1]), schemaVersionSetting = _a[0];
|
|
1180
|
-
if (!(schemaVersionSetting !== undefined &&
|
|
1181
|
-
schemaVersionSetting.value !== undefined)) return [3 /*break*/, 4];
|
|
1182
|
-
storedValue = JSON.parse(schemaVersionSetting.value);
|
|
1183
|
-
if (!(storedValue !== version)) return [3 /*break*/, 3];
|
|
1184
|
-
return [4 /*yield*/, s.clear(false)];
|
|
1185
|
-
case 2:
|
|
1186
|
-
_b.sent();
|
|
1187
|
-
_b.label = 3;
|
|
1188
|
-
case 3: return [3 /*break*/, 6];
|
|
1189
|
-
case 4: return [4 /*yield*/, s.save(modelInstanceCreator(Setting, {
|
|
1190
|
-
key: SETTING_SCHEMA_VERSION,
|
|
1191
|
-
value: JSON.stringify(version),
|
|
1192
|
-
}))];
|
|
1193
|
-
case 5:
|
|
1194
|
-
_b.sent();
|
|
1195
|
-
_b.label = 6;
|
|
1196
|
-
case 6: return [2 /*return*/];
|
|
1197
|
-
}
|
|
1198
|
-
});
|
|
1199
|
-
}); })];
|
|
1200
|
-
case 1:
|
|
1201
|
-
_a.sent();
|
|
1202
|
-
return [2 /*return*/];
|
|
917
|
+
async function checkSchemaVersion(storage, version) {
|
|
918
|
+
const Setting = dataStoreClasses.Setting;
|
|
919
|
+
const modelDefinition = schema.namespaces[util_1.DATASTORE].models.Setting;
|
|
920
|
+
await storage.runExclusive(async (s) => {
|
|
921
|
+
const [schemaVersionSetting] = await s.query(Setting, predicates_1.ModelPredicateCreator.createFromAST(modelDefinition, {
|
|
922
|
+
and: { key: { eq: SETTING_SCHEMA_VERSION } },
|
|
923
|
+
}), { page: 0, limit: 1 });
|
|
924
|
+
if (schemaVersionSetting !== undefined &&
|
|
925
|
+
schemaVersionSetting.value !== undefined) {
|
|
926
|
+
const storedValue = JSON.parse(schemaVersionSetting.value);
|
|
927
|
+
if (storedValue !== version) {
|
|
928
|
+
await s.clear(false);
|
|
1203
929
|
}
|
|
1204
|
-
}
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
await s.save(modelInstanceCreator(Setting, {
|
|
933
|
+
key: SETTING_SCHEMA_VERSION,
|
|
934
|
+
value: JSON.stringify(version),
|
|
935
|
+
}));
|
|
936
|
+
}
|
|
1205
937
|
});
|
|
1206
938
|
}
|
|
1207
|
-
|
|
939
|
+
let syncSubscription;
|
|
1208
940
|
function getNamespace() {
|
|
1209
|
-
|
|
941
|
+
const namespace = {
|
|
1210
942
|
name: util_1.DATASTORE,
|
|
1211
943
|
relationships: {},
|
|
1212
944
|
enums: {},
|
|
@@ -1251,9 +983,8 @@ var DataStoreState;
|
|
|
1251
983
|
})(DataStoreState || (DataStoreState = {}));
|
|
1252
984
|
// TODO: How can we get rid of the non-null assertions?
|
|
1253
985
|
// https://github.com/aws-amplify/amplify-js/pull/10477/files#r1007363485
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
var _this = this;
|
|
986
|
+
class DataStore {
|
|
987
|
+
constructor() {
|
|
1257
988
|
// reference to configured category instances. Used for preserving SSR context
|
|
1258
989
|
this.InternalAPI = internals_1.InternalAPI;
|
|
1259
990
|
this.Cache = core_1.Cache;
|
|
@@ -1315,419 +1046,322 @@ var DataStore = /** @class */ (function () {
|
|
|
1315
1046
|
* 3. If `this.amplifyConfig.aws_appsync_graphqlEndpoint` contains a URL,
|
|
1316
1047
|
* attaches a sync engine, starts it, and subscribes.
|
|
1317
1048
|
*/
|
|
1318
|
-
this.start =
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
return [4 /*yield*/, this.processSyncExpressions()];
|
|
1354
|
-
case 6:
|
|
1355
|
-
_a.syncPredicates = _b.sent();
|
|
1356
|
-
this.sync = new sync_1.SyncEngine(schema, namespaceResolver, exports.syncClasses, userClasses, this.storage, modelInstanceCreator, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy, this.amplifyContext, this.connectivityMonitor);
|
|
1357
|
-
fullSyncIntervalInMilliseconds = this.fullSyncInterval * 1000 * 60;
|
|
1358
|
-
syncSubscription = this.sync
|
|
1359
|
-
.start({ fullSyncInterval: fullSyncIntervalInMilliseconds })
|
|
1360
|
-
.subscribe({
|
|
1361
|
-
next: function (_a) {
|
|
1362
|
-
var type = _a.type, data = _a.data;
|
|
1363
|
-
// In the Browser, we can begin returning data once subscriptions are in place.
|
|
1364
|
-
var readyType = sync_1.ControlMessage.SYNC_ENGINE_STORAGE_SUBSCRIBED;
|
|
1365
|
-
if (type === readyType) {
|
|
1366
|
-
_this.initResolve();
|
|
1367
|
-
}
|
|
1368
|
-
core_1.Hub.dispatch('datastore', {
|
|
1369
|
-
event: type,
|
|
1370
|
-
data: data,
|
|
1371
|
-
});
|
|
1372
|
-
},
|
|
1373
|
-
error: function (err) {
|
|
1374
|
-
logger.warn('Sync error', err);
|
|
1375
|
-
_this.initReject();
|
|
1376
|
-
},
|
|
1377
|
-
});
|
|
1378
|
-
return [3 /*break*/, 8];
|
|
1379
|
-
case 7:
|
|
1380
|
-
logger.warn("Data won't be synchronized. No GraphQL endpoint configured. Did you forget `Amplify.configure(awsconfig)`?", {
|
|
1381
|
-
config: this.amplifyConfig,
|
|
1382
|
-
});
|
|
1383
|
-
this.initResolve();
|
|
1384
|
-
_b.label = 8;
|
|
1385
|
-
case 8: return [4 /*yield*/, this.initialized];
|
|
1386
|
-
case 9:
|
|
1387
|
-
_b.sent();
|
|
1388
|
-
this.state = DataStoreState.Running;
|
|
1389
|
-
return [2 /*return*/];
|
|
1390
|
-
}
|
|
1391
|
-
});
|
|
1392
|
-
}); }, 'datastore start')
|
|
1393
|
-
.catch(this.handleAddProcError('DataStore.start()'))];
|
|
1394
|
-
});
|
|
1395
|
-
}); };
|
|
1396
|
-
this.query = function (modelConstructor, identifierOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
|
|
1397
|
-
var _this = this;
|
|
1398
|
-
return __generator(this, function (_a) {
|
|
1399
|
-
return [2 /*return*/, this.runningProcesses
|
|
1400
|
-
.add(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1401
|
-
var result, msg, modelDefinition, pagination, keyFields, msg, predicate, predicate, seedPredicate, predicate, returnOne;
|
|
1402
|
-
var _a;
|
|
1403
|
-
var _b;
|
|
1404
|
-
return __generator(this, function (_c) {
|
|
1405
|
-
switch (_c.label) {
|
|
1406
|
-
case 0: return [4 /*yield*/, this.start()];
|
|
1407
|
-
case 1:
|
|
1408
|
-
_c.sent();
|
|
1409
|
-
if (!this.storage) {
|
|
1410
|
-
throw new Error('No storage to query');
|
|
1411
|
-
}
|
|
1412
|
-
//#region Input validation
|
|
1413
|
-
if (!isValidModelConstructor(modelConstructor)) {
|
|
1414
|
-
msg = 'Constructor is not for a valid model';
|
|
1415
|
-
logger.error(msg, { modelConstructor: modelConstructor });
|
|
1416
|
-
throw new Error(msg);
|
|
1417
|
-
}
|
|
1418
|
-
if (typeof identifierOrCriteria === 'string') {
|
|
1419
|
-
if (paginationProducer !== undefined) {
|
|
1420
|
-
logger.warn('Pagination is ignored when querying by id');
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
modelDefinition = getModelDefinition(modelConstructor);
|
|
1424
|
-
if (!modelDefinition) {
|
|
1425
|
-
throw new Error('Invalid model definition provided!');
|
|
1426
|
-
}
|
|
1427
|
-
pagination = this.processPagination(modelDefinition, paginationProducer);
|
|
1428
|
-
keyFields = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
1429
|
-
if (!isQueryOne(identifierOrCriteria)) return [3 /*break*/, 3];
|
|
1430
|
-
if (keyFields.length > 1) {
|
|
1431
|
-
msg = util_1.errorMessages.queryByPkWithCompositeKeyPresent;
|
|
1432
|
-
logger.error(msg, { keyFields: keyFields });
|
|
1433
|
-
throw new Error(msg);
|
|
1434
|
-
}
|
|
1435
|
-
predicate = predicates_1.ModelPredicateCreator.createFromFlatEqualities(modelDefinition, (_a = {}, _a[keyFields[0]] = identifierOrCriteria, _a));
|
|
1436
|
-
return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
|
|
1437
|
-
case 2:
|
|
1438
|
-
result = _c.sent();
|
|
1439
|
-
return [3 /*break*/, 9];
|
|
1440
|
-
case 3:
|
|
1441
|
-
if (!(0, types_1.isIdentifierObject)(identifierOrCriteria, modelDefinition)) return [3 /*break*/, 5];
|
|
1442
|
-
predicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
|
|
1443
|
-
return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
|
|
1444
|
-
case 4:
|
|
1445
|
-
result = _c.sent();
|
|
1446
|
-
return [3 /*break*/, 9];
|
|
1447
|
-
case 5:
|
|
1448
|
-
if (!(!identifierOrCriteria ||
|
|
1449
|
-
(0, predicates_1.isPredicatesAll)(identifierOrCriteria))) return [3 /*break*/, 7];
|
|
1450
|
-
return [4 /*yield*/, ((_b = this.storage) === null || _b === void 0 ? void 0 : _b.query(modelConstructor, undefined, pagination))];
|
|
1451
|
-
case 6:
|
|
1452
|
-
result = _c.sent();
|
|
1453
|
-
return [3 /*break*/, 9];
|
|
1454
|
-
case 7:
|
|
1455
|
-
seedPredicate = (0, next_1.recursivePredicateFor)({
|
|
1456
|
-
builder: modelConstructor,
|
|
1457
|
-
schema: modelDefinition,
|
|
1458
|
-
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
1459
|
-
});
|
|
1460
|
-
predicate = (0, next_1.internals)(identifierOrCriteria(seedPredicate));
|
|
1461
|
-
return [4 /*yield*/, predicate.fetch(this.storage)];
|
|
1462
|
-
case 8:
|
|
1463
|
-
result = (_c.sent());
|
|
1464
|
-
result = (0, util_1.inMemoryPagination)(result, pagination);
|
|
1465
|
-
_c.label = 9;
|
|
1466
|
-
case 9:
|
|
1467
|
-
returnOne = isQueryOne(identifierOrCriteria) ||
|
|
1468
|
-
(0, types_1.isIdentifierObject)(identifierOrCriteria, modelDefinition);
|
|
1469
|
-
return [2 /*return*/, attached(returnOne ? result[0] : result, ModelAttachment.DataStore)];
|
|
1049
|
+
this.start = async () => {
|
|
1050
|
+
return this.runningProcesses
|
|
1051
|
+
.add(async () => {
|
|
1052
|
+
this.state = DataStoreState.Starting;
|
|
1053
|
+
if (this.initialized === undefined) {
|
|
1054
|
+
logger.debug('Starting DataStore');
|
|
1055
|
+
this.initialized = new Promise((res, rej) => {
|
|
1056
|
+
this.initResolve = res;
|
|
1057
|
+
this.initReject = rej;
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
else {
|
|
1061
|
+
await this.initialized;
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
this.storage = new storage_1.ExclusiveStorage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
|
|
1065
|
+
await this.storage.init();
|
|
1066
|
+
checkSchemaInitialized();
|
|
1067
|
+
await checkSchemaVersion(this.storage, schema.version);
|
|
1068
|
+
const { aws_appsync_graphqlEndpoint } = this.amplifyConfig;
|
|
1069
|
+
if (aws_appsync_graphqlEndpoint) {
|
|
1070
|
+
logger.debug('GraphQL endpoint available', aws_appsync_graphqlEndpoint);
|
|
1071
|
+
this.syncPredicates = await this.processSyncExpressions();
|
|
1072
|
+
this.sync = new sync_1.SyncEngine(schema, namespaceResolver, exports.syncClasses, userClasses, this.storage, modelInstanceCreator, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy, this.amplifyContext, this.connectivityMonitor);
|
|
1073
|
+
const fullSyncIntervalInMilliseconds = this.fullSyncInterval * 1000 * 60; // fullSyncInterval from param is in minutes
|
|
1074
|
+
syncSubscription = this.sync
|
|
1075
|
+
.start({ fullSyncInterval: fullSyncIntervalInMilliseconds })
|
|
1076
|
+
.subscribe({
|
|
1077
|
+
next: ({ type, data }) => {
|
|
1078
|
+
// In the Browser, we can begin returning data once subscriptions are in place.
|
|
1079
|
+
const readyType = (0, utils_1.isBrowser)()
|
|
1080
|
+
? sync_1.ControlMessage.SYNC_ENGINE_STORAGE_SUBSCRIBED
|
|
1081
|
+
: sync_1.ControlMessage.SYNC_ENGINE_SYNC_QUERIES_READY;
|
|
1082
|
+
if (type === readyType) {
|
|
1083
|
+
this.initResolve();
|
|
1470
1084
|
}
|
|
1085
|
+
core_1.Hub.dispatch('datastore', {
|
|
1086
|
+
event: type,
|
|
1087
|
+
data,
|
|
1088
|
+
});
|
|
1089
|
+
},
|
|
1090
|
+
error: err => {
|
|
1091
|
+
logger.warn('Sync error', err);
|
|
1092
|
+
this.initReject();
|
|
1093
|
+
},
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
else {
|
|
1097
|
+
logger.warn("Data won't be synchronized. No GraphQL endpoint configured. Did you forget `Amplify.configure(awsconfig)`?", {
|
|
1098
|
+
config: this.amplifyConfig,
|
|
1099
|
+
});
|
|
1100
|
+
this.initResolve();
|
|
1101
|
+
}
|
|
1102
|
+
await this.initialized;
|
|
1103
|
+
this.state = DataStoreState.Running;
|
|
1104
|
+
}, 'datastore start')
|
|
1105
|
+
.catch(this.handleAddProcError('DataStore.start()'));
|
|
1106
|
+
};
|
|
1107
|
+
this.query = async (modelConstructor, identifierOrCriteria, paginationProducer) => {
|
|
1108
|
+
return this.runningProcesses
|
|
1109
|
+
.add(async () => {
|
|
1110
|
+
await this.start();
|
|
1111
|
+
let result;
|
|
1112
|
+
if (!this.storage) {
|
|
1113
|
+
throw new Error('No storage to query');
|
|
1114
|
+
}
|
|
1115
|
+
//#region Input validation
|
|
1116
|
+
if (!isValidModelConstructor(modelConstructor)) {
|
|
1117
|
+
const msg = 'Constructor is not for a valid model';
|
|
1118
|
+
logger.error(msg, { modelConstructor });
|
|
1119
|
+
throw new Error(msg);
|
|
1120
|
+
}
|
|
1121
|
+
if (typeof identifierOrCriteria === 'string') {
|
|
1122
|
+
if (paginationProducer !== undefined) {
|
|
1123
|
+
logger.warn('Pagination is ignored when querying by id');
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1127
|
+
if (!modelDefinition) {
|
|
1128
|
+
throw new Error('Invalid model definition provided!');
|
|
1129
|
+
}
|
|
1130
|
+
const pagination = this.processPagination(modelDefinition, paginationProducer);
|
|
1131
|
+
const keyFields = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
1132
|
+
if (isQueryOne(identifierOrCriteria)) {
|
|
1133
|
+
if (keyFields.length > 1) {
|
|
1134
|
+
const msg = util_1.errorMessages.queryByPkWithCompositeKeyPresent;
|
|
1135
|
+
logger.error(msg, { keyFields });
|
|
1136
|
+
throw new Error(msg);
|
|
1137
|
+
}
|
|
1138
|
+
const predicate = predicates_1.ModelPredicateCreator.createFromFlatEqualities(modelDefinition, { [keyFields[0]]: identifierOrCriteria });
|
|
1139
|
+
result = await this.storage.query(modelConstructor, predicate, pagination);
|
|
1140
|
+
}
|
|
1141
|
+
else {
|
|
1142
|
+
// Object is being queried using object literal syntax
|
|
1143
|
+
if ((0, types_1.isIdentifierObject)(identifierOrCriteria, modelDefinition)) {
|
|
1144
|
+
const predicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
|
|
1145
|
+
result = await this.storage.query(modelConstructor, predicate, pagination);
|
|
1146
|
+
}
|
|
1147
|
+
else if (!identifierOrCriteria ||
|
|
1148
|
+
(0, predicates_1.isPredicatesAll)(identifierOrCriteria)) {
|
|
1149
|
+
result = await this.storage?.query(modelConstructor, undefined, pagination);
|
|
1150
|
+
}
|
|
1151
|
+
else {
|
|
1152
|
+
const seedPredicate = (0, next_1.recursivePredicateFor)({
|
|
1153
|
+
builder: modelConstructor,
|
|
1154
|
+
schema: modelDefinition,
|
|
1155
|
+
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
1471
1156
|
});
|
|
1472
|
-
|
|
1473
|
-
.
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
"Data integrity error. You tried to save a ".concat(modelDefinition.name, " (").concat(JSON.stringify(model), ")"),
|
|
1535
|
-
"but the instance assigned to the \"".concat(relationship.field, "\" property"),
|
|
1536
|
-
"does not exist in the local database. If you're trying to create the related",
|
|
1537
|
-
"\"".concat((_b = relationship.remoteDefinition) === null || _b === void 0 ? void 0 : _b.name, "\", you must save it independently first."),
|
|
1538
|
-
].join(' '));
|
|
1539
|
-
}
|
|
1540
|
-
_c.label = 4;
|
|
1541
|
-
case 4:
|
|
1542
|
-
nonHasManyRelationships_1_1 = nonHasManyRelationships_1.next();
|
|
1543
|
-
return [3 /*break*/, 2];
|
|
1544
|
-
case 5: return [3 /*break*/, 8];
|
|
1545
|
-
case 6:
|
|
1546
|
-
e_7_1 = _c.sent();
|
|
1547
|
-
e_7 = { error: e_7_1 };
|
|
1548
|
-
return [3 /*break*/, 8];
|
|
1549
|
-
case 7:
|
|
1550
|
-
try {
|
|
1551
|
-
if (nonHasManyRelationships_1_1 && !nonHasManyRelationships_1_1.done && (_a = nonHasManyRelationships_1.return)) _a.call(nonHasManyRelationships_1);
|
|
1552
|
-
}
|
|
1553
|
-
finally { if (e_7) throw e_7.error; }
|
|
1554
|
-
return [7 /*endfinally*/];
|
|
1555
|
-
case 8: return [2 /*return*/];
|
|
1556
|
-
}
|
|
1557
|
-
});
|
|
1558
|
-
}); })];
|
|
1559
|
-
case 2:
|
|
1560
|
-
_b.sent();
|
|
1561
|
-
producedCondition = condition
|
|
1562
|
-
? (0, next_1.internals)(condition((0, next_1.predicateFor)(modelMeta))).toStoragePredicate()
|
|
1563
|
-
: undefined;
|
|
1564
|
-
return [4 /*yield*/, this.storage.runExclusive(function (s) { return __awaiter(_this, void 0, void 0, function () {
|
|
1565
|
-
var saved;
|
|
1566
|
-
return __generator(this, function (_a) {
|
|
1567
|
-
switch (_a.label) {
|
|
1568
|
-
case 0: return [4 /*yield*/, s.save(model, producedCondition, undefined, patchesTuple)];
|
|
1569
|
-
case 1:
|
|
1570
|
-
saved = _a.sent();
|
|
1571
|
-
return [2 /*return*/, s.query(modelConstructor, predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model))];
|
|
1572
|
-
}
|
|
1573
|
-
});
|
|
1574
|
-
}); })];
|
|
1575
|
-
case 3:
|
|
1576
|
-
_a = __read.apply(void 0, [_b.sent(), 1]), savedModel = _a[0];
|
|
1577
|
-
return [2 /*return*/, attached(savedModel, ModelAttachment.DataStore)];
|
|
1157
|
+
const predicate = (0, next_1.internals)(identifierOrCriteria(seedPredicate));
|
|
1158
|
+
result = (await predicate.fetch(this.storage));
|
|
1159
|
+
result = (0, util_1.inMemoryPagination)(result, pagination);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
//#endregion
|
|
1163
|
+
const returnOne = isQueryOne(identifierOrCriteria) ||
|
|
1164
|
+
(0, types_1.isIdentifierObject)(identifierOrCriteria, modelDefinition);
|
|
1165
|
+
return attached(returnOne ? result[0] : result, ModelAttachment.DataStore);
|
|
1166
|
+
}, 'datastore query')
|
|
1167
|
+
.catch(this.handleAddProcError('DataStore.query()'));
|
|
1168
|
+
};
|
|
1169
|
+
this.save = async (model, condition) => {
|
|
1170
|
+
return this.runningProcesses
|
|
1171
|
+
.add(async () => {
|
|
1172
|
+
await this.start();
|
|
1173
|
+
if (!this.storage) {
|
|
1174
|
+
throw new Error('No storage to save to');
|
|
1175
|
+
}
|
|
1176
|
+
// Immer patches for constructing a correct update mutation input
|
|
1177
|
+
// Allows us to only include changed fields for updates
|
|
1178
|
+
const updatedPatchesTuple = modelPatchesMap.get(model);
|
|
1179
|
+
// Immer patches for initial object construction. These are used if
|
|
1180
|
+
// there are no `update` patches under the assumption we're performing
|
|
1181
|
+
// a CREATE and wish to send only explicitly specified fields to the cloud.
|
|
1182
|
+
const initPatchesTuple = initPatches.has(model)
|
|
1183
|
+
? [initPatches.get(model), {}]
|
|
1184
|
+
: undefined;
|
|
1185
|
+
// favor update patches over init/create patches, because init patches
|
|
1186
|
+
// are ALWAYS present, whereas update patches are only present if copyOf
|
|
1187
|
+
// was used to create the instance.
|
|
1188
|
+
const patchesTuple = updatedPatchesTuple || initPatchesTuple;
|
|
1189
|
+
const modelConstructor = model ? model.constructor : undefined;
|
|
1190
|
+
if (!isValidModelConstructor(modelConstructor)) {
|
|
1191
|
+
const msg = 'Object is not an instance of a valid model';
|
|
1192
|
+
logger.error(msg, { model });
|
|
1193
|
+
throw new Error(msg);
|
|
1194
|
+
}
|
|
1195
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1196
|
+
if (!modelDefinition) {
|
|
1197
|
+
throw new Error('Model Definition could not be found for model');
|
|
1198
|
+
}
|
|
1199
|
+
const modelMeta = {
|
|
1200
|
+
builder: modelConstructor,
|
|
1201
|
+
schema: modelDefinition,
|
|
1202
|
+
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
1203
|
+
};
|
|
1204
|
+
await this.storage.runExclusive(async (s) => {
|
|
1205
|
+
// no enforcement for HAS_MANY on save, because the ~related~ entities
|
|
1206
|
+
// hold the FK in that case.
|
|
1207
|
+
const nonHasManyRelationships = relationship_1.ModelRelationship.allFrom(modelMeta).filter(r => r.type === 'BELONGS_TO');
|
|
1208
|
+
for (const relationship of nonHasManyRelationships) {
|
|
1209
|
+
const queryObject = relationship.createRemoteQueryObject(model);
|
|
1210
|
+
if (queryObject !== null) {
|
|
1211
|
+
const related = await s.query(relationship.remoteModelConstructor, predicates_1.ModelPredicateCreator.createFromFlatEqualities(relationship.remoteDefinition, queryObject));
|
|
1212
|
+
if (related.length === 0) {
|
|
1213
|
+
throw new Error([
|
|
1214
|
+
`Data integrity error. You tried to save a ${modelDefinition.name} (${JSON.stringify(model)})`,
|
|
1215
|
+
`but the instance assigned to the "${relationship.field}" property`,
|
|
1216
|
+
`does not exist in the local database. If you're trying to create the related`,
|
|
1217
|
+
`"${relationship.remoteDefinition?.name}", you must save it independently first.`,
|
|
1218
|
+
].join(' '));
|
|
1578
1219
|
}
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
const producedCondition = condition
|
|
1224
|
+
? (0, next_1.internals)(condition((0, next_1.predicateFor)(modelMeta))).toStoragePredicate()
|
|
1225
|
+
: undefined;
|
|
1226
|
+
const [savedModel] = await this.storage.runExclusive(async (s) => {
|
|
1227
|
+
const saved = await s.save(model, producedCondition, undefined, patchesTuple);
|
|
1228
|
+
return s.query(modelConstructor, predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model));
|
|
1229
|
+
});
|
|
1230
|
+
return attached(savedModel, ModelAttachment.DataStore);
|
|
1231
|
+
}, 'datastore save')
|
|
1232
|
+
.catch(this.handleAddProcError('DataStore.save()'));
|
|
1233
|
+
};
|
|
1234
|
+
this.setConflictHandler = (config) => {
|
|
1235
|
+
const { DataStore: configDataStore } = config;
|
|
1236
|
+
const conflictHandlerIsDefault = () => this.conflictHandler === defaultConflictHandler;
|
|
1589
1237
|
if (configDataStore && configDataStore.conflictHandler) {
|
|
1590
1238
|
return configDataStore.conflictHandler;
|
|
1591
1239
|
}
|
|
1592
1240
|
if (conflictHandlerIsDefault() && config.conflictHandler) {
|
|
1593
1241
|
return config.conflictHandler;
|
|
1594
1242
|
}
|
|
1595
|
-
return
|
|
1243
|
+
return this.conflictHandler || defaultConflictHandler;
|
|
1596
1244
|
};
|
|
1597
|
-
this.setErrorHandler =
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
return _this.errorHandler === defaultErrorHandler;
|
|
1601
|
-
};
|
|
1245
|
+
this.setErrorHandler = (config) => {
|
|
1246
|
+
const { DataStore: configDataStore } = config;
|
|
1247
|
+
const errorHandlerIsDefault = () => this.errorHandler === defaultErrorHandler;
|
|
1602
1248
|
if (configDataStore && configDataStore.errorHandler) {
|
|
1603
1249
|
return configDataStore.errorHandler;
|
|
1604
1250
|
}
|
|
1605
1251
|
if (errorHandlerIsDefault() && config.errorHandler) {
|
|
1606
1252
|
return config.errorHandler;
|
|
1607
1253
|
}
|
|
1608
|
-
return
|
|
1254
|
+
return this.errorHandler || defaultErrorHandler;
|
|
1609
1255
|
};
|
|
1610
|
-
this.delete =
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
case 4:
|
|
1703
|
-
_b = __read.apply(void 0, [_e.sent(), 1]), _c = __read(_b[0], 1), deleted = _c[0];
|
|
1704
|
-
return [2 /*return*/, attached(deleted, ModelAttachment.DataStore)];
|
|
1705
|
-
}
|
|
1706
|
-
});
|
|
1707
|
-
}); }, 'datastore delete')
|
|
1708
|
-
.catch(this.handleAddProcError('DataStore.delete()'))];
|
|
1709
|
-
});
|
|
1710
|
-
}); };
|
|
1711
|
-
this.observe = function (modelOrConstructor, identifierOrCriteria) {
|
|
1712
|
-
var executivePredicate;
|
|
1713
|
-
var modelConstructor = modelOrConstructor && isValidModelConstructor(modelOrConstructor)
|
|
1256
|
+
this.delete = async (modelOrConstructor, identifierOrCriteria) => {
|
|
1257
|
+
return this.runningProcesses
|
|
1258
|
+
.add(async () => {
|
|
1259
|
+
await this.start();
|
|
1260
|
+
if (!this.storage) {
|
|
1261
|
+
throw new Error('No storage to delete from');
|
|
1262
|
+
}
|
|
1263
|
+
let condition;
|
|
1264
|
+
if (!modelOrConstructor) {
|
|
1265
|
+
const msg = 'Model or Model Constructor required';
|
|
1266
|
+
logger.error(msg, { modelOrConstructor });
|
|
1267
|
+
throw new Error(msg);
|
|
1268
|
+
}
|
|
1269
|
+
if (isValidModelConstructor(modelOrConstructor)) {
|
|
1270
|
+
const modelConstructor = modelOrConstructor;
|
|
1271
|
+
if (!identifierOrCriteria) {
|
|
1272
|
+
const msg = 'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
|
|
1273
|
+
logger.error(msg, { identifierOrCriteria });
|
|
1274
|
+
throw new Error(msg);
|
|
1275
|
+
}
|
|
1276
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1277
|
+
if (!modelDefinition) {
|
|
1278
|
+
throw new Error('Could not find model definition for modelConstructor.');
|
|
1279
|
+
}
|
|
1280
|
+
if (typeof identifierOrCriteria === 'string') {
|
|
1281
|
+
const keyFields = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
1282
|
+
if (keyFields.length > 1) {
|
|
1283
|
+
const msg = util_1.errorMessages.deleteByPkWithCompositeKeyPresent;
|
|
1284
|
+
logger.error(msg, { keyFields });
|
|
1285
|
+
throw new Error(msg);
|
|
1286
|
+
}
|
|
1287
|
+
condition = predicates_1.ModelPredicateCreator.createFromFlatEqualities(modelDefinition, { [keyFields[0]]: identifierOrCriteria });
|
|
1288
|
+
}
|
|
1289
|
+
else {
|
|
1290
|
+
if ((0, types_1.isIdentifierObject)(identifierOrCriteria, modelDefinition)) {
|
|
1291
|
+
condition = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
|
|
1292
|
+
}
|
|
1293
|
+
else {
|
|
1294
|
+
condition = (0, next_1.internals)(identifierOrCriteria((0, next_1.predicateFor)({
|
|
1295
|
+
builder: modelConstructor,
|
|
1296
|
+
schema: modelDefinition,
|
|
1297
|
+
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
1298
|
+
}))).toStoragePredicate();
|
|
1299
|
+
}
|
|
1300
|
+
if (!condition ||
|
|
1301
|
+
!predicates_1.ModelPredicateCreator.isValidPredicate(condition)) {
|
|
1302
|
+
const msg = 'Criteria required. Do you want to delete all? Pass Predicates.ALL';
|
|
1303
|
+
logger.error(msg, { condition });
|
|
1304
|
+
throw new Error(msg);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
const [deleted] = await this.storage.delete(modelConstructor, condition);
|
|
1308
|
+
return attached(deleted, ModelAttachment.DataStore);
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
const model = modelOrConstructor;
|
|
1312
|
+
const modelConstructor = Object.getPrototypeOf(model || {})
|
|
1313
|
+
.constructor;
|
|
1314
|
+
if (!isValidModelConstructor(modelConstructor)) {
|
|
1315
|
+
const msg = 'Object is not an instance of a valid model';
|
|
1316
|
+
logger.error(msg, { model });
|
|
1317
|
+
throw new Error(msg);
|
|
1318
|
+
}
|
|
1319
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1320
|
+
if (!modelDefinition) {
|
|
1321
|
+
throw new Error('Could not find model definition for modelConstructor.');
|
|
1322
|
+
}
|
|
1323
|
+
const pkPredicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model);
|
|
1324
|
+
if (identifierOrCriteria) {
|
|
1325
|
+
if (typeof identifierOrCriteria !== 'function') {
|
|
1326
|
+
const msg = 'Invalid criteria';
|
|
1327
|
+
logger.error(msg, { identifierOrCriteria });
|
|
1328
|
+
throw new Error(msg);
|
|
1329
|
+
}
|
|
1330
|
+
condition = (0, next_1.internals)(identifierOrCriteria((0, next_1.predicateFor)({
|
|
1331
|
+
builder: modelConstructor,
|
|
1332
|
+
schema: modelDefinition,
|
|
1333
|
+
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
1334
|
+
}))).toStoragePredicate();
|
|
1335
|
+
}
|
|
1336
|
+
else {
|
|
1337
|
+
condition = pkPredicate;
|
|
1338
|
+
}
|
|
1339
|
+
const [[deleted]] = await this.storage.delete(model, condition);
|
|
1340
|
+
return attached(deleted, ModelAttachment.DataStore);
|
|
1341
|
+
}
|
|
1342
|
+
}, 'datastore delete')
|
|
1343
|
+
.catch(this.handleAddProcError('DataStore.delete()'));
|
|
1344
|
+
};
|
|
1345
|
+
this.observe = (modelOrConstructor, identifierOrCriteria) => {
|
|
1346
|
+
let executivePredicate;
|
|
1347
|
+
const modelConstructor = modelOrConstructor && isValidModelConstructor(modelOrConstructor)
|
|
1714
1348
|
? modelOrConstructor
|
|
1715
1349
|
: undefined;
|
|
1716
1350
|
if (modelOrConstructor && modelConstructor === undefined) {
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
if (isValidModelConstructor(
|
|
1351
|
+
const model = modelOrConstructor;
|
|
1352
|
+
const modelConstructor = model && Object.getPrototypeOf(model).constructor;
|
|
1353
|
+
if (isValidModelConstructor(modelConstructor)) {
|
|
1720
1354
|
if (identifierOrCriteria) {
|
|
1721
1355
|
logger.warn('idOrCriteria is ignored when using a model instance', {
|
|
1722
|
-
model
|
|
1723
|
-
identifierOrCriteria
|
|
1356
|
+
model,
|
|
1357
|
+
identifierOrCriteria,
|
|
1724
1358
|
});
|
|
1725
1359
|
}
|
|
1726
|
-
return
|
|
1360
|
+
return this.observe(modelConstructor, model.id);
|
|
1727
1361
|
}
|
|
1728
1362
|
else {
|
|
1729
|
-
|
|
1730
|
-
logger.error(msg, { model
|
|
1363
|
+
const msg = 'The model is not an instance of a PersistentModelConstructor';
|
|
1364
|
+
logger.error(msg, { model });
|
|
1731
1365
|
throw new Error(msg);
|
|
1732
1366
|
}
|
|
1733
1367
|
}
|
|
@@ -1735,110 +1369,86 @@ var DataStore = /** @class */ (function () {
|
|
|
1735
1369
|
if (identifierOrCriteria &&
|
|
1736
1370
|
modelConstructor &&
|
|
1737
1371
|
(0, types_1.isIdentifierObject)(identifierOrCriteria, getModelDefinition(modelConstructor))) {
|
|
1738
|
-
|
|
1372
|
+
const msg = util_1.errorMessages.observeWithObjectLiteral;
|
|
1739
1373
|
logger.error(msg, { objectLiteral: identifierOrCriteria });
|
|
1740
1374
|
throw new Error(msg);
|
|
1741
1375
|
}
|
|
1742
1376
|
if (identifierOrCriteria !== undefined && modelConstructor === undefined) {
|
|
1743
|
-
|
|
1377
|
+
const msg = 'Cannot provide criteria without a modelConstructor';
|
|
1744
1378
|
logger.error(msg, identifierOrCriteria);
|
|
1745
1379
|
throw new Error(msg);
|
|
1746
1380
|
}
|
|
1747
1381
|
if (modelConstructor && !isValidModelConstructor(modelConstructor)) {
|
|
1748
|
-
|
|
1749
|
-
logger.error(msg, { modelConstructor
|
|
1382
|
+
const msg = 'Constructor is not for a valid model';
|
|
1383
|
+
logger.error(msg, { modelConstructor });
|
|
1750
1384
|
throw new Error(msg);
|
|
1751
1385
|
}
|
|
1752
1386
|
if (modelConstructor && typeof identifierOrCriteria === 'string') {
|
|
1753
|
-
|
|
1387
|
+
const buildIdPredicate = seed => seed.id.eq(identifierOrCriteria);
|
|
1754
1388
|
executivePredicate = (0, next_1.internals)(buildIdPredicate(buildSeedPredicate(modelConstructor)));
|
|
1755
1389
|
}
|
|
1756
1390
|
else if (modelConstructor && typeof identifierOrCriteria === 'function') {
|
|
1757
1391
|
executivePredicate = (0, next_1.internals)(identifierOrCriteria(buildSeedPredicate(modelConstructor)));
|
|
1758
1392
|
}
|
|
1759
|
-
return new rxjs_1.Observable(
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
.add(
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
case 2:
|
|
1795
|
-
_a = !executivePredicate;
|
|
1796
|
-
if (_a) return [3 /*break*/, 4];
|
|
1797
|
-
return [4 /*yield*/, executivePredicate.matches(message.element)];
|
|
1798
|
-
case 3:
|
|
1799
|
-
_a = (_b.sent());
|
|
1800
|
-
_b.label = 4;
|
|
1801
|
-
case 4:
|
|
1802
|
-
if (_a) {
|
|
1803
|
-
observer.next(message);
|
|
1804
|
-
}
|
|
1805
|
-
return [2 /*return*/];
|
|
1806
|
-
}
|
|
1807
|
-
});
|
|
1808
|
-
}); }, 'datastore observe message handler');
|
|
1809
|
-
},
|
|
1810
|
-
error: function (err) { return observer.error(err); },
|
|
1811
|
-
complete: function () { return observer.complete(); },
|
|
1812
|
-
});
|
|
1813
|
-
return [2 /*return*/];
|
|
1814
|
-
}
|
|
1393
|
+
return new rxjs_1.Observable(observer => {
|
|
1394
|
+
let source;
|
|
1395
|
+
this.runningProcesses
|
|
1396
|
+
.add(async () => {
|
|
1397
|
+
await this.start();
|
|
1398
|
+
// Filter the events returned by Storage according to namespace,
|
|
1399
|
+
// append original element data, and subscribe to the observable
|
|
1400
|
+
source = this.storage.observe(modelConstructor)
|
|
1401
|
+
.pipe((0, rxjs_1.filter)(({ model }) => namespaceResolver(model) === util_1.USER))
|
|
1402
|
+
.subscribe({
|
|
1403
|
+
next: item => this.runningProcesses.isOpen &&
|
|
1404
|
+
this.runningProcesses.add(async () => {
|
|
1405
|
+
// the `element` doesn't necessarily contain all item details or
|
|
1406
|
+
// have related records attached consistently with that of a query()
|
|
1407
|
+
// result item. for consistency, we attach them here.
|
|
1408
|
+
let message = item;
|
|
1409
|
+
// as long as we're not dealing with a DELETE, we need to fetch a fresh
|
|
1410
|
+
// item from storage to ensure it's fully populated.
|
|
1411
|
+
if (item.opType !== 'DELETE') {
|
|
1412
|
+
const modelDefinition = getModelDefinition(item.model);
|
|
1413
|
+
const keyFields = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
1414
|
+
const primaryKeysAndValues = (0, util_1.extractPrimaryKeysAndValues)(item.element, keyFields);
|
|
1415
|
+
const freshElement = await this.query(item.model, primaryKeysAndValues);
|
|
1416
|
+
message = {
|
|
1417
|
+
...message,
|
|
1418
|
+
element: freshElement,
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
if (!executivePredicate ||
|
|
1422
|
+
(await executivePredicate.matches(message.element))) {
|
|
1423
|
+
observer.next(message);
|
|
1424
|
+
}
|
|
1425
|
+
}, 'datastore observe message handler'),
|
|
1426
|
+
error: err => observer.error(err),
|
|
1427
|
+
complete: () => observer.complete(),
|
|
1815
1428
|
});
|
|
1816
|
-
}
|
|
1817
|
-
.catch(
|
|
1818
|
-
.catch(
|
|
1429
|
+
}, 'datastore observe observable initialization')
|
|
1430
|
+
.catch(this.handleAddProcError('DataStore.observe()'))
|
|
1431
|
+
.catch(error => {
|
|
1819
1432
|
observer.error(error);
|
|
1820
1433
|
});
|
|
1821
1434
|
// better than no cleaner, but if the subscriber is handling the
|
|
1822
1435
|
// complete() message async and not registering with the context,
|
|
1823
1436
|
// this will still be problematic.
|
|
1824
|
-
return
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
return [2 /*return*/];
|
|
1830
|
-
});
|
|
1831
|
-
}); }, 'DataStore.observe() cleanup');
|
|
1437
|
+
return this.runningProcesses.addCleaner(async () => {
|
|
1438
|
+
if (source) {
|
|
1439
|
+
source.unsubscribe();
|
|
1440
|
+
}
|
|
1441
|
+
}, 'DataStore.observe() cleanup');
|
|
1832
1442
|
});
|
|
1833
1443
|
};
|
|
1834
|
-
this.observeQuery =
|
|
1835
|
-
return new rxjs_1.Observable(
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1444
|
+
this.observeQuery = (model, criteria, options) => {
|
|
1445
|
+
return new rxjs_1.Observable(observer => {
|
|
1446
|
+
const items = new Map();
|
|
1447
|
+
const itemsChanged = new Map();
|
|
1448
|
+
let deletedItemIds = [];
|
|
1449
|
+
let handle;
|
|
1840
1450
|
// let predicate: ModelPredicate<T> | undefined;
|
|
1841
|
-
|
|
1451
|
+
let executivePredicate;
|
|
1842
1452
|
/**
|
|
1843
1453
|
* As the name suggests, this geneates a snapshot in the form of
|
|
1844
1454
|
* `{items: T[], isSynced: boolean}`
|
|
@@ -1849,20 +1459,20 @@ var DataStore = /** @class */ (function () {
|
|
|
1849
1459
|
*
|
|
1850
1460
|
* Refer to `generateSnapshot` and `emitSnapshot` for more details.
|
|
1851
1461
|
*/
|
|
1852
|
-
|
|
1853
|
-
|
|
1462
|
+
const generateAndEmitSnapshot = () => {
|
|
1463
|
+
const snapshot = generateSnapshot();
|
|
1854
1464
|
emitSnapshot(snapshot);
|
|
1855
1465
|
};
|
|
1856
1466
|
// a mechanism to return data after X amount of seconds OR after the
|
|
1857
1467
|
// "limit" (itemsChanged >= this.syncPageSize) has been reached, whichever comes first
|
|
1858
|
-
|
|
1468
|
+
const limitTimerRace = new util_1.DeferredCallbackResolver({
|
|
1859
1469
|
callback: generateAndEmitSnapshot,
|
|
1860
1470
|
errorHandler: observer.error,
|
|
1861
1471
|
maxInterval: 2000,
|
|
1862
1472
|
});
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1473
|
+
const { sort } = options || {};
|
|
1474
|
+
const sortOptions = sort ? { sort } : undefined;
|
|
1475
|
+
const modelDefinition = getModelDefinition(model);
|
|
1866
1476
|
if (!modelDefinition) {
|
|
1867
1477
|
throw new Error('Could not find model definition.');
|
|
1868
1478
|
}
|
|
@@ -1872,94 +1482,66 @@ var DataStore = /** @class */ (function () {
|
|
|
1872
1482
|
else if ((0, predicates_1.isPredicatesAll)(criteria)) {
|
|
1873
1483
|
executivePredicate = undefined;
|
|
1874
1484
|
}
|
|
1875
|
-
|
|
1876
|
-
.add(
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
itemsChanged.set(idOrPk, element);
|
|
1936
|
-
}
|
|
1937
|
-
isSynced = (_c = (_b = this.sync) === null || _b === void 0 ? void 0 : _b.getModelSyncedStatus(model)) !== null && _c !== void 0 ? _c : false;
|
|
1938
|
-
limit = itemsChanged.size - deletedItemIds.length >=
|
|
1939
|
-
this.syncPageSize;
|
|
1940
|
-
if (limit || isSynced) {
|
|
1941
|
-
limitTimerRace.resolve();
|
|
1942
|
-
}
|
|
1943
|
-
// kicks off every subsequent race as results sync down
|
|
1944
|
-
limitTimerRace.start();
|
|
1945
|
-
return [2 /*return*/];
|
|
1946
|
-
}
|
|
1947
|
-
});
|
|
1948
|
-
}); }, 'handle observeQuery observed event');
|
|
1949
|
-
});
|
|
1950
|
-
// returns a set of initial/locally-available results
|
|
1951
|
-
generateAndEmitSnapshot();
|
|
1952
|
-
return [3 /*break*/, 3];
|
|
1953
|
-
case 2:
|
|
1954
|
-
err_1 = _a.sent();
|
|
1955
|
-
observer.error(err_1);
|
|
1956
|
-
return [3 /*break*/, 3];
|
|
1957
|
-
case 3: return [2 /*return*/];
|
|
1958
|
-
}
|
|
1959
|
-
});
|
|
1960
|
-
}); }, 'datastore observequery startup')
|
|
1961
|
-
.catch(_this.handleAddProcError('DataStore.observeQuery()'))
|
|
1962
|
-
.catch(function (error) {
|
|
1485
|
+
this.runningProcesses
|
|
1486
|
+
.add(async () => {
|
|
1487
|
+
try {
|
|
1488
|
+
// first, query and return any locally-available records
|
|
1489
|
+
(await this.query(model, criteria, sortOptions)).forEach(item => {
|
|
1490
|
+
const itemModelDefinition = getModelDefinition(model);
|
|
1491
|
+
const idOrPk = (0, utils_2.getIdentifierValue)(itemModelDefinition, item);
|
|
1492
|
+
items.set(idOrPk, item);
|
|
1493
|
+
});
|
|
1494
|
+
// Observe the model and send a stream of updates (debounced).
|
|
1495
|
+
// We need to post-filter results instead of passing criteria through
|
|
1496
|
+
// to have visibility into items that move from in-set to out-of-set.
|
|
1497
|
+
// We need to explicitly remove those items from the existing snapshot.
|
|
1498
|
+
handle = this.observe(model).subscribe(({ element, model, opType }) => this.runningProcesses.isOpen &&
|
|
1499
|
+
this.runningProcesses.add(async () => {
|
|
1500
|
+
const itemModelDefinition = getModelDefinition(model);
|
|
1501
|
+
const idOrPk = (0, utils_2.getIdentifierValue)(itemModelDefinition, element);
|
|
1502
|
+
if (executivePredicate &&
|
|
1503
|
+
!(await executivePredicate.matches(element))) {
|
|
1504
|
+
if (opType === 'UPDATE' &&
|
|
1505
|
+
(items.has(idOrPk) || itemsChanged.has(idOrPk))) {
|
|
1506
|
+
// tracking as a "deleted item" will include the item in
|
|
1507
|
+
// page limit calculations and ensure it is removed from the
|
|
1508
|
+
// final items collection, regardless of which collection(s)
|
|
1509
|
+
// it is currently in. (I mean, it could be in both, right!?)
|
|
1510
|
+
deletedItemIds.push(idOrPk);
|
|
1511
|
+
}
|
|
1512
|
+
else {
|
|
1513
|
+
// ignore updates for irrelevant/filtered items.
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
// Flag items which have been recently deleted
|
|
1518
|
+
// NOTE: Merging of separate operations to the same model instance is handled upstream
|
|
1519
|
+
// in the `mergePage` method within src/sync/merger.ts. The final state of a model instance
|
|
1520
|
+
// depends on the LATEST record (for a given id).
|
|
1521
|
+
if (opType === 'DELETE') {
|
|
1522
|
+
deletedItemIds.push(idOrPk);
|
|
1523
|
+
}
|
|
1524
|
+
else {
|
|
1525
|
+
itemsChanged.set(idOrPk, element);
|
|
1526
|
+
}
|
|
1527
|
+
const isSynced = this.sync?.getModelSyncedStatus(model) ?? false;
|
|
1528
|
+
const limit = itemsChanged.size - deletedItemIds.length >=
|
|
1529
|
+
this.syncPageSize;
|
|
1530
|
+
if (limit || isSynced) {
|
|
1531
|
+
limitTimerRace.resolve();
|
|
1532
|
+
}
|
|
1533
|
+
// kicks off every subsequent race as results sync down
|
|
1534
|
+
limitTimerRace.start();
|
|
1535
|
+
}, 'handle observeQuery observed event'));
|
|
1536
|
+
// returns a set of initial/locally-available results
|
|
1537
|
+
generateAndEmitSnapshot();
|
|
1538
|
+
}
|
|
1539
|
+
catch (err) {
|
|
1540
|
+
observer.error(err);
|
|
1541
|
+
}
|
|
1542
|
+
}, 'datastore observequery startup')
|
|
1543
|
+
.catch(this.handleAddProcError('DataStore.observeQuery()'))
|
|
1544
|
+
.catch(error => {
|
|
1963
1545
|
observer.error(error);
|
|
1964
1546
|
});
|
|
1965
1547
|
/**
|
|
@@ -1968,27 +1550,29 @@ var DataStore = /** @class */ (function () {
|
|
|
1968
1550
|
*
|
|
1969
1551
|
* SIDE EFFECT: The shared `items` collection is recreated.
|
|
1970
1552
|
*/
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1553
|
+
const generateSnapshot = () => {
|
|
1554
|
+
const isSynced = this.sync?.getModelSyncedStatus(model) ?? false;
|
|
1555
|
+
const itemsArray = [
|
|
1556
|
+
...Array.from(items.values()),
|
|
1557
|
+
...Array.from(itemsChanged.values()),
|
|
1558
|
+
];
|
|
1975
1559
|
items.clear();
|
|
1976
|
-
itemsArray.forEach(
|
|
1977
|
-
|
|
1978
|
-
|
|
1560
|
+
itemsArray.forEach(item => {
|
|
1561
|
+
const itemModelDefinition = getModelDefinition(model);
|
|
1562
|
+
const idOrPk = (0, utils_2.getIdentifierValue)(itemModelDefinition, item);
|
|
1979
1563
|
items.set(idOrPk, item);
|
|
1980
1564
|
});
|
|
1981
1565
|
// remove deleted items from the final result set
|
|
1982
|
-
deletedItemIds.forEach(
|
|
1983
|
-
|
|
1566
|
+
deletedItemIds.forEach(idOrPk => items.delete(idOrPk));
|
|
1567
|
+
const snapshot = Array.from(items.values());
|
|
1984
1568
|
// we sort after we merge the snapshots (items, itemsChanged)
|
|
1985
1569
|
// otherwise, the merge may not
|
|
1986
|
-
if (options
|
|
1570
|
+
if (options?.sort) {
|
|
1987
1571
|
sortItems(snapshot);
|
|
1988
1572
|
}
|
|
1989
1573
|
return {
|
|
1990
1574
|
items: snapshot,
|
|
1991
|
-
isSynced
|
|
1575
|
+
isSynced,
|
|
1992
1576
|
};
|
|
1993
1577
|
};
|
|
1994
1578
|
/**
|
|
@@ -1999,7 +1583,7 @@ var DataStore = /** @class */ (function () {
|
|
|
1999
1583
|
*
|
|
2000
1584
|
* @param snapshot The generated items data to emit.
|
|
2001
1585
|
*/
|
|
2002
|
-
|
|
1586
|
+
const emitSnapshot = (snapshot) => {
|
|
2003
1587
|
// send the generated snapshot to the primary subscription.
|
|
2004
1588
|
// NOTE: This observer's handler *could* be async ...
|
|
2005
1589
|
observer.next(snapshot);
|
|
@@ -2013,12 +1597,12 @@ var DataStore = /** @class */ (function () {
|
|
|
2013
1597
|
*
|
|
2014
1598
|
* @param itemsToSort A array of model type.
|
|
2015
1599
|
*/
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
1600
|
+
const sortItems = (itemsToSort) => {
|
|
1601
|
+
const modelDefinition = getModelDefinition(model);
|
|
1602
|
+
const pagination = this.processPagination(modelDefinition, options);
|
|
1603
|
+
const sortPredicates = predicates_1.ModelSortPredicateCreator.getPredicates(pagination.sort);
|
|
2020
1604
|
if (sortPredicates.length) {
|
|
2021
|
-
|
|
1605
|
+
const compareFn = (0, util_1.sortCompareFunction)(sortPredicates);
|
|
2022
1606
|
itemsToSort.sort(compareFn);
|
|
2023
1607
|
}
|
|
2024
1608
|
};
|
|
@@ -2030,93 +1614,90 @@ var DataStore = /** @class */ (function () {
|
|
|
2030
1614
|
*
|
|
2031
1615
|
* @param payload The payload from the Hub event.
|
|
2032
1616
|
*/
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
var payload = _a.payload;
|
|
2036
|
-
var event = payload.event, data = payload.data;
|
|
1617
|
+
const hubCallback = ({ payload }) => {
|
|
1618
|
+
const { event, data } = payload;
|
|
2037
1619
|
if (event === sync_1.ControlMessage.SYNC_ENGINE_MODEL_SYNCED &&
|
|
2038
|
-
|
|
1620
|
+
data?.model?.name === model.name) {
|
|
2039
1621
|
generateAndEmitSnapshot();
|
|
2040
1622
|
hubRemove();
|
|
2041
1623
|
}
|
|
2042
1624
|
};
|
|
2043
|
-
|
|
2044
|
-
return
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
return [2 /*return*/];
|
|
2050
|
-
});
|
|
2051
|
-
}); }, 'datastore observequery cleaner');
|
|
1625
|
+
const hubRemove = core_1.Hub.listen('datastore', hubCallback);
|
|
1626
|
+
return this.runningProcesses.addCleaner(async () => {
|
|
1627
|
+
if (handle) {
|
|
1628
|
+
handle.unsubscribe();
|
|
1629
|
+
}
|
|
1630
|
+
}, 'datastore observequery cleaner');
|
|
2052
1631
|
});
|
|
2053
1632
|
};
|
|
2054
|
-
this.configure =
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
1633
|
+
this.configure = (config = {}) => {
|
|
1634
|
+
this.amplifyContext.InternalAPI = this.InternalAPI;
|
|
1635
|
+
const { DataStore: configDataStore, authModeStrategyType: configAuthModeStrategyType, conflictHandler: configConflictHandler, errorHandler: configErrorHandler, maxRecordsToSync: configMaxRecordsToSync, syncPageSize: configSyncPageSize, fullSyncInterval: configFullSyncInterval, syncExpressions: configSyncExpressions, authProviders: configAuthProviders, storageAdapter: configStorageAdapter, ...configFromAmplify } = config;
|
|
1636
|
+
const currentAppSyncConfig = core_1.Amplify.getConfig().API?.GraphQL;
|
|
1637
|
+
const appSyncConfig = {
|
|
1638
|
+
aws_appsync_graphqlEndpoint: currentAppSyncConfig?.endpoint,
|
|
1639
|
+
aws_appsync_authenticationType: currentAppSyncConfig?.defaultAuthMode,
|
|
1640
|
+
aws_appsync_region: currentAppSyncConfig?.region,
|
|
1641
|
+
aws_appsync_apiKey: currentAppSyncConfig?.apiKey,
|
|
1642
|
+
};
|
|
1643
|
+
this.amplifyConfig = {
|
|
1644
|
+
...this.amplifyConfig,
|
|
1645
|
+
...configFromAmplify,
|
|
1646
|
+
...(currentAppSyncConfig && appSyncConfig),
|
|
2065
1647
|
};
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
var authModeStrategyType = (configDataStore && configDataStore.authModeStrategyType) ||
|
|
1648
|
+
this.conflictHandler = this.setConflictHandler(config);
|
|
1649
|
+
this.errorHandler = this.setErrorHandler(config);
|
|
1650
|
+
const authModeStrategyType = (configDataStore && configDataStore.authModeStrategyType) ||
|
|
2070
1651
|
configAuthModeStrategyType ||
|
|
2071
1652
|
types_1.AuthModeStrategyType.DEFAULT;
|
|
2072
1653
|
switch (authModeStrategyType) {
|
|
2073
1654
|
case types_1.AuthModeStrategyType.MULTI_AUTH:
|
|
2074
|
-
|
|
1655
|
+
this.authModeStrategy = (0, authModeStrategies_1.multiAuthStrategy)(this.amplifyContext);
|
|
2075
1656
|
break;
|
|
2076
1657
|
case types_1.AuthModeStrategyType.DEFAULT:
|
|
2077
|
-
|
|
1658
|
+
this.authModeStrategy = authModeStrategies_1.defaultAuthStrategy;
|
|
2078
1659
|
break;
|
|
2079
1660
|
default:
|
|
2080
|
-
|
|
1661
|
+
this.authModeStrategy = authModeStrategies_1.defaultAuthStrategy;
|
|
2081
1662
|
break;
|
|
2082
1663
|
}
|
|
2083
1664
|
// store on config object, so that Sync, Subscription, and Mutation processors can have access
|
|
2084
|
-
|
|
1665
|
+
this.amplifyConfig.authProviders =
|
|
2085
1666
|
(configDataStore && configDataStore.authProviders) || configAuthProviders;
|
|
2086
|
-
|
|
1667
|
+
this.syncExpressions =
|
|
2087
1668
|
(configDataStore && configDataStore.syncExpressions) ||
|
|
2088
1669
|
configSyncExpressions ||
|
|
2089
|
-
|
|
2090
|
-
|
|
1670
|
+
this.syncExpressions;
|
|
1671
|
+
this.maxRecordsToSync =
|
|
2091
1672
|
(configDataStore && configDataStore.maxRecordsToSync) ||
|
|
2092
1673
|
configMaxRecordsToSync ||
|
|
2093
|
-
|
|
1674
|
+
this.maxRecordsToSync ||
|
|
2094
1675
|
10000;
|
|
2095
1676
|
// store on config object, so that Sync, Subscription, and Mutation processors can have access
|
|
2096
|
-
|
|
2097
|
-
|
|
1677
|
+
this.amplifyConfig.maxRecordsToSync = this.maxRecordsToSync;
|
|
1678
|
+
this.syncPageSize =
|
|
2098
1679
|
(configDataStore && configDataStore.syncPageSize) ||
|
|
2099
1680
|
configSyncPageSize ||
|
|
2100
|
-
|
|
1681
|
+
this.syncPageSize ||
|
|
2101
1682
|
1000;
|
|
2102
1683
|
// store on config object, so that Sync, Subscription, and Mutation processors can have access
|
|
2103
|
-
|
|
2104
|
-
|
|
1684
|
+
this.amplifyConfig.syncPageSize = this.syncPageSize;
|
|
1685
|
+
this.fullSyncInterval =
|
|
2105
1686
|
(configDataStore && configDataStore.fullSyncInterval) ||
|
|
2106
1687
|
configFullSyncInterval ||
|
|
2107
|
-
|
|
1688
|
+
this.fullSyncInterval ||
|
|
2108
1689
|
24 * 60; // 1 day
|
|
2109
|
-
|
|
1690
|
+
this.storageAdapter =
|
|
2110
1691
|
(configDataStore && configDataStore.storageAdapter) ||
|
|
2111
1692
|
configStorageAdapter ||
|
|
2112
|
-
|
|
1693
|
+
this.storageAdapter ||
|
|
2113
1694
|
undefined;
|
|
2114
|
-
|
|
1695
|
+
this.sessionId = this.retrieveSessionId();
|
|
2115
1696
|
};
|
|
2116
1697
|
}
|
|
2117
|
-
|
|
1698
|
+
getModuleName() {
|
|
2118
1699
|
return 'DataStore';
|
|
2119
|
-
}
|
|
1700
|
+
}
|
|
2120
1701
|
/**
|
|
2121
1702
|
* Builds a function to capture `BackgroundManagerNotOpenError`'s to produce friendlier,
|
|
2122
1703
|
* more instructive errors for customers.
|
|
@@ -2124,19 +1705,18 @@ var DataStore = /** @class */ (function () {
|
|
|
2124
1705
|
* @param operation The name of the operation (usually a Datastore method) the customer
|
|
2125
1706
|
* tried to call.
|
|
2126
1707
|
*/
|
|
2127
|
-
|
|
2128
|
-
var _this = this;
|
|
1708
|
+
handleAddProcError(operation) {
|
|
2129
1709
|
/**
|
|
2130
1710
|
* If the tested error is a `BackgroundManagerNotOpenError`, it will be captured
|
|
2131
1711
|
* and replaced with a friendlier message that instructs the App Developer.
|
|
2132
1712
|
*
|
|
2133
1713
|
* @param err An error to test.
|
|
2134
1714
|
*/
|
|
2135
|
-
|
|
1715
|
+
const handler = (err) => {
|
|
2136
1716
|
if (err.message.startsWith('BackgroundManagerNotOpenError')) {
|
|
2137
1717
|
throw new Error([
|
|
2138
|
-
|
|
2139
|
-
|
|
1718
|
+
`DataStoreStateError: Tried to execute \`${operation}\` while DataStore was "${this.state}".`,
|
|
1719
|
+
`This can only be done while DataStore is "Started" or "Stopped". To remedy:`,
|
|
2140
1720
|
'Ensure all calls to `stop()` and `clear()` have completed first.',
|
|
2141
1721
|
'If this is not possible, retry the operation until it succeeds.',
|
|
2142
1722
|
].join('\n'));
|
|
@@ -2146,7 +1726,7 @@ var DataStore = /** @class */ (function () {
|
|
|
2146
1726
|
}
|
|
2147
1727
|
};
|
|
2148
1728
|
return handler;
|
|
2149
|
-
}
|
|
1729
|
+
}
|
|
2150
1730
|
/**
|
|
2151
1731
|
* Clears all data from storage and removes all data, schema info, other
|
|
2152
1732
|
* initialization details, and then stops DataStore.
|
|
@@ -2155,83 +1735,49 @@ var DataStore = /** @class */ (function () {
|
|
|
2155
1735
|
* by explicitiliy calling `start()` or any method that implicitly starts
|
|
2156
1736
|
* DataStore, such as `query()`, `save()`, or `delete()`.
|
|
2157
1737
|
*/
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
case 4:
|
|
2182
|
-
_a.sent();
|
|
2183
|
-
_a.label = 5;
|
|
2184
|
-
case 5: return [4 /*yield*/, this.storage.clear()];
|
|
2185
|
-
case 6:
|
|
2186
|
-
_a.sent();
|
|
2187
|
-
this.initialized = undefined; // Should re-initialize when start() is called.
|
|
2188
|
-
this.storage = undefined;
|
|
2189
|
-
this.sync = undefined;
|
|
2190
|
-
this.syncPredicates = new WeakMap();
|
|
2191
|
-
return [4 /*yield*/, this.runningProcesses.open()];
|
|
2192
|
-
case 7:
|
|
2193
|
-
_a.sent();
|
|
2194
|
-
this.state = DataStoreState.NotRunning;
|
|
2195
|
-
return [2 /*return*/];
|
|
2196
|
-
}
|
|
2197
|
-
});
|
|
2198
|
-
});
|
|
2199
|
-
};
|
|
1738
|
+
async clear() {
|
|
1739
|
+
checkSchemaInitialized();
|
|
1740
|
+
this.state = DataStoreState.Clearing;
|
|
1741
|
+
await this.runningProcesses.close();
|
|
1742
|
+
if (this.storage === undefined) {
|
|
1743
|
+
// connect to storage so that it can be cleared without fully starting DataStore
|
|
1744
|
+
this.storage = new storage_1.ExclusiveStorage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
|
|
1745
|
+
await this.storage.init();
|
|
1746
|
+
}
|
|
1747
|
+
if (syncSubscription && !syncSubscription.closed) {
|
|
1748
|
+
syncSubscription.unsubscribe();
|
|
1749
|
+
}
|
|
1750
|
+
if (this.sync) {
|
|
1751
|
+
await this.sync.stop();
|
|
1752
|
+
}
|
|
1753
|
+
await this.storage.clear();
|
|
1754
|
+
this.initialized = undefined; // Should re-initialize when start() is called.
|
|
1755
|
+
this.storage = undefined;
|
|
1756
|
+
this.sync = undefined;
|
|
1757
|
+
this.syncPredicates = new WeakMap();
|
|
1758
|
+
await this.runningProcesses.open();
|
|
1759
|
+
this.state = DataStoreState.NotRunning;
|
|
1760
|
+
}
|
|
2200
1761
|
/**
|
|
2201
1762
|
* Stops all DataStore sync activities.
|
|
2202
1763
|
*
|
|
2203
1764
|
* TODO: "Waits for graceful termination of
|
|
2204
1765
|
* running queries and terminates subscriptions."
|
|
2205
1766
|
*/
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
case 2:
|
|
2221
|
-
_a.sent();
|
|
2222
|
-
_a.label = 3;
|
|
2223
|
-
case 3:
|
|
2224
|
-
this.initialized = undefined; // Should re-initialize when start() is called.
|
|
2225
|
-
this.sync = undefined;
|
|
2226
|
-
return [4 /*yield*/, this.runningProcesses.open()];
|
|
2227
|
-
case 4:
|
|
2228
|
-
_a.sent();
|
|
2229
|
-
this.state = DataStoreState.NotRunning;
|
|
2230
|
-
return [2 /*return*/];
|
|
2231
|
-
}
|
|
2232
|
-
});
|
|
2233
|
-
});
|
|
2234
|
-
};
|
|
1767
|
+
async stop() {
|
|
1768
|
+
this.state = DataStoreState.Stopping;
|
|
1769
|
+
await this.runningProcesses.close();
|
|
1770
|
+
if (syncSubscription && !syncSubscription.closed) {
|
|
1771
|
+
syncSubscription.unsubscribe();
|
|
1772
|
+
}
|
|
1773
|
+
if (this.sync) {
|
|
1774
|
+
await this.sync.stop();
|
|
1775
|
+
}
|
|
1776
|
+
this.initialized = undefined; // Should re-initialize when start() is called.
|
|
1777
|
+
this.sync = undefined;
|
|
1778
|
+
await this.runningProcesses.open();
|
|
1779
|
+
this.state = DataStoreState.NotRunning;
|
|
1780
|
+
}
|
|
2235
1781
|
/**
|
|
2236
1782
|
* Validates given pagination input from a query and creates a pagination
|
|
2237
1783
|
* argument for use against the storage layer.
|
|
@@ -2239,9 +1785,9 @@ var DataStore = /** @class */ (function () {
|
|
|
2239
1785
|
* @param modelDefinition
|
|
2240
1786
|
* @param paginationProducer
|
|
2241
1787
|
*/
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
1788
|
+
processPagination(modelDefinition, paginationProducer) {
|
|
1789
|
+
let sortPredicate;
|
|
1790
|
+
const { limit, page, sort } = paginationProducer || {};
|
|
2245
1791
|
if (limit === undefined && page === undefined && sort === undefined) {
|
|
2246
1792
|
return undefined;
|
|
2247
1793
|
}
|
|
@@ -2268,83 +1814,55 @@ var DataStore = /** @class */ (function () {
|
|
|
2268
1814
|
sortPredicate = predicates_1.ModelSortPredicateCreator.createFromExisting(modelDefinition, sort);
|
|
2269
1815
|
}
|
|
2270
1816
|
return {
|
|
2271
|
-
limit
|
|
2272
|
-
page
|
|
1817
|
+
limit,
|
|
1818
|
+
page,
|
|
2273
1819
|
sort: sortPredicate,
|
|
2274
1820
|
};
|
|
2275
|
-
}
|
|
1821
|
+
}
|
|
2276
1822
|
/**
|
|
2277
1823
|
* Examines the configured `syncExpressions` and produces a WeakMap of
|
|
2278
1824
|
* SchemaModel -> predicate to use during sync.
|
|
2279
1825
|
*/
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
}
|
|
2317
|
-
});
|
|
2318
|
-
});
|
|
2319
|
-
};
|
|
2320
|
-
DataStore.prototype.unwrapPromise = function (conditionProducer) {
|
|
2321
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2322
|
-
var condition, error_1;
|
|
2323
|
-
return __generator(this, function (_a) {
|
|
2324
|
-
switch (_a.label) {
|
|
2325
|
-
case 0:
|
|
2326
|
-
_a.trys.push([0, 2, , 3]);
|
|
2327
|
-
return [4 /*yield*/, conditionProducer()];
|
|
2328
|
-
case 1:
|
|
2329
|
-
condition = _a.sent();
|
|
2330
|
-
return [2 /*return*/, condition || conditionProducer];
|
|
2331
|
-
case 2:
|
|
2332
|
-
error_1 = _a.sent();
|
|
2333
|
-
if (error_1 instanceof TypeError) {
|
|
2334
|
-
return [2 /*return*/, conditionProducer];
|
|
2335
|
-
}
|
|
2336
|
-
throw error_1;
|
|
2337
|
-
case 3: return [2 /*return*/];
|
|
2338
|
-
}
|
|
2339
|
-
});
|
|
2340
|
-
});
|
|
2341
|
-
};
|
|
2342
|
-
DataStore.prototype.weakMapFromEntries = function (entries) {
|
|
2343
|
-
return entries.reduce(function (map, _a) {
|
|
2344
|
-
var _b = __read(_a, 2), modelDefinition = _b[0], predicate = _b[1];
|
|
1826
|
+
async processSyncExpressions() {
|
|
1827
|
+
if (!this.syncExpressions || !this.syncExpressions.length) {
|
|
1828
|
+
return new WeakMap();
|
|
1829
|
+
}
|
|
1830
|
+
const syncPredicates = await Promise.all(this.syncExpressions.map(async (syncExpression) => {
|
|
1831
|
+
const { modelConstructor, conditionProducer } = await syncExpression;
|
|
1832
|
+
const modelDefinition = getModelDefinition(modelConstructor);
|
|
1833
|
+
// conditionProducer is either a predicate, e.g. (c) => c.field.eq(1)
|
|
1834
|
+
// OR a function/promise that returns a predicate
|
|
1835
|
+
const condition = await this.unwrapPromise(conditionProducer);
|
|
1836
|
+
if ((0, predicates_1.isPredicatesAll)(condition)) {
|
|
1837
|
+
return [modelDefinition, null];
|
|
1838
|
+
}
|
|
1839
|
+
const predicate = (0, next_1.internals)(condition((0, next_1.predicateFor)({
|
|
1840
|
+
builder: modelConstructor,
|
|
1841
|
+
schema: modelDefinition,
|
|
1842
|
+
pkField: (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition),
|
|
1843
|
+
}))).toStoragePredicate();
|
|
1844
|
+
return [modelDefinition, predicate];
|
|
1845
|
+
}));
|
|
1846
|
+
return this.weakMapFromEntries(syncPredicates);
|
|
1847
|
+
}
|
|
1848
|
+
async unwrapPromise(conditionProducer) {
|
|
1849
|
+
try {
|
|
1850
|
+
const condition = await conditionProducer();
|
|
1851
|
+
return condition || conditionProducer;
|
|
1852
|
+
}
|
|
1853
|
+
catch (error) {
|
|
1854
|
+
if (error instanceof TypeError) {
|
|
1855
|
+
return conditionProducer;
|
|
1856
|
+
}
|
|
1857
|
+
throw error;
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
weakMapFromEntries(entries) {
|
|
1861
|
+
return entries.reduce((map, [modelDefinition, predicate]) => {
|
|
2345
1862
|
if (map.has(modelDefinition)) {
|
|
2346
|
-
|
|
2347
|
-
logger.warn(
|
|
1863
|
+
const { name } = modelDefinition;
|
|
1864
|
+
logger.warn(`You can only utilize one Sync Expression per model.
|
|
1865
|
+
Subsequent sync expressions for the ${name} model will be ignored.`);
|
|
2348
1866
|
return map;
|
|
2349
1867
|
}
|
|
2350
1868
|
if (predicate) {
|
|
@@ -2352,31 +1870,30 @@ var DataStore = /** @class */ (function () {
|
|
|
2352
1870
|
}
|
|
2353
1871
|
return map;
|
|
2354
1872
|
}, new WeakMap());
|
|
2355
|
-
}
|
|
1873
|
+
}
|
|
2356
1874
|
/**
|
|
2357
1875
|
* A session ID to allow CMS to open databases against multiple apps.
|
|
2358
1876
|
* This session ID is only expected be set by AWS Amplify Studio.
|
|
2359
1877
|
*/
|
|
2360
|
-
|
|
1878
|
+
retrieveSessionId() {
|
|
2361
1879
|
try {
|
|
2362
|
-
|
|
1880
|
+
const sessionId = sessionStorage.getItem('datastoreSessionId');
|
|
2363
1881
|
if (sessionId) {
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
return
|
|
1882
|
+
const { aws_appsync_graphqlEndpoint } = this.amplifyConfig;
|
|
1883
|
+
const appSyncUrl = aws_appsync_graphqlEndpoint.split('/')[2];
|
|
1884
|
+
const [appSyncId] = appSyncUrl.split('.');
|
|
1885
|
+
return `${sessionId}-${appSyncId}`;
|
|
2368
1886
|
}
|
|
2369
1887
|
}
|
|
2370
|
-
catch
|
|
1888
|
+
catch { }
|
|
2371
1889
|
return undefined;
|
|
2372
|
-
}
|
|
2373
|
-
|
|
2374
|
-
}());
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
2375
1892
|
exports.DataStoreClass = DataStore;
|
|
2376
|
-
|
|
1893
|
+
const instance = new DataStore();
|
|
2377
1894
|
exports.DataStore = instance;
|
|
2378
1895
|
instance.configure({});
|
|
2379
|
-
core_1.Hub.listen('core',
|
|
1896
|
+
core_1.Hub.listen('core', capsule => {
|
|
2380
1897
|
if (capsule.payload.event === 'configure') {
|
|
2381
1898
|
instance.configure({});
|
|
2382
1899
|
}
|