@warp-drive-mirror/schema-record 4.13.0-alpha.3 → 4.13.0-alpha.5

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 (54) hide show
  1. package/LICENSE.md +19 -8
  2. package/README.md +211 -123
  3. package/dist/-private.js +1 -0
  4. package/dist/-private.js.map +1 -0
  5. package/dist/{record.js → index.js} +531 -68
  6. package/dist/index.js.map +1 -0
  7. package/dist/symbols-DqoS4ybV.js.map +1 -1
  8. package/logos/NCC-1701-a-gold.svg +4 -0
  9. package/logos/NCC-1701-a-gold_100.svg +1 -0
  10. package/logos/NCC-1701-a-gold_base-64.txt +1 -0
  11. package/logos/README.md +4 -0
  12. package/logos/docs-badge.svg +2 -0
  13. package/logos/ember-data-logo-dark.svg +12 -0
  14. package/logos/ember-data-logo-light.svg +12 -0
  15. package/logos/github-header.svg +444 -0
  16. package/logos/social1.png +0 -0
  17. package/logos/social2.png +0 -0
  18. package/logos/warp-drive-logo-dark.svg +4 -0
  19. package/logos/warp-drive-logo-gold.svg +4 -0
  20. package/package.json +38 -55
  21. package/unstable-preview-types/-private/{compute.d.ts → fields/compute.d.ts} +17 -15
  22. package/unstable-preview-types/-private/fields/compute.d.ts.map +1 -0
  23. package/unstable-preview-types/-private/{managed-array.d.ts → fields/managed-array.d.ts} +4 -4
  24. package/unstable-preview-types/-private/fields/managed-array.d.ts.map +1 -0
  25. package/unstable-preview-types/-private/{managed-object.d.ts → fields/managed-object.d.ts} +4 -4
  26. package/unstable-preview-types/-private/fields/managed-object.d.ts.map +1 -0
  27. package/unstable-preview-types/-private/fields/many-array-manager.d.ts +23 -0
  28. package/unstable-preview-types/-private/fields/many-array-manager.d.ts.map +1 -0
  29. package/unstable-preview-types/{hooks.d.ts → -private/hooks.d.ts} +3 -3
  30. package/unstable-preview-types/-private/hooks.d.ts.map +1 -0
  31. package/unstable-preview-types/{record.d.ts → -private/record.d.ts} +3 -3
  32. package/unstable-preview-types/-private/record.d.ts.map +1 -0
  33. package/unstable-preview-types/{schema.d.ts → -private/schema.d.ts} +2 -2
  34. package/unstable-preview-types/-private/schema.d.ts.map +1 -0
  35. package/unstable-preview-types/{symbols.d.ts → -private/symbols.d.ts} +1 -1
  36. package/unstable-preview-types/-private/symbols.d.ts.map +1 -0
  37. package/unstable-preview-types/-private.d.ts +4 -0
  38. package/unstable-preview-types/-private.d.ts.map +1 -0
  39. package/unstable-preview-types/index.d.ts +16 -7
  40. package/unstable-preview-types/index.d.ts.map +1 -0
  41. package/dist/hooks.js +0 -19
  42. package/dist/hooks.js.map +0 -1
  43. package/dist/record.js.map +0 -1
  44. package/dist/schema.js +0 -278
  45. package/dist/schema.js.map +0 -1
  46. package/unstable-preview-types/-private/compute.d.ts.map +0 -1
  47. package/unstable-preview-types/-private/managed-array.d.ts.map +0 -1
  48. package/unstable-preview-types/-private/managed-object.d.ts.map +0 -1
  49. package/unstable-preview-types/hooks.d.ts.map +0 -1
  50. package/unstable-preview-types/record.d.ts.map +0 -1
  51. package/unstable-preview-types/schema.d.ts.map +0 -1
  52. package/unstable-preview-types/symbols.d.ts.map +0 -1
  53. /package/{NCC-1701-a-blue.svg → logos/NCC-1701-a-blue.svg} +0 -0
  54. /package/{NCC-1701-a.svg → logos/NCC-1701-a.svg} +0 -0
@@ -1,10 +1,13 @@
1
1
  import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
2
- import { setRecordIdentifier, recordIdentifierFor } from '@ember-data-mirror/store/-private';
3
- import { createSignal, subscribe, defineSignal, peekSignal, getSignal, Signals, entangleSignal, addToTransaction } from '@ember-data-mirror/tracking/-private';
4
- import { STRUCTURED } from '@warp-drive-mirror/core-types/request';
5
- import { RecordStore } from '@warp-drive-mirror/core-types/symbols';
2
+ import { SOURCE as SOURCE$1, fastPush, RelatedCollection, setRecordIdentifier, recordIdentifierFor } from '@ember-data-mirror/store/-private';
3
+ import { createSignal, subscribe, defineSignal, peekSignal, getSignal, Signals, addToTransaction, entangleSignal } from '@ember-data-mirror/tracking/-private';
4
+ import { EnableHydration, STRUCTURED } from '@warp-drive-mirror/core-types/request';
5
+ import { RecordStore, Type } from '@warp-drive-mirror/core-types/symbols';
6
6
  import { getOrSetGlobal } from '@warp-drive-mirror/core-types/-private';
7
7
  import { S as SOURCE, A as ARRAY_SIGNAL, E as Editable, L as Legacy, I as Identifier, P as Parent, O as OBJECT_SIGNAL, a as EmbeddedPath, D as Destroy, C as Checkout, b as EmbeddedType } from "./symbols-DqoS4ybV.js";
