@warp-drive/core 5.9.0-alpha.18 → 5.9.0-alpha.19

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 (30) hide show
  1. package/declarations/index.d.ts +10 -1
  2. package/dist/graph/-private.js +17 -21
  3. package/dist/{index-BoY6aNE5.js → index-LI2ckwf9.js} +244 -1
  4. package/dist/index.js +1 -1
  5. package/dist/reactive.js +1 -1
  6. package/dist/store/-private.js +1 -1
  7. package/dist/types/-private.js +1 -1
  8. package/dist/unpkg/dev/graph/-private.js +17 -21
  9. package/dist/unpkg/dev/{index-BZ6PKU-a.js → index-DU_HLpg-.js} +244 -1
  10. package/dist/unpkg/dev/index.js +1 -1
  11. package/dist/unpkg/dev/reactive.js +1 -1
  12. package/dist/unpkg/dev/store/-private.js +2 -2
  13. package/dist/unpkg/dev/types/-private.js +1 -1
  14. package/dist/unpkg/dev-deprecated/graph/-private.js +17 -21
  15. package/dist/unpkg/dev-deprecated/{index-CDjd631s.js → index-BYFUHVPd.js} +244 -1
  16. package/dist/unpkg/dev-deprecated/index.js +1 -1
  17. package/dist/unpkg/dev-deprecated/reactive.js +1 -1
  18. package/dist/unpkg/dev-deprecated/store/-private.js +1 -1
  19. package/dist/unpkg/dev-deprecated/types/-private.js +1 -1
  20. package/dist/unpkg/prod/{index-BMBm3kYx.js → index-C-AhVafS.js} +146 -1
  21. package/dist/unpkg/prod/index.js +1 -1
  22. package/dist/unpkg/prod/reactive.js +1 -1
  23. package/dist/unpkg/prod/store/-private.js +2 -2
  24. package/dist/unpkg/prod/types/-private.js +1 -1
  25. package/dist/unpkg/prod-deprecated/{index-CZkDXZog.js → index-CplZl2hv.js} +146 -1
  26. package/dist/unpkg/prod-deprecated/index.js +1 -1
  27. package/dist/unpkg/prod-deprecated/reactive.js +1 -1
  28. package/dist/unpkg/prod-deprecated/store/-private.js +1 -1
  29. package/dist/unpkg/prod-deprecated/types/-private.js +1 -1
  30. package/package.json +3 -3
@@ -6361,6 +6361,9 @@ class ReactiveResource {
6361
6361
  if (prop === Destroy || prop === Checkout) {
6362
6362
  return true;
6363
6363
  }
6364
+ if (prop === identityField?.name) {
6365
+ return true;
6366
+ }
6364
6367
  return fields.has(prop);
6365
6368
  },
