@luvio/environments 0.59.0 → 0.61.0-236.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/es2018/environments.js +223 -36
- package/dist/es/es2018/makeDurable/cachepolicies/cache-and-network.d.ts +3 -0
- package/dist/es/es2018/makeDurable/cachepolicies/cache-then-network.d.ts +3 -0
- package/dist/es/es2018/makeDurable/cachepolicies/index.d.ts +4 -0
- package/dist/es/es2018/makeDurable/cachepolicies/no-cache.d.ts +3 -0
- package/dist/es/es2018/makeDurable/cachepolicies/only-if-cached.d.ts +3 -0
- package/dist/es/es2018/makeDurable/cachepolicies/stale-while-revalidate.d.ts +1 -1
- package/dist/es/es2018/makeDurable/cachepolicies/utils.d.ts +2 -1
- package/dist/es/es2018/makeDurable/cachepolicies/valid-at.d.ts +3 -0
- package/dist/umd/es2018/environments.js +222 -35
- package/dist/umd/es2018/makeDurable/cachepolicies/cache-and-network.d.ts +3 -0
- package/dist/umd/es2018/makeDurable/cachepolicies/cache-then-network.d.ts +3 -0
- package/dist/umd/es2018/makeDurable/cachepolicies/index.d.ts +4 -0
- package/dist/umd/es2018/makeDurable/cachepolicies/no-cache.d.ts +3 -0
- package/dist/umd/es2018/makeDurable/cachepolicies/only-if-cached.d.ts +3 -0
- package/dist/umd/es2018/makeDurable/cachepolicies/stale-while-revalidate.d.ts +1 -1
- package/dist/umd/es2018/makeDurable/cachepolicies/utils.d.ts +2 -1
- package/dist/umd/es2018/makeDurable/cachepolicies/valid-at.d.ts +3 -0
- package/dist/umd/es5/environments.js +229 -38
- package/dist/umd/es5/makeDurable/cachepolicies/cache-and-network.d.ts +3 -0
- package/dist/umd/es5/makeDurable/cachepolicies/cache-then-network.d.ts +3 -0
- package/dist/umd/es5/makeDurable/cachepolicies/index.d.ts +4 -0
- package/dist/umd/es5/makeDurable/cachepolicies/no-cache.d.ts +3 -0
- package/dist/umd/es5/makeDurable/cachepolicies/only-if-cached.d.ts +3 -0
- package/dist/umd/es5/makeDurable/cachepolicies/stale-while-revalidate.d.ts +1 -1
- package/dist/umd/es5/makeDurable/cachepolicies/utils.d.ts +2 -1
- package/dist/umd/es5/makeDurable/cachepolicies/valid-at.d.ts +3 -0
- package/package.json +4 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StoreResolveResultState, Store, buildStaleWhileRevalidateImplementation as buildStaleWhileRevalidateImplementation$1 } from '@luvio/engine';
|
|
1
|
+
import { StoreResolveResultState, HttpStatusCode, Store, buildStaleWhileRevalidateImplementation as buildStaleWhileRevalidateImplementation$1 } from '@luvio/engine';
|
|
2
2
|
|
|
3
3
|
function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
4
4
|
if (durableRecord.expiration !== undefined) {
|
|
@@ -17,12 +17,20 @@ const DefaultDurableSegment = 'DEFAULT';
|
|
|
17
17
|
const { keys, create, assign, freeze } = Object;
|
|
18
18
|
const { isArray } = Array;
|
|
19
19
|
|
|
20
|
-
function
|
|
20
|
+
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
21
|
+
return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
|
|
22
|
+
}
|
|
23
|
+
function buildNetworkSnapshot(args) {
|
|
24
|
+
const { buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest } = args;
|
|
25
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest).then((snapshot) => snapshot.state === 'Pending' ? args.resolvePendingSnapshot(snapshot) : snapshot);
|
|
26
|
+
}
|
|
27
|
+
function buildTTLStrategy(staleDurationMilliseconds = 0) {
|
|
21
28
|
return (timestamp, metadata, valueIsError) => {
|
|
22
29
|
if (metadata !== undefined) {
|
|
23
30
|
const { expirationTimestamp } = metadata;
|
|
24
31
|
if (timestamp > expirationTimestamp) {
|
|
25
|
-
if (timestamp <= expirationTimestamp +
|
|
32
|
+
if (timestamp <= expirationTimestamp + staleDurationMilliseconds &&
|
|
33
|
+
valueIsError !== true) {
|
|
26
34
|
return StoreResolveResultState.Stale;
|
|
27
35
|
}
|
|
28
36
|
return StoreResolveResultState.NotPresent;
|
|
@@ -33,29 +41,86 @@ function buildTTLStrategy(staleDuration = 0) {
|
|
|
33
41
|
}
|
|
34
42
|
return StoreResolveResultState.Found;
|
|
35
43
|
};
|
|
36
|
-
}
|
|
37
|
-
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
38
|
-
return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
function
|
|
46
|
+
function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
|
|
42
47
|
return function (args) {
|
|
43
48
|
funcs.validateNotDisposed();
|
|
44
|
-
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
45
|
-
const
|
|
49
|
+
const { buildInMemorySnapshot, buildNetworkSnapshot: buildNetworkSnapshot$1, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
50
|
+
const staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
|
|
51
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
|
|
46
52
|
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
47
53
|
if (snapshot !== undefined) {
|
|
48
54
|
// data found in L1 cache
|
|
49
55
|
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
56
|
+
// kick off network request, do not await it
|
|
57
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
58
|
+
// return the cached snapshot to caller
|
|
50
59
|
return snapshot;
|
|
51
60
|
}
|
|
52
|
-
|
|
61
|
+
// network request outstanding
|
|
62
|
+
if (snapshot.state === 'Pending') {
|
|
63
|
+
// kick off another network request, do not await it
|
|
64
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
65
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
66
|
+
}
|
|
53
67
|
// stale data found in L1 cache
|
|
54
68
|
if (snapshot.state === 'Stale') {
|
|
69
|
+
// kick off network request, do not await it
|
|
55
70
|
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
56
71
|
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
72
|
+
// return the cached snapshot to caller
|
|
57
73
|
return snapshot;
|
|
58
74
|
}
|
|
75
|
+
// if unfulfilled we have enough info to do an L2 lookup
|
|
76
|
+
if (snapshot.state === 'Unfulfilled') {
|
|
77
|
+
return funcs
|
|
78
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
79
|
+
.then((revivedSnapshot) => {
|
|
80
|
+
// data found in L2 cache
|
|
81
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
82
|
+
revivedSnapshot.state === 'Error') {
|
|
83
|
+
// kick off network request, do not await it
|
|
84
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
85
|
+
// return the L2 cached snapshot to caller
|
|
86
|
+
return revivedSnapshot;
|
|
87
|
+
}
|
|
88
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
89
|
+
// kick off network request, do not await it
|
|
90
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
91
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
92
|
+
}
|
|
93
|
+
// stale data found in L2 cache
|
|
94
|
+
if (revivedSnapshot.state === 'Stale') {
|
|
95
|
+
// kick off network request, do not await it
|
|
96
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
97
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
98
|
+
// return the L2 cached snapshot to caller
|
|
99
|
+
return revivedSnapshot;
|
|
100
|
+
}
|
|
101
|
+
// data not found in L2 cache, go to the network
|
|
102
|
+
return buildNetworkSnapshot(args);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return buildNetworkSnapshot(args);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function buildCacheThenNetworkImplementation(funcs) {
|
|
111
|
+
return function (args) {
|
|
112
|
+
funcs.validateNotDisposed();
|
|
113
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
114
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
115
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
116
|
+
if (snapshot !== undefined) {
|
|
117
|
+
// data found in L1 cache
|
|
118
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
119
|
+
return snapshot;
|
|
120
|
+
}
|
|
121
|
+
if (snapshot.state === 'Pending') {
|
|
122
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
123
|
+
}
|
|
59
124
|
// data not found in L1 cache, try L2 cache
|
|
60
125
|
return funcs
|
|
61
126
|
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
@@ -65,19 +130,136 @@ function buildStaleWhileRevalidateImplementation(funcs, staleDuration) {
|
|
|
65
130
|
revivedSnapshot.state === 'Error') {
|
|
66
131
|
return revivedSnapshot;
|
|
67
132
|
}
|
|
68
|
-
if (revivedSnapshot.state === 'Pending')
|
|
133
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
134
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
135
|
+
}
|
|
136
|
+
// data not found in L2 cache, go to the network
|
|
137
|
+
return buildNetworkSnapshot(args);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
141
|
+
return buildNetworkSnapshot(args);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function buildNoCacheImplementation(funcs) {
|
|
146
|
+
return function (args) {
|
|
147
|
+
funcs.validateNotDisposed();
|
|
148
|
+
return buildNetworkSnapshot(args);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function deepFreeze(value) {
|
|
153
|
+
// No need to freeze primitives
|
|
154
|
+
if (typeof value !== 'object' || value === null) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (isArray(value)) {
|
|
158
|
+
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
159
|
+
deepFreeze(value[i]);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const keys$1 = keys(value);
|
|
164
|
+
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
165
|
+
deepFreeze(value[keys$1[i]]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
freeze(value);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// TODO[@W-10165595]: consolidate this code with the corresponding logic in the default environment's only-if-cached.ts
|
|
172
|
+
function buildNotCachedErrorSnapshot() {
|
|
173
|
+
const error = {
|
|
174
|
+
body: undefined,
|
|
175
|
+
headers: {},
|
|
176
|
+
ok: false,
|
|
177
|
+
status: HttpStatusCode.GatewayTimeout,
|
|
178
|
+
statusText: 'Gateway Timeout',
|
|
179
|
+
};
|
|
180
|
+
deepFreeze(error);
|
|
181
|
+
return {
|
|
182
|
+
error,
|
|
183
|
+
state: 'Error',
|
|
184
|
+
data: undefined,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function buildOnlyIfCachedImplementation(funcs) {
|
|
188
|
+
return function (args) {
|
|
189
|
+
funcs.validateNotDisposed();
|
|
190
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
191
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
192
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
193
|
+
if (snapshot !== undefined) {
|
|
194
|
+
// data found in L1 cache
|
|
195
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
196
|
+
return snapshot;
|
|
197
|
+
}
|
|
198
|
+
// network request outstanding, data is not cached
|
|
199
|
+
if (snapshot.state === 'Pending') {
|
|
200
|
+
return buildNotCachedErrorSnapshot();
|
|
201
|
+
}
|
|
202
|
+
// data not found in L1 cache, try L2 cache
|
|
203
|
+
return funcs
|
|
204
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
205
|
+
.then((revivedSnapshot) => {
|
|
206
|
+
// data found in L2 cache
|
|
207
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
208
|
+
revivedSnapshot.state === 'Error') {
|
|
209
|
+
return revivedSnapshot;
|
|
210
|
+
}
|
|
211
|
+
// data is not cached
|
|
212
|
+
return buildNotCachedErrorSnapshot();
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return buildNotCachedErrorSnapshot();
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
|
|
220
|
+
return function (args) {
|
|
221
|
+
funcs.validateNotDisposed();
|
|
222
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
223
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
|
|
224
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
225
|
+
if (snapshot !== undefined) {
|
|
226
|
+
// data found in L1 cache
|
|
227
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
228
|
+
return snapshot;
|
|
229
|
+
}
|
|
230
|
+
if (snapshot.state === 'Pending') {
|
|
231
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
232
|
+
}
|
|
233
|
+
// stale data found in L1 cache
|
|
234
|
+
if (snapshot.state === 'Stale') {
|
|
235
|
+
// TODO [@W-10093408]: offline environment is already doing this; uncomment once we get rid of offline environment
|
|
236
|
+
// buildNetworkSnapshot(args);
|
|
237
|
+
return snapshot;
|
|
238
|
+
}
|
|
239
|
+
// data not found in L1 cache, try L2 cache
|
|
240
|
+
return funcs
|
|
241
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
242
|
+
.then((revivedSnapshot) => {
|
|
243
|
+
// data found in L2 cache
|
|
244
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
245
|
+
revivedSnapshot.state === 'Error') {
|
|
246
|
+
return revivedSnapshot;
|
|
247
|
+
}
|
|
248
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
249
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
250
|
+
}
|
|
69
251
|
// stale data found in L2 cache
|
|
70
252
|
if (revivedSnapshot.state === 'Stale') {
|
|
71
|
-
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
72
|
-
// buildNetworkSnapshot(
|
|
253
|
+
// TODO [@W-10093408]: offline environment is already doing this; uncomment once we get rid of offline environment
|
|
254
|
+
// buildNetworkSnapshot(args);
|
|
73
255
|
return revivedSnapshot;
|
|
74
256
|
}
|
|
75
257
|
// data not found in L2 cache, go to the network
|
|
76
|
-
return buildNetworkSnapshot(
|
|
258
|
+
return buildNetworkSnapshot(args);
|
|
77
259
|
});
|
|
78
260
|
}
|
|
79
261
|
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
80
|
-
return buildNetworkSnapshot(
|
|
262
|
+
return buildNetworkSnapshot(args);
|
|
81
263
|
};
|
|
82
264
|
}
|
|
83
265
|
|
|
@@ -105,25 +287,6 @@ function handleDurableStoreRejection(instrument) {
|
|
|
105
287
|
};
|
|
106
288
|
}
|
|
107
289
|
|
|
108
|
-
function deepFreeze(value) {
|
|
109
|
-
// No need to freeze primitives
|
|
110
|
-
if (typeof value !== 'object' || value === null) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (isArray(value)) {
|
|
114
|
-
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
115
|
-
deepFreeze(value[i]);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
const keys$1 = keys(value);
|
|
120
|
-
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
121
|
-
deepFreeze(value[keys$1[i]]);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
freeze(value);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
290
|
const SELECTOR_PAGINATION_TOKEN = 'tokenDataKey';
|
|
128
291
|
function isFragmentUnionSelection(sel) {
|
|
129
292
|
return sel.union === true;
|
|
@@ -272,7 +435,9 @@ function publishDurableStoreEntries(durableRecords, publish, publishMetadata) {
|
|
|
272
435
|
* will refresh the snapshot from network, and then run the results from network
|
|
273
436
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
274
437
|
*/
|
|
275
|
-
function reviveSnapshot(baseEnvironment, durableStore,
|
|
438
|
+
function reviveSnapshot(baseEnvironment, durableStore,
|
|
439
|
+
// TODO [W-10165787]: We should only allow Unfulfilled snapshot be passed in
|
|
440
|
+
unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot) {
|
|
276
441
|
const { recordId, select, seenRecords, state } = unavailableSnapshot;
|
|
277
442
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
278
443
|
// info needed to revive (like missingLinks) and rebuild. Otherwise return L1 snapshot.
|
|
@@ -764,7 +929,27 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
764
929
|
return buildStaleWhileRevalidateImplementation({
|
|
765
930
|
validateNotDisposed,
|
|
766
931
|
reviveSnapshotWithCachePolicy,
|
|
767
|
-
}, cachePolicy.
|
|
932
|
+
}, cachePolicy.staleDurationSeconds);
|
|
933
|
+
case 'cache-and-network':
|
|
934
|
+
return buildCacheAndNetworkImplementation({
|
|
935
|
+
validateNotDisposed,
|
|
936
|
+
reviveSnapshotWithCachePolicy,
|
|
937
|
+
}, cachePolicy.staleDurationSeconds);
|
|
938
|
+
case 'cache-then-network':
|
|
939
|
+
return buildCacheThenNetworkImplementation({
|
|
940
|
+
validateNotDisposed,
|
|
941
|
+
reviveSnapshotWithCachePolicy,
|
|
942
|
+
});
|
|
943
|
+
case 'no-cache':
|
|
944
|
+
return buildNoCacheImplementation({
|
|
945
|
+
validateNotDisposed,
|
|
946
|
+
reviveSnapshotWithCachePolicy,
|
|
947
|
+
});
|
|
948
|
+
case 'only-if-cached':
|
|
949
|
+
return buildOnlyIfCachedImplementation({
|
|
950
|
+
validateNotDisposed,
|
|
951
|
+
reviveSnapshotWithCachePolicy,
|
|
952
|
+
});
|
|
768
953
|
default: {
|
|
769
954
|
if (process.env.NODE_ENV !== 'production') {
|
|
770
955
|
throw new Error(`unrecognized cache policy: ${JSON.stringify(cachePolicy)}`);
|
|
@@ -776,12 +961,14 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
776
961
|
const applyCachePolicy = function (cachePolicy, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
|
|
777
962
|
validateNotDisposed();
|
|
778
963
|
const cachePolicyImpl = resolveCachePolicy(cachePolicy);
|
|
964
|
+
const resolvePendingSnapshot = (snapshot) => environment.resolvePendingSnapshot(snapshot);
|
|
779
965
|
const storeLookup = (sel, refresh, ttlStrategy) => environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy);
|
|
780
966
|
const applyCachePolicy = () => {
|
|
781
967
|
return cachePolicyImpl({
|
|
782
968
|
buildInMemorySnapshot,
|
|
783
969
|
buildNetworkSnapshot,
|
|
784
970
|
buildSnapshotContext,
|
|
971
|
+
resolvePendingSnapshot,
|
|
785
972
|
storeLookup,
|
|
786
973
|
dispatchResourceRequest: environment.dispatchResourceRequest,
|
|
787
974
|
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildCacheAndNetworkImplementation(funcs: DurableCachePolicyFunctions, staleDurationSeconds?: number): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildCacheThenNetworkImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
+
export { buildCacheAndNetworkImplementation } from './cache-and-network';
|
|
2
|
+
export { buildCacheThenNetworkImplementation } from './cache-then-network';
|
|
3
|
+
export { buildNoCacheImplementation } from './no-cache';
|
|
4
|
+
export { buildOnlyIfCachedImplementation } from './only-if-cached';
|
|
1
5
|
export { buildStaleWhileRevalidateImplementation } from './stale-while-revalidate';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildNoCacheImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, ErrorSnapshot, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildOnlyIfCachedImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
2
|
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
-
export declare function buildStaleWhileRevalidateImplementation(funcs: DurableCachePolicyFunctions,
|
|
3
|
+
export declare function buildStaleWhileRevalidateImplementation(funcs: DurableCachePolicyFunctions, staleDurationSeconds: number): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -3,5 +3,6 @@ export declare type DurableCachePolicyFunctions = {
|
|
|
3
3
|
validateNotDisposed: () => void;
|
|
4
4
|
reviveSnapshotWithCachePolicy: <D, V>(unavailableSnapshot: UnAvailableSnapshot<D, V>, storeLookup: StoreLookup<D, V>) => Promise<Snapshot<D, V>>;
|
|
5
5
|
};
|
|
6
|
-
export declare function buildTTLStrategy(staleDuration?: number): TTLStrategy;
|
|
7
6
|
export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
|
|
7
|
+
export declare function buildNetworkSnapshot<C, D>(args: CachePolicyImplementationArgs<C, D>): Promise<Snapshot<D, unknown>>;
|
|
8
|
+
export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementation, CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildValidAtImplementation<C, D>(funcs: DurableCachePolicyFunctions, basePolicyImplementation: CachePolicyImplementation<C, D>, timestamp: number): (args: CachePolicyImplementationArgs<C, D>) => Snapshot<D> | Promise<Snapshot<D>>;
|
|
@@ -20,12 +20,20 @@
|
|
|
20
20
|
const { keys, create, assign, freeze } = Object;
|
|
21
21
|
const { isArray } = Array;
|
|
22
22
|
|
|
23
|
-
function
|
|
23
|
+
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
24
|
+
return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
|
|
25
|
+
}
|
|
26
|
+
function buildNetworkSnapshot(args) {
|
|
27
|
+
const { buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest } = args;
|
|
28
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest).then((snapshot) => snapshot.state === 'Pending' ? args.resolvePendingSnapshot(snapshot) : snapshot);
|
|
29
|
+
}
|
|
30
|
+
function buildTTLStrategy(staleDurationMilliseconds = 0) {
|
|
24
31
|
return (timestamp, metadata, valueIsError) => {
|
|
25
32
|
if (metadata !== undefined) {
|
|
26
33
|
const { expirationTimestamp } = metadata;
|
|
27
34
|
if (timestamp > expirationTimestamp) {
|
|
28
|
-
if (timestamp <= expirationTimestamp +
|
|
35
|
+
if (timestamp <= expirationTimestamp + staleDurationMilliseconds &&
|
|
36
|
+
valueIsError !== true) {
|
|
29
37
|
return engine.StoreResolveResultState.Stale;
|
|
30
38
|
}
|
|
31
39
|
return engine.StoreResolveResultState.NotPresent;
|
|
@@ -36,29 +44,86 @@
|
|
|
36
44
|
}
|
|
37
45
|
return engine.StoreResolveResultState.Found;
|
|
38
46
|
};
|
|
39
|
-
}
|
|
40
|
-
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
41
|
-
return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
function
|
|
49
|
+
function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
|
|
45
50
|
return function (args) {
|
|
46
51
|
funcs.validateNotDisposed();
|
|
47
|
-
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
48
|
-
const
|
|
52
|
+
const { buildInMemorySnapshot, buildNetworkSnapshot: buildNetworkSnapshot$1, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
53
|
+
const staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
|
|
54
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
|
|
49
55
|
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
50
56
|
if (snapshot !== undefined) {
|
|
51
57
|
// data found in L1 cache
|
|
52
58
|
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
59
|
+
// kick off network request, do not await it
|
|
60
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
61
|
+
// return the cached snapshot to caller
|
|
53
62
|
return snapshot;
|
|
54
63
|
}
|
|
55
|
-
|
|
64
|
+
// network request outstanding
|
|
65
|
+
if (snapshot.state === 'Pending') {
|
|
66
|
+
// kick off another network request, do not await it
|
|
67
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
68
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
69
|
+
}
|
|
56
70
|
// stale data found in L1 cache
|
|
57
71
|
if (snapshot.state === 'Stale') {
|
|
72
|
+
// kick off network request, do not await it
|
|
58
73
|
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
59
74
|
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
75
|
+
// return the cached snapshot to caller
|
|
60
76
|
return snapshot;
|
|
61
77
|
}
|
|
78
|
+
// if unfulfilled we have enough info to do an L2 lookup
|
|
79
|
+
if (snapshot.state === 'Unfulfilled') {
|
|
80
|
+
return funcs
|
|
81
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
82
|
+
.then((revivedSnapshot) => {
|
|
83
|
+
// data found in L2 cache
|
|
84
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
85
|
+
revivedSnapshot.state === 'Error') {
|
|
86
|
+
// kick off network request, do not await it
|
|
87
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
88
|
+
// return the L2 cached snapshot to caller
|
|
89
|
+
return revivedSnapshot;
|
|
90
|
+
}
|
|
91
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
92
|
+
// kick off network request, do not await it
|
|
93
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
94
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
95
|
+
}
|
|
96
|
+
// stale data found in L2 cache
|
|
97
|
+
if (revivedSnapshot.state === 'Stale') {
|
|
98
|
+
// kick off network request, do not await it
|
|
99
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
100
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
101
|
+
// return the L2 cached snapshot to caller
|
|
102
|
+
return revivedSnapshot;
|
|
103
|
+
}
|
|
104
|
+
// data not found in L2 cache, go to the network
|
|
105
|
+
return buildNetworkSnapshot(args);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return buildNetworkSnapshot(args);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function buildCacheThenNetworkImplementation(funcs) {
|
|
114
|
+
return function (args) {
|
|
115
|
+
funcs.validateNotDisposed();
|
|
116
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
117
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
118
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
119
|
+
if (snapshot !== undefined) {
|
|
120
|
+
// data found in L1 cache
|
|
121
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
122
|
+
return snapshot;
|
|
123
|
+
}
|
|
124
|
+
if (snapshot.state === 'Pending') {
|
|
125
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
126
|
+
}
|
|
62
127
|
// data not found in L1 cache, try L2 cache
|
|
63
128
|
return funcs
|
|
64
129
|
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
@@ -68,19 +133,136 @@
|
|
|
68
133
|
revivedSnapshot.state === 'Error') {
|
|
69
134
|
return revivedSnapshot;
|
|
70
135
|
}
|
|
71
|
-
if (revivedSnapshot.state === 'Pending')
|
|
136
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
137
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
138
|
+
}
|
|
139
|
+
// data not found in L2 cache, go to the network
|
|
140
|
+
return buildNetworkSnapshot(args);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
144
|
+
return buildNetworkSnapshot(args);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function buildNoCacheImplementation(funcs) {
|
|
149
|
+
return function (args) {
|
|
150
|
+
funcs.validateNotDisposed();
|
|
151
|
+
return buildNetworkSnapshot(args);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function deepFreeze(value) {
|
|
156
|
+
// No need to freeze primitives
|
|
157
|
+
if (typeof value !== 'object' || value === null) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (isArray(value)) {
|
|
161
|
+
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
162
|
+
deepFreeze(value[i]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const keys$1 = keys(value);
|
|
167
|
+
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
168
|
+
deepFreeze(value[keys$1[i]]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
freeze(value);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// TODO[@W-10165595]: consolidate this code with the corresponding logic in the default environment's only-if-cached.ts
|
|
175
|
+
function buildNotCachedErrorSnapshot() {
|
|
176
|
+
const error = {
|
|
177
|
+
body: undefined,
|
|
178
|
+
headers: {},
|
|
179
|
+
ok: false,
|
|
180
|
+
status: engine.HttpStatusCode.GatewayTimeout,
|
|
181
|
+
statusText: 'Gateway Timeout',
|
|
182
|
+
};
|
|
183
|
+
deepFreeze(error);
|
|
184
|
+
return {
|
|
185
|
+
error,
|
|
186
|
+
state: 'Error',
|
|
187
|
+
data: undefined,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function buildOnlyIfCachedImplementation(funcs) {
|
|
191
|
+
return function (args) {
|
|
192
|
+
funcs.validateNotDisposed();
|
|
193
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
194
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
195
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
196
|
+
if (snapshot !== undefined) {
|
|
197
|
+
// data found in L1 cache
|
|
198
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
199
|
+
return snapshot;
|
|
200
|
+
}
|
|
201
|
+
// network request outstanding, data is not cached
|
|
202
|
+
if (snapshot.state === 'Pending') {
|
|
203
|
+
return buildNotCachedErrorSnapshot();
|
|
204
|
+
}
|
|
205
|
+
// data not found in L1 cache, try L2 cache
|
|
206
|
+
return funcs
|
|
207
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
208
|
+
.then((revivedSnapshot) => {
|
|
209
|
+
// data found in L2 cache
|
|
210
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
211
|
+
revivedSnapshot.state === 'Error') {
|
|
212
|
+
return revivedSnapshot;
|
|
213
|
+
}
|
|
214
|
+
// data is not cached
|
|
215
|
+
return buildNotCachedErrorSnapshot();
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return buildNotCachedErrorSnapshot();
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
|
|
223
|
+
return function (args) {
|
|
224
|
+
funcs.validateNotDisposed();
|
|
225
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
226
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
|
|
227
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
228
|
+
if (snapshot !== undefined) {
|
|
229
|
+
// data found in L1 cache
|
|
230
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
231
|
+
return snapshot;
|
|
232
|
+
}
|
|
233
|
+
if (snapshot.state === 'Pending') {
|
|
234
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
235
|
+
}
|
|
236
|
+
// stale data found in L1 cache
|
|
237
|
+
if (snapshot.state === 'Stale') {
|
|
238
|
+
// TODO [@W-10093408]: offline environment is already doing this; uncomment once we get rid of offline environment
|
|
239
|
+
// buildNetworkSnapshot(args);
|
|
240
|
+
return snapshot;
|
|
241
|
+
}
|
|
242
|
+
// data not found in L1 cache, try L2 cache
|
|
243
|
+
return funcs
|
|
244
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
245
|
+
.then((revivedSnapshot) => {
|
|
246
|
+
// data found in L2 cache
|
|
247
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
248
|
+
revivedSnapshot.state === 'Error') {
|
|
249
|
+
return revivedSnapshot;
|
|
250
|
+
}
|
|
251
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
252
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
253
|
+
}
|
|
72
254
|
// stale data found in L2 cache
|
|
73
255
|
if (revivedSnapshot.state === 'Stale') {
|
|
74
|
-
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
75
|
-
// buildNetworkSnapshot(
|
|
256
|
+
// TODO [@W-10093408]: offline environment is already doing this; uncomment once we get rid of offline environment
|
|
257
|
+
// buildNetworkSnapshot(args);
|
|
76
258
|
return revivedSnapshot;
|
|
77
259
|
}
|
|
78
260
|
// data not found in L2 cache, go to the network
|
|
79
|
-
return buildNetworkSnapshot(
|
|
261
|
+
return buildNetworkSnapshot(args);
|
|
80
262
|
});
|
|
81
263
|
}
|
|
82
264
|
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
83
|
-
return buildNetworkSnapshot(
|
|
265
|
+
return buildNetworkSnapshot(args);
|
|
84
266
|
};
|
|
85
267
|
}
|
|
86
268
|
|
|
@@ -108,25 +290,6 @@
|
|
|
108
290
|
};
|
|
109
291
|
}
|
|
110
292
|
|
|
111
|
-
function deepFreeze(value) {
|
|
112
|
-
// No need to freeze primitives
|
|
113
|
-
if (typeof value !== 'object' || value === null) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (isArray(value)) {
|
|
117
|
-
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
118
|
-
deepFreeze(value[i]);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
const keys$1 = keys(value);
|
|
123
|
-
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
124
|
-
deepFreeze(value[keys$1[i]]);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
freeze(value);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
293
|
const SELECTOR_PAGINATION_TOKEN = 'tokenDataKey';
|
|
131
294
|
function isFragmentUnionSelection(sel) {
|
|
132
295
|
return sel.union === true;
|
|
@@ -275,7 +438,9 @@
|
|
|
275
438
|
* will refresh the snapshot from network, and then run the results from network
|
|
276
439
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
277
440
|
*/
|
|
278
|
-
function reviveSnapshot(baseEnvironment, durableStore,
|
|
441
|
+
function reviveSnapshot(baseEnvironment, durableStore,
|
|
442
|
+
// TODO [W-10165787]: We should only allow Unfulfilled snapshot be passed in
|
|
443
|
+
unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot) {
|
|
279
444
|
const { recordId, select, seenRecords, state } = unavailableSnapshot;
|
|
280
445
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
281
446
|
// info needed to revive (like missingLinks) and rebuild. Otherwise return L1 snapshot.
|
|
@@ -767,7 +932,27 @@
|
|
|
767
932
|
return buildStaleWhileRevalidateImplementation({
|
|
768
933
|
validateNotDisposed,
|
|
769
934
|
reviveSnapshotWithCachePolicy,
|
|
770
|
-
}, cachePolicy.
|
|
935
|
+
}, cachePolicy.staleDurationSeconds);
|
|
936
|
+
case 'cache-and-network':
|
|
937
|
+
return buildCacheAndNetworkImplementation({
|
|
938
|
+
validateNotDisposed,
|
|
939
|
+
reviveSnapshotWithCachePolicy,
|
|
940
|
+
}, cachePolicy.staleDurationSeconds);
|
|
941
|
+
case 'cache-then-network':
|
|
942
|
+
return buildCacheThenNetworkImplementation({
|
|
943
|
+
validateNotDisposed,
|
|
944
|
+
reviveSnapshotWithCachePolicy,
|
|
945
|
+
});
|
|
946
|
+
case 'no-cache':
|
|
947
|
+
return buildNoCacheImplementation({
|
|
948
|
+
validateNotDisposed,
|
|
949
|
+
reviveSnapshotWithCachePolicy,
|
|
950
|
+
});
|
|
951
|
+
case 'only-if-cached':
|
|
952
|
+
return buildOnlyIfCachedImplementation({
|
|
953
|
+
validateNotDisposed,
|
|
954
|
+
reviveSnapshotWithCachePolicy,
|
|
955
|
+
});
|
|
771
956
|
default: {
|
|
772
957
|
if (process.env.NODE_ENV !== 'production') {
|
|
773
958
|
throw new Error(`unrecognized cache policy: ${JSON.stringify(cachePolicy)}`);
|
|
@@ -779,12 +964,14 @@
|
|
|
779
964
|
const applyCachePolicy = function (cachePolicy, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
|
|
780
965
|
validateNotDisposed();
|
|
781
966
|
const cachePolicyImpl = resolveCachePolicy(cachePolicy);
|
|
967
|
+
const resolvePendingSnapshot = (snapshot) => environment.resolvePendingSnapshot(snapshot);
|
|
782
968
|
const storeLookup = (sel, refresh, ttlStrategy) => environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy);
|
|
783
969
|
const applyCachePolicy = () => {
|
|
784
970
|
return cachePolicyImpl({
|
|
785
971
|
buildInMemorySnapshot,
|
|
786
972
|
buildNetworkSnapshot,
|
|
787
973
|
buildSnapshotContext,
|
|
974
|
+
resolvePendingSnapshot,
|
|
788
975
|
storeLookup,
|
|
789
976
|
dispatchResourceRequest: environment.dispatchResourceRequest,
|
|
790
977
|
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildCacheAndNetworkImplementation(funcs: DurableCachePolicyFunctions, staleDurationSeconds?: number): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildCacheThenNetworkImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
+
export { buildCacheAndNetworkImplementation } from './cache-and-network';
|
|
2
|
+
export { buildCacheThenNetworkImplementation } from './cache-then-network';
|
|
3
|
+
export { buildNoCacheImplementation } from './no-cache';
|
|
4
|
+
export { buildOnlyIfCachedImplementation } from './only-if-cached';
|
|
1
5
|
export { buildStaleWhileRevalidateImplementation } from './stale-while-revalidate';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildNoCacheImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, ErrorSnapshot, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildOnlyIfCachedImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
2
|
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
-
export declare function buildStaleWhileRevalidateImplementation(funcs: DurableCachePolicyFunctions,
|
|
3
|
+
export declare function buildStaleWhileRevalidateImplementation(funcs: DurableCachePolicyFunctions, staleDurationSeconds: number): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -3,5 +3,6 @@ export declare type DurableCachePolicyFunctions = {
|
|
|
3
3
|
validateNotDisposed: () => void;
|
|
4
4
|
reviveSnapshotWithCachePolicy: <D, V>(unavailableSnapshot: UnAvailableSnapshot<D, V>, storeLookup: StoreLookup<D, V>) => Promise<Snapshot<D, V>>;
|
|
5
5
|
};
|
|
6
|
-
export declare function buildTTLStrategy(staleDuration?: number): TTLStrategy;
|
|
7
6
|
export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
|
|
7
|
+
export declare function buildNetworkSnapshot<C, D>(args: CachePolicyImplementationArgs<C, D>): Promise<Snapshot<D, unknown>>;
|
|
8
|
+
export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementation, CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildValidAtImplementation<C, D>(funcs: DurableCachePolicyFunctions, basePolicyImplementation: CachePolicyImplementation<C, D>, timestamp: number): (args: CachePolicyImplementationArgs<C, D>) => Snapshot<D> | Promise<Snapshot<D>>;
|
|
@@ -54,13 +54,25 @@
|
|
|
54
54
|
var keys = Object.keys, create = Object.create, assign = Object.assign, freeze = Object.freeze;
|
|
55
55
|
var isArray = Array.isArray;
|
|
56
56
|
|
|
57
|
-
function
|
|
58
|
-
|
|
57
|
+
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
58
|
+
return function (sel, refresh) {
|
|
59
|
+
return storeLookup(sel, refresh, ttlStrategy);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function buildNetworkSnapshot(args) {
|
|
63
|
+
var buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest;
|
|
64
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest).then(function (snapshot) {
|
|
65
|
+
return snapshot.state === 'Pending' ? args.resolvePendingSnapshot(snapshot) : snapshot;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function buildTTLStrategy(staleDurationMilliseconds) {
|
|
69
|
+
if (staleDurationMilliseconds === void 0) { staleDurationMilliseconds = 0; }
|
|
59
70
|
return function (timestamp, metadata, valueIsError) {
|
|
60
71
|
if (metadata !== undefined) {
|
|
61
72
|
var expirationTimestamp = metadata.expirationTimestamp;
|
|
62
73
|
if (timestamp > expirationTimestamp) {
|
|
63
|
-
if (timestamp <= expirationTimestamp +
|
|
74
|
+
if (timestamp <= expirationTimestamp + staleDurationMilliseconds &&
|
|
75
|
+
valueIsError !== true) {
|
|
64
76
|
return engine.StoreResolveResultState.Stale;
|
|
65
77
|
}
|
|
66
78
|
return engine.StoreResolveResultState.NotPresent;
|
|
@@ -71,29 +83,199 @@
|
|
|
71
83
|
}
|
|
72
84
|
return engine.StoreResolveResultState.Found;
|
|
73
85
|
};
|
|
74
|
-
}
|
|
75
|
-
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
76
|
-
return function (sel, refresh) {
|
|
77
|
-
return storeLookup(sel, refresh, ttlStrategy);
|
|
78
|
-
};
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
function
|
|
88
|
+
function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
|
|
82
89
|
return function (args) {
|
|
83
90
|
funcs.validateNotDisposed();
|
|
84
|
-
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest, storeLookup = args.storeLookup;
|
|
85
|
-
var
|
|
91
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot$1 = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest, storeLookup = args.storeLookup;
|
|
92
|
+
var staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
|
|
93
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
|
|
86
94
|
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
87
95
|
if (snapshot !== undefined) {
|
|
88
96
|
// data found in L1 cache
|
|
89
97
|
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
98
|
+
// kick off network request, do not await it
|
|
99
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
100
|
+
// return the cached snapshot to caller
|
|
90
101
|
return snapshot;
|
|
91
102
|
}
|
|
92
|
-
|
|
103
|
+
// network request outstanding
|
|
104
|
+
if (snapshot.state === 'Pending') {
|
|
105
|
+
// kick off another network request, do not await it
|
|
106
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
107
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
108
|
+
}
|
|
93
109
|
// stale data found in L1 cache
|
|
94
110
|
if (snapshot.state === 'Stale') {
|
|
111
|
+
// kick off network request, do not await it
|
|
95
112
|
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
96
113
|
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
114
|
+
// return the cached snapshot to caller
|
|
115
|
+
return snapshot;
|
|
116
|
+
}
|
|
117
|
+
// if unfulfilled we have enough info to do an L2 lookup
|
|
118
|
+
if (snapshot.state === 'Unfulfilled') {
|
|
119
|
+
return funcs
|
|
120
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
121
|
+
.then(function (revivedSnapshot) {
|
|
122
|
+
// data found in L2 cache
|
|
123
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
124
|
+
revivedSnapshot.state === 'Error') {
|
|
125
|
+
// kick off network request, do not await it
|
|
126
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
127
|
+
// return the L2 cached snapshot to caller
|
|
128
|
+
return revivedSnapshot;
|
|
129
|
+
}
|
|
130
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
131
|
+
// kick off network request, do not await it
|
|
132
|
+
buildNetworkSnapshot$1(buildSnapshotContext, dispatchResourceRequest);
|
|
133
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
134
|
+
}
|
|
135
|
+
// stale data found in L2 cache
|
|
136
|
+
if (revivedSnapshot.state === 'Stale') {
|
|
137
|
+
// kick off network request, do not await it
|
|
138
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
139
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
140
|
+
// return the L2 cached snapshot to caller
|
|
141
|
+
return revivedSnapshot;
|
|
142
|
+
}
|
|
143
|
+
// data not found in L2 cache, go to the network
|
|
144
|
+
return buildNetworkSnapshot(args);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return buildNetworkSnapshot(args);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function buildCacheThenNetworkImplementation(funcs) {
|
|
153
|
+
return function (args) {
|
|
154
|
+
funcs.validateNotDisposed();
|
|
155
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
|
|
156
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
157
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
158
|
+
if (snapshot !== undefined) {
|
|
159
|
+
// data found in L1 cache
|
|
160
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
161
|
+
return snapshot;
|
|
162
|
+
}
|
|
163
|
+
if (snapshot.state === 'Pending') {
|
|
164
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
165
|
+
}
|
|
166
|
+
// data not found in L1 cache, try L2 cache
|
|
167
|
+
return funcs
|
|
168
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
169
|
+
.then(function (revivedSnapshot) {
|
|
170
|
+
// data found in L2 cache
|
|
171
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
172
|
+
revivedSnapshot.state === 'Error') {
|
|
173
|
+
return revivedSnapshot;
|
|
174
|
+
}
|
|
175
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
176
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
177
|
+
}
|
|
178
|
+
// data not found in L2 cache, go to the network
|
|
179
|
+
return buildNetworkSnapshot(args);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
183
|
+
return buildNetworkSnapshot(args);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function buildNoCacheImplementation(funcs) {
|
|
188
|
+
return function (args) {
|
|
189
|
+
funcs.validateNotDisposed();
|
|
190
|
+
return buildNetworkSnapshot(args);
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function deepFreeze(value) {
|
|
195
|
+
// No need to freeze primitives
|
|
196
|
+
if (typeof value !== 'object' || value === null) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (isArray(value)) {
|
|
200
|
+
for (var i = 0, len = value.length; i < len; i += 1) {
|
|
201
|
+
deepFreeze(value[i]);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
var keys$1 = keys(value);
|
|
206
|
+
for (var i = 0, len = keys$1.length; i < len; i += 1) {
|
|
207
|
+
deepFreeze(value[keys$1[i]]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
freeze(value);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// TODO[@W-10165595]: consolidate this code with the corresponding logic in the default environment's only-if-cached.ts
|
|
214
|
+
function buildNotCachedErrorSnapshot() {
|
|
215
|
+
var error = {
|
|
216
|
+
body: undefined,
|
|
217
|
+
headers: {},
|
|
218
|
+
ok: false,
|
|
219
|
+
status: engine.HttpStatusCode.GatewayTimeout,
|
|
220
|
+
statusText: 'Gateway Timeout',
|
|
221
|
+
};
|
|
222
|
+
deepFreeze(error);
|
|
223
|
+
return {
|
|
224
|
+
error: error,
|
|
225
|
+
state: 'Error',
|
|
226
|
+
data: undefined,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function buildOnlyIfCachedImplementation(funcs) {
|
|
230
|
+
return function (args) {
|
|
231
|
+
funcs.validateNotDisposed();
|
|
232
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
|
|
233
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
234
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
235
|
+
if (snapshot !== undefined) {
|
|
236
|
+
// data found in L1 cache
|
|
237
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
238
|
+
return snapshot;
|
|
239
|
+
}
|
|
240
|
+
// network request outstanding, data is not cached
|
|
241
|
+
if (snapshot.state === 'Pending') {
|
|
242
|
+
return buildNotCachedErrorSnapshot();
|
|
243
|
+
}
|
|
244
|
+
// data not found in L1 cache, try L2 cache
|
|
245
|
+
return funcs
|
|
246
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
247
|
+
.then(function (revivedSnapshot) {
|
|
248
|
+
// data found in L2 cache
|
|
249
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
250
|
+
revivedSnapshot.state === 'Error') {
|
|
251
|
+
return revivedSnapshot;
|
|
252
|
+
}
|
|
253
|
+
// data is not cached
|
|
254
|
+
return buildNotCachedErrorSnapshot();
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return buildNotCachedErrorSnapshot();
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
|
|
262
|
+
return function (args) {
|
|
263
|
+
funcs.validateNotDisposed();
|
|
264
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
|
|
265
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
|
|
266
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
267
|
+
if (snapshot !== undefined) {
|
|
268
|
+
// data found in L1 cache
|
|
269
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
270
|
+
return snapshot;
|
|
271
|
+
}
|
|
272
|
+
if (snapshot.state === 'Pending') {
|
|
273
|
+
return args.resolvePendingSnapshot(snapshot);
|
|
274
|
+
}
|
|
275
|
+
// stale data found in L1 cache
|
|
276
|
+
if (snapshot.state === 'Stale') {
|
|
277
|
+
// TODO [@W-10093408]: offline environment is already doing this; uncomment once we get rid of offline environment
|
|
278
|
+
// buildNetworkSnapshot(args);
|
|
97
279
|
return snapshot;
|
|
98
280
|
}
|
|
99
281
|
// data not found in L1 cache, try L2 cache
|
|
@@ -105,19 +287,21 @@
|
|
|
105
287
|
revivedSnapshot.state === 'Error') {
|
|
106
288
|
return revivedSnapshot;
|
|
107
289
|
}
|
|
108
|
-
if (revivedSnapshot.state === 'Pending')
|
|
290
|
+
if (revivedSnapshot.state === 'Pending') {
|
|
291
|
+
return args.resolvePendingSnapshot(revivedSnapshot);
|
|
292
|
+
}
|
|
109
293
|
// stale data found in L2 cache
|
|
110
294
|
if (revivedSnapshot.state === 'Stale') {
|
|
111
|
-
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
112
|
-
// buildNetworkSnapshot(
|
|
295
|
+
// TODO [@W-10093408]: offline environment is already doing this; uncomment once we get rid of offline environment
|
|
296
|
+
// buildNetworkSnapshot(args);
|
|
113
297
|
return revivedSnapshot;
|
|
114
298
|
}
|
|
115
299
|
// data not found in L2 cache, go to the network
|
|
116
|
-
return buildNetworkSnapshot(
|
|
300
|
+
return buildNetworkSnapshot(args);
|
|
117
301
|
});
|
|
118
302
|
}
|
|
119
303
|
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
120
|
-
return buildNetworkSnapshot(
|
|
304
|
+
return buildNetworkSnapshot(args);
|
|
121
305
|
};
|
|
122
306
|
}
|
|
123
307
|
|
|
@@ -146,25 +330,6 @@
|
|
|
146
330
|
};
|
|
147
331
|
}
|
|
148
332
|
|
|
149
|
-
function deepFreeze(value) {
|
|
150
|
-
// No need to freeze primitives
|
|
151
|
-
if (typeof value !== 'object' || value === null) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
if (isArray(value)) {
|
|
155
|
-
for (var i = 0, len = value.length; i < len; i += 1) {
|
|
156
|
-
deepFreeze(value[i]);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
var keys$1 = keys(value);
|
|
161
|
-
for (var i = 0, len = keys$1.length; i < len; i += 1) {
|
|
162
|
-
deepFreeze(value[keys$1[i]]);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
freeze(value);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
333
|
var SELECTOR_PAGINATION_TOKEN = 'tokenDataKey';
|
|
169
334
|
function isFragmentUnionSelection(sel) {
|
|
170
335
|
return sel.union === true;
|
|
@@ -307,7 +472,9 @@
|
|
|
307
472
|
* will refresh the snapshot from network, and then run the results from network
|
|
308
473
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
309
474
|
*/
|
|
310
|
-
function reviveSnapshot(baseEnvironment, durableStore,
|
|
475
|
+
function reviveSnapshot(baseEnvironment, durableStore,
|
|
476
|
+
// TODO [W-10165787]: We should only allow Unfulfilled snapshot be passed in
|
|
477
|
+
unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot) {
|
|
311
478
|
var _a;
|
|
312
479
|
var recordId = unavailableSnapshot.recordId, select = unavailableSnapshot.select, seenRecords = unavailableSnapshot.seenRecords, state = unavailableSnapshot.state;
|
|
313
480
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
@@ -809,7 +976,27 @@
|
|
|
809
976
|
return buildStaleWhileRevalidateImplementation({
|
|
810
977
|
validateNotDisposed: validateNotDisposed,
|
|
811
978
|
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
812
|
-
}, cachePolicy.
|
|
979
|
+
}, cachePolicy.staleDurationSeconds);
|
|
980
|
+
case 'cache-and-network':
|
|
981
|
+
return buildCacheAndNetworkImplementation({
|
|
982
|
+
validateNotDisposed: validateNotDisposed,
|
|
983
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
984
|
+
}, cachePolicy.staleDurationSeconds);
|
|
985
|
+
case 'cache-then-network':
|
|
986
|
+
return buildCacheThenNetworkImplementation({
|
|
987
|
+
validateNotDisposed: validateNotDisposed,
|
|
988
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
989
|
+
});
|
|
990
|
+
case 'no-cache':
|
|
991
|
+
return buildNoCacheImplementation({
|
|
992
|
+
validateNotDisposed: validateNotDisposed,
|
|
993
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
994
|
+
});
|
|
995
|
+
case 'only-if-cached':
|
|
996
|
+
return buildOnlyIfCachedImplementation({
|
|
997
|
+
validateNotDisposed: validateNotDisposed,
|
|
998
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
999
|
+
});
|
|
813
1000
|
default: {
|
|
814
1001
|
if (process.env.NODE_ENV !== 'production') {
|
|
815
1002
|
throw new Error("unrecognized cache policy: " + JSON.stringify(cachePolicy));
|
|
@@ -821,12 +1008,16 @@
|
|
|
821
1008
|
var applyCachePolicy = function (cachePolicy, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
|
|
822
1009
|
validateNotDisposed();
|
|
823
1010
|
var cachePolicyImpl = resolveCachePolicy(cachePolicy);
|
|
1011
|
+
var resolvePendingSnapshot = function (snapshot) {
|
|
1012
|
+
return environment.resolvePendingSnapshot(snapshot);
|
|
1013
|
+
};
|
|
824
1014
|
var storeLookup = function (sel, refresh, ttlStrategy) { return environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy); };
|
|
825
1015
|
var applyCachePolicy = function () {
|
|
826
1016
|
return cachePolicyImpl({
|
|
827
1017
|
buildInMemorySnapshot: buildInMemorySnapshot,
|
|
828
1018
|
buildNetworkSnapshot: buildNetworkSnapshot,
|
|
829
1019
|
buildSnapshotContext: buildSnapshotContext,
|
|
1020
|
+
resolvePendingSnapshot: resolvePendingSnapshot,
|
|
830
1021
|
storeLookup: storeLookup,
|
|
831
1022
|
dispatchResourceRequest: environment.dispatchResourceRequest,
|
|
832
1023
|
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildCacheAndNetworkImplementation(funcs: DurableCachePolicyFunctions, staleDurationSeconds?: number): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildCacheThenNetworkImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
+
export { buildCacheAndNetworkImplementation } from './cache-and-network';
|
|
2
|
+
export { buildCacheThenNetworkImplementation } from './cache-then-network';
|
|
3
|
+
export { buildNoCacheImplementation } from './no-cache';
|
|
4
|
+
export { buildOnlyIfCachedImplementation } from './only-if-cached';
|
|
1
5
|
export { buildStaleWhileRevalidateImplementation } from './stale-while-revalidate';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildNoCacheImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, ErrorSnapshot, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildOnlyIfCachedImplementation(funcs: DurableCachePolicyFunctions): <C, D>(args: CachePolicyImplementationArgs<C, D>) => ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
2
|
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
-
export declare function buildStaleWhileRevalidateImplementation(funcs: DurableCachePolicyFunctions,
|
|
3
|
+
export declare function buildStaleWhileRevalidateImplementation(funcs: DurableCachePolicyFunctions, staleDurationSeconds: number): <C, D>(args: CachePolicyImplementationArgs<C, D>) => import("@luvio/engine").ErrorSnapshot | import("@luvio/engine").FulfilledSnapshot<D, unknown> | import("@luvio/engine").UnfulfilledSnapshot<D, unknown> | import("@luvio/engine").StaleSnapshot<D, unknown> | import("@luvio/engine").PendingSnapshot<D, unknown> | Promise<Snapshot<D, unknown>>;
|
|
@@ -3,5 +3,6 @@ export declare type DurableCachePolicyFunctions = {
|
|
|
3
3
|
validateNotDisposed: () => void;
|
|
4
4
|
reviveSnapshotWithCachePolicy: <D, V>(unavailableSnapshot: UnAvailableSnapshot<D, V>, storeLookup: StoreLookup<D, V>) => Promise<Snapshot<D, V>>;
|
|
5
5
|
};
|
|
6
|
-
export declare function buildTTLStrategy(staleDuration?: number): TTLStrategy;
|
|
7
6
|
export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
|
|
7
|
+
export declare function buildNetworkSnapshot<C, D>(args: CachePolicyImplementationArgs<C, D>): Promise<Snapshot<D, unknown>>;
|
|
8
|
+
export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CachePolicyImplementation, CachePolicyImplementationArgs, Snapshot } from '@luvio/engine';
|
|
2
|
+
import { DurableCachePolicyFunctions } from './utils';
|
|
3
|
+
export declare function buildValidAtImplementation<C, D>(funcs: DurableCachePolicyFunctions, basePolicyImplementation: CachePolicyImplementation<C, D>, timestamp: number): (args: CachePolicyImplementationArgs<C, D>) => Snapshot<D> | Promise<Snapshot<D>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luvio/environments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0-236.1",
|
|
4
4
|
"description": "Luvio Environments",
|
|
5
5
|
"main": "dist/umd/es2018/environments.js",
|
|
6
6
|
"module": "dist/es/es2018/environments.js",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"dist/"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@luvio/engine": "0.
|
|
20
|
-
}
|
|
19
|
+
"@luvio/engine": "0.61.0-236.1"
|
|
20
|
+
},
|
|
21
|
+
"gitHead": "21ff2ffbe18cd546d4a1f2c0bc35fcd6526a6b75"
|
|
21
22
|
}
|