8
+ import { deprecate } from '@ember/debug';
9
+ import { recordIdentifierFor as recordIdentifierFor$1 } from '@ember-data-mirror/store';
10
+ import { createCache, getValue } from '@ember-data-mirror/tracking';
8
11
  const ARRAY_GETTER_METHODS = new Set([Symbol.iterator, 'concat', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flat', 'flatMap', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'slice', 'some', 'values']);
9
12
  // const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
10
13
  const SYNC_PROPS = new Set(['[]', 'length']);
@@ -32,7 +35,7 @@ function safeForEach(instance, arr, store, callback, target) {
32
35
  }
33
36
  // clone to prevent mutation
34
37
  arr = arr.slice();
35
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
38
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
36
39
  if (!test) {
37
40
  throw new Error('`forEach` expects a function as first argument.');
38
41
  }
@@ -112,7 +115,7 @@ class ManagedArray {
112
115
  // the given field does not exist OR
113
116
  // the field is anything other than a GenericField or LegacyAttributeField.
114
117
  if (mode !== '@identity' && mode !== '@index') {
115
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
118
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
116
119
  if (!test) {
117
120
  throw new Error('mode must be a string');
118
121
  }
@@ -120,12 +123,12 @@ class ManagedArray {
120
123
  const modeField = schema.resource({
121
124
  type: field.type
122
125
  }).fields.find(f => f.name === mode);
123
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
126
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
124
127
  if (!test) {
125
128
  throw new Error('field must exist in schema');
126
129
  }
127
130
  })(modeField) : {};
128
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
131
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
129
132
  if (!test) {
130
133
  throw new Error('field must be a GenericField or LegacyAttributeField');
131
134
  }
@@ -257,6 +260,12 @@ class ManagedArray {
257
260
  _SIGNAL.shouldReset = true;
258
261
  }
259
262
  return reflect;
263
+ },
264
+ has(target, prop) {
265
+ if (prop === 'identifier' || prop === 'owner' || prop === ARRAY_SIGNAL) {
266
+ return true;
267
+ }
268
+ return Reflect.has(target, prop);
260
269
  }
261
270
  });
262
271
  return proxy;
@@ -337,7 +346,7 @@ class ManagedObject {
337
346
  return Reflect.get(target, prop, receiver);
338
347
  },
339
348
  set(target, prop, value, receiver) {
340
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
349
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
341
350
  if (!test) {
342
351
  throw new Error(`Cannot set read-only property '${String(prop)}' on ManagedObject`);
343
352
  }
@@ -360,6 +369,75 @@ class ManagedObject {
360
369
  return proxy;
361
370
  }
362
371
  }
372
+ class ManyArrayManager {
373
+ constructor(record) {
374
+ this.record = record;
375
+ this.store = record[RecordStore];
376
+ this.identifier = record[Identifier];
377
+ }
378
+ _syncArray(array) {
379
+ const rawValue = this.store.cache.getRelationship(this.identifier, array.key);
380
+ if (rawValue.meta) {
381
+ array.meta = rawValue.meta;
382
+ }
383
+ if (rawValue.links) {
384
+ array.links = rawValue.links;
385
+ }
386
+ const currentState = array[SOURCE$1];
387
+ currentState.length = 0;
388
+ fastPush(currentState, rawValue.data);
389
+ }
390
+ reloadHasMany(key, options) {
391
+ const field = this.store.schema.fields(this.identifier).get(key);
392
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
393
+ if (!test) {
394
+ throw new Error(`Expected a hasMany field for ${key}`);
395
+ }
396
+ })(field?.kind === 'hasMany') : {};
397
+ const cacheOptions = options ? extractCacheOptions(options) : {
398
+ reload: true
399
+ };
400
+ cacheOptions.types = [field.type];
401
+ const rawValue = this.store.cache.getRelationship(this.identifier, key);
402
+ const req = {
403
+ url: getRelatedLink(rawValue),
404
+ op: 'findHasMany',
405
+ method: 'GET',
406
+ records: rawValue.data,
407
+ cacheOptions,
408
+ options: {
409
+ field,
410
+ identifier: this.identifier,
411
+ links: rawValue.links,
412
+ meta: rawValue.meta
413
+ },
414
+ [EnableHydration]: false
415
+ };
416
+ return this.store.request(req);
417
+ }
418
+ mutate(mutation) {
419
+ this.cache.mutate(mutation);
420
+ }
421
+ }
422
+ function getRelatedLink(resource) {
423
+ const related = resource.links?.related;
424
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
425
+ if (!test) {
426
+ throw new Error(`Expected a related link`);
427
+ }
428
+ })(related) : {};
429
+ return typeof related === 'object' ? related.href : related;
430
+ }
431
+ function extractCacheOptions(options) {
432
+ const cacheOptions = {};
433
+ if ('reload' in options) {
434
+ cacheOptions.reload = options.reload;
435
+ }
436
+ if ('backgroundReload' in options) {
437
+ cacheOptions.backgroundReload = options.backgroundReload;
438
+ }
439
+ return cacheOptions;
440
+ }
363
441
  const ManagedArrayMap = getOrSetGlobal('ManagedArrayMap', new Map());
364
442
  const ManagedObjectMap = getOrSetGlobal('ManagedObjectMap', new Map());
