@warp-drive/core 5.8.0-alpha.6 → 5.8.0-alpha.8
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/reactive/-private/document.d.ts +58 -46
- package/declarations/reactive.d.ts +3 -2
- package/declarations/request.d.ts +25 -0
- package/declarations/store/-private/caches/instance-cache.d.ts +2 -2
- package/declarations/store/-private/managers/cache-key-manager.d.ts +26 -8
- package/declarations/store/-private/managers/cache-manager.d.ts +6 -4
- package/declarations/store/deprecated/store.d.ts +1 -1
- package/declarations/types/cache.d.ts +6 -4
- package/declarations/types/request.d.ts +0 -3
- package/declarations/types/symbols.d.ts +2 -2
- package/dist/graph/-private.js +1 -1
- package/dist/{index-Cg2akouS.js → index-CKXq9_RZ.js} +132 -190
- package/dist/index.js +2 -2
- package/dist/reactive.js +6 -1
- package/dist/{future-BKkJJkj7.js → request-CN-dNlEY.js} +21 -1
- package/dist/request.js +1 -1
- package/dist/store/-private.js +1 -1
- package/dist/types/-private.js +1 -1
- package/dist/types/request.js +1 -4
- package/dist/types/symbols.js +2 -2
- package/package.json +3 -3
|
@@ -3,25 +3,13 @@ import type { RequestKey } from "../../types/identifier.js";
|
|
|
3
3
|
import type { ImmutableRequestInfo, RequestInfo } from "../../types/request.js";
|
|
4
4
|
import type { ResourceDocument } from "../../types/spec/document.js";
|
|
5
5
|
import type { Meta, PaginationLinks } from "../../types/spec/json-api-raw.js";
|
|
6
|
-
|
|
7
|
-
* A Document is a class that wraps the response content from a request to the API
|
|
8
|
-
* returned by `Cache.put` or `Cache.peek`, converting ResourceKeys into
|
|
9
|
-
* ReactiveResource instances.
|
|
10
|
-
*
|
|
11
|
-
* It is not directly instantiated by the user, and its properties should not
|
|
12
|
-
* be directly modified. Whether individual properties are mutable or not is
|
|
13
|
-
* determined by the record instance itself.
|
|
14
|
-
*
|
|
15
|
-
* @public
|
|
16
|
-
* @hideconstructor
|
|
17
|
-
*/
|
|
18
|
-
export declare class ReactiveDocument<T> {
|
|
6
|
+
export interface ReactiveDocumentBase<T> {
|
|
19
7
|
/**
|
|
20
8
|
* The links object for this document, if any
|
|
21
9
|
*
|
|
22
10
|
* e.g.
|
|
23
11
|
*
|
|
24
|
-
* ```
|
|
12
|
+
* ```ts
|
|
25
13
|
* {
|
|
26
14
|
* self: '/articles?page[number]=3',
|
|
27
15
|
* }
|
|
@@ -31,24 +19,6 @@ export declare class ReactiveDocument<T> {
|
|
|
31
19
|
*/
|
|
32
20
|
readonly links?: PaginationLinks;
|
|
33
21
|
/**
|
|
34
|
-
* The primary data for this document, if any.
|
|
35
|
-
*
|
|
36
|
-
* If this document has no primary data (e.g. because it is an error document)
|
|
37
|
-
* this property will be `undefined`.
|
|
38
|
-
*
|
|
39
|
-
* For collections this will be an array of record instances,
|
|
40
|
-
* for single resource requests it will be a single record instance or null.
|
|
41
|
-
*
|
|
42
|
-
* @public
|
|
43
|
-
*/
|
|
44
|
-
readonly data?: T;
|
|
45
|
-
/**
|
|
46
|
-
* The errors returned by the API for this request, if any
|
|
47
|
-
*
|
|
48
|
-
* @public
|
|
49
|
-
*/
|
|
50
|
-
readonly errors?: object[];
|
|
51
|
-
/**
|
|
52
22
|
* The meta object for this document, if any
|
|
53
23
|
*
|
|
54
24
|
* @public
|
|
@@ -60,18 +30,12 @@ export declare class ReactiveDocument<T> {
|
|
|
60
30
|
* @public
|
|
61
31
|
*/
|
|
62
32
|
readonly identifier: RequestKey | null;
|
|
63
|
-
constructor(store: Store, cacheKey: RequestKey | null, localCache: {
|
|
64
|
-
document: ResourceDocument;
|
|
65
|
-
request: ImmutableRequestInfo;
|
|
66
|
-
} | null);
|
|
67
33
|
/**
|
|
68
34
|
* Fetches the related link for this document, returning a promise that resolves
|
|
69
35
|
* with the document when the request completes. If no related link is present,
|
|
70
36
|
* will fallback to the self link if present
|
|
71
37
|
*
|
|
72
38
|
* @public
|
|
73
|
-
* @param {Object} options
|
|
74
|
-
* @return {Promise<Document>}
|
|
75
39
|
*/
|
|
76
40
|
fetch(options?: RequestInfo<ReactiveDocument<T>>): Promise<ReactiveDocument<T>>;
|
|
77
41
|
/**
|
|
@@ -80,8 +44,6 @@ export declare class ReactiveDocument<T> {
|
|
|
80
44
|
* next link.
|
|
81
45
|
*
|
|
82
46
|
* @public
|
|
83
|
-
* @param {Object} options
|
|
84
|
-
* @return {Promise<Document | null>}
|
|
85
47
|
*/
|
|
86
48
|
next(options?: RequestInfo<ReactiveDocument<T>>): Promise<ReactiveDocument<T> | null>;
|
|
87
49
|
/**
|
|
@@ -90,8 +52,6 @@ export declare class ReactiveDocument<T> {
|
|
|
90
52
|
* prev link.
|
|
91
53
|
*
|
|
92
54
|
* @public
|
|
93
|
-
* @param {Object} options
|
|
94
|
-
* @return {Promise<Document | null>}
|
|
95
55
|
*/
|
|
96
56
|
prev(options: RequestInfo<ReactiveDocument<T>>): Promise<ReactiveDocument<T> | null>;
|
|
97
57
|
/**
|
|
@@ -100,8 +60,6 @@ export declare class ReactiveDocument<T> {
|
|
|
100
60
|
* first link.
|
|
101
61
|
*
|
|
102
62
|
* @public
|
|
103
|
-
* @param {Object} options
|
|
104
|
-
* @return {Promise<Document | null>}
|
|
105
63
|
*/
|
|
106
64
|
first(options: RequestInfo<ReactiveDocument<T>>): Promise<ReactiveDocument<T> | null>;
|
|
107
65
|
/**
|
|
@@ -110,8 +68,6 @@ export declare class ReactiveDocument<T> {
|
|
|
110
68
|
* last link.
|
|
111
69
|
*
|
|
112
70
|
* @public
|
|
113
|
-
* @param {Object} options
|
|
114
|
-
* @return {Promise<Document | null>}
|
|
115
71
|
*/
|
|
116
72
|
last(options: RequestInfo<ReactiveDocument<T>>): Promise<ReactiveDocument<T> | null>;
|
|
117
73
|
/**
|
|
@@ -128,3 +84,59 @@ export declare class ReactiveDocument<T> {
|
|
|
128
84
|
*/
|
|
129
85
|
toJSON(): object;
|
|
130
86
|
}
|
|
87
|
+
export interface ReactiveErrorDocument<T> extends ReactiveDocumentBase<T> {
|
|
88
|
+
/**
|
|
89
|
+
* The primary data for this document, if any.
|
|
90
|
+
*
|
|
91
|
+
* If this document has no primary data (e.g. because it is an error document)
|
|
92
|
+
* this property will be `undefined`.
|
|
93
|
+
*
|
|
94
|
+
* For collections this will be an array of record instances,
|
|
95
|
+
* for single resource requests it will be a single record instance or null.
|
|
96
|
+
*
|
|
97
|
+
* @public
|
|
98
|
+
*/
|
|
99
|
+
readonly data?: undefined;
|
|
100
|
+
/**
|
|
101
|
+
* The errors returned by the API for this request, if any
|
|
102
|
+
*
|
|
103
|
+
* @public
|
|
104
|
+
*/
|
|
105
|
+
readonly errors: object[];
|
|
106
|
+
}
|
|
107
|
+
export interface ReactiveDataDocument<T> extends ReactiveDocumentBase<T> {
|
|
108
|
+
/**
|
|
109
|
+
* The primary data for this document, if any.
|
|
110
|
+
*
|
|
111
|
+
* If this document has no primary data (e.g. because it is an error document)
|
|
112
|
+
* this property will be `undefined`.
|
|
113
|
+
*
|
|
114
|
+
* For collections this will be an array of record instances,
|
|
115
|
+
* for single resource requests it will be a single record instance or null.
|
|
116
|
+
*
|
|
117
|
+
* @public
|
|
118
|
+
*/
|
|
119
|
+
readonly data: T;
|
|
120
|
+
/**
|
|
121
|
+
* The errors returned by the API for this request, if any
|
|
122
|
+
*
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
readonly errors?: undefined;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A Document is a class that wraps the response content from a request to the API
|
|
129
|
+
* returned by `Cache.put` or `Cache.peek`, converting ResourceKeys into
|
|
130
|
+
* ReactiveResource instances.
|
|
131
|
+
*
|
|
132
|
+
* It is not directly instantiated by the user, and its properties should not
|
|
133
|
+
* be directly modified. Whether individual properties are mutable or not is
|
|
134
|
+
* determined by the record instance itself.
|
|
135
|
+
*
|
|
136
|
+
* @public
|
|
137
|
+
*/
|
|
138
|
+
export type ReactiveDocument<T> = ReactiveDataDocument<T> | ReactiveErrorDocument<T>;
|
|
139
|
+
export declare function createReactiveDocument<T>(store: Store, cacheKey: RequestKey | null, localCache: {
|
|
140
|
+
document: ResourceDocument;
|
|
141
|
+
request: ImmutableRequestInfo;
|
|
142
|
+
} | null): ReactiveDocument<T>;
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
* The shape of the object and the transformation of raw cache data into its
|
|
56
56
|
* reactive form is controlled by a resource schema.
|
|
57
57
|
*
|
|
58
|
-
* For instance, lets say your API is a [{
|
|
58
|
+
* For instance, lets say your API is a [{json:api}](https://jsonapi.org) and your store is using
|
|
59
59
|
* the Cache provided by [@warp-drive/json-api](/api/@warp-drive/json-api), and a request
|
|
60
60
|
* returns the following raw data:
|
|
61
61
|
*
|
|
@@ -277,5 +277,6 @@ export { type CAUTION_MEGA_DANGER_ZONE_Extension, type ProcessedExtension, type
|
|
|
277
277
|
export { commit, type ReactiveResource } from "./reactive/-private/record.js";
|
|
278
278
|
export { checkout };
|
|
279
279
|
export { Checkout } from "./reactive/-private/symbols.js";
|
|
280
|
-
export { type ReactiveDocument } from "./reactive/-private/document.js";
|
|
280
|
+
export { type ReactiveDocument, type ReactiveDataDocument, type ReactiveErrorDocument } from "./reactive/-private/document.js";
|
|
281
281
|
export { getExpensiveRequestSubscription } from "./store/-private/new-core-tmp/expensive-subscription.js";
|
|
282
|
+
export { createRequestSubscription, getRequestState, getPromiseState, type PromiseState, type RequestState } from "./store/-private.js";
|
|
@@ -1,5 +1,30 @@
|
|
|
1
|
+
import type { RequestInfo } from "./types/request.js";
|
|
2
|
+
import type { RequestSignature } from "./types/symbols.js";
|
|
1
3
|
export { createDeferred } from "./request/-private/future.js";
|
|
2
4
|
export type { Future, Handler, CacheHandler, NextFn, Deferred, ManagedRequestPriority } from "./request/-private/types.js";
|
|
3
5
|
export { setPromiseResult, getPromiseResult } from "./request/-private/promise-cache.js";
|
|
4
6
|
export type { Awaitable } from "./request/-private/promise-cache.js";
|
|
5
7
|
export type { Context } from "./request/-private/context.js";
|
|
8
|
+
/**
|
|
9
|
+
* Brands the supplied object with the supplied response type.
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import type { ReactiveDataDocument } from '@warp-drive/core/reactive';
|
|
13
|
+
* import { withResponseType } from '@warp-drive/core/request';
|
|
14
|
+
* import type { User } from '#/data/user.ts'
|
|
15
|
+
*
|
|
16
|
+
* const result = await store.request(
|
|
17
|
+
* withResponseType<ReactiveDataDocument<User>>({ url: '/users/1' })
|
|
18
|
+
* );
|
|
19
|
+
*
|
|
20
|
+
* result.content.data; // will have type User
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
export declare function withResponseType<T>(obj: RequestInfo): RequestInfo<T> & {
|
|
25
|
+
[RequestSignature]: T;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated use {@link withResponseType} instead
|
|
29
|
+
*/
|
|
30
|
+
export { withResponseType as withBrand };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactiveDocument } from "../../../reactive/-private/document.js";
|
|
1
|
+
import { type ReactiveDocument } from "../../../reactive/-private/document.js";
|
|
2
2
|
import type { Cache } from "../../../types/cache.js";
|
|
3
3
|
import type { RequestKey, ResourceKey } from "../../../types/identifier.js";
|
|
4
4
|
import type { TypedRecordInstance, TypeFromInstance } from "../../../types/record.js";
|
|
@@ -6,7 +6,7 @@ import type { OpaqueRecordInstance } from "../../-types/q/record-instance.js";
|
|
|
6
6
|
import { CacheCapabilitiesManager } from "../managers/cache-capabilities-manager.js";
|
|
7
7
|
import type { CacheManager } from "../managers/cache-manager.js";
|
|
8
8
|
import type { CreateRecordProperties, Store } from "../store-service.js";
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function peekResourceKey(record: OpaqueRecordInstance): ResourceKey | undefined;
|
|
10
10
|
/**
|
|
11
11
|
Retrieves the unique referentially-stable {@link ResourceKey}
|
|
12
12
|
assigned to the given record instance.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PersistedResourceKey, type RequestKey, type ResourceKey } from "../../../types/identifier.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { RequestInfo } from "../../../types/request.js";
|
|
3
3
|
import type { ExistingResourceIdentifierObject, ResourceIdentifierObject } from "../../../types/spec/json-api-raw.js";
|
|
4
4
|
import type { ForgetMethod, GenerationMethod, KeyInfo, KeyInfoMethod, ResetMethod, UpdateMethod } from "../../-types/q/identifier.js";
|
|
5
5
|
type TypeFromIdentifier<T> = T extends {
|
|
@@ -197,16 +197,34 @@ export declare class CacheKeyManager {
|
|
|
197
197
|
*
|
|
198
198
|
* @private
|
|
199
199
|
*/
|
|
200
|
-
|
|
200
|
+
peekResourceKey(resource: ResourceIdentifierObject): ResourceKey | undefined;
|
|
201
201
|
/**
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
@public
|
|
202
|
+
* Peeks the {@link RequestKey} for the given {@link RequestInfo}, but will not
|
|
203
|
+
* create one if none has been previously generated.
|
|
204
|
+
*
|
|
205
|
+
* @public
|
|
206
|
+
*/
|
|
207
|
+
peekRequestKey(request: RequestInfo): RequestKey | null;
|
|
208
|
+
/**
|
|
209
|
+
* Returns the {@link RequestKey} for the given {@link RequestInfo} if the request is
|
|
210
|
+
* considered cacheable. For cacheable requests, this method will create
|
|
211
|
+
* a RequestKey if none is found.
|
|
212
|
+
*
|
|
213
|
+
* A `null` response indicates the request cannot/will not be cached,
|
|
214
|
+
* generally this means either
|
|
215
|
+
*
|
|
216
|
+
* - {@link RequestInfo.cacheOptions.key} is not present on the `RequestInfo`
|
|
217
|
+
* - the request's method is `GET` but it has no `url`
|
|
218
|
+
*
|
|
219
|
+
* Generally you should not seek to cache requests that are not idempotent
|
|
220
|
+
* or have side effects, such as mutations that create, update or delete
|
|
221
|
+
* a resource.
|
|
222
|
+
*
|
|
223
|
+
* @public
|
|
206
224
|
*/
|
|
207
|
-
getOrCreateDocumentIdentifier(request:
|
|
225
|
+
getOrCreateDocumentIdentifier(request: RequestInfo): RequestKey | null;
|
|
208
226
|
/**
|
|
209
|
-
Returns the
|
|
227
|
+
Returns the {@link ResourceKey} for the given Resource, creates one if it does not yet exist.
|
|
210
228
|
|
|
211
229
|
Specifically this means that we:
|
|
212
230
|
|
|
@@ -6,7 +6,7 @@ import type { LocalRelationshipOperation } from "../../../types/graph.js";
|
|
|
6
6
|
import type { RequestKey, ResourceKey } from "../../../types/identifier.js";
|
|
7
7
|
import type { Value } from "../../../types/json/raw.js";
|
|
8
8
|
import type { StructuredDataDocument, StructuredDocument } from "../../../types/request.js";
|
|
9
|
-
import type { ResourceDocument, SingleResourceDataDocument } from "../../../types/spec/document.js";
|
|
9
|
+
import type { CollectionResourceDataDocument, ResourceDocument, SingleResourceDataDocument } from "../../../types/spec/document.js";
|
|
10
10
|
import type { ApiError } from "../../../types/spec/error.js";
|
|
11
11
|
import type { StoreRequestContext } from "../cache-handler/handler.js";
|
|
12
12
|
/**
|
|
@@ -220,21 +220,23 @@ export declare class CacheManager implements Cache {
|
|
|
220
220
|
* @public
|
|
221
221
|
* @param key
|
|
222
222
|
*/
|
|
223
|
-
willCommit(key: ResourceKey, context: StoreRequestContext): void;
|
|
223
|
+
willCommit(key: ResourceKey | ResourceKey[], context: StoreRequestContext): void;
|
|
224
224
|
/**
|
|
225
225
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
226
226
|
* was successfully updated as part of a save transaction.
|
|
227
227
|
*
|
|
228
228
|
* @public
|
|
229
229
|
*/
|
|
230
|
-
didCommit(key: ResourceKey, result: StructuredDataDocument<
|
|
230
|
+
didCommit(key: ResourceKey, result: StructuredDataDocument<SingleResourceDataDocument> | null): SingleResourceDataDocument;
|
|
231
|
+
didCommit(key: ResourceKey[], result: StructuredDataDocument<SingleResourceDataDocument> | null): SingleResourceDataDocument;
|
|
232
|
+
didCommit(key: ResourceKey[], result: StructuredDataDocument<CollectionResourceDataDocument> | null): CollectionResourceDataDocument;
|
|
231
233
|
/**
|
|
232
234
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
233
235
|
* was update via a save transaction failed.
|
|
234
236
|
*
|
|
235
237
|
* @public
|
|
236
238
|
*/
|
|
237
|
-
commitWasRejected(key: ResourceKey, errors?: ApiError[]): void;
|
|
239
|
+
commitWasRejected(key: ResourceKey | ResourceKey[], errors?: ApiError[]): void;
|
|
238
240
|
/**
|
|
239
241
|
* [LIFECYCLE] Signals to the cache that all data for a resource
|
|
240
242
|
* should be cleared.
|
|
@@ -254,7 +254,7 @@ declare module "../-private/store-service" {
|
|
|
254
254
|
|
|
255
255
|
If you use an adapter such as the
|
|
256
256
|
[JSONAPIAdapter](/api/@warp-drive/legacy/adapter/json-api/classes/JSONAPIAdapter)
|
|
257
|
-
which supports the [{
|
|
257
|
+
which supports the [{json:api} specification](http://jsonapi.org/) and if your server
|
|
258
258
|
endpoint supports the use of an
|
|
259
259
|
['include' query parameter](http://jsonapi.org/format/#fetching-includes),
|
|
260
260
|
you can use `findRecord()` or `findAll()` to automatically retrieve additional records related to
|
|
@@ -7,7 +7,7 @@ import type { RequestKey, ResourceKey } from "./identifier.js";
|
|
|
7
7
|
import type { Value } from "./json/raw.js";
|
|
8
8
|
import type { TypeFromInstanceOrString } from "./record.js";
|
|
9
9
|
import type { RequestContext, StructuredDataDocument, StructuredDocument } from "./request.js";
|
|
10
|
-
import type { ResourceDocument, SingleResourceDataDocument } from "./spec/document.js";
|
|
10
|
+
import type { CollectionResourceDataDocument, ResourceDocument, SingleResourceDataDocument } from "./spec/document.js";
|
|
11
11
|
import type { ApiError } from "./spec/error.js";
|
|
12
12
|
/**
|
|
13
13
|
* A hash of changed attributes with the key being the attribute name and the value being an
|
|
@@ -253,7 +253,7 @@ export interface Cache {
|
|
|
253
253
|
*
|
|
254
254
|
* @public
|
|
255
255
|
*/
|
|
256
|
-
willCommit(cacheKey: ResourceKey, context: RequestContext | null): void;
|
|
256
|
+
willCommit(cacheKey: ResourceKey | ResourceKey[], context: RequestContext | null): void;
|
|
257
257
|
/**
|
|
258
258
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
259
259
|
* was successfully updated as part of a save transaction.
|
|
@@ -262,14 +262,16 @@ export interface Cache {
|
|
|
262
262
|
* @param the primary ResourceKey that was operated on
|
|
263
263
|
* @param data - a document in the cache format containing any updated data
|
|
264
264
|
*/
|
|
265
|
-
didCommit(cacheKey: ResourceKey, result: StructuredDataDocument<
|
|
265
|
+
didCommit(cacheKey: ResourceKey, result: StructuredDataDocument<SingleResourceDataDocument> | null): SingleResourceDataDocument;
|
|
266
|
+
didCommit(cacheKey: ResourceKey[], result: StructuredDataDocument<SingleResourceDataDocument> | null): SingleResourceDataDocument;
|
|
267
|
+
didCommit(cacheKey: ResourceKey[], result: StructuredDataDocument<CollectionResourceDataDocument> | null): CollectionResourceDataDocument;
|
|
266
268
|
/**
|
|
267
269
|
* [LIFECYCLE] Signals to the cache that a resource
|
|
268
270
|
* was update via a save transaction failed.
|
|
269
271
|
*
|
|
270
272
|
* @public
|
|
271
273
|
*/
|
|
272
|
-
commitWasRejected(cacheKey: ResourceKey, errors?: ApiError[]): void;
|
|
274
|
+
commitWasRejected(cacheKey: ResourceKey | ResourceKey[], errors?: ApiError[]): void;
|
|
273
275
|
/**
|
|
274
276
|
* [LIFECYCLE] Signals to the cache that all data for a resource
|
|
275
277
|
* should be cleared.
|
|
@@ -350,7 +350,4 @@ export interface RequestContext {
|
|
|
350
350
|
setStream(stream: ReadableStream | Promise<ReadableStream | null>): void;
|
|
351
351
|
setResponse(response: Response | ResponseInfo | null): void;
|
|
352
352
|
}
|
|
353
|
-
export declare function withBrand<T>(obj: RequestInfo): RequestInfo<T> & {
|
|
354
|
-
[RequestSignature]: T;
|
|
355
|
-
};
|
|
356
353
|
export {};
|
|
@@ -9,7 +9,7 @@ export declare const RecordStore: "___(unique) Symbol(Store)";
|
|
|
9
9
|
* record implementations to provide a typescript
|
|
10
10
|
* hint for the type of the resource.
|
|
11
11
|
*
|
|
12
|
-
* When used,
|
|
12
|
+
* When used, WarpDrive APIs can
|
|
13
13
|
* take advantage of this to provide better type
|
|
14
14
|
* safety and intellisense.
|
|
15
15
|
*
|
|
@@ -45,7 +45,7 @@ export declare const Type: "___(unique) Symbol($type)";
|
|
|
45
45
|
* record implementations to provide a typescript
|
|
46
46
|
* hint for the type of the resource.
|
|
47
47
|
*
|
|
48
|
-
* When used,
|
|
48
|
+
* When used, WarpDrive APIs can
|
|
49
49
|
* take advantage of this to provide better type
|
|
50
50
|
* safety and intellisense.
|
|
51
51
|
*
|
package/dist/graph/-private.js
CHANGED
|
@@ -3331,7 +3331,7 @@ function isReordered(relationship) {
|
|
|
3331
3331
|
/**
|
|
3332
3332
|
Provides a performance tuned normalized graph for intelligently managing relationships between resources based on identity
|
|
3333
3333
|
|
|
3334
|
-
While this Graph is abstract, it currently is a private implementation required as a peer-dependency by the {
|
|
3334
|
+
While this Graph is abstract, it currently is a private implementation required as a peer-dependency by the {json:api} Cache Implementation.
|
|
3335
3335
|
|
|
3336
3336
|
We intend to make this Graph public API after some additional iteration during the 5.x timeframe, until then all APIs should be considered experimental and unstable, not fit for direct application or 3rd party library usage.
|
|
3337
3337
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { deprecate, warn } from '@ember/debug';
|
|
2
|
-
import {
|
|
2
|
+
import { EnableHydration, SkipCache, STRUCTURED } from './types/request.js';
|
|
3
3
|
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
4
|
-
import {
|
|
4
|
+
import { D as Destroy, C as Context, S as SOURCE, a as Checkout, b as Commit } from "./symbols-sql1_mdx.js";
|
|
5
5
|
import { isResourceSchema } from './types/schema/fields.js';
|
|
6
|
-
import { g as getPromiseResult, s as setPromiseResult,
|
|
7
|
-
import { c as createSignal, a as consumeSignal, n as notifySignal, b as createMemo, d as willSyncFlushWatchers, A as ARRAY_SIGNAL, O as OBJECT_SIGNAL, w as waitFor } from "./configure-C3x8YXzL.js";
|
|
6
|
+
import { w as withResponseType, g as getPromiseResult, s as setPromiseResult, c as cloneResponseProperties, I as IS_CACHE_HANDLER, a as assertValidRequest, e as executeNextHandler, b as getRequestResult, u as upgradePromise, d as clearRequestResult } from "./request-CN-dNlEY.js";
|
|
8
7
|
import { getOrSetGlobal, peekTransient, setTransient, peekUniversalTransient, setUniversalTransient } from './types/-private.js';
|
|
9
|
-
import {
|
|
8
|
+
import { c as createSignal, a as consumeSignal, n as notifySignal, b as createMemo, d as willSyncFlushWatchers, A as ARRAY_SIGNAL, O as OBJECT_SIGNAL, w as waitFor } from "./configure-C3x8YXzL.js";
|
|
10
9
|
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_KEY_TYPE, DEBUG_CLIENT_ORIGINATED } from './types/identifier.js';
|
|
11
10
|
import { dasherize } from './utils/string.js';
|
|
11
|
+
import { D as DefaultCachePolicy } from "./default-cache-policy-D7_u4YRH.js";
|
|
12
12
|
import { setLogging, getRuntimeConfig } from './types/runtime.js';
|
|
13
13
|
import { RecordStore, Type } from './types/symbols.js';
|
|
14
14
|
const INITIALIZER_PROTO = {
|
|
@@ -490,83 +490,10 @@ function urlFromLink(link) {
|
|
|
490
490
|
* determined by the record instance itself.
|
|
491
491
|
*
|
|
492
492
|
* @public
|
|
493
|
-
* @hideconstructor
|
|
494
493
|
*/
|
|
495
|
-
class ReactiveDocument {
|
|
496
|
-
/**
|
|
497
|
-
* The links object for this document, if any
|
|
498
|
-
*
|
|
499
|
-
* e.g.
|
|
500
|
-
*
|
|
501
|
-
* ```
|
|
502
|
-
* {
|
|
503
|
-
* self: '/articles?page[number]=3',
|
|
504
|
-
* }
|
|
505
|
-
* ```
|
|
506
|
-
*
|
|
507
|
-
* @public
|
|
508
|
-
*/
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* The primary data for this document, if any.
|
|
512
|
-
*
|
|
513
|
-
* If this document has no primary data (e.g. because it is an error document)
|
|
514
|
-
* this property will be `undefined`.
|
|
515
|
-
*
|
|
516
|
-
* For collections this will be an array of record instances,
|
|
517
|
-
* for single resource requests it will be a single record instance or null.
|
|
518
|
-
*
|
|
519
|
-
* @public
|
|
520
|
-
*/
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* The errors returned by the API for this request, if any
|
|
524
|
-
*
|
|
525
|
-
* @public
|
|
526
|
-
*/
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* The meta object for this document, if any
|
|
530
|
-
*
|
|
531
|
-
* @public
|
|
532
|
-
*/
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* The RequestKey associated with this document, if any
|
|
536
|
-
*
|
|
537
|
-
* @public
|
|
538
|
-
*/
|
|
539
|
-
|
|
540
|
-
/** @internal */
|
|
541
|
-
|
|
542
|
-
/** @internal */
|
|
543
|
-
|
|
544
|
-
constructor(store, cacheKey, localCache) {
|
|
545
|
-
this._store = store;
|
|
546
|
-
this._localCache = localCache;
|
|
547
|
-
this.identifier = cacheKey;
|
|
548
|
-
const signals = withSignalStore(this);
|
|
549
|
-
|
|
550
|
-
// TODO if we ever enable auto-cleanup of the cache, we will need to tear this down
|
|
551
|
-
// in a destroy method
|
|
552
|
-
if (cacheKey) {
|
|
553
|
-
store.notifications.subscribe(cacheKey, (_key, type) => {
|
|
554
|
-
switch (type) {
|
|
555
|
-
case 'updated':
|
|
556
|
-
// FIXME in the case of a collection we need to notify it's length
|
|
557
|
-
// and have it recalc
|
|
558
|
-
notifyInternalSignal(peekInternalSignal(signals, 'data'));
|
|
559
|
-
notifyInternalSignal(peekInternalSignal(signals, 'links'));
|
|
560
|
-
notifyInternalSignal(peekInternalSignal(signals, 'meta'));
|
|
561
|
-
notifyInternalSignal(peekInternalSignal(signals, 'errors'));
|
|
562
|
-
break;
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
494
|
|
|
568
|
-
|
|
569
|
-
async
|
|
495
|
+
const ReactiveDocumentProto = {
|
|
496
|
+
async _request(link, options = withResponseType({
|
|
570
497
|
url: '',
|
|
571
498
|
method: 'GET'
|
|
572
499
|
})) {
|
|
@@ -580,18 +507,8 @@ class ReactiveDocument {
|
|
|
580
507
|
});
|
|
581
508
|
const response = await this._store.request(options);
|
|
582
509
|
return response.content;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
/**
|
|
586
|
-
* Fetches the related link for this document, returning a promise that resolves
|
|
587
|
-
* with the document when the request completes. If no related link is present,
|
|
588
|
-
* will fallback to the self link if present
|
|
589
|
-
*
|
|
590
|
-
* @public
|
|
591
|
-
* @param {Object} options
|
|
592
|
-
* @return {Promise<Document>}
|
|
593
|
-
*/
|
|
594
|
-
fetch(options = withBrand({
|
|
510
|
+
},
|
|
511
|
+
fetch(options = withResponseType({
|
|
595
512
|
url: '',
|
|
596
513
|
method: 'GET'
|
|
597
514
|
})) {
|
|
@@ -602,73 +519,20 @@ class ReactiveDocument {
|
|
|
602
519
|
})(this.links?.related || this.links?.self) : {};
|
|
603
520
|
options.cacheOptions = options.cacheOptions || {};
|
|
604
521
|
options.cacheOptions.key = this.identifier?.lid;
|
|
605
|
-
return this
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/**
|
|
609
|
-
* Fetches the next link for this document, returning a promise that resolves
|
|
610
|
-
* with the new document when the request completes, or null if there is no
|
|
611
|
-
* next link.
|
|
612
|
-
*
|
|
613
|
-
* @public
|
|
614
|
-
* @param {Object} options
|
|
615
|
-
* @return {Promise<Document | null>}
|
|
616
|
-
*/
|
|
522
|
+
return this._request(this.links.related ? 'related' : 'self', options);
|
|
523
|
+
},
|
|
617
524
|
next(options) {
|
|
618
|
-
return this
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
/**
|
|
622
|
-
* Fetches the prev link for this document, returning a promise that resolves
|
|
623
|
-
* with the new document when the request completes, or null if there is no
|
|
624
|
-
* prev link.
|
|
625
|
-
*
|
|
626
|
-
* @public
|
|
627
|
-
* @param {Object} options
|
|
628
|
-
* @return {Promise<Document | null>}
|
|
629
|
-
*/
|
|
525
|
+
return this._request('next', options);
|
|
526
|
+
},
|
|
630
527
|
prev(options) {
|
|
631
|
-
return this
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
/**
|
|
635
|
-
* Fetches the first link for this document, returning a promise that resolves
|
|
636
|
-
* with the new document when the request completes, or null if there is no
|
|
637
|
-
* first link.
|
|
638
|
-
*
|
|
639
|
-
* @public
|
|
640
|
-
* @param {Object} options
|
|
641
|
-
* @return {Promise<Document | null>}
|
|
642
|
-
*/
|
|
528
|
+
return this._request('prev', options);
|
|
529
|
+
},
|
|
643
530
|
first(options) {
|
|
644
|
-
return this
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
/**
|
|
648
|
-
* Fetches the last link for this document, returning a promise that resolves
|
|
649
|
-
* with the new document when the request completes, or null if there is no
|
|
650
|
-
* last link.
|
|
651
|
-
*
|
|
652
|
-
* @public
|
|
653
|
-
* @param {Object} options
|
|
654
|
-
* @return {Promise<Document | null>}
|
|
655
|
-
*/
|
|
531
|
+
return this._request('first', options);
|
|
532
|
+
},
|
|
656
533
|
last(options) {
|
|
657
|
-
return this
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Implemented for `JSON.stringify` support.
|
|
662
|
-
*
|
|
663
|
-
* Returns the JSON representation of the document wrapper.
|
|
664
|
-
*
|
|
665
|
-
* This is a shallow serialization, it does not deeply serialize
|
|
666
|
-
* the document's contents, leaving that to the individual record
|
|
667
|
-
* instances to determine how to do, if at all.
|
|
668
|
-
*
|
|
669
|
-
* @public
|
|
670
|
-
* @return
|
|
671
|
-
*/
|
|
534
|
+
return this._request('last', options);
|
|
535
|
+
},
|
|
672
536
|
toJSON() {
|
|
673
537
|
const data = {};
|
|
674
538
|
data.identifier = this.identifier;
|
|
@@ -685,9 +549,23 @@ class ReactiveDocument {
|
|
|
685
549
|
data.meta = this.meta;
|
|
686
550
|
}
|
|
687
551
|
return data;
|
|
552
|
+
},
|
|
553
|
+
[Destroy]() {
|
|
554
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
555
|
+
if (!test) {
|
|
556
|
+
throw new Error(`Cannot destroy a ReactiveDocument which has already been destroyed`);
|
|
557
|
+
}
|
|
558
|
+
})(this._store) : {};
|
|
559
|
+
if (this._subscription) {
|
|
560
|
+
this._store.notifications.unsubscribe(this._subscription);
|
|
561
|
+
// @ts-expect-error
|
|
562
|
+
this._store = null;
|
|
563
|
+
// @ts-expect-error
|
|
564
|
+
this._subscription = null;
|
|
565
|
+
}
|
|
688
566
|
}
|
|
689
|
-
}
|
|
690
|
-
defineGate(
|
|
567
|
+
};
|
|
568
|
+
defineGate(ReactiveDocumentProto, 'errors', {
|
|
691
569
|
get() {
|
|
692
570
|
const {
|
|
693
571
|
identifier
|
|
@@ -710,7 +588,7 @@ defineGate(ReactiveDocument.prototype, 'errors', {
|
|
|
710
588
|
return 'errors' in doc ? doc.errors : undefined;
|
|
711
589
|
}
|
|
712
590
|
});
|
|
713
|
-
defineGate(
|
|
591
|
+
defineGate(ReactiveDocumentProto, 'data', {
|
|
714
592
|
get() {
|
|
715
593
|
const {
|
|
716
594
|
identifier,
|
|
@@ -737,7 +615,7 @@ defineGate(ReactiveDocument.prototype, 'data', {
|
|
|
737
615
|
}
|
|
738
616
|
}
|
|
739
617
|
});
|
|
740
|
-
defineGate(
|
|
618
|
+
defineGate(ReactiveDocumentProto, 'links', {
|
|
741
619
|
get() {
|
|
742
620
|
const {
|
|
743
621
|
identifier
|
|
@@ -754,7 +632,7 @@ defineGate(ReactiveDocument.prototype, 'links', {
|
|
|
754
632
|
return data.links;
|
|
755
633
|
}
|
|
756
634
|
});
|
|
757
|
-
defineGate(
|
|
635
|
+
defineGate(ReactiveDocumentProto, 'meta', {
|
|
758
636
|
get() {
|
|
759
637
|
const {
|
|
760
638
|
identifier
|
|
@@ -771,6 +649,32 @@ defineGate(ReactiveDocument.prototype, 'meta', {
|
|
|
771
649
|
return data.meta;
|
|
772
650
|
}
|
|
773
651
|
});
|
|
652
|
+
function createReactiveDocument(store, cacheKey, localCache) {
|
|
653
|
+
const doc = Object.create(ReactiveDocumentProto);
|
|
654
|
+
doc._store = store;
|
|
655
|
+
doc._localCache = localCache;
|
|
656
|
+
// @ts-expect-error we are initializing it here
|
|
657
|
+
doc.identifier = cacheKey;
|
|
658
|
+
const signals = withSignalStore(doc);
|
|
659
|
+
|
|
660
|
+
// TODO if we ever enable auto-cleanup of the cache, we will need to tear this down
|
|
661
|
+
// in a destroy method
|
|
662
|
+
if (cacheKey) {
|
|
663
|
+
doc._subscription = store.notifications.subscribe(cacheKey, (_key, type) => {
|
|
664
|
+
switch (type) {
|
|
665
|
+
case 'updated':
|
|
666
|
+
// FIXME in the case of a collection we need to notify it's length
|
|
667
|
+
// and have it recalc
|
|
668
|
+
notifyInternalSignal(peekInternalSignal(signals, 'data'));
|
|
669
|
+
notifyInternalSignal(peekInternalSignal(signals, 'links'));
|
|
670
|
+
notifyInternalSignal(peekInternalSignal(signals, 'meta'));
|
|
671
|
+
notifyInternalSignal(peekInternalSignal(signals, 'errors'));
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
return doc;
|
|
677
|
+
}
|
|
774
678
|
const TEXT_COLORS = {
|
|
775
679
|
TEXT: 'inherit',
|
|
776
680
|
notify: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
@@ -1403,15 +1307,45 @@ class CacheKeyManager {
|
|
|
1403
1307
|
*
|
|
1404
1308
|
* @private
|
|
1405
1309
|
*/
|
|
1406
|
-
|
|
1310
|
+
peekResourceKey(resource) {
|
|
1407
1311
|
return this._getRecordIdentifier(resource, 0);
|
|
1408
1312
|
}
|
|
1409
1313
|
|
|
1410
1314
|
/**
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1315
|
+
* Peeks the {@link RequestKey} for the given {@link RequestInfo}, but will not
|
|
1316
|
+
* create one if none has been previously generated.
|
|
1317
|
+
*
|
|
1318
|
+
* @public
|
|
1319
|
+
*/
|
|
1320
|
+
peekRequestKey(request) {
|
|
1321
|
+
let cacheKey = request.cacheOptions?.key;
|
|
1322
|
+
if (!cacheKey) {
|
|
1323
|
+
cacheKey = this._generate(request, 'document');
|
|
1324
|
+
}
|
|
1325
|
+
if (!cacheKey) {
|
|
1326
|
+
return null;
|
|
1327
|
+
}
|
|
1328
|
+
const identifier = this._cache.documents.get(cacheKey);
|
|
1329
|
+
return identifier ?? null;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
/**
|
|
1333
|
+
* Returns the {@link RequestKey} for the given {@link RequestInfo} if the request is
|
|
1334
|
+
* considered cacheable. For cacheable requests, this method will create
|
|
1335
|
+
* a RequestKey if none is found.
|
|
1336
|
+
*
|
|
1337
|
+
* A `null` response indicates the request cannot/will not be cached,
|
|
1338
|
+
* generally this means either
|
|
1339
|
+
*
|
|
1340
|
+
* - {@link RequestInfo.cacheOptions.key} is not present on the `RequestInfo`
|
|
1341
|
+
* - the request's method is `GET` but it has no `url`
|
|
1342
|
+
*
|
|
1343
|
+
* Generally you should not seek to cache requests that are not idempotent
|
|
1344
|
+
* or have side effects, such as mutations that create, update or delete
|
|
1345
|
+
* a resource.
|
|
1346
|
+
*
|
|
1347
|
+
* @public
|
|
1348
|
+
*/
|
|
1415
1349
|
getOrCreateDocumentIdentifier(request) {
|
|
1416
1350
|
let cacheKey = request.cacheOptions?.key;
|
|
1417
1351
|
if (!cacheKey) {
|
|
@@ -1436,7 +1370,7 @@ class CacheKeyManager {
|
|
|
1436
1370
|
}
|
|
1437
1371
|
|
|
1438
1372
|
/**
|
|
1439
|
-
Returns the
|
|
1373
|
+
Returns the {@link ResourceKey} for the given Resource, creates one if it does not yet exist.
|
|
1440
1374
|
Specifically this means that we:
|
|
1441
1375
|
- validate the `id` `type` and `lid` combo against known identifiers
|
|
1442
1376
|
- return an object with an `lid` that is stable (repeated calls with the same
|
|
@@ -1941,7 +1875,7 @@ function isDestroyable(record) {
|
|
|
1941
1875
|
return Boolean(record && typeof record === 'object' && typeof record.destroy === 'function');
|
|
1942
1876
|
}
|
|
1943
1877
|
const RecordCache = getOrSetGlobal('RecordCache', new Map());
|
|
1944
|
-
function
|
|
1878
|
+
function peekResourceKey(record) {
|
|
1945
1879
|
return RecordCache.get(record);
|
|
1946
1880
|
}
|
|
1947
1881
|
|
|
@@ -2075,7 +2009,7 @@ class InstanceCache {
|
|
|
2075
2009
|
getDocument(identifier) {
|
|
2076
2010
|
let doc = this.__instances.document.get(identifier);
|
|
2077
2011
|
if (!doc) {
|
|
2078
|
-
doc =
|
|
2012
|
+
doc = createReactiveDocument(this.store, identifier, null);
|
|
2079
2013
|
this.__instances.document.set(identifier, doc);
|
|
2080
2014
|
}
|
|
2081
2015
|
return doc;
|
|
@@ -2207,7 +2141,7 @@ class InstanceCache {
|
|
|
2207
2141
|
console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
|
|
2208
2142
|
}
|
|
2209
2143
|
}
|
|
2210
|
-
const existingIdentifier = this.store.cacheKeyManager.
|
|
2144
|
+
const existingIdentifier = this.store.cacheKeyManager.peekResourceKey({
|
|
2211
2145
|
type,
|
|
2212
2146
|
id
|
|
2213
2147
|
});
|
|
@@ -2584,7 +2518,9 @@ class CacheManager {
|
|
|
2584
2518
|
*
|
|
2585
2519
|
* @public
|
|
2586
2520
|
*/
|
|
2521
|
+
|
|
2587
2522
|
didCommit(key, result) {
|
|
2523
|
+
// @ts-expect-error TS doesn't enable proxying overload calls
|
|
2588
2524
|
return this.___cache.didCommit(key, result);
|
|
2589
2525
|
}
|
|
2590
2526
|
|
|
@@ -5196,7 +5132,7 @@ class Store extends BaseClass {
|
|
|
5196
5132
|
id
|
|
5197
5133
|
};
|
|
5198
5134
|
if (resource.id) {
|
|
5199
|
-
const identifier = this.cacheKeyManager.
|
|
5135
|
+
const identifier = this.cacheKeyManager.peekResourceKey(resource);
|
|
5200
5136
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
5201
5137
|
if (!test) {
|
|
5202
5138
|
throw new Error(`The id ${String(properties.id)} has already been used with another '${normalizedModelName}' record.`);
|
|
@@ -5204,7 +5140,7 @@ class Store extends BaseClass {
|
|
|
5204
5140
|
})(!identifier) : {};
|
|
5205
5141
|
}
|
|
5206
5142
|
if (context?.lid) {
|
|
5207
|
-
const identifier = this.cacheKeyManager.
|
|
5143
|
+
const identifier = this.cacheKeyManager.peekResourceKey({
|
|
5208
5144
|
lid: context?.lid
|
|
5209
5145
|
});
|
|
5210
5146
|
resource.lid = context.lid;
|
|
@@ -5239,7 +5175,7 @@ class Store extends BaseClass {
|
|
|
5239
5175
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5240
5176
|
assertDestroyingStore(this, 'deleteRecord');
|
|
5241
5177
|
}
|
|
5242
|
-
const identifier =
|
|
5178
|
+
const identifier = peekResourceKey(record);
|
|
5243
5179
|
const cache = this.cache;
|
|
5244
5180
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
5245
5181
|
if (!test) {
|
|
@@ -5269,7 +5205,7 @@ class Store extends BaseClass {
|
|
|
5269
5205
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5270
5206
|
assertDestroyingStore(this, 'unloadRecord');
|
|
5271
5207
|
}
|
|
5272
|
-
const identifier =
|
|
5208
|
+
const identifier = peekResourceKey(record);
|
|
5273
5209
|
if (identifier) {
|
|
5274
5210
|
this._instanceCache.unloadRecord(identifier);
|
|
5275
5211
|
}
|
|
@@ -5308,7 +5244,7 @@ class Store extends BaseClass {
|
|
|
5308
5244
|
|
|
5309
5245
|
peekRecord(identifier, id) {
|
|
5310
5246
|
if (arguments.length === 1 && isMaybeIdentifier(identifier)) {
|
|
5311
|
-
const stableIdentifier = this.cacheKeyManager.
|
|
5247
|
+
const stableIdentifier = this.cacheKeyManager.peekResourceKey(identifier);
|
|
5312
5248
|
const isLoaded = stableIdentifier && this._instanceCache.recordIsLoaded(stableIdentifier);
|
|
5313
5249
|
// TODO come up with a better mechanism for determining if we have data and could peek.
|
|
5314
5250
|
// this is basically an "are we not empty" query.
|
|
@@ -5333,7 +5269,7 @@ class Store extends BaseClass {
|
|
|
5333
5269
|
type,
|
|
5334
5270
|
id: normalizedId
|
|
5335
5271
|
};
|
|
5336
|
-
const stableIdentifier = this.cacheKeyManager.
|
|
5272
|
+
const stableIdentifier = this.cacheKeyManager.peekResourceKey(resource);
|
|
5337
5273
|
const isLoaded = stableIdentifier && this._instanceCache.recordIsLoaded(stableIdentifier);
|
|
5338
5274
|
return isLoaded ? this._instanceCache.getRecord(stableIdentifier) : null;
|
|
5339
5275
|
}
|
|
@@ -6703,7 +6639,7 @@ function maybeUpdateUiObjects(store, request, options, document) {
|
|
|
6703
6639
|
|
|
6704
6640
|
// if we don't have an identifier, we give the document
|
|
6705
6641
|
// its own local cache
|
|
6706
|
-
return
|
|
6642
|
+
return createReactiveDocument(store, null, {
|
|
6707
6643
|
request,
|
|
6708
6644
|
document
|
|
6709
6645
|
});
|
|
@@ -6711,9 +6647,11 @@ function maybeUpdateUiObjects(store, request, options, document) {
|
|
|
6711
6647
|
function updateCacheForSuccess(store, request, options, document) {
|
|
6712
6648
|
let response = null;
|
|
6713
6649
|
if (isMutation(request)) {
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6650
|
+
if (Array.isArray(request.records)) {
|
|
6651
|
+
response = store.cache.didCommit(request.records, document);
|
|
6652
|
+
} else if (request.data?.record) {
|
|
6653
|
+
// legacy fallback, the data option should no longer be used for this
|
|
6654
|
+
response = store.cache.didCommit(request.data.record, document);
|
|
6717
6655
|
|
|
6718
6656
|
// a mutation combined with a 204 has no cache impact when no known records were involved
|
|
6719
6657
|
// a createRecord with a 201 with an empty response and no known records should similarly
|
|
@@ -6753,8 +6691,14 @@ function updateCacheForError(store, context, options, error) {
|
|
|
6753
6691
|
// TODO similar to didCommit we should spec this to be similar to cache.put for handling full response
|
|
6754
6692
|
// currently we let the response remain undefiend.
|
|
6755
6693
|
const errors = error && error.content && typeof error.content === 'object' && 'errors' in error.content && Array.isArray(error.content.errors) ? error.content.errors : undefined;
|
|
6756
|
-
|
|
6757
|
-
|
|
6694
|
+
if (Array.isArray(context.request.records)) {
|
|
6695
|
+
store.cache.commitWasRejected(context.request.records, errors);
|
|
6696
|
+
} else if (context.request.data?.record) {
|
|
6697
|
+
// legacy fallback, the data option should no longer be used for this
|
|
6698
|
+
store.cache.commitWasRejected(context.request.data.record, errors);
|
|
6699
|
+
} else {
|
|
6700
|
+
store.cache.put(error);
|
|
6701
|
+
}
|
|
6758
6702
|
} else {
|
|
6759
6703
|
response = store.cache.put(error);
|
|
6760
6704
|
return maybeUpdateUiObjects(store, context.request, options, response);
|
|
@@ -6799,15 +6743,13 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
|
|
|
6799
6743
|
let isMut = false;
|
|
6800
6744
|
if (isMutation(context.request)) {
|
|
6801
6745
|
isMut = true;
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
if (record) {
|
|
6810
|
-
store.cache.willCommit(record, context);
|
|
6746
|
+
if (Array.isArray(context.request.records)) {
|
|
6747
|
+
context.request.records.forEach(record => {
|
|
6748
|
+
store.cache.willCommit(record, context);
|
|
6749
|
+
});
|
|
6750
|
+
} else if (context.request.data?.record) {
|
|
6751
|
+
// legacy fallback, the data option should no longer be used for this
|
|
6752
|
+
store.cache.willCommit(context.request.data.record, context);
|
|
6811
6753
|
}
|
|
6812
6754
|
}
|
|
6813
6755
|
if (store.lifetimes?.willRequest) {
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { C as CacheHandler, V as Fetch, W as RequestManager, S as Store, r as recordIdentifierFor, $ as setIdentifierForgetMethod, Y as setIdentifierGenerationMethod, a0 as setIdentifierResetMethod, Z as setIdentifierUpdateMethod, a1 as setKeyInfoForResource, s as storeFor, X as useRecommendedStore } from "./index-
|
|
1
|
+
export { C as CacheHandler, V as Fetch, W as RequestManager, S as Store, r as recordIdentifierFor, $ as setIdentifierForgetMethod, Y as setIdentifierGenerationMethod, a0 as setIdentifierResetMethod, Z as setIdentifierUpdateMethod, a1 as setKeyInfoForResource, s as storeFor, X as useRecommendedStore } from "./index-CKXq9_RZ.js";
|
|
2
2
|
import "./symbols-sql1_mdx.js";
|
|
3
|
-
import "./default-cache-policy-D7_u4YRH.js";
|
|
4
3
|
import '@ember/debug';
|
|
5
4
|
import '@embroider/macros';
|
|
6
5
|
import './utils/string.js';
|
|
7
6
|
import "./configure-C3x8YXzL.js";
|
|
7
|
+
import "./default-cache-policy-D7_u4YRH.js";
|
|
8
8
|
import './types/runtime.js';
|
package/dist/reactive.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
export { O as SchemaService, L as checkout, U as commit, Q as fromIdentity, M as instantiateRecord, T as registerDerivations, N as teardownRecord, P as withDefaults } from "./index-
|
|
1
|
+
export { O as SchemaService, L as checkout, U as commit, q as createRequestSubscription, Q as fromIdentity, p as getPromiseState, t as getRequestState, M as instantiateRecord, T as registerDerivations, N as teardownRecord, P as withDefaults } from "./index-CKXq9_RZ.js";
|
|
2
2
|
export { a as Checkout } from "./symbols-sql1_mdx.js";
|
|
3
|
+
import './types/request.js';
|
|
4
|
+
import '@embroider/macros';
|
|
5
|
+
import '@ember/debug';
|
|
6
|
+
import './utils/string.js';
|
|
7
|
+
import "./configure-C3x8YXzL.js";
|
|
3
8
|
const Subscriptions = new WeakMap();
|
|
4
9
|
|
|
5
10
|
/**
|
|
@@ -675,4 +675,24 @@ function createFuture(owner) {
|
|
|
675
675
|
deferred.promise = promise;
|
|
676
676
|
return deferred;
|
|
677
677
|
}
|
|
678
|
-
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Brands the supplied object with the supplied response type.
|
|
681
|
+
*
|
|
682
|
+
* ```ts
|
|
683
|
+
* import type { ReactiveDataDocument } from '@warp-drive/core/reactive';
|
|
684
|
+
* import { withResponseType } from '@warp-drive/core/request';
|
|
685
|
+
* import type { User } from '#/data/user.ts'
|
|
686
|
+
*
|
|
687
|
+
* const result = await store.request(
|
|
688
|
+
* withResponseType<ReactiveDataDocument<User>>({ url: '/users/1' })
|
|
689
|
+
* );
|
|
690
|
+
*
|
|
691
|
+
* result.content.data; // will have type User
|
|
692
|
+
* ```
|
|
693
|
+
*
|
|
694
|
+
*/
|
|
695
|
+
function withResponseType(obj) {
|
|
696
|
+
return obj;
|
|
697
|
+
}
|
|
698
|
+
export { IS_CACHE_HANDLER as I, assertValidRequest as a, getRequestResult as b, cloneResponseProperties as c, clearRequestResult as d, executeNextHandler as e, createDeferred as f, getPromiseResult as g, setPromiseResult as s, upgradePromise as u, withResponseType as w };
|
package/dist/request.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { f as createDeferred, g as getPromiseResult, s as setPromiseResult, w as withBrand, w as withResponseType } from "./request-CN-dNlEY.js";
|
package/dist/store/-private.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as CacheHandler, D as DISPOSE, R as RecordArrayManager, E as Signals, S as Store, k as StoreMap, _ as _clearCaches, n as _deprecatingNormalize, h as assertPrivateCapabilities, d as assertPrivateStore, b as coerceId, c as constructResource, J as consumeInternalSignal, G as createInternalMemo, l as createLegacyManyArray, q as createRequestSubscription, A as defineGate, B as defineNonEnumerableSignal, z as defineSignal, e as ensureStringId, y as entangleInitiallyStaleSignal, x as entangleSignal, f as fastPush, w as gate, K as getOrCreateInternalSignal, p as getPromiseState, t as getRequestState, g as isPrivateStore, a as isRequestKey, i as isResourceKey, m as log, o as logGroup, v as memoized, I as notifyInternalSignal, F as peekInternalSignal, r as recordIdentifierFor, j as setRecordIdentifier, u as signal, s as storeFor, H as withSignalStore } from "../index-
|
|
1
|
+
export { C as CacheHandler, D as DISPOSE, R as RecordArrayManager, E as Signals, S as Store, k as StoreMap, _ as _clearCaches, n as _deprecatingNormalize, h as assertPrivateCapabilities, d as assertPrivateStore, b as coerceId, c as constructResource, J as consumeInternalSignal, G as createInternalMemo, l as createLegacyManyArray, q as createRequestSubscription, A as defineGate, B as defineNonEnumerableSignal, z as defineSignal, e as ensureStringId, y as entangleInitiallyStaleSignal, x as entangleSignal, f as fastPush, w as gate, K as getOrCreateInternalSignal, p as getPromiseState, t as getRequestState, g as isPrivateStore, a as isRequestKey, i as isResourceKey, m as log, o as logGroup, v as memoized, I as notifyInternalSignal, F as peekInternalSignal, r as recordIdentifierFor, j as setRecordIdentifier, u as signal, s as storeFor, H as withSignalStore } from "../index-CKXq9_RZ.js";
|
|
2
2
|
export { A as ARRAY_SIGNAL, O as OBJECT_SIGNAL, w as waitFor } from "../configure-C3x8YXzL.js";
|
package/dist/types/-private.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { macroCondition, getGlobalConfig } from '@embroider/macros';
|
|
2
2
|
const name = "@warp-drive/core";
|
|
3
|
-
const version = "5.8.0-alpha.
|
|
3
|
+
const version = "5.8.0-alpha.8";
|
|
4
4
|
|
|
5
5
|
// in testing mode, we utilize globals to ensure only one copy exists of
|
|
6
6
|
// these maps, due to bugs in ember-auto-import
|
package/dist/types/request.js
CHANGED
package/dist/types/symbols.js
CHANGED
|
@@ -11,7 +11,7 @@ const RecordStore = getOrSetGlobal('Store', Symbol('Store'));
|
|
|
11
11
|
* record implementations to provide a typescript
|
|
12
12
|
* hint for the type of the resource.
|
|
13
13
|
*
|
|
14
|
-
* When used,
|
|
14
|
+
* When used, WarpDrive APIs can
|
|
15
15
|
* take advantage of this to provide better type
|
|
16
16
|
* safety and intellisense.
|
|
17
17
|
*
|
|
@@ -48,7 +48,7 @@ const Type = getOrSetGlobal('$type', Symbol('$type'));
|
|
|
48
48
|
* record implementations to provide a typescript
|
|
49
49
|
* hint for the type of the resource.
|
|
50
50
|
*
|
|
51
|
-
* When used,
|
|
51
|
+
* When used, WarpDrive APIs can
|
|
52
52
|
* take advantage of this to provide better type
|
|
53
53
|
* safety and intellisense.
|
|
54
54
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warp-drive/core",
|
|
3
|
-
"version": "5.8.0-alpha.
|
|
3
|
+
"version": "5.8.0-alpha.8",
|
|
4
4
|
"description": "Core package for WarpDrive | All the Universal Basics",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@embroider/macros": "^1.18.1",
|
|
40
|
-
"@warp-drive/build-config": "5.8.0-alpha.
|
|
40
|
+
"@warp-drive/build-config": "5.8.0-alpha.8"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@babel/core": "^7.28.3",
|
|
44
44
|
"@babel/plugin-transform-typescript": "^7.28.0",
|
|
45
45
|
"@babel/preset-typescript": "^7.27.1",
|
|
46
|
-
"@warp-drive/internal-config": "5.8.0-alpha.
|
|
46
|
+
"@warp-drive/internal-config": "5.8.0-alpha.8",
|
|
47
47
|
"decorator-transforms": "^2.3.0",
|
|
48
48
|
"ember-source": "~6.6.0",
|
|
49
49
|
"expect-type": "^1.2.2",
|