@luvio/environments 0.58.1 → 0.61.0-236.0
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/ReaderWithPrivateProperties.d.ts +4 -0
- package/dist/es/es2018/environments.js +194 -26
- 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 +1 -1
- package/dist/es/es2018/makeDurable/pendingWriter.d.ts +16 -0
- package/dist/es/es2018/makeDurable/refresh.d.ts +3 -0
- package/dist/umd/es2018/ReaderWithPrivateProperties.d.ts +4 -0
- package/dist/umd/es2018/environments.js +193 -25
- 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 +1 -1
- package/dist/umd/es2018/makeDurable/pendingWriter.d.ts +16 -0
- package/dist/umd/es2018/makeDurable/refresh.d.ts +3 -0
- package/dist/umd/es5/ReaderWithPrivateProperties.d.ts +4 -0
- package/dist/umd/es5/environments.js +194 -26
- 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 +1 -1
- package/dist/umd/es5/makeDurable/pendingWriter.d.ts +16 -0
- package/dist/umd/es5/makeDurable/refresh.d.ts +3 -0
- package/package.json +4 -3
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Fragment, FragmentUnionSelection, ObjectSelection, Reader, ReaderFragment } from '@luvio/engine';
|
|
2
|
+
export declare class ReaderWithPrivateProperties<V> extends Reader<V> {
|
|
3
|
+
traverseSelections(node: ObjectSelection | Exclude<Fragment, FragmentUnionSelection | ReaderFragment>, record: any, data: any): void;
|
|
4
|
+
}
|
|
@@ -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,13 @@ const DefaultDurableSegment = 'DEFAULT';
|
|
|
17
17
|
const { keys, create, assign, freeze } = Object;
|
|
18
18
|
const { isArray } = Array;
|
|
19
19
|
|
|
20
|
-
function buildTTLStrategy(
|
|
20
|
+
function buildTTLStrategy(staleDurationMilliseconds = 0) {
|
|
21
21
|
return (timestamp, metadata, valueIsError) => {
|
|
22
22
|
if (metadata !== undefined) {
|
|
23
23
|
const { expirationTimestamp } = metadata;
|
|
24
24
|
if (timestamp > expirationTimestamp) {
|
|
25
|
-
if (timestamp <= expirationTimestamp +
|
|
25
|
+
if (timestamp <= expirationTimestamp + staleDurationMilliseconds &&
|
|
26
|
+
valueIsError !== true) {
|
|
26
27
|
return StoreResolveResultState.Stale;
|
|
27
28
|
}
|
|
28
29
|
return StoreResolveResultState.NotPresent;
|
|
@@ -38,11 +39,175 @@ function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
|
38
39
|
return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
function
|
|
42
|
+
function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
|
|
42
43
|
return function (args) {
|
|
43
44
|
funcs.validateNotDisposed();
|
|
44
45
|
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
45
|
-
const
|
|
46
|
+
const staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
|
|
47
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
|
|
48
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
49
|
+
if (snapshot !== undefined) {
|
|
50
|
+
// data found in L1 cache
|
|
51
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
52
|
+
// kick off network request, do not await it
|
|
53
|
+
buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
54
|
+
// return the cached snapshot to caller
|
|
55
|
+
return snapshot;
|
|
56
|
+
}
|
|
57
|
+
// stale data found in L1 cache
|
|
58
|
+
if (snapshot.state === 'Stale') {
|
|
59
|
+
// kick off network request, do not await it
|
|
60
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
61
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
62
|
+
// return the cached snapshot to caller
|
|
63
|
+
return snapshot;
|
|
64
|
+
}
|
|
65
|
+
// if unfulfilled we have enough info to do an L2 lookup
|
|
66
|
+
if (snapshot.state === 'Unfulfilled') {
|
|
67
|
+
return funcs
|
|
68
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
69
|
+
.then((revivedSnapshot) => {
|
|
70
|
+
// data found in L2 cache
|
|
71
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
72
|
+
revivedSnapshot.state === 'Error') {
|
|
73
|
+
// kick off network request, do not await it
|
|
74
|
+
buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
75
|
+
// return the L2 cached snapshot to caller
|
|
76
|
+
return revivedSnapshot;
|
|
77
|
+
}
|
|
78
|
+
if (revivedSnapshot.state === 'Pending') ;
|
|
79
|
+
// stale data found in L2 cache
|
|
80
|
+
if (revivedSnapshot.state === 'Stale') {
|
|
81
|
+
// kick off network request, do not await it
|
|
82
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
83
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
84
|
+
// return the L2 cached snapshot to caller
|
|
85
|
+
return revivedSnapshot;
|
|
86
|
+
}
|
|
87
|
+
// data not found in L2 cache, go to the network
|
|
88
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (snapshot.state === 'Pending') ;
|
|
92
|
+
}
|
|
93
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function buildCacheThenNetworkImplementation(funcs) {
|
|
98
|
+
return function (args) {
|
|
99
|
+
funcs.validateNotDisposed();
|
|
100
|
+
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
101
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
102
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
103
|
+
if (snapshot !== undefined) {
|
|
104
|
+
// data found in L1 cache
|
|
105
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
106
|
+
return snapshot;
|
|
107
|
+
}
|
|
108
|
+
if (snapshot.state === 'Pending') ;
|
|
109
|
+
// data not found in L1 cache, try L2 cache
|
|
110
|
+
return funcs
|
|
111
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
112
|
+
.then((revivedSnapshot) => {
|
|
113
|
+
// data found in L2 cache
|
|
114
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
115
|
+
revivedSnapshot.state === 'Error') {
|
|
116
|
+
return revivedSnapshot;
|
|
117
|
+
}
|
|
118
|
+
if (revivedSnapshot.state === 'Pending') ;
|
|
119
|
+
// data not found in L2 cache, go to the network
|
|
120
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
124
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function buildNoCacheImplementation(funcs) {
|
|
129
|
+
return function (args) {
|
|
130
|
+
funcs.validateNotDisposed();
|
|
131
|
+
const { buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest } = args;
|
|
132
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest).then((snapshot) => {
|
|
133
|
+
if (snapshot.state === 'Pending') ;
|
|
134
|
+
return snapshot;
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function deepFreeze(value) {
|
|
140
|
+
// No need to freeze primitives
|
|
141
|
+
if (typeof value !== 'object' || value === null) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (isArray(value)) {
|
|
145
|
+
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
146
|
+
deepFreeze(value[i]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const keys$1 = keys(value);
|
|
151
|
+
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
152
|
+
deepFreeze(value[keys$1[i]]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
freeze(value);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// TODO[@W-10165595]: consolidate this code with the corresponding logic in the default environment's only-if-cached.ts
|
|
159
|
+
function buildNotCachedErrorSnapshot() {
|
|
160
|
+
const error = {
|
|
161
|
+
body: undefined,
|
|
162
|
+
headers: {},
|
|
163
|
+
ok: false,
|
|
164
|
+
status: HttpStatusCode.GatewayTimeout,
|
|
165
|
+
statusText: 'Gateway Timeout',
|
|
166
|
+
};
|
|
167
|
+
deepFreeze(error);
|
|
168
|
+
return {
|
|
169
|
+
error,
|
|
170
|
+
state: 'Error',
|
|
171
|
+
data: undefined,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function buildOnlyIfCachedImplementation(funcs) {
|
|
175
|
+
return function (args) {
|
|
176
|
+
funcs.validateNotDisposed();
|
|
177
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
178
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
179
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
180
|
+
if (snapshot !== undefined) {
|
|
181
|
+
// data found in L1 cache
|
|
182
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
183
|
+
return snapshot;
|
|
184
|
+
}
|
|
185
|
+
// network request outstanding, data is not cached
|
|
186
|
+
if (snapshot.state === 'Pending') {
|
|
187
|
+
return buildNotCachedErrorSnapshot();
|
|
188
|
+
}
|
|
189
|
+
// data not found in L1 cache, try L2 cache
|
|
190
|
+
return funcs
|
|
191
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
192
|
+
.then((revivedSnapshot) => {
|
|
193
|
+
// data found in L2 cache
|
|
194
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
195
|
+
revivedSnapshot.state === 'Error') {
|
|
196
|
+
return revivedSnapshot;
|
|
197
|
+
}
|
|
198
|
+
// data is not cached
|
|
199
|
+
return buildNotCachedErrorSnapshot();
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return buildNotCachedErrorSnapshot();
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
|
|
207
|
+
return function (args) {
|
|
208
|
+
funcs.validateNotDisposed();
|
|
209
|
+
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
210
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
|
|
46
211
|
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
47
212
|
if (snapshot !== undefined) {
|
|
48
213
|
// data found in L1 cache
|
|
@@ -105,25 +270,6 @@ function handleDurableStoreRejection(instrument) {
|
|
|
105
270
|
};
|
|
106
271
|
}
|
|
107
272
|
|
|
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
273
|
const SELECTOR_PAGINATION_TOKEN = 'tokenDataKey';
|
|
128
274
|
function isFragmentUnionSelection(sel) {
|
|
129
275
|
return sel.union === true;
|
|
@@ -272,7 +418,9 @@ function publishDurableStoreEntries(durableRecords, publish, publishMetadata) {
|
|
|
272
418
|
* will refresh the snapshot from network, and then run the results from network
|
|
273
419
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
274
420
|
*/
|
|
275
|
-
function reviveSnapshot(baseEnvironment, durableStore,
|
|
421
|
+
function reviveSnapshot(baseEnvironment, durableStore,
|
|
422
|
+
// TODO [W-10165787]: We should only allow Unfulfilled snapshot be passed in
|
|
423
|
+
unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot) {
|
|
276
424
|
const { recordId, select, seenRecords, state } = unavailableSnapshot;
|
|
277
425
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
278
426
|
// info needed to revive (like missingLinks) and rebuild. Otherwise return L1 snapshot.
|
|
@@ -764,7 +912,27 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
764
912
|
return buildStaleWhileRevalidateImplementation({
|
|
765
913
|
validateNotDisposed,
|
|
766
914
|
reviveSnapshotWithCachePolicy,
|
|
767
|
-
}, cachePolicy.
|
|
915
|
+
}, cachePolicy.staleDurationSeconds);
|
|
916
|
+
case 'cache-and-network':
|
|
917
|
+
return buildCacheAndNetworkImplementation({
|
|
918
|
+
validateNotDisposed,
|
|
919
|
+
reviveSnapshotWithCachePolicy,
|
|
920
|
+
}, cachePolicy.staleDurationSeconds);
|
|
921
|
+
case 'cache-then-network':
|
|
922
|
+
return buildCacheThenNetworkImplementation({
|
|
923
|
+
validateNotDisposed,
|
|
924
|
+
reviveSnapshotWithCachePolicy,
|
|
925
|
+
});
|
|
926
|
+
case 'no-cache':
|
|
927
|
+
return buildNoCacheImplementation({
|
|
928
|
+
validateNotDisposed,
|
|
929
|
+
reviveSnapshotWithCachePolicy,
|
|
930
|
+
});
|
|
931
|
+
case 'only-if-cached':
|
|
932
|
+
return buildOnlyIfCachedImplementation({
|
|
933
|
+
validateNotDisposed,
|
|
934
|
+
reviveSnapshotWithCachePolicy,
|
|
935
|
+
});
|
|
768
936
|
default: {
|
|
769
937
|
if (process.env.NODE_ENV !== 'production') {
|
|
770
938
|
throw new Error(`unrecognized cache policy: ${JSON.stringify(cachePolicy)}`);
|
|
@@ -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,5 @@ 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(
|
|
6
|
+
export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
|
|
7
7
|
export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Environment } from '@luvio/engine';
|
|
2
|
+
import { DurableStore } from '../DurableStore';
|
|
3
|
+
import { DurableStoreRejectionHandler } from './error';
|
|
4
|
+
export interface FlushResult {
|
|
5
|
+
flushedKeys: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
export interface PendingWriter {
|
|
8
|
+
clearPendingWrites(): void;
|
|
9
|
+
addPendingWrite(key: string): void;
|
|
10
|
+
removePendingWrite(key: string): void;
|
|
11
|
+
hasPendingWrite(key: string): boolean;
|
|
12
|
+
flushPendingWritesToDurableStore(environment: Environment, durableStore: DurableStore, durableStoreErrorHandler: DurableStoreRejectionHandler): Promise<void>;
|
|
13
|
+
getLastFlushResult(): FlushResult | undefined;
|
|
14
|
+
resetLastFlushResult(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildPendingWriter(): PendingWriter;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Environment, Snapshot, SnapshotRefresh, UnAvailableSnapshot } from '@luvio/engine';
|
|
2
|
+
import { PendingWriter } from './pendingWriter';
|
|
3
|
+
export declare function buildDurableStoreAwareRefresh<ResponseType>(refresh: SnapshotRefresh<ResponseType>, snapshot: UnAvailableSnapshot<ResponseType>, environment: Environment, pendingWriter: PendingWriter): () => Promise<Snapshot<ResponseType>>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Fragment, FragmentUnionSelection, ObjectSelection, Reader, ReaderFragment } from '@luvio/engine';
|
|
2
|
+
export declare class ReaderWithPrivateProperties<V> extends Reader<V> {
|
|
3
|
+
traverseSelections(node: ObjectSelection | Exclude<Fragment, FragmentUnionSelection | ReaderFragment>, record: any, data: any): void;
|
|
4
|
+
}
|
|
@@ -20,12 +20,13 @@
|
|
|
20
20
|
const { keys, create, assign, freeze } = Object;
|
|
21
21
|
const { isArray } = Array;
|
|
22
22
|
|
|
23
|
-
function buildTTLStrategy(
|
|
23
|
+
function buildTTLStrategy(staleDurationMilliseconds = 0) {
|
|
24
24
|
return (timestamp, metadata, valueIsError) => {
|
|
25
25
|
if (metadata !== undefined) {
|
|
26
26
|
const { expirationTimestamp } = metadata;
|
|
27
27
|
if (timestamp > expirationTimestamp) {
|
|
28
|
-
if (timestamp <= expirationTimestamp +
|
|
28
|
+
if (timestamp <= expirationTimestamp + staleDurationMilliseconds &&
|
|
29
|
+
valueIsError !== true) {
|
|
29
30
|
return engine.StoreResolveResultState.Stale;
|
|
30
31
|
}
|
|
31
32
|
return engine.StoreResolveResultState.NotPresent;
|
|
@@ -41,11 +42,175 @@
|
|
|
41
42
|
return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
function
|
|
45
|
+
function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
|
|
45
46
|
return function (args) {
|
|
46
47
|
funcs.validateNotDisposed();
|
|
47
48
|
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
48
|
-
const
|
|
49
|
+
const staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
|
|
50
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
|
|
51
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
52
|
+
if (snapshot !== undefined) {
|
|
53
|
+
// data found in L1 cache
|
|
54
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
55
|
+
// kick off network request, do not await it
|
|
56
|
+
buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
57
|
+
// return the cached snapshot to caller
|
|
58
|
+
return snapshot;
|
|
59
|
+
}
|
|
60
|
+
// stale data found in L1 cache
|
|
61
|
+
if (snapshot.state === 'Stale') {
|
|
62
|
+
// kick off network request, do not await it
|
|
63
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
64
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
65
|
+
// return the cached snapshot to caller
|
|
66
|
+
return snapshot;
|
|
67
|
+
}
|
|
68
|
+
// if unfulfilled we have enough info to do an L2 lookup
|
|
69
|
+
if (snapshot.state === 'Unfulfilled') {
|
|
70
|
+
return funcs
|
|
71
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
72
|
+
.then((revivedSnapshot) => {
|
|
73
|
+
// data found in L2 cache
|
|
74
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
75
|
+
revivedSnapshot.state === 'Error') {
|
|
76
|
+
// kick off network request, do not await it
|
|
77
|
+
buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
78
|
+
// return the L2 cached snapshot to caller
|
|
79
|
+
return revivedSnapshot;
|
|
80
|
+
}
|
|
81
|
+
if (revivedSnapshot.state === 'Pending') ;
|
|
82
|
+
// stale data found in L2 cache
|
|
83
|
+
if (revivedSnapshot.state === 'Stale') {
|
|
84
|
+
// kick off network request, do not await it
|
|
85
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
86
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
87
|
+
// return the L2 cached snapshot to caller
|
|
88
|
+
return revivedSnapshot;
|
|
89
|
+
}
|
|
90
|
+
// data not found in L2 cache, go to the network
|
|
91
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (snapshot.state === 'Pending') ;
|
|
95
|
+
}
|
|
96
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function buildCacheThenNetworkImplementation(funcs) {
|
|
101
|
+
return function (args) {
|
|
102
|
+
funcs.validateNotDisposed();
|
|
103
|
+
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
104
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
105
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
106
|
+
if (snapshot !== undefined) {
|
|
107
|
+
// data found in L1 cache
|
|
108
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
109
|
+
return snapshot;
|
|
110
|
+
}
|
|
111
|
+
if (snapshot.state === 'Pending') ;
|
|
112
|
+
// data not found in L1 cache, try L2 cache
|
|
113
|
+
return funcs
|
|
114
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
115
|
+
.then((revivedSnapshot) => {
|
|
116
|
+
// data found in L2 cache
|
|
117
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
118
|
+
revivedSnapshot.state === 'Error') {
|
|
119
|
+
return revivedSnapshot;
|
|
120
|
+
}
|
|
121
|
+
if (revivedSnapshot.state === 'Pending') ;
|
|
122
|
+
// data not found in L2 cache, go to the network
|
|
123
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
127
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function buildNoCacheImplementation(funcs) {
|
|
132
|
+
return function (args) {
|
|
133
|
+
funcs.validateNotDisposed();
|
|
134
|
+
const { buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest } = args;
|
|
135
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest).then((snapshot) => {
|
|
136
|
+
if (snapshot.state === 'Pending') ;
|
|
137
|
+
return snapshot;
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function deepFreeze(value) {
|
|
143
|
+
// No need to freeze primitives
|
|
144
|
+
if (typeof value !== 'object' || value === null) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (isArray(value)) {
|
|
148
|
+
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
149
|
+
deepFreeze(value[i]);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
const keys$1 = keys(value);
|
|
154
|
+
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
155
|
+
deepFreeze(value[keys$1[i]]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
freeze(value);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// TODO[@W-10165595]: consolidate this code with the corresponding logic in the default environment's only-if-cached.ts
|
|
162
|
+
function buildNotCachedErrorSnapshot() {
|
|
163
|
+
const error = {
|
|
164
|
+
body: undefined,
|
|
165
|
+
headers: {},
|
|
166
|
+
ok: false,
|
|
167
|
+
status: engine.HttpStatusCode.GatewayTimeout,
|
|
168
|
+
statusText: 'Gateway Timeout',
|
|
169
|
+
};
|
|
170
|
+
deepFreeze(error);
|
|
171
|
+
return {
|
|
172
|
+
error,
|
|
173
|
+
state: 'Error',
|
|
174
|
+
data: undefined,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function buildOnlyIfCachedImplementation(funcs) {
|
|
178
|
+
return function (args) {
|
|
179
|
+
funcs.validateNotDisposed();
|
|
180
|
+
const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
|
|
181
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
182
|
+
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
183
|
+
if (snapshot !== undefined) {
|
|
184
|
+
// data found in L1 cache
|
|
185
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
186
|
+
return snapshot;
|
|
187
|
+
}
|
|
188
|
+
// network request outstanding, data is not cached
|
|
189
|
+
if (snapshot.state === 'Pending') {
|
|
190
|
+
return buildNotCachedErrorSnapshot();
|
|
191
|
+
}
|
|
192
|
+
// data not found in L1 cache, try L2 cache
|
|
193
|
+
return funcs
|
|
194
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
195
|
+
.then((revivedSnapshot) => {
|
|
196
|
+
// data found in L2 cache
|
|
197
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
198
|
+
revivedSnapshot.state === 'Error') {
|
|
199
|
+
return revivedSnapshot;
|
|
200
|
+
}
|
|
201
|
+
// data is not cached
|
|
202
|
+
return buildNotCachedErrorSnapshot();
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return buildNotCachedErrorSnapshot();
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
|
|
210
|
+
return function (args) {
|
|
211
|
+
funcs.validateNotDisposed();
|
|
212
|
+
const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
|
|
213
|
+
const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
|
|
49
214
|
const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
50
215
|
if (snapshot !== undefined) {
|
|
51
216
|
// data found in L1 cache
|
|
@@ -108,25 +273,6 @@
|
|
|
108
273
|
};
|
|
109
274
|
}
|
|
110
275
|
|
|
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
276
|
const SELECTOR_PAGINATION_TOKEN = 'tokenDataKey';
|
|
131
277
|
function isFragmentUnionSelection(sel) {
|
|
132
278
|
return sel.union === true;
|
|
@@ -275,7 +421,9 @@
|
|
|
275
421
|
* will refresh the snapshot from network, and then run the results from network
|
|
276
422
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
277
423
|
*/
|
|
278
|
-
function reviveSnapshot(baseEnvironment, durableStore,
|
|
424
|
+
function reviveSnapshot(baseEnvironment, durableStore,
|
|
425
|
+
// TODO [W-10165787]: We should only allow Unfulfilled snapshot be passed in
|
|
426
|
+
unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot) {
|
|
279
427
|
const { recordId, select, seenRecords, state } = unavailableSnapshot;
|
|
280
428
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
281
429
|
// info needed to revive (like missingLinks) and rebuild. Otherwise return L1 snapshot.
|
|
@@ -767,7 +915,27 @@
|
|
|
767
915
|
return buildStaleWhileRevalidateImplementation({
|
|
768
916
|
validateNotDisposed,
|
|
769
917
|
reviveSnapshotWithCachePolicy,
|
|
770
|
-
}, cachePolicy.
|
|
918
|
+
}, cachePolicy.staleDurationSeconds);
|
|
919
|
+
case 'cache-and-network':
|
|
920
|
+
return buildCacheAndNetworkImplementation({
|
|
921
|
+
validateNotDisposed,
|
|
922
|
+
reviveSnapshotWithCachePolicy,
|
|
923
|
+
}, cachePolicy.staleDurationSeconds);
|
|
924
|
+
case 'cache-then-network':
|
|
925
|
+
return buildCacheThenNetworkImplementation({
|
|
926
|
+
validateNotDisposed,
|
|
927
|
+
reviveSnapshotWithCachePolicy,
|
|
928
|
+
});
|
|
929
|
+
case 'no-cache':
|
|
930
|
+
return buildNoCacheImplementation({
|
|
931
|
+
validateNotDisposed,
|
|
932
|
+
reviveSnapshotWithCachePolicy,
|
|
933
|
+
});
|
|
934
|
+
case 'only-if-cached':
|
|
935
|
+
return buildOnlyIfCachedImplementation({
|
|
936
|
+
validateNotDisposed,
|
|
937
|
+
reviveSnapshotWithCachePolicy,
|
|
938
|
+
});
|
|
771
939
|
default: {
|
|
772
940
|
if (process.env.NODE_ENV !== 'production') {
|
|
773
941
|
throw new Error(`unrecognized cache policy: ${JSON.stringify(cachePolicy)}`);
|
|
@@ -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,5 @@ 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(
|
|
6
|
+
export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
|
|
7
7
|
export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Environment } from '@luvio/engine';
|
|
2
|
+
import { DurableStore } from '../DurableStore';
|
|
3
|
+
import { DurableStoreRejectionHandler } from './error';
|
|
4
|
+
export interface FlushResult {
|
|
5
|
+
flushedKeys: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
export interface PendingWriter {
|
|
8
|
+
clearPendingWrites(): void;
|
|
9
|
+
addPendingWrite(key: string): void;
|
|
10
|
+
removePendingWrite(key: string): void;
|
|
11
|
+
hasPendingWrite(key: string): boolean;
|
|
12
|
+
flushPendingWritesToDurableStore(environment: Environment, durableStore: DurableStore, durableStoreErrorHandler: DurableStoreRejectionHandler): Promise<void>;
|
|
13
|
+
getLastFlushResult(): FlushResult | undefined;
|
|
14
|
+
resetLastFlushResult(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildPendingWriter(): PendingWriter;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Environment, Snapshot, SnapshotRefresh, UnAvailableSnapshot } from '@luvio/engine';
|
|
2
|
+
import { PendingWriter } from './pendingWriter';
|
|
3
|
+
export declare function buildDurableStoreAwareRefresh<ResponseType>(refresh: SnapshotRefresh<ResponseType>, snapshot: UnAvailableSnapshot<ResponseType>, environment: Environment, pendingWriter: PendingWriter): () => Promise<Snapshot<ResponseType>>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Fragment, FragmentUnionSelection, ObjectSelection, Reader, ReaderFragment } from '@luvio/engine';
|
|
2
|
+
export declare class ReaderWithPrivateProperties<V> extends Reader<V> {
|
|
3
|
+
traverseSelections(node: ObjectSelection | Exclude<Fragment, FragmentUnionSelection | ReaderFragment>, record: any, data: any): void;
|
|
4
|
+
}
|
|
@@ -54,13 +54,14 @@
|
|
|
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 buildTTLStrategy(
|
|
58
|
-
if (
|
|
57
|
+
function buildTTLStrategy(staleDurationMilliseconds) {
|
|
58
|
+
if (staleDurationMilliseconds === void 0) { staleDurationMilliseconds = 0; }
|
|
59
59
|
return function (timestamp, metadata, valueIsError) {
|
|
60
60
|
if (metadata !== undefined) {
|
|
61
61
|
var expirationTimestamp = metadata.expirationTimestamp;
|
|
62
62
|
if (timestamp > expirationTimestamp) {
|
|
63
|
-
if (timestamp <= expirationTimestamp +
|
|
63
|
+
if (timestamp <= expirationTimestamp + staleDurationMilliseconds &&
|
|
64
|
+
valueIsError !== true) {
|
|
64
65
|
return engine.StoreResolveResultState.Stale;
|
|
65
66
|
}
|
|
66
67
|
return engine.StoreResolveResultState.NotPresent;
|
|
@@ -78,11 +79,175 @@
|
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
function
|
|
82
|
+
function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
|
|
82
83
|
return function (args) {
|
|
83
84
|
funcs.validateNotDisposed();
|
|
84
85
|
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest, storeLookup = args.storeLookup;
|
|
85
|
-
var
|
|
86
|
+
var staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
|
|
87
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
|
|
88
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
89
|
+
if (snapshot !== undefined) {
|
|
90
|
+
// data found in L1 cache
|
|
91
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
92
|
+
// kick off network request, do not await it
|
|
93
|
+
buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
94
|
+
// return the cached snapshot to caller
|
|
95
|
+
return snapshot;
|
|
96
|
+
}
|
|
97
|
+
// stale data found in L1 cache
|
|
98
|
+
if (snapshot.state === 'Stale') {
|
|
99
|
+
// kick off network request, do not await it
|
|
100
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
101
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
102
|
+
// return the cached snapshot to caller
|
|
103
|
+
return snapshot;
|
|
104
|
+
}
|
|
105
|
+
// if unfulfilled we have enough info to do an L2 lookup
|
|
106
|
+
if (snapshot.state === 'Unfulfilled') {
|
|
107
|
+
return funcs
|
|
108
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
109
|
+
.then(function (revivedSnapshot) {
|
|
110
|
+
// data found in L2 cache
|
|
111
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
112
|
+
revivedSnapshot.state === 'Error') {
|
|
113
|
+
// kick off network request, do not await it
|
|
114
|
+
buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
115
|
+
// return the L2 cached snapshot to caller
|
|
116
|
+
return revivedSnapshot;
|
|
117
|
+
}
|
|
118
|
+
if (revivedSnapshot.state === 'Pending') ;
|
|
119
|
+
// stale data found in L2 cache
|
|
120
|
+
if (revivedSnapshot.state === 'Stale') {
|
|
121
|
+
// kick off network request, do not await it
|
|
122
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
123
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
124
|
+
// return the L2 cached snapshot to caller
|
|
125
|
+
return revivedSnapshot;
|
|
126
|
+
}
|
|
127
|
+
// data not found in L2 cache, go to the network
|
|
128
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (snapshot.state === 'Pending') ;
|
|
132
|
+
}
|
|
133
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function buildCacheThenNetworkImplementation(funcs) {
|
|
138
|
+
return function (args) {
|
|
139
|
+
funcs.validateNotDisposed();
|
|
140
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest, storeLookup = args.storeLookup;
|
|
141
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
142
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
143
|
+
if (snapshot !== undefined) {
|
|
144
|
+
// data found in L1 cache
|
|
145
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
146
|
+
return snapshot;
|
|
147
|
+
}
|
|
148
|
+
if (snapshot.state === 'Pending') ;
|
|
149
|
+
// data not found in L1 cache, try L2 cache
|
|
150
|
+
return funcs
|
|
151
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
152
|
+
.then(function (revivedSnapshot) {
|
|
153
|
+
// data found in L2 cache
|
|
154
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
155
|
+
revivedSnapshot.state === 'Error') {
|
|
156
|
+
return revivedSnapshot;
|
|
157
|
+
}
|
|
158
|
+
if (revivedSnapshot.state === 'Pending') ;
|
|
159
|
+
// data not found in L2 cache, go to the network
|
|
160
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// L1 lookup could not find enough information to even construct a snapshot, go to the network
|
|
164
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function buildNoCacheImplementation(funcs) {
|
|
169
|
+
return function (args) {
|
|
170
|
+
funcs.validateNotDisposed();
|
|
171
|
+
var buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest;
|
|
172
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest).then(function (snapshot) {
|
|
173
|
+
if (snapshot.state === 'Pending') ;
|
|
174
|
+
return snapshot;
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function deepFreeze(value) {
|
|
180
|
+
// No need to freeze primitives
|
|
181
|
+
if (typeof value !== 'object' || value === null) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (isArray(value)) {
|
|
185
|
+
for (var i = 0, len = value.length; i < len; i += 1) {
|
|
186
|
+
deepFreeze(value[i]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
var keys$1 = keys(value);
|
|
191
|
+
for (var i = 0, len = keys$1.length; i < len; i += 1) {
|
|
192
|
+
deepFreeze(value[keys$1[i]]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
freeze(value);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// TODO[@W-10165595]: consolidate this code with the corresponding logic in the default environment's only-if-cached.ts
|
|
199
|
+
function buildNotCachedErrorSnapshot() {
|
|
200
|
+
var error = {
|
|
201
|
+
body: undefined,
|
|
202
|
+
headers: {},
|
|
203
|
+
ok: false,
|
|
204
|
+
status: engine.HttpStatusCode.GatewayTimeout,
|
|
205
|
+
statusText: 'Gateway Timeout',
|
|
206
|
+
};
|
|
207
|
+
deepFreeze(error);
|
|
208
|
+
return {
|
|
209
|
+
error: error,
|
|
210
|
+
state: 'Error',
|
|
211
|
+
data: undefined,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function buildOnlyIfCachedImplementation(funcs) {
|
|
215
|
+
return function (args) {
|
|
216
|
+
funcs.validateNotDisposed();
|
|
217
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
|
|
218
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
|
|
219
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
220
|
+
if (snapshot !== undefined) {
|
|
221
|
+
// data found in L1 cache
|
|
222
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
223
|
+
return snapshot;
|
|
224
|
+
}
|
|
225
|
+
// network request outstanding, data is not cached
|
|
226
|
+
if (snapshot.state === 'Pending') {
|
|
227
|
+
return buildNotCachedErrorSnapshot();
|
|
228
|
+
}
|
|
229
|
+
// data not found in L1 cache, try L2 cache
|
|
230
|
+
return funcs
|
|
231
|
+
.reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
|
|
232
|
+
.then(function (revivedSnapshot) {
|
|
233
|
+
// data found in L2 cache
|
|
234
|
+
if (revivedSnapshot.state === 'Fulfilled' ||
|
|
235
|
+
revivedSnapshot.state === 'Error') {
|
|
236
|
+
return revivedSnapshot;
|
|
237
|
+
}
|
|
238
|
+
// data is not cached
|
|
239
|
+
return buildNotCachedErrorSnapshot();
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return buildNotCachedErrorSnapshot();
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
|
|
247
|
+
return function (args) {
|
|
248
|
+
funcs.validateNotDisposed();
|
|
249
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest, storeLookup = args.storeLookup;
|
|
250
|
+
var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
|
|
86
251
|
var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
|
|
87
252
|
if (snapshot !== undefined) {
|
|
88
253
|
// data found in L1 cache
|
|
@@ -146,25 +311,6 @@
|
|
|
146
311
|
};
|
|
147
312
|
}
|
|
148
313
|
|
|
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
314
|
var SELECTOR_PAGINATION_TOKEN = 'tokenDataKey';
|
|
169
315
|
function isFragmentUnionSelection(sel) {
|
|
170
316
|
return sel.union === true;
|
|
@@ -307,7 +453,9 @@
|
|
|
307
453
|
* will refresh the snapshot from network, and then run the results from network
|
|
308
454
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
309
455
|
*/
|
|
310
|
-
function reviveSnapshot(baseEnvironment, durableStore,
|
|
456
|
+
function reviveSnapshot(baseEnvironment, durableStore,
|
|
457
|
+
// TODO [W-10165787]: We should only allow Unfulfilled snapshot be passed in
|
|
458
|
+
unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot) {
|
|
311
459
|
var _a;
|
|
312
460
|
var recordId = unavailableSnapshot.recordId, select = unavailableSnapshot.select, seenRecords = unavailableSnapshot.seenRecords, state = unavailableSnapshot.state;
|
|
313
461
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
@@ -809,7 +957,27 @@
|
|
|
809
957
|
return buildStaleWhileRevalidateImplementation({
|
|
810
958
|
validateNotDisposed: validateNotDisposed,
|
|
811
959
|
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
812
|
-
}, cachePolicy.
|
|
960
|
+
}, cachePolicy.staleDurationSeconds);
|
|
961
|
+
case 'cache-and-network':
|
|
962
|
+
return buildCacheAndNetworkImplementation({
|
|
963
|
+
validateNotDisposed: validateNotDisposed,
|
|
964
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
965
|
+
}, cachePolicy.staleDurationSeconds);
|
|
966
|
+
case 'cache-then-network':
|
|
967
|
+
return buildCacheThenNetworkImplementation({
|
|
968
|
+
validateNotDisposed: validateNotDisposed,
|
|
969
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
970
|
+
});
|
|
971
|
+
case 'no-cache':
|
|
972
|
+
return buildNoCacheImplementation({
|
|
973
|
+
validateNotDisposed: validateNotDisposed,
|
|
974
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
975
|
+
});
|
|
976
|
+
case 'only-if-cached':
|
|
977
|
+
return buildOnlyIfCachedImplementation({
|
|
978
|
+
validateNotDisposed: validateNotDisposed,
|
|
979
|
+
reviveSnapshotWithCachePolicy: reviveSnapshotWithCachePolicy,
|
|
980
|
+
});
|
|
813
981
|
default: {
|
|
814
982
|
if (process.env.NODE_ENV !== 'production') {
|
|
815
983
|
throw new Error("unrecognized cache policy: " + JSON.stringify(cachePolicy));
|
|
@@ -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,5 @@ 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(
|
|
6
|
+
export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
|
|
7
7
|
export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Environment } from '@luvio/engine';
|
|
2
|
+
import { DurableStore } from '../DurableStore';
|
|
3
|
+
import { DurableStoreRejectionHandler } from './error';
|
|
4
|
+
export interface FlushResult {
|
|
5
|
+
flushedKeys: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
export interface PendingWriter {
|
|
8
|
+
clearPendingWrites(): void;
|
|
9
|
+
addPendingWrite(key: string): void;
|
|
10
|
+
removePendingWrite(key: string): void;
|
|
11
|
+
hasPendingWrite(key: string): boolean;
|
|
12
|
+
flushPendingWritesToDurableStore(environment: Environment, durableStore: DurableStore, durableStoreErrorHandler: DurableStoreRejectionHandler): Promise<void>;
|
|
13
|
+
getLastFlushResult(): FlushResult | undefined;
|
|
14
|
+
resetLastFlushResult(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare function buildPendingWriter(): PendingWriter;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Environment, Snapshot, SnapshotRefresh, UnAvailableSnapshot } from '@luvio/engine';
|
|
2
|
+
import { PendingWriter } from './pendingWriter';
|
|
3
|
+
export declare function buildDurableStoreAwareRefresh<ResponseType>(refresh: SnapshotRefresh<ResponseType>, snapshot: UnAvailableSnapshot<ResponseType>, environment: Environment, pendingWriter: PendingWriter): () => Promise<Snapshot<ResponseType>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luvio/environments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0-236.0",
|
|
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.0"
|
|
20
|
+
},
|
|
21
|
+
"gitHead": "4b95b09a954e65b46e5c5e004717349a046113de"
|
|
21
22
|
}
|