@luvio/environments 0.70.0 → 0.71.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.
@@ -18,7 +18,11 @@ const { keys, create, assign, freeze } = Object;
18
18
  const { isArray } = Array;
19
19
 
20
20
  function appendTTLStrategy(storeLookup, ttlStrategy) {
21
- return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
21
+ const returnStoreLookup = (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
22
+ // append ttlStrategy to storeLookup function (in cases where custom adapter
23
+ // wants to perform it's own lookup)
24
+ returnStoreLookup.ttlStrategy = ttlStrategy;
25
+ return returnStoreLookup;
22
26
  }
23
27
  function buildNetworkSnapshot(args) {
24
28
  const { buildNetworkSnapshot, buildSnapshotContext, coercedAdapterRequestContext } = args;
@@ -41,102 +45,112 @@ function buildTTLStrategy(staleDurationMilliseconds = 0) {
41
45
  }
42
46
  return StoreResolveResultState.Found;
43
47
  };
48
+ }
49
+ // TODO - update userland-facing APIs to return `AvailableSnapshot` instead of `Snapshot`
50
+ // and then the signatures here can be updated as well
51
+ function buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, availableSnapshotFunc) {
52
+ if (isPromise(cachedSnapshot)) {
53
+ return cachedSnapshot.then(availableSnapshotFunc);
54
+ }
55
+ return availableSnapshotFunc(cachedSnapshot);
56
+ }
57
+ function isPromise(value) {
58
+ if (value === undefined) {
59
+ return false;
60
+ }
61
+ // check for Thenable due to test frameworks using custom Promise impls
62
+ return value.then !== undefined;
44
63
  }
45
64
 
46
- function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
65
+ function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds = 0) {
47
66
  return function (args) {
48
67
  funcs.validateNotDisposed();
49
- const { buildInMemorySnapshot, buildNetworkSnapshot: buildNetworkSnapshot$1, buildSnapshotContext, storeLookup, coercedAdapterRequestContext, } = args;
50
- const staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
68
+ const { buildCachedSnapshot, buildNetworkSnapshot: buildNetworkSnapshot$1, buildSnapshotContext, storeLookup, coercedAdapterRequestContext, } = args;
69
+ const staleDurationMilliseconds = staleDurationSeconds * 1000;
51
70
  const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
52
- const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
53
- if (snapshot !== undefined) {
54
- // data found in L1 cache
55
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
56
- // kick off network request, do not await it
57
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
58
- // return the cached snapshot to caller
59
- return snapshot;
60
- }
61
- // network request outstanding
62
- if (snapshot.state === 'Pending') {
63
- // kick off another network request, do not await it
64
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
65
- return args.resolvePendingSnapshot(snapshot);
66
- }
67
- // stale data found in L1 cache
68
- if (snapshot.state === 'Stale') {
69
- // kick off network request, do not await it
70
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
71
- // return the cached snapshot to caller
72
- return snapshot;
73
- }
74
- // if unfulfilled we have enough info to do an L2 lookup
75
- if (snapshot.state === 'Unfulfilled') {
76
- return funcs
77
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
78
- .then((revivedSnapshot) => {
79
- // data found in L2 cache
80
- if (revivedSnapshot.state === 'Fulfilled' ||
81
- revivedSnapshot.state === 'Error') {
82
- // kick off network request, do not await it
83
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
84
- // return the L2 cached snapshot to caller
85
- return revivedSnapshot;
86
- }
87
- if (revivedSnapshot.state === 'Pending') {
88
- // kick off network request, do not await it
89
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
90
- return args.resolvePendingSnapshot(revivedSnapshot);
91
- }
92
- // stale data found in L2 cache
93
- if (revivedSnapshot.state === 'Stale') {
94
- // kick off network request, do not await it
95
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
96
- // return the L2 cached snapshot to caller
97
- return revivedSnapshot;
98
- }
99
- // data not found in L2 cache, go to the network
100
- return buildNetworkSnapshot(args);
101
- });
71
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
72
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
73
+ if (snapshot !== undefined) {
74
+ // data found in L1 cache
75
+ if (snapshot.state === 'Fulfilled' ||
76
+ snapshot.state === 'Error' ||
77
+ snapshot.state === 'Stale') {
78
+ // kick off network request, do not await it
79
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
80
+ // return the cached snapshot to caller
81
+ return snapshot;
82
+ }
83
+ // network request outstanding
84
+ if (snapshot.state === 'Pending') {
85
+ // kick off another network request, do not await it
86
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
87
+ return args.resolvePendingSnapshot(snapshot);
88
+ }
89
+ // if unfulfilled we have enough info to do an L2 lookup
90
+ if (snapshot.state === 'Unfulfilled') {
91
+ return funcs
92
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
93
+ .then((revivedSnapshot) => {
94
+ // data found in L2 cache
95
+ if (revivedSnapshot.state === 'Fulfilled' ||
96
+ revivedSnapshot.state === 'Error' ||
97
+ revivedSnapshot.state === 'Stale') {
98
+ // kick off network request, do not await it
99
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
100
+ // return the L2 cached snapshot to caller
101
+ return revivedSnapshot;
102
+ }
103
+ if (revivedSnapshot.state === 'Pending') {
104
+ // kick off network request, do not await it
105
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
106
+ return args.resolvePendingSnapshot(revivedSnapshot);
107
+ }
108
+ // data not found in L2 cache, go to the network
109
+ return buildNetworkSnapshot(args);
110
+ });
111
+ }
102
112
  }
103
- }
104
- return buildNetworkSnapshot(args);
113
+ return buildNetworkSnapshot(args);
114
+ });
105
115
  };
106
116
  }
107
117
 
