@ember-data/store 5.4.0-alpha.8 → 5.4.0-beta.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/addon/-private.js CHANGED
@@ -1 +1 @@
1
- export { f as AdapterPopulatedRecordArray, C as CacheHandler, h as IDENTIFIER_ARRAY_TAG, I as IdentifierArray, M as MUTATE, I as RecordArray, R as RecordArrayManager, g as SOURCE, S as Store, m as StoreMap, _ as _clearCaches, e as coerceId, j as fastPush, i as isStableIdentifier, n as notifyArray, p as peekCache, r as recordIdentifierFor, k as removeRecordDataFor, o as setCacheFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, l as setRecordIdentifier, s as storeFor } from "./store-service-fc1e0bd5";
1
+ export { f as AdapterPopulatedRecordArray, C as CacheHandler, h as IDENTIFIER_ARRAY_TAG, I as IdentifierArray, M as MUTATE, I as RecordArray, R as RecordArrayManager, g as SOURCE, S as Store, m as StoreMap, _ as _clearCaches, e as coerceId, j as fastPush, i as isStableIdentifier, n as notifyArray, p as peekCache, r as recordIdentifierFor, k as removeRecordDataFor, o as setCacheFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, l as setRecordIdentifier, s as storeFor } from "./store-service-aee9dd76";
package/addon/index.js CHANGED
@@ -1 +1 @@
1
- export { C as CacheHandler, S as default, r as recordIdentifierFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, s as storeFor } from "./store-service-fc1e0bd5";
1
+ export { C as CacheHandler, S as default, r as recordIdentifierFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, s as storeFor } from "./store-service-aee9dd76";
@@ -2,9 +2,9 @@ import { macroCondition, getOwnConfig } from '@embroider/macros';
2
2
  import { getOwner } from '@ember/application';
3
3
  import { assert, deprecate, warn } from '@ember/debug';
4
4
  import EmberObject from '@ember/object';
5
- import { _backburner } from '@ember/runloop';
6
5
  import { tracked } from '@glimmer/tracking';
7
6
  import { dasherize } from '@ember/string';
7
+ import { _backburner } from '@ember/runloop';
8
8
  import { addToTransaction, subscribe, addTransactionCB } from '@ember-data/tracking/-private';
9
9
  import { tagForProperty } from '@ember/-internals/metal';
10
10
  import { dependentKeyCompat } from '@ember/object/compat';
@@ -233,11 +233,12 @@ function maybeUpdateUiObjects(store, request, options, document, isFromCache) {
233
233
  return options.shouldHydrate ? doc : document;
234
234
  }
235
235
  }
236
+ const MUTATION_OPS = new Set(['createRecord', 'updateRecord', 'deleteRecord']);
236
237
  function calcShouldFetch(store, request, hasCachedValue, identifier) {
237
238
  const {
238
239
  cacheOptions
239
240
  } = request;
240
- return cacheOptions?.reload || !hasCachedValue || (store.lifetimes && identifier ? store.lifetimes.isHardExpired(identifier) : false);
241
+ return request.op && MUTATION_OPS.has(request.op) || cacheOptions?.reload || !hasCachedValue || (store.lifetimes && identifier ? store.lifetimes.isHardExpired(identifier) : false);
241
242
  }
