@warp-drive-mirror/json-api 5.6.0-alpha.11 → 5.6.0-alpha.13
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/declarations/-private/cache.d.ts +154 -99
- package/declarations/-private/cache.d.ts.map +1 -1
- package/dist/index.js +188 -113
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { logGroup, isStableIdentifier, isDocumentIdentifier } from '@warp-drive-
|
|
|
3
3
|
import Fuse from 'fuse.js';
|
|
4
4
|
import jsonToAst from 'json-to-ast';
|
|
5
5
|
import { macroCondition, getGlobalConfig } from '@embroider/macros';
|
|
6
|
+
|
|
6
7
|
function validateDocumentFields(schema, jsonApiDoc) {
|
|
7
8
|
const {
|
|
8
9
|
data,
|
|
@@ -97,6 +98,7 @@ function validateHasManyToLinksMode(resourceType, field, _relationshipDoc, _opti
|
|
|
97
98
|
throw new Error(`Cannot fetch ${resourceType}.${field.name} because the field is in linksMode but async hasMany is not yet supported`);
|
|
98
99
|
}
|
|
99
100
|
}
|
|
101
|
+
|
|
100
102
|
function inspectType(obj) {
|
|
101
103
|
if (obj === null) {
|
|
102
104
|
return 'null';
|
|
@@ -424,6 +426,7 @@ function getRemoteField(fields, key) {
|
|
|
424
426
|
}
|
|
425
427
|
return field;
|
|
426
428
|
}
|
|
429
|
+
|
|
427
430
|
const VALID_TOP_LEVEL_MEMBERS = ['data', 'included', 'meta', 'jsonapi', 'links'];
|
|
428
431
|
|
|
429
432
|
/**
|
|
@@ -534,6 +537,7 @@ function validateTopLevelDocumentMembers(reporter, doc) {
|
|
|
534
537
|
}
|
|
535
538
|
}
|
|
536
539
|
}
|
|
540
|
+
|
|
537
541
|
const VALID_COLLECTION_LINKS = ['self', 'related', 'first', 'last', 'prev', 'next'];
|
|
538
542
|
const VALID_RESOURCE_RELATIONSHIP_LINKS = ['self', 'related'];
|
|
539
543
|
const VALID_RESOURCE_LINKS = ['self'];
|
|
@@ -575,7 +579,7 @@ function validateLinks(reporter, doc, type, path = ['links']) {
|
|
|
575
579
|
reporter.warn([...path, key], `Unrecognized top-level link. The data it provides may be ignored as it is not a valid {JSON:API} link for a ${type}`);
|
|
576
580
|
}
|
|
577
581
|
// links may be either a string or an object with an href property or null
|
|
578
|
-
if (links[key] === null) ;else if (typeof links[key] === 'string') {
|
|
582
|
+
if (links[key] === null) ; else if (typeof links[key] === 'string') {
|
|
579
583
|
if (links[key].length === 0) {
|
|
580
584
|
reporter.warn([...path, key], `Expected a non-empty string, but received an empty string`);
|
|
581
585
|
}
|
|
@@ -608,6 +612,7 @@ function validateLinks(reporter, doc, type, path = ['links']) {
|
|
|
608
612
|
}
|
|
609
613
|
}
|
|
610
614
|
}
|
|
615
|
+
|
|
611
616
|
const SINGULAR_OPS = ['createRecord', 'updateRecord', 'deleteRecord', 'findRecord', 'queryRecord'];
|
|
612
617
|
|
|
613
618
|
/**
|
|
@@ -850,6 +855,7 @@ function validateResourceRelationships(reporter, type, resource, path) {
|
|
|
850
855
|
// TODO @runspired we should warn if the discovered resource-type in a relationship is the abstract
|
|
851
856
|
// type instead of the concrete type.
|
|
852
857
|
}
|
|
858
|
+
|
|
853
859
|
function validateDocument(capabilities, doc) {
|
|
854
860
|
macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
|
|
855
861
|
if (!test) {
|
|
@@ -917,6 +923,7 @@ function validateResourceDocument(reporter, doc) {
|
|
|
917
923
|
|
|
918
924
|
reporter.report();
|
|
919
925
|
}
|
|
926
|
+
|
|
920
927
|
function isImplicit(relationship) {
|
|
921
928
|
return relationship.definition.isImplicit;
|
|
922
929
|
}
|
|
@@ -949,26 +956,95 @@ function makeCache() {
|
|
|
949
956
|
}
|
|
950
957
|
|
|
951
958
|
/**
|
|
952
|
-
|
|
959
|
+
* ### JSONAPICache
|
|
960
|
+
*
|
|
961
|
+
* ```ts
|
|
962
|
+
* import { JSONAPICache } from '@warp-drive-mirror/json-api';
|
|
963
|
+
* ```
|
|
964
|
+
*
|
|
965
|
+
A {@link Cache} implementation tuned for [{json:api}](https://jsonapi.org/)
|
|
953
966
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
967
|
+
This format excels at simiplifying common complex problems around cache
|
|
968
|
+
consistency and information density. Because most API responses can be quickly
|
|
969
|
+
transformed into {json:api} format without losing any information, WarpDrive
|
|
970
|
+
recommends that most apps use this Cache implementation.
|
|
957
971
|
|
|
958
|
-
|
|
972
|
+
If a cache built to understand another format would do better for your app then
|
|
973
|
+
it just needs to follow the same interface.
|
|
959
974
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
975
|
+
Do you really need a cache? Are sunsets beautiful? Caching is what powers features like
|
|
976
|
+
immutability, mutation management, and allows ***Warp*Drive** to understand your relational
|
|
977
|
+
data.
|
|
963
978
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
979
|
+
Some caches are simple request/response maps. ***Warp*Drive**'s is not. The Cache deeply
|
|
980
|
+
understands the structure of your data, ensuring your data remains consistent both within
|
|
981
|
+
and across requests.
|
|
982
|
+
|
|
983
|
+
### Installation
|
|
984
|
+
|
|
985
|
+
::: code-group
|
|
986
|
+
|
|
987
|
+
```sh [pnpm]
|
|
988
|
+
pnpm add -E @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
```sh [npm]
|
|
992
|
+
npm add -E @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
```sh [yarn]
|
|
996
|
+
yarn add -E @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
```sh [bun]
|
|
1000
|
+
bun add --exact @warp-drive-mirror/core@latest @warp-drive-mirror/json-api@latest
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
:::
|
|
1004
|
+
|
|
1005
|
+
### Setup
|
|
1006
|
+
|
|
1007
|
+
```ts [services/store.ts]
|
|
1008
|
+
import { Fetch, RequestManager, Store } from '@warp-drive-mirror/core';
|
|
1009
|
+
import {
|
|
1010
|
+
registerDerivations,
|
|
1011
|
+
SchemaService,
|
|
1012
|
+
} from '@warp-drive-mirror/core/reactive';
|
|
1013
|
+
import { CacheHandler } from '@warp-drive-mirror/core/store';
|
|
1014
|
+
import type { CacheCapabilitiesManager } from '@warp-drive-mirror/core/types'; // [!code focus:2]
|
|
1015
|
+
import { JSONAPICache } from '@warp-drive-mirror/json-api';
|
|
1016
|
+
|
|
1017
|
+
export default class AppStore extends Store {
|
|
1018
|
+
|
|
1019
|
+
requestManager = new RequestManager()
|
|
1020
|
+
.use([Fetch])
|
|
1021
|
+
.useCache(CacheHandler);
|
|
1022
|
+
|
|
1023
|
+
createSchemaService() {
|
|
1024
|
+
const schema = new SchemaService();
|
|
1025
|
+
registerDerivations(schema);
|
|
1026
|
+
return schema;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
createCache(capabilities: CacheCapabilitiesManager) { // [!code focus:3]
|
|
1030
|
+
return new JSONAPICache(capabilities);
|
|
967
1031
|
}
|
|
968
1032
|
}
|
|
969
1033
|
```
|
|
970
1034
|
|
|
971
|
-
|
|
1035
|
+
* @categoryDescription Cache Management
|
|
1036
|
+
* APIs for primary cache management functionality
|
|
1037
|
+
* @categoryDescription Cache Forking
|
|
1038
|
+
* APIs that support Cache Forking
|
|
1039
|
+
* @categoryDescription SSR Support
|
|
1040
|
+
* APIs that support SSR functionality
|
|
1041
|
+
* @categoryDescription Resource Lifecycle
|
|
1042
|
+
* APIs that support management of resource data
|
|
1043
|
+
* @categoryDescription Resource Data
|
|
1044
|
+
* APIs that support granular field level management of resource data
|
|
1045
|
+
* @categoryDescription Resource State
|
|
1046
|
+
* APIs that support managing Resource states
|
|
1047
|
+
|
|
972
1048
|
@public
|
|
973
1049
|
*/
|
|
974
1050
|
|
|
@@ -976,9 +1052,7 @@ class JSONAPICache {
|
|
|
976
1052
|
/**
|
|
977
1053
|
* The Cache Version that this implementation implements.
|
|
978
1054
|
*
|
|
979
|
-
* @type {'2'}
|
|
980
1055
|
* @public
|
|
981
|
-
* @property version
|
|
982
1056
|
*/
|
|
983
1057
|
|
|
984
1058
|
/** @internal */
|
|
@@ -1000,8 +1074,9 @@ class JSONAPICache {
|
|
|
1000
1074
|
this.__documents = new Map();
|
|
1001
1075
|
}
|
|
1002
1076
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1077
|
+
////////// ================ //////////
|
|
1078
|
+
////////// Cache Management //////////
|
|
1079
|
+
////////// ================ //////////
|
|
1005
1080
|
|
|
1006
1081
|
/**
|
|
1007
1082
|
* Cache the response to a request
|
|
@@ -1037,8 +1112,7 @@ class JSONAPICache {
|
|
|
1037
1112
|
* associated resource membership order and contents preserved but linked
|
|
1038
1113
|
* into the cache.
|
|
1039
1114
|
*
|
|
1040
|
-
* @
|
|
1041
|
-
* @return {ResourceDocument}
|
|
1115
|
+
* @category Cache Management
|
|
1042
1116
|
* @public
|
|
1043
1117
|
*/
|
|
1044
1118
|
|
|
@@ -1186,9 +1260,9 @@ class JSONAPICache {
|
|
|
1186
1260
|
* Update the "remote" or "canonical" (persisted) state of the Cache
|
|
1187
1261
|
* by merging new information into the existing state.
|
|
1188
1262
|
*
|
|
1263
|
+
* @category Cache Management
|
|
1189
1264
|
* @public
|
|
1190
|
-
* @param
|
|
1191
|
-
* @return {void}
|
|
1265
|
+
* @param op the operation or list of operations to perform
|
|
1192
1266
|
*/
|
|
1193
1267
|
patch(op) {
|
|
1194
1268
|
if (Array.isArray(op)) {
|
|
@@ -1217,8 +1291,7 @@ class JSONAPICache {
|
|
|
1217
1291
|
/**
|
|
1218
1292
|
* Update the "local" or "current" (unpersisted) state of the Cache
|
|
1219
1293
|
*
|
|
1220
|
-
* @
|
|
1221
|
-
* @return {void}
|
|
1294
|
+
* @category Cache Management
|
|
1222
1295
|
* @public
|
|
1223
1296
|
*/
|
|
1224
1297
|
mutate(mutation) {
|
|
@@ -1271,9 +1344,8 @@ class JSONAPICache {
|
|
|
1271
1344
|
* of the Graph handling necessary entanglements and
|
|
1272
1345
|
* notifications for relational data.
|
|
1273
1346
|
*
|
|
1347
|
+
* @category Cache Management
|
|
1274
1348
|
* @public
|
|
1275
|
-
* @param {StableRecordIdentifier | StableDocumentIdentifier} identifier
|
|
1276
|
-
* @return {ResourceDocument | ResourceObject | null} the known resource data
|
|
1277
1349
|
*/
|
|
1278
1350
|
|
|
1279
1351
|
peek(identifier) {
|
|
@@ -1329,6 +1401,14 @@ class JSONAPICache {
|
|
|
1329
1401
|
}
|
|
1330
1402
|
return null;
|
|
1331
1403
|
}
|
|
1404
|
+
|
|
1405
|
+
/**
|
|
1406
|
+
* Peek the remote resource data from the Cache.
|
|
1407
|
+
*
|
|
1408
|
+
* @category Cache Management
|
|
1409
|
+
* @public
|
|
1410
|
+
*/
|
|
1411
|
+
|
|
1332
1412
|
peekRemoteState(identifier) {
|
|
1333
1413
|
if ('type' in identifier) {
|
|
1334
1414
|
const peeked = this.__safePeek(identifier, false);
|
|
@@ -1379,6 +1459,7 @@ class JSONAPICache {
|
|
|
1379
1459
|
}
|
|
1380
1460
|
return null;
|
|
1381
1461
|
}
|
|
1462
|
+
|
|
1382
1463
|
/**
|
|
1383
1464
|
* Peek the Cache for the existing request data associated with
|
|
1384
1465
|
* a cacheable request.
|
|
@@ -1387,8 +1468,7 @@ class JSONAPICache {
|
|
|
1387
1468
|
* that it will return the the request, response, and content
|
|
1388
1469
|
* whereas `peek` will return just the `content`.
|
|
1389
1470
|
*
|
|
1390
|
-
* @
|
|
1391
|
-
* @return {StructuredDocument<ResourceDocument> | null}
|
|
1471
|
+
* @category Cache Management
|
|
1392
1472
|
* @public
|
|
1393
1473
|
*/
|
|
1394
1474
|
peekRequest(identifier) {
|
|
@@ -1398,11 +1478,9 @@ class JSONAPICache {
|
|
|
1398
1478
|
/**
|
|
1399
1479
|
* Push resource data from a remote source into the cache for this identifier
|
|
1400
1480
|
*
|
|
1481
|
+
* @category Cache Management
|
|
1401
1482
|
* @public
|
|
1402
|
-
* @
|
|
1403
|
-
* @param data
|
|
1404
|
-
* @param hasRecord
|
|
1405
|
-
* @return {void | string[]} if `hasRecord` is true then calculated key changes should be returned
|
|
1483
|
+
* @return if `calculateChanges` is true then calculated key changes should be returned
|
|
1406
1484
|
*/
|
|
1407
1485
|
upsert(identifier, data, calculateChanges) {
|
|
1408
1486
|
upgradeCapabilities(this._capabilities);
|
|
@@ -1417,8 +1495,9 @@ class JSONAPICache {
|
|
|
1417
1495
|
return cacheUpsert(this, identifier, data, calculateChanges);
|
|
1418
1496
|
}
|
|
1419
1497
|
|
|
1420
|
-
|
|
1421
|
-
|
|
1498
|
+
////////// ============= //////////
|
|
1499
|
+
////////// Cache Forking //////////
|
|
1500
|
+
////////// ============= //////////
|
|
1422
1501
|
|
|
1423
1502
|
/**
|
|
1424
1503
|
* Create a fork of the cache from the current state.
|
|
@@ -1427,8 +1506,8 @@ class JSONAPICache {
|
|
|
1427
1506
|
* preferring instead to fork at the Store level, which will
|
|
1428
1507
|
* utilize this method to fork the cache.
|
|
1429
1508
|
*
|
|
1509
|
+
* @category Cache Forking
|
|
1430
1510
|
* @internal
|
|
1431
|
-
* @return {Promise<Cache>}
|
|
1432
1511
|
*/
|
|
1433
1512
|
fork() {
|
|
1434
1513
|
throw new Error(`Not Implemented`);
|
|
@@ -1441,11 +1520,10 @@ class JSONAPICache {
|
|
|
1441
1520
|
* preferring instead to merge at the Store level, which will
|
|
1442
1521
|
* utilize this method to merge the caches.
|
|
1443
1522
|
*
|
|
1444
|
-
* @
|
|
1445
|
-
* @
|
|
1446
|
-
* @return {Promise<void>}
|
|
1523
|
+
* @category Cache Forking
|
|
1524
|
+
* @internal
|
|
1447
1525
|
*/
|
|
1448
|
-
merge(
|
|
1526
|
+
merge(_cache) {
|
|
1449
1527
|
throw new Error(`Not Implemented`);
|
|
1450
1528
|
}
|
|
1451
1529
|
|
|
@@ -1479,22 +1557,24 @@ class JSONAPICache {
|
|
|
1479
1557
|
* }
|
|
1480
1558
|
* ```
|
|
1481
1559
|
*
|
|
1482
|
-
* @
|
|
1560
|
+
* @category Cache Forking
|
|
1561
|
+
* @internal
|
|
1483
1562
|
*/
|
|
1484
1563
|
diff() {
|
|
1485
1564
|
throw new Error(`Not Implemented`);
|
|
1486
1565
|
}
|
|
1487
1566
|
|
|
1488
|
-
|
|
1489
|
-
|
|
1567
|
+
////////// =========== //////////
|
|
1568
|
+
////////// SSR Support //////////
|
|
1569
|
+
////////// =========== //////////
|
|
1490
1570
|
|
|
1491
1571
|
/**
|
|
1492
1572
|
* Serialize the entire contents of the Cache into a Stream
|
|
1493
1573
|
* which may be fed back into a new instance of the same Cache
|
|
1494
1574
|
* via `cache.hydrate`.
|
|
1495
1575
|
*
|
|
1496
|
-
* @
|
|
1497
|
-
* @
|
|
1576
|
+
* @category SSR Support
|
|
1577
|
+
* @internal
|
|
1498
1578
|
*/
|
|
1499
1579
|
dump() {
|
|
1500
1580
|
throw new Error(`Not Implemented`);
|
|
@@ -1512,16 +1592,16 @@ class JSONAPICache {
|
|
|
1512
1592
|
* behavior supports optimizing pre/fetching of data for route transitions
|
|
1513
1593
|
* via data-only SSR modes.
|
|
1514
1594
|
*
|
|
1515
|
-
* @
|
|
1516
|
-
* @
|
|
1517
|
-
* @public
|
|
1595
|
+
* @category SSR Support
|
|
1596
|
+
* @internal
|
|
1518
1597
|
*/
|
|
1519
1598
|
hydrate(stream) {
|
|
1520
1599
|
throw new Error('Not Implemented');
|
|
1521
1600
|
}
|
|
1522
1601
|
|
|
1523
|
-
|
|
1524
|
-
|
|
1602
|
+
////////// ================== //////////
|
|
1603
|
+
////////// Resource Lifecycle //////////
|
|
1604
|
+
////////// ================== //////////
|
|
1525
1605
|
|
|
1526
1606
|
/**
|
|
1527
1607
|
* [LIFECYCLE] Signal to the cache that a new record has been instantiated on the client
|
|
@@ -1529,9 +1609,8 @@ class JSONAPICache {
|
|
|
1529
1609
|
* It returns properties from options that should be set on the record during the create
|
|
1530
1610
|
* process. This return value behavior is deprecated.
|
|
1531
1611
|
*
|
|
1612
|
+
* @category Resource Lifecycle
|
|
1532
1613
|
* @public
|
|
1533
|
-
* @param identifier
|
|
1534
|
-
* @param createArgs
|
|
1535
1614
|
*/
|
|
1536
1615
|
clientDidCreate(identifier, options) {
|
|
1537
1616
|
if (macroCondition(getGlobalConfig().WarpDriveMirror.activeLogging.LOG_CACHE)) {
|
|
@@ -1604,8 +1683,8 @@ class JSONAPICache {
|
|
|
1604
1683
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
1605
1684
|
* will be part of a save transaction.
|
|
1606
1685
|
*
|
|
1686
|
+
* @category Resource Lifecycle
|
|
1607
1687
|
* @public
|
|
1608
|
-
* @param identifier
|
|
1609
1688
|
*/
|
|
1610
1689
|
willCommit(identifier) {
|
|
1611
1690
|
const cached = this.__peek(identifier, false);
|
|
@@ -1659,9 +1738,8 @@ class JSONAPICache {
|
|
|
1659
1738
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
1660
1739
|
* was successfully updated as part of a save transaction.
|
|
1661
1740
|
*
|
|
1741
|
+
* @category Resource Lifecycle
|
|
1662
1742
|
* @public
|
|
1663
|
-
* @param identifier
|
|
1664
|
-
* @param data
|
|
1665
1743
|
*/
|
|
1666
1744
|
didCommit(committedIdentifier, result) {
|
|
1667
1745
|
const payload = result.content;
|
|
@@ -1781,9 +1859,8 @@ class JSONAPICache {
|
|
|
1781
1859
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
1782
1860
|
* was update via a save transaction failed.
|
|
1783
1861
|
*
|
|
1862
|
+
* @category Resource Lifecycle
|
|
1784
1863
|
* @public
|
|
1785
|
-
* @param identifier
|
|
1786
|
-
* @param errors
|
|
1787
1864
|
*/
|
|
1788
1865
|
commitWasRejected(identifier, errors) {
|
|
1789
1866
|
const cached = this.__peek(identifier, false);
|
|
@@ -1811,8 +1888,8 @@ class JSONAPICache {
|
|
|
1811
1888
|
*
|
|
1812
1889
|
* This method is a candidate to become a mutation
|
|
1813
1890
|
*
|
|
1891
|
+
* @category Resource Lifecycle
|
|
1814
1892
|
* @public
|
|
1815
|
-
* @param identifier
|
|
1816
1893
|
*/
|
|
1817
1894
|
unloadRecord(identifier) {
|
|
1818
1895
|
const storeWrapper = this._capabilities;
|
|
@@ -1881,16 +1958,16 @@ class JSONAPICache {
|
|
|
1881
1958
|
}
|
|
1882
1959
|
}
|
|
1883
1960
|
|
|
1884
|
-
|
|
1885
|
-
|
|
1961
|
+
////////// ============= //////////
|
|
1962
|
+
////////// Resource Data //////////
|
|
1963
|
+
////////// ============= //////////
|
|
1886
1964
|
|
|
1887
1965
|
/**
|
|
1888
1966
|
* Retrieve the data for an attribute from the cache
|
|
1967
|
+
* with local mutations applied.
|
|
1889
1968
|
*
|
|
1969
|
+
* @category Resource Data
|
|
1890
1970
|
* @public
|
|
1891
|
-
* @param identifier
|
|
1892
|
-
* @param field
|
|
1893
|
-
* @return {unknown}
|
|
1894
1971
|
*/
|
|
1895
1972
|
getAttr(identifier, attr) {
|
|
1896
1973
|
const isSimplePath = !Array.isArray(attr) || attr.length === 1;
|
|
@@ -1954,6 +2031,13 @@ class JSONAPICache {
|
|
|
1954
2031
|
}
|
|
1955
2032
|
return current;
|
|
1956
2033
|
}
|
|
2034
|
+
|
|
2035
|
+
/**
|
|
2036
|
+
* Retrieve the remote data for an attribute from the cache
|
|
2037
|
+
*
|
|
2038
|
+
* @category Resource Data
|
|
2039
|
+
* @public
|
|
2040
|
+
*/
|
|
1957
2041
|
getRemoteAttr(identifier, attr) {
|
|
1958
2042
|
const isSimplePath = !Array.isArray(attr) || attr.length === 1;
|
|
1959
2043
|
if (Array.isArray(attr) && attr.length === 1) {
|
|
@@ -2014,10 +2098,8 @@ class JSONAPICache {
|
|
|
2014
2098
|
*
|
|
2015
2099
|
* This method is a candidate to become a mutation
|
|
2016
2100
|
*
|
|
2101
|
+
* @category Resource Data
|
|
2017
2102
|
* @public
|
|
2018
|
-
* @param identifier
|
|
2019
|
-
* @param field
|
|
2020
|
-
* @param value
|
|
2021
2103
|
*/
|
|
2022
2104
|
setAttr(identifier, attr, value) {
|
|
2023
2105
|
// this assert works to ensure we have a non-empty string and/or a non-empty array
|
|
@@ -2113,9 +2195,9 @@ class JSONAPICache {
|
|
|
2113
2195
|
/**
|
|
2114
2196
|
* Query the cache for the changed attributes of a resource.
|
|
2115
2197
|
*
|
|
2198
|
+
* @category Resource Data
|
|
2116
2199
|
* @public
|
|
2117
|
-
* @
|
|
2118
|
-
* @return {ChangedAttributesHash} `{ <field>: [<old>, <new>] }`
|
|
2200
|
+
* @return `{ '<field>': ['<old>', '<new>'] }`
|
|
2119
2201
|
*/
|
|
2120
2202
|
changedAttrs(identifier) {
|
|
2121
2203
|
const cached = this.__peek(identifier, false);
|
|
@@ -2138,9 +2220,8 @@ class JSONAPICache {
|
|
|
2138
2220
|
/**
|
|
2139
2221
|
* Query the cache for whether any mutated attributes exist
|
|
2140
2222
|
*
|
|
2223
|
+
* @category Resource Data
|
|
2141
2224
|
* @public
|
|
2142
|
-
* @param identifier
|
|
2143
|
-
* @return {Boolean}
|
|
2144
2225
|
*/
|
|
2145
2226
|
hasChangedAttrs(identifier) {
|
|
2146
2227
|
const cached = this.__peek(identifier, true);
|
|
@@ -2163,9 +2244,9 @@ class JSONAPICache {
|
|
|
2163
2244
|
*
|
|
2164
2245
|
* This method is a candidate to become a mutation
|
|
2165
2246
|
*
|
|
2247
|
+
* @category Resource Data
|
|
2166
2248
|
* @public
|
|
2167
|
-
* @
|
|
2168
|
-
* @return {String[]} the names of fields that were restored
|
|
2249
|
+
* @return the names of fields that were restored
|
|
2169
2250
|
*/
|
|
2170
2251
|
rollbackAttrs(identifier) {
|
|
2171
2252
|
const cached = this.__peek(identifier, false);
|
|
@@ -2196,31 +2277,30 @@ class JSONAPICache {
|
|
|
2196
2277
|
}
|
|
2197
2278
|
|
|
2198
2279
|
/**
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2280
|
+
* Query the cache for the changes to relationships of a resource.
|
|
2281
|
+
*
|
|
2282
|
+
* Returns a map of relationship names to RelationshipDiff objects.
|
|
2283
|
+
*
|
|
2284
|
+
* ```ts
|
|
2285
|
+
* type RelationshipDiff =
|
|
2286
|
+
| {
|
|
2206
2287
|
kind: 'collection';
|
|
2207
2288
|
remoteState: StableRecordIdentifier[];
|
|
2208
2289
|
additions: Set<StableRecordIdentifier>;
|
|
2209
2290
|
removals: Set<StableRecordIdentifier>;
|
|
2210
2291
|
localState: StableRecordIdentifier[];
|
|
2211
2292
|
reordered: boolean;
|
|
2212
|
-
|
|
2213
|
-
|
|
2293
|
+
}
|
|
2294
|
+
| {
|
|
2214
2295
|
kind: 'resource';
|
|
2215
2296
|
remoteState: StableRecordIdentifier | null;
|
|
2216
2297
|
localState: StableRecordIdentifier | null;
|
|
2217
2298
|
};
|
|
2218
2299
|
```
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
*/
|
|
2300
|
+
*
|
|
2301
|
+
* @category Resource Data
|
|
2302
|
+
* @public
|
|
2303
|
+
*/
|
|
2224
2304
|
changedRelationships(identifier) {
|
|
2225
2305
|
return this.__graph.getChanged(identifier);
|
|
2226
2306
|
}
|
|
@@ -2228,9 +2308,8 @@ class JSONAPICache {
|
|
|
2228
2308
|
/**
|
|
2229
2309
|
* Query the cache for whether any mutated relationships exist
|
|
2230
2310
|
*
|
|
2311
|
+
* @category Resource Data
|
|
2231
2312
|
* @public
|
|
2232
|
-
* @param {StableRecordIdentifier} identifier
|
|
2233
|
-
* @return {Boolean}
|
|
2234
2313
|
*/
|
|
2235
2314
|
hasChangedRelationships(identifier) {
|
|
2236
2315
|
return this.__graph.hasChanged(identifier);
|
|
@@ -2243,9 +2322,9 @@ class JSONAPICache {
|
|
|
2243
2322
|
*
|
|
2244
2323
|
* This method is a candidate to become a mutation
|
|
2245
2324
|
*
|
|
2325
|
+
* @category Resource Data
|
|
2246
2326
|
* @public
|
|
2247
|
-
* @
|
|
2248
|
-
* @return {String[]} the names of relationships that were restored
|
|
2327
|
+
* @return the names of relationships that were restored
|
|
2249
2328
|
*/
|
|
2250
2329
|
rollbackRelationships(identifier) {
|
|
2251
2330
|
upgradeCapabilities(this._capabilities);
|
|
@@ -2259,20 +2338,28 @@ class JSONAPICache {
|
|
|
2259
2338
|
/**
|
|
2260
2339
|
* Query the cache for the current state of a relationship property
|
|
2261
2340
|
*
|
|
2341
|
+
* @category Resource Data
|
|
2262
2342
|
* @public
|
|
2263
|
-
* @param identifier
|
|
2264
|
-
* @param field
|
|
2265
2343
|
* @return resource relationship object
|
|
2266
2344
|
*/
|
|
2267
2345
|
getRelationship(identifier, field) {
|
|
2268
2346
|
return this.__graph.getData(identifier, field);
|
|
2269
2347
|
}
|
|
2348
|
+
|
|
2349
|
+
/**
|
|
2350
|
+
* Query the cache for the remote state of a relationship property
|
|
2351
|
+
*
|
|
2352
|
+
* @category Resource Data
|
|
2353
|
+
* @public
|
|
2354
|
+
* @return resource relationship object
|
|
2355
|
+
*/
|
|
2270
2356
|
getRemoteRelationship(identifier, field) {
|
|
2271
2357
|
return this.__graph.getRemoteData(identifier, field);
|
|
2272
2358
|
}
|
|
2273
2359
|
|
|
2274
|
-
|
|
2275
|
-
|
|
2360
|
+
////////// ============== //////////
|
|
2361
|
+
////////// Resource State //////////
|
|
2362
|
+
////////// ============== //////////
|
|
2276
2363
|
|
|
2277
2364
|
/**
|
|
2278
2365
|
* Update the cache state for the given resource to be marked
|
|
@@ -2280,9 +2367,8 @@ class JSONAPICache {
|
|
|
2280
2367
|
*
|
|
2281
2368
|
* This method is a candidate to become a mutation
|
|
2282
2369
|
*
|
|
2370
|
+
* @category Resource State
|
|
2283
2371
|
* @public
|
|
2284
|
-
* @param identifier
|
|
2285
|
-
* @param {Boolean} isDeleted
|
|
2286
2372
|
*/
|
|
2287
2373
|
setIsDeleted(identifier, isDeleted) {
|
|
2288
2374
|
const cached = this.__peek(identifier, false);
|
|
@@ -2294,9 +2380,8 @@ class JSONAPICache {
|
|
|
2294
2380
|
/**
|
|
2295
2381
|
* Query the cache for any validation errors applicable to the given resource.
|
|
2296
2382
|
*
|
|
2383
|
+
* @category Resource State
|
|
2297
2384
|
* @public
|
|
2298
|
-
* @param identifier
|
|
2299
|
-
* @return {JsonApiError[]}
|
|
2300
2385
|
*/
|
|
2301
2386
|
getErrors(identifier) {
|
|
2302
2387
|
return this.__peek(identifier, true).errors || [];
|
|
@@ -2305,9 +2390,8 @@ class JSONAPICache {
|
|
|
2305
2390
|
/**
|
|
2306
2391
|
* Query the cache for whether a given resource has any available data
|
|
2307
2392
|
*
|
|
2393
|
+
* @category Resource State
|
|
2308
2394
|
* @public
|
|
2309
|
-
* @param identifier
|
|
2310
|
-
* @return {Boolean}
|
|
2311
2395
|
*/
|
|
2312
2396
|
isEmpty(identifier) {
|
|
2313
2397
|
const cached = this.__safePeek(identifier, true);
|
|
@@ -2318,9 +2402,8 @@ class JSONAPICache {
|
|
|
2318
2402
|
* Query the cache for whether a given resource was created locally and not
|
|
2319
2403
|
* yet persisted.
|
|
2320
2404
|
*
|
|
2405
|
+
* @category Resource State
|
|
2321
2406
|
* @public
|
|
2322
|
-
* @param identifier
|
|
2323
|
-
* @return {Boolean}
|
|
2324
2407
|
*/
|
|
2325
2408
|
isNew(identifier) {
|
|
2326
2409
|
// TODO can we assert here?
|
|
@@ -2331,9 +2414,8 @@ class JSONAPICache {
|
|
|
2331
2414
|
* Query the cache for whether a given resource is marked as deleted (but not
|
|
2332
2415
|
* necessarily persisted yet).
|
|
2333
2416
|
*
|
|
2417
|
+
* @category Resource State
|
|
2334
2418
|
* @public
|
|
2335
|
-
* @param identifier
|
|
2336
|
-
* @return {Boolean}
|
|
2337
2419
|
*/
|
|
2338
2420
|
isDeleted(identifier) {
|
|
2339
2421
|
// TODO can we assert here?
|
|
@@ -2344,9 +2426,8 @@ class JSONAPICache {
|
|
|
2344
2426
|
* Query the cache for whether a given resource has been deleted and that deletion
|
|
2345
2427
|
* has also been persisted.
|
|
2346
2428
|
*
|
|
2429
|
+
* @category Resource State
|
|
2347
2430
|
* @public
|
|
2348
|
-
* @param identifier
|
|
2349
|
-
* @return {Boolean}
|
|
2350
2431
|
*/
|
|
2351
2432
|
isDeletionCommitted(identifier) {
|
|
2352
2433
|
// TODO can we assert here?
|
|
@@ -2357,8 +2438,6 @@ class JSONAPICache {
|
|
|
2357
2438
|
* Private method used to populate an entry for the identifier
|
|
2358
2439
|
*
|
|
2359
2440
|
* @internal
|
|
2360
|
-
* @param {StableRecordIdentifier} identifier
|
|
2361
|
-
* @return {CachedResource}
|
|
2362
2441
|
*/
|
|
2363
2442
|
_createCache(identifier) {
|
|
2364
2443
|
macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) ? (test => {
|
|
@@ -2375,10 +2454,7 @@ class JSONAPICache {
|
|
|
2375
2454
|
* Peek whether we have cached resource data matching the identifier
|
|
2376
2455
|
* without asserting if the resource data is missing.
|
|
2377
2456
|
*
|
|
2378
|
-
* @param {StableRecordIdentifier} identifier
|
|
2379
|
-
* @param {Boolean} allowDestroyed
|
|
2380
2457
|
* @internal
|
|
2381
|
-
* @return {CachedResource | undefined}
|
|
2382
2458
|
*/
|
|
2383
2459
|
__safePeek(identifier, allowDestroyed) {
|
|
2384
2460
|
let resource = this.__cache.get(identifier);
|
|
@@ -2392,10 +2468,7 @@ class JSONAPICache {
|
|
|
2392
2468
|
* Peek whether we have cached resource data matching the identifier
|
|
2393
2469
|
* Asserts if the resource data is missing.
|
|
2394
2470
|
*
|
|
2395
|
-
* @param {StableRecordIdentifier} identifier
|
|
2396
|
-
* @param {Boolean} allowDestroyed
|
|
2397
2471
|
* @internal
|
|
2398
|
-
* @return {CachedResource}
|
|
2399
2472
|
*/
|
|
2400
2473
|
__peek(identifier, allowDestroyed) {
|
|
2401
2474
|
const resource = this.__safePeek(identifier, allowDestroyed);
|
|
@@ -3154,4 +3227,6 @@ function patchCache(Cache, op) {
|
|
|
3154
3227
|
}
|
|
3155
3228
|
}
|
|
3156
3229
|
}
|
|
3157
|
-
|
|
3230
|
+
|
|
3231
|
+
export { JSONAPICache };
|
|
3232
|
+
//# sourceMappingURL=index.js.map
|