108
118
  function buildCacheThenNetworkImplementation(funcs) {
109
119
  return function (args) {
110
120
  funcs.validateNotDisposed();
111
- const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
121
+ const { buildCachedSnapshot, buildSnapshotContext, storeLookup } = args;
112
122
  const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
113
- const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
114
- if (snapshot !== undefined) {
115
- // data found in L1 cache
116
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
117
- return snapshot;
118
- }
119
- if (snapshot.state === 'Pending') {
120
- return args.resolvePendingSnapshot(snapshot);
121
- }
122
- // data not found in L1 cache, try L2 cache
123
- return funcs
124
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
125
- .then((revivedSnapshot) => {
126
- // data found in L2 cache
127
- if (revivedSnapshot.state === 'Fulfilled' ||
128
- revivedSnapshot.state === 'Error') {
129
- return revivedSnapshot;
123
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
124
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
125
+ if (snapshot !== undefined) {
126
+ // data found in L1 cache
127
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
128
+ return snapshot;
130
129
  }
131
- if (revivedSnapshot.state === 'Pending') {
132
- return args.resolvePendingSnapshot(revivedSnapshot);
130
+ if (snapshot.state === 'Pending') {
131
+ return args.resolvePendingSnapshot(snapshot);
133
132
  }
134
- // data not found in L2 cache, go to the network
135
- return buildNetworkSnapshot(args);
136
- });
137
- }
138
- // L1 lookup could not find enough information to even construct a snapshot, go to the network
139
- return buildNetworkSnapshot(args);
133
+ // if unfulfilled we have enough info to do an L2 lookup
134
+ if (snapshot.state === 'Unfulfilled') {
135
+ return funcs
136
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
137
+ .then((revivedSnapshot) => {
138
+ // data found in L2 cache
139
+ if (revivedSnapshot.state === 'Fulfilled' ||
140
+ revivedSnapshot.state === 'Error') {
141
+ return revivedSnapshot;
142
+ }
143
+ if (revivedSnapshot.state === 'Pending') {
144
+ return args.resolvePendingSnapshot(revivedSnapshot);
145
+ }
146
+ // data not found in L2 cache, go to the network
147
+ return buildNetworkSnapshot(args);
148
+ });
149
+ }
150
+ }
151
+ // L1 lookup could not find enough information to even construct a snapshot, go to the network
152
+ return buildNetworkSnapshot(args);
153
+ });
140
154
  };
141
155
  }
142
156
 
@@ -180,84 +194,90 @@ function buildNotCachedErrorSnapshot() {
180
194
  error,
181
195
  state: 'Error',
182
196
  data: undefined,
183
- // TODO[@W-10164067]: copy refresh data from the snapshot returned by buildInMemorySnapshot (if any)
197
+ // TODO[@W-10164067]: copy refresh data from the snapshot returned by buildCachedSnapshot (if any)
184
198
  // refresh: ...
185
199
  };
186
200
  }
187
201
  function buildOnlyIfCachedImplementation(funcs) {
188
202
  return function (args) {
189
203
  funcs.validateNotDisposed();
190
- const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
204
+ const { buildCachedSnapshot, buildSnapshotContext, storeLookup } = args;
191
205
  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;
206
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
207
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
208
+ if (snapshot !== undefined) {
209
+ // data found in L1 cache
210
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
211
+ return snapshot;
210
212
  }
211
- // data is not cached
212
- return buildNotCachedErrorSnapshot();
213
- });
214
- }
215
- return buildNotCachedErrorSnapshot();
213
+ // network request outstanding, data is not cached
214
+ if (snapshot.state === 'Pending') {
215
+ return buildNotCachedErrorSnapshot();
216
+ }
217
+ // if unfulfilled we have enough info to do an L2 lookup
218
+ if (snapshot.state === 'Unfulfilled') {
219
+ return funcs
220
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
221
+ .then((revivedSnapshot) => {
222
+ // data found in L2 cache
223
+ if (revivedSnapshot.state === 'Fulfilled' ||
224
+ revivedSnapshot.state === 'Error') {
225
+ return revivedSnapshot;
226
+ }
227
+ // data is not cached
228
+ return buildNotCachedErrorSnapshot();
229
+ });
230
+ }
231
+ }
232
+ return buildNotCachedErrorSnapshot();
233
+ });
216
234
  };
217
235
  }
218
236
 
219
237
  function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
220
238
  return function (args) {
221
239
  funcs.validateNotDisposed();
222
- const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
240
+ const { buildCachedSnapshot, buildSnapshotContext, storeLookup } = args;
223
241
  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
- buildNetworkSnapshot(args);
236
- return snapshot;
237
- }
238
- // data not found in L1 cache, try L2 cache
239
- return funcs
240
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
241
- .then((revivedSnapshot) => {
242
- // data found in L2 cache
243
- if (revivedSnapshot.state === 'Fulfilled' ||
244
- revivedSnapshot.state === 'Error') {
245
- return revivedSnapshot;
242
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
243
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
244
+ if (snapshot !== undefined) {
245
+ // data found in L1 cache
246
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
247
+ return snapshot;
246
248
  }
247
- if (revivedSnapshot.state === 'Pending') {
248
- return args.resolvePendingSnapshot(revivedSnapshot);
249
+ if (snapshot.state === 'Pending') {
250
+ return args.resolvePendingSnapshot(snapshot);
249
251
  }
250
- // stale data found in L2 cache
251
- if (revivedSnapshot.state === 'Stale') {
252
+ // stale data found in L1 cache
253
+ if (snapshot.state === 'Stale') {
252
254
  buildNetworkSnapshot(args);
253
- return revivedSnapshot;
255
+ return snapshot;
254
256
  }
255
- // data not found in L2 cache, go to the network
256
- return buildNetworkSnapshot(args);
257
- });
258
- }
259
- // L1 lookup could not find enough information to even construct a snapshot, go to the network
260
- return buildNetworkSnapshot(args);
257
+ // data not found in L1 cache, try L2 cache
258
+ return funcs
259
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
260
+ .then((revivedSnapshot) => {
261
+ // data found in L2 cache
262
+ if (revivedSnapshot.state === 'Fulfilled' ||
263
+ revivedSnapshot.state === 'Error') {
264
+ return revivedSnapshot;
265
+ }
266
+ if (revivedSnapshot.state === 'Pending') {
267
+ return args.resolvePendingSnapshot(revivedSnapshot);
268
+ }
269
+ // stale data found in L2 cache
270
+ if (revivedSnapshot.state === 'Stale') {
271
+ buildNetworkSnapshot(args);
272
+ return revivedSnapshot;
273
+ }
274
+ // data not found in L2 cache, go to the network
275
+ return buildNetworkSnapshot(args);
276
+ });
277
+ }
278
+ // L1 lookup could not find enough information to even construct a snapshot, go to the network
279
+ return buildNetworkSnapshot(args);
280
+ });
261
281
  };
