@warp-drive/core 5.9.0-alpha.17 → 5.9.0-alpha.18
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/graph/-private/-state.d.ts +1 -0
- package/declarations/reactive/-private/default-mode.d.ts +22 -9
- package/declarations/reactive/-private/kind/belongs-to-field.d.ts +3 -0
- package/declarations/types/runtime.d.ts +16 -0
- package/declarations/types/schema/fields.d.ts +40 -12
- package/dist/graph/-private.js +50 -31
- package/dist/{index-CFwnjldF.js → index-BoY6aNE5.js} +88 -9
- package/dist/index.js +1 -1
- package/dist/reactive.js +1 -1
- package/dist/store/-private.js +1 -1
- package/dist/types/-private.js +1 -1
- package/dist/types/runtime.js +20 -1
- package/dist/unpkg/dev/graph/-private.js +50 -31
- package/dist/unpkg/dev/{index-BZRBBa34.js → index-BZ6PKU-a.js} +88 -9
- package/dist/unpkg/dev/index.js +1 -1
- package/dist/unpkg/dev/reactive.js +1 -1
- package/dist/unpkg/dev/store/-private.js +2 -2
- package/dist/unpkg/dev/types/-private.js +1 -1
- package/dist/unpkg/dev/types/runtime.js +20 -1
- package/dist/unpkg/dev-deprecated/graph/-private.js +50 -31
- package/dist/unpkg/dev-deprecated/{index-Bu52tQ9I.js → index-CDjd631s.js} +88 -9
- package/dist/unpkg/dev-deprecated/index.js +1 -1
- package/dist/unpkg/dev-deprecated/reactive.js +1 -1
- package/dist/unpkg/dev-deprecated/store/-private.js +1 -1
- package/dist/unpkg/dev-deprecated/types/-private.js +1 -1
- package/dist/unpkg/dev-deprecated/types/runtime.js +20 -1
- package/dist/unpkg/prod/{-leaked-BHLmJyaw.js → -leaked-DgjQ5X55.js} +2 -2
- package/dist/unpkg/prod/configure.js +1 -1
- package/dist/unpkg/prod/graph/-private.js +17 -25
- package/dist/unpkg/prod/{schema-BdC3DirM.js → index-BMBm3kYx.js} +2256 -91
- package/dist/unpkg/prod/index.js +5 -483
- package/dist/unpkg/prod/{promise-cache-DIT8Ypjq.js → promise-cache-DUblkX-U.js} +1 -1
- package/dist/unpkg/prod/reactive.js +3 -29
- package/dist/unpkg/prod/{request-BrJSCG6r.js → request-eb7Zm-oS.js} +1 -1
- package/dist/unpkg/prod/request.js +2 -2
- package/dist/unpkg/prod/signals/-leaked.js +1 -1
- package/dist/unpkg/prod/store/-private.js +2 -3
- package/dist/unpkg/prod/types/-private.js +1 -1
- package/dist/unpkg/prod/types/runtime.js +20 -1
- package/dist/unpkg/prod-deprecated/{-leaked-D_5Yrs5c.js → -leaked-BNVttukY.js} +1 -1
- package/dist/unpkg/prod-deprecated/configure.js +1 -1
- package/dist/unpkg/prod-deprecated/graph/-private.js +17 -25
- package/dist/unpkg/prod-deprecated/{schema-h0nuUTCj.js → index-CZkDXZog.js} +890 -7
- package/dist/unpkg/prod-deprecated/index.js +5 -483
- package/dist/unpkg/prod-deprecated/{promise-cache-DIT8Ypjq.js → promise-cache-DUblkX-U.js} +1 -1
- package/dist/unpkg/prod-deprecated/reactive.js +2 -3
- package/dist/unpkg/prod-deprecated/{request-BrJSCG6r.js → request-eb7Zm-oS.js} +1 -1
- package/dist/unpkg/prod-deprecated/request.js +2 -2
- package/dist/unpkg/prod-deprecated/signals/-leaked.js +1 -1
- package/dist/unpkg/prod-deprecated/store/-private.js +1 -2
- package/dist/unpkg/prod-deprecated/types/-private.js +1 -1
- package/dist/unpkg/prod-deprecated/types/runtime.js +20 -1
- package/package.json +3 -3
- package/dist/unpkg/prod/handler-BJogFbfS.js +0 -1619
- package/dist/unpkg/prod-deprecated/handler-kGR8zguj.js +0 -334
- package/dist/unpkg/prod-deprecated/hooks-wJdveHPi.js +0 -26
|
@@ -55,9 +55,14 @@ function assertValidRelationshipPayload(graph, op) {
|
|
|
55
55
|
kind
|
|
56
56
|
} = definition;
|
|
57
57
|
if (payload.links) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
// once JSON_API_CACHE_VALIDATION_ERRORS is active, this warning is instead
|
|
59
|
+
// the responsibility of the new document validator (see validateResourceRelationships
|
|
60
|
+
// in warp-drive-packages/json-api/src/-private/validator/1.1/7.2_resource-objects.ts)
|
|
61
|
+
{
|
|
62
|
+
console.warn(`You pushed a record of type '${type}' with a relationship '${field}' configured as 'async: false'. You've included a link but no primary data, this may be an error in your payload. WarpDrive will treat this relationship as known-to-be-empty.`, isAsync || payload.data === null || !!payload.data || state.hasReceivedData, {
|
|
63
|
+
id: 'ds.store.push-link-for-sync-relationship'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
61
66
|
} else if (payload.data) {
|
|
62
67
|
if (kind === 'belongsTo') {
|
|
63
68
|
(test => {
|
|
@@ -1355,8 +1360,10 @@ function replaceRelatedRecord(graph, op, isRemote = false) {
|
|
|
1355
1360
|
if (op.value === existingState) {
|
|
1356
1361
|
// if we were empty before but now know we are empty this needs to be true
|
|
1357
1362
|
state.hasReceivedData = true;
|
|
1363
|
+
|
|
1358
1364
|
// if this is a remote update we still sync
|
|
1359
1365
|
if (isRemote) {
|
|
1366
|
+
state.hasReceivedRemoteData = true;
|
|
1360
1367
|
const {
|
|
1361
1368
|
localState
|
|
1362
1369
|
} = relationship;
|
|
@@ -1379,6 +1386,15 @@ function replaceRelatedRecord(graph, op, isRemote = false) {
|
|
|
1379
1386
|
// update value to the new value
|
|
1380
1387
|
relationship[prop] = op.value;
|
|
1381
1388
|
state.hasReceivedData = true;
|
|
1389
|
+
/**
|
|
1390
|
+
* Local mutations never give us additional information about
|
|
1391
|
+
* whether the relationship has received *remote* data. This is
|
|
1392
|
+
* what `getRemoteRelationship` relies on to avoid reflecting
|
|
1393
|
+
* local-only edits.
|
|
1394
|
+
*/
|
|
1395
|
+
if (isRemote) {
|
|
1396
|
+
state.hasReceivedRemoteData = true;
|
|
1397
|
+
}
|
|
1382
1398
|
state.isEmpty = op.value === null;
|
|
1383
1399
|
state.isStale = false;
|
|
1384
1400
|
state.hasFailedLoadAttempt = false;
|
|
@@ -1890,8 +1906,30 @@ function rollbackRelationship(graph, key, field, relationship) {
|
|
|
1890
1906
|
}
|
|
1891
1907
|
}
|
|
1892
1908
|
function createState() {
|
|
1909
|
+
{
|
|
1910
|
+
{
|
|
1911
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
|
|
1912
|
+
let hasReceivedData = false;
|
|
1913
|
+
return {
|
|
1914
|
+
get hasReceivedData() {
|
|
1915
|
+
return hasReceivedData;
|
|
1916
|
+
},
|
|
1917
|
+
set hasReceivedData(value) {
|
|
1918
|
+
hasReceivedData = value;
|
|
1919
|
+
},
|
|
1920
|
+
hasReceivedRemoteData: false,
|
|
1921
|
+
isEmpty: true,
|
|
1922
|
+
isStale: false,
|
|
1923
|
+
hasFailedLoadAttempt: false,
|
|
1924
|
+
shouldForceReload: false,
|
|
1925
|
+
hasDematerializedInverse: false
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1893
1930
|
return {
|
|
1894
1931
|
hasReceivedData: false,
|
|
1932
|
+
hasReceivedRemoteData: false,
|
|
1895
1933
|
isEmpty: true,
|
|
1896
1934
|
isStale: false,
|
|
1897
1935
|
hasFailedLoadAttempt: false,
|
|
@@ -1996,13 +2034,10 @@ function legacyGetResourceRelationshipData(source, getRemoteState) {
|
|
|
1996
2034
|
source.accessed = true;
|
|
1997
2035
|
let data;
|
|
1998
2036
|
const payload = {};
|
|
1999
|
-
if (getRemoteState && source.remoteState) {
|
|
2000
|
-
data = source.remoteState;
|
|
2001
|
-
} else if (!getRemoteState && source.localState) {
|
|
2002
|
-
data = source.localState;
|
|
2003
|
-
}
|
|
2004
|
-
if ((getRemoteState && source.remoteState === null || source.localState === null) && source.state.hasReceivedData) {
|
|
2005
|
-
data = null;
|
|
2037
|
+
if (getRemoteState && (source.remoteState || source.state.hasReceivedRemoteData)) {
|
|
2038
|
+
data = source.remoteState ?? null;
|
|
2039
|
+
} else if (!getRemoteState && (source.localState || source.state.hasReceivedData)) {
|
|
2040
|
+
data = source.localState ?? null;
|
|
2006
2041
|
}
|
|
2007
2042
|
if (source.links) {
|
|
2008
2043
|
payload.links = source.links;
|
|
@@ -2216,7 +2251,6 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2216
2251
|
})(isHasMany(relationship) || isBelongsTo(relationship));
|
|
2217
2252
|
const {
|
|
2218
2253
|
definition,
|
|
2219
|
-
state,
|
|
2220
2254
|
identifier
|
|
2221
2255
|
} = relationship;
|
|
2222
2256
|
const {
|
|
@@ -2256,23 +2290,6 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2256
2290
|
value: payload.data ? graph.store.cacheKeyManager.upgradeIdentifier(payload.data) : null
|
|
2257
2291
|
}, true);
|
|
2258
2292
|
}
|
|
2259
|
-
} else if (definition.isAsync === false && !state.hasReceivedData) {
|
|
2260
|
-
hasRelationshipDataProperty = true;
|
|
2261
|
-
if (isCollection) {
|
|
2262
|
-
graph.update({
|
|
2263
|
-
op: 'replaceRelatedRecords',
|
|
2264
|
-
record: identifier,
|
|
2265
|
-
field: op.field,
|
|
2266
|
-
value: []
|
|
2267
|
-
}, true);
|
|
2268
|
-
} else {
|
|
2269
|
-
graph.update({
|
|
2270
|
-
op: 'replaceRelatedRecord',
|
|
2271
|
-
record: identifier,
|
|
2272
|
-
field: op.field,
|
|
2273
|
-
value: null
|
|
2274
|
-
}, true);
|
|
2275
|
-
}
|
|
2276
2293
|
}
|
|
2277
2294
|
if (payload.links) {
|
|
2278
2295
|
const originalLinks = relationship.links;
|
|
@@ -2282,9 +2299,10 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2282
2299
|
const currentLink = originalLinks && originalLinks.related ? _normalizeLink(originalLinks.related) : null;
|
|
2283
2300
|
const currentLinkHref = currentLink ? currentLink.href : null;
|
|
2284
2301
|
if (relatedLink && relatedLink.href && relatedLink.href !== currentLinkHref) {
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2302
|
+
// Note: the equivalent warning for this case is issued eagerly (and with a more
|
|
2303
|
+
// complete condition, since it also accounts for `payload.data` being present) by
|
|
2304
|
+
// `assertValidRelationshipPayload` in `-utils.ts`, which always runs immediately
|
|
2305
|
+
// before this operation in DEBUG builds. Warning here too would double-warn.
|
|
2288
2306
|
(test => {
|
|
2289
2307
|
if (!test) {
|
|
2290
2308
|
throw new Error(`You have pushed a record of type '${identifier.type}' with '${definition.key}' as a link, but the value of that link is not a string.`);
|
|
@@ -2315,6 +2333,7 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2315
2333
|
// we don't need to notify here as the update op we pushed in above will notify once
|
|
2316
2334
|
// membership is in the correct state.
|
|
2317
2335
|
relationship.state.hasReceivedData = true;
|
|
2336
|
+
relationship.state.hasReceivedRemoteData = true;
|
|
2318
2337
|
relationship.state.isStale = false;
|
|
2319
2338
|
relationship.state.hasDematerializedInverse = false;
|
|
2320
2339
|
relationship.state.isEmpty = relationshipIsEmpty;
|
|
@@ -2,13 +2,13 @@ import { D as Destroy, C as Context, S as SOURCE, a as Checkout, b as Commit } f
|
|
|
2
2
|
import { d as defineGate, w as withSignalStore, n as notifyInternalSignal, p as peekInternalSignal, a as willSyncFlushWatchers, g as getOrCreateInternalSignal, c as consumeInternalSignal, b as createInternalSignal, A as ARRAY_SIGNAL, S as Signals, e as createSignalDescriptor, f as defineSignal, h as entangleSignal, i as entangleInitiallyStaleSignal, O as OBJECT_SIGNAL, j as createInternalMemo, o as waitFor } from "./-leaked-BohmerbH.js";
|
|
3
3
|
import { EnableHydration, SkipCache, STRUCTURED } from './types/request.js';
|
|
4
4
|
import { isResourceSchema } from './types/schema/fields.js';
|
|
5
|
+
import { setLogging, getRuntimeConfig, setIsMaybeMirage } from './types/runtime.js';
|
|
5
6
|
import { a as cloneResponseProperties, I as IS_CACHE_HANDLER, b as assertValidRequest, e as executeNextHandler, d as getRequestResult, u as upgradePromise, s as setPromiseResult, f as clearRequestResult } from "./future-DUuPqyLj.js";
|
|
6
7
|
import { getOrSetGlobal, setTransient, peekTransient, peekUniversalTransient, setUniversalTransient } from './types/-private.js';
|
|
7
8
|
import { DefaultCachePolicy } from './store.js';
|
|
8
9
|
import { withBrand } from './request.js';
|
|
9
10
|
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_KEY_TYPE, DEBUG_CLIENT_ORIGINATED } from './types/identifier.js';
|
|
10
11
|
import { g as getGlobalConfig } from "./runtime-DGG4CvlW.js";
|
|
11
|
-
import { setLogging, getRuntimeConfig } from './types/runtime.js';
|
|
12
12
|
import { RecordStore, Type } from './types/symbols.js';
|
|
13
13
|
function urlFromLink(link) {
|
|
14
14
|
if (typeof link === 'string') return link;
|
|
@@ -6660,11 +6660,32 @@ function getBelongsToField(context) {
|
|
|
6660
6660
|
}
|
|
6661
6661
|
function setBelongsToField(context) {
|
|
6662
6662
|
const {
|
|
6663
|
+
field,
|
|
6664
|
+
resourceKey,
|
|
6663
6665
|
store
|
|
6664
6666
|
} = context;
|
|
6665
6667
|
const {
|
|
6666
|
-
schema
|
|
6668
|
+
schema,
|
|
6669
|
+
cache
|
|
6667
6670
|
} = store;
|
|
6671
|
+
|
|
6672
|
+
/**
|
|
6673
|
+
* We currently only allow editing sync belongsTo relationships
|
|
6674
|
+
* in PolarisMode
|
|
6675
|
+
*/
|
|
6676
|
+
const isValidPolarisConfig = field.options.linksMode && !field.options.async;
|
|
6677
|
+
if (!context.legacy && isValidPolarisConfig) {
|
|
6678
|
+
const name = context.path.at(-1);
|
|
6679
|
+
cache.mutate({
|
|
6680
|
+
op: 'replaceRelatedRecord',
|
|
6681
|
+
record: resourceKey,
|
|
6682
|
+
field: name,
|
|
6683
|
+
value: getResourceKey(context.value)
|
|
6684
|
+
},
|
|
6685
|
+
// @ts-expect-error
|
|
6686
|
+
true);
|
|
6687
|
+
return true;
|
|
6688
|
+
}
|
|
6668
6689
|
(test => {
|
|
6669
6690
|
if (!test) {
|
|
6670
6691
|
throw new Error(`Can only mutate belongsTo fields when the resource is in legacy mode`);
|
|
@@ -6673,6 +6694,12 @@ function setBelongsToField(context) {
|
|
|
6673
6694
|
schema._kind('@legacy', 'belongsTo').set(store, context.record, context.resourceKey, context.field, context.value);
|
|
6674
6695
|
return true;
|
|
6675
6696
|
}
|
|
6697
|
+
function getResourceKey(record) {
|
|
6698
|
+
if (!record) {
|
|
6699
|
+
return null;
|
|
6700
|
+
}
|
|
6701
|
+
return recordIdentifierFor(record);
|
|
6702
|
+
}
|
|
6676
6703
|
function getCollectionField(context) {
|
|
6677
6704
|
entangleSignal(context.signals, context.record, context.path.at(-1), null);
|
|
6678
6705
|
(test => {
|
|
@@ -7405,6 +7432,17 @@ function setSchemaObjectField(context) {
|
|
|
7405
7432
|
// }
|
|
7406
7433
|
return true;
|
|
7407
7434
|
}
|
|
7435
|
+
|
|
7436
|
+
/**
|
|
7437
|
+
* A ReactiveResource context object passed to
|
|
7438
|
+
* the get/set functions of a field kind implementation.
|
|
7439
|
+
*
|
|
7440
|
+
* This provides all the necessary information for
|
|
7441
|
+
* the field kind to perform its operations.
|
|
7442
|
+
*
|
|
7443
|
+
* @internal
|
|
7444
|
+
*/
|
|
7445
|
+
|
|
7408
7446
|
const DefaultMode = {
|
|
7409
7447
|
'@hash': {
|
|
7410
7448
|
get: getHashField,
|
|
@@ -8198,6 +8236,14 @@ const TypeField = {
|
|
|
8198
8236
|
key: 'type'
|
|
8199
8237
|
}
|
|
8200
8238
|
};
|
|
8239
|
+
const IdentifierField = {
|
|
8240
|
+
type: '@identity',
|
|
8241
|
+
name: '$key',
|
|
8242
|
+
kind: 'derived',
|
|
8243
|
+
options: {
|
|
8244
|
+
key: '^'
|
|
8245
|
+
}
|
|
8246
|
+
};
|
|
8201
8247
|
const DefaultIdentityField = {
|
|
8202
8248
|
name: 'id',
|
|
8203
8249
|
kind: '@id'
|
|
@@ -8386,6 +8432,7 @@ function withDefaults(schema) {
|
|
|
8386
8432
|
// we add TypeField to the beginning so that it will
|
|
8387
8433
|
// appear right next to the identity field
|
|
8388
8434
|
schema.fields.unshift(TypeField);
|
|
8435
|
+
schema.fields.unshift(IdentifierField);
|
|
8389
8436
|
schema.fields.push(ConstructorField);
|
|
8390
8437
|
return schema;
|
|
8391
8438
|
}
|
|
@@ -8875,9 +8922,33 @@ function cloneResponse(response, overrides) {
|
|
|
8875
8922
|
const props = cloneResponseProperties(response);
|
|
8876
8923
|
return new Response(response.body, Object.assign(props, overrides));
|
|
8877
8924
|
}
|
|
8925
|
+
function withDateHeader(response) {
|
|
8926
|
+
const headers = new Headers(response.headers);
|
|
8927
|
+
headers.set('date', new Date().toUTCString());
|
|
8928
|
+
return cloneResponse(response, {
|
|
8929
|
+
headers
|
|
8930
|
+
});
|
|
8931
|
+
}
|
|
8932
|
+
|
|
8933
|
+
// Detects Mirage (or another Pretender-based fetch mock), whose `Response`
|
|
8934
|
+
// may (unlike a spec-compliant `fetch()`, whose Response headers are always
|
|
8935
|
+
// immutable) allow header mutation and may not support streaming reads.
|
|
8936
|
+
//
|
|
8937
|
+
// This is inherently a heuristic - many legitimate tools (APM/monitoring
|
|
8938
|
+
// agents, browser extensions, polyfills) also patch `window.fetch`, and can
|
|
8939
|
+
// produce false positives. `setWarpDriveIsMaybeMirage(value)` lets an app
|
|
8940
|
+
// declare the answer explicitly (`true` or `false`), overriding the
|
|
8941
|
+
// heuristic in either direction; leave it unset to keep the default
|
|
8942
|
+
// detection. See https://github.com/warp-drive-data/warp-drive/issues/10535
|
|
8878
8943
|
let IS_MAYBE_MIRAGE = () => false;
|
|
8879
8944
|
{
|
|
8880
|
-
IS_MAYBE_MIRAGE = () =>
|
|
8945
|
+
IS_MAYBE_MIRAGE = () => {
|
|
8946
|
+
const override = getRuntimeConfig().mirage;
|
|
8947
|
+
if (override !== undefined) {
|
|
8948
|
+
return override;
|
|
8949
|
+
}
|
|
8950
|
+
return Boolean(typeof window !== 'undefined' && (window.server?.pretender || window.fetch.toString().replace(/\s+/g, '') !== 'function fetch() { [native code] }'.replace(/\s+/g, '')));
|
|
8951
|
+
};
|
|
8881
8952
|
}
|
|
8882
8953
|
const MUTATION_OPS = new Set(['updateRecord', 'createRecord', 'deleteRecord']);
|
|
8883
8954
|
const ERROR_STATUS_CODE_FOR = new Map([[400, 'Bad Request'], [401, 'Unauthorized'], [402, 'Payment Required'], [403, 'Forbidden'], [404, 'Not Found'], [405, 'Method Not Allowed'], [406, 'Not Acceptable'], [407, 'Proxy Authentication Required'], [408, 'Request Timeout'], [409, 'Conflict'], [410, 'Gone'], [411, 'Length Required'], [412, 'Precondition Failed'], [413, 'Payload Too Large'], [414, 'URI Too Long'], [415, 'Unsupported Media Type'], [416, 'Range Not Satisfiable'], [417, 'Expectation Failed'], [419, 'Page Expired'], [420, 'Enhance Your Calm'], [421, 'Misdirected Request'], [422, 'Unprocessable Entity'], [423, 'Locked'], [424, 'Failed Dependency'], [425, 'Too Early'], [426, 'Upgrade Required'], [428, 'Precondition Required'], [429, 'Too Many Requests'], [430, 'Request Header Fields Too Large'], [431, 'Request Header Fields Too Large'], [450, 'Blocked By Windows Parental Controls'], [451, 'Unavailable For Legal Reasons'], [500, 'Internal Server Error'], [501, 'Not Implemented'], [502, 'Bad Gateway'], [503, 'Service Unavailable'], [504, 'Gateway Timeout'], [505, 'HTTP Version Not Supported'], [506, 'Variant Also Negotiates'], [507, 'Insufficient Storage'], [508, 'Loop Detected'], [509, 'Bandwidth Limit Exceeded'], [510, 'Not Extended'], [511, 'Network Authentication Required']]);
|
|
@@ -8929,13 +9000,15 @@ const Fetch = {
|
|
|
8929
9000
|
const isMutationOp = Boolean(op && MUTATION_OPS.has(op));
|
|
8930
9001
|
if (!isError && !isMutationOp && response.status !== 204 && !response.headers.has('date')) {
|
|
8931
9002
|
if (IS_MAYBE_MIRAGE()) {
|
|
8932
|
-
|
|
9003
|
+
try {
|
|
9004
|
+
response.headers.set('date', new Date().toUTCString());
|
|
9005
|
+
} catch {
|
|
9006
|
+
// IS_MAYBE_MIRAGE() was a false positive, or the mock's headers
|
|
9007
|
+
// are (correctly) immutable - fall back to cloning.
|
|
9008
|
+
response = withDateHeader(response);
|
|
9009
|
+
}
|
|
8933
9010
|
} else {
|
|
8934
|
-
|
|
8935
|
-
headers.set('date', new Date().toUTCString());
|
|
8936
|
-
response = cloneResponse(response, {
|
|
8937
|
-
headers
|
|
8938
|
-
});
|
|
9011
|
+
response = withDateHeader(response);
|
|
8939
9012
|
}
|
|
8940
9013
|
}
|
|
8941
9014
|
context.setResponse(response);
|
|
@@ -9330,6 +9403,12 @@ class RequestManager {
|
|
|
9330
9403
|
globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
|
|
9331
9404
|
}
|
|
9332
9405
|
|
|
9406
|
+
// Mirage (or another Pretender-based fetch mock) may be used outside of a
|
|
9407
|
+
// `TESTING` build (e.g. `ember serve` in dev mode), so this override is
|
|
9408
|
+
// exposed unconditionally rather than gated to the `TESTING` env.
|
|
9409
|
+
// @ts-expect-error adding to globalThis
|
|
9410
|
+
globalThis.setWarpDriveIsMaybeMirage = setIsMaybeMirage;
|
|
9411
|
+
|
|
9333
9412
|
/**
|
|
9334
9413
|
* Options for setting up a Store instance with `useRecommendedStore`.
|
|
9335
9414
|
*/
|
package/dist/unpkg/dev/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as CacheHandler, F as Fetch, y as RequestManager, S as Store, r as cacheKeyFor, r as recordIdentifierFor, D as setIdentifierForgetMethod, A as setIdentifierGenerationMethod, E as setIdentifierResetMethod, B as setIdentifierUpdateMethod, G as setKeyInfoForResource, s as storeFor, z as useRecommendedStore } from "./index-
|
|
1
|
+
export { C as CacheHandler, F as Fetch, y as RequestManager, S as Store, r as cacheKeyFor, r as recordIdentifierFor, D as setIdentifierForgetMethod, A as setIdentifierGenerationMethod, E as setIdentifierResetMethod, B as setIdentifierUpdateMethod, G as setKeyInfoForResource, s as storeFor, z as useRecommendedStore } from "./index-BZ6PKU-a.js";
|
|
2
2
|
import "./-private-sql1_mdx.js";
|
|
3
3
|
import "./-leaked-BohmerbH.js";
|
|
4
4
|
import './store.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { q as SchemaService, o as checkout, x as commit, u as fromIdentity, p as instantiateRecord, v as registerDerivations, t as teardownRecord, w as withDefaults } from "./index-
|
|
1
|
+
export { q as SchemaService, o as checkout, x as commit, u as fromIdentity, p as instantiateRecord, v as registerDerivations, t as teardownRecord, w as withDefaults } from "./index-BZ6PKU-a.js";
|
|
2
2
|
export { a as Checkout } from "./-private-sql1_mdx.js";
|
|
3
3
|
export { k as createRequestSubscription, m as getPromiseState, l as getRequestState } from "./-leaked-BohmerbH.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../types/request.js';
|
|
2
|
-
import { i as isResourceKey, c as coerceId } from "../index-
|
|
3
|
-
export { C as CacheHandler, R as RecordArrayManager, S as Store, j as StoreMap, _ as _clearCaches, n as _deprecatingNormalize, g as assertPrivateCapabilities, b as assertPrivateStore, k as createLegacyManyArray, e as ensureStringId, f as fastPush, d as isPrivateStore, a as isRequestKey, l as log, m as logGroup, r as recordIdentifierFor, h as setRecordIdentifier, s as storeFor } from "../index-
|
|
2
|
+
import { i as isResourceKey, c as coerceId } from "../index-BZ6PKU-a.js";
|
|
3
|
+
export { C as CacheHandler, R as RecordArrayManager, S as Store, j as StoreMap, _ as _clearCaches, n as _deprecatingNormalize, g as assertPrivateCapabilities, b as assertPrivateStore, k as createLegacyManyArray, e as ensureStringId, f as fastPush, d as isPrivateStore, a as isRequestKey, l as log, m as logGroup, r as recordIdentifierFor, h as setRecordIdentifier, s as storeFor } from "../index-BZ6PKU-a.js";
|
|
4
4
|
function isNonEmptyString(str) {
|
|
5
5
|
return Boolean(str && typeof str === 'string');
|
|
6
6
|
}
|
|
@@ -31,4 +31,23 @@ function setLogging(config) {
|
|
|
31
31
|
Object.assign(RuntimeConfig.debug, config);
|
|
32
32
|
storage?.setItem('WarpDriveRuntimeConfig', JSON.stringify(RuntimeConfig));
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Explicitly declares whether requests may be served by Mirage (or another
|
|
37
|
+
* Pretender-based fetch mock) instead of a native `fetch` implementation.
|
|
38
|
+
*
|
|
39
|
+
* The `Fetch` request handler otherwise infers this via a heuristic (the
|
|
40
|
+
* presence of `window.server.pretender`, or `window.fetch` appearing to be
|
|
41
|
+
* patched), which can be wrong in either direction: some Mirage setups don't
|
|
42
|
+
* expose `window.server`, while some unrelated tools (APM agents, browser
|
|
43
|
+
* extensions) also patch `fetch`. Call this to override that heuristic:
|
|
44
|
+
* `true` to force Mirage-compatible behavior on, `false` to force it off.
|
|
45
|
+
*
|
|
46
|
+
* globalThis.setWarpDriveIsMaybeMirage(true);
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
function setIsMaybeMirage(value) {
|
|
50
|
+
RuntimeConfig.mirage = value;
|
|
51
|
+
storage?.setItem('WarpDriveRuntimeConfig', JSON.stringify(RuntimeConfig));
|
|
52
|
+
}
|
|
53
|
+
export { getRuntimeConfig, setIsMaybeMirage, setLogging };
|
|
@@ -59,9 +59,14 @@ function assertValidRelationshipPayload(graph, op) {
|
|
|
59
59
|
kind
|
|
60
60
|
} = definition;
|
|
61
61
|
if (payload.links) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
// once JSON_API_CACHE_VALIDATION_ERRORS is active, this warning is instead
|
|
63
|
+
// the responsibility of the new document validator (see validateResourceRelationships
|
|
64
|
+
// in warp-drive-packages/json-api/src/-private/validator/1.1/7.2_resource-objects.ts)
|
|
65
|
+
{
|
|
66
|
+
console.warn(`You pushed a record of type '${type}' with a relationship '${field}' configured as 'async: false'. You've included a link but no primary data, this may be an error in your payload. WarpDrive will treat this relationship as known-to-be-empty.`, isAsync || payload.data === null || !!payload.data || state.hasReceivedData, {
|
|
67
|
+
id: 'ds.store.push-link-for-sync-relationship'
|
|
68
|
+
});
|
|
69
|
+
}
|
|
65
70
|
} else if (payload.data) {
|
|
66
71
|
if (kind === 'belongsTo') {
|
|
67
72
|
(test => {
|
|
@@ -1409,8 +1414,10 @@ function replaceRelatedRecord(graph, op, isRemote = false) {
|
|
|
1409
1414
|
if (op.value === existingState) {
|
|
1410
1415
|
// if we were empty before but now know we are empty this needs to be true
|
|
1411
1416
|
state.hasReceivedData = true;
|
|
1417
|
+
|
|
1412
1418
|
// if this is a remote update we still sync
|
|
1413
1419
|
if (isRemote) {
|
|
1420
|
+
state.hasReceivedRemoteData = true;
|
|
1414
1421
|
const {
|
|
1415
1422
|
localState
|
|
1416
1423
|
} = relationship;
|
|
@@ -1441,6 +1448,15 @@ function replaceRelatedRecord(graph, op, isRemote = false) {
|
|
|
1441
1448
|
// update value to the new value
|
|
1442
1449
|
relationship[prop] = op.value;
|
|
1443
1450
|
state.hasReceivedData = true;
|
|
1451
|
+
/**
|
|
1452
|
+
* Local mutations never give us additional information about
|
|
1453
|
+
* whether the relationship has received *remote* data. This is
|
|
1454
|
+
* what `getRemoteRelationship` relies on to avoid reflecting
|
|
1455
|
+
* local-only edits.
|
|
1456
|
+
*/
|
|
1457
|
+
if (isRemote) {
|
|
1458
|
+
state.hasReceivedRemoteData = true;
|
|
1459
|
+
}
|
|
1444
1460
|
state.isEmpty = op.value === null;
|
|
1445
1461
|
state.isStale = false;
|
|
1446
1462
|
state.hasFailedLoadAttempt = false;
|
|
@@ -2085,8 +2101,30 @@ function rollbackRelationship(graph, key, field, relationship) {
|
|
|
2085
2101
|
}
|
|
2086
2102
|
}
|
|
2087
2103
|
function createState() {
|
|
2104
|
+
{
|
|
2105
|
+
{
|
|
2106
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
|
|
2107
|
+
let hasReceivedData = false;
|
|
2108
|
+
return {
|
|
2109
|
+
get hasReceivedData() {
|
|
2110
|
+
return hasReceivedData;
|
|
2111
|
+
},
|
|
2112
|
+
set hasReceivedData(value) {
|
|
2113
|
+
hasReceivedData = value;
|
|
2114
|
+
},
|
|
2115
|
+
hasReceivedRemoteData: false,
|
|
2116
|
+
isEmpty: true,
|
|
2117
|
+
isStale: false,
|
|
2118
|
+
hasFailedLoadAttempt: false,
|
|
2119
|
+
shouldForceReload: false,
|
|
2120
|
+
hasDematerializedInverse: false
|
|
2121
|
+
};
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2088
2125
|
return {
|
|
2089
2126
|
hasReceivedData: false,
|
|
2127
|
+
hasReceivedRemoteData: false,
|
|
2090
2128
|
isEmpty: true,
|
|
2091
2129
|
isStale: false,
|
|
2092
2130
|
hasFailedLoadAttempt: false,
|
|
@@ -2191,13 +2229,10 @@ function legacyGetResourceRelationshipData(source, getRemoteState) {
|
|
|
2191
2229
|
source.accessed = true;
|
|
2192
2230
|
let data;
|
|
2193
2231
|
const payload = {};
|
|
2194
|
-
if (getRemoteState && source.remoteState) {
|
|
2195
|
-
data = source.remoteState;
|
|
2196
|
-
} else if (!getRemoteState && source.localState) {
|
|
2197
|
-
data = source.localState;
|
|
2198
|
-
}
|
|
2199
|
-
if ((getRemoteState && source.remoteState === null || source.localState === null) && source.state.hasReceivedData) {
|
|
2200
|
-
data = null;
|
|
2232
|
+
if (getRemoteState && (source.remoteState || source.state.hasReceivedRemoteData)) {
|
|
2233
|
+
data = source.remoteState ?? null;
|
|
2234
|
+
} else if (!getRemoteState && (source.localState || source.state.hasReceivedData)) {
|
|
2235
|
+
data = source.localState ?? null;
|
|
2201
2236
|
}
|
|
2202
2237
|
if (source.links) {
|
|
2203
2238
|
payload.links = source.links;
|
|
@@ -2411,7 +2446,6 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2411
2446
|
})(isHasMany(relationship) || isBelongsTo(relationship));
|
|
2412
2447
|
const {
|
|
2413
2448
|
definition,
|
|
2414
|
-
state,
|
|
2415
2449
|
identifier
|
|
2416
2450
|
} = relationship;
|
|
2417
2451
|
const {
|
|
@@ -2451,23 +2485,6 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2451
2485
|
value: payload.data ? graph.store.cacheKeyManager.upgradeIdentifier(payload.data) : null
|
|
2452
2486
|
}, true);
|
|
2453
2487
|
}
|
|
2454
|
-
} else if (definition.isAsync === false && !state.hasReceivedData) {
|
|
2455
|
-
hasRelationshipDataProperty = true;
|
|
2456
|
-
if (isCollection) {
|
|
2457
|
-
graph.update({
|
|
2458
|
-
op: 'replaceRelatedRecords',
|
|
2459
|
-
record: identifier,
|
|
2460
|
-
field: op.field,
|
|
2461
|
-
value: []
|
|
2462
|
-
}, true);
|
|
2463
|
-
} else {
|
|
2464
|
-
graph.update({
|
|
2465
|
-
op: 'replaceRelatedRecord',
|
|
2466
|
-
record: identifier,
|
|
2467
|
-
field: op.field,
|
|
2468
|
-
value: null
|
|
2469
|
-
}, true);
|
|
2470
|
-
}
|
|
2471
2488
|
}
|
|
2472
2489
|
if (payload.links) {
|
|
2473
2490
|
const originalLinks = relationship.links;
|
|
@@ -2477,9 +2494,10 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2477
2494
|
const currentLink = originalLinks && originalLinks.related ? _normalizeLink(originalLinks.related) : null;
|
|
2478
2495
|
const currentLinkHref = currentLink ? currentLink.href : null;
|
|
2479
2496
|
if (relatedLink && relatedLink.href && relatedLink.href !== currentLinkHref) {
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2497
|
+
// Note: the equivalent warning for this case is issued eagerly (and with a more
|
|
2498
|
+
// complete condition, since it also accounts for `payload.data` being present) by
|
|
2499
|
+
// `assertValidRelationshipPayload` in `-utils.ts`, which always runs immediately
|
|
2500
|
+
// before this operation in DEBUG builds. Warning here too would double-warn.
|
|
2483
2501
|
(test => {
|
|
2484
2502
|
if (!test) {
|
|
2485
2503
|
throw new Error(`You have pushed a record of type '${identifier.type}' with '${definition.key}' as a link, but the value of that link is not a string.`);
|
|
@@ -2510,6 +2528,7 @@ function updateRelationshipOperation(graph, op) {
|
|
|
2510
2528
|
// we don't need to notify here as the update op we pushed in above will notify once
|
|
2511
2529
|
// membership is in the correct state.
|
|
2512
2530
|
relationship.state.hasReceivedData = true;
|
|
2531
|
+
relationship.state.hasReceivedRemoteData = true;
|
|
2513
2532
|
relationship.state.isStale = false;
|
|
2514
2533
|
relationship.state.hasDematerializedInverse = false;
|
|
2515
2534
|
relationship.state.isEmpty = relationshipIsEmpty;
|