@warp-drive-mirror/json-api 5.8.0-alpha.9 → 5.8.0-beta.1

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/README.md CHANGED
@@ -1,41 +1,28 @@
1
- <h1 align="center">
2
- <img
3
- class="project-logo"
4
- src="./logos/github-header.svg#gh-light-mode-only"
5
- alt="WarpDrive | Boldly go where no app has gone before"
6
- title="WarpDrive | Boldly go where no app has gone before"
7
- />
1
+ <p align="center">
8
2
  <img
9
3
  class="project-logo"
10
- src="./logos/github-header.svg#gh-dark-mode-only"
11
- alt="WarpDrive | Boldly go where no app has gone before"
12
- title="WarpDrive | Boldly go where no app has gone before"
4
+ src="./logos/logo-yellow-slab.svg"
5
+ alt="WarpDrive"
6
+ width="180px"
7
+ title="WarpDrive"
13
8
  />
14
- </h1>
9
+ </p>
15
10
 
16
- ![NPM Stable Version](https://img.shields.io/npm/v/ember-data/latest?label=version&style=flat&color=FFC474)
17
- ![NPM Downloads](https://img.shields.io/npm/dm/ember-data.svg?style=flat&color=FFC474)
18
- ![License](https://img.shields.io/github/license/emberjs/data.svg?style=flat&color=FFC474)
19
- [![Docs](./logos/docs-badge.svg)](https://docs.warp-drive.io)
20
- [![EmberJS Discord Community Server](https://img.shields.io/badge/EmberJS-grey?logo=discord&logoColor=FFC474)](https://discord.gg/zT3asNS
11
+ ![NPM Stable Version](https://img.shields.io/npm/v/ember-data/latest?label=version&style=flat&color=fdb155)
12
+ ![NPM Downloads](https://img.shields.io/npm/dm/ember-data.svg?style=flat&color=fdb155)
13
+ ![License](https://img.shields.io/github/license/warp-drive-data/warp-drive.svg?style=flat&color=fdb155)
14
+ [![EmberJS Discord Community Server](https://img.shields.io/badge/EmberJS-grey?logo=discord&logoColor=fdb155)](https://discord.gg/zT3asNS
21
15
  )
22
- [![WarpDrive Discord Server](https://img.shields.io/badge/WarpDrive-grey?logo=discord&logoColor=FFC474)](https://discord.gg/PHBbnWJx5S
16
+ [![WarpDrive Discord Server](https://img.shields.io/badge/WarpDrive-grey?logo=discord&logoColor=fdb155)](https://discord.gg/PHBbnWJx5S
23
17
  )
24
18
 
19
+ # @warp-drive-mirror/json-api
25
20
 
26
- <br>
27
-
28
- <p align="center">
29
- A {json:api} Cache Implementation for <em>Warp</em><strong>Drive</strong>.
30
- </p>
31
-
32
- <br>
21
+ A {json:api} Cache Implementation for ***Warp*Drive**.
33
22
 
34
- ## Installation
23
+ `{json:api}` excels at simplifying common complex problems around cache consistency and information density, especially in regards to relational or polymorphic data.
35
24
 
36
- ```sh
37
- pnpm add -E @warp-drive-mirror/json-api
38
- ```
25
+ Because most API responses can be quickly transformed into the `{json:api}` format without losing any information, ***Warp*Drive** recommends that most-if-not-all apps should use this Cache implementation.
39
26
 
40
27
  <br>
41
28
 
@@ -48,7 +35,7 @@ pnpm add -E @warp-drive-mirror/json-api
48
35
 
49
36
  ## Code of Conduct
50
37
 
51
- Refer to the [Code of Conduct](https://github.com/emberjs/data/blob/main/CODE_OF_CONDUCT.md) for community guidelines and inclusivity.
38
+ Refer to the [Code of Conduct](https://github.com/warp-drive-data/warp-drive/blob/main/CODE_OF_CONDUCT.md) for community guidelines and inclusivity.
52
39
 
53
40
  <br>
54
41
 
@@ -124,6 +124,15 @@ export declare class JSONAPICache implements Cache {
124
124
  * of the Graph handling necessary entanglements and
125
125
  * notifications for relational data.
126
126
  *
127
+ * :::warning
128
+ * It is not recommended to use the return value as
129
+ * a serialized representation of the resource both
130
+ * due to it containing local mutations and because
131
+ * it may contain additional fields not recognized
132
+ * by the {json:api} API implementation such as `lid` and
133
+ * the various internal WarpDrive bookkeeping fields.
134
+ * :::
135
+ *
127
136
  * @category Cache Management
128
137
  * @public
129
138
  */
package/dist/index.js CHANGED
@@ -196,7 +196,10 @@ class Reporter {
196
196
  const allFields = this.schema.fields({
197
197
  type
198
198
  });
199
- const attrs = Array.from(allFields.values()).filter(isRemoteField).map(v => v.name);
199
+ const allCacheFields = this.schema.cacheFields?.({
200
+ type
201
+ }) ?? allFields;
202
+ const attrs = Array.from(allCacheFields.values()).filter(isRemoteField).map(v => v.name);
200
203
  this._fieldFilters.set(type, new Fuse(attrs));
201
204
  }
202
205
  const result = this._fieldFilters.get(type).search(field);
@@ -786,12 +789,15 @@ function validateTopLevelResourceShape(reporter, resource, path) {
786
789
  }
787
790
  }
788
791
  function validateResourceAttributes(reporter, type, resource, path) {
789
- const schema = reporter.schema.fields({
792
+ const fields = reporter.schema.fields({
790
793
  type
791
794
  });
795
+ const cacheFields = reporter.schema.cacheFields?.({
796
+ type
797
+ }) ?? fields;
792
798
  for (const [key] of Object.entries(resource)) {
793
- const field = getRemoteField(schema, key);
794
- const actualField = schema.get(key);
799
+ const field = getRemoteField(cacheFields, key);
800
+ const actualField = cacheFields.get(key);
795
801
  if (!field && actualField) {
796
802
  reporter.warn([...path, key], `Expected the ${actualField.kind} field "${key}" to not have its own data in the ResourceObject's attributes. Likely this field should either not be returned in this payload or the field definition should be updated in the schema.`);
797
803
  } else if (!field) {
@@ -1279,6 +1285,15 @@ class JSONAPICache {
1279
1285
  * of the Graph handling necessary entanglements and
1280
1286
  * notifications for relational data.
1281
1287
  *
1288
+ * :::warning
1289
+ * It is not recommended to use the return value as
1290
+ * a serialized representation of the resource both
1291
+ * due to it containing local mutations and because
1292
+ * it may contain additional fields not recognized
1293
+ * by the {json:api} API implementation such as `lid` and
1294
+ * the various internal WarpDrive bookkeeping fields.
1295
+ * :::
1296
+ *
1282
1297
  * @category Cache Management
1283
1298
  * @public
1284
1299
  */
@@ -1294,7 +1309,7 @@ class JSONAPICache {
1294
1309
  id,
1295
1310
  lid
1296
1311
  } = identifier;
1297
- const attributes = Object.assign({}, peeked.remoteAttrs, peeked.inflightAttrs, peeked.localAttrs);
1312
+ const attributes = structuredClone(Object.assign({}, peeked.remoteAttrs, peeked.inflightAttrs, peeked.localAttrs));
1298
1313
  const relationships = {};
1299
1314
  const rels = this.__graph.identifiers.get(identifier);
1300
1315
  if (rels) {
@@ -1352,7 +1367,7 @@ class JSONAPICache {
1352
1367
  id,
1353
1368
  lid
1354
1369
  } = identifier;
1355
- const attributes = Object.assign({}, peeked.remoteAttrs);
1370
+ const attributes = structuredClone(peeked.remoteAttrs);
1356
1371
  const relationships = {};
1357
1372
  const rels = this.__graph.identifiers.get(identifier);
1358
1373
  if (rels) {
@@ -1361,7 +1376,7 @@ class JSONAPICache {
1361
1376
  if (rel.definition.isImplicit) {
1362
1377
  return;
1363
1378
  } else {
1364
- relationships[key] = this.__graph.getData(identifier, key);
1379
+ relationships[key] = structuredClone(this.__graph.getData(identifier, key));
1365
1380
  }
1366
1381
  });
1367
1382
  }
@@ -3053,7 +3068,10 @@ function patchCache(Cache, op) {
3053
3068
  }
3054
3069
  function getCacheFields(cache, identifier) {
3055
3070
  if (cache._capabilities.schema.cacheFields) {
3056
- return cache._capabilities.schema.cacheFields(identifier);
3071
+ const result = cache._capabilities.schema.cacheFields(identifier);
3072
+ if (result) {
3073
+ return result;
3074
+ }
3057
3075
  }
3058
3076
 
3059
3077
  // the model schema service cannot process fields that are not cache fields
@@ -3092,12 +3110,13 @@ function didCommit(cache, committedIdentifier, data, op) {
3092
3110
  const existingId = committedIdentifier.id;
3093
3111
  const identifier = op !== 'deleteRecord' && data ? cacheKeyManager.updateRecordIdentifier(committedIdentifier, data) : committedIdentifier;
3094
3112
  const cached = cache.__peek(identifier, false);
3095
- if (cached.isDeleted) {
3113
+ if (cached.isDeleted || op === 'deleteRecord') {
3096
3114
  cache.__graph.push({
3097
3115
  op: 'deleteRecord',
3098
3116
  record: identifier,
3099
3117
  isNew: false
3100
3118
  });
3119
+ cached.isDeleted = true;
3101
3120
  cached.isDeletionCommitted = true;
3102
3121
  cache._capabilities.notifyChange(identifier, 'removed', null);
3103
3122
  // TODO @runspired should we early exit here?