262
282
  }
263
283
 
@@ -268,7 +288,7 @@ function buildValidAtImplementation(funcs, basePolicyImplementation, timestamp)
268
288
  // TTLStrategy to use the the valid-at cache policy's timestamp. The flow goes:
269
289
  //
270
290
  // Environment.applyCachePolicy => validAtImplementation (this function) =>
271
- // basePolicyImplementation => adapter's buildInMemorySnapshot =>
291
+ // basePolicyImplementation => adapter's buildCachedSnapshot =>
272
292
  // basePolicyImplementation's storeLookup => validAtStoreLookup (below) =>
273
293
  // Environment.applyCachePolicy's storeLookup => Store/Reader code =>
274
294
  // valid-at TTLStrategy (below) =>
@@ -808,7 +828,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
808
828
  if (ingestStagingStore !== null) {
809
829
  return ingestStagingStore.lookup(sel, createSnapshot, refresh, ttlStrategy);
810
830
  }
811
- // otherwise this is from buildInMemorySnapshot and we should use the luvio
831
+ // otherwise this is from buildCachedSnapshot and we should use the luvio
812
832
  // L1 store
813
833
  return environment.storeLookup(sel, createSnapshot, refresh, ttlStrategy);
814
834
  };
@@ -969,7 +989,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
969
989
  }
970
990
  }
971
991
  }
972
- const applyCachePolicy = function (adapterRequestContext, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
992
+ const applyCachePolicy = function (adapterRequestContext, buildSnapshotContext, buildCachedSnapshot, buildNetworkSnapshot) {
973
993
  validateNotDisposed();
974
994
  const { cachePolicy } = adapterRequestContext;
975
995
  const cachePolicyImpl = resolveCachePolicy(cachePolicy);
@@ -977,7 +997,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
977
997
  const storeLookup = (sel, refresh, ttlStrategy) => environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy);
978
998
  const applyCachePolicy = () => {
979
999
  return cachePolicyImpl({
980
- buildInMemorySnapshot,
1000
+ buildCachedSnapshot,
981
1001
  buildNetworkSnapshot,
982
1002
  buildSnapshotContext,
983
1003
  resolvePendingSnapshot,
@@ -1,8 +1,9 @@
1
- import { BuildInMemorySnapshot, CachePolicyImplementationArgs, Snapshot, StoreLookup, TTLStrategy, UnAvailableSnapshot } from '@luvio/engine';
1
+ import { BuildCachedSnapshot, CachePolicyImplementationArgs, Snapshot, StoreLookup, TTLStrategy, UnAvailableSnapshot } from '@luvio/engine';
2
2
  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 appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
6
+ export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildCachedSnapshot<C, D>>[1];
7
7
  export declare function buildNetworkSnapshot<C, D>(args: CachePolicyImplementationArgs<C, D>): Promise<Snapshot<D, unknown>>;
8
8
  export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
9
+ export declare function buildAvailableSnapshotFromCachedSnapshotResponse<C, D>(cachedSnapshot: ReturnType<BuildCachedSnapshot<C, D>>, availableSnapshotFunc: (snapshot: Snapshot<D> | undefined) => Snapshot<D> | Promise<Snapshot<D>>): Snapshot<D> | Promise<Snapshot<D>>;
@@ -22,7 +22,11 @@
22
22
  const { isArray } = Array;
23
23
 
24
24
  function appendTTLStrategy(storeLookup, ttlStrategy) {
25
- return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
25
+ const returnStoreLookup = (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
26
+ // append ttlStrategy to storeLookup function (in cases where custom adapter
27
+ // wants to perform it's own lookup)
28
+ returnStoreLookup.ttlStrategy = ttlStrategy;
29
+ return returnStoreLookup;
26
30
  }
27
31
  function buildNetworkSnapshot(args) {
28
32
  const { buildNetworkSnapshot, buildSnapshotContext, coercedAdapterRequestContext } = args;
@@ -45,102 +49,112 @@
45
49
  }
46
50
  return engine.StoreResolveResultState.Found;
47
51
  };
52
+ }
53
+ // TODO - update userland-facing APIs to return `AvailableSnapshot` instead of `Snapshot`
54
+ // and then the signatures here can be updated as well
55
+ function buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, availableSnapshotFunc) {
56
+ if (isPromise(cachedSnapshot)) {
57
+ return cachedSnapshot.then(availableSnapshotFunc);
58
+ }
59
+ return availableSnapshotFunc(cachedSnapshot);
60
+ }
61
+ function isPromise(value) {
62
+ if (value === undefined) {
63
+ return false;
64
+ }
65
+ // check for Thenable due to test frameworks using custom Promise impls
66
+ return value.then !== undefined;
48
67
  }
49
68
 
50
- function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
69
+ function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds = 0) {
51
70
  return function (args) {
52
71
  funcs.validateNotDisposed();
53
- const { buildInMemorySnapshot, buildNetworkSnapshot: buildNetworkSnapshot$1, buildSnapshotContext, storeLookup, coercedAdapterRequestContext, } = args;
54
- const staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
72
+ const { buildCachedSnapshot, buildNetworkSnapshot: buildNetworkSnapshot$1, buildSnapshotContext, storeLookup, coercedAdapterRequestContext, } = args;
73
+ const staleDurationMilliseconds = staleDurationSeconds * 1000;
55
74
  const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
56
- const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
57
- if (snapshot !== undefined) {
58
- // data found in L1 cache
59
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
60
- // kick off network request, do not await it
61
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
62
- // return the cached snapshot to caller
63
- return snapshot;
64
- }
65
- // network request outstanding
66
- if (snapshot.state === 'Pending') {
67
- // kick off another network request, do not await it
68
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
69
- return args.resolvePendingSnapshot(snapshot);
70
- }
71
- // stale data found in L1 cache
72
- if (snapshot.state === 'Stale') {
73
- // kick off network request, do not await it
74
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
75
- // return the cached snapshot to caller
76
- return snapshot;
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, coercedAdapterRequestContext);
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, coercedAdapterRequestContext);
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
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
100
- // return the L2 cached snapshot to caller
101
- return revivedSnapshot;
102
- }
103
- // data not found in L2 cache, go to the network
104
- return buildNetworkSnapshot(args);
105
- });
75
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
76
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
77
+ if (snapshot !== undefined) {
78
+ // data found in L1 cache
79
+ if (snapshot.state === 'Fulfilled' ||
80
+ snapshot.state === 'Error' ||
81
+ snapshot.state === 'Stale') {
82
+ // kick off network request, do not await it
83
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
84
+ // return the cached snapshot to caller
85
+ return snapshot;
86
+ }
87
+ // network request outstanding
88
+ if (snapshot.state === 'Pending') {
89
+ // kick off another network request, do not await it
90
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
91
+ return args.resolvePendingSnapshot(snapshot);
92
+ }
93
+ // if unfulfilled we have enough info to do an L2 lookup
94
+ if (snapshot.state === 'Unfulfilled') {
95
+ return funcs
96
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
97
+ .then((revivedSnapshot) => {
98
+ // data found in L2 cache
99
+ if (revivedSnapshot.state === 'Fulfilled' ||
100
+ revivedSnapshot.state === 'Error' ||
101
+ revivedSnapshot.state === 'Stale') {
102
+ // kick off network request, do not await it
103
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
104
+ // return the L2 cached snapshot to caller
105
+ return revivedSnapshot;
106
+ }
107
+ if (revivedSnapshot.state === 'Pending') {
108
+ // kick off network request, do not await it
109
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
110
+ return args.resolvePendingSnapshot(revivedSnapshot);
111
+ }
112
+ // data not found in L2 cache, go to the network
113
+ return buildNetworkSnapshot(args);
114
+ });
115
+ }
106
116
  }