365
443
  function computeLocal(record, field, prop) {
@@ -373,24 +451,25 @@ function computeLocal(record, field, prop) {
373
451
  function peekManagedArray(record, field) {
374
452
  const managedArrayMapForRecord = ManagedArrayMap.get(record);
375
453
  if (managedArrayMapForRecord) {
376
- return managedArrayMapForRecord.get(field);
454
+ return managedArrayMapForRecord.get(field.name);
377
455
  }
378
456
  }
379
457
  function peekManagedObject(record, field) {
380
458
  const managedObjectMapForRecord = ManagedObjectMap.get(record);
381
459
  if (managedObjectMapForRecord) {
382
- return managedObjectMapForRecord.get(field);
460
+ return managedObjectMapForRecord.get(field.name);
383
461
  }
384
462
  }
385
- function computeField(schema, cache, record, identifier, field, prop) {
386
- const rawValue = cache.getAttr(identifier, prop);
463
+ function computeField(schema, cache, record, identifier, field, prop, editable) {
464
+ const rawValue = editable ? cache.getAttr(identifier, prop) : cache.getRemoteAttr(identifier, prop);
387
465
  if (!field.type) {
388
466
  return rawValue;
389
467
  }
390
468
  const transform = schema.transformation(field);
391
469
  return transform.hydrate(rawValue, field.options ?? null, record);
392
470
  }
393
- function computeArray(store, schema, cache, record, identifier, field, path, isSchemaArray, editable, legacy) {
471
+ function computeArray(store, schema, cache, record, identifier, field, path, editable, legacy) {
472
+ const isSchemaArray = field.kind === 'schema-array';
394
473
  // the thing we hand out needs to know its owner and path in a private manner
395
474
  // its "address" is the parent identifier (identifier) + field name (field.name)
396
475
  // in the nested object case field name here is the full dot path from root resource to this value
@@ -400,20 +479,20 @@ function computeArray(store, schema, cache, record, identifier, field, path, isS
400
479
  const managedArrayMapForRecord = ManagedArrayMap.get(record);
401
480
  let managedArray;
402
481
  if (managedArrayMapForRecord) {
403
- managedArray = managedArrayMapForRecord.get(field);
482
+ managedArray = managedArrayMapForRecord.get(field.name);
404
483
  }
405
484
  if (managedArray) {
406
485
  return managedArray;
407
486
  } else {
408
- const rawValue = cache.getAttr(identifier, path);
487
+ const rawValue = editable ? cache.getAttr(identifier, path) : cache.getRemoteAttr(identifier, path);
409
488
  if (!rawValue) {
410
489
  return null;
411
490
  }
412
491
  managedArray = new ManagedArray(store, schema, cache, field, rawValue, identifier, path, record, isSchemaArray, editable, legacy);
413
492
  if (!managedArrayMapForRecord) {
414
- ManagedArrayMap.set(record, new Map([[field, managedArray]]));
493
+ ManagedArrayMap.set(record, new Map([[field.name, managedArray]]));
415
494
  } else {
416
- managedArrayMapForRecord.set(field, managedArray);
495
+ managedArrayMapForRecord.set(field.name, managedArray);
417
496
  }
418
497
  }
419
498
  return managedArray;
@@ -422,12 +501,12 @@ function computeObject(schema, cache, record, identifier, field, path, editable,
422
501
  const managedObjectMapForRecord = ManagedObjectMap.get(record);
423
502
  let managedObject;
424
503
  if (managedObjectMapForRecord) {
425
- managedObject = managedObjectMapForRecord.get(field);
504
+ managedObject = managedObjectMapForRecord.get(field.name);
426
505
  }
427
506
  if (managedObject) {
428
507
  return managedObject;
429
508
  } else {
430
- let rawValue = cache.getAttr(identifier, path);
509
+ let rawValue = editable ? cache.getAttr(identifier, path) : cache.getRemoteAttr(identifier, path);
431
510
  if (!rawValue) {
432
511
  return null;
433
512
  }
@@ -437,9 +516,9 @@ function computeObject(schema, cache, record, identifier, field, path, editable,
437
516
  }
438
517
  managedObject = new ManagedObject(schema, cache, field, rawValue, identifier, path, record, editable, legacy);
439
518
  if (!managedObjectMapForRecord) {
440
- ManagedObjectMap.set(record, new Map([[field, managedObject]]));
519
+ ManagedObjectMap.set(record, new Map([[field.name, managedObject]]));
441
520
  } else {
442
- managedObjectMapForRecord.set(field, managedObject);
521
+ managedObjectMapForRecord.set(field.name, managedObject);
443
522
  }
444
523
  }
445
524
  return managedObject;
@@ -448,12 +527,12 @@ function computeSchemaObject(store, cache, record, identifier, field, path, lega
448
527
  const schemaObjectMapForRecord = ManagedObjectMap.get(record);
449
528
  let schemaObject;
450
529
  if (schemaObjectMapForRecord) {
451
- schemaObject = schemaObjectMapForRecord.get(field);
530
+ schemaObject = schemaObjectMapForRecord.get(field.name);
452
531
  }
453
532
  if (schemaObject) {
454
533
  return schemaObject;
455
534
  } else {
456
- const rawValue = cache.getAttr(identifier, path);
535
+ const rawValue = editable ? cache.getAttr(identifier, path) : cache.getRemoteAttr(identifier, path);
457
536
  if (!rawValue) {
458
537
  return null;
459
538
  }
@@ -464,14 +543,14 @@ function computeSchemaObject(store, cache, record, identifier, field, path, lega
464
543
  }, true, field.type, embeddedPath);
465
544
  }
466
545
  if (!schemaObjectMapForRecord) {
467
- ManagedObjectMap.set(record, new Map([[field, schemaObject]]));
546
+ ManagedObjectMap.set(record, new Map([[field.name, schemaObject]]));
468
547
  } else {
469
- schemaObjectMapForRecord.set(field, schemaObject);
548
+ schemaObjectMapForRecord.set(field.name, schemaObject);
470
549
  }
471
550
  return schemaObject;
472
551
  }
473
- function computeAttribute(cache, identifier, prop) {
474
- return cache.getAttr(identifier, prop);
552
+ function computeAttribute(cache, identifier, prop, editable) {
553
+ return editable ? cache.getAttr(identifier, prop) : cache.getRemoteAttr(identifier, prop);
475
554
  }
476
555
  function computeDerivation(schema, record, identifier, field, prop) {
477
556
  return schema.derivation(field)(record, field.options ?? null, prop);
@@ -480,8 +559,8 @@ function computeDerivation(schema, record, identifier, field, prop) {
480
559
  // TODO probably this should just be a Document
481
560
  // but its separate until we work out the lid situation
482
561
  class ResourceRelationship {
483
- constructor(store, cache, parent, identifier, field, name) {
484
- const rawValue = cache.getRelationship(identifier, name);
562
+ constructor(store, cache, parent, identifier, field, name, editable) {
563
+ const rawValue = editable ? cache.getRelationship(identifier, name) : cache.getRemoteRelationship(identifier, name);
485
564
 
486
565
  // TODO setup true lids for relationship documents
487
566
  // @ts-expect-error we need to give relationship documents a lid
@@ -489,7 +568,7 @@ class ResourceRelationship {
489
568
  this.lid = rawValue.lid ?? rawValue.links?.self ?? `relationship:${identifier.lid}.${name}`;
490
569
  this.data = rawValue.data ? store.peekRecord(rawValue.data) : null;
491
570
  this.name = name;
492
- if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
571
+ if (macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG)) {
493
572
  this.links = Object.freeze(Object.assign({}, rawValue.links));
494
573
  this.meta = Object.freeze(Object.assign({}, rawValue.meta));
495
574
  } else {
@@ -523,11 +602,56 @@ function getHref(link) {
523
602
  }
524
603
  return link.href;
525
604
  }
526
- function computeResource(store, cache, parent, identifier, field, prop) {
605
+ function computeResource(store, cache, parent, identifier, field, prop, editable) {
527
606
  if (field.kind !== 'resource') {
528
607
  throw new Error(`The schema for ${identifier.type}.${String(prop)} is not a resource relationship`);
529
608
  }
530
- return new ResourceRelationship(store, cache, parent, identifier, field, prop);
609
+ return new ResourceRelationship(store, cache, parent, identifier, field, prop, editable);
610
+ }
611
+ function computeHasMany(store, schema, cache, record, identifier, field, path, editable, legacy) {
612
+ // the thing we hand out needs to know its owner and path in a private manner
613
+ // its "address" is the parent identifier (identifier) + field name (field.name)
614
+ // in the nested object case field name here is the full dot path from root resource to this value
615
+ // its "key" is the field on the parent record
616
+ // its "owner" is the parent record
617
+
618
+ const managedArrayMapForRecord = ManagedArrayMap.get(record);
619
+ let managedArray;
620
+ if (managedArrayMapForRecord) {
621
+ managedArray = managedArrayMapForRecord.get(field.name);
622
+ }
623
+ if (managedArray) {
624
+ return managedArray;
625
+ } else {
626
+ const rawValue = cache.getRelationship(identifier, field.name);
627
+ if (!rawValue) {
628
+ return null;
629
+ }
630
+ managedArray = new RelatedCollection({
631
+ store,
632
+ type: field.type,
633
+ identifier,
634
+ cache,
635
+ identifiers: rawValue.data,
636
+ key: field.name,
637
+ meta: rawValue.meta || null,
638
+ links: rawValue.links || null,
639
+ isPolymorphic: field.options.polymorphic ?? false,
640
+ isAsync: field.options.async ?? false,
641
+ // TODO: Grab the proper value
642
+ _inverseIsAsync: false,
643
+ // @ts-expect-error Typescript doesn't have a way for us to thread the generic backwards so it infers unknown instead of T
644
+ manager: new ManyArrayManager(record),
645
+ isLoaded: true,
646
+ allowMutation: editable
647
+ });
648
+ if (!managedArrayMapForRecord) {
649
+ ManagedArrayMap.set(record, new Map([[field.name, managedArray]]));
650
+ } else {
651
+ managedArrayMapForRecord.set(field.name, managedArray);
652
+ }
653
+ }
654
+ return managedArray;
531
655
  }
532
656
  const HAS_MODEL_PACKAGE = dependencySatisfies('@ember-data-mirror/model', '*');
533
657
  const getLegacySupport = macroCondition(dependencySatisfies('@ember-data-mirror/model', '*')) ? importSync('@ember-data-mirror/model/-private').lookupLegacySupport : null;
@@ -570,6 +694,9 @@ class SchemaRecord {
570
694
  return Array.from(fields.keys());
571
695
  },
572
696
  has(target, prop) {
697
+ if (prop === Destroy || prop === Checkout) {
698
+ return true;
699
+ }
573
700
  return fields.has(prop);
574
701
  },
575
702
  getOwnPropertyDescriptor(target, prop) {
@@ -652,7 +779,7 @@ class SchemaRecord {
652
779
  throw new Error(`No field named ${String(prop)} on ${type}`);
653
780
  }
654
781
  const field = maybeField.kind === 'alias' ? maybeField.options : maybeField;
655
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
782
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
656
783
  if (!test) {
657
784
  throw new Error(`Alias fields cannot alias '@id' '@local' '@hash' or 'derived' fields`);
658
785
  }
@@ -677,39 +804,37 @@ class SchemaRecord {
677
804
  return lastValue;
678
805
  }
679
806
  case 'field':
680
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
807
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
681
808
  if (!test) {
682
809
  throw new Error(`SchemaRecord.${field.name} is not available in legacy mode because it has type '${field.kind}'`);
683
810
  }
684
811
  })(!target[Legacy]) : {};
685
812
  entangleSignal(signals, receiver, field.name);
686
- return computeField(schema, cache, target, identifier, field, propArray);
813
+ return computeField(schema, cache, target, identifier, field, propArray, IS_EDITABLE);
687
814
  case 'attribute':
688
815
  entangleSignal(signals, receiver, field.name);
689
- return computeAttribute(cache, identifier, prop);
816
+ return computeAttribute(cache, identifier, prop, IS_EDITABLE);
690
817
  case 'resource':
691
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
818
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
692
819
  if (!test) {
693
820
  throw new Error(`SchemaRecord.${field.name} is not available in legacy mode because it has type '${field.kind}'`);
694
821
  }
695
822
  })(!target[Legacy]) : {};
696
823
  entangleSignal(signals, receiver, field.name);
697
- return computeResource(store, cache, target, identifier, field, prop);
824
+ return computeResource(store, cache, target, identifier, field, prop, IS_EDITABLE);
698
825
  case 'derived':
699
826
  return computeDerivation(schema, receiver, identifier, field, prop);
700
827
  case 'schema-array':
701
- entangleSignal(signals, receiver, field.name);
702
- return computeArray(store, schema, cache, target, identifier, field, propArray, true, Mode[Editable], Mode[Legacy]);
703
828
  case 'array':
704
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
829
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
705
830
  if (!test) {
706
831
  throw new Error(`SchemaRecord.${field.name} is not available in legacy mode because it has type '${field.kind}'`);
707
832
  }
708
833
  })(!target[Legacy]) : {};
709
834
  entangleSignal(signals, receiver, field.name);
710
- return computeArray(store, schema, cache, target, identifier, field, propArray, false, Mode[Editable], Mode[Legacy]);
835
+ return computeArray(store, schema, cache, target, identifier, field, propArray, Mode[Editable], Mode[Legacy]);
711
836
  case 'object':
712
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
837
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
713
838
  if (!test) {
714
839
  throw new Error(`SchemaRecord.${field.name} is not available in legacy mode because it has type '${field.kind}'`);
715
840
  }
@@ -717,7 +842,7 @@ class SchemaRecord {
717
842
  entangleSignal(signals, receiver, field.name);
718
843
  return computeObject(schema, cache, target, identifier, field, propArray, Mode[Editable], Mode[Legacy]);
719
844
  case 'schema-object':
720
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
845
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
721
846
  if (!test) {
722
847
  throw new Error(`SchemaRecord.${field.name} is not available in legacy mode because it has type '${field.kind}'`);
723
848
  }
@@ -726,19 +851,26 @@ class SchemaRecord {
726
851
  // run transform, then use that value as the object to manage
727
852
  return computeSchemaObject(store, cache, target, identifier, field, propArray, Mode[Legacy], Mode[Editable]);
728
853
  case 'belongsTo':
854
+ if (field.options.linksMode) {
855
+ entangleSignal(signals, receiver, field.name);
856
+ const rawValue = IS_EDITABLE ? cache.getRelationship(identifier, field.name) : cache.getRemoteRelationship(identifier, field.name);
857
+
858
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
859
+ return rawValue.data ? store.peekRecord(rawValue.data) : null;
860
+ }
729
861
  if (!HAS_MODEL_PACKAGE) {
730
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
862
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
731
863
  {
732
864
  throw new Error(`Cannot use belongsTo fields in your schema unless @ember-data-mirror/model is installed to provide legacy model support. ${field.name} should likely be migrated to be a resource field.`);
733
865
  }
734
866
  })() : {};
735
867
  }
736
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
868
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
737
869
  if (!test) {
738
870
  throw new Error(`Expected to have a getLegacySupport function`);
739
871
  }
740
872
  })(getLegacySupport) : {};
741
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
873
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
742
874
  if (!test) {
743
875
  throw new Error(`Can only use belongsTo fields when the resource is in legacy mode`);
744
876
  }
@@ -746,19 +878,23 @@ class SchemaRecord {
746
878
  entangleSignal(signals, receiver, field.name);
747
879
  return getLegacySupport(receiver).getBelongsTo(field.name);
748
880
  case 'hasMany':
881
+ if (field.options.linksMode) {
882
+ entangleSignal(signals, receiver, field.name);
883
+ return computeHasMany(store, schema, cache, target, identifier, field, propArray, Mode[Editable], Mode[Legacy]);
884
+ }
749
885
  if (!HAS_MODEL_PACKAGE) {
750
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
886
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
751
887
  {
752
888
  throw new Error(`Cannot use hasMany fields in your schema unless @ember-data-mirror/model is installed to provide legacy model support. ${field.name} should likely be migrated to be a collection field.`);
753
889
  }
754
890
  })() : {};
755
891
  }
756
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
892
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
757
893
  if (!test) {
758
894
  throw new Error(`Expected to have a getLegacySupport function`);
759
895
  }
760
896
  })(getLegacySupport) : {};
761
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
897
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
762
898
  if (!test) {
763
899
  throw new Error(`Can only use hasMany fields when the resource is in legacy mode`);
764
900
  }
@@ -780,7 +916,7 @@ class SchemaRecord {
780
916
  throw new Error(`There is no field named ${String(prop)} on ${type}`);
781
917
  }
782
918
  const field = maybeField.kind === 'alias' ? maybeField.options : maybeField;
783
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
919
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
784
920
  if (!test) {
785
921
  throw new Error(`Alias fields cannot alias '@id' '@local' '@hash' or 'derived' fields`);
786
922
  }
@@ -794,14 +930,14 @@ class SchemaRecord {
794
930
  switch (field.kind) {
795
931
  case '@id':
796
932
  {
797
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
933
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
798
934
  if (!test) {
799
935
  throw new Error(`Expected to receive a string id`);
800
936
  }
801
937
  })(typeof value === 'string' && value.length) : {};
802
938
  const normalizedId = String(value);
803
939
  const didChange = normalizedId !== identifier.id;
804
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
940
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
805
941
  if (!test) {
806
942
  throw new Error(`Cannot set ${identifier.type} record's id to ${normalizedId}, because id is already ${identifier.id}`);
807
943
  }
@@ -843,6 +979,11 @@ class SchemaRecord {
843
979
  cache.setAttr(identifier, propArray, value?.slice());
844
980
  const peeked = peekManagedArray(self, field);
845
981
  if (peeked) {
982
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
983
+ if (!test) {
984
+ throw new Error(`Expected the peekManagedArray for ${field.kind} to return a ManagedArray`);
985
+ }
986
+ })(ARRAY_SIGNAL in peeked) : {};
846
987
  const arrSignal = peeked[ARRAY_SIGNAL];
847
988
  arrSignal.shouldReset = true;
848
989
  }
@@ -856,6 +997,11 @@ class SchemaRecord {
856
997
  cache.setAttr(identifier, propArray, rawValue);
857
998
  const peeked = peekManagedArray(self, field);
858
999
  if (peeked) {
1000
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1001
+ if (!test) {
1002
+ throw new Error(`Expected the peekManagedArray for ${field.kind} to return a ManagedArray`);
1003
+ }
1004
+ })(ARRAY_SIGNAL in peeked) : {};
859
1005
  const arrSignal = peeked[ARRAY_SIGNAL];
860
1006
  arrSignal.shouldReset = true;
861
1007
  }
@@ -870,6 +1016,11 @@ class SchemaRecord {
870
1016
  cache.setAttr(identifier, propArray, arrayValue);
871
1017
  const peeked = peekManagedArray(self, field);
872
1018
  if (peeked) {
1019
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1020
+ if (!test) {
1021
+ throw new Error(`Expected the peekManagedArray for ${field.kind} to return a ManagedArray`);
1022
+ }
1023
+ })(ARRAY_SIGNAL in peeked) : {};
873
1024
  const arrSignal = peeked[ARRAY_SIGNAL];
874
1025
  arrSignal.shouldReset = true;
875
1026
  }
@@ -913,7 +1064,7 @@ class SchemaRecord {
913
1064
  {
914
1065
  let newValue = value;
915
1066
  if (value !== null) {
916
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1067
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
917
1068
  if (!test) {
918
1069
  throw new Error(`Expected value to be an object`);
919
1070
  }
@@ -946,18 +1097,18 @@ class SchemaRecord {
946
1097
  }
947
1098
  case 'belongsTo':
948
1099
  if (!HAS_MODEL_PACKAGE) {
949
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1100
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
950
1101
  {
951
1102
  throw new Error(`Cannot use belongsTo fields in your schema unless @ember-data-mirror/model is installed to provide legacy model support. ${field.name} should likely be migrated to be a resource field.`);
952
1103
  }
953
1104
  })() : {};
954
1105
  }
955
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1106
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
956
1107
  if (!test) {
957
1108
  throw new Error(`Expected to have a getLegacySupport function`);
958
1109
  }
959
1110
  })(getLegacySupport) : {};
