@warp-drive/legacy 5.8.0-beta.0 → 5.8.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +16 -26
  2. package/declarations/adapter/error.d.ts +7 -7
  3. package/declarations/adapter/json-api.d.ts +6 -8
  4. package/declarations/adapter/rest.d.ts +26 -112
  5. package/declarations/adapter.d.ts +6 -8
  6. package/declarations/compat/-private.d.ts +1 -1
  7. package/declarations/compat/builders/find-all.d.ts +6 -6
  8. package/declarations/compat/builders/find-record.d.ts +8 -8
  9. package/declarations/compat/builders/query.d.ts +12 -12
  10. package/declarations/compat/extensions.d.ts +1 -1
  11. package/declarations/compat/legacy-network-handler/minimum-adapter-interface.d.ts +7 -9
  12. package/declarations/compat/legacy-network-handler/minimum-serializer-interface.d.ts +20 -30
  13. package/declarations/compat/utils.d.ts +17 -17
  14. package/declarations/compat.d.ts +35 -11
  15. package/declarations/index.d.ts +102 -0
  16. package/declarations/model/-private/attr.d.ts +5 -6
  17. package/declarations/model/-private/belongs-to.d.ts +4 -5
  18. package/declarations/model/-private/has-many.d.ts +4 -5
  19. package/declarations/model/-private/hooks.d.ts +1 -1
  20. package/declarations/model/-private/legacy-relationships-support.d.ts +2 -2
  21. package/declarations/model/-private/model.d.ts +18 -59
  22. package/declarations/model/-private/promise-many-array.d.ts +0 -18
  23. package/declarations/model/-private/record-state.d.ts +1 -1
  24. package/declarations/model/-private/references/belongs-to.d.ts +19 -29
  25. package/declarations/model/-private/references/has-many.d.ts +14 -16
  26. package/declarations/model/migration-support.d.ts +46 -21
  27. package/declarations/model-fragments/extensions/fragment-array.d.ts +16 -0
  28. package/declarations/model-fragments/extensions/fragment.d.ts +15 -0
  29. package/declarations/model-fragments/hooks/model-for.d.ts +20 -0
  30. package/declarations/model-fragments/index.d.ts +5 -0
  31. package/declarations/model-fragments/instance-initializers/fragment-extensions.d.ts +9 -0
  32. package/declarations/model-fragments/utilities/with-array-defaults.d.ts +15 -0
  33. package/declarations/model-fragments/utilities/with-fragment-array-defaults.d.ts +20 -0
  34. package/declarations/model-fragments/utilities/with-fragment-defaults.d.ts +19 -0
  35. package/declarations/model-fragments/utilities/with-legacy.d.ts +3 -0
  36. package/declarations/model-fragments.d.ts +9 -0
  37. package/declarations/model.d.ts +2 -2
  38. package/declarations/serializer/-private/embedded-records-mixin.d.ts +1 -6
  39. package/declarations/serializer/-private/transforms/boolean.d.ts +2 -2
  40. package/declarations/serializer/-private/transforms/date.d.ts +2 -2
  41. package/declarations/serializer/-private/transforms/number.d.ts +1 -1
  42. package/declarations/serializer/-private/transforms/string.d.ts +1 -1
  43. package/declarations/serializer/json-api.d.ts +11 -12
  44. package/declarations/serializer/json.d.ts +9 -11
  45. package/declarations/serializer/rest.d.ts +4 -6
  46. package/declarations/serializer.d.ts +9 -12
  47. package/dist/{-private-8UmnAf9J.js → -private-BG3bMiKp.js} +3 -2
  48. package/dist/adapter/-private.js +1 -1
  49. package/dist/adapter/error.js +14 -15
  50. package/dist/adapter/json-api.js +4 -1
  51. package/dist/adapter/rest.js +38 -125
  52. package/dist/adapter.js +6 -8
  53. package/dist/compat/-private.js +1 -1
  54. package/dist/compat/builders.js +26 -26
  55. package/dist/compat/utils.js +17 -18
  56. package/dist/compat.js +61 -43
  57. package/dist/{errors-8kD2mSe_.js → errors-Cz5KrzBk.js} +115 -122
  58. package/dist/hooks-D6diaM34.js +74 -0
  59. package/dist/index.js +195 -0
  60. package/dist/{json-Et4mt_LM.js → json-ChdEfB0X.js} +18 -35
  61. package/dist/model/-private.js +1 -1
  62. package/dist/model/migration-support.js +59 -27
  63. package/dist/model-for-CqXsIKws.js +221 -0
  64. package/dist/model-fragments.js +76 -0
  65. package/dist/model.js +18 -90
  66. package/dist/{schema-provider-DQu4Rjco.js → schema-provider-DJCV_6AF.js} +50 -95
  67. package/dist/{serialize-into-hash-CS0MIv4F.js → serialize-into-hash-DPZYoF-i.js} +1 -1
  68. package/dist/serializer/json-api.js +18 -45
  69. package/dist/serializer/json.js +1 -1
  70. package/dist/serializer/rest.js +14 -21
  71. package/dist/serializer/transform.js +15 -6
  72. package/dist/serializer.js +9 -13
  73. package/dist/store.js +5 -1
  74. package/dist/unpkg/dev/-private-DtjBbEgy.js +1206 -0
  75. package/dist/unpkg/dev/adapter/-private.js +1 -0
  76. package/dist/unpkg/dev/adapter/error.js +335 -0
  77. package/dist/unpkg/dev/adapter/json-api.js +271 -0
  78. package/dist/unpkg/dev/adapter/rest.js +1171 -0
  79. package/dist/unpkg/dev/adapter.js +1252 -0
  80. package/dist/unpkg/dev/compat/-private.js +1 -0
  81. package/dist/unpkg/dev/compat/builders.js +275 -0
  82. package/dist/unpkg/dev/compat/extensions.js +242 -0
  83. package/dist/unpkg/dev/compat/utils.js +223 -0
  84. package/dist/unpkg/dev/compat.js +1147 -0
  85. package/dist/unpkg/dev/errors-DmGGJr3T.js +2562 -0
  86. package/dist/unpkg/dev/hooks-CkYiE6Ud.js +73 -0
  87. package/dist/unpkg/dev/index.js +197 -0
  88. package/dist/unpkg/dev/json-Cu1LNgmQ.js +1256 -0
  89. package/dist/unpkg/dev/model/-private.js +1 -0
  90. package/dist/unpkg/dev/model/migration-support.js +553 -0
  91. package/dist/unpkg/dev/model-for-CqXsIKws.js +221 -0
  92. package/dist/unpkg/dev/model-fragments.js +76 -0
  93. package/dist/unpkg/dev/model.js +678 -0
  94. package/dist/unpkg/dev/runtime-BPCpkOf1-BKOwiRJp.js +65 -0
  95. package/dist/unpkg/dev/schema-provider-DDVYxmUV.js +2186 -0
  96. package/dist/unpkg/dev/serialize-into-hash-B2xDbuo5.js +259 -0
  97. package/dist/unpkg/dev/serializer/json-api.js +649 -0
  98. package/dist/unpkg/dev/serializer/json.js +4 -0
  99. package/dist/unpkg/dev/serializer/rest.js +1242 -0
  100. package/dist/unpkg/dev/serializer/transform.js +278 -0
  101. package/dist/unpkg/dev/serializer.js +248 -0
  102. package/dist/unpkg/dev/store.js +637 -0
  103. package/dist/unpkg/dev/util-DvanW33H.js +20 -0
  104. package/dist/unpkg/dev/utils-BhvS1iTS.js +8 -0
  105. package/dist/unpkg/dev-deprecated/-private-DtjBbEgy.js +1206 -0
  106. package/dist/unpkg/dev-deprecated/adapter/-private.js +1 -0
  107. package/dist/unpkg/dev-deprecated/adapter/error.js +335 -0
  108. package/dist/unpkg/dev-deprecated/adapter/json-api.js +271 -0
  109. package/dist/unpkg/dev-deprecated/adapter/rest.js +1171 -0
  110. package/dist/unpkg/dev-deprecated/adapter.js +1252 -0
  111. package/dist/unpkg/dev-deprecated/compat/-private.js +1 -0
  112. package/dist/unpkg/dev-deprecated/compat/builders.js +275 -0
  113. package/dist/unpkg/dev-deprecated/compat/extensions.js +242 -0
  114. package/dist/unpkg/dev-deprecated/compat/utils.js +223 -0
  115. package/dist/unpkg/dev-deprecated/compat.js +1147 -0
  116. package/dist/unpkg/dev-deprecated/errors-Spt6ubMd.js +2565 -0
  117. package/dist/unpkg/dev-deprecated/hooks-DOXegvhL.js +73 -0
  118. package/dist/unpkg/dev-deprecated/index.js +196 -0
  119. package/dist/unpkg/dev-deprecated/json-Cu1LNgmQ.js +1256 -0
  120. package/dist/unpkg/dev-deprecated/model/-private.js +1 -0
  121. package/dist/unpkg/dev-deprecated/model/migration-support.js +570 -0
  122. package/dist/unpkg/dev-deprecated/model-for-CqXsIKws.js +221 -0
  123. package/dist/unpkg/dev-deprecated/model-fragments.js +76 -0
  124. package/dist/unpkg/dev-deprecated/model.js +682 -0
  125. package/dist/unpkg/dev-deprecated/runtime-BPCpkOf1-BKOwiRJp.js +65 -0
  126. package/dist/unpkg/dev-deprecated/schema-provider-BP6_8N-V.js +2211 -0
  127. package/dist/unpkg/dev-deprecated/serialize-into-hash-B2xDbuo5.js +259 -0
  128. package/dist/unpkg/dev-deprecated/serializer/json-api.js +649 -0
  129. package/dist/unpkg/dev-deprecated/serializer/json.js +4 -0
  130. package/dist/unpkg/dev-deprecated/serializer/rest.js +1242 -0
  131. package/dist/unpkg/dev-deprecated/serializer/transform.js +278 -0
  132. package/dist/unpkg/dev-deprecated/serializer.js +248 -0
  133. package/dist/unpkg/dev-deprecated/store.js +637 -0
  134. package/dist/unpkg/dev-deprecated/util-CWr5WQOT.js +24 -0
  135. package/dist/unpkg/dev-deprecated/utils-C9PJehtL.js +12 -0
  136. package/dist/unpkg/prod/-private-BdyZaGEh.js +971 -0
  137. package/dist/unpkg/prod/adapter/-private.js +1 -0
  138. package/dist/unpkg/prod/adapter/error.js +330 -0
  139. package/dist/unpkg/prod/adapter/json-api.js +266 -0
  140. package/dist/unpkg/prod/adapter/rest.js +1134 -0
  141. package/dist/unpkg/prod/adapter.js +1219 -0
  142. package/dist/unpkg/prod/compat/-private.js +1 -0
  143. package/dist/unpkg/prod/compat/builders.js +210 -0
  144. package/dist/unpkg/prod/compat/extensions.js +232 -0
  145. package/dist/unpkg/prod/compat/utils.js +218 -0
  146. package/dist/unpkg/prod/compat.js +727 -0
  147. package/dist/unpkg/prod/errors-BGVFCBmi.js +2314 -0
  148. package/dist/unpkg/prod/hooks-BztVA_x0.js +41 -0
  149. package/dist/unpkg/prod/index.js +151 -0
  150. package/dist/unpkg/prod/json-BWrZ5546.js +1243 -0
  151. package/dist/unpkg/prod/model/-private.js +1 -0
  152. package/dist/unpkg/prod/model/migration-support.js +546 -0
  153. package/dist/unpkg/prod/model-for-CqXsIKws.js +221 -0
  154. package/dist/unpkg/prod/model-fragments.js +76 -0
  155. package/dist/unpkg/prod/model.js +593 -0
  156. package/dist/unpkg/prod/runtime-BPCpkOf1-BKOwiRJp.js +65 -0
  157. package/dist/unpkg/prod/schema-provider-DJtD_8jZ.js +1861 -0
  158. package/dist/unpkg/prod/serialize-into-hash-DGlzQteF.js +215 -0
  159. package/dist/unpkg/prod/serializer/json-api.js +592 -0
  160. package/dist/unpkg/prod/serializer/json.js +4 -0
  161. package/dist/unpkg/prod/serializer/rest.js +1210 -0
  162. package/dist/unpkg/prod/serializer/transform.js +278 -0
  163. package/dist/unpkg/prod/serializer.js +248 -0
  164. package/dist/unpkg/prod/store.js +505 -0
  165. package/dist/unpkg/prod/util-DvanW33H.js +20 -0
  166. package/dist/unpkg/prod/utils-BhvS1iTS.js +8 -0
  167. package/dist/unpkg/prod-deprecated/-private-BdyZaGEh.js +971 -0
  168. package/dist/unpkg/prod-deprecated/adapter/-private.js +1 -0
  169. package/dist/unpkg/prod-deprecated/adapter/error.js +330 -0
  170. package/dist/unpkg/prod-deprecated/adapter/json-api.js +266 -0
  171. package/dist/unpkg/prod-deprecated/adapter/rest.js +1134 -0
  172. package/dist/unpkg/prod-deprecated/adapter.js +1219 -0
  173. package/dist/unpkg/prod-deprecated/compat/-private.js +1 -0
  174. package/dist/unpkg/prod-deprecated/compat/builders.js +210 -0
  175. package/dist/unpkg/prod-deprecated/compat/extensions.js +232 -0
  176. package/dist/unpkg/prod-deprecated/compat/utils.js +218 -0
  177. package/dist/unpkg/prod-deprecated/compat.js +727 -0
  178. package/dist/unpkg/prod-deprecated/errors-CdDaK81x.js +2317 -0
  179. package/dist/unpkg/prod-deprecated/hooks-yId87yyG.js +41 -0
  180. package/dist/unpkg/prod-deprecated/index.js +150 -0
  181. package/dist/unpkg/prod-deprecated/json-BWrZ5546.js +1243 -0
  182. package/dist/unpkg/prod-deprecated/model/-private.js +1 -0
  183. package/dist/unpkg/prod-deprecated/model/migration-support.js +563 -0
  184. package/dist/unpkg/prod-deprecated/model-for-CqXsIKws.js +221 -0
  185. package/dist/unpkg/prod-deprecated/model-fragments.js +76 -0
  186. package/dist/unpkg/prod-deprecated/model.js +596 -0
  187. package/dist/unpkg/prod-deprecated/runtime-BPCpkOf1-BKOwiRJp.js +65 -0
  188. package/dist/unpkg/prod-deprecated/schema-provider-CjX55uSY.js +1904 -0
  189. package/dist/unpkg/prod-deprecated/serialize-into-hash-DGlzQteF.js +215 -0
  190. package/dist/unpkg/prod-deprecated/serializer/json-api.js +592 -0
  191. package/dist/unpkg/prod-deprecated/serializer/json.js +4 -0
  192. package/dist/unpkg/prod-deprecated/serializer/rest.js +1210 -0
  193. package/dist/unpkg/prod-deprecated/serializer/transform.js +278 -0
  194. package/dist/unpkg/prod-deprecated/serializer.js +248 -0
  195. package/dist/unpkg/prod-deprecated/store.js +505 -0
  196. package/dist/unpkg/prod-deprecated/util-B6cn-i93.js +23 -0
  197. package/dist/unpkg/prod-deprecated/utils-BUWwQwCh.js +11 -0
  198. package/logos/README.md +2 -2
  199. package/logos/logo-yellow-slab.svg +1 -0
  200. package/logos/word-mark-black.svg +1 -0
  201. package/logos/word-mark-white.svg +1 -0
  202. package/package.json +15 -7
  203. package/logos/NCC-1701-a-blue.svg +0 -4
  204. package/logos/NCC-1701-a-gold.svg +0 -4
  205. package/logos/NCC-1701-a-gold_100.svg +0 -1
  206. package/logos/NCC-1701-a-gold_base-64.txt +0 -1
  207. package/logos/NCC-1701-a.svg +0 -4
  208. package/logos/docs-badge.svg +0 -2
  209. package/logos/ember-data-logo-dark.svg +0 -12
  210. package/logos/ember-data-logo-light.svg +0 -12
  211. package/logos/social1.png +0 -0
  212. package/logos/social2.png +0 -0
  213. package/logos/warp-drive-logo-dark.svg +0 -4
  214. package/logos/warp-drive-logo-gold.svg +0 -4
