@ember-data/store 4.12.0-beta.8 → 4.12.0-beta.9
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/README.md +14 -12
- package/addon/-private.js +1 -1
- package/addon/{index-0d52354f.js → index-8b77b852.js} +462 -88
- package/addon/index-8b77b852.js.map +1 -0
- package/addon/index.js +1 -1
- package/package.json +15 -15
- package/addon/index-0d52354f.js.map +0 -1
|
@@ -35,36 +35,225 @@ import ObjectProxy from '@ember/object/proxy';
|
|
|
35
35
|
function normalizeModelName$1(modelName) {
|
|
36
36
|
return dasherize(modelName);
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function _initializerDefineProperty(target, property, descriptor, context) {
|
|
39
|
+
if (!descriptor) return;
|
|
40
|
+
Object.defineProperty(target, property, {
|
|
41
|
+
enumerable: descriptor.enumerable,
|
|
42
|
+
configurable: descriptor.configurable,
|
|
43
|
+
writable: descriptor.writable,
|
|
44
|
+
value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function _classPrivateFieldBase(receiver, privateKey) {
|
|
48
|
+
if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
|
|
49
|
+
throw new TypeError("attempted to use private field on non-instance");
|
|
50
|
+
}
|
|
51
|
+
return receiver;
|
|
52
|
+
}
|
|
53
|
+
var id = 0;
|
|
54
|
+
function _classPrivateFieldKey(name) {
|
|
55
|
+
return "__private_" + id++ + "_" + name;
|
|
56
|
+
}
|
|
57
|
+
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
|
|
58
|
+
var desc = {};
|
|
59
|
+
Object.keys(descriptor).forEach(function (key) {
|
|
60
|
+
desc[key] = descriptor[key];
|
|
61
|
+
});
|
|
62
|
+
desc.enumerable = !!desc.enumerable;
|
|
63
|
+
desc.configurable = !!desc.configurable;
|
|
64
|
+
if ('value' in desc || desc.initializer) {
|
|
65
|
+
desc.writable = true;
|
|
66
|
+
}
|
|
67
|
+
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
|
|
68
|
+
return decorator(target, property, desc) || desc;
|
|
69
|
+
}, desc);
|
|
70
|
+
if (context && desc.initializer !== void 0) {
|
|
71
|
+
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
|
|
72
|
+
desc.initializer = undefined;
|
|
73
|
+
}
|
|
74
|
+
if (desc.initializer === void 0) {
|
|
75
|
+
Object.defineProperty(target, property, desc);
|
|
76
|
+
desc = null;
|
|
77
|
+
}
|
|
78
|
+
return desc;
|
|
79
|
+
}
|
|
80
|
+
var _class$3, _descriptor$3, _descriptor2$1, _descriptor3, _descriptor4, _store$1, _request;
|
|
81
|
+
function urlFromLink(link) {
|
|
82
|
+
if (typeof link === 'string') return link;
|
|
83
|
+
return link.href;
|
|
84
|
+
}
|
|
85
|
+
let Document = (_class$3 = (_store$1 = /*#__PURE__*/_classPrivateFieldKey("store"), _request = /*#__PURE__*/_classPrivateFieldKey("request"), class Document {
|
|
86
|
+
constructor(store, identifier) {
|
|
87
|
+
Object.defineProperty(this, _request, {
|
|
88
|
+
value: _request2
|
|
89
|
+
});
|
|
90
|
+
_initializerDefineProperty(this, "links", _descriptor$3, this);
|
|
91
|
+
_initializerDefineProperty(this, "data", _descriptor2$1, this);
|
|
92
|
+
_initializerDefineProperty(this, "errors", _descriptor3, this);
|
|
93
|
+
_initializerDefineProperty(this, "meta", _descriptor4, this);
|
|
94
|
+
Object.defineProperty(this, _store$1, {
|
|
95
|
+
writable: true,
|
|
96
|
+
value: void 0
|
|
97
|
+
});
|
|
98
|
+
_classPrivateFieldBase(this, _store$1)[_store$1] = store;
|
|
99
|
+
this.identifier = identifier;
|
|
100
|
+
}
|
|
101
|
+
fetch(options = {}) {
|
|
102
|
+
assert(`No self link`, this.links?.self);
|
|
103
|
+
options.cacheOptions = options.cacheOptions || {};
|
|
104
|
+
options.cacheOptions.key = this.identifier?.lid;
|
|
105
|
+
return _classPrivateFieldBase(this, _request)[_request]('self', options);
|
|
106
|
+
}
|
|
107
|
+
next(options) {
|
|
108
|
+
return _classPrivateFieldBase(this, _request)[_request]('next', options);
|
|
109
|
+
}
|
|
110
|
+
prev(options) {
|
|
111
|
+
return _classPrivateFieldBase(this, _request)[_request]('prev', options);
|
|
112
|
+
}
|
|
113
|
+
first(options) {
|
|
114
|
+
return _classPrivateFieldBase(this, _request)[_request]('first', options);
|
|
115
|
+
}
|
|
116
|
+
last(options) {
|
|
117
|
+
return _classPrivateFieldBase(this, _request)[_request]('last', options);
|
|
118
|
+
}
|
|
119
|
+
toJSON() {
|
|
120
|
+
const data = {};
|
|
121
|
+
data.identifier = this.identifier;
|
|
122
|
+
if (this.data !== undefined) {
|
|
123
|
+
data.data = this.data;
|
|
124
|
+
}
|
|
125
|
+
if (this.links !== undefined) {
|
|
126
|
+
data.links = this.links;
|
|
127
|
+
}
|
|
128
|
+
if (this.errors !== undefined) {
|
|
129
|
+
data.errors = this.errors;
|
|
130
|
+
}
|
|
131
|
+
if (this.meta !== undefined) {
|
|
132
|
+
data.meta = this.meta;
|
|
133
|
+
}
|
|
134
|
+
return data;
|
|
135
|
+
}
|
|
136
|
+
}), (_descriptor$3 = _applyDecoratedDescriptor(_class$3.prototype, "links", [tracked], {
|
|
137
|
+
configurable: true,
|
|
138
|
+
enumerable: true,
|
|
139
|
+
writable: true,
|
|
140
|
+
initializer: null
|
|
141
|
+
}), _descriptor2$1 = _applyDecoratedDescriptor(_class$3.prototype, "data", [tracked], {
|
|
142
|
+
configurable: true,
|
|
143
|
+
enumerable: true,
|
|
144
|
+
writable: true,
|
|
145
|
+
initializer: null
|
|
146
|
+
}), _descriptor3 = _applyDecoratedDescriptor(_class$3.prototype, "errors", [tracked], {
|
|
147
|
+
configurable: true,
|
|
148
|
+
enumerable: true,
|
|
149
|
+
writable: true,
|
|
150
|
+
initializer: null
|
|
151
|
+
}), _descriptor4 = _applyDecoratedDescriptor(_class$3.prototype, "meta", [tracked], {
|
|
152
|
+
configurable: true,
|
|
153
|
+
enumerable: true,
|
|
154
|
+
writable: true,
|
|
155
|
+
initializer: null
|
|
156
|
+
})), _class$3);
|
|
157
|
+
async function _request2(link, options = {}) {
|
|
158
|
+
const href = this.links?.[link];
|
|
159
|
+
if (!href) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const response = await _classPrivateFieldBase(this, _store$1)[_store$1].request(Object.assign(options, {
|
|
163
|
+
url: urlFromLink(href)
|
|
164
|
+
}));
|
|
165
|
+
return response.content;
|
|
166
|
+
}
|
|
167
|
+
function isErrorDocument(document) {
|
|
168
|
+
return 'errors' in document;
|
|
169
|
+
}
|
|
170
|
+
function maybeUpdateUiObjects(store, request, options, document, isFromCache) {
|
|
171
|
+
const {
|
|
172
|
+
identifier
|
|
173
|
+
} = options;
|
|
174
|
+
if (isErrorDocument(document)) {
|
|
175
|
+
if (!identifier && !options.shouldHydrate) {
|
|
176
|
+
return document;
|
|
177
|
+
}
|
|
178
|
+
let doc;
|
|
179
|
+
if (identifier) {
|
|
180
|
+
doc = store._documentCache.get(identifier);
|
|
181
|
+
}
|
|
182
|
+
if (!doc) {
|
|
183
|
+
doc = new Document(store, identifier);
|
|
184
|
+
copyDocumentProperties(doc, document);
|
|
185
|
+
if (identifier) {
|
|
186
|
+
store._documentCache.set(identifier, doc);
|
|
187
|
+
}
|
|
188
|
+
} else if (!isFromCache) {
|
|
189
|
+
doc.data = undefined;
|
|
190
|
+
copyDocumentProperties(doc, document);
|
|
191
|
+
}
|
|
192
|
+
return options.shouldHydrate ? doc : document;
|
|
193
|
+
}
|
|
39
194
|
if (Array.isArray(document.data)) {
|
|
40
|
-
const {
|
|
41
|
-
lid
|
|
42
|
-
} = document;
|
|
43
195
|
const {
|
|
44
196
|
recordArrayManager
|
|
45
197
|
} = store;
|
|
46
|
-
if (!
|
|
47
|
-
|
|
198
|
+
if (!identifier) {
|
|
199
|
+
if (!options.shouldHydrate) {
|
|
200
|
+
return document;
|
|
201
|
+
}
|
|
202
|
+
const data = recordArrayManager.createArray({
|
|
48
203
|
identifiers: document.data,
|
|
49
204
|
doc: document,
|
|
50
205
|
query: request
|
|
51
206
|
});
|
|
207
|
+
const doc = new Document(store, null);
|
|
208
|
+
doc.data = data;
|
|
209
|
+
doc.meta = document.meta;
|
|
210
|
+
doc.links = document.links;
|
|
211
|
+
return doc;
|
|
52
212
|
}
|
|
53
|
-
let managed = recordArrayManager._keyedArrays.get(lid);
|
|
213
|
+
let managed = recordArrayManager._keyedArrays.get(identifier.lid);
|
|
54
214
|
if (!managed) {
|
|
55
215
|
managed = recordArrayManager.createArray({
|
|
56
216
|
identifiers: document.data,
|
|
57
217
|
doc: document
|
|
58
218
|
});
|
|
59
|
-
recordArrayManager._keyedArrays.set(lid, managed);
|
|
219
|
+
recordArrayManager._keyedArrays.set(identifier.lid, managed);
|
|
220
|
+
const doc = new Document(store, identifier);
|
|
221
|
+
doc.data = managed;
|
|
222
|
+
doc.meta = document.meta;
|
|
223
|
+
doc.links = document.links;
|
|
224
|
+
store._documentCache.set(identifier, doc);
|
|
225
|
+
return options.shouldHydrate ? doc : document;
|
|
60
226
|
} else {
|
|
61
|
-
|
|
227
|
+
const doc = store._documentCache.get(identifier);
|
|
228
|
+
if (!isFromCache) {
|
|
229
|
+
recordArrayManager.populateManagedArray(managed, document.data, document);
|
|
230
|
+
doc.data = managed;
|
|
231
|
+
doc.meta = document.meta;
|
|
232
|
+
doc.links = document.links;
|
|
233
|
+
}
|
|
234
|
+
return options.shouldHydrate ? doc : document;
|
|
62
235
|
}
|
|
63
|
-
return managed;
|
|
64
236
|
} else {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
237
|
+
if (!identifier && !options.shouldHydrate) {
|
|
238
|
+
return document;
|
|
239
|
+
}
|
|
240
|
+
const data = document.data ? store.peekRecord(document.data) : null;
|
|
241
|
+
let doc;
|
|
242
|
+
if (identifier) {
|
|
243
|
+
doc = store._documentCache.get(identifier);
|
|
244
|
+
}
|
|
245
|
+
if (!doc) {
|
|
246
|
+
doc = new Document(store, identifier);
|
|
247
|
+
doc.data = data;
|
|
248
|
+
copyDocumentProperties(doc, document);
|
|
249
|
+
if (identifier) {
|
|
250
|
+
store._documentCache.set(identifier, doc);
|
|
251
|
+
}
|
|
252
|
+
} else if (!isFromCache) {
|
|
253
|
+
doc.data = data;
|
|
254
|
+
copyDocumentProperties(doc, document);
|
|
255
|
+
}
|
|
256
|
+
return options.shouldHydrate ? doc : document;
|
|
68
257
|
}
|
|
69
258
|
}
|
|
70
259
|
function calcShouldFetch(store, request, hasCachedValue, identifier) {
|
|
@@ -79,37 +268,63 @@ function calcShouldBackgroundFetch(store, request, willFetch, identifier) {
|
|
|
79
268
|
} = request;
|
|
80
269
|
return !willFetch && (cacheOptions?.backgroundReload || (store.lifetimes && identifier ? store.lifetimes.isSoftExpired(identifier) : false));
|
|
81
270
|
}
|
|
82
|
-
function fetchContentAndHydrate(next, context, shouldFetch, shouldBackgroundFetch) {
|
|
271
|
+
function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBackgroundFetch) {
|
|
83
272
|
const {
|
|
84
273
|
store
|
|
85
274
|
} = context.request;
|
|
86
275
|
const shouldHydrate = context.request[Symbol.for('ember-data:enable-hydration')] || false;
|
|
87
276
|
return next(context.request).then(document => {
|
|
277
|
+
store.requestManager._pending.delete(context.id);
|
|
88
278
|
store._enableAsyncFlush = true;
|
|
89
279
|
let response;
|
|
90
280
|
store._join(() => {
|
|
91
281
|
response = store.cache.put(document);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
282
|
+
response = maybeUpdateUiObjects(store, context.request, {
|
|
283
|
+
shouldHydrate,
|
|
284
|
+
shouldFetch,
|
|
285
|
+
shouldBackgroundFetch,
|
|
286
|
+
identifier
|
|
287
|
+
}, response, false);
|
|
95
288
|
});
|
|
96
289
|
store._enableAsyncFlush = null;
|
|
97
290
|
if (shouldFetch) {
|
|
98
291
|
return response;
|
|
292
|
+
} else if (shouldBackgroundFetch) {
|
|
293
|
+
store.notifications._flush();
|
|
99
294
|
}
|
|
100
295
|
}, error => {
|
|
296
|
+
store.requestManager._pending.delete(context.id);
|
|
297
|
+
if (context.request.signal?.aborted) {
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
300
|
+
store.requestManager._pending.delete(context.id);
|
|
101
301
|
store._enableAsyncFlush = true;
|
|
302
|
+
let response;
|
|
102
303
|
store._join(() => {
|
|
103
|
-
store.cache.put(error);
|
|
304
|
+
response = store.cache.put(error);
|
|
305
|
+
response = maybeUpdateUiObjects(store, context.request, {
|
|
306
|
+
shouldHydrate,
|
|
307
|
+
shouldFetch,
|
|
308
|
+
shouldBackgroundFetch,
|
|
309
|
+
identifier
|
|
310
|
+
}, response, false);
|
|
104
311
|
});
|
|
105
312
|
store._enableAsyncFlush = null;
|
|
106
|
-
|
|
107
|
-
// TODO @runspired this is probably not the right thing to throw so make sure we add a test
|
|
108
313
|
if (!shouldBackgroundFetch) {
|
|
109
|
-
|
|
314
|
+
const newError = cloneError(error);
|
|
315
|
+
newError.content = response;
|
|
316
|
+
throw newError;
|
|
317
|
+
} else {
|
|
318
|
+
store.notifications._flush();
|
|
110
319
|
}
|
|
111
320
|
});
|
|
112
321
|
}
|
|
322
|
+
function cloneError(error) {
|
|
323
|
+
const cloned = new Error(error.message);
|
|
324
|
+
cloned.stack = error.stack;
|
|
325
|
+
cloned.error = error.error;
|
|
326
|
+
return cloned;
|
|
327
|
+
}
|
|
113
328
|
const SkipCache = Symbol.for('ember-data:skip-cache');
|
|
114
329
|
const EnableHydration = Symbol.for('ember-data:enable-hydration');
|
|
115
330
|
const CacheHandler = {
|
|
@@ -126,20 +341,41 @@ const CacheHandler = {
|
|
|
126
341
|
|
|
127
342
|
// determine if we should skip cache
|
|
128
343
|
if (calcShouldFetch(store, context.request, !!peeked, identifier)) {
|
|
129
|
-
return fetchContentAndHydrate(next, context, true, false);
|
|
344
|
+
return fetchContentAndHydrate(next, context, identifier, true, false);
|
|
130
345
|
}
|
|
131
346
|
|
|
132
347
|
// if we have not skipped cache, determine if we should update behind the scenes
|
|
133
348
|
if (calcShouldBackgroundFetch(store, context.request, false, identifier)) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if ('error' in peeked) {
|
|
137
|
-
throw peeked.error;
|
|
349
|
+
let promise = fetchContentAndHydrate(next, context, identifier, false, true);
|
|
350
|
+
store.requestManager._pending.set(context.id, promise);
|
|
138
351
|
}
|
|
139
352
|
const shouldHydrate = context.request[EnableHydration] || false;
|
|
140
|
-
|
|
353
|
+
if ('error' in peeked) {
|
|
354
|
+
const content = shouldHydrate ? maybeUpdateUiObjects(store, context.request, {
|
|
355
|
+
shouldHydrate,
|
|
356
|
+
identifier
|
|
357
|
+
}, peeked.content, true) : peeked.content;
|
|
358
|
+
const newError = cloneError(peeked);
|
|
359
|
+
newError.content = content;
|
|
360
|
+
throw newError;
|
|
361
|
+
}
|
|
362
|
+
return Promise.resolve(shouldHydrate ? maybeUpdateUiObjects(store, context.request, {
|
|
363
|
+
shouldHydrate,
|
|
364
|
+
identifier
|
|
365
|
+
}, peeked.content, true) : peeked.content);
|
|
141
366
|
}
|
|
142
367
|
};
|
|
368
|
+
function copyDocumentProperties(target, source) {
|
|
369
|
+
if ('links' in source) {
|
|
370
|
+
target.links = source.links;
|
|
371
|
+
}
|
|
372
|
+
if ('meta' in source) {
|
|
373
|
+
target.meta = source.meta;
|
|
374
|
+
}
|
|
375
|
+
if ('errors' in source) {
|
|
376
|
+
target.errors = source.errors;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
143
379
|
|
|
144
380
|
/*
|
|
145
381
|
* Returns the Cache instance associated with a given
|
|
@@ -848,38 +1084,6 @@ function detectMerge(typesCache, identifier, data, newId, lids) {
|
|
|
848
1084
|
}
|
|
849
1085
|
return false;
|
|
850
1086
|
}
|
|
851
|
-
function _initializerDefineProperty(target, property, descriptor, context) {
|
|
852
|
-
if (!descriptor) return;
|
|
853
|
-
Object.defineProperty(target, property, {
|
|
854
|
-
enumerable: descriptor.enumerable,
|
|
855
|
-
configurable: descriptor.configurable,
|
|
856
|
-
writable: descriptor.writable,
|
|
857
|
-
value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
|
|
861
|
-
var desc = {};
|
|
862
|
-
Object.keys(descriptor).forEach(function (key) {
|
|
863
|
-
desc[key] = descriptor[key];
|
|
864
|
-
});
|
|
865
|
-
desc.enumerable = !!desc.enumerable;
|
|
866
|
-
desc.configurable = !!desc.configurable;
|
|
867
|
-
if ('value' in desc || desc.initializer) {
|
|
868
|
-
desc.writable = true;
|
|
869
|
-
}
|
|
870
|
-
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
|
|
871
|
-
return decorator(target, property, desc) || desc;
|
|
872
|
-
}, desc);
|
|
873
|
-
if (context && desc.initializer !== void 0) {
|
|
874
|
-
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
|
|
875
|
-
desc.initializer = undefined;
|
|
876
|
-
}
|
|
877
|
-
if (desc.initializer === void 0) {
|
|
878
|
-
Object.defineProperty(target, property, desc);
|
|
879
|
-
desc = null;
|
|
880
|
-
}
|
|
881
|
-
return desc;
|
|
882
|
-
}
|
|
883
1087
|
let tokenId = 0;
|
|
884
1088
|
const CacheOperations = new Set(['added', 'removed', 'state', 'updated']);
|
|
885
1089
|
function isCacheOperationValue(value) {
|
|
@@ -907,16 +1111,12 @@ function unsubscribe(token) {
|
|
|
907
1111
|
}
|
|
908
1112
|
}
|
|
909
1113
|
|
|
910
|
-
/*
|
|
911
|
-
Currently only support a single callback per identifier
|
|
912
|
-
*/
|
|
913
|
-
|
|
914
1114
|
/**
|
|
915
1115
|
* The NotificationManager provides the ability to subscribe to
|
|
916
1116
|
* changes to Cache state.
|
|
917
1117
|
*
|
|
918
1118
|
* This Feature is what allows EmberData to create subscriptions that
|
|
919
|
-
* work with any framework or change
|
|
1119
|
+
* work with any framework or change-notification system.
|
|
920
1120
|
*
|
|
921
1121
|
* @class NotificationManager
|
|
922
1122
|
* @public
|
|
@@ -930,20 +1130,30 @@ class NotificationManager {
|
|
|
930
1130
|
}
|
|
931
1131
|
|
|
932
1132
|
/**
|
|
933
|
-
* Subscribe to changes for a given resource identifier
|
|
1133
|
+
* Subscribe to changes for a given resource identifier, resource addition/removal, or document addition/removal.
|
|
934
1134
|
*
|
|
935
1135
|
* ```ts
|
|
936
|
-
*
|
|
1136
|
+
* export type CacheOperation = 'added' | 'removed' | 'updated' | 'state';
|
|
1137
|
+
*
|
|
1138
|
+
* export interface NotificationCallback {
|
|
937
1139
|
* (identifier: StableRecordIdentifier, notificationType: 'attributes' | 'relationships', key?: string): void;
|
|
938
1140
|
* (identifier: StableRecordIdentifier, notificationType: 'errors' | 'meta' | 'identity' | 'state'): void;
|
|
939
1141
|
* (identifier: StableRecordIdentifier, notificationType: NotificationType, key?: string): void;
|
|
940
1142
|
* }
|
|
1143
|
+
* export interface ResourceOperationCallback {
|
|
1144
|
+
* // resource updates
|
|
1145
|
+
* (identifier: StableRecordIdentifier, notificationType: CacheOperation): void;
|
|
1146
|
+
* }
|
|
1147
|
+
* export interface DocumentOperationCallback {
|
|
1148
|
+
* // document updates
|
|
1149
|
+
* (identifier: StableDocumentIdentifier, notificationType: CacheOperation): void;
|
|
1150
|
+
* }
|
|
941
1151
|
* ```
|
|
942
1152
|
*
|
|
943
1153
|
* @method subscribe
|
|
944
1154
|
* @public
|
|
945
|
-
* @param {StableRecordIdentifier} identifier
|
|
946
|
-
* @param {NotificationCallback} callback
|
|
1155
|
+
* @param {StableDocumentIdentifier | StableRecordIdentifier | 'resource' | 'document'} identifier
|
|
1156
|
+
* @param {NotificationCallback | ResourceOperationCallback | DocumentOperationCallback} callback
|
|
947
1157
|
* @returns {UnsubscribeToken} an opaque token to be used with unsubscribe
|
|
948
1158
|
*/
|
|
949
1159
|
|
|
@@ -1266,16 +1476,6 @@ let RecordReference = (_class$2 = class RecordReference {
|
|
|
1266
1476
|
return 0;
|
|
1267
1477
|
}
|
|
1268
1478
|
}), _class$2);
|
|
1269
|
-
function _classPrivateFieldBase(receiver, privateKey) {
|
|
1270
|
-
if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
|
|
1271
|
-
throw new TypeError("attempted to use private field on non-instance");
|
|
1272
|
-
}
|
|
1273
|
-
return receiver;
|
|
1274
|
-
}
|
|
1275
|
-
var id = 0;
|
|
1276
|
-
function _classPrivateFieldKey(name) {
|
|
1277
|
-
return "__private_" + id++ + "_" + name;
|
|
1278
|
-
}
|
|
1279
1479
|
function legacyCachePut(store, doc) {
|
|
1280
1480
|
const jsonApiDoc = doc.content;
|
|
1281
1481
|
let ret;
|
|
@@ -1397,7 +1597,6 @@ class NonSingletonCacheManager {
|
|
|
1397
1597
|
}
|
|
1398
1598
|
// Cache Management
|
|
1399
1599
|
// ================
|
|
1400
|
-
|
|
1401
1600
|
/**
|
|
1402
1601
|
* Cache the response to a request
|
|
1403
1602
|
*
|
|
@@ -2575,7 +2774,7 @@ class LegacyWrapper {
|
|
|
2575
2774
|
assert(`Expected a stable identifier`, isStableIdentifier(type));
|
|
2576
2775
|
identifier = type;
|
|
2577
2776
|
}
|
|
2578
|
-
const cache = macroCondition(getOwnConfig().deprecations.
|
|
2777
|
+
const cache = macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA) ? this._store._instanceCache.getResourceCache(identifier) : this._store.cache;
|
|
2579
2778
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_V1CACHE_STORE_APIS)) {
|
|
2580
2779
|
if (!id && !lid && typeof type === 'string') {
|
|
2581
2780
|
cache.clientDidCreate(identifier);
|
|
@@ -2710,7 +2909,7 @@ class V2CacheStoreWrapper {
|
|
|
2710
2909
|
return this._store.getSchemaDefinitionService();
|
|
2711
2910
|
}
|
|
2712
2911
|
recordDataFor(identifier) {
|
|
2713
|
-
if (macroCondition(getOwnConfig().deprecations.
|
|
2912
|
+
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA)) {
|
|
2714
2913
|
deprecate(`StoreWrapper.recordDataFor is deprecated. With Singleton Cache, this method is no longer needed as the caller is its own cache reference.`, false, {
|
|
2715
2914
|
for: '@ember-data/store',
|
|
2716
2915
|
id: 'ember-data:deprecate-record-data-for',
|
|
@@ -2722,7 +2921,7 @@ class V2CacheStoreWrapper {
|
|
|
2722
2921
|
});
|
|
2723
2922
|
}
|
|
2724
2923
|
assert(`Expected a stable identifier`, isStableIdentifier(identifier));
|
|
2725
|
-
return macroCondition(getOwnConfig().deprecations.
|
|
2924
|
+
return macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA) ? this._store._instanceCache.getResourceCache(identifier) : void 0;
|
|
2726
2925
|
}
|
|
2727
2926
|
setRecordId(identifier, id) {
|
|
2728
2927
|
assert(`Expected a stable identifier`, isStableIdentifier(identifier));
|
|
@@ -2815,7 +3014,7 @@ class InstanceCache {
|
|
|
2815
3014
|
};
|
|
2816
3015
|
this.store = store;
|
|
2817
3016
|
this._storeWrapper = new CacheStoreWrapper(this.store);
|
|
2818
|
-
if (macroCondition(getOwnConfig().deprecations.
|
|
3017
|
+
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA)) {
|
|
2819
3018
|
this.__cacheFor = resource => {
|
|
2820
3019
|
// TODO enforce strict
|
|
2821
3020
|
const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resource);
|
|
@@ -2856,7 +3055,7 @@ class InstanceCache {
|
|
|
2856
3055
|
record: staleIdentifier,
|
|
2857
3056
|
value: keptIdentifier
|
|
2858
3057
|
});
|
|
2859
|
-
} else if (macroCondition(!getOwnConfig().deprecations.
|
|
3058
|
+
} else if (macroCondition(!getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA)) {
|
|
2860
3059
|
this.store.cache.patch({
|
|
2861
3060
|
op: 'mergeIdentifiers',
|
|
2862
3061
|
record: staleIdentifier,
|
|
@@ -3498,7 +3697,6 @@ var _dec, _class$1, _descriptor$1;
|
|
|
3498
3697
|
@extends Ember.ArrayProxy
|
|
3499
3698
|
@uses Ember.PromiseProxyMixin
|
|
3500
3699
|
*/
|
|
3501
|
-
|
|
3502
3700
|
let PromiseArray = (_dec = reads('content.meta'), (_class$1 = class PromiseArray extends PromiseArrayProxy {
|
|
3503
3701
|
constructor(...args) {
|
|
3504
3702
|
super(...args);
|
|
@@ -3638,6 +3836,10 @@ function convertToInt(prop) {
|
|
|
3638
3836
|
return num % 1 === 0 ? num : null;
|
|
3639
3837
|
}
|
|
3640
3838
|
let Tag = (_class = class Tag {
|
|
3839
|
+
/*
|
|
3840
|
+
* whether this was part of a transaction when last mutated
|
|
3841
|
+
*/
|
|
3842
|
+
|
|
3641
3843
|
constructor() {
|
|
3642
3844
|
_initializerDefineProperty(this, "ref", _descriptor, this);
|
|
3643
3845
|
this.shouldReset = false;
|
|
@@ -3712,6 +3914,22 @@ let IdentifierArray = (_class3 = class IdentifierArray {
|
|
|
3712
3914
|
[NOTIFY]() {
|
|
3713
3915
|
notifyArray(this);
|
|
3714
3916
|
}
|
|
3917
|
+
|
|
3918
|
+
/**
|
|
3919
|
+
The modelClass represented by this record array.
|
|
3920
|
+
@property type
|
|
3921
|
+
@public
|
|
3922
|
+
@deprecated
|
|
3923
|
+
@type {subclass of Model}
|
|
3924
|
+
*/
|
|
3925
|
+
|
|
3926
|
+
/**
|
|
3927
|
+
The store that created this record array.
|
|
3928
|
+
@property store
|
|
3929
|
+
@private
|
|
3930
|
+
@type Store
|
|
3931
|
+
*/
|
|
3932
|
+
|
|
3715
3933
|
destroy() {
|
|
3716
3934
|
this.isDestroying = true;
|
|
3717
3935
|
// changing the reference breaks the Proxy
|
|
@@ -4710,12 +4928,23 @@ function sync(array, changes) {
|
|
|
4710
4928
|
}
|
|
4711
4929
|
}
|
|
4712
4930
|
|
|
4931
|
+
/**
|
|
4932
|
+
* @module @ember-data/store
|
|
4933
|
+
*/
|
|
4713
4934
|
const Touching = Symbol('touching');
|
|
4714
4935
|
const RequestPromise = Symbol('promise');
|
|
4715
4936
|
function hasRecordIdentifier(op) {
|
|
4716
4937
|
return 'recordIdentifier' in op;
|
|
4717
4938
|
}
|
|
4718
|
-
|
|
4939
|
+
|
|
4940
|
+
/**
|
|
4941
|
+
* The RequestStateService is used to track the state of requests
|
|
4942
|
+
* for fetching or updating known resource identifies that are inflight.
|
|
4943
|
+
*
|
|
4944
|
+
* @class RequestStateService
|
|
4945
|
+
* @public
|
|
4946
|
+
*/
|
|
4947
|
+
class RequestStateService {
|
|
4719
4948
|
constructor(store) {
|
|
4720
4949
|
this._pending = Object.create(null);
|
|
4721
4950
|
this._done = new Map();
|
|
@@ -4727,7 +4956,7 @@ class RequestCache {
|
|
|
4727
4956
|
_clearEntries(identifier) {
|
|
4728
4957
|
this._done.delete(identifier);
|
|
4729
4958
|
}
|
|
4730
|
-
|
|
4959
|
+
_enqueue(promise, queryRequest) {
|
|
4731
4960
|
let query = queryRequest.data[0];
|
|
4732
4961
|
if (hasRecordIdentifier(query)) {
|
|
4733
4962
|
let lid = query.recordIdentifier.lid;
|
|
@@ -4826,18 +5055,66 @@ class RequestCache {
|
|
|
4826
5055
|
this._done.set(identifier, requests);
|
|
4827
5056
|
});
|
|
4828
5057
|
}
|
|
5058
|
+
|
|
5059
|
+
/**
|
|
5060
|
+
* Subscribe to requests for a given resource identity.
|
|
5061
|
+
*
|
|
5062
|
+
* The callback will receive the current state of the request.
|
|
5063
|
+
*
|
|
5064
|
+
* ```ts
|
|
5065
|
+
* interface RequestState {
|
|
5066
|
+
* state: 'pending' | 'fulfilled' | 'rejected';
|
|
5067
|
+
* type: 'query' | 'mutation';
|
|
5068
|
+
* request: Request;
|
|
5069
|
+
* response?: { data: unknown };
|
|
5070
|
+
* }
|
|
5071
|
+
* ```
|
|
5072
|
+
*
|
|
5073
|
+
* Note: It should be considered dangerous to use this API for more than simple
|
|
5074
|
+
* state derivation or debugging. The `request` and `response` properties are poorly
|
|
5075
|
+
* spec'd and may change unexpectedly when shifting what Handlers are in use or how
|
|
5076
|
+
* requests are issued from the Store.
|
|
5077
|
+
*
|
|
5078
|
+
* We expect to revisit this API in the near future as we continue to refine the
|
|
5079
|
+
* RequestManager ergonomics, as a simpler but more powerful direct integration
|
|
5080
|
+
* with the RequestManager for these purposes is likely to be a better long-term
|
|
5081
|
+
* design.
|
|
5082
|
+
*
|
|
5083
|
+
* @method subscribeForRecord
|
|
5084
|
+
* @public
|
|
5085
|
+
* @param {StableRecordIdentifier} identifier
|
|
5086
|
+
* @param {(state: RequestState) => void} callback
|
|
5087
|
+
*/
|
|
4829
5088
|
subscribeForRecord(identifier, callback) {
|
|
4830
5089
|
if (!this._subscriptions[identifier.lid]) {
|
|
4831
5090
|
this._subscriptions[identifier.lid] = [];
|
|
4832
5091
|
}
|
|
4833
5092
|
this._subscriptions[identifier.lid].push(callback);
|
|
4834
5093
|
}
|
|
5094
|
+
|
|
5095
|
+
/**
|
|
5096
|
+
* Retrieve all active requests for a given resource identity.
|
|
5097
|
+
*
|
|
5098
|
+
* @method getPendingRequestsForRecord
|
|
5099
|
+
* @public
|
|
5100
|
+
* @param {StableRecordIdentifier} identifier
|
|
5101
|
+
* @returns {RequestState[]} an array of request states for any pending requests for the given identifier
|
|
5102
|
+
*/
|
|
4835
5103
|
getPendingRequestsForRecord(identifier) {
|
|
4836
5104
|
if (this._pending[identifier.lid]) {
|
|
4837
5105
|
return this._pending[identifier.lid];
|
|
4838
5106
|
}
|
|
4839
5107
|
return [];
|
|
4840
5108
|
}
|
|
5109
|
+
|
|
5110
|
+
/**
|
|
5111
|
+
* Retrieve the last completed request for a given resource identity.
|
|
5112
|
+
*
|
|
5113
|
+
* @method getLastRequestForRecord
|
|
5114
|
+
* @public
|
|
5115
|
+
* @param {StableRecordIdentifier} identifier
|
|
5116
|
+
* @returns {RequestState | null} the state of the most recent request for the given identifier
|
|
5117
|
+
*/
|
|
4841
5118
|
getLastRequestForRecord(identifier) {
|
|
4842
5119
|
let requests = this._done.get(identifier);
|
|
4843
5120
|
if (requests) {
|
|
@@ -4854,6 +5131,27 @@ class RequestCache {
|
|
|
4854
5131
|
// hello world
|
|
4855
5132
|
|
|
4856
5133
|
let _Cache;
|
|
5134
|
+
|
|
5135
|
+
/**
|
|
5136
|
+
* A Store coordinates interaction between your application, a [Cache](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache),
|
|
5137
|
+
* and sources of data (such as your API or a local persistence layer)
|
|
5138
|
+
* accessed via a [RequestManager](https://github.com/emberjs/data/tree/main/packages/request).
|
|
5139
|
+
*
|
|
5140
|
+
* ```app/services/store.js
|
|
5141
|
+
* import Store from '@ember-data/store';
|
|
5142
|
+
*
|
|
5143
|
+
* export default class extends Store {}
|
|
5144
|
+
* ```
|
|
5145
|
+
*
|
|
5146
|
+
* Most Ember applications will only have a single `Store` configured as a Service
|
|
5147
|
+
* in this manner. However, setting up multiple stores is possible, including using
|
|
5148
|
+
* each as a unique service.
|
|
5149
|
+
*
|
|
5150
|
+
|
|
5151
|
+
@class Store
|
|
5152
|
+
@public
|
|
5153
|
+
*/
|
|
5154
|
+
|
|
4857
5155
|
class Store {
|
|
4858
5156
|
/**
|
|
4859
5157
|
* Provides access to the NotificationManager associated
|
|
@@ -4879,6 +5177,80 @@ class Store {
|
|
|
4879
5177
|
get schema() {
|
|
4880
5178
|
return this.getSchemaDefinitionService();
|
|
4881
5179
|
}
|
|
5180
|
+
|
|
5181
|
+
/**
|
|
5182
|
+
* Provides access to the IdentifierCache instance
|
|
5183
|
+
* for this store.
|
|
5184
|
+
*
|
|
5185
|
+
* The IdentifierCache can be used to generate or
|
|
5186
|
+
* retrieve a stable unique identifier for any resource.
|
|
5187
|
+
*
|
|
5188
|
+
* @property {IdentifierCache} identifierCache
|
|
5189
|
+
* @public
|
|
5190
|
+
*/
|
|
5191
|
+
|
|
5192
|
+
/**
|
|
5193
|
+
* Provides access to the requestManager instance associated
|
|
5194
|
+
* with this Store instance.
|
|
5195
|
+
*
|
|
5196
|
+
* When using `ember-data` this property is automatically
|
|
5197
|
+
* set to an instance of `RequestManager`. When not using `ember-data`
|
|
5198
|
+
* you must configure this property yourself, either by declaring
|
|
5199
|
+
* it as a service or by initializing it.
|
|
5200
|
+
*
|
|
5201
|
+
* ```ts
|
|
5202
|
+
* import Store, { CacheHandler } from '@ember-data/store';
|
|
5203
|
+
* import RequestManager from '@ember-data/request';
|
|
5204
|
+
* import Fetch from '@ember/data/request/fetch';
|
|
5205
|
+
*
|
|
5206
|
+
* class extends Store {
|
|
5207
|
+
* constructor() {
|
|
5208
|
+
* super(...arguments);
|
|
5209
|
+
* this.requestManager = new RequestManager();
|
|
5210
|
+
* this.requestManager.use([Fetch]);
|
|
5211
|
+
* this.requestManager.useCache(CacheHandler);
|
|
5212
|
+
* }
|
|
5213
|
+
* }
|
|
5214
|
+
* ```
|
|
5215
|
+
*
|
|
5216
|
+
* @public
|
|
5217
|
+
* @property {RequestManager} requestManager
|
|
5218
|
+
*/
|
|
5219
|
+
|
|
5220
|
+
/**
|
|
5221
|
+
* A Property which an App may set to provide a Lifetimes Service
|
|
5222
|
+
* to control when a cached request becomes stale.
|
|
5223
|
+
*
|
|
5224
|
+
* Note, when defined, these methods will only be invoked if a
|
|
5225
|
+
* cache key exists for the request, either because the request
|
|
5226
|
+
* contains `cacheOptions.key` or because the [IdentifierCache](/ember-data/release/classes/IdentifierCache)
|
|
5227
|
+
* was able to generate a key for the request using the configured
|
|
5228
|
+
* [generation method](/ember-data/release/functions/@ember-data%2Fstore/setIdentifierGenerationMethod).
|
|
5229
|
+
*
|
|
5230
|
+
* `isSoftExpired` will only be invoked if `isHardExpired` returns `false`.
|
|
5231
|
+
*
|
|
5232
|
+
* ```ts
|
|
5233
|
+
* store.lifetimes = {
|
|
5234
|
+
* // make the request and ignore the current cache state
|
|
5235
|
+
* isHardExpired(identifier: StableDocumentIdentifier): boolean {
|
|
5236
|
+
* return false;
|
|
5237
|
+
* }
|
|
5238
|
+
*
|
|
5239
|
+
* // make the request in the background if true, return cache state
|
|
5240
|
+
* isSoftExpired(identifier: StableDocumentIdentifier): boolean {
|
|
5241
|
+
* return false;
|
|
5242
|
+
* }
|
|
5243
|
+
* }
|
|
5244
|
+
* ```
|
|
5245
|
+
*
|
|
5246
|
+
* @public
|
|
5247
|
+
* @property {LivetimesService|undefined} lifetimes
|
|
5248
|
+
*/
|
|
5249
|
+
|
|
5250
|
+
// Private
|
|
5251
|
+
|
|
5252
|
+
// DEBUG-only properties
|
|
5253
|
+
|
|
4882
5254
|
/**
|
|
4883
5255
|
@method init
|
|
4884
5256
|
@private
|
|
@@ -4896,11 +5268,12 @@ class Store {
|
|
|
4896
5268
|
});
|
|
4897
5269
|
|
|
4898
5270
|
// private
|
|
4899
|
-
this._requestCache = new
|
|
5271
|
+
this._requestCache = new RequestStateService(this);
|
|
4900
5272
|
this._instanceCache = new InstanceCache(this);
|
|
4901
5273
|
this._adapterCache = Object.create(null);
|
|
4902
5274
|
this._serializerCache = Object.create(null);
|
|
4903
5275
|
this._modelFactoryCache = Object.create(null);
|
|
5276
|
+
this._documentCache = new Map();
|
|
4904
5277
|
}
|
|
4905
5278
|
_run(cb) {
|
|
4906
5279
|
assert(`EmberData should never encounter a nested run`, !this._cbs);
|
|
@@ -4952,6 +5325,7 @@ class Store {
|
|
|
4952
5325
|
lids.forEach(lid => {
|
|
4953
5326
|
all.push(...pending[lid].map(v => v[RequestPromise]));
|
|
4954
5327
|
});
|
|
5328
|
+
this.requestManager._pending.forEach(v => all.push(v));
|
|
4955
5329
|
const promise = Promise.allSettled(all);
|
|
4956
5330
|
promise.length = all.length;
|
|
4957
5331
|
return promise;
|