107
- }
108
- return buildNetworkSnapshot(args);
117
+ return buildNetworkSnapshot(args);
118
+ });
109
119
  };
110
120
  }
111
121
 
112
122
  function buildCacheThenNetworkImplementation(funcs) {
113
123
  return function (args) {
114
124
  funcs.validateNotDisposed();
115
- const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
125
+ const { buildCachedSnapshot, buildSnapshotContext, storeLookup } = args;
116
126
  const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
117
- const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
118
- if (snapshot !== undefined) {
119
- // data found in L1 cache
120
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
121
- return snapshot;
122
- }
123
- if (snapshot.state === 'Pending') {
124
- return args.resolvePendingSnapshot(snapshot);
125
- }
126
- // data not found in L1 cache, try L2 cache
127
- return funcs
128
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
129
- .then((revivedSnapshot) => {
130
- // data found in L2 cache
131
- if (revivedSnapshot.state === 'Fulfilled' ||
132
- revivedSnapshot.state === 'Error') {
133
- return revivedSnapshot;
127
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
128
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
129
+ if (snapshot !== undefined) {
130
+ // data found in L1 cache
131
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
132
+ return snapshot;
134
133
  }
135
- if (revivedSnapshot.state === 'Pending') {
136
- return args.resolvePendingSnapshot(revivedSnapshot);
134
+ if (snapshot.state === 'Pending') {
135
+ return args.resolvePendingSnapshot(snapshot);
137
136
  }
138
- // data not found in L2 cache, go to the network
139
- return buildNetworkSnapshot(args);
140
- });
141
- }
142
- // L1 lookup could not find enough information to even construct a snapshot, go to the network
143
- return buildNetworkSnapshot(args);
137
+ // if unfulfilled we have enough info to do an L2 lookup
138
+ if (snapshot.state === 'Unfulfilled') {
139
+ return funcs
140
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
141
+ .then((revivedSnapshot) => {
142
+ // data found in L2 cache
143
+ if (revivedSnapshot.state === 'Fulfilled' ||
144
+ revivedSnapshot.state === 'Error') {
145
+ return revivedSnapshot;
146
+ }
147
+ if (revivedSnapshot.state === 'Pending') {
148
+ return args.resolvePendingSnapshot(revivedSnapshot);
149
+ }
150
+ // data not found in L2 cache, go to the network
151
+ return buildNetworkSnapshot(args);
152
+ });
153
+ }
154
+ }
155
+ // L1 lookup could not find enough information to even construct a snapshot, go to the network
156
+ return buildNetworkSnapshot(args);
157
+ });
144
158
  };
145
159
  }
146
160
 
@@ -184,84 +198,90 @@
184
198
  error,
185
199
  state: 'Error',
186
200
  data: undefined,
187
- // TODO[@W-10164067]: copy refresh data from the snapshot returned by buildInMemorySnapshot (if any)
201
+ // TODO[@W-10164067]: copy refresh data from the snapshot returned by buildCachedSnapshot (if any)
188
202
  // refresh: ...
189
203
  };
190
204
  }
191
205
  function buildOnlyIfCachedImplementation(funcs) {
192
206
  return function (args) {
193
207
  funcs.validateNotDisposed();
194
- const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
208
+ const { buildCachedSnapshot, buildSnapshotContext, storeLookup } = args;
195
209
  const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
196
- const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
197
- if (snapshot !== undefined) {
198
- // data found in L1 cache
199
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
200
- return snapshot;
201
- }
202
- // network request outstanding, data is not cached
203
- if (snapshot.state === 'Pending') {
204
- return buildNotCachedErrorSnapshot();
205
- }
206
- // data not found in L1 cache, try L2 cache
207
- return funcs
208
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
209
- .then((revivedSnapshot) => {
210
- // data found in L2 cache
211
- if (revivedSnapshot.state === 'Fulfilled' ||
212
- revivedSnapshot.state === 'Error') {
213
- return revivedSnapshot;
210
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
211
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
212
+ if (snapshot !== undefined) {
213
+ // data found in L1 cache
214
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
215
+ return snapshot;
214
216
  }
215
- // data is not cached
216
- return buildNotCachedErrorSnapshot();
217
- });
218
- }
219
- return buildNotCachedErrorSnapshot();
217
+ // network request outstanding, data is not cached
218
+ if (snapshot.state === 'Pending') {
219
+ return buildNotCachedErrorSnapshot();
220
+ }
221
+ // if unfulfilled we have enough info to do an L2 lookup
222
+ if (snapshot.state === 'Unfulfilled') {
223
+ return funcs
224
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
225
+ .then((revivedSnapshot) => {
226
+ // data found in L2 cache
227
+ if (revivedSnapshot.state === 'Fulfilled' ||
228
+ revivedSnapshot.state === 'Error') {
229
+ return revivedSnapshot;
230
+ }
231
+ // data is not cached
232
+ return buildNotCachedErrorSnapshot();
233
+ });
234
+ }
235
+ }
236
+ return buildNotCachedErrorSnapshot();
237
+ });
220
238
  };