960
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1111
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
961
1112
  if (!test) {
962
1113
  throw new Error(`Can only use belongsTo fields when the resource is in legacy mode`);
963
1114
  }
@@ -968,23 +1119,23 @@ class SchemaRecord {
968
1119
  return true;
969
1120
  case 'hasMany':
970
1121
  if (!HAS_MODEL_PACKAGE) {
971
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1122
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
972
1123
  {
973
1124
  throw new Error(`Cannot use hasMany fields in your schema unless @ember-data-mirror/model is installed to provide legacy model support. ${field.name} should likely be migrated to be a collection field.`);
974
1125
  }
975
1126
  })() : {};
976
1127
  }
977
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1128
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
978
1129
  if (!test) {
979
1130
  throw new Error(`Expected to have a getLegacySupport function`);
980
1131
  }
981
1132
  })(getLegacySupport) : {};
982
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1133
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
983
1134
  if (!test) {
984
1135
  throw new Error(`Can only use hasMany fields when the resource is in legacy mode`);
985
1136
  }
986
1137
  })(Mode[Legacy]) : {};
987
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1138
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
988
1139
  if (!test) {
989
1140
  throw new Error(`You must pass an array of records to set a hasMany relationship`);
990
1141
  }
@@ -1047,6 +1198,11 @@ class SchemaRecord {
1047
1198
  if (field?.kind === 'array' || field?.kind === 'schema-array') {
1048
1199
  const peeked = peekManagedArray(self, field);
1049
1200
  if (peeked) {
1201
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1202
+ if (!test) {
1203
+ throw new Error(`Expected the peekManagedArray for ${field.kind} to return a ManagedArray`);
1204
+ }
1205
+ })(ARRAY_SIGNAL in peeked) : {};
1050
1206
  const arrSignal = peeked[ARRAY_SIGNAL];
1051
1207
  arrSignal.shouldReset = true;
1052
1208
  addToTransaction(arrSignal);
@@ -1069,7 +1225,7 @@ class SchemaRecord {
1069
1225
  if (isEmbedded) return; // base paths never apply to embedded records
1070
1226
 
1071
1227
  const field = fields.get(key);
1072
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1228
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1073
1229
  if (!test) {
1074
1230
  throw new Error(`Expected relationshp ${key} to be the name of a field`);
1075
1231
  }
@@ -1083,12 +1239,22 @@ class SchemaRecord {
1083
1239
  }
1084
1240
  // FIXME
1085
1241
  } else if (field.kind === 'resource') ;else if (field.kind === 'hasMany') {
1086
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1242
+ if (field.options.linksMode) {
1243
+ const peeked = peekManagedArray(self, field);
1244
+ if (peeked) {
1245
+ // const arrSignal = peeked[ARRAY_SIGNAL];
1246
+ // arrSignal.shouldReset = true;
1247
+ // addToTransaction(arrSignal);
1248
+ peeked.notify();
1249
+ }
1250
+ return;
1251
+ }
1252
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1087
1253
  if (!test) {
1088
1254
  throw new Error(`Expected to have a getLegacySupport function`);
1089
1255
  }
1090
1256
  })(getLegacySupport) : {};
