@warp-drive-mirror/json-api 5.8.0-alpha.37 → 5.8.0-alpha.40
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/dist/unpkg/dev/index.js +252 -139
- package/dist/unpkg/dev-deprecated/index.js +246 -172
- package/dist/unpkg/prod/index.js +4 -1357
- package/dist/unpkg/prod-deprecated/index.js +4 -1357
- package/package.json +12 -20
- package/dist/unpkg/dev/declarations/-private/cache.d.ts +0 -445
- package/dist/unpkg/dev/declarations/-private/validate-document-fields.d.ts +0 -3
- package/dist/unpkg/dev/declarations/-private/validator/1.1/7.1_top-level-document-members.d.ts +0 -1
- package/dist/unpkg/dev/declarations/-private/validator/1.1/7.2_resource-objects.d.ts +0 -1
- package/dist/unpkg/dev/declarations/-private/validator/1.1/links.d.ts +0 -1
- package/dist/unpkg/dev/declarations/-private/validator/index.d.ts +0 -4
- package/dist/unpkg/dev/declarations/-private/validator/utils.d.ts +0 -75
- package/dist/unpkg/dev/declarations/index.d.ts +0 -5
- package/dist/unpkg/dev-deprecated/declarations/-private/cache.d.ts +0 -445
- package/dist/unpkg/dev-deprecated/declarations/-private/validate-document-fields.d.ts +0 -3
- package/dist/unpkg/dev-deprecated/declarations/-private/validator/1.1/7.1_top-level-document-members.d.ts +0 -1
- package/dist/unpkg/dev-deprecated/declarations/-private/validator/1.1/7.2_resource-objects.d.ts +0 -1
- package/dist/unpkg/dev-deprecated/declarations/-private/validator/1.1/links.d.ts +0 -1
- package/dist/unpkg/dev-deprecated/declarations/-private/validator/index.d.ts +0 -4
- package/dist/unpkg/dev-deprecated/declarations/-private/validator/utils.d.ts +0 -75
- package/dist/unpkg/dev-deprecated/declarations/index.d.ts +0 -5
- package/dist/unpkg/prod/declarations/-private/cache.d.ts +0 -445
- package/dist/unpkg/prod/declarations/-private/validate-document-fields.d.ts +0 -3
- package/dist/unpkg/prod/declarations/-private/validator/1.1/7.1_top-level-document-members.d.ts +0 -1
- package/dist/unpkg/prod/declarations/-private/validator/1.1/7.2_resource-objects.d.ts +0 -1
- package/dist/unpkg/prod/declarations/-private/validator/1.1/links.d.ts +0 -1
- package/dist/unpkg/prod/declarations/-private/validator/index.d.ts +0 -4
- package/dist/unpkg/prod/declarations/-private/validator/utils.d.ts +0 -75
- package/dist/unpkg/prod/declarations/index.d.ts +0 -5
- package/dist/unpkg/prod-deprecated/declarations/-private/cache.d.ts +0 -445
- package/dist/unpkg/prod-deprecated/declarations/-private/validate-document-fields.d.ts +0 -3
- package/dist/unpkg/prod-deprecated/declarations/-private/validator/1.1/7.1_top-level-document-members.d.ts +0 -1
- package/dist/unpkg/prod-deprecated/declarations/-private/validator/1.1/7.2_resource-objects.d.ts +0 -1
- package/dist/unpkg/prod-deprecated/declarations/-private/validator/1.1/links.d.ts +0 -1
- package/dist/unpkg/prod-deprecated/declarations/-private/validator/index.d.ts +0 -4
- package/dist/unpkg/prod-deprecated/declarations/-private/validator/utils.d.ts +0 -75
- package/dist/unpkg/prod-deprecated/declarations/index.d.ts +0 -5
package/dist/unpkg/dev/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import { graphFor, peekGraph, isBelongsTo } from '@warp-drive-mirror/core/graph/
|
|
|
2
2
|
import { logGroup, isResourceKey, assertPrivateCapabilities, isRequestKey } from '@warp-drive-mirror/core/store/-private';
|
|
3
3
|
import Fuse from 'fuse.js';
|
|
4
4
|
import jsonToAst from 'json-to-ast';
|
|
5
|
-
import { macroCondition, getGlobalConfig } from '@embroider/macros';
|
|
6
5
|
|
|
7
6
|
function validateDocumentFields(schema, jsonApiDoc) {
|
|
8
7
|
const {
|
|
@@ -219,11 +218,11 @@ class Reporter {
|
|
|
219
218
|
// handle array paths
|
|
220
219
|
//
|
|
221
220
|
if (typeof segment === 'number') {
|
|
222
|
-
|
|
221
|
+
(test => {
|
|
223
222
|
if (!test) {
|
|
224
223
|
throw new Error(`Because the segment is a number, expected a node of type Array`);
|
|
225
224
|
}
|
|
226
|
-
})(node.type === 'Array')
|
|
225
|
+
})(node.type === 'Array');
|
|
227
226
|
if (node.children && node.children[segment]) {
|
|
228
227
|
priorNode = node;
|
|
229
228
|
const childNode = node.children[segment];
|
|
@@ -243,11 +242,11 @@ class Reporter {
|
|
|
243
242
|
// handle object paths
|
|
244
243
|
//
|
|
245
244
|
} else {
|
|
246
|
-
|
|
245
|
+
(test => {
|
|
247
246
|
if (!test) {
|
|
248
247
|
throw new Error(`Because the segment is a string, expected a node of type Object`);
|
|
249
248
|
}
|
|
250
|
-
})(node.type === 'Object')
|
|
249
|
+
})(node.type === 'Object');
|
|
251
250
|
const child = node.children.find(childCandidate => {
|
|
252
251
|
if (childCandidate.type === 'Property') {
|
|
253
252
|
return childCandidate.key.type === 'Identifier' && childCandidate.key.value === segment;
|
|
@@ -369,11 +368,6 @@ class Reporter {
|
|
|
369
368
|
|
|
370
369
|
// eslint-disable-next-line no-console, @typescript-eslint/no-unused-expressions
|
|
371
370
|
colorize ? console.log(errorString, ...colors) : console.log(errorString);
|
|
372
|
-
if (macroCondition(getGlobalConfig().WarpDriveMirror.features.JSON_API_CACHE_VALIDATION_ERRORS)) {
|
|
373
|
-
if (counts.error > 0) {
|
|
374
|
-
throw new Error(contextStr);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
371
|
}
|
|
378
372
|
}
|
|
379
373
|
|
|
@@ -863,28 +857,11 @@ function validateResourceRelationships(reporter, type, resource, path) {
|
|
|
863
857
|
}
|
|
864
858
|
|
|
865
859
|
function validateDocument(capabilities, doc) {
|
|
866
|
-
|
|
860
|
+
(test => {
|
|
867
861
|
if (!test) {
|
|
868
862
|
throw new Error(`Expected a JSON:API Document as the content provided to the cache, received ${typeof doc.content}`);
|
|
869
863
|
}
|
|
870
|
-
})(doc instanceof Error || typeof doc.content === 'object' && doc.content !== null)
|
|
871
|
-
|
|
872
|
-
// if the feature is not active and the payloads are not being logged
|
|
873
|
-
// we don't need to validate the payloads
|
|
874
|
-
if (macroCondition(!getGlobalConfig().WarpDriveMirror.features.JSON_API_CACHE_VALIDATION_ERRORS)) {
|
|
875
|
-
if (macroCondition(!getGlobalConfig().WarpDriveMirror.activeLogging.LOG_CACHE)) {
|
|
876
|
-
if (!(getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE)) {
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
if (macroCondition(!getGlobalConfig().WarpDriveMirror.activeLogging.LOG_CACHE)) {
|
|
882
|
-
if (!(getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE)) {
|
|
883
|
-
if (macroCondition(!getGlobalConfig().WarpDriveMirror.features.JSON_API_CACHE_VALIDATION_ERRORS)) {
|
|
884
|
-
return;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
}
|
|
864
|
+
})(doc instanceof Error || typeof doc.content === 'object' && doc.content !== null);
|
|
888
865
|
if (isErrorDocument(doc)) {
|
|
889
866
|
return; // return validateErrorDocument(reporter, doc);
|
|
890
867
|
} else if (isMetaDocument(doc)) {
|
|
@@ -930,6 +907,142 @@ function validateResourceDocument(reporter, doc) {
|
|
|
930
907
|
reporter.report();
|
|
931
908
|
}
|
|
932
909
|
|
|
910
|
+
/*
|
|
911
|
+
These are the runtime implementations for the javascript macros that have
|
|
912
|
+
runtime implementations.
|
|
913
|
+
|
|
914
|
+
Not every macro has a runtime implementation, some only make sense in the
|
|
915
|
+
build and always run there.
|
|
916
|
+
|
|
917
|
+
Even when we have runtime implementations, we are still careful to emit static
|
|
918
|
+
errors during the build wherever possible, and runtime errors when necessary,
|
|
919
|
+
so that you're not surprised when you switch from runtime-mode to compile-time
|
|
920
|
+
mode.
|
|
921
|
+
*/
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
// This is here as a compile target for `getConfig` and `getOwnConfig` when
|
|
925
|
+
// we're in runtime mode. This is not public API to call from your own code.
|
|
926
|
+
function config(packageRoot) {
|
|
927
|
+
return runtimeConfig.packages[packageRoot];
|
|
928
|
+
}
|
|
929
|
+
function getGlobalConfig() {
|
|
930
|
+
return runtimeConfig.global;
|
|
931
|
+
}
|
|
932
|
+
const runtimeConfig = initializeRuntimeMacrosConfig();
|
|
933
|
+
|
|
934
|
+
// this exists to be targeted by our babel plugin
|
|
935
|
+
function initializeRuntimeMacrosConfig() {
|
|
936
|
+
return {
|
|
937
|
+
"packages": {},
|
|
938
|
+
"global": {
|
|
939
|
+
"@embroider/macros": {
|
|
940
|
+
"isTesting": false
|
|
941
|
+
},
|
|
942
|
+
"WarpDrive": {
|
|
943
|
+
"debug": {
|
|
944
|
+
"DEBUG_RELATIONSHIP_NOTIFICATIONS": false,
|
|
945
|
+
"LOG_CACHE": false,
|
|
946
|
+
"LOG_CACHE_POLICY": false,
|
|
947
|
+
"LOG_GRAPH": false,
|
|
948
|
+
"LOG_IDENTIFIERS": false,
|
|
949
|
+
"LOG_INSTANCE_CACHE": false,
|
|
950
|
+
"LOG_METRIC_COUNTS": false,
|
|
951
|
+
"LOG_MUTATIONS": false,
|
|
952
|
+
"LOG_NOTIFICATIONS": false,
|
|
953
|
+
"LOG_OPERATIONS": false,
|
|
954
|
+
"LOG_PAYLOADS": false,
|
|
955
|
+
"LOG_REACT_SIGNAL_INTEGRATION": false,
|
|
956
|
+
"LOG_REQUESTS": false,
|
|
957
|
+
"LOG_REQUEST_STATUS": false,
|
|
958
|
+
"__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS": false
|
|
959
|
+
},
|
|
960
|
+
"polyfillUUID": false,
|
|
961
|
+
"includeDataAdapter": true,
|
|
962
|
+
"compatWith": "99.0",
|
|
963
|
+
"deprecations": {
|
|
964
|
+
"DEPRECATE_CATCH_ALL": false,
|
|
965
|
+
"DEPRECATE_COMPUTED_CHAINS": false,
|
|
966
|
+
"DEPRECATE_EMBER_INFLECTOR": false,
|
|
967
|
+
"DEPRECATE_LEGACY_IMPORTS": false,
|
|
968
|
+
"DEPRECATE_MANY_ARRAY_DUPLICATES": false,
|
|
969
|
+
"DEPRECATE_NON_STRICT_ID": false,
|
|
970
|
+
"DEPRECATE_NON_STRICT_TYPES": false,
|
|
971
|
+
"DEPRECATE_NON_UNIQUE_PAYLOADS": false,
|
|
972
|
+
"DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE": false,
|
|
973
|
+
"DEPRECATE_STORE_EXTENDS_EMBER_OBJECT": false,
|
|
974
|
+
"DEPRECATE_TRACKING_PACKAGE": false,
|
|
975
|
+
"DISABLE_7X_DEPRECATIONS": false,
|
|
976
|
+
"ENABLE_LEGACY_REQUEST_METHODS": false,
|
|
977
|
+
"ENABLE_LEGACY_SCHEMA_SERVICE": false
|
|
978
|
+
},
|
|
979
|
+
"features": {
|
|
980
|
+
"ENFORCE_STRICT_RESOURCE_FINALIZATION": false,
|
|
981
|
+
"JSON_API_CACHE_VALIDATION_ERRORS": false,
|
|
982
|
+
"SAMPLE_FEATURE_FLAG": null
|
|
983
|
+
},
|
|
984
|
+
"activeLogging": {
|
|
985
|
+
"DEBUG_RELATIONSHIP_NOTIFICATIONS": true,
|
|
986
|
+
"LOG_CACHE": true,
|
|
987
|
+
"LOG_CACHE_POLICY": true,
|
|
988
|
+
"LOG_GRAPH": true,
|
|
989
|
+
"LOG_IDENTIFIERS": true,
|
|
990
|
+
"LOG_INSTANCE_CACHE": true,
|
|
991
|
+
"LOG_METRIC_COUNTS": true,
|
|
992
|
+
"LOG_MUTATIONS": true,
|
|
993
|
+
"LOG_NOTIFICATIONS": true,
|
|
994
|
+
"LOG_OPERATIONS": true,
|
|
995
|
+
"LOG_PAYLOADS": true,
|
|
996
|
+
"LOG_REACT_SIGNAL_INTEGRATION": true,
|
|
997
|
+
"LOG_REQUESTS": true,
|
|
998
|
+
"LOG_REQUEST_STATUS": true,
|
|
999
|
+
"__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS": true
|
|
1000
|
+
},
|
|
1001
|
+
"env": {
|
|
1002
|
+
"TESTING": true,
|
|
1003
|
+
"PRODUCTION": false,
|
|
1004
|
+
"DEBUG": true,
|
|
1005
|
+
"IS_RECORDING": false,
|
|
1006
|
+
"IS_CI": true,
|
|
1007
|
+
"SHOULD_RECORD": false
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
function updaterMethods() {
|
|
1014
|
+
return {
|
|
1015
|
+
config,
|
|
1016
|
+
getGlobalConfig,
|
|
1017
|
+
setConfig(packageRoot, value) {
|
|
1018
|
+
runtimeConfig.packages[packageRoot] = value;
|
|
1019
|
+
},
|
|
1020
|
+
setGlobalConfig(key, value) {
|
|
1021
|
+
runtimeConfig.global[key] = value;
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// this is how runtime config can get injected at boot. I'm not sure yet if this
|
|
1027
|
+
// should be public API, but we certainly need it internally to set things like
|
|
1028
|
+
// the global fastboot.isRunning.
|
|
1029
|
+
//
|
|
1030
|
+
// consumers of this API push a function onto
|
|
1031
|
+
// window._embroider_macros_runtime_config. The function is given four methods
|
|
1032
|
+
// which allow it to read and write the per-package and global configs. The
|
|
1033
|
+
// reason for allowing both read & write is that merging strategies are up to
|
|
1034
|
+
// each consumers -- read first, then merge, then write.
|
|
1035
|
+
//
|
|
1036
|
+
// For an example user of this API, see where we generate
|
|
1037
|
+
// embroider_macros_fastboot_init.js' in @embroider/core.
|
|
1038
|
+
let updaters = typeof window !== 'undefined' ? window._embroider_macros_runtime_config : undefined;
|
|
1039
|
+
if (updaters) {
|
|
1040
|
+
let methods = updaterMethods();
|
|
1041
|
+
for (let updater of updaters) {
|
|
1042
|
+
updater(methods);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
933
1046
|
function isImplicit(relationship) {
|
|
934
1047
|
return relationship.definition.isImplicit;
|
|
935
1048
|
}
|
|
@@ -1051,7 +1164,7 @@ class JSONAPICache {
|
|
|
1051
1164
|
*/
|
|
1052
1165
|
|
|
1053
1166
|
put(doc) {
|
|
1054
|
-
|
|
1167
|
+
{
|
|
1055
1168
|
validateDocument(this._capabilities, doc);
|
|
1056
1169
|
}
|
|
1057
1170
|
if (isErrorDocument(doc)) {
|
|
@@ -1065,10 +1178,10 @@ class JSONAPICache {
|
|
|
1065
1178
|
const {
|
|
1066
1179
|
cacheKeyManager
|
|
1067
1180
|
} = this._capabilities;
|
|
1068
|
-
|
|
1181
|
+
{
|
|
1069
1182
|
validateDocumentFields(this._capabilities.schema, jsonApiDoc);
|
|
1070
1183
|
}
|
|
1071
|
-
|
|
1184
|
+
{
|
|
1072
1185
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1073
1186
|
const Counts = new Map();
|
|
1074
1187
|
let totalCount = 0;
|
|
@@ -1149,16 +1262,16 @@ class JSONAPICache {
|
|
|
1149
1262
|
resourceDocument.data = data;
|
|
1150
1263
|
}
|
|
1151
1264
|
if (included !== undefined) {
|
|
1152
|
-
|
|
1265
|
+
(test => {
|
|
1153
1266
|
if (!test) {
|
|
1154
1267
|
throw new Error(`There should not be included data on an Error document`);
|
|
1155
1268
|
}
|
|
1156
|
-
})(!isErrorDocument(doc))
|
|
1157
|
-
|
|
1269
|
+
})(!isErrorDocument(doc));
|
|
1270
|
+
(test => {
|
|
1158
1271
|
if (!test) {
|
|
1159
1272
|
throw new Error(`There should not be included data on a Meta document`);
|
|
1160
1273
|
}
|
|
1161
|
-
})(!isMetaDocument(doc))
|
|
1274
|
+
})(!isMetaDocument(doc));
|
|
1162
1275
|
resourceDocument.included = included;
|
|
1163
1276
|
}
|
|
1164
1277
|
const request = doc.request;
|
|
@@ -1175,16 +1288,16 @@ class JSONAPICache {
|
|
|
1175
1288
|
if (doc.request?.op === 'findHasMany') {
|
|
1176
1289
|
const parentIdentifier = doc.request.options?.identifier;
|
|
1177
1290
|
const parentField = doc.request.options?.field;
|
|
1178
|
-
|
|
1291
|
+
(test => {
|
|
1179
1292
|
if (!test) {
|
|
1180
1293
|
throw new Error(`Expected a hasMany field`);
|
|
1181
1294
|
}
|
|
1182
|
-
})(parentField?.kind === 'hasMany')
|
|
1183
|
-
|
|
1295
|
+
})(parentField?.kind === 'hasMany');
|
|
1296
|
+
(test => {
|
|
1184
1297
|
if (!test) {
|
|
1185
1298
|
throw new Error(`Expected a parent identifier for a findHasMany request`);
|
|
1186
1299
|
}
|
|
1187
|
-
})(parentIdentifier && isResourceKey(parentIdentifier))
|
|
1300
|
+
})(parentIdentifier && isResourceKey(parentIdentifier));
|
|
1188
1301
|
if (parentField && parentIdentifier) {
|
|
1189
1302
|
this.__graph.push({
|
|
1190
1303
|
op: 'updateRelationship',
|
|
@@ -1207,7 +1320,7 @@ class JSONAPICache {
|
|
|
1207
1320
|
*/
|
|
1208
1321
|
patch(op) {
|
|
1209
1322
|
if (Array.isArray(op)) {
|
|
1210
|
-
|
|
1323
|
+
{
|
|
1211
1324
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1212
1325
|
logGroup('cache', 'patch', '<BATCH>', String(op.length) + ' operations', '', '');
|
|
1213
1326
|
}
|
|
@@ -1218,7 +1331,7 @@ class JSONAPICache {
|
|
|
1218
1331
|
patchCache(this, operation);
|
|
1219
1332
|
}
|
|
1220
1333
|
});
|
|
1221
|
-
|
|
1334
|
+
{
|
|
1222
1335
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1223
1336
|
// eslint-disable-next-line no-console
|
|
1224
1337
|
console.groupEnd();
|
|
@@ -1236,7 +1349,7 @@ class JSONAPICache {
|
|
|
1236
1349
|
* @public
|
|
1237
1350
|
*/
|
|
1238
1351
|
mutate(mutation) {
|
|
1239
|
-
|
|
1352
|
+
{
|
|
1240
1353
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1241
1354
|
logGroup('cache', 'mutate', mutation.record.type, mutation.record.lid, mutation.field, mutation.op);
|
|
1242
1355
|
try {
|
|
@@ -1250,7 +1363,7 @@ class JSONAPICache {
|
|
|
1250
1363
|
}
|
|
1251
1364
|
}
|
|
1252
1365
|
this.__graph.update(mutation, false);
|
|
1253
|
-
|
|
1366
|
+
{
|
|
1254
1367
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1255
1368
|
// eslint-disable-next-line no-console
|
|
1256
1369
|
console.groupEnd();
|
|
@@ -1551,7 +1664,7 @@ class JSONAPICache {
|
|
|
1551
1664
|
* @public
|
|
1552
1665
|
*/
|
|
1553
1666
|
clientDidCreate(identifier, options) {
|
|
1554
|
-
|
|
1667
|
+
{
|
|
1555
1668
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1556
1669
|
try {
|
|
1557
1670
|
const _data = options ? JSON.parse(JSON.stringify(options)) : options;
|
|
@@ -1645,7 +1758,7 @@ class JSONAPICache {
|
|
|
1645
1758
|
const payload = result ? result.content : null;
|
|
1646
1759
|
const operation = result?.request?.op ?? null;
|
|
1647
1760
|
const data = payload && payload.data;
|
|
1648
|
-
|
|
1761
|
+
{
|
|
1649
1762
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
1650
1763
|
try {
|
|
1651
1764
|
const payloadCopy = payload ? JSON.parse(JSON.stringify(payload)) : payload;
|
|
@@ -1662,11 +1775,11 @@ class JSONAPICache {
|
|
|
1662
1775
|
if (Array.isArray(committedIdentifier)) {
|
|
1663
1776
|
// if we get back an array of primary data, we treat each
|
|
1664
1777
|
// entry as a separate commit for each identifier
|
|
1665
|
-
|
|
1778
|
+
(test => {
|
|
1666
1779
|
if (!test) {
|
|
1667
1780
|
throw new Error(`Expected the array of primary data to match the array of committed identifiers`);
|
|
1668
1781
|
}
|
|
1669
|
-
})(!hasMultipleIdentifiers || !responseIsCollection || data.length === committedIdentifier.length)
|
|
1782
|
+
})(!hasMultipleIdentifiers || !responseIsCollection || data.length === committedIdentifier.length);
|
|
1670
1783
|
if (responseIsCollection) {
|
|
1671
1784
|
for (let i = 0; i < committedIdentifier.length; i++) {
|
|
1672
1785
|
const identifier = committedIdentifier[i];
|
|
@@ -1811,11 +1924,11 @@ class JSONAPICache {
|
|
|
1811
1924
|
if (isSimplePath) {
|
|
1812
1925
|
const attribute = attr;
|
|
1813
1926
|
const cached = this.__peek(identifier, true);
|
|
1814
|
-
|
|
1927
|
+
(test => {
|
|
1815
1928
|
if (!test) {
|
|
1816
1929
|
throw new Error(`Cannot retrieve attributes for identifier ${String(identifier)} as it is not present in the cache`);
|
|
1817
1930
|
}
|
|
1818
|
-
})(cached)
|
|
1931
|
+
})(cached);
|
|
1819
1932
|
|
|
1820
1933
|
// in Prod we try to recover when accessing something that
|
|
1821
1934
|
// doesn't exist
|
|
@@ -1880,11 +1993,11 @@ class JSONAPICache {
|
|
|
1880
1993
|
if (isSimplePath) {
|
|
1881
1994
|
const attribute = attr;
|
|
1882
1995
|
const cached = this.__peek(identifier, true);
|
|
1883
|
-
|
|
1996
|
+
(test => {
|
|
1884
1997
|
if (!test) {
|
|
1885
1998
|
throw new Error(`Cannot retrieve remote attributes for identifier ${String(identifier)} as it is not present in the cache`);
|
|
1886
1999
|
}
|
|
1887
|
-
})(cached)
|
|
2000
|
+
})(cached);
|
|
1888
2001
|
|
|
1889
2002
|
// in Prod we try to recover when accessing something that
|
|
1890
2003
|
// doesn't exist
|
|
@@ -1937,11 +2050,11 @@ class JSONAPICache {
|
|
|
1937
2050
|
*/
|
|
1938
2051
|
setAttr(identifier, attr, value) {
|
|
1939
2052
|
// this assert works to ensure we have a non-empty string and/or a non-empty array
|
|
1940
|
-
|
|
2053
|
+
(test => {
|
|
1941
2054
|
if (!test) {
|
|
1942
2055
|
throw new Error('setAttr must receive at least one attribute path');
|
|
1943
2056
|
}
|
|
1944
|
-
})(attr.length > 0)
|
|
2057
|
+
})(attr.length > 0);
|
|
1945
2058
|
const isSimplePath = !Array.isArray(attr) || attr.length === 1;
|
|
1946
2059
|
if (Array.isArray(attr) && attr.length === 1) {
|
|
1947
2060
|
attr = attr[0];
|
|
@@ -2035,11 +2148,11 @@ class JSONAPICache {
|
|
|
2035
2148
|
*/
|
|
2036
2149
|
changedAttrs(identifier) {
|
|
2037
2150
|
const cached = this.__peek(identifier, false);
|
|
2038
|
-
|
|
2151
|
+
(test => {
|
|
2039
2152
|
if (!test) {
|
|
2040
2153
|
throw new Error(`Cannot retrieve changed attributes for identifier ${String(identifier)} as it is not present in the cache`);
|
|
2041
2154
|
}
|
|
2042
|
-
})(cached)
|
|
2155
|
+
})(cached);
|
|
2043
2156
|
|
|
2044
2157
|
// in Prod we try to recover when accessing something that
|
|
2045
2158
|
// doesn't exist
|
|
@@ -2059,11 +2172,11 @@ class JSONAPICache {
|
|
|
2059
2172
|
*/
|
|
2060
2173
|
hasChangedAttrs(identifier) {
|
|
2061
2174
|
const cached = this.__peek(identifier, true);
|
|
2062
|
-
|
|
2175
|
+
(test => {
|
|
2063
2176
|
if (!test) {
|
|
2064
2177
|
throw new Error(`Cannot retrieve changed attributes for identifier ${String(identifier)} as it is not present in the cache`);
|
|
2065
2178
|
}
|
|
2066
|
-
})(cached)
|
|
2179
|
+
})(cached);
|
|
2067
2180
|
|
|
2068
2181
|
// in Prod we try to recover when accessing something that
|
|
2069
2182
|
// doesn't exist
|
|
@@ -2274,11 +2387,11 @@ class JSONAPICache {
|
|
|
2274
2387
|
* @internal
|
|
2275
2388
|
*/
|
|
2276
2389
|
_createCache(identifier) {
|
|
2277
|
-
|
|
2390
|
+
(test => {
|
|
2278
2391
|
if (!test) {
|
|
2279
2392
|
throw new Error(`Expected no resource data to yet exist in the cache`);
|
|
2280
2393
|
}
|
|
2281
|
-
})(!this.__cache.has(identifier))
|
|
2394
|
+
})(!this.__cache.has(identifier));
|
|
2282
2395
|
const cache = makeCache();
|
|
2283
2396
|
this.__cache.set(identifier, cache);
|
|
2284
2397
|
return cache;
|
|
@@ -2306,62 +2419,62 @@ class JSONAPICache {
|
|
|
2306
2419
|
*/
|
|
2307
2420
|
__peek(identifier, allowDestroyed) {
|
|
2308
2421
|
const resource = this.__safePeek(identifier, allowDestroyed);
|
|
2309
|
-
|
|
2422
|
+
(test => {
|
|
2310
2423
|
if (!test) {
|
|
2311
2424
|
throw new Error(`Expected Cache to have a resource entry for the identifier ${String(identifier)} but none was found`);
|
|
2312
2425
|
}
|
|
2313
|
-
})(resource)
|
|
2426
|
+
})(resource);
|
|
2314
2427
|
return resource;
|
|
2315
2428
|
}
|
|
2316
2429
|
}
|
|
2317
2430
|
function addResourceToDocument(cache, op) {
|
|
2318
|
-
|
|
2431
|
+
(test => {
|
|
2319
2432
|
if (!test) {
|
|
2320
2433
|
throw new Error(`Expected field to be either 'data' or 'included'`);
|
|
2321
2434
|
}
|
|
2322
|
-
})(op.field === 'data' || op.field === 'included')
|
|
2435
|
+
})(op.field === 'data' || op.field === 'included');
|
|
2323
2436
|
const doc = cache.__documents.get(op.record.lid);
|
|
2324
|
-
|
|
2437
|
+
(test => {
|
|
2325
2438
|
if (!test) {
|
|
2326
2439
|
throw new Error(`Expected to have a cached document on which to perform the add operation`);
|
|
2327
2440
|
}
|
|
2328
|
-
})(doc)
|
|
2329
|
-
|
|
2441
|
+
})(doc);
|
|
2442
|
+
(test => {
|
|
2330
2443
|
if (!test) {
|
|
2331
2444
|
throw new Error(`Expected to have content on the document`);
|
|
2332
2445
|
}
|
|
2333
|
-
})(doc.content)
|
|
2446
|
+
})(doc.content);
|
|
2334
2447
|
const {
|
|
2335
2448
|
content
|
|
2336
2449
|
} = doc;
|
|
2337
2450
|
if (op.field === 'data') {
|
|
2338
2451
|
let shouldNotify = false;
|
|
2339
|
-
|
|
2452
|
+
(test => {
|
|
2340
2453
|
if (!test) {
|
|
2341
2454
|
throw new Error(`Expected to have a data property on the document`);
|
|
2342
2455
|
}
|
|
2343
|
-
})('data' in content)
|
|
2456
|
+
})('data' in content);
|
|
2344
2457
|
|
|
2345
2458
|
// if data is not an array, we set the data property directly
|
|
2346
2459
|
if (!Array.isArray(content.data)) {
|
|
2347
|
-
|
|
2460
|
+
(test => {
|
|
2348
2461
|
if (!test) {
|
|
2349
2462
|
throw new Error(`Expected to have a single record as the operation value`);
|
|
2350
2463
|
}
|
|
2351
|
-
})(op.value && !Array.isArray(op.value))
|
|
2464
|
+
})(op.value && !Array.isArray(op.value));
|
|
2352
2465
|
shouldNotify = content.data !== op.value;
|
|
2353
2466
|
if (shouldNotify) content.data = op.value;
|
|
2354
|
-
|
|
2467
|
+
(test => {
|
|
2355
2468
|
if (!test) {
|
|
2356
2469
|
throw new Error(`The value '${op.value.lid}' cannot be added from the data of document '${op.record.lid}' as it is already the current value '${content.data ? content.data.lid : '<null>'}'`);
|
|
2357
2470
|
}
|
|
2358
|
-
})(shouldNotify)
|
|
2471
|
+
})(shouldNotify);
|
|
2359
2472
|
} else {
|
|
2360
|
-
|
|
2473
|
+
(test => {
|
|
2361
2474
|
if (!test) {
|
|
2362
2475
|
throw new Error(`Expected to have a non-null operation value`);
|
|
2363
2476
|
}
|
|
2364
|
-
})(op.value)
|
|
2477
|
+
})(op.value);
|
|
2365
2478
|
if (Array.isArray(op.value)) {
|
|
2366
2479
|
if (op.index !== undefined) {
|
|
2367
2480
|
// for collections, because we allow duplicates we are always changed.
|
|
@@ -2390,26 +2503,26 @@ function addResourceToDocument(cache, op) {
|
|
|
2390
2503
|
return;
|
|
2391
2504
|
}
|
|
2392
2505
|
content.included = content.included || [];
|
|
2393
|
-
|
|
2506
|
+
(test => {
|
|
2394
2507
|
if (!test) {
|
|
2395
2508
|
throw new Error(`Expected to have a non-null operation value`);
|
|
2396
2509
|
}
|
|
2397
|
-
})(op.value)
|
|
2510
|
+
})(op.value);
|
|
2398
2511
|
if (Array.isArray(op.value)) {
|
|
2399
2512
|
// included is not allowed to have duplicates, so we do a dirty check here
|
|
2400
|
-
|
|
2513
|
+
(test => {
|
|
2401
2514
|
if (!test) {
|
|
2402
2515
|
throw new Error(`included should not contain duplicate members`);
|
|
2403
2516
|
}
|
|
2404
|
-
})(new Set([...content.included, ...op.value]).size === content.included.length + op.value.length)
|
|
2517
|
+
})(new Set([...content.included, ...op.value]).size === content.included.length + op.value.length);
|
|
2405
2518
|
content.included = content.included.concat(op.value);
|
|
2406
2519
|
} else {
|
|
2407
2520
|
// included is not allowed to have duplicates, so we do a dirty check here
|
|
2408
|
-
|
|
2521
|
+
(test => {
|
|
2409
2522
|
if (!test) {
|
|
2410
2523
|
throw new Error(`included should not contain duplicate members`);
|
|
2411
2524
|
}
|
|
2412
|
-
})(content.included.includes(op.value) === false)
|
|
2525
|
+
})(content.included.includes(op.value) === false);
|
|
2413
2526
|
content.included.push(op.value);
|
|
2414
2527
|
}
|
|
2415
2528
|
|
|
@@ -2417,54 +2530,54 @@ function addResourceToDocument(cache, op) {
|
|
|
2417
2530
|
// exposed. We should possibly consider doing so though for subscribers
|
|
2418
2531
|
}
|
|
2419
2532
|
function removeResourceFromDocument(cache, op) {
|
|
2420
|
-
|
|
2533
|
+
(test => {
|
|
2421
2534
|
if (!test) {
|
|
2422
2535
|
throw new Error(`Expected field to be either 'data' or 'included'`);
|
|
2423
2536
|
}
|
|
2424
|
-
})(op.field === 'data' || op.field === 'included')
|
|
2537
|
+
})(op.field === 'data' || op.field === 'included');
|
|
2425
2538
|
const doc = cache.__documents.get(op.record.lid);
|
|
2426
|
-
|
|
2539
|
+
(test => {
|
|
2427
2540
|
if (!test) {
|
|
2428
2541
|
throw new Error(`Expected to have a cached document on which to perform the remove operation`);
|
|
2429
2542
|
}
|
|
2430
|
-
})(doc)
|
|
2431
|
-
|
|
2543
|
+
})(doc);
|
|
2544
|
+
(test => {
|
|
2432
2545
|
if (!test) {
|
|
2433
2546
|
throw new Error(`Expected to have content on the document`);
|
|
2434
2547
|
}
|
|
2435
|
-
})(doc.content)
|
|
2548
|
+
})(doc.content);
|
|
2436
2549
|
const {
|
|
2437
2550
|
content
|
|
2438
2551
|
} = doc;
|
|
2439
2552
|
if (op.field === 'data') {
|
|
2440
2553
|
let shouldNotify = false;
|
|
2441
|
-
|
|
2554
|
+
(test => {
|
|
2442
2555
|
if (!test) {
|
|
2443
2556
|
throw new Error(`Expected to have a data property on the document`);
|
|
2444
2557
|
}
|
|
2445
|
-
})('data' in content)
|
|
2558
|
+
})('data' in content);
|
|
2446
2559
|
|
|
2447
2560
|
// if data is not an array, we set the data property directly
|
|
2448
2561
|
if (!Array.isArray(content.data)) {
|
|
2449
|
-
|
|
2562
|
+
(test => {
|
|
2450
2563
|
if (!test) {
|
|
2451
2564
|
throw new Error(`Expected to have a single record as the operation value`);
|
|
2452
2565
|
}
|
|
2453
|
-
})(op.value && !Array.isArray(op.value))
|
|
2566
|
+
})(op.value && !Array.isArray(op.value));
|
|
2454
2567
|
shouldNotify = content.data === op.value;
|
|
2455
2568
|
// we only remove the value if it was our existing value
|
|
2456
2569
|
if (shouldNotify) content.data = null;
|
|
2457
|
-
|
|
2570
|
+
(test => {
|
|
2458
2571
|
if (!test) {
|
|
2459
2572
|
throw new Error(`The value '${op.value.lid}' cannot be removed from the data of document '${op.record.lid}' as it is not the current value '${content.data ? content.data.lid : '<null>'}'`);
|
|
2460
2573
|
}
|
|
2461
|
-
})(shouldNotify)
|
|
2574
|
+
})(shouldNotify);
|
|
2462
2575
|
} else {
|
|
2463
|
-
|
|
2576
|
+
(test => {
|
|
2464
2577
|
if (!test) {
|
|
2465
2578
|
throw new Error(`Expected to have a non-null operation value`);
|
|
2466
2579
|
}
|
|
2467
|
-
})(op.value)
|
|
2580
|
+
})(op.value);
|
|
2468
2581
|
const toRemove = Array.isArray(op.value) ? op.value : [op.value];
|
|
2469
2582
|
for (let i = 0; i < toRemove.length; i++) {
|
|
2470
2583
|
const value = toRemove[i];
|
|
@@ -2472,11 +2585,11 @@ function removeResourceFromDocument(cache, op) {
|
|
|
2472
2585
|
// in production we want to recover gracefully
|
|
2473
2586
|
// so we fallback to first-index-of
|
|
2474
2587
|
const index = op.index < content.data.length && content.data[op.index] === value ? op.index : content.data.indexOf(value);
|
|
2475
|
-
|
|
2588
|
+
(test => {
|
|
2476
2589
|
if (!test) {
|
|
2477
2590
|
throw new Error(`Mismatched Index: Expected index '${op.index}' to contain the value '${value.lid}' but that value is at index '${index}'`);
|
|
2478
2591
|
}
|
|
2479
|
-
})(op.index < content.data.length && content.data[op.index] === value)
|
|
2592
|
+
})(op.index < content.data.length && content.data[op.index] === value);
|
|
2480
2593
|
if (index !== -1) {
|
|
2481
2594
|
// we remove the first occurrence of the value
|
|
2482
2595
|
shouldNotify = true;
|
|
@@ -2497,24 +2610,24 @@ function removeResourceFromDocument(cache, op) {
|
|
|
2497
2610
|
if (shouldNotify) cache._capabilities.notifyChange(op.record, 'updated', null);
|
|
2498
2611
|
} else {
|
|
2499
2612
|
content.included = content.included || [];
|
|
2500
|
-
|
|
2613
|
+
(test => {
|
|
2501
2614
|
if (!test) {
|
|
2502
2615
|
throw new Error(`Expected to have a non-null operation value`);
|
|
2503
2616
|
}
|
|
2504
|
-
})(op.value)
|
|
2617
|
+
})(op.value);
|
|
2505
2618
|
const toRemove = Array.isArray(op.value) ? op.value : [op.value];
|
|
2506
2619
|
for (const identifier of toRemove) {
|
|
2507
|
-
|
|
2620
|
+
(test => {
|
|
2508
2621
|
if (!test) {
|
|
2509
2622
|
throw new Error(`attempted to remove a value from included that was not present in the included array`);
|
|
2510
2623
|
}
|
|
2511
|
-
})(content.included.includes(identifier))
|
|
2624
|
+
})(content.included.includes(identifier));
|
|
2512
2625
|
const index = content.included.indexOf(identifier);
|
|
2513
|
-
|
|
2626
|
+
(test => {
|
|
2514
2627
|
if (!test) {
|
|
2515
2628
|
throw new Error(`The value '${identifier.lid}' cannot be removed from the included of document '${op.record.lid}' as it is not present`);
|
|
2516
2629
|
}
|
|
2517
|
-
})(index !== -1)
|
|
2630
|
+
})(index !== -1);
|
|
2518
2631
|
if (index !== -1) {
|
|
2519
2632
|
content.included.splice(index, 1);
|
|
2520
2633
|
}
|
|
@@ -2570,11 +2683,11 @@ function getDefaultValue(schema, identifier, store) {
|
|
|
2570
2683
|
// legacy support for defaultValues that are primitives
|
|
2571
2684
|
} else if (options && 'defaultValue' in options) {
|
|
2572
2685
|
const defaultValue = options.defaultValue;
|
|
2573
|
-
|
|
2686
|
+
(test => {
|
|
2574
2687
|
if (!test) {
|
|
2575
2688
|
throw new Error(`Non primitive defaultValues are not supported because they are shared between all instances. If you would like to use a complex object as a default value please provide a function that returns the complex object.`);
|
|
2576
2689
|
}
|
|
2577
|
-
})(typeof defaultValue !== 'object' || defaultValue === null)
|
|
2690
|
+
})(typeof defaultValue !== 'object' || defaultValue === null);
|
|
2578
2691
|
return defaultValue;
|
|
2579
2692
|
|
|
2580
2693
|
// new style transforms
|
|
@@ -2723,16 +2836,16 @@ function patchLocalAttributes(cached, changedRemoteKeys) {
|
|
|
2723
2836
|
return hasAppliedPatch;
|
|
2724
2837
|
}
|
|
2725
2838
|
function putOne(cache, identifiers, resource) {
|
|
2726
|
-
|
|
2839
|
+
(test => {
|
|
2727
2840
|
if (!test) {
|
|
2728
2841
|
throw new Error(`You must include an 'id' for the resource data ${resource.type}`);
|
|
2729
2842
|
}
|
|
2730
|
-
})(resource.id !== null && resource.id !== undefined && resource.id !== '')
|
|
2731
|
-
|
|
2843
|
+
})(resource.id !== null && resource.id !== undefined && resource.id !== '');
|
|
2844
|
+
(test => {
|
|
2732
2845
|
if (!test) {
|
|
2733
2846
|
throw new Error(`Missing Resource Type: received resource data with a type '${resource.type}' but no schema could be found with that name.`);
|
|
2734
2847
|
}
|
|
2735
|
-
})(cache._capabilities.schema.hasResource(resource))
|
|
2848
|
+
})(cache._capabilities.schema.hasResource(resource));
|
|
2736
2849
|
let identifier = identifiers.peekResourceKey(resource);
|
|
2737
2850
|
if (identifier) {
|
|
2738
2851
|
identifier = identifiers.updateRecordIdentifier(identifier, resource);
|
|
@@ -2866,7 +2979,7 @@ function cacheUpsert(cache, identifier, data, calculateChanges) {
|
|
|
2866
2979
|
const cached = peeked || cache._createCache(identifier);
|
|
2867
2980
|
const isLoading = /*#__NOINLINE__*/_isLoading(peeked, cache._capabilities, identifier) || !recordIsLoaded(peeked);
|
|
2868
2981
|
const isUpdate = /*#__NOINLINE__*/!_isEmpty(peeked) && !isLoading;
|
|
2869
|
-
|
|
2982
|
+
{
|
|
2870
2983
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
2871
2984
|
logGroup('cache', 'upsert', identifier.type, identifier.lid, existed ? 'merged' : 'inserted', calculateChanges ? 'has-subscription' : '');
|
|
2872
2985
|
try {
|
|
@@ -2910,7 +3023,7 @@ function cacheUpsert(cache, identifier, data, calculateChanges) {
|
|
|
2910
3023
|
if (changedKeys?.size) {
|
|
2911
3024
|
notifyAttributes(cache._capabilities, identifier, changedKeys);
|
|
2912
3025
|
}
|
|
2913
|
-
|
|
3026
|
+
{
|
|
2914
3027
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
2915
3028
|
// eslint-disable-next-line no-console
|
|
2916
3029
|
console.groupEnd();
|
|
@@ -2921,12 +3034,12 @@ function cacheUpsert(cache, identifier, data, calculateChanges) {
|
|
|
2921
3034
|
function patchCache(Cache, op) {
|
|
2922
3035
|
const isRecord = isResourceKey(op.record);
|
|
2923
3036
|
const isDocument = !isRecord && isRequestKey(op.record);
|
|
2924
|
-
|
|
3037
|
+
(test => {
|
|
2925
3038
|
if (!test) {
|
|
2926
3039
|
throw new Error(`Expected Cache.patch op.record to be a record or document identifier`);
|
|
2927
3040
|
}
|
|
2928
|
-
})(isRecord || isDocument)
|
|
2929
|
-
|
|
3041
|
+
})(isRecord || isDocument);
|
|
3042
|
+
{
|
|
2930
3043
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
2931
3044
|
logGroup('cache', 'patch', isRecord ? op.record.type : '<@document>', op.record.lid, op.op, 'field' in op ? op.field : op.op === 'mergeIdentifiers' ? op.value.lid : '');
|
|
2932
3045
|
try {
|
|
@@ -2955,11 +3068,11 @@ function patchCache(Cache, op) {
|
|
|
2955
3068
|
if (isRecord) {
|
|
2956
3069
|
if ('field' in op) {
|
|
2957
3070
|
const field = getCacheFields(Cache, op.record).get(op.field);
|
|
2958
|
-
|
|
3071
|
+
(test => {
|
|
2959
3072
|
if (!test) {
|
|
2960
3073
|
throw new Error(`Expected ${op.field} to be a field on ${op.record.type}`);
|
|
2961
3074
|
}
|
|
2962
|
-
})(field)
|
|
3075
|
+
})(field);
|
|
2963
3076
|
if (isRelationship(field)) {
|
|
2964
3077
|
Cache.__graph.push(op);
|
|
2965
3078
|
} else {
|
|
@@ -2975,11 +3088,11 @@ function patchCache(Cache, op) {
|
|
|
2975
3088
|
Cache.upsert(op.record, op.value, Cache._capabilities.hasRecord(op.record));
|
|
2976
3089
|
}
|
|
2977
3090
|
} else {
|
|
2978
|
-
|
|
3091
|
+
(test => {
|
|
2979
3092
|
{
|
|
2980
3093
|
throw new Error(`Update operations on documents is not supported`);
|
|
2981
3094
|
}
|
|
2982
|
-
})()
|
|
3095
|
+
})();
|
|
2983
3096
|
}
|
|
2984
3097
|
break;
|
|
2985
3098
|
}
|
|
@@ -2992,11 +3105,11 @@ function patchCache(Cache, op) {
|
|
|
2992
3105
|
Cache.upsert(op.record, op.value, Cache._capabilities.hasRecord(op.record));
|
|
2993
3106
|
}
|
|
2994
3107
|
} else {
|
|
2995
|
-
|
|
3108
|
+
(test => {
|
|
2996
3109
|
if (!test) {
|
|
2997
3110
|
throw new Error(`Expected a field in the add operation`);
|
|
2998
3111
|
}
|
|
2999
|
-
})('field' in op)
|
|
3112
|
+
})('field' in op);
|
|
3000
3113
|
addResourceToDocument(Cache, op);
|
|
3001
3114
|
}
|
|
3002
3115
|
break;
|
|
@@ -3022,11 +3135,11 @@ function patchCache(Cache, op) {
|
|
|
3022
3135
|
}
|
|
3023
3136
|
} else {
|
|
3024
3137
|
if ('field' in op) {
|
|
3025
|
-
|
|
3138
|
+
(test => {
|
|
3026
3139
|
if (!test) {
|
|
3027
3140
|
throw new Error(`Expected a field in the remove operation`);
|
|
3028
3141
|
}
|
|
3029
|
-
})('field' in op)
|
|
3142
|
+
})('field' in op);
|
|
3030
3143
|
removeResourceFromDocument(Cache, op);
|
|
3031
3144
|
} else {
|
|
3032
3145
|
// TODO @runspired teardown associated state ... notify subscribers etc.
|
|
@@ -3034,23 +3147,23 @@ function patchCache(Cache, op) {
|
|
|
3034
3147
|
// holding onto reactive documents instead of the CacheHandler
|
|
3035
3148
|
// and use a subscription to remove them.
|
|
3036
3149
|
// Cache.__documents.delete(op.record.lid);
|
|
3037
|
-
|
|
3150
|
+
(test => {
|
|
3038
3151
|
{
|
|
3039
3152
|
throw new Error(`Removing documents from the cache is not yet supported`);
|
|
3040
3153
|
}
|
|
3041
|
-
})()
|
|
3154
|
+
})();
|
|
3042
3155
|
}
|
|
3043
3156
|
}
|
|
3044
3157
|
break;
|
|
3045
3158
|
}
|
|
3046
3159
|
default:
|
|
3047
|
-
|
|
3160
|
+
(test => {
|
|
3048
3161
|
{
|
|
3049
3162
|
throw new Error(`Unhandled cache.patch operation ${op.op}`);
|
|
3050
3163
|
}
|
|
3051
|
-
})()
|
|
3164
|
+
})();
|
|
3052
3165
|
}
|
|
3053
|
-
|
|
3166
|
+
{
|
|
3054
3167
|
if (getGlobalConfig().WarpDriveMirror.debug.LOG_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_CACHE) {
|
|
3055
3168
|
// eslint-disable-next-line no-console
|
|
3056
3169
|
console.groupEnd();
|
|
@@ -3086,11 +3199,11 @@ function commitDidError(cache, identifier, errors) {
|
|
|
3086
3199
|
}
|
|
3087
3200
|
function didCommit(cache, committedIdentifier, data, op) {
|
|
3088
3201
|
if (!data) {
|
|
3089
|
-
|
|
3202
|
+
(test => {
|
|
3090
3203
|
if (!test) {
|
|
3091
3204
|
throw new Error(`Your ${committedIdentifier.type} record was saved to the server, but the response does not have an id and no id has been set client side. Records must have ids. Please update the server response to provide an id in the response or generate the id on the client side either before saving the record or while normalizing the response.`);
|
|
3092
3205
|
}
|
|
3093
|
-
})(committedIdentifier.id)
|
|
3206
|
+
})(committedIdentifier.id);
|
|
3094
3207
|
}
|
|
3095
3208
|
const {
|
|
3096
3209
|
cacheKeyManager
|
|
@@ -3109,7 +3222,7 @@ function didCommit(cache, committedIdentifier, data, op) {
|
|
|
3109
3222
|
cache._capabilities.notifyChange(identifier, 'removed', null);
|
|
3110
3223
|
// TODO @runspired should we early exit here?
|
|
3111
3224
|
}
|
|
3112
|
-
|
|
3225
|
+
{
|
|
3113
3226
|
if (cached.isNew && !identifier.id && (typeof data?.id !== 'string' || data.id.length > 0)) {
|
|
3114
3227
|
const error = new Error(`Expected an id ${String(identifier)} in response ${JSON.stringify(data)}`);
|
|
3115
3228
|
//@ts-expect-error
|
|
@@ -3129,14 +3242,14 @@ function didCommit(cache, committedIdentifier, data, op) {
|
|
|
3129
3242
|
if (identifier === committedIdentifier && identifier.id !== existingId) {
|
|
3130
3243
|
cache._capabilities.notifyChange(identifier, 'identity', null);
|
|
3131
3244
|
}
|
|
3132
|
-
|
|
3245
|
+
(test => {
|
|
3133
3246
|
if (!test) {
|
|
3134
3247
|
throw new Error(`Expected the ID received for the primary '${identifier.type}' resource being saved to match the current id '${cached.id}' but received '${identifier.id}'.`);
|
|
3135
3248
|
}
|
|
3136
|
-
})(identifier.id === cached.id)
|
|
3249
|
+
})(identifier.id === cached.id);
|
|
3137
3250
|
if (data.relationships) {
|
|
3138
|
-
|
|
3139
|
-
|
|
3251
|
+
{
|
|
3252
|
+
{
|
|
3140
3253
|
// assert against bad API behavior where a belongsTo relationship
|
|
3141
3254
|
// is saved but the return payload indicates a different final state.
|
|
3142
3255
|
fields.forEach((field, name) => {
|
|
@@ -3148,11 +3261,11 @@ function didCommit(cache, committedIdentifier, data, op) {
|
|
|
3148
3261
|
return;
|
|
3149
3262
|
}
|
|
3150
3263
|
const actualData = relationshipData ? cache._capabilities.cacheKeyManager.getOrCreateRecordIdentifier(relationshipData) : null;
|
|
3151
|
-
|
|
3264
|
+
(test => {
|
|
3152
3265
|
if (!test) {
|
|
3153
3266
|
throw new Error(`Expected the resource relationship '<${identifier.type}>.${name}' on ${identifier.lid} to be saved as ${inFlightData.data ? inFlightData.data.lid : '<null>'} but it was saved as ${actualData ? actualData.lid : '<null>'}`);
|
|
3154
3267
|
}
|
|
3155
|
-
})(inFlightData.data === actualData)
|
|
3268
|
+
})(inFlightData.data === actualData);
|
|
3156
3269
|
}
|
|
3157
3270
|
}
|
|
3158
3271
|
});
|
|
@@ -3205,8 +3318,8 @@ function willCommit(cache, identifier) {
|
|
|
3205
3318
|
cached.inflightAttrs = cached.localAttrs;
|
|
3206
3319
|
}
|
|
3207
3320
|
cached.localAttrs = null;
|
|
3208
|
-
|
|
3209
|
-
|
|
3321
|
+
{
|
|
3322
|
+
{
|
|
3210
3323
|
// save off info about saved relationships
|
|
3211
3324
|
const fields = getCacheFields(cache, identifier);
|
|
3212
3325
|
fields.forEach((schema, name) => {
|