242
243
  function calcShouldBackgroundFetch(store, request, willFetch, identifier) {
243
244
  const {
@@ -245,17 +246,31 @@ function calcShouldBackgroundFetch(store, request, willFetch, identifier) {
245
246
  } = request;
246
247
  return !willFetch && (cacheOptions?.backgroundReload || (store.lifetimes && identifier ? store.lifetimes.isSoftExpired(identifier) : false));
247
248
  }
249
+ function isMutation(request) {
250
+ return Boolean(request.op && MUTATION_OPS.has(request.op));
251
+ }
248
252
  function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBackgroundFetch) {
249
253
  const {
250
254
  store
251
255
  } = context.request;
252
256
  const shouldHydrate = context.request[Symbol.for('ember-data:enable-hydration')] || false;
253
- return next(context.request).then(document => {
257
+ let isMut = false;
258
+ if (isMutation(context.request)) {
259
+ isMut = true;
260
+ const record = context.request.data?.record;
261
+ assert(`Expected to receive a list of records included in the ${context.request.op} request`, record);
262
+ store.cache.willCommit(record, context);
263
+ }
264
+ const promise = next(context.request).then(document => {
254
265
  store.requestManager._pending.delete(context.id);
255
266
  store._enableAsyncFlush = true;
256
267
  let response;
257
268
  store._join(() => {
258
- response = store.cache.put(document);
269
+ if (isMutation(context.request)) {
270
+ response = store.cache.didCommit(context.request.data.record, document);
271
+ } else {
272
+ response = store.cache.put(document);
273
+ }
259
274
  response = maybeUpdateUiObjects(store, context.request, {
260
275
  shouldHydrate,
261
276
  shouldFetch,
@@ -278,13 +293,22 @@ function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBa
278
293
  store._enableAsyncFlush = true;
279
294
  let response;
280
295
  store._join(() => {
281
- response = store.cache.put(error);
282
- response = maybeUpdateUiObjects(store, context.request, {
283
- shouldHydrate,
284
- shouldFetch,
285
- shouldBackgroundFetch,
286
- identifier
287
- }, response, false);
296
+ if (isMutation(context.request)) {
297
+ // TODO similar to didCommit we should spec this to be similar to cache.put for handling full response
298
+ // currently we let the response remain undefiend.
299
+ const errors = error && error.content && typeof error.content === 'object' && 'errors' in error.content && Array.isArray(error.content.errors) ? error.content.errors : undefined;
300
+ store.cache.commitWasRejected(context.request.data.record, errors);
301
+ // re-throw the original error to preserve `errors` property.
302
+ throw error;
303
+ } else {
304
+ response = store.cache.put(error);
305
+ response = maybeUpdateUiObjects(store, context.request, {
306
+ shouldHydrate,
307
+ shouldFetch,
308
+ shouldBackgroundFetch,
309
+ identifier
310
+ }, response, false);
311
+ }
288
312
  });
289
313
  store._enableAsyncFlush = null;
290
314
  if (!shouldBackgroundFetch) {
@@ -295,6 +319,19 @@ function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBa
295
319
  store.notifications._flush();
296
320
  }
297
321
  });
322
+ if (!isMut) {
323
+ return promise;
324
+ }
325
+ assert(`Expected a mutation`, isMutation(context.request));
326
+
327
+ // for mutations we need to enqueue the promise with the requestStateService
328
+ return store._requestCache._enqueue(promise, {
329
+ data: [{
330
+ op: 'saveRecord',
331
+ recordIdentifier: context.request.data.record,
332
+ options: undefined
333
+ }]
334
+ });
298
335
  }
299
336
  function cloneError(error) {
300
337
  const cloned = new Error(error.message);
@@ -2879,7 +2916,7 @@ let IdentifierArray = (_class3 = class IdentifierArray {
2879
2916
  });
2880
2917
  if (macroCondition(getOwnConfig().env.DEBUG)) {
2881
2918
  const meta = Ember.meta(this);
2882
- meta.hasMixin = mixin => {
2919
+ meta.addMixin = mixin => {
2883
2920
  assert(`Do not call A() on EmberData RecordArrays`);
2884
2921
  };
2885
2922
  }
@@ -4108,43 +4145,41 @@ class Store extends EmberObject {
4108
4145
  //
4109
4146
  // to remove this, we would need to move to a new `async` API.
4110
4147
  let record;
4111
- _backburner.join(() => {
4112
- this._join(() => {
4113
- let normalizedModelName = normalizeModelName(modelName);
4114
- let properties = {
4115
- ...inputProperties
4116
- };
4148
+ this._join(() => {
4149
+ let normalizedModelName = normalizeModelName(modelName);
4150
+ let properties = {
4151
+ ...inputProperties
4152
+ };
4117
4153
 
4118
- // If the passed properties do not include a primary key,
4119
- // give the adapter an opportunity to generate one. Typically,
4120
- // client-side ID generators will use something like uuid.js
4121
- // to avoid conflicts.
4154
+ // If the passed properties do not include a primary key,
4155
+ // give the adapter an opportunity to generate one. Typically,
4156
+ // client-side ID generators will use something like uuid.js
4157
+ // to avoid conflicts.
4122
4158
 
4123
- if (properties.id === null || properties.id === undefined) {
4124
- let adapter = this.adapterFor(modelName, true);
4125
- if (adapter && adapter.generateIdForRecord) {
4126
- properties.id = adapter.generateIdForRecord(this, modelName, properties);
4127
- } else {
4128
- properties.id = null;
4129
- }
4159
+ if (properties.id === null || properties.id === undefined) {
4160
+ let adapter = this.adapterFor(modelName, true);
4161
+ if (adapter && adapter.generateIdForRecord) {
4162
+ properties.id = adapter.generateIdForRecord(this, modelName, properties);
4163
+ } else {
4164
+ properties.id = null;
4130
4165
  }
4166
+ }
4131
4167
 
4132
- // Coerce ID to a string
4133
- properties.id = coerceId(properties.id);
4134
- const resource = {
4135
- type: normalizedModelName,
4136
- id: properties.id
4137
- };
4138
- if (resource.id) {
4139
- const identifier = this.identifierCache.peekRecordIdentifier(resource);
4140
- assert(`The id ${String(properties.id)} has already been used with another '${normalizedModelName}' record.`, !identifier);
4141
- }
4142
- const identifier = this.identifierCache.createIdentifierForNewRecord(resource);
4143
- const cache = this.cache;
4144
- const createOptions = normalizeProperties(this, identifier, properties);
4145
- const resultProps = cache.clientDidCreate(identifier, createOptions);
4146
- record = this._instanceCache.getRecord(identifier, resultProps);
4147
- });
4168
+ // Coerce ID to a string
4169
+ properties.id = coerceId(properties.id);
4170
+ const resource = {
4171
+ type: normalizedModelName,
4172
+ id: properties.id
4173
+ };
4174
+ if (resource.id) {
4175
+ const identifier = this.identifierCache.peekRecordIdentifier(resource);
4176
+ assert(`The id ${String(properties.id)} has already been used with another '${normalizedModelName}' record.`, !identifier);
4177
+ }
4178
+ const identifier = this.identifierCache.createIdentifierForNewRecord(resource);
4179
+ const cache = this.cache;
4180
+ const createOptions = normalizeProperties(this, identifier, properties);
4181
+ const resultProps = cache.clientDidCreate(identifier, createOptions);
4182
+ record = this._instanceCache.getRecord(identifier, resultProps);
4148
4183
  });
4149
4184
  return record;
4150
4185
  }
@@ -4172,9 +4207,7 @@ class Store extends EmberObject {
4172
4207
  this._join(() => {
4173
4208
  cache.setIsDeleted(identifier, true);
4174
4209
  if (cache.isNew(identifier)) {
4175
- _backburner.join(() => {
4176
- this._instanceCache.unloadRecord(identifier);
4177
- });
4210
+ this._instanceCache.unloadRecord(identifier);
4178
4211
  }
4179
4212
  });
4180
4213
  }