221
239
  }
222
240
 
223
241
  function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
224
242
  return function (args) {
225
243
  funcs.validateNotDisposed();
226
- const { buildInMemorySnapshot, buildSnapshotContext, storeLookup } = args;
244
+ const { buildCachedSnapshot, buildSnapshotContext, storeLookup } = args;
227
245
  const cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
228
- const snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
229
- if (snapshot !== undefined) {
230
- // data found in L1 cache
231
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
232
- return snapshot;
233
- }
234
- if (snapshot.state === 'Pending') {
235
- return args.resolvePendingSnapshot(snapshot);
236
- }
237
- // stale data found in L1 cache
238
- if (snapshot.state === 'Stale') {
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;
246
+ const cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
247
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, (snapshot) => {
248
+ if (snapshot !== undefined) {
249
+ // data found in L1 cache
250
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
251
+ return snapshot;
250
252
  }
251
- if (revivedSnapshot.state === 'Pending') {
252
- return args.resolvePendingSnapshot(revivedSnapshot);
253
+ if (snapshot.state === 'Pending') {
254
+ return args.resolvePendingSnapshot(snapshot);
253
255
  }
254
- // stale data found in L2 cache
255
- if (revivedSnapshot.state === 'Stale') {
256
+ // stale data found in L1 cache
257
+ if (snapshot.state === 'Stale') {
256
258
  buildNetworkSnapshot(args);
257
- return revivedSnapshot;
259
+ return snapshot;
258
260
  }
259
- // data not found in L2 cache, go to the network
260
- return buildNetworkSnapshot(args);
261
- });
262
- }
263
- // L1 lookup could not find enough information to even construct a snapshot, go to the network
264
- return buildNetworkSnapshot(args);
261
+ // data not found in L1 cache, try L2 cache
262
+ return funcs
263
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
264
+ .then((revivedSnapshot) => {
265
+ // data found in L2 cache
266
+ if (revivedSnapshot.state === 'Fulfilled' ||
267
+ revivedSnapshot.state === 'Error') {
268
+ return revivedSnapshot;
269
+ }
270
+ if (revivedSnapshot.state === 'Pending') {
271
+ return args.resolvePendingSnapshot(revivedSnapshot);
272
+ }
273
+ // stale data found in L2 cache
274
+ if (revivedSnapshot.state === 'Stale') {
275
+ buildNetworkSnapshot(args);
276
+ return revivedSnapshot;
277
+ }
278
+ // data not found in L2 cache, go to the network
279
+ return buildNetworkSnapshot(args);
280
+ });
281
+ }
282
+ // L1 lookup could not find enough information to even construct a snapshot, go to the network
283
+ return buildNetworkSnapshot(args);
284
+ });
265
285
  };
266
286
  }
267
287
 
@@ -272,7 +292,7 @@
272
292
  // TTLStrategy to use the the valid-at cache policy's timestamp. The flow goes:
273
293
  //
274
294
  // Environment.applyCachePolicy => validAtImplementation (this function) =>
275
- // basePolicyImplementation => adapter's buildInMemorySnapshot =>
295
+ // basePolicyImplementation => adapter's buildCachedSnapshot =>
276
296
  // basePolicyImplementation's storeLookup => validAtStoreLookup (below) =>
277
297
  // Environment.applyCachePolicy's storeLookup => Store/Reader code =>
278
298
  // valid-at TTLStrategy (below) =>
@@ -812,7 +832,7 @@
812
832
  if (ingestStagingStore !== null) {
813
833
  return ingestStagingStore.lookup(sel, createSnapshot, refresh, ttlStrategy);
814
834
  }
815
- // otherwise this is from buildInMemorySnapshot and we should use the luvio
835
+ // otherwise this is from buildCachedSnapshot and we should use the luvio
816
836
  // L1 store
817
837
  return environment.storeLookup(sel, createSnapshot, refresh, ttlStrategy);
818
838
  };
@@ -973,7 +993,7 @@
973
993
  }
974
994
  }
975
995
  }