@@ -0,0 +1,971 @@
1
+ import { Context } from '@warp-drive/core/reactive/-private';
2
+ import { createDeferred } from '@warp-drive/core/request';
3
+ import '@warp-drive/core/signals/-leaked';
4
+ import { assertPrivateStore } from '@warp-drive/core/store/-private';
5
+ import { getOrSetGlobal } from '@warp-drive/core/types/-private';
6
+
7
+ /**
8
+ SnapshotRecordArray is not directly instantiable.
9
+ Instances are provided to consuming application's
10
+ adapters for certain `findAll` requests.
11
+
12
+ @hideconstructor
13
+ @public
14
+ */
15
+ class SnapshotRecordArray {
16
+ /**
17
+ * An array of snapshots
18
+ *
19
+ * @internal
20
+ */
21
+
22
+ /** @internal */
23
+
24
+ /**
25
+ * The ResourceType of the underlying records for the {@link Snapshot | Snapshots} in the array
26
+ */
27
+
28
+ /** @internal */
29
+
30
+ /**
31
+ * A hash of adapter options passed into the store method for this request.
32
+ Example
33
+ ```js [app/adapters/post.js]
34
+ import MyCustomAdapter from './custom-adapter';
35
+ export default class PostAdapter extends MyCustomAdapter {
36
+ findAll(store, type, sinceToken, snapshotRecordArray) {
37
+ if (snapshotRecordArray.adapterOptions.subscribe) {
38
+ // ...
39
+ }
40
+ // ...
41
+ }
42
+ }
43
+ ```
44
+ */
45
+
46
+ /**
47
+ * The relationships to include for this request.
48
+ Example
49
+ ```js [app/adapters/application.js]
50
+ import Adapter from '@ember-data/adapter';
51
+ export default class ApplicationAdapter extends Adapter {
52
+ findAll(store, type, snapshotRecordArray) {
53
+ let url = `/${type.modelName}?include=${encodeURIComponent(snapshotRecordArray.include)}`;
54
+ return fetch(url).then((response) => response.json())
55
+ }
56
+ }
57
+ ```
58
+ */
59
+
60
+ /**
61
+ SnapshotRecordArray is not directly instantiable.
62
+ Instances are provided to consuming application's
63
+ adapters and serializers for certain requests.
64
+ @private
65
+ @constructor
66
+ @param {Store} store
67
+ @param {String} type
68
+ @param options
69
+ */
70
+ constructor(store, type, options = {}) {
71
+ this.__store = store;
72
+ this._snapshots = null;
73
+ this.modelName = type;
74
+ this.adapterOptions = options.adapterOptions;
75
+ this.include = options.include;
76
+ }
77
+
78
+ /**
79
+ An array of records
80
+ @internal
81
+ */
82
+ get _recordArray() {
83
+ return this.__store.peekAll(this.modelName);
84
+ }
85
+
86
+ /**
87
+ Number of records in the array
88
+ Example
89
+ ```js [app/adapters/post.js]
90
+ import JSONAPIAdapter from '@ember-data/adapter/json-api';
91
+ export default class PostAdapter extends JSONAPIAdapter {
92
+ shouldReloadAll(store, snapshotRecordArray) {
93
+ return !snapshotRecordArray.length;
94
+ }
95
+ });
96
+ ```
97
+ */
98
+ get length() {
99
+ return this._recordArray.length;
100
+ }
101
+
102
+ /**
103
+ Get snapshots of the underlying record array
104
+ Example
105
+ ```js [app/adapters/post.js]
106
+ import JSONAPIAdapter from '@ember-data/adapter/json-api';
107
+ export default class PostAdapter extends JSONAPIAdapter {
108
+ shouldReloadAll(store, snapshotArray) {
109
+ let snapshots = snapshotArray.snapshots();
110
+ return snapshots.any(function(ticketSnapshot) {
111
+ let timeDiff = moment().diff(ticketSnapshot.attr('lastAccessedAt'), 'minutes');
112
+ if (timeDiff > 20) {
113
+ return true;
114
+ } else {
115
+ return false;
116
+ }
117
+ });
118
+ }
119
+ }
120
+ ```
121
+ @public
122
+ @return Array of snapshots
123
+ */
124
+ snapshots() {
125
+ if (this._snapshots !== null) {
126
+ return this._snapshots;
127
+ }
128
+ upgradeStore(this.__store);
129
+ const {
130
+ _fetchManager
131
+ } = this.__store;
132
+ const LiveArrayContext = this._recordArray[Context];
133
+ this._snapshots = LiveArrayContext.source.map(identifier => _fetchManager.createSnapshot(identifier));
134
+ return this._snapshots;
135
+ }
136
+ }
137
+
138
+ /**
139
+ This is a helper method that validates a JSON API top-level document
140
+
141
+ The format of a document is described here:
142
+ http://jsonapi.org/format/#document-top-level
143
+
144
+ @internal
145
+ */
146
+ function normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
147
+ const normalizedResponse = serializer ? serializer.normalizeResponse(store, modelClass, payload, id, requestType) : payload;
148
+ return normalizedResponse;
149
+ }
150
+
151
+ /**
152
+ Snapshot is not directly instantiable.
153
+ Instances are provided to a consuming application's
154
+ adapters and serializers for certain requests.
155
+
156
+ Snapshots are only available when using `@ember-data/legacy-compat`
157
+ for legacy compatibility with adapters and serializers.
158
+
159
+ For serialization of records in modern paradigms, request data from
160
+ the cache or off the record directly.
161
+
162
+ @hideconstructor
163
+ @public
164
+ */
165
+ class Snapshot {
166
+ /** @internal */
167
+
168
+ /** @internal */
169
+
170
+ /** @internal */
171
+
172
+ /** @internal */
173
+
174
+ /** @internal */
175
+
176
+ /** @internal */
177
+
178
+ /** @internal */
179
+
180
+ /**
181
+ The unique ResourceKey associated with this Snapshot.
182
+ @public
183
+ */
184
+
185
+ /**
186
+ The ResourceType of the underlying record for this Snapshot, as a string.
187
+ @public
188
+ */
189
+
190
+ /**
191
+ The id of the snapshot's underlying record
192
+ Example
193
+ ```js
194
+ // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
195
+ postSnapshot.id; // => '1'
196
+ ```
197
+ @public
198
+ */
199
+
200
+ /**
201
+ If `include` was passed to the options for the request, the value
202
+ would be available here.
203
+ @public
204
+ */
205
+
206
+ /**
207
+ The adapterOptions passed to the request which generated this Snapshot, if any
208
+ @public
209
+ */
210
+
211
+ constructor(options, identifier, store) {
212
+ this._store = store;
213
+ this.__attributes = null;
214
+ this._belongsToRelationships = Object.create(null);
215
+ this._belongsToIds = Object.create(null);
216
+ this._hasManyRelationships = Object.create(null);
217
+ this._hasManyIds = Object.create(null);
218
+ assertPrivateStore(store);
219
+ const hasRecord = !!store._instanceCache.peek(identifier);
220
+ this.modelName = identifier.type;
221
+ this.identifier = identifier;
222
+
223
+ /*
224
+ If the we do not yet have a record, then we are
225
+ likely a snapshot being provided to a find request, so we
226
+ populate __attributes lazily. Else, to preserve the "moment
227
+ in time" in which a snapshot is created, we greedily grab
228
+ the values.
229
+ */
230
+ if (hasRecord) {
231
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
232
+ this._attributes;
233
+ }
234
+ this.id = identifier.id;
235
+ this.adapterOptions = options.adapterOptions;
236
+ this.include = options.include;
237
+ this.modelName = identifier.type;
238
+ if (hasRecord) {
239
+ const cache = this._store.cache;
240
+ this._changedAttributes = cache.changedAttrs(identifier);
241
+ }
242
+ }
243
+
244
+ /**
245
+ The underlying record for this snapshot. Can be used to access methods and
246
+ properties defined on the record.
247
+ ```js
248
+ const someValue = snapshot.record.someProp;
249
+ ```
250
+ @property record
251
+ @public
252
+ */
253
+ get record() {
254
+ const record = this._store.peekRecord(this.identifier);
255
+ return record;
256
+ }
257
+
258
+ /** @internal */
259
+ get _attributes() {
260
+ if (this.__attributes !== null) {
261
+ return this.__attributes;
262
+ }
263
+ const attributes = this.__attributes = Object.create(null);
264
+ const {
265
+ identifier
266
+ } = this;
267
+ const cache = this._store.cache;
268
+ this.eachAttribute((key, meta) => {
269
+ attributes[key] = cache.getAttr(identifier, key);
270
+ });
271
+ return attributes;
272
+ }
273
+ get isNew() {
274
+ const cache = this._store.cache;
275
+ return cache?.isNew(this.identifier) || false;
276
+ }
277
+
278
+ /**
279
+ Returns the value of an attribute.
280
+ Example
281
+ ```javascript
282
+ // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
283
+ postSnapshot.attr('author'); // => 'Tomster'
284
+ postSnapshot.attr('title'); // => 'Ember.js rocks'
285
+ ```
286
+ Note: Values are loaded eagerly and cached when the snapshot is created.
287
+ @return The attribute value or undefined
288
+ @public
289
+ */
290
+ attr(keyName) {
291
+ if (keyName in this._attributes) {
292
+ return this._attributes[keyName];
293
+ }
294
+ }
295
+
296
+ /**
297
+ Returns all attributes and their corresponding values.
298
+ ::: warning ⚠️ WARNING
299
+ Attributes are SHALLOW copied from the cache.
300
+ Because they are NOT deep copied from the cache, mutating
301
+ any object or array fields will cause unintended side-effects
302
+ and bugs.
303
+ :::
304
+ Example
305
+ ```js
306
+ // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
307
+ postSnapshot.attributes(); // => { author: 'Tomster', title: 'Ember.js rocks' }
308
+ ```
309
+ @return All attributes of the current snapshot
310
+ @public
311
+ */
312
+ attributes() {
313
+ return {
314
+ ...this._attributes
315
+ };
316
+ }
317
+
318
+ /**
319
+ Returns all changed attributes and their old and new values.
320
+ Example
321
+ ```js
322
+ // store.push('post', { id: 1, author: 'Tomster', title: 'Ember.js rocks' });
323
+ postModel.set('title', 'Ember.js rocks!');
324
+ postSnapshot.changedAttributes(); // => { title: ['Ember.js rocks', 'Ember.js rocks!'] }
325
+ ```
326
+ @return All changed attributes of the current snapshot
327
+ @public
328
+ */
329
+ changedAttributes() {
330
+ const changedAttributes = Object.create(null);
331
+ if (!this._changedAttributes) {
332
+ return changedAttributes;
333
+ }
334
+ const changedAttributeKeys = Object.keys(this._changedAttributes);
335
+ for (let i = 0, length = changedAttributeKeys.length; i < length; i++) {
336
+ const key = changedAttributeKeys[i];
337
+ changedAttributes[key] = this._changedAttributes[key].slice();
338
+ }
339
+ return changedAttributes;
340
+ }
341
+
342
+ /**
343
+ Returns the current value of a belongsTo relationship.
344
+ `belongsTo` takes an optional hash of options as a second parameter,
345
+ currently supported options are:
346
+ - `id`: set to `true` if you only want the ID of the related record to be
347
+ returned.
348
+ Example
349
+ ```js
350
+ // store.push('post', { id: 1, title: 'Hello World' });
351
+ // store.createRecord('comment', { body: 'Lorem ipsum', post: post });
352
+ commentSnapshot.belongsTo('post'); // => Snapshot
353
+ commentSnapshot.belongsTo('post', { id: true }); // => '1'
354
+ // store.push('comment', { id: 1, body: 'Lorem ipsum' });
355
+ commentSnapshot.belongsTo('post'); // => undefined
356
+ ```
357
+ Calling `belongsTo` will return a new Snapshot as long as there's any known
358
+ data for the relationship available, such as an ID. If the relationship is
359
+ known but unset, `belongsTo` will return `null`. If the contents of the
360
+ relationship is unknown `belongsTo` will return `undefined`.
361
+ Note: Relationships are loaded lazily and cached upon first access.
362
+ @public
363
+ @return A snapshot or ID of a known relationship or null if the
364
+ relationship is known but unset. undefined will be returned if the
365
+ contents of the relationship are unknown.
366
+ */
367
+ belongsTo(keyName, options) {
368
+ const returnModeIsId = !!(options && options.id);
369
+ let result;
370
+ const store = this._store;
371
+ if (returnModeIsId === true && keyName in this._belongsToIds) {
372
+ return this._belongsToIds[keyName];
373
+ }
374
+ if (returnModeIsId === false && keyName in this._belongsToRelationships) {
375
+ return this._belongsToRelationships[keyName];
376
+ }
377
+ store.schema.fields({
378
+ type: this.modelName
379
+ }).get(keyName);
380
+ const {
381
+ identifier
382
+ } = this;
383
+ const value = this._store.cache.getRelationship(identifier, keyName);
384
+ const data = value && value.data;
385
+ const inverseIdentifier = data ? store.cacheKeyManager.getOrCreateRecordIdentifier(data) : null;
386
+ if (value && value.data !== undefined) {
387
+ const cache = store.cache;
388
+ if (inverseIdentifier && !cache.isDeleted(inverseIdentifier)) {
389
+ if (returnModeIsId) {
390
+ result = inverseIdentifier.id;
391
+ } else {
392
+ result = store._fetchManager.createSnapshot(inverseIdentifier);
393
+ }
394
+ } else {
395
+ result = null;
396
+ }
397
+ }
398
+ if (returnModeIsId) {
399
+ this._belongsToIds[keyName] = result;
400
+ } else {
401
+ this._belongsToRelationships[keyName] = result;
402
+ }
403
+ return result;
404
+ }
405
+
406
+ /**
407
+ Returns the current value of a hasMany relationship.
408
+ `hasMany` takes an optional hash of options as a second parameter,
409
+ currently supported options are:
410
+ - `ids`: set to `true` if you only want the IDs of the related records to be
411
+ returned.
412
+ Example
413
+ ```javascript
414
+ // store.push('post', { id: 1, title: 'Hello World', comments: [2, 3] });
415
+ postSnapshot.hasMany('comments'); // => [Snapshot, Snapshot]
416
+ postSnapshot.hasMany('comments', { ids: true }); // => ['2', '3']
417
+ // store.push('post', { id: 1, title: 'Hello World' });
418
+ postSnapshot.hasMany('comments'); // => undefined
419
+ ```
420
+ Note: Relationships are loaded lazily and cached upon first access.
421
+ @public
422
+ @return An array of snapshots or IDs of a known
423
+ relationship or an empty array if the relationship is known but unset.
424
+ undefined will be returned if the contents of the relationship is unknown.
425
+ */
426
+ hasMany(keyName, options) {
427
+ const returnModeIsIds = !!(options && options.ids);
428
+ let results;
429
+ const cachedIds = this._hasManyIds[keyName];
430
+ const cachedSnapshots = this._hasManyRelationships[keyName];
431
+ if (returnModeIsIds === true && keyName in this._hasManyIds) {
432
+ return cachedIds;
433
+ }
434
+ if (returnModeIsIds === false && keyName in this._hasManyRelationships) {
435
+ return cachedSnapshots;
436
+ }
437
+ const store = this._store;
438
+ store.schema.fields({
439
+ type: this.modelName
440
+ }).get(keyName);
441
+ const {
442
+ identifier
443
+ } = this;
444
+ const value = this._store.cache.getRelationship(identifier, keyName);
445
+ if (value.data) {
446
+ results = [];
447
+ value.data.forEach(member => {
448
+ const inverseIdentifier = store.cacheKeyManager.getOrCreateRecordIdentifier(member);
449
+ const cache = store.cache;
450
+ if (!cache.isDeleted(inverseIdentifier)) {
451
+ if (returnModeIsIds) {
452
+ results.push(inverseIdentifier.id);
453
+ } else {
454
+ results.push(store._fetchManager.createSnapshot(inverseIdentifier));
455
+ }
456
+ }
457
+ });
458
+ }
459
+
460
+ // we assign even if `undefined` so that we don't reprocess the relationship
461
+ // on next access. This works with the `keyName in` checks above.
462
+ if (returnModeIsIds) {
463
+ this._hasManyIds[keyName] = results;
464
+ } else {
465
+ this._hasManyRelationships[keyName] = results;
466
+ }
467
+ return results;
468
+ }
469
+
470
+ /**
471
+ Iterates through all the attributes of the model, calling the passed
472
+ function on each attribute.
473
+ Example
474
+ ```javascript
475
+ snapshot.eachAttribute(function(name, meta) {
476
+ // ...
477
+ });
478
+ ```
479
+ @param callback the callback to execute
480
+ @param binding the optional value to which the callback's `this` should be bound
481
+ @public
482
+ */
483
+ eachAttribute(callback, binding) {
484
+ // if the store has a modelFor implementation, we use it to iterate attributes. This allows
485
+ // a custom "ModelSchema" class for legacy serializers to adapt to new fields if desired.
486
+ if (typeof this._store.modelFor === 'function') {
487
+ const modelSchema = this._store.modelFor(this.identifier.type);
488
+ modelSchema.eachAttribute(callback, binding);
489
+ } else {
490
+ const fields = this._store.schema.fields(this.identifier);
491
+ fields.forEach((field, key) => {
492
+ if (field.kind === 'attribute') {
493
+ callback.call(binding, key, field);
494
+ }
495
+ });
496
+ }
497
+ }
498
+
499
+ /**
500
+ Iterates through all the relationships of the model, calling the passed
501
+ function on each relationship.
502
+ Example
503
+ ```javascript
504
+ snapshot.eachRelationship(function(name, relationship) {
505
+ // ...
506
+ });
507
+ ```
508
+ @param callback the callback to execute
509
+ @param binding the optional value to which the callback's `this` should be bound
510
+ @public
511
+ */
512
+ eachRelationship(callback, binding) {
513
+ // if the store has a modelFor implementation, we use it to iterate relationships. This allows
514
+ // a custom "ModelSchema" class for legacy serializers to adapt to new fields if desired.
515
+ if (typeof this._store.modelFor === 'function') {
516
+ const modelSchema = this._store.modelFor(this.identifier.type);
517
+ modelSchema.eachRelationship(callback, binding);
518
+ } else {
519
+ const fields = this._store.schema.fields(this.identifier);
520
+ fields.forEach((field, key) => {
521
+ if (field.kind === 'belongsTo' || field.kind === 'hasMany') {
522
+ callback.call(binding, key, field);
523
+ }
524
+ });
525
+ }
526
+ }
527
+
528
+ /**
529
+ Serializes the snapshot using the serializer for the model.
530
+ Example
531
+ ```js [app/adapters/application.js]
532
+ import Adapter from '@ember-data/adapter';
533
+ export default Adapter.extend({
534
+ createRecord(store, type, snapshot) {
535
+ let data = snapshot.serialize({ includeId: true });
536
+ let url = `/${type.modelName}`;
537
+ return fetch(url, {
538
+ method: 'POST',
539
+ body: data,
540
+ }).then((response) => response.json())
541
+ }
542
+ });
543
+ ```
544
+ @return an object whose values are primitive JSON values only
545
+ @public
546
+ */
547
+ serialize(options) {
548
+ upgradeStore(this._store);
549
+ const serializer = this._store.serializerFor(this.modelName);
550
+ return serializer.serialize(this, options);
551
+ }
552
+ }
553
+ const SaveOp = getOrSetGlobal('SaveOp', Symbol('SaveOp'));
554
+ /**
555
+ * @private
556
+ */
557
+ class FetchManager {
558
+ /**
559
+ * @internal
560
+ */
561
+
562
+ /** @internal */
563
+
564
+ // fetches pending in the runloop, waiting to be coalesced
565
+ /**
566
+ * @internal
567
+ */
568
+
569
+ /** @internal */
570
+
571
+ constructor(store) {
572
+ assertPrivateStore(store);
573
+ this._store = store;
574
+ // used to keep track of all the find requests that need to be coalesced
575
+ this._pendingFetch = new Map();
576
+ this.requestCache = store.getRequestStateService();
577
+ this.isDestroyed = false;
578
+ }
579
+ createSnapshot(identifier, options = {}) {
580
+ return new Snapshot(options, identifier, this._store);
581
+ }
582
+
583
+ /**
584
+ This method is called by `record.save`, and gets passed a
585
+ resolver for the promise that `record.save` returns.
586
+ It schedules saving to happen at the end of the run loop.
587
+ @private
588
+ */
589
+ scheduleSave(identifier, options) {
590
+ const resolver = createDeferred();
591
+ const query = {
592
+ op: 'saveRecord',
593
+ recordIdentifier: identifier,
594
+ options
595
+ };
596
+ const queryRequest = {
597
+ data: [query]
598
+ };
599
+ const snapshot = this.createSnapshot(identifier, options);
600
+ const pendingSaveItem = {
601
+ snapshot: snapshot,
602
+ resolver: resolver,
603
+ identifier,
604
+ options,
605
+ queryRequest
606
+ };
607
+ const monitored = this.requestCache._enqueue(resolver.promise, pendingSaveItem.queryRequest);
608
+ _flushPendingSave(this._store, pendingSaveItem);
609
+ return monitored;
610
+ }
611
+ scheduleFetch(identifier, options, request) {
612
+ const query = {
613
+ op: 'findRecord',
614
+ recordIdentifier: identifier,
615
+ options
616
+ };
617
+ const queryRequest = {
618
+ data: [query]
619
+ };
620
+ const pendingFetch = this.getPendingFetch(identifier, options);
621
+ if (pendingFetch) {
622
+ return pendingFetch;
623
+ }
624
+ const modelName = identifier.type;
625
+ const resolver = createDeferred();
626
+ const pendingFetchItem = {
627
+ identifier,
628
+ resolver,
629
+ options,
630
+ queryRequest
631
+ };
632
+ const resolverPromise = resolver.promise;
633
+ const store = this._store;
634
+ const isInitialLoad = !store._instanceCache.recordIsLoaded(identifier); // we don't use isLoading directly because we are the request
635
+
636
+ const monitored = this.requestCache._enqueue(resolverPromise, pendingFetchItem.queryRequest);
637
+ let promise = monitored.then(payload => {
638
+ // ensure that regardless of id returned we assign to the correct record
639
+ if (payload.data && !Array.isArray(payload.data)) {
640
+ payload.data.lid = identifier.lid;
641
+ }
642
+
643
+ // additional data received in the payload
644
+ // may result in the merging of identifiers (and thus records)
645
+ const potentiallyNewIm = store._push(payload, options.reload);
646
+ if (potentiallyNewIm && !Array.isArray(potentiallyNewIm)) {
647
+ return potentiallyNewIm;
648
+ }
649
+ return identifier;
650
+ }, error => {
651
+ const cache = store.cache;
652
+ if (!cache || cache.isEmpty(identifier) || isInitialLoad) {
653
+ let isReleasable = true;
654
+ if (store._graph) {
655
+ const graph = store._graph;
656
+ if (!cache) {
657
+ isReleasable = graph.isReleasable(identifier);
658
+ if (!isReleasable) {
659
+ graph.unload(identifier, true);
660
+ }
661
+ }
662
+ }
663
+ if (cache || isReleasable) {
664
+ store._enableAsyncFlush = true;
665
+ store._instanceCache.unloadRecord(identifier);
666
+ store._enableAsyncFlush = null;
667
+ }
668
+ }
669
+ throw error;
670
+ });
671
+ if (this._pendingFetch.size === 0) {
672
+ void new Promise(resolve => setTimeout(resolve, 0)).then(() => {
673
+ this.flushAllPendingFetches();
674
+ });
675
+ }
676
+ const fetchesByType = this._pendingFetch;
677
+ let fetchesById = fetchesByType.get(modelName);
678
+ if (!fetchesById) {
679
+ fetchesById = new Map();
680
+ fetchesByType.set(modelName, fetchesById);
681
+ }
682
+ let requestsForIdentifier = fetchesById.get(identifier);
683
+ if (!requestsForIdentifier) {
684
+ requestsForIdentifier = [];
685
+ fetchesById.set(identifier, requestsForIdentifier);
686
+ }
687
+ requestsForIdentifier.push(pendingFetchItem);
688
+ pendingFetchItem.promise = promise;
689
+ return promise;
690
+ }
691
+ getPendingFetch(identifier, options) {
692
+ const pendingFetches = this._pendingFetch.get(identifier.type)?.get(identifier);
693
+
694
+ // We already have a pending fetch for this
695
+ if (pendingFetches) {
696
+ const matchingPendingFetch = pendingFetches.find(fetch => isSameRequest(options, fetch.options));
697
+ if (matchingPendingFetch) {
698
+ return matchingPendingFetch.promise;
699
+ }
700
+ }
701
+ }
702
+ flushAllPendingFetches() {
703
+ if (this.isDestroyed) {
704
+ return;
705
+ }
706
+ const store = this._store;
707
+ this._pendingFetch.forEach((fetchItem, type) => _flushPendingFetchForType(store, fetchItem, type));
708
+ this._pendingFetch.clear();
709
+ }
710
+ fetchDataIfNeededForIdentifier(identifier, options = {}, request) {
711
+ // pre-loading will change the isEmpty value
712
+ const isEmpty = _isEmpty(this._store._instanceCache, identifier);
713
+ const isLoading = _isLoading(this._store._instanceCache, identifier);
714
+ let promise;
715
+ if (isEmpty) {
716
+ {
717
+ options.reload = true;
718
+ promise = this.scheduleFetch(identifier, options, request);
719
+ }
720
+ } else if (isLoading) {
721
+ promise = this.getPendingFetch(identifier, options);
722
+ } else {
723
+ promise = Promise.resolve(identifier);
724
+ }
725
+ return promise;
726
+ }
727
+ destroy() {
728
+ this.isDestroyed = true;
729
+ }
730
+ }
731
+
732
+ /**
733
+ * This type exists for internal use only for
734
+ * where intimate contracts still exist either for
735
+ * the Test Suite or for Legacy code.
736
+ *
737
+ * @private
738
+ */
739
+
740
+ function _isEmpty(instanceCache, identifier) {
741
+ const cache = instanceCache.cache;
742
+ if (!cache) {
743
+ return true;
744
+ }
745
+ const isNew = cache.isNew(identifier);
746
+ const isDeleted = cache.isDeleted(identifier);
747
+ const isEmpty = cache.isEmpty(identifier);
748
+ return (!isNew || isDeleted) && isEmpty;
749
+ }
750
+ function _isLoading(cache, identifier) {
751
+ const req = cache.store.getRequestStateService();
752
+ // const fulfilled = req.getLastRequestForRecord(identifier);
753
+ const isLoaded = cache.recordIsLoaded(identifier);
754
+ return !isLoaded &&
755
+ // fulfilled === null &&
756
+ req.getPendingRequestsForRecord(identifier).some(r => r.type === 'query');
757
+ }
758
+ function includesSatisfies(current, existing) {
759
+ // if we have no includes we are good
760
+ if (!current?.length) {
761
+ return true;
762
+ }
763
+
764
+ // if we are here we have includes,
765
+ // and if existing has no includes then we will need a new request
766
+ if (!existing?.length) {
767
+ return false;
768
+ }
769
+ const arrCurrent = (Array.isArray(current) ? current : current.split(',')).sort();
770
+ const arrExisting = (Array.isArray(existing) ? existing : existing.split(',')).sort();
771
+
772
+ // includes are identical
773
+ if (arrCurrent.join(',') === arrExisting.join(',')) {
774
+ return true;
775
+ }
776
+
777
+ // if all of current includes are in existing includes then we are good
778
+ // so if we find one that is not in existing then we need a new request
779
+ for (let i = 0; i < arrCurrent.length; i++) {
780
+ if (!arrExisting.includes(arrCurrent[i])) {
781
+ return false;
782
+ }
783
+ }
784
+ return true;
785
+ }
786
+ function optionsSatisfies(current, existing) {
787
+ return !current || current === existing || Object.keys(current).length === 0;
788
+ }
789
+
790
+ // this function helps resolve whether we have a pending request that we should use instead
791
+ function isSameRequest(options = {}, existingOptions = {}) {
792
+ return optionsSatisfies(options.adapterOptions, existingOptions.adapterOptions) && includesSatisfies(options.include, existingOptions.include);
793
+ }
794
+ function _findMany(store, adapter, modelName, snapshots) {
795
+ const modelClass = store.modelFor(modelName); // `adapter.findMany` gets the modelClass still
796
+ const promise = Promise.resolve().then(() => {
797
+ const ids = snapshots.map(s => s.id);
798
+ const ret = adapter.findMany(store, modelClass, ids, snapshots);
799
+ return ret;
800
+ });
801
+ return promise.then(adapterPayload => {
802
+ const serializer = store.serializerFor(modelName);
803
+ const payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findMany');
804
+ return payload;
805
+ });
806
+ }
807
+ function rejectFetchedItems(fetchMap, snapshots, error) {
808
+ for (let i = 0, l = snapshots.length; i < l; i++) {
809
+ const snapshot = snapshots[i];
810
+ const pair = fetchMap.get(snapshot);
811
+ if (pair) {
812
+ pair.resolver.reject(error || new Error(`Expected: '<${snapshot.modelName}:${snapshot.id}>' to be present in the adapter provided payload, but it was not found.`));
813
+ }
814
+ }
815
+ }
816
+ function handleFoundRecords(store, fetchMap, snapshots, coalescedPayload) {
817
+ /*
818
+ It is possible that the same ID is included multiple times
819
+ via multiple snapshots. This happens when more than one
820
+ options hash was supplied, each of which must be uniquely
821
+ accounted for.
822
+ However, since we can't map from response to a specific
823
+ options object, we resolve all snapshots by id with
824
+ the first response we see.
825
+ */
826
+ const snapshotsById = new Map();
827
+ for (let i = 0; i < snapshots.length; i++) {
828
+ const id = snapshots[i].id;
829
+ let snapshotGroup = snapshotsById.get(id);
830
+ if (!snapshotGroup) {
831
+ snapshotGroup = [];
832
+ snapshotsById.set(id, snapshotGroup);
833
+ }
834
+ snapshotGroup.push(snapshots[i]);
835
+ }
836
+ const included = Array.isArray(coalescedPayload.included) ? coalescedPayload.included : [];
837
+
838
+ // resolve found records
839
+ const resources = coalescedPayload.data;
840
+ for (let i = 0, l = resources.length; i < l; i++) {
841
+ const resource = resources[i];
842
+ const snapshotGroup = snapshotsById.get(resource.id);
843
+ snapshotsById.delete(resource.id);
844
+ if (!snapshotGroup) {
845
+ // TODO consider whether this should be a deprecation/assertion
846
+ included.push(resource);
847
+ } else {
848
+ snapshotGroup.forEach(snapshot => {
849
+ const pair = fetchMap.get(snapshot);
850
+ const resolver = pair.resolver;
851
+ resolver.resolve({
852
+ data: resource
853
+ });
854
+ });
855
+ }
856
+ }
857
+ if (included.length > 0) {
858
+ store._push({
859
+ data: null,
860
+ included
861
+ }, true);
862
+ }
863
+ if (snapshotsById.size === 0) {
864
+ return;
865
+ }
866
+
867
+ // reject missing records
868
+ const rejected = [];
869
+ snapshotsById.forEach(snapshotArray => {
870
+ rejected.push(...snapshotArray);
871
+ });
872
+ rejectFetchedItems(fetchMap, rejected);
873
+ }
874
+ function _fetchRecord(store, adapter, fetchItem) {
875
+ const identifier = fetchItem.identifier;
876
+ const modelName = identifier.type;
877
+ const snapshot = store._fetchManager.createSnapshot(identifier, fetchItem.options);
878
+ const klass = store.modelFor(identifier.type);
879
+ const id = identifier.id;
880
+ let promise = Promise.resolve().then(() => {
881
+ return adapter.findRecord(store, klass, identifier.id, snapshot);
882
+ });
883
+ promise = promise.then(adapterPayload => {
884
+ const serializer = store.serializerFor(modelName);
885
+ const payload = normalizeResponseHelper(serializer, store, klass, adapterPayload, id, 'findRecord');
886
+ return payload;
887
+ });
888
+ fetchItem.resolver.resolve(promise);
889
+ }
890
+ function _processCoalescedGroup(store, fetchMap, group, adapter, modelName) {
891
+ if (group.length > 1) {
892
+ _findMany(store, adapter, modelName, group).then(payloads => {
893
+ handleFoundRecords(store, fetchMap, group, payloads);
894
+ }).catch(error => {
895
+ rejectFetchedItems(fetchMap, group, error);
896
+ });
897
+ } else if (group.length === 1) {
898
+ _fetchRecord(store, adapter, fetchMap.get(group[0]));
899
+ } else ;
900
+ }
901
+ function _flushPendingFetchForType(store, pendingFetchMap, modelName) {
902
+ const adapter = store.adapterFor(modelName);
903
+ const shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
904
+ if (shouldCoalesce) {
905
+ const pendingFetchItems = [];
906
+ pendingFetchMap.forEach((requestsForIdentifier, identifier) => {
907
+ if (requestsForIdentifier.length > 1) {
908
+ return;
909
+ }
910
+
911
+ // remove this entry from the map so it's not processed again
912
+ pendingFetchMap.delete(identifier);
913
+ pendingFetchItems.push(requestsForIdentifier[0]);
914
+ });
915
+ const totalItems = pendingFetchItems.length;
916
+ if (totalItems > 1) {
917
+ const snapshots = new Array(totalItems);
918
+ const fetchMap = new Map();
919
+ for (let i = 0; i < totalItems; i++) {
920
+ const fetchItem = pendingFetchItems[i];
921
+ snapshots[i] = store._fetchManager.createSnapshot(fetchItem.identifier, fetchItem.options);
922
+ fetchMap.set(snapshots[i], fetchItem);
923
+ }
924
+ let groups;
925
+ if (adapter.groupRecordsForFindMany) {
926
+ groups = adapter.groupRecordsForFindMany(store, snapshots);
927
+ } else {
928
+ groups = [snapshots];
929
+ }
930
+ for (let i = 0, l = groups.length; i < l; i++) {
931
+ _processCoalescedGroup(store, fetchMap, groups[i], adapter, modelName);
932
+ }
933
+ } else if (totalItems === 1) {
934
+ _fetchRecord(store, adapter, pendingFetchItems[0]);
935
+ }
936
+ }
937
+ pendingFetchMap.forEach(pendingFetchItems => {
938
+ pendingFetchItems.forEach(pendingFetchItem => {
939
+ _fetchRecord(store, adapter, pendingFetchItem);
940
+ });
941
+ });
942
+ }
943
+ function _flushPendingSave(store, pending) {
944
+ const {
945
+ snapshot,
946
+ resolver,
947
+ identifier,
948
+ options
949
+ } = pending;
950
+ const adapter = store.adapterFor(identifier.type);
951
+ const operation = options[SaveOp];
952
+ const modelName = snapshot.modelName;
953
+ const modelClass = store.modelFor(modelName);
954
+ let promise = Promise.resolve().then(() => adapter[operation](store, modelClass, snapshot));
955
+ const serializer = store.serializerFor(modelName);
956
+ promise = promise.then(adapterPayload => {
957
+ if (adapterPayload) {
958
+ return normalizeResponseHelper(serializer, store, modelClass, adapterPayload, snapshot.id, operation);
959
+ }
960
+ });
961
+ resolver.resolve(promise);
962
+ }
963
+
964
+ /**
965
+ * Utilities - often temporary - for maintaining backwards compatibility with
966
+ * older parts of WarpDrive.
967
+ *
968
+ @module
969
+ */
970
+ function upgradeStore(store) {}
971
+ export { FetchManager as F, SaveOp as S, SnapshotRecordArray as a, Snapshot as b, normalizeResponseHelper as n, upgradeStore as u };