@warp-drive/core 5.7.0-alpha.14 → 5.7.0-alpha.16
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/-diff.d.ts +8 -8
- package/declarations/graph/-private/-edge-definition.d.ts +2 -2
- package/declarations/graph/-private/-state.d.ts +2 -2
- package/declarations/graph/-private/-utils.d.ts +5 -5
- package/declarations/graph/-private/debug/assert-polymorphic-type.d.ts +3 -3
- package/declarations/graph/-private/edges/collection.d.ts +10 -10
- package/declarations/graph/-private/edges/implicit.d.ts +5 -5
- package/declarations/graph/-private/edges/resource.d.ts +5 -5
- package/declarations/graph/-private/graph.d.ts +15 -15
- package/declarations/graph/-private/operations/replace-related-records.d.ts +4 -4
- package/declarations/graph/-private/operations/update-relationship.d.ts +3 -3
- package/declarations/index.d.ts +1 -1
- package/declarations/reactive/-private/default-mode.d.ts +2 -2
- package/declarations/reactive/-private/document.d.ts +6 -16
- package/declarations/reactive/-private/fields/managed-array.d.ts +2 -2
- package/declarations/reactive/-private/fields/many-array-manager.d.ts +2 -2
- package/declarations/reactive/-private/hooks.d.ts +2 -2
- package/declarations/reactive/-private/record.d.ts +44 -5
- package/declarations/reactive/-private/schema.d.ts +12 -12
- package/declarations/reactive/-private/symbols.d.ts +1 -0
- package/declarations/reactive.d.ts +277 -1
- package/declarations/request/-private/context.d.ts +2 -2
- package/declarations/request/-private/manager.d.ts +2 -2
- package/declarations/request/-private/types.d.ts +4 -4
- package/declarations/store/-private/cache-handler/types.d.ts +9 -9
- package/declarations/store/-private/cache-handler/utils.d.ts +4 -4
- package/declarations/store/-private/caches/instance-cache.d.ts +18 -18
- package/declarations/store/-private/default-cache-policy.d.ts +25 -38
- package/declarations/store/-private/managers/cache-capabilities-manager.d.ts +13 -11
- package/declarations/store/-private/{caches/identifier-cache.d.ts → managers/cache-key-manager.d.ts} +21 -19
- package/declarations/store/-private/managers/cache-manager.d.ts +46 -94
- package/declarations/store/-private/managers/notification-manager.d.ts +21 -22
- package/declarations/store/-private/managers/record-array-manager.d.ts +15 -15
- package/declarations/store/-private/network/request-cache.d.ts +11 -11
- package/declarations/store/-private/new-core-tmp/expensive-subscription.d.ts +24 -0
- package/declarations/store/-private/new-core-tmp/request-state.d.ts +1 -1
- package/declarations/store/-private/record-arrays/-utils.d.ts +3 -3
- package/declarations/store/-private/record-arrays/legacy-live-array.d.ts +2 -2
- package/declarations/store/-private/record-arrays/legacy-many-array.d.ts +2 -2
- package/declarations/store/-private/record-arrays/resource-array.d.ts +9 -9
- package/declarations/store/-private/store-service.d.ts +19 -16
- package/declarations/store/-private.d.ts +1 -1
- package/declarations/store/-types/q/cache-capabilities-manager.d.ts +15 -24
- package/declarations/store/-types/q/identifier.d.ts +9 -6
- package/declarations/store/-types/q/schema-service.d.ts +9 -9
- package/declarations/store/deprecated/-private.d.ts +5 -5
- package/declarations/types/-private.d.ts +1 -1
- package/declarations/types/cache/aliases.d.ts +2 -2
- package/declarations/types/cache/change.d.ts +2 -2
- package/declarations/types/cache/mutations.d.ts +13 -13
- package/declarations/types/cache/operations.d.ts +20 -20
- package/declarations/types/cache/relationship.d.ts +4 -4
- package/declarations/types/cache.d.ts +51 -113
- package/declarations/types/graph.d.ts +12 -12
- package/declarations/types/identifier.d.ts +60 -76
- package/declarations/types/request.d.ts +6 -6
- package/declarations/types/schema/concepts.d.ts +2 -2
- package/declarations/types/spec/document.d.ts +6 -6
- package/dist/graph/-private.js +125 -125
- package/dist/index.js +2 -2
- package/dist/reactive/-private.js +1 -1
- package/dist/reactive.js +126 -4
- package/dist/{request-state-CCrTjb0Z.js → request-state-CQ0Q6d1V.js} +3493 -3483
- package/dist/store/-private.js +1 -1
- package/dist/store.js +30 -43
- package/dist/{symbols-C5p2hcy9.js → symbols-sql1_mdx.js} +2 -1
- package/dist/types/-private.js +1 -1
- package/dist/types/identifier.js +19 -45
- package/package.json +3 -3
|
@@ -1,5 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # About
|
|
3
|
+
*
|
|
4
|
+
* This module provides an implementation of reactive objects that a Store may use for creating
|
|
5
|
+
* reactive representations of the raw data for requests, resources and their relationships
|
|
6
|
+
* stored in the cache.
|
|
7
|
+
*
|
|
8
|
+
* - For configuring the store to use these reactive objects, see [The Setup Guide](/guides/1-configuration/2-setup/1-universal.md)
|
|
9
|
+
* - For defining resource schemas, see [The Schema Guide](/guides)
|
|
10
|
+
*
|
|
11
|
+
* Any method that returns a record instance will use the `instantiateRecord`
|
|
12
|
+
* hook configured above to instantiate a ReactiveResource once this is in place.
|
|
13
|
+
* After that, its up to you what ReactiveResource can do.
|
|
14
|
+
*
|
|
15
|
+
* ## Modes
|
|
16
|
+
*
|
|
17
|
+
* ReactiveResource has two modes: `legacy` and `polaris`.
|
|
18
|
+
*
|
|
19
|
+
* **LegacyMode** can be used to emulate the behaviors and capabilities of WarpDrive's `Model` class,
|
|
20
|
+
* and because there is little distinction between Model and a ReactiveResource in LegacyMode we refer
|
|
21
|
+
* to both of these approaches as LegacyMode. This mode is the default experience in V5.
|
|
22
|
+
*
|
|
23
|
+
* In LegacyMode:
|
|
24
|
+
*
|
|
25
|
+
* - records are mutable
|
|
26
|
+
* - local changes immediately reflect app wide
|
|
27
|
+
* - records have all the APIs of Model (references, state props, currentState, methods etc)
|
|
28
|
+
* - the continued use of `@warp-drive/legacy` is required (though most imports from it can be removed)
|
|
29
|
+
* - `async: true` relationships are supported (but not recommended outside of [LinksMode](https://github.com/emberjs/data/blob/main/guides/relationships/features/links-mode.md))
|
|
30
|
+
*
|
|
31
|
+
* ---
|
|
32
|
+
*
|
|
33
|
+
* **PolarisMode** is an upcoming suite of features that will become the default experience in V6.
|
|
34
|
+
*
|
|
35
|
+
* In PolarisMode:
|
|
36
|
+
*
|
|
37
|
+
* - records are immutable, unless creating a new resource or explicitly checking out a record for editing
|
|
38
|
+
* - local changes are isolated until committed, displaying only via the editable version of the record
|
|
39
|
+
* - records have a more limited API, focused on only what is in their schema.
|
|
40
|
+
* - some common operations may have more friction to perform because intended utilities are not yet available
|
|
41
|
+
* - `async: true` relationships are not supported (see [LinksMode](https://github.com/emberjs/data/blob/main/guides/relationships/features/links-mode.md))
|
|
42
|
+
* - The `@warp-drive/legacy` package is not required
|
|
43
|
+
*
|
|
44
|
+
* These modes are interopable. The reactive object (record) for a resource in PolarisMode can relate to
|
|
45
|
+
* a record in LegacyMode and vice-versa. This interopability is true whether the record in LegacyMode is
|
|
46
|
+
* a ReactiveResource or a Model.
|
|
47
|
+
*
|
|
48
|
+
* ---
|
|
49
|
+
*
|
|
50
|
+
* ## Basic Usage
|
|
51
|
+
*
|
|
52
|
+
* ReactiveResource is a reactive object that transforms raw data from an associated
|
|
53
|
+
* cache into reactive data backed by Signals.
|
|
54
|
+
*
|
|
55
|
+
* The shape of the object and the transformation of raw cache data into its
|
|
56
|
+
* reactive form is controlled by a resource schema.
|
|
57
|
+
*
|
|
58
|
+
* For instance, lets say your API is a [{JSON:API}](https://jsonapi.org) and your store is using
|
|
59
|
+
* the Cache provided by [@warp-drive/json-api](/api/@warp-drive/json-api), and a request
|
|
60
|
+
* returns the following raw data:
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* {
|
|
64
|
+
* data: {
|
|
65
|
+
* type: 'user',
|
|
66
|
+
* id: '1',
|
|
67
|
+
* attributes: { firstName: 'Chris', lastName: 'Thoburn' },
|
|
68
|
+
* relationships: { pets: { data: [{ type: 'dog', id: '1' }] }}
|
|
69
|
+
* },
|
|
70
|
+
* included: [
|
|
71
|
+
* {
|
|
72
|
+
* type: 'dog',
|
|
73
|
+
* id: '1',
|
|
74
|
+
* attributes: { name: 'Rey' },
|
|
75
|
+
* relationships: { owner: { data: { type: 'user', id: '1' }}}
|
|
76
|
+
* }
|
|
77
|
+
* ]
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* We could describe the `'user'` and `'dog'` resources in the above payload
|
|
82
|
+
* with the following schemas:
|
|
83
|
+
*
|
|
84
|
+
* ```ts
|
|
85
|
+
* store.schema.registerResources([
|
|
86
|
+
* {
|
|
87
|
+
* type: 'user',
|
|
88
|
+
* identity: { type: '@id', name: 'id' },
|
|
89
|
+
* fields: [
|
|
90
|
+
* {
|
|
91
|
+
* type: '@identity',
|
|
92
|
+
* name: '$type',
|
|
93
|
+
* kind: 'derived',
|
|
94
|
+
* options: { key: 'type' },
|
|
95
|
+
* },
|
|
96
|
+
* { kind: 'field', name: 'firstName' },
|
|
97
|
+
* { kind: 'field', name: 'lastName' },
|
|
98
|
+
* {
|
|
99
|
+
* kind: 'derived',
|
|
100
|
+
* name: 'name',
|
|
101
|
+
* type: 'concat',
|
|
102
|
+
* options: { fields: ['firstName', 'lastName'], separator: ' ' }
|
|
103
|
+
* },
|
|
104
|
+
* {
|
|
105
|
+
* kind: 'hasMany',
|
|
106
|
+
* name: 'pets',
|
|
107
|
+
* type: 'pet',
|
|
108
|
+
* options: {
|
|
109
|
+
* async: false,
|
|
110
|
+
* inverse: 'owner',
|
|
111
|
+
* polymorphic: true,
|
|
112
|
+
* linksMode: true,
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* ]
|
|
116
|
+
* },
|
|
117
|
+
* {
|
|
118
|
+
* type: 'dog',
|
|
119
|
+
* identity: { type: '@id', name: 'id' },
|
|
120
|
+
* fields: [
|
|
121
|
+
* {
|
|
122
|
+
* type: '@identity',
|
|
123
|
+
* name: '$type',
|
|
124
|
+
* kind: 'derived',
|
|
125
|
+
* options: { key: 'type' },
|
|
126
|
+
* },
|
|
127
|
+
* { kind: 'field', name: 'name' },
|
|
128
|
+
* {
|
|
129
|
+
* kind: 'belongsTo',
|
|
130
|
+
* name: 'owner',
|
|
131
|
+
* type: 'user',
|
|
132
|
+
* options: {
|
|
133
|
+
* async: false,
|
|
134
|
+
* inverse: 'pets',
|
|
135
|
+
* as: 'pet',
|
|
136
|
+
* linksMode: true,
|
|
137
|
+
* }
|
|
138
|
+
* }
|
|
139
|
+
* ]
|
|
140
|
+
* }
|
|
141
|
+
* ]);
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* With these schemas in place, the reactive objects that the store would
|
|
145
|
+
* provide us whenever we encountered a `'user'` or a `'dog'` would be:
|
|
146
|
+
*
|
|
147
|
+
* ```ts
|
|
148
|
+
* interface Pet {
|
|
149
|
+
* readonly id: string;
|
|
150
|
+
* readonly owner: User;
|
|
151
|
+
* }
|
|
152
|
+
*
|
|
153
|
+
* interface Dog extends Pet {
|
|
154
|
+
* readonly $type: 'dog';
|
|
155
|
+
* readonly name: string;
|
|
156
|
+
* }
|
|
157
|
+
*
|
|
158
|
+
* interface EditableUser {
|
|
159
|
+
* readonly $type: 'user';
|
|
160
|
+
* readonly id: string;
|
|
161
|
+
* firstName: string;
|
|
162
|
+
* lastName: string;
|
|
163
|
+
* readonly name: string;
|
|
164
|
+
* pets: Array<Dog | Pet>;
|
|
165
|
+
* }
|
|
166
|
+
*
|
|
167
|
+
* interface User {
|
|
168
|
+
* readonly $type: 'user';
|
|
169
|
+
* readonly id: string;
|
|
170
|
+
* readonly firstName: string;
|
|
171
|
+
* readonly lastName: string;
|
|
172
|
+
* readonly name: string;
|
|
173
|
+
* readonly pets: Readonly<Array<Dog | Pet>>;
|
|
174
|
+
* [Checkout]: Promise<EditableUser>
|
|
175
|
+
* }>
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* Note how based on the schema the reactive object we receive is able to produce
|
|
179
|
+
* `name` on user (despite no name field being in the cache), provide `$type`
|
|
180
|
+
* pulled from the identity of the resource, and flatten the individual attributes
|
|
181
|
+
* and relationships onto the record for easier use.
|
|
182
|
+
*
|
|
183
|
+
* Notice also how we typed this object with `readonly`. This is because while
|
|
184
|
+
* ReactiveResource instances are ***deeply reactive***, they are also ***immutable***.
|
|
185
|
+
*
|
|
186
|
+
* We can mutate a ReactiveResource only be explicitly asking permission to do so, and
|
|
187
|
+
* in the process gaining access to an editable copy. The immutable version will
|
|
188
|
+
* not show any in-process edits made to this editable copy.
|
|
189
|
+
*
|
|
190
|
+
* ```ts
|
|
191
|
+
* import { Checkout } from '@warp-drive/schema-record';
|
|
192
|
+
*
|
|
193
|
+
* const editable = await user[Checkout]();
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* ## Utilities
|
|
197
|
+
*
|
|
198
|
+
* ReactiveResource provides a schema builder that simplifies setting up a couple of
|
|
199
|
+
* conventional fields like identity and `$type`. We can rewrite the schema
|
|
200
|
+
* definition above using this utility like so:
|
|
201
|
+
*
|
|
202
|
+
* ```ts
|
|
203
|
+
* import { withDefaults } from '@warp-drive/core/reactive';
|
|
204
|
+
*
|
|
205
|
+
* store.schema.registerResources([
|
|
206
|
+
* withDefaults({
|
|
207
|
+
* type: 'user',
|
|
208
|
+
* fields: [
|
|
209
|
+
* { kind: 'field', name: 'firstName' },
|
|
210
|
+
* { kind: 'field', name: 'lastName' },
|
|
211
|
+
* {
|
|
212
|
+
* kind: 'derived',
|
|
213
|
+
* name: 'name',
|
|
214
|
+
* type: 'concat',
|
|
215
|
+
* options: { fields: ['firstName', 'lastName'], separator: ' ' }
|
|
216
|
+
* },
|
|
217
|
+
* {
|
|
218
|
+
* kind: 'hasMany',
|
|
219
|
+
* name: 'pets',
|
|
220
|
+
* type: 'pet',
|
|
221
|
+
* options: {
|
|
222
|
+
* async: false,
|
|
223
|
+
* inverse: 'owner',
|
|
224
|
+
* polymorphic: true,
|
|
225
|
+
* linksMode: true,
|
|
226
|
+
* resetOnRemoteUpdate: false,
|
|
227
|
+
* }
|
|
228
|
+
* }
|
|
229
|
+
* ]
|
|
230
|
+
* }),
|
|
231
|
+
* withDefaults({
|
|
232
|
+
* type: 'dog',
|
|
233
|
+
* fields: [
|
|
234
|
+
* { kind: 'field', name: 'name' },
|
|
235
|
+
* {
|
|
236
|
+
* kind: 'belongsTo',
|
|
237
|
+
* name: 'owner',
|
|
238
|
+
* type: 'user',
|
|
239
|
+
* options: {
|
|
240
|
+
* async: false,
|
|
241
|
+
* inverse: 'pets',
|
|
242
|
+
* as: 'pet',
|
|
243
|
+
* linksMode: true,
|
|
244
|
+
* resetOnRemoteUpdate: false,
|
|
245
|
+
* }
|
|
246
|
+
* }
|
|
247
|
+
* ]
|
|
248
|
+
* })
|
|
249
|
+
* ]);
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* ## Type Support
|
|
253
|
+
*
|
|
254
|
+
* ### Resource Schemas
|
|
255
|
+
*
|
|
256
|
+
* - {@link PolarisResourceSchema}
|
|
257
|
+
* - {@link LegacyResourceSchema}
|
|
258
|
+
* - {@link ObjectSchema}
|
|
259
|
+
*
|
|
260
|
+
* ### Resource Schema Type Utils
|
|
261
|
+
*
|
|
262
|
+
* - {@link resourceSchema}
|
|
263
|
+
* - {@link objectSchema}
|
|
264
|
+
* - {@link isResourceSchema}
|
|
265
|
+
* - {@link isLegacyResourceSchema}
|
|
266
|
+
*
|
|
267
|
+
* ### Field Schemas
|
|
268
|
+
*
|
|
269
|
+
* - {@link LegacyModeFieldSchema}
|
|
270
|
+
* - {@link PolarisModeFieldSchema}
|
|
271
|
+
*
|
|
272
|
+
* @module
|
|
273
|
+
*/
|
|
274
|
+
import { checkout } from "./reactive/-private/record.js";
|
|
1
275
|
export { instantiateRecord, teardownRecord } from "./reactive/-private/hooks.js";
|
|
2
276
|
export { type CAUTION_MEGA_DANGER_ZONE_Extension, type ProcessedExtension, type ExtensionDef, type Transformation, SchemaService, withDefaults, fromIdentity, registerDerivations } from "./reactive/-private/schema.js";
|
|
3
|
-
export { type ReactiveResource } from "./reactive/-private/record.js";
|
|
277
|
+
export { commit, type ReactiveResource } from "./reactive/-private/record.js";
|
|
278
|
+
export { checkout };
|
|
4
279
|
export { Checkout } from "./reactive/-private/symbols.js";
|
|
5
280
|
export { type ReactiveDocument } from "./reactive/-private/document.js";
|
|
281
|
+
export { getExpensiveRequestSubscription } from "./store/-private/new-core-tmp/expensive-subscription.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestKey } from "../../types/identifier.js";
|
|
2
2
|
import type { ImmutableHeaders, ImmutableRequestInfo, RequestInfo, ResponseInfo } from "../../types/request.js";
|
|
3
3
|
import type { DeferredStream, GodContext } from "./types.js";
|
|
4
4
|
export declare function upgradeHeaders(headers: Headers | ImmutableHeaders): ImmutableHeaders;
|
|
@@ -34,7 +34,7 @@ export declare class Context {
|
|
|
34
34
|
constructor(owner: ContextOwner, isCacheHandler: boolean);
|
|
35
35
|
setStream(stream: ReadableStream | Promise<ReadableStream | null>): void;
|
|
36
36
|
setResponse(response: ResponseInfo | Response | null): void;
|
|
37
|
-
setIdentifier(identifier:
|
|
37
|
+
setIdentifier(identifier: RequestKey): void;
|
|
38
38
|
get hasRequestedStream(): boolean;
|
|
39
39
|
_finalize(): void;
|
|
40
40
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestKey } from "../../types/identifier.js";
|
|
2
2
|
import type { RequestInfo } from "../../types/request.js";
|
|
3
3
|
import type { CacheHandler, Future, GenericCreateArgs, Handler, ManagedRequestPriority } from "./types.js";
|
|
4
4
|
import { IS_CACHE_HANDLER } from "./utils.js";
|
|
@@ -107,7 +107,7 @@ export declare class RequestManager {
|
|
|
107
107
|
*/
|
|
108
108
|
_pending: Map<number, Promise<unknown>>;
|
|
109
109
|
/** @internal */
|
|
110
|
-
_deduped: Map<
|
|
110
|
+
_deduped: Map<RequestKey, {
|
|
111
111
|
priority: ManagedRequestPriority;
|
|
112
112
|
promise: Promise<unknown>;
|
|
113
113
|
}>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-irregular-whitespace */
|
|
2
|
-
import type {
|
|
2
|
+
import type { RequestKey } from "../../types/identifier.js";
|
|
3
3
|
import type { IS_FUTURE, RequestContext, RequestInfo, ResponseInfo, StructuredDataDocument } from "../../types/request.js";
|
|
4
4
|
export interface GodContext {
|
|
5
5
|
controller: AbortController;
|
|
@@ -7,7 +7,7 @@ export interface GodContext {
|
|
|
7
7
|
stream: ReadableStream | Promise<ReadableStream | null> | null;
|
|
8
8
|
hasRequestedStream: boolean;
|
|
9
9
|
id: number;
|
|
10
|
-
identifier:
|
|
10
|
+
identifier: RequestKey | null;
|
|
11
11
|
}
|
|
12
12
|
export type Deferred<T> = {
|
|
13
13
|
resolve(v: T): void;
|
|
@@ -64,10 +64,10 @@ export interface Future<T> extends Promise<StructuredDataDocument<T>> {
|
|
|
64
64
|
* assigned by the CacheHandler.
|
|
65
65
|
*
|
|
66
66
|
* @property lid
|
|
67
|
-
* @type {
|
|
67
|
+
* @type {RequestKey | null}
|
|
68
68
|
* @public
|
|
69
69
|
*/
|
|
70
|
-
lid:
|
|
70
|
+
lid: RequestKey | null;
|
|
71
71
|
/**
|
|
72
72
|
* The id of the associated request, if any, as assigned
|
|
73
73
|
* by the RequestManager
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestKey } from "../../../types/identifier.js";
|
|
2
2
|
import type { ImmutableRequestInfo, ResponseInfo } from "../../../types/request.js";
|
|
3
3
|
import type { Store } from "../store-service.js";
|
|
4
4
|
/**
|
|
@@ -27,11 +27,11 @@ export interface CachePolicy {
|
|
|
27
27
|
* and the cache will be updated before returning the response.
|
|
28
28
|
*
|
|
29
29
|
* @public
|
|
30
|
-
* @param {
|
|
30
|
+
* @param {RequestKey} identifier
|
|
31
31
|
* @param {Store} store
|
|
32
32
|
* @return {Boolean} true if the request is considered hard expired
|
|
33
33
|
*/
|
|
34
|
-
isHardExpired(identifier:
|
|
34
|
+
isHardExpired(identifier: RequestKey, store: Store): boolean;
|
|
35
35
|
/**
|
|
36
36
|
* Invoked if `isHardExpired` is false to determine if the request
|
|
37
37
|
* should be update behind the scenes if cache data is already available.
|
|
@@ -42,11 +42,11 @@ export interface CachePolicy {
|
|
|
42
42
|
* request is made to update the cache via the configured request handlers.
|
|
43
43
|
*
|
|
44
44
|
* @public
|
|
45
|
-
* @param {
|
|
45
|
+
* @param {RequestKey} identifier
|
|
46
46
|
* @param {Store} store
|
|
47
47
|
* @return {Boolean} true if the request is considered soft expired
|
|
48
48
|
*/
|
|
49
|
-
isSoftExpired(identifier:
|
|
49
|
+
isSoftExpired(identifier: RequestKey, store: Store): boolean;
|
|
50
50
|
/**
|
|
51
51
|
* Invoked when a request will be sent to the configured request handlers.
|
|
52
52
|
* This is invoked for both foreground and background requests.
|
|
@@ -55,11 +55,11 @@ export interface CachePolicy {
|
|
|
55
55
|
*
|
|
56
56
|
* @public
|
|
57
57
|
* @param {ImmutableRequestInfo} request
|
|
58
|
-
* @param {
|
|
58
|
+
* @param {RequestKey | null} identifier
|
|
59
59
|
* @param {Store} store
|
|
60
60
|
* @return {void}
|
|
61
61
|
*/
|
|
62
|
-
willRequest?(request: ImmutableRequestInfo, identifier:
|
|
62
|
+
willRequest?(request: ImmutableRequestInfo, identifier: RequestKey | null, store: Store): void;
|
|
63
63
|
/**
|
|
64
64
|
* Invoked when a request has been fulfilled from the configured request handlers.
|
|
65
65
|
* This is invoked for both foreground and background requests once the cache has
|
|
@@ -90,9 +90,9 @@ export interface CachePolicy {
|
|
|
90
90
|
* @public
|
|
91
91
|
* @param {ImmutableRequestInfo} request
|
|
92
92
|
* @param {ImmutableResponse} response
|
|
93
|
-
* @param {
|
|
93
|
+
* @param {RequestKey | null} identifier
|
|
94
94
|
* @param {Store} store
|
|
95
95
|
* @return {void}
|
|
96
96
|
*/
|
|
97
|
-
didRequest?(request: ImmutableRequestInfo, response: Response | ResponseInfo | null, identifier:
|
|
97
|
+
didRequest?(request: ImmutableRequestInfo, response: Response | ResponseInfo | null, identifier: RequestKey | null, store: Store): void;
|
|
98
98
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestKey } from "../../../types/identifier.js";
|
|
2
2
|
import type { ImmutableCreateRequestOptions, ImmutableDeleteRequestOptions, ImmutableRequestInfo, ImmutableUpdateRequestOptions, StructuredDataDocument } from "../../../types/request.js";
|
|
3
3
|
import type { ResourceDataDocument, ResourceErrorDocument } from "../../../types/spec/document.js";
|
|
4
4
|
import type { ApiError } from "../../../types/spec/error.js";
|
|
5
5
|
import type { Store } from "../store-service.js";
|
|
6
6
|
export declare const MUTATION_OPS: Set<string>;
|
|
7
|
-
export declare function calcShouldFetch(store: Store, request: ImmutableRequestInfo, hasCachedValue: boolean, identifier:
|
|
8
|
-
export declare function calcShouldBackgroundFetch(store: Store, request: ImmutableRequestInfo, willFetch: boolean, identifier:
|
|
7
|
+
export declare function calcShouldFetch(store: Store, request: ImmutableRequestInfo, hasCachedValue: boolean, identifier: RequestKey | null): boolean;
|
|
8
|
+
export declare function calcShouldBackgroundFetch(store: Store, request: ImmutableRequestInfo, willFetch: boolean, identifier: RequestKey | null): boolean;
|
|
9
9
|
export declare function isMutation(request: Partial<ImmutableRequestInfo>): request is ImmutableUpdateRequestOptions | ImmutableCreateRequestOptions | ImmutableDeleteRequestOptions;
|
|
10
10
|
export declare function isCacheAffecting<T>(document: StructuredDataDocument<T>): boolean;
|
|
11
11
|
export declare function isAggregateError(error: Error & {
|
|
@@ -21,7 +21,7 @@ export type RobustError = Error & {
|
|
|
21
21
|
// TODO @runspired, consider if we should deep freeze errors (potentially only in debug) vs cloning them
|
|
22
22
|
export declare function cloneError(error: RobustError): RobustError;
|
|
23
23
|
export declare function isErrorDocument(document: ResourceDataDocument | ResourceErrorDocument): document is ResourceErrorDocument;
|
|
24
|
-
export declare function getPriority(identifier:
|
|
24
|
+
export declare function getPriority(identifier: RequestKey | null, deduped: Map<RequestKey, {
|
|
25
25
|
priority: {
|
|
26
26
|
blocking: boolean;
|
|
27
27
|
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { ReactiveDocument } from "../../../reactive/-private/document.js";
|
|
2
2
|
import type { Cache } from "../../../types/cache.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { RequestKey, ResourceKey } from "../../../types/identifier.js";
|
|
4
4
|
import type { TypedRecordInstance, TypeFromInstance } from "../../../types/record.js";
|
|
5
5
|
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 peekRecordIdentifier(record: OpaqueRecordInstance):
|
|
9
|
+
export declare function peekRecordIdentifier(record: OpaqueRecordInstance): ResourceKey | undefined;
|
|
10
10
|
/**
|
|
11
|
-
Retrieves the unique referentially-stable [RecordIdentifier](/ember-data/release/classes/
|
|
11
|
+
Retrieves the unique referentially-stable [RecordIdentifier](/ember-data/release/classes/ResourceKey)
|
|
12
12
|
assigned to the given record instance.
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
15
|
import { recordIdentifierFor } from "@ember-data/store";
|
|
16
16
|
// ... gain access to a record, for instance with peekRecord or findRecord
|
|
17
17
|
const record = store.peekRecord("user", "1");
|
|
18
|
-
// get the identifier for the record (see docs for
|
|
18
|
+
// get the identifier for the record (see docs for ResourceKey)
|
|
19
19
|
const identifier = recordIdentifierFor(record);
|
|
20
20
|
// access the identifier's properties.
|
|
21
21
|
const { id, type, lid } = identifier;
|
|
@@ -23,11 +23,11 @@ const { id, type, lid } = identifier;
|
|
|
23
23
|
|
|
24
24
|
@public
|
|
25
25
|
@param {Object} record a record instance previously obstained from the store.
|
|
26
|
-
@return {
|
|
26
|
+
@return {ResourceKey}
|
|
27
27
|
*/
|
|
28
|
-
export declare function recordIdentifierFor<T extends TypedRecordInstance>(record: T):
|
|
29
|
-
export declare function recordIdentifierFor(record: OpaqueRecordInstance):
|
|
30
|
-
export declare function setRecordIdentifier(record: OpaqueRecordInstance, identifier:
|
|
28
|
+
export declare function recordIdentifierFor<T extends TypedRecordInstance>(record: T): ResourceKey<TypeFromInstance<T>>;
|
|
29
|
+
export declare function recordIdentifierFor(record: OpaqueRecordInstance): ResourceKey;
|
|
30
|
+
export declare function setRecordIdentifier(record: OpaqueRecordInstance, identifier: ResourceKey): void;
|
|
31
31
|
export declare function removeRecordIdentifier(record: OpaqueRecordInstance): void;
|
|
32
32
|
export declare const StoreMap: Map<unknown, Store>;
|
|
33
33
|
/**
|
|
@@ -36,8 +36,8 @@ export declare const StoreMap: Map<unknown, Store>;
|
|
|
36
36
|
*/
|
|
37
37
|
export declare function storeFor(record: OpaqueRecordInstance, ignoreMissing: boolean): Store | null;
|
|
38
38
|
export type Caches = {
|
|
39
|
-
record: Map<
|
|
40
|
-
document: Map<
|
|
39
|
+
record: Map<ResourceKey, OpaqueRecordInstance>;
|
|
40
|
+
document: Map<RequestKey, ReactiveDocument<OpaqueRecordInstance | OpaqueRecordInstance[] | null | undefined>>;
|
|
41
41
|
};
|
|
42
42
|
export declare class InstanceCache {
|
|
43
43
|
store: Store;
|
|
@@ -46,15 +46,15 @@ export declare class InstanceCache {
|
|
|
46
46
|
__cacheManager: CacheManager;
|
|
47
47
|
__instances: Caches;
|
|
48
48
|
constructor(store: Store);
|
|
49
|
-
peek(identifier:
|
|
50
|
-
getDocument<T>(identifier:
|
|
51
|
-
getRecord(identifier:
|
|
52
|
-
recordIsLoaded(identifier:
|
|
53
|
-
disconnect(identifier:
|
|
54
|
-
unloadRecord(identifier:
|
|
49
|
+
peek(identifier: ResourceKey): Cache | OpaqueRecordInstance | undefined;
|
|
50
|
+
getDocument<T>(identifier: RequestKey): ReactiveDocument<T>;
|
|
51
|
+
getRecord(identifier: ResourceKey): OpaqueRecordInstance;
|
|
52
|
+
recordIsLoaded(identifier: ResourceKey, filterDeleted?: boolean): boolean;
|
|
53
|
+
disconnect(identifier: ResourceKey): void;
|
|
54
|
+
unloadRecord(identifier: ResourceKey): void;
|
|
55
55
|
clear(type?: string): void;
|
|
56
56
|
// TODO this should move into something coordinating operations
|
|
57
|
-
setRecordId(identifier:
|
|
57
|
+
setRecordId(identifier: ResourceKey, id: string): void;
|
|
58
58
|
}
|
|
59
|
-
export declare function getNewRecord(instances: InstanceCache, identifier:
|
|
59
|
+
export declare function getNewRecord(instances: InstanceCache, identifier: ResourceKey, properties: CreateRecordProperties): OpaqueRecordInstance;
|
|
60
60
|
export declare function _clearCaches(): void;
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import type { Cache } from "@warp-drive/core/types/cache";
|
|
2
|
-
import type {
|
|
2
|
+
import type { RequestKey, ResourceKey } from "@warp-drive/core/types/identifier";
|
|
3
3
|
import type { ImmutableRequestInfo, ResponseInfo, StructuredDocument } from "@warp-drive/core/types/request";
|
|
4
4
|
import type { ResourceDocument } from "@warp-drive/core/types/spec/document";
|
|
5
5
|
type UnsubscribeToken = object;
|
|
6
6
|
type CacheOperation = "added" | "removed" | "updated" | "state";
|
|
7
7
|
type DocumentCacheOperation = "invalidated" | "added" | "removed" | "updated" | "state";
|
|
8
8
|
export interface NotificationCallback {
|
|
9
|
-
(
|
|
10
|
-
(
|
|
9
|
+
(resourceKey: ResourceKey, notificationType: "attributes" | "relationships", key?: string): void;
|
|
10
|
+
(resourceKey: ResourceKey, notificationType: "errors" | "meta" | "identity" | "state"): void;
|
|
11
11
|
}
|
|
12
12
|
interface ResourceOperationCallback {
|
|
13
13
|
// resource updates
|
|
14
|
-
(
|
|
14
|
+
(resourceKey: ResourceKey, notificationType: CacheOperation): void;
|
|
15
15
|
}
|
|
16
16
|
interface DocumentOperationCallback {
|
|
17
17
|
// document updates
|
|
18
|
-
(
|
|
18
|
+
(cacheKey: RequestKey, notificationType: DocumentCacheOperation): void;
|
|
19
19
|
}
|
|
20
20
|
type NotificationManager = {
|
|
21
|
-
subscribe(
|
|
22
|
-
subscribe(
|
|
23
|
-
subscribe(
|
|
24
|
-
notify(
|
|
25
|
-
notify(
|
|
26
|
-
notify(
|
|
27
|
-
notify(
|
|
21
|
+
subscribe(resourceKey: ResourceKey, callback: NotificationCallback): UnsubscribeToken;
|
|
22
|
+
subscribe(cacheKey: "resource", callback: ResourceOperationCallback): UnsubscribeToken;
|
|
23
|
+
subscribe(cacheKey: "document" | RequestKey, callback: DocumentOperationCallback): UnsubscribeToken;
|
|
24
|
+
notify(cacheKey: ResourceKey, value: "attributes" | "relationships", key?: string): boolean;
|
|
25
|
+
notify(cacheKey: ResourceKey, value: "errors" | "meta" | "identity" | "state"): boolean;
|
|
26
|
+
notify(cacheKey: ResourceKey, value: CacheOperation): boolean;
|
|
27
|
+
notify(cacheKey: RequestKey, value: DocumentCacheOperation): boolean;
|
|
28
28
|
};
|
|
29
29
|
type Store = {
|
|
30
30
|
cache: Cache;
|
|
@@ -236,7 +236,7 @@ export type PolicyConfig = {
|
|
|
236
236
|
* request for that type is successful.
|
|
237
237
|
*
|
|
238
238
|
* For this to work, the `createRecord` request must include the `cacheOptions.types` array
|
|
239
|
-
* with the types that should be invalidated, or its request should specify the
|
|
239
|
+
* with the types that should be invalidated, or its request should specify the ResourceKeys
|
|
240
240
|
* of the records that are being created via `records`. Providing both is valid.
|
|
241
241
|
*
|
|
242
242
|
* > [!NOTE]
|
|
@@ -285,30 +285,28 @@ export type PolicyConfig = {
|
|
|
285
285
|
export declare class DefaultCachePolicy {
|
|
286
286
|
config: PolicyConfig;
|
|
287
287
|
_stores: WeakMap<Store, {
|
|
288
|
-
invalidated: Set<
|
|
289
|
-
types: Map<string, Set<
|
|
288
|
+
invalidated: Set<RequestKey>;
|
|
289
|
+
types: Map<string, Set<RequestKey>>;
|
|
290
290
|
}>;
|
|
291
291
|
_getStore(store: Store): {
|
|
292
|
-
invalidated: Set<
|
|
293
|
-
types: Map<string, Set<
|
|
292
|
+
invalidated: Set<RequestKey>;
|
|
293
|
+
types: Map<string, Set<RequestKey>>;
|
|
294
294
|
};
|
|
295
295
|
constructor(config: PolicyConfig);
|
|
296
296
|
/**
|
|
297
|
-
* Invalidate a request by its
|
|
297
|
+
* Invalidate a request by its CacheKey for the given store instance.
|
|
298
298
|
*
|
|
299
299
|
* While the store argument may seem redundant, the CachePolicy
|
|
300
300
|
* is designed to be shared across multiple stores / forks
|
|
301
301
|
* of the store.
|
|
302
302
|
*
|
|
303
303
|
* ```ts
|
|
304
|
-
* store.lifetimes.invalidateRequest(store,
|
|
304
|
+
* store.lifetimes.invalidateRequest(store, cacheKey);
|
|
305
305
|
* ```
|
|
306
306
|
*
|
|
307
307
|
* @public
|
|
308
|
-
* @param {StableDocumentIdentifier} identifier
|
|
309
|
-
* @param {Store} store
|
|
310
308
|
*/
|
|
311
|
-
invalidateRequest(
|
|
309
|
+
invalidateRequest(cacheKey: RequestKey, store: Store): void;
|
|
312
310
|
/**
|
|
313
311
|
* Invalidate all requests associated to a specific type
|
|
314
312
|
* for a given store instance.
|
|
@@ -325,8 +323,6 @@ export declare class DefaultCachePolicy {
|
|
|
325
323
|
* ```
|
|
326
324
|
*
|
|
327
325
|
* @public
|
|
328
|
-
* @param {String} type
|
|
329
|
-
* @param {Store} store
|
|
330
326
|
*/
|
|
331
327
|
invalidateRequestsForType(type: string, store: Store): void;
|
|
332
328
|
/**
|
|
@@ -340,13 +336,8 @@ export declare class DefaultCachePolicy {
|
|
|
340
336
|
* This method should not be invoked directly by consumers.
|
|
341
337
|
*
|
|
342
338
|
* @public
|
|
343
|
-
* @param {ImmutableRequestInfo} request
|
|
344
|
-
* @param {ImmutableResponse} response
|
|
345
|
-
* @param {Store} store
|
|
346
|
-
* @param {StableDocumentIdentifier | null} identifier
|
|
347
|
-
* @return {void}
|
|
348
339
|
*/
|
|
349
|
-
didRequest(request: ImmutableRequestInfo, response: Response | ResponseInfo | null,
|
|
340
|
+
didRequest(request: ImmutableRequestInfo, response: Response | ResponseInfo | null, cacheKey: RequestKey | null, store: Store): void;
|
|
350
341
|
/**
|
|
351
342
|
* Invoked to determine if the request may be fulfilled from cache
|
|
352
343
|
* if possible.
|
|
@@ -359,11 +350,9 @@ export declare class DefaultCachePolicy {
|
|
|
359
350
|
* and the cache will be updated before returning the response.
|
|
360
351
|
*
|
|
361
352
|
* @public
|
|
362
|
-
* @
|
|
363
|
-
* @param {Store} store
|
|
364
|
-
* @return {Boolean} true if the request is considered hard expired
|
|
353
|
+
* @return true if the request is considered hard expired
|
|
365
354
|
*/
|
|
366
|
-
isHardExpired(
|
|
355
|
+
isHardExpired(cacheKey: RequestKey, store: Store): boolean;
|
|
367
356
|
/**
|
|
368
357
|
* Invoked if `isHardExpired` is false to determine if the request
|
|
369
358
|
* should be update behind the scenes if cache data is already available.
|
|
@@ -375,10 +364,8 @@ export declare class DefaultCachePolicy {
|
|
|
375
364
|
* request is made to update the cache via the configured request handlers.
|
|
376
365
|
*
|
|
377
366
|
* @public
|
|
378
|
-
* @
|
|
379
|
-
* @param {Store} store
|
|
380
|
-
* @return {Boolean} true if the request is considered soft expired
|
|
367
|
+
* @return true if the request is considered soft expired
|
|
381
368
|
*/
|
|
382
|
-
isSoftExpired(
|
|
369
|
+
isSoftExpired(cacheKey: RequestKey, store: Store): boolean;
|
|
383
370
|
}
|
|
384
371
|
export {};
|