976
- const applyCachePolicy = function (adapterRequestContext, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
996
+ const applyCachePolicy = function (adapterRequestContext, buildSnapshotContext, buildCachedSnapshot, buildNetworkSnapshot) {
977
997
  validateNotDisposed();
978
998
  const { cachePolicy } = adapterRequestContext;
979
999
  const cachePolicyImpl = resolveCachePolicy(cachePolicy);
@@ -981,7 +1001,7 @@
981
1001
  const storeLookup = (sel, refresh, ttlStrategy) => environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy);
982
1002
  const applyCachePolicy = () => {
983
1003
  return cachePolicyImpl({
984
- buildInMemorySnapshot,
1004
+ buildCachedSnapshot,
985
1005
  buildNetworkSnapshot,
986
1006
  buildSnapshotContext,
987
1007
  resolvePendingSnapshot,
@@ -1,8 +1,9 @@
1
- import { BuildInMemorySnapshot, CachePolicyImplementationArgs, Snapshot, StoreLookup, TTLStrategy, UnAvailableSnapshot } from '@luvio/engine';
1
+ import { BuildCachedSnapshot, CachePolicyImplementationArgs, Snapshot, StoreLookup, TTLStrategy, UnAvailableSnapshot } from '@luvio/engine';
2
2
  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 appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
6
+ export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildCachedSnapshot<C, D>>[1];
7
7
  export declare function buildNetworkSnapshot<C, D>(args: CachePolicyImplementationArgs<C, D>): Promise<Snapshot<D, unknown>>;
8
8
  export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
9
+ export declare function buildAvailableSnapshotFromCachedSnapshotResponse<C, D>(cachedSnapshot: ReturnType<BuildCachedSnapshot<C, D>>, availableSnapshotFunc: (snapshot: Snapshot<D> | undefined) => Snapshot<D> | Promise<Snapshot<D>>): Snapshot<D> | Promise<Snapshot<D>>;
@@ -58,9 +58,13 @@
58
58
  var isArray = Array.isArray;
59
59
 
60
60
  function appendTTLStrategy(storeLookup, ttlStrategy) {
61
- return function (sel, refresh) {
61
+ var returnStoreLookup = function (sel, refresh) {
62
62
  return storeLookup(sel, refresh, ttlStrategy);
63
63
  };
64
+ // append ttlStrategy to storeLookup function (in cases where custom adapter
65
+ // wants to perform it's own lookup)
66
+ returnStoreLookup.ttlStrategy = ttlStrategy;
67
+ return returnStoreLookup;
64
68
  }
65
69
  function buildNetworkSnapshot(args) {
66
70
  var buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, coercedAdapterRequestContext = args.coercedAdapterRequestContext;
@@ -86,102 +90,113 @@
86
90
  }
87
91
  return engine.StoreResolveResultState.Found;
88
92
  };
93
+ }
94
+ // TODO - update userland-facing APIs to return `AvailableSnapshot` instead of `Snapshot`
95
+ // and then the signatures here can be updated as well
96
+ function buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, availableSnapshotFunc) {
97
+ if (isPromise(cachedSnapshot)) {
98
+ return cachedSnapshot.then(availableSnapshotFunc);
99
+ }
100
+ return availableSnapshotFunc(cachedSnapshot);
101
+ }
102
+ function isPromise(value) {
103
+ if (value === undefined) {
104
+ return false;
105
+ }
106
+ // check for Thenable due to test frameworks using custom Promise impls
107
+ return value.then !== undefined;
89
108
  }
90
109
 
91
110
  function buildCacheAndNetworkImplementation(funcs, staleDurationSeconds) {
111
+ if (staleDurationSeconds === void 0) { staleDurationSeconds = 0; }
92
112
  return function (args) {
93
113
  funcs.validateNotDisposed();
94
- var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot$1 = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup, coercedAdapterRequestContext = args.coercedAdapterRequestContext;
95
- var staleDurationMilliseconds = staleDurationSeconds === undefined ? undefined : staleDurationSeconds * 1000;
114
+ var buildCachedSnapshot = args.buildCachedSnapshot, buildNetworkSnapshot$1 = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup, coercedAdapterRequestContext = args.coercedAdapterRequestContext;
115
+ var staleDurationMilliseconds = staleDurationSeconds * 1000;
96
116
  var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationMilliseconds));
97
- var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
98
- if (snapshot !== undefined) {
99
- // data found in L1 cache
100
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
101
- // kick off network request, do not await it
102
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
103
- // return the cached snapshot to caller
104
- return snapshot;
105
- }
106
- // network request outstanding
107
- if (snapshot.state === 'Pending') {
108
- // kick off another network request, do not await it
109
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
110
- return args.resolvePendingSnapshot(snapshot);
111
- }
112
- // stale data found in L1 cache
113
- if (snapshot.state === 'Stale') {
114
- // kick off network request, do not await it
115
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
116
- // return the cached snapshot to caller
117
- return snapshot;
118
- }
119
- // if unfulfilled we have enough info to do an L2 lookup
120
- if (snapshot.state === 'Unfulfilled') {
121
- return funcs
122
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
123
- .then(function (revivedSnapshot) {
124
- // data found in L2 cache
125
- if (revivedSnapshot.state === 'Fulfilled' ||
126
- revivedSnapshot.state === 'Error') {
127
- // kick off network request, do not await it
128
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
129
- // return the L2 cached snapshot to caller
130
- return revivedSnapshot;
131
- }
132
- if (revivedSnapshot.state === 'Pending') {
133
- // kick off network request, do not await it
134
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
135
- return args.resolvePendingSnapshot(revivedSnapshot);
136
- }
137
- // stale data found in L2 cache
138
- if (revivedSnapshot.state === 'Stale') {
139
- // kick off network request, do not await it
140
- buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
141
- // return the L2 cached snapshot to caller
142
- return revivedSnapshot;
143
- }
144
- // data not found in L2 cache, go to the network
145
- return buildNetworkSnapshot(args);
146
- });
117
+ var cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
118
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, function (snapshot) {
119
+ if (snapshot !== undefined) {
120
+ // data found in L1 cache
121
+ if (snapshot.state === 'Fulfilled' ||
122
+ snapshot.state === 'Error' ||
123
+ snapshot.state === 'Stale') {
124
+ // kick off network request, do not await it
125
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
126
+ // return the cached snapshot to caller
127
+ return snapshot;
128
+ }
129
+ // network request outstanding
130
+ if (snapshot.state === 'Pending') {
131
+ // kick off another network request, do not await it
132
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
133
+ return args.resolvePendingSnapshot(snapshot);
134
+ }
135
+ // if unfulfilled we have enough info to do an L2 lookup
136
+ if (snapshot.state === 'Unfulfilled') {
137
+ return funcs
138
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
139
+ .then(function (revivedSnapshot) {
140
+ // data found in L2 cache
141
+ if (revivedSnapshot.state === 'Fulfilled' ||
142
+ revivedSnapshot.state === 'Error' ||
143
+ revivedSnapshot.state === 'Stale') {
144
+ // kick off network request, do not await it
145
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
146
+ // return the L2 cached snapshot to caller
147
+ return revivedSnapshot;
148
+ }
149
+ if (revivedSnapshot.state === 'Pending') {
150
+ // kick off network request, do not await it
151
+ buildNetworkSnapshot$1(buildSnapshotContext, coercedAdapterRequestContext);
152
+ return args.resolvePendingSnapshot(revivedSnapshot);
153
+ }
154
+ // data not found in L2 cache, go to the network
155
+ return buildNetworkSnapshot(args);
156
+ });
157
+ }
147
158
  }
148
- }
149
- return buildNetworkSnapshot(args);
159
+ return buildNetworkSnapshot(args);
160
+ });
150
161
  };
151
162
  }
152
163
 