1091
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1257
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1092
1258
  if (!test) {
1093
1259
  throw new Error(`Can only use hasMany fields when the resource is in legacy mode`);
1094
1260
  }
@@ -1103,12 +1269,12 @@ class SchemaRecord {
1103
1269
  }
1104
1270
  if (manyArray) {
1105
1271
  manyArray.notify();
1106
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1272
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1107
1273
  if (!test) {
1108
1274
  throw new Error(`Expected options to exist on relationship meta`);
1109
1275
  }
1110
1276
  })(field.options) : {};
1111
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1277
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1112
1278
  if (!test) {
1113
1279
  throw new Error(`Expected async to exist on relationship meta options`);
1114
1280
  }
@@ -1138,6 +1304,10 @@ class SchemaRecord {
1138
1304
  this[RecordStore].notifications.unsubscribe(this.___notifications);
1139
1305
  }
1140
1306
  [Checkout]() {
1307
+ // IF we are already the editable record, throw an error
1308
+ if (this[Editable]) {
1309
+ throw new Error(`Cannot checkout an already editable record`);
1310
+ }
1141
1311
  const editable = Editables.get(this);
1142
1312
  if (editable) {
1143
1313
  return Promise.resolve(editable);
@@ -1156,4 +1326,297 @@ class SchemaRecord {
1156
1326
  return Promise.resolve(editableRecord);
1157
1327
  }
1158
1328
  }
1159
- export { Checkout, Editable, Legacy, SchemaRecord };
1329
+ function instantiateRecord(store, identifier, createArgs) {
1330
+ const schema = store.schema;
1331
+ const isLegacy = schema.resource(identifier)?.legacy ?? false;
1332
+ const isEditable = isLegacy || store.cache.isNew(identifier);
1333
+ const record = new SchemaRecord(store, identifier, {
1334
+ [Editable]: isEditable,
1335
+ [Legacy]: isLegacy
1336
+ });
1337
+ if (createArgs) {
1338
+ Object.assign(record, createArgs);
1339
+ }
1340
+ return record;
1341
+ }
1342
+ function assertSchemaRecord(record) {
1343
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1344
+ if (!test) {
1345
+ throw new Error('Expected a SchemaRecord');
1346
+ }
1347
+ })(record && typeof record === 'object' && Destroy in record) : {};
1348
+ }
1349
+ function teardownRecord(record) {
1350
+ assertSchemaRecord(record);
1351
+ record[Destroy]();
1352
+ }
1353
+ const Support = getOrSetGlobal('Support', new WeakMap());
1354
+ const SchemaRecordFields = [{
1355
+ type: '@constructor',
1356
+ name: 'constructor',
1357
+ kind: 'derived'
1358
+ }, {
1359
+ type: '@identity',
1360
+ name: '$type',
1361
+ kind: 'derived',
1362
+ options: {
1363
+ key: 'type'
1364
+ }
1365
+ }];
1366
+ function _constructor(record) {
1367
+ let state = Support.get(record);
1368
+ if (!state) {
1369
+ state = {};
1370
+ Support.set(record, state);
1371
+ }
1372
+ return state._constructor = state._constructor || {
1373
+ name: `SchemaRecord<${recordIdentifierFor$1(record).type}>`,
1374
+ get modelName() {
1375
+ throw new Error('Cannot access record.constructor.modelName on non-Legacy Schema Records.');
1376
+ }
1377
+ };
1378
+ }
1379
+ _constructor[Type] = '@constructor';
1380
+ function withDefaults(schema) {
1381
+ schema.identity = schema.identity || {
1382
+ name: 'id',
1383
+ kind: '@id'
1384
+ };
1385
+ schema.fields.push(...SchemaRecordFields);
1386
+ return schema;
1387
+ }
1388
+ function fromIdentity(record, options, key) {
1389
+ const identifier = record[Identifier];
1390
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1391
+ if (!test) {
1392
+ throw new Error(`Cannot compute @identity for a record without an identifier`);
1393
+ }
1394
+ })(identifier) : {};
1395
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1396
+ if (!test) {
1397
+ throw new Error(`Expected to receive a key to compute @identity, but got ${String(options)}`);
1398
+ }
1399
+ })(options?.key && ['lid', 'id', 'type', '^'].includes(options.key)) : {};
1400
+ return options.key === '^' ? identifier : identifier[options.key];
1401
+ }
1402
+ fromIdentity[Type] = '@identity';
1403
+ function registerDerivations(schema) {
1404
+ schema.registerDerivation(fromIdentity);
1405
+ schema.registerDerivation(_constructor);
1406
+ }
1407
+ /**
1408
+ * Wraps a derivation in a new function with Derivation signature but that looks
1409
+ * up the value in the cache before recomputing.
1410
+ *
1411
+ * @param record
1412
+ * @param options
1413
+ * @param prop
1414
+ */
1415
+ function makeCachedDerivation(derivation) {
1416
+ const memoizedDerivation = (record, options, prop) => {
1417
+ const signals = record[Signals];
1418
+ let signal = signals.get(prop);
1419
+ if (!signal) {
1420
+ signal = createCache(() => {
1421
+ return derivation(record, options, prop);
1422
+ }); // a total lie, for convenience of reusing the storage
1423
+ signals.set(prop, signal);
1424
+ }
1425
+ return getValue(signal);
1426
+ };
1427
+ memoizedDerivation[Type] = derivation[Type];
1428
+ return memoizedDerivation;
1429
+ }
1430
+ class SchemaService {
1431
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1432
+
1433
+ constructor() {
1434
+ this._schemas = new Map();
1435
+ this._transforms = new Map();
1436
+ this._hashFns = new Map();
1437
+ this._derivations = new Map();
1438
+ }
1439
+ hasTrait(type) {
1440
+ return this._traits.has(type);
1441
+ }
1442
+ resourceHasTrait(resource, trait) {
1443
+ return this._schemas.get(resource.type).traits.has(trait);
1444
+ }
1445
+ transformation(field) {
1446
+ const kind = 'kind' in field ? field.kind : '<unknown kind>';
1447
+ const name = 'name' in field ? field.name : '<unknown name>';
1448
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1449
+ if (!test) {
1450
+ throw new Error(`'${kind}' fields cannot be transformed. Only fields of kind 'field' 'object' or 'array' can specify a transformation. Attempted to find '${field.type ?? '<unknown type>'}' on field '${name}'.`);
1451
+ }
1452
+ })(!('kind' in field) || ['field', 'object', 'array'].includes(kind)) : {};
1453
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1454
+ if (!test) {
1455
+ throw new Error(`Expected the '${kind}' field '${name}' to specify a transformation via 'field.type', but none was present`);
1456
+ }
1457
+ })(field.type) : {};
1458
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1459
+ if (!test) {
1460
+ throw new Error(`No transformation registered with name '${field.type}' for '${kind}' field '${name}'`);
1461
+ }
1462
+ })(this._transforms.has(field.type)) : {};
1463
+ return this._transforms.get(field.type);
1464
+ }
1465
+ derivation(field) {
1466
+ const kind = 'kind' in field ? field.kind : '<unknown kind>';
1467
+ const name = 'name' in field ? field.name : '<unknown name>';
1468
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1469
+ if (!test) {
1470
+ throw new Error(`The '${kind}' field '${name}' is not derived and so cannot be used to lookup a derivation`);
1471
+ }
1472
+ })(!('kind' in field) || kind === 'derived') : {};
1473
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1474
+ if (!test) {
1475
+ throw new Error(`Expected the '${kind}' field '${name}' to specify a derivation via 'field.type', but no value was present`);
1476
+ }
1477
+ })(field.type) : {};
1478
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1479
+ if (!test) {
1480
+ throw new Error(`No '${field.type}' derivation registered for use by the '${kind}' field '${name}'`);
1481
+ }
1482
+ })(this._derivations.has(field.type)) : {};
1483
+ return this._derivations.get(field.type);
1484
+ }
1485
+ hashFn(field) {
1486
+ const kind = 'kind' in field ? field.kind : '<unknown kind>';
1487
+ const name = 'name' in field ? field.name : '<unknown name>';
1488
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1489
+ if (!test) {
1490
+ throw new Error(`The '${kind}' field '${name}' is not a HashField and so cannot be used to lookup a hash function`);
1491
+ }
1492
+ })(!('kind' in field) || kind === '@hash') : {};
1493
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1494
+ if (!test) {
1495
+ throw new Error(`Expected the '${kind}' field '${name}' to specify a hash function via 'field.type', but no value was present`);
1496
+ }
1497
+ })(field.type) : {};
1498
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1499
+ if (!test) {
1500
+ throw new Error(`No '${field.type}' hash function is registered for use by the '${kind}' field '${name}'`);
1501
+ }
1502
+ })(this._hashFns.has(field.type)) : {};
1503
+ return this._hashFns.get(field.type);
1504
+ }
1505
+ resource(resource) {
1506
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1507
+ if (!test) {
1508
+ throw new Error(`No resource registered with name '${resource.type}'`);
1509
+ }
1510
+ })(this._schemas.has(resource.type)) : {};
1511
+ return this._schemas.get(resource.type).original;
1512
+ }
1513
+ registerResources(schemas) {
1514
+ schemas.forEach(schema => {
1515
+ this.registerResource(schema);
1516
+ });
1517
+ }
1518
+ registerResource(schema) {
1519
+ const fields = new Map();
1520
+ const relationships = {};
1521
+ const attributes = {};
1522
+ schema.fields.forEach(field => {
1523
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
1524
+ if (!test) {
1525
+ throw new Error(`${field.kind} is not valid inside a ResourceSchema's fields.`);
1526
+ }
1527
+ })(
1528
+ // @ts-expect-error we are checking for mistakes at runtime
1529
+ field.kind !== '@id' && field.kind !== '@hash') : {};
1530
+ fields.set(field.name, field);
1531
+ if (field.kind === 'attribute') {
1532
+ attributes[field.name] = field;
1533
+ } else if (field.kind === 'belongsTo' || field.kind === 'hasMany') {
1534
+ relationships[field.name] = field;
1535
+ }
1536
+ });
1537
+ const traits = new Set(schema.traits);
1538
+ traits.forEach(trait => {
1539
+ this._traits.add(trait);
1540
+ });
1541
+ const internalSchema = {
1542
+ original: schema,
1543
+ fields,
1544
+ relationships,
1545
+ attributes,
1546
+ traits
1547
+ };
1548
+ this._schemas.set(schema.type, internalSchema);
1549
+ }
1550
+ registerTransformation(transformation) {
1551
+ this._transforms.set(transformation[Type], transformation);
1552
+ }
1553
+ registerDerivation(derivation) {
1554
+ this._derivations.set(derivation[Type], makeCachedDerivation(derivation));
1555
+ }
1556
+ registerHashFn(hashFn) {
1557
+ this._hashFns.set(hashFn[Type], hashFn);
1558
+ }
1559
+ fields({
1560
+ type
1561
+ }) {
1562
+ const schema = this._schemas.get(type);
1563
+ if (!schema) {
1564
+ throw new Error(`No schema defined for ${type}`);
1565
+ }
1566
+ return schema.fields;
1567
+ }
1568
+ hasResource(resource) {
1569
+ return this._schemas.has(resource.type);
1570
+ }
1571
+ }
1572
+ if (macroCondition(getGlobalConfig().WarpDriveMirror.deprecations.ENABLE_LEGACY_SCHEMA_SERVICE)) {
1573
+ SchemaService.prototype.attributesDefinitionFor = function ({
1574
+ type
1575
+ }) {
1576
+ deprecate(`Use \`schema.fields({ type })\` instead of \`schema.attributesDefinitionFor({ type })\``, false, {
1577
+ id: 'ember-data-mirror:schema-service-updates',
1578
+ until: '6.0',
1579
+ for: 'ember-data-mirror',
1580
+ since: {
1581
+ available: '4.13',
1582
+ enabled: '5.4'
1583
+ }
1584
+ });
1585
+ const schema = this._schemas.get(type);
1586
+ if (!schema) {
1587
+ throw new Error(`No schema defined for ${type}`);
1588
+ }
1589
+ return schema.attributes;
1590
+ };
1591
+ SchemaService.prototype.relationshipsDefinitionFor = function ({
1592
+ type
1593
+ }) {
1594
+ deprecate(`Use \`schema.fields({ type })\` instead of \`schema.relationshipsDefinitionFor({ type })\``, false, {
1595
+ id: 'ember-data-mirror:schema-service-updates',
1596
+ until: '6.0',
1597
+ for: 'ember-data-mirror',
1598
+ since: {
1599
+ available: '4.13',
1600
+ enabled: '5.4'
1601
+ }
1602
+ });
1603
+ const schema = this._schemas.get(type);
1604
+ if (!schema) {
1605
+ throw new Error(`No schema defined for ${type}`);
1606
+ }
1607
+ return schema.relationships;
1608
+ };
1609
+ SchemaService.prototype.doesTypeExist = function (type) {
1610
+ deprecate(`Use \`schema.hasResource({ type })\` instead of \`schema.doesTypeExist(type)\``, false, {
1611
+ id: 'ember-data-mirror:schema-service-updates',
1612
+ until: '6.0',
1613
+ for: 'ember-data-mirror',
1614
+ since: {
1615
+ available: '4.13',
1616
+ enabled: '5.4'
1617
+ }
1618
+ });
1619
+ return this._schemas.has(type);
1620
+ };
1621
+ }
1622
+ export { Checkout, SchemaService, fromIdentity, instantiateRecord, registerDerivations, teardownRecord, withDefaults };