6366
6369
  getOwnPropertyDescriptor(target, prop) {
@@ -7057,6 +7060,18 @@ class SchemaService {
7057
7060
 
7058
7061
  /** @internal */
7059
7062
 
7063
+ /**
7064
+ * Tracks, per abstract type, the relationship fields that concrete
7065
+ * implementers have contributed via `options.as`, along with the type
7066
+ * that contributed each one (for assertion messages). This is
7067
+ * independent of whatever schema (synthesized or user-registered)
7068
+ * currently occupies `_schemas` for that type, so that these fields
7069
+ * survive regardless of the order in which the abstract type's
7070
+ * implementers and its own (optional) concrete schema are registered.
7071
+ *
7072
+ * @internal
7073
+ */
7074
+
7060
7075
  /** @internal */
7061
7076
 
7062
7077
  /** @internal */
@@ -7068,6 +7083,7 @@ class SchemaService {
7068
7083
  this._derivations = new Map();
7069
7084
  this._traits = new Map();
7070
7085
  this._modes = new Map();
7086
+ this._abstractImplementerFields = new Map();
7071
7087
  this._extensions = {
7072
7088
  object: new Map(),
7073
7089
  array: new Map()
@@ -7113,12 +7129,33 @@ class SchemaService {
7113
7129
  const fields = new Map();
7114
7130
  const relationships = {};
7115
7131
  const attributes = {};
7132
+ const abstractImplementations = [];
7116
7133
  for (const field of schema.fields) {
7117
7134
  fields.set(field.name, field);
7118
7135
  if (field.kind === 'attribute') {
7119
7136
  attributes[field.name] = field;
7120
7137
  } else if (field.kind === 'belongsTo' || field.kind === 'hasMany') {
7121
7138
  relationships[field.name] = field;
7139
+ if (field.options?.as) {
7140
+ abstractImplementations.push(field);
7141
+ }
7142
+ }
7143
+ }
7144
+
7145
+ // This type may already be known as an abstract polymorphic type,
7146
+ // implemented by other concrete types via `options.as`, from before it
7147
+ // ever had a schema of its own (see `_registerAbstractTypeImplementation`).
7148
+ // Carry those previously-contributed fields forward so that registering
7149
+ // a "real" schema for the type - whenever that happens to occur - never
7150
+ // erases the relationships its implementers depend on.
7151
+ const implementerFields = this._abstractImplementerFields.get(schema.type);
7152
+ if (implementerFields) {
7153
+ for (const [name, contribution] of implementerFields) {
7154
+ const ownField = fields.get(name);
7155
+ if (!ownField) {
7156
+ fields.set(name, contribution.field);
7157
+ relationships[name] = contribution.field;
7158
+ }
7122
7159
  }
7123
7160
  }
7124
7161
  const cacheFields = null;
@@ -7137,6 +7174,92 @@ class SchemaService {
7137
7174
  internalSchema.cacheFields = getCacheFields(internalSchema);
7138
7175
  }
7139
7176
  this._schemas.set(schema.type, internalSchema);
7177
+
7178
+ // A relationship field's `as` option marks it as a valid concrete
7179
+ // implementer of an abstract polymorphic type (e.g. `as: 'commentable'`).
7180
+ // That abstract type may never be given its own schema by the user - it
7181
+ // may exist only to be implemented by concrete types like this one - or
7182
+ // it may already have (or later receive) a schema of its own, e.g. if it
7183
+ // turns out to also be a real, directly-resolvable resource. Either way,
7184
+ // ensure it has a schema with this field present, so that it behaves
7185
+ // like any other registered resource (`hasResource`, `fields`, etc.)
7186
+ // instead of requiring special-casing wherever abstract relationship
7187
+ // types are resolved.
7188
+ for (const field of abstractImplementations) {
7189
+ this._registerAbstractTypeImplementation(field, schema.type);
7190
+ }
7191
+ }
7192
+
7193
+ /** @internal */
7194
+ _registerAbstractTypeImplementation(field, implementer) {
7195
+ const abstractType = field.options.as;
7196
+ let implementerFields = this._abstractImplementerFields.get(abstractType);
7197
+ if (!implementerFields) {
7198
+ implementerFields = new Map();
7199
+ this._abstractImplementerFields.set(abstractType, implementerFields);
7200
+ }
7201
+
7202
+ // Unlike the original approach this replaced, `as` is *not* stripped here:
7203
+ // the field as synthesized onto the abstract type's own schema keeps
7204
+ // `options.as === abstractType`, redundant/self-referential as that is.
7205
+ // This keeps every contributor - implementers and the abstract type's
7206
+ // own schema alike - declaring the same thing, which is what
7207
+ // `assertConsistentAbstractFieldShape` checks, and it is also what lets
7208
+ // `assertPolymorphicType` (which reads a field's declared `as` off
7209
+ // whatever `schema.fields()` serves for its type) correctly permit the
7210
+ // abstract type itself to be pushed directly into this relationship.
7211
+ const abstractField = {
7212
+ ...field
7213
+ };
7214
+ const contribution = {
7215
+ field: abstractField,
7216
+ source: implementer
7217
+ };
7218
+
7219
+ // all concrete implementations of an abstract type are required to
7220
+ // share the same shape for the field that implements it, so the first
7221
+ // one registered is as good a canonical source as any - but a later,
7222
+ // differently-shaped one is almost certainly a mistake rather than an
7223
+ // intentional override, so we catch it rather than silently ignoring it.
7224
+ const existingImplementer = implementerFields.get(field.name);
7225
+ if (existingImplementer) {
7226
+ return;
7227
+ }
7228
+ implementerFields.set(field.name, contribution);
7229
+ let abstractSchema = this._schemas.get(abstractType);
7230
+ if (!abstractSchema) {
7231
+ abstractSchema = {
7232
+ original: {
7233
+ legacy: true,
7234
+ identity: {
7235
+ kind: '@id',
7236
+ name: 'id'
7237
+ },
7238
+ type: abstractType,
7239
+ fields: []
7240
+ },
7241
+ finalized: true,
7242
+ fields: new Map(),
7243
+ cacheFields: new Map(),
7244
+ relationships: {},
7245
+ attributes: {},
7246
+ traits: new Set()
7247
+ };
7248
+ this._schemas.set(abstractType, abstractSchema);
7249
+ }
7250
+ const existingAbstractField = abstractSchema.fields.get(field.name);
7251
+ if (existingAbstractField) {
7252
+ return;
7253
+ }
7254
+ abstractSchema.fields.set(field.name, abstractField);
7255
+ abstractSchema.relationships[field.name] = abstractField;
7256
+
7257
+ // If the schema is mid-finalization (traits pending), finalizeResource
7258
+ // will recompute cacheFields from the current `fields` map anyway; avoid
7259
+ // doing so prematurely from a partially-resolved set of fields.
7260
+ if (abstractSchema.finalized) {
7261
+ abstractSchema.cacheFields = getCacheFields(abstractSchema);
7262
+ }
7140
7263
  }
7141
7264
 
7142
7265
  /**
@@ -7780,7 +7903,29 @@ globalThis.setWarpDriveIsMaybeMirage = setIsMaybeMirage;
7780
7903
  */
7781
7904
  function useRecommendedStore(options, StoreKlass = Store) {
7782
7905
  return class AppStore extends StoreKlass {
7783
- requestManager = new RequestManager().use([...(options.handlers ?? []), Fetch]).useCache(CacheHandler);
7906
+ constructor(createArgs) {
7907
+ super(createArgs);
7908
+ // installed via defineProperty (rather than a class field/accessor) so that
7909
+ // this lazy override of the inherited `requestManager` field does not
7910
+ // conflict with the documented pattern of assigning it directly on
7911
+ // consumer-authored Store subclasses. The setter preserves the ability
7912
+ // to replace `requestManager` outright after construction.
7913
+ let requestManager;
7914
+ Object.defineProperty(this, 'requestManager', {
7915
+ configurable: true,
7916
+ enumerable: true,
7917
+ get: () => {
7918
+ if (!requestManager) {
7919
+ const handlers = typeof options.handlers === 'function' ? options.handlers(this) : options.handlers ?? [];
7920
+ requestManager = new RequestManager().use([...handlers, Fetch]).useCache(CacheHandler);
7921
+ }
7922
+ return requestManager;
7923
+ },
7924
+ set: value => {
7925
+ requestManager = value;
7926
+ }
7927
+ });
7928
+ }
7784
7929
  lifetimes = options.policy ?? new DefaultCachePolicy({
7785
7930
  apiCacheHardExpires: 15 * 60 * 1000,
7786
7931
  // 15 minutes
@@ -1,4 +1,4 @@
1
- export { C as CacheHandler, F as Fetch, x as RequestManager, b as Store, d as cacheKeyFor, d as recordIdentifierFor, B as setIdentifierForgetMethod, z as setIdentifierGenerationMethod, D as setIdentifierResetMethod, A as setIdentifierUpdateMethod, E as setKeyInfoForResource, s as storeFor, y as useRecommendedStore } from "./index-CZkDXZog.js";
1
+ export { C as CacheHandler, F as Fetch, x as RequestManager, b as Store, d as cacheKeyFor, d as recordIdentifierFor, B as setIdentifierForgetMethod, z as setIdentifierGenerationMethod, D as setIdentifierResetMethod, A as setIdentifierUpdateMethod, E as setKeyInfoForResource, s as storeFor, y as useRecommendedStore } from "./index-CplZl2hv.js";
2
2
  import './types/-private.js';
3
3
  import "./-leaked-BNVttukY.js";
4
4
  import './store.js';
@@ -1,4 +1,4 @@
1
- export { S as SchemaService, c as checkout, a as commit, f as fromIdentity, i as instantiateRecord, r as registerDerivations, t as teardownRecord, w as withDefaults } from "./index-CZkDXZog.js";
1
+ export { S as SchemaService, c as checkout, a as commit, f as fromIdentity, i as instantiateRecord, r as registerDerivations, t as teardownRecord, w as withDefaults } from "./index-CplZl2hv.js";
2
2
  export { C as Checkout } from "./-private-3C1OkYtZ.js";
3
3
  export { c as createRequestSubscription, a as getPromiseState, g as getRequestState } from "./-leaked-BNVttukY.js";
4
4
  import './types/-private.js';
@@ -1,4 +1,4 @@
1
- export { C as CacheHandler, R as RecordArrayManager, b as Store, q as StoreMap, _ as _clearCaches, u as _deprecatingNormalize, o as assertPrivateCapabilities, m as assertPrivateStore, j as coerceId, h as constructResource, v as createLegacyManyArray, k as ensureStringId, l as fastPush, n as isPrivateStore, g as isRequestKey, e as isResourceKey, d as recordIdentifierFor, p as setRecordIdentifier, s as storeFor } from "../index-CZkDXZog.js";
1
+ export { C as CacheHandler, R as RecordArrayManager, b as Store, q as StoreMap, _ as _clearCaches, u as _deprecatingNormalize, o as assertPrivateCapabilities, m as assertPrivateStore, j as coerceId, h as constructResource, v as createLegacyManyArray, k as ensureStringId, l as fastPush, n as isPrivateStore, g as isRequestKey, e as isResourceKey, d as recordIdentifierFor, p as setRecordIdentifier, s as storeFor } from "../index-CplZl2hv.js";
2
2
  const TEXT_COLORS = {
3
3
  TEXT: 'inherit',
4
4
  notify: ['white', 'white', 'inherit', 'magenta', 'inherit'],
@@ -1,5 +1,5 @@
1
1
  const name = "@warp-drive/core";
2
- const version = "5.9.0-alpha.18";
2
+ const version = "5.9.0-alpha.19";
3
3
 
4
4
  // in testing mode, we utilize globals to ensure only one copy exists of
5
5
  // these maps, due to bugs in ember-auto-import
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warp-drive/core",
3
- "version": "5.9.0-alpha.18",
3
+ "version": "5.9.0-alpha.19",
4
4
  "description": "Core package for WarpDrive | All the Universal Basics",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -45,13 +45,13 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@embroider/macros": "^1.19.6",
48
- "@warp-drive/build-config": "5.9.0-alpha.18"
48
+ "@warp-drive/build-config": "5.9.0-alpha.19"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@babel/core": "^7.28.3",
52
52
  "@babel/plugin-transform-typescript": "^7.28.0",
53
53
  "@babel/preset-typescript": "^7.27.1",
54
- "@warp-drive/internal-config": "5.9.0-alpha.18",
54
+ "@warp-drive/internal-config": "5.9.0-alpha.19",
55
55
  "decorator-transforms": "^2.3.0",
56
56
  "ember-source": "~6.12.0",
57
57
  "expect-type": "^1.2.2",