153
164
  function buildCacheThenNetworkImplementation(funcs) {
154
165
  return function (args) {
155
166
  funcs.validateNotDisposed();
156
- var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
167
+ var buildCachedSnapshot = args.buildCachedSnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
157
168
  var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
158
- var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
159
- if (snapshot !== undefined) {
160
- // data found in L1 cache
161
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
162
- return snapshot;
163
- }
164
- if (snapshot.state === 'Pending') {
165
- return args.resolvePendingSnapshot(snapshot);
166
- }
167
- // data not found in L1 cache, try L2 cache
168
- return funcs
169
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
170
- .then(function (revivedSnapshot) {
171
- // data found in L2 cache
172
- if (revivedSnapshot.state === 'Fulfilled' ||
173
- revivedSnapshot.state === 'Error') {
174
- return revivedSnapshot;
169
+ var cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
170
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, function (snapshot) {
171
+ if (snapshot !== undefined) {
172
+ // data found in L1 cache
173
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
174
+ return snapshot;
175
175
  }
176
- if (revivedSnapshot.state === 'Pending') {
177
- return args.resolvePendingSnapshot(revivedSnapshot);
176
+ if (snapshot.state === 'Pending') {
177
+ return args.resolvePendingSnapshot(snapshot);
178
178
  }
179
- // data not found in L2 cache, go to the network
180
- return buildNetworkSnapshot(args);
181
- });
182
- }
183
- // L1 lookup could not find enough information to even construct a snapshot, go to the network
184
- return buildNetworkSnapshot(args);
179
+ // if unfulfilled we have enough info to do an L2 lookup
180
+ if (snapshot.state === 'Unfulfilled') {
181
+ return funcs
182
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
183
+ .then(function (revivedSnapshot) {
184
+ // data found in L2 cache
185
+ if (revivedSnapshot.state === 'Fulfilled' ||
186
+ revivedSnapshot.state === 'Error') {
187
+ return revivedSnapshot;
188
+ }
189
+ if (revivedSnapshot.state === 'Pending') {
190
+ return args.resolvePendingSnapshot(revivedSnapshot);
191
+ }
192
+ // data not found in L2 cache, go to the network
193
+ return buildNetworkSnapshot(args);
194
+ });
195
+ }
196
+ }
197
+ // L1 lookup could not find enough information to even construct a snapshot, go to the network
198
+ return buildNetworkSnapshot(args);
199
+ });
185
200
  };
186
201
  }
187
202
 
@@ -225,84 +240,90 @@
225
240
  error: error,
226
241
  state: 'Error',
227
242
  data: undefined,
228
- // TODO[@W-10164067]: copy refresh data from the snapshot returned by buildInMemorySnapshot (if any)
243
+ // TODO[@W-10164067]: copy refresh data from the snapshot returned by buildCachedSnapshot (if any)
229
244
  // refresh: ...
230
245
  };
231
246
  }
232
247
  function buildOnlyIfCachedImplementation(funcs) {
233
248
  return function (args) {
234
249
  funcs.validateNotDisposed();
235
- var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
250
+ var buildCachedSnapshot = args.buildCachedSnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
236
251
  var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy());
237
- var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
238
- if (snapshot !== undefined) {
239
- // data found in L1 cache
240
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
241
- return snapshot;
242
- }
243
- // network request outstanding, data is not cached
244
- if (snapshot.state === 'Pending') {
245
- return buildNotCachedErrorSnapshot();
246
- }
247
- // data not found in L1 cache, try L2 cache
248
- return funcs
249
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
250
- .then(function (revivedSnapshot) {
251
- // data found in L2 cache
252
- if (revivedSnapshot.state === 'Fulfilled' ||
253
- revivedSnapshot.state === 'Error') {
254
- return revivedSnapshot;
252
+ var cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
253
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, function (snapshot) {
254
+ if (snapshot !== undefined) {
255
+ // data found in L1 cache
256
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
257
+ return snapshot;
255
258
  }
256
- // data is not cached
257
- return buildNotCachedErrorSnapshot();
258
- });
259
- }
260
- return buildNotCachedErrorSnapshot();
259
+ // network request outstanding, data is not cached
260
+ if (snapshot.state === 'Pending') {
261
+ return buildNotCachedErrorSnapshot();
262
+ }
263
+ // if unfulfilled we have enough info to do an L2 lookup
264
+ if (snapshot.state === 'Unfulfilled') {
265
+ return funcs
266
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
267
+ .then(function (revivedSnapshot) {
268
+ // data found in L2 cache
269
+ if (revivedSnapshot.state === 'Fulfilled' ||
270
+ revivedSnapshot.state === 'Error') {
271
+ return revivedSnapshot;
272
+ }
273
+ // data is not cached
274
+ return buildNotCachedErrorSnapshot();
275
+ });
276
+ }
277
+ }
278
+ return buildNotCachedErrorSnapshot();
279
+ });
261
280
  };
262
281
  }
263
282
 
