@warp-drive/core 5.7.0-alpha.11 → 5.7.0-alpha.12

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.
@@ -15,7 +15,7 @@ export declare function getStore(wrapper: CacheCapabilitiesManager | {
15
15
  export declare function expandingGet<T>(cache: Record<string, Record<string, T>>, key1: string, key2: string): T | undefined;
16
16
  export declare function expandingSet<T>(cache: Record<string, Record<string, T>>, key1: string, key2: string, value: T): void;
17
17
  export declare function assertValidRelationshipPayload(graph: Graph, op: UpdateRelationshipOperation | UpdateResourceRelationshipOperation): void;
18
- export declare function isNew(identifier: StableRecordIdentifier): boolean;
18
+ export declare function checkIfNew(store: Store, identifier: StableRecordIdentifier): boolean;
19
19
  export declare function isBelongsTo(relationship: GraphEdge): relationship is ResourceEdge;
20
20
  export declare function isImplicit(relationship: GraphEdge): relationship is ImplicitEdge;
21
21
  export declare function isHasMany(relationship: GraphEdge): relationship is CollectionEdge;
@@ -1,3 +1,4 @@
1
+ import type { Store } from "../../store/-private.js";
1
2
  import type { CacheCapabilitiesManager, StableRecordIdentifier } from "../../types.js";
2
3
  import type { RelationshipDiff } from "../../types/cache.js";
3
4
  import type { MergeOperation } from "../../types/cache/operations.js";
@@ -39,6 +40,7 @@ export declare class Graph {
39
40
  _potentialPolymorphicTypes: Record<string, Record<string, boolean>>;
40
41
  identifiers: Map<StableRecordIdentifier, Record<string, GraphEdge>>;
41
42
  store: CacheCapabilitiesManager;
43
+ _realStore: Store;
42
44
  isDestroyed: boolean;
43
45
  _willSyncRemote: boolean;
44
46
  _willSyncLocal: boolean;
@@ -47,3 +47,4 @@ export interface ReactiveResource {
47
47
  export declare class ReactiveResource {
48
48
  constructor(context: ResourceContext | ObjectContext);
49
49
  }
50
+ export declare function _CHECKOUT(record: ReactiveResource): ReactiveResource;
@@ -263,6 +263,7 @@ export declare class IdentifierCache {
263
263
  createIdentifierForNewRecord(data: {
264
264
  type: string;
265
265
  id?: string | null;
266
+ lid?: string;
266
267
  }): StableRecordIdentifier;
267
268
  /**
268
269
  Provides the opportunity to update secondary lookup tables for existing identifiers
@@ -28,12 +28,13 @@ const { id, type, lid } = identifier;
28
28
  export declare function recordIdentifierFor<T extends TypedRecordInstance>(record: T): StableRecordIdentifier<TypeFromInstance<T>>;
29
29
  export declare function recordIdentifierFor(record: OpaqueRecordInstance): StableRecordIdentifier;
30
30
  export declare function setRecordIdentifier(record: OpaqueRecordInstance, identifier: StableRecordIdentifier): void;
31
+ export declare function removeRecordIdentifier(record: OpaqueRecordInstance): void;
31
32
  export declare const StoreMap: Map<unknown, Store>;
32
33
  /**
33
34
  * We may eventually make this public, but its likely better for this to be killed off
34
35
  * @internal
35
36
  */
36
- export declare function storeFor(record: OpaqueRecordInstance): Store | undefined;
37
+ export declare function storeFor(record: OpaqueRecordInstance, ignoreMissing: boolean): Store | null;
37
38
  export type Caches = {
38
39
  record: Map<StableRecordIdentifier, OpaqueRecordInstance>;
39
40
  document: Map<StableDocumentIdentifier, ReactiveDocument<OpaqueRecordInstance | OpaqueRecordInstance[] | null | undefined>>;
@@ -47,7 +48,7 @@ export declare class InstanceCache {
47
48
  constructor(store: Store);
48
49
  peek(identifier: StableRecordIdentifier): Cache | OpaqueRecordInstance | undefined;
49
50
  getDocument<T>(identifier: StableDocumentIdentifier): ReactiveDocument<T>;
50
- getRecord(identifier: StableRecordIdentifier, properties?: CreateRecordProperties): OpaqueRecordInstance;
51
+ getRecord(identifier: StableRecordIdentifier): OpaqueRecordInstance;
51
52
  recordIsLoaded(identifier: StableRecordIdentifier, filterDeleted?: boolean): boolean;
52
53
  disconnect(identifier: StableRecordIdentifier): void;
53
54
  unloadRecord(identifier: StableRecordIdentifier): void;
@@ -55,4 +56,5 @@ export declare class InstanceCache {
55
56
  // TODO this should move into something coordinating operations
56
57
  setRecordId(identifier: StableRecordIdentifier, id: string): void;
57
58
  }
59
+ export declare function getNewRecord(instances: InstanceCache, identifier: StableRecordIdentifier, properties: CreateRecordProperties): OpaqueRecordInstance;
58
60
  export declare function _clearCaches(): void;
@@ -45,6 +45,9 @@ type MaybeHasId = {
45
45
  *
46
46
  */
47
47
  export type CreateRecordProperties<T = MaybeHasId & Record<string, unknown>> = T extends TypedRecordInstance ? Partial<FilteredKeys<T>> : T extends MaybeHasId ? MaybeHasId & Partial<FilteredKeys<T>> : MaybeHasId & Record<string, unknown>;
48
+ export interface CreateContext {
49
+ lid?: string;
50
+ }
48
51
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
52
  type ConstructorFunction = new (...args: any[]) => any;
50
53
  // eslint-disable-next-line @typescript-eslint/no-extraneous-class
@@ -508,35 +511,75 @@ export declare class Store extends BaseClass {
508
511
  T = unknown
509
512
  >(requestConfig: StoreRequestInput<RT, T>): Future<RT>;
510
513
  /**
511
- Create a new record in the current store. The properties passed
512
- to this method are set on the newly created record.
514
+ Creates a new record in the current store.
515
+
516
+ > [!CAUTION]
517
+ > This should not be used to mock records or to create
518
+ > a record representing data that could be fetched from
519
+ > the API.
513
520
 
514
- To create a new instance of a `Post`:
521
+ The properties passed to this method are set on
522
+ the newly created record.
523
+
524
+ For instance: to create a new `post`:
515
525
 
516
526
  ```js
517
527
  store.createRecord('post', {
518
- title: 'Ember is awesome!'
528
+ title: 'WarpDrive is Stellar!'
519
529
  });
520
530
  ```
521
531
 
522
- To create a new instance of a `Post` that has a relationship with a `User` record:
532
+ Relationships can be set during create. For instance,
533
+ to create a new `post` that has an existing user as
534
+ it's author:
523
535
 
524
536
  ```js
525
- let user = this.store.peekRecord('user', '1');
537
+ const user = store.peekRecord('user', '1');
538
+
526
539
  store.createRecord('post', {
527
- title: 'Ember is awesome!',
540
+ title: 'WarpDrive is Stellar!',
528
541
  user: user
529
542
  });
530
543
  ```
531
544
 
545
+ ### lid handling
546
+
547
+ All new records are assigned an `lid` that can be used to handle
548
+ transactional saves of multiple records, or to link the data to
549
+ other data in scenarios involving eventual-consistency or remote
550
+ syncing.
551
+
552
+ ```ts
553
+ const post = store.createRecord('post', {
554
+ title: 'WarpDrive is Stellar!'
555
+ });
556
+ const { lid } = recordIdentifierFor(post);
557
+ ```
558
+
559
+ The `lid` defaults to a uuidv4 string.
560
+
561
+ In order to support receiving knowledge about unpersisted creates
562
+ from other sources (say a different tab in the same web-browser),
563
+ createRecord allows for the `lid` to be provided as part of an
564
+ optional third argument. **If this lid already exists in the store
565
+ an error will be thrown.**
566
+
567
+ ```ts
568
+ const post = store.createRecord(
569
+ 'post',
570
+ { title: 'WarpDrive is Stellar!' },
571
+ { lid: '4d47bb88-931f-496e-986d-c4888cef7373' }
572
+ );
573
+ ```
574
+
532
575
  @public
533
- @param {String} type the name of the resource
534
- @param {Object} inputProperties a hash of properties to set on the
576
+ @param type the name of the resource
577
+ @param inputProperties a hash of properties to set on the
535
578
  newly created record.
536
- @return {Model} record
579
+ @return a record in the "isNew" state
537
580
  */
538
- createRecord<T>(type: TypeFromInstance<T>, inputProperties: CreateRecordProperties<T>): T;
539
- createRecord(type: string, inputProperties: CreateRecordProperties): OpaqueRecordInstance;
581
+ createRecord<T>(type: TypeFromInstance<T>, inputProperties: CreateRecordProperties<T>, context?: CreateContext): T;
582
+ createRecord(type: string, inputProperties: CreateRecordProperties, context?: CreateContext): OpaqueRecordInstance;
540
583
  /**
541
584
  For symmetry, a record can be deleted via the store.
542
585
 
@@ -16,10 +16,8 @@ export { IdentifierArray as LiveArray, Collection as CollectionRecordArray, SOUR
16
16
  export { RecordArrayManager, fastPush } from "./-private/managers/record-array-manager.js";
17
17
  // leaked for private use / test use, should investigate removing
18
18
  export { _clearCaches } from "./-private/caches/instance-cache.js";
19
- export { peekCache, removeRecordDataFor } from "./-private/caches/cache-utils.js";
20
19
  // @ember-data/model needs these temporarily
21
20
  export { setRecordIdentifier, StoreMap } from "./-private/caches/instance-cache.js";
22
- export { setCacheFor } from "./-private/caches/cache-utils.js";
23
21
  export { normalizeModelName as _deprecatingNormalize } from "./-private/utils/normalize-model-name.js";
24
22
  export type { StoreRequestInput } from "./-private/cache-handler/handler.js";
25
23
  export { RelatedCollection } from "./-private/record-arrays/many-array.js";
@@ -1,7 +1,7 @@
1
1
  type UniversalTransientKey = "REQ_ID";
2
2
  type UniversalKey = `(transient) ${UniversalTransientKey}` | "RequestMap" | "PromiseCache" | "RequestCache" | "SkipCache" | "EnableHydration" | "WarpDriveRuntimeConfig";
3
3
  type TransientKey = "transactionRef" | "configuredGenerationMethod" | "configuredUpdateMethod" | "configuredForgetMethod" | "configuredResetMethod" | "configuredKeyInfoMethod" | "signalHooks";
4
- type GlobalKey = `(transient) ${TransientKey}` | "AdapterError" | "InvalidError" | "TimeoutError" | "AbortError" | "UnauthorizedError" | "ForbiddenError" | "NotFoundError" | "ConflictError" | "ServerError" | "#{}" | "#[]" | "Signals" | "AvailableShims" | "FAKE_ARR" | "#source" | "#update" | "#notify" | "IS_COLLECTION" | "Touching" | "RequestPromise" | "SaveOp" | "LEGACY_SUPPORT" | "LegacySupport" | "Graphs" | "IS_FROZEN" | "IS_CACHE_HANDLER" | "CONFIG" | "DEBUG_MAP" | "IDENTIFIERS" | "DOCUMENTS" | "CacheForIdentifierCache" | "RecordCache" | "StoreMap" | "Store" | "$type" | "TransformName" | "RequestSignature" | "IS_FUTURE" | "DOC" | "ManagedArrayMap" | "ManagedObjectMap" | "Support" | "SOURCE" | "MUTATE" | "Destroy" | "Checkout" | "Context";
4
+ type GlobalKey = `(transient) ${TransientKey}` | "AdapterError" | "InvalidError" | "TimeoutError" | "AbortError" | "UnauthorizedError" | "ForbiddenError" | "NotFoundError" | "ConflictError" | "ServerError" | "#{}" | "#[]" | "Signals" | "AvailableShims" | "FAKE_ARR" | "#source" | "#update" | "#notify" | "IS_COLLECTION" | "Touching" | "RequestPromise" | "SaveOp" | "LEGACY_SUPPORT" | "LegacySupport" | "Graphs" | "IS_FROZEN" | "IS_CACHE_HANDLER" | "CONFIG" | "DEBUG_MAP" | "IDENTIFIERS" | "DOCUMENTS" | "RecordCache" | "StoreMap" | "Store" | "$type" | "TransformName" | "RequestSignature" | "IS_FUTURE" | "DOC" | "ManagedArrayMap" | "ManagedObjectMap" | "Support" | "SOURCE" | "MUTATE" | "Destroy" | "Checkout" | "Context";
5
5
  type UniqueSymbol<T extends string> = `___(unique) Symbol(${T})`;
6
6
  type UniqueSymbolOr<
7
7
  T,
@@ -1,9 +1,5 @@
1
1
  import { deprecate, warn } from '@ember/debug';
2
- import { p as peekCache } from "../request-state-CeN66aML.js";
3
- import '../types/request.js';
4
2
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
5
- import '../utils/string.js';
6
- import "../configure-B48bFHOl.js";
7
3
  import { getOrSetGlobal, peekTransient, setTransient } from '../types/-private.js';
8
4
  function coerceId(id) {
9
5
  if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_NON_STRICT_ID)) {
@@ -121,12 +117,11 @@ function inspect(value) {
121
117
  }
122
118
  return 'object';
123
119
  }
124
- function isNew(identifier) {
120
+ function checkIfNew(store, identifier) {
125
121
  if (!identifier.id) {
126
122
  return true;
127
123
  }
128
- const cache = peekCache(identifier);
129
- return Boolean(cache?.isNew(identifier));
124
+ return store.cache.isNew(identifier);
130
125
  }
131
126
  function isBelongsTo(relationship) {
132
127
  return relationship.definition.kind === 'belongsTo';
@@ -1210,7 +1205,7 @@ function replaceRelatedRecordsRemote(graph, op, isRemote) {
1210
1205
  // we were not "committed" which means we are not present
1211
1206
  // in the remoteMembers. So we "remove" from the inverse.
1212
1207
  // however we only do this if we are not a "new" record.
1213
- if (!isNew(identifier)) {
1208
+ if (!checkIfNew(graph._realStore, identifier)) {
1214
1209
  deprecationInfo.triggered = true;
1215
1210
  deprecationInfo.additions.push(identifier);
1216
1211
  relationship.isDirty = true;
@@ -1418,7 +1413,7 @@ function replaceRelatedRecord(graph, op, isRemote = false) {
1418
1413
  localState
1419
1414
  } = relationship;
1420
1415
  // don't sync if localState is a new record and our remoteState is null
1421
- if (localState && isNew(localState) && !existingState) {
1416
+ if (localState && checkIfNew(graph._realStore, localState) && !existingState) {
1422
1417
  return;
1423
1418
  }
1424
1419
  if (existingState && localState === existingState) {
@@ -1479,7 +1474,7 @@ function replaceRelatedRecord(graph, op, isRemote = false) {
1479
1474
  localState,
1480
1475
  remoteState
1481
1476
  } = relationship;
1482
- if (localState && isNew(localState) && !remoteState) {
1477
+ if (localState && checkIfNew(graph._realStore, localState) && !remoteState) {
1483
1478
  return;
1484
1479
  }
1485
1480
  // when localState does not match the new remoteState and
@@ -2616,6 +2611,7 @@ class Graph {
2616
2611
  this._potentialPolymorphicTypes = Object.create(null);
2617
2612
  this.identifiers = new Map();
2618
2613
  this.store = store;
2614
+ this._realStore = store._store;
2619
2615
  this.isDestroyed = false;
2620
2616
  this._willSyncRemote = false;
2621
2617
  this._willSyncLocal = false;
@@ -2761,7 +2757,7 @@ class Graph {
2761
2757
  throw new Error(`Expected a relationship`);
2762
2758
  }
2763
2759
  })(relationship) : {};
2764
- if (relationship.definition.inverseIsAsync && !isNew(identifier)) {
2760
+ if (relationship.definition.inverseIsAsync && !checkIfNew(this._realStore, identifier)) {
2765
2761
  if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2766
2762
  if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2767
2763
  // eslint-disable-next-line no-console
@@ -3214,7 +3210,7 @@ function clearRelationship(relationship) {
3214
3210
  function removeDematerializedInverse(graph, relationship, inverseIdentifier, silenceNotifications) {
3215
3211
  if (isBelongsTo(relationship)) {
3216
3212
  const localInverse = relationship.localState;
3217
- if (!relationship.definition.isAsync || localInverse && isNew(localInverse)) {
3213
+ if (!relationship.definition.isAsync || localInverse && checkIfNew(graph._realStore, localInverse)) {
3218
3214
  // unloading inverse of a sync relationship is treated as a client-side
3219
3215
  // delete, so actually remove the models don't merely invalidate the cp
3220
3216
  // cache.
@@ -3227,7 +3223,7 @@ function removeDematerializedInverse(graph, relationship, inverseIdentifier, sil
3227
3223
  relationship.remoteState = null;
3228
3224
  relationship.state.hasReceivedData = true;
3229
3225
  relationship.state.isEmpty = true;
3230
- if (relationship.localState && !isNew(relationship.localState)) {
3226
+ if (relationship.localState && !checkIfNew(graph._realStore, relationship.localState)) {
3231
3227
  relationship.localState = null;
3232
3228
  }
3233
3229
  }
@@ -3238,7 +3234,7 @@ function removeDematerializedInverse(graph, relationship, inverseIdentifier, sil
3238
3234
  notifyChange(graph, relationship);
3239
3235
  }
3240
3236
  } else {
3241
- if (!relationship.definition.isAsync || inverseIdentifier && isNew(inverseIdentifier)) {
3237
+ if (!relationship.definition.isAsync || inverseIdentifier && checkIfNew(graph._realStore, inverseIdentifier)) {
3242
3238
  // unloading inverse of a sync relationship is treated as a client-side
3243
3239
  // delete, so actually remove the models don't merely invalidate the cp
3244
3240
  // cache.
package/dist/index.js CHANGED
@@ -3,8 +3,7 @@ import { a as cloneResponseProperties, I as IS_CACHE_HANDLER, b as assertValidRe
3
3
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
4
4
  import { w as waitFor } from "./configure-B48bFHOl.js";
5
5
  import { peekUniversalTransient, setUniversalTransient } from './types/-private.js';
6
- export { S as Store, r as recordIdentifierFor, O as setIdentifierForgetMethod, L as setIdentifierGenerationMethod, P as setIdentifierResetMethod, N as setIdentifierUpdateMethod, Q as setKeyInfoForResource, s as storeFor } from "./request-state-CeN66aML.js";
7
- export { C as CacheHandler } from "./handler-SdXlte1w.js";
6
+ export { C as CacheHandler, S as Store, r as recordIdentifierFor, O as setIdentifierForgetMethod, L as setIdentifierGenerationMethod, P as setIdentifierResetMethod, N as setIdentifierUpdateMethod, Q as setKeyInfoForResource, s as storeFor } from "./request-state-BWYju5O9.js";
8
7
  import '@ember/debug';
9
8
  import './utils/string.js';
10
9