264
283
  function buildStaleWhileRevalidateImplementation(funcs, staleDurationSeconds) {
265
284
  return function (args) {
266
285
  funcs.validateNotDisposed();
267
- var buildInMemorySnapshot = args.buildInMemorySnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
286
+ var buildCachedSnapshot = args.buildCachedSnapshot, buildSnapshotContext = args.buildSnapshotContext, storeLookup = args.storeLookup;
268
287
  var cachePolicyStoreLookup = appendTTLStrategy(storeLookup, buildTTLStrategy(staleDurationSeconds * 1000));
269
- var snapshot = buildInMemorySnapshot(buildSnapshotContext, cachePolicyStoreLookup);
270
- if (snapshot !== undefined) {
271
- // data found in L1 cache
272
- if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
273
- return snapshot;
274
- }
275
- if (snapshot.state === 'Pending') {
276
- return args.resolvePendingSnapshot(snapshot);
277
- }
278
- // stale data found in L1 cache
279
- if (snapshot.state === 'Stale') {
280
- buildNetworkSnapshot(args);
281
- return snapshot;
282
- }
283
- // data not found in L1 cache, try L2 cache
284
- return funcs
285
- .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
286
- .then(function (revivedSnapshot) {
287
- // data found in L2 cache
288
- if (revivedSnapshot.state === 'Fulfilled' ||
289
- revivedSnapshot.state === 'Error') {
290
- return revivedSnapshot;
288
+ var cachedSnapshot = buildCachedSnapshot(buildSnapshotContext, cachePolicyStoreLookup);
289
+ return buildAvailableSnapshotFromCachedSnapshotResponse(cachedSnapshot, function (snapshot) {
290
+ if (snapshot !== undefined) {
291
+ // data found in L1 cache
292
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
293
+ return snapshot;
291
294
  }
292
- if (revivedSnapshot.state === 'Pending') {
293
- return args.resolvePendingSnapshot(revivedSnapshot);
295
+ if (snapshot.state === 'Pending') {
296
+ return args.resolvePendingSnapshot(snapshot);
294
297
  }
295
- // stale data found in L2 cache
296
- if (revivedSnapshot.state === 'Stale') {
298
+ // stale data found in L1 cache
299
+ if (snapshot.state === 'Stale') {
297
300
  buildNetworkSnapshot(args);
298
- return revivedSnapshot;
301
+ return snapshot;
299
302
  }
300
- // data not found in L2 cache, go to the network
301
- return buildNetworkSnapshot(args);
302
- });
303
- }
304
- // L1 lookup could not find enough information to even construct a snapshot, go to the network
305
- return buildNetworkSnapshot(args);
303
+ // data not found in L1 cache, try L2 cache
304
+ return funcs
305
+ .reviveSnapshotWithCachePolicy(snapshot, cachePolicyStoreLookup)
306
+ .then(function (revivedSnapshot) {
307
+ // data found in L2 cache
308
+ if (revivedSnapshot.state === 'Fulfilled' ||
309
+ revivedSnapshot.state === 'Error') {
310
+ return revivedSnapshot;
311
+ }
312
+ if (revivedSnapshot.state === 'Pending') {
313
+ return args.resolvePendingSnapshot(revivedSnapshot);
314
+ }
315
+ // stale data found in L2 cache
316
+ if (revivedSnapshot.state === 'Stale') {
317
+ buildNetworkSnapshot(args);
318
+ return revivedSnapshot;
319
+ }
320
+ // data not found in L2 cache, go to the network
321
+ return buildNetworkSnapshot(args);
322
+ });
323
+ }
324
+ // L1 lookup could not find enough information to even construct a snapshot, go to the network
325
+ return buildNetworkSnapshot(args);
326
+ });
306
327
  };
307
328
  }
308
329
 
@@ -313,7 +334,7 @@
313
334
  // TTLStrategy to use the the valid-at cache policy's timestamp. The flow goes:
314
335
  //
315
336
  // Environment.applyCachePolicy => validAtImplementation (this function) =>
316
- // basePolicyImplementation => adapter's buildInMemorySnapshot =>
337
+ // basePolicyImplementation => adapter's buildCachedSnapshot =>
317
338
  // basePolicyImplementation's storeLookup => validAtStoreLookup (below) =>
318
339
  // Environment.applyCachePolicy's storeLookup => Store/Reader code =>
319
340
  // valid-at TTLStrategy (below) =>
@@ -854,7 +875,7 @@
854
875
  if (ingestStagingStore !== null) {
855
876
  return ingestStagingStore.lookup(sel, createSnapshot, refresh, ttlStrategy);
856
877
  }
857
- // otherwise this is from buildInMemorySnapshot and we should use the luvio
878
+ // otherwise this is from buildCachedSnapshot and we should use the luvio
858
879
  // L1 store
859
880
  return environment.storeLookup(sel, createSnapshot, refresh, ttlStrategy);
860
881
  };
@@ -1018,7 +1039,7 @@
1018
1039
  }
1019
1040
  }
1020
1041
  }
1021
- var applyCachePolicy = function (adapterRequestContext, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
1042
+ var applyCachePolicy = function (adapterRequestContext, buildSnapshotContext, buildCachedSnapshot, buildNetworkSnapshot) {
1022
1043
  validateNotDisposed();
1023
1044
  var cachePolicy = adapterRequestContext.cachePolicy;
1024
1045
  var cachePolicyImpl = resolveCachePolicy(cachePolicy);
@@ -1028,7 +1049,7 @@
1028
1049
  var storeLookup = function (sel, refresh, ttlStrategy) { return environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy); };
1029
1050
  var applyCachePolicy = function () {
1030
1051
  return cachePolicyImpl({
1031
- buildInMemorySnapshot: buildInMemorySnapshot,
1052
+ buildCachedSnapshot: buildCachedSnapshot,
1032
1053
  buildNetworkSnapshot: buildNetworkSnapshot,
1033
1054
  buildSnapshotContext: buildSnapshotContext,
1034
1055
  resolvePendingSnapshot: resolvePendingSnapshot,
@@ -1,8 +1,9 @@
1
- import { BuildInMemorySnapshot, CachePolicyImplementationArgs, Snapshot, StoreLookup, TTLStrategy, UnAvailableSnapshot } from '@luvio/engine';
1
+ import { BuildCachedSnapshot, CachePolicyImplementationArgs, Snapshot, StoreLookup, TTLStrategy, UnAvailableSnapshot } from '@luvio/engine';
2
2
  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 appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildInMemorySnapshot<C, D>>[1];
6
+ export declare function appendTTLStrategy<C, D>(storeLookup: CachePolicyImplementationArgs<C, D>['storeLookup'], ttlStrategy: TTLStrategy): Parameters<BuildCachedSnapshot<C, D>>[1];
7
7
  export declare function buildNetworkSnapshot<C, D>(args: CachePolicyImplementationArgs<C, D>): Promise<Snapshot<D, unknown>>;
8
8
  export declare function buildTTLStrategy(staleDurationMilliseconds?: number): TTLStrategy;
9
+ export declare function buildAvailableSnapshotFromCachedSnapshotResponse<C, D>(cachedSnapshot: ReturnType<BuildCachedSnapshot<C, D>>, availableSnapshotFunc: (snapshot: Snapshot<D> | undefined) => Snapshot<D> | Promise<Snapshot<D>>): Snapshot<D> | Promise<Snapshot<D>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luvio/environments",
3
- "version": "0.70.0",
3
+ "version": "0.71.0",
4
4
  "description": "Luvio Environments",
5
5
  "main": "dist/umd/es2018/environments.js",
6
6
  "module": "dist/es/es2018/environments.js",
@@ -26,6 +26,6 @@
26
26
  "dist/"
27
27
  ],
28
28
  "dependencies": {
29
- "@luvio/engine": "0.70.0"
29
+ "@luvio/engine": "0.71.0"
30
30
  }
31
31
  }