@luvio/environments 0.52.0 → 0.55.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/DurableTTLStore.d.ts +25 -0
- package/dist/es/es2018/environments.js +227 -26
- package/dist/es/es2018/main.d.ts +2 -0
- package/dist/es/es2018/makeDurable/cachepolicy.d.ts +2 -0
- package/dist/es/es2018/makeDurable/flush.d.ts +4 -0
- package/dist/es/es2018/makeDurable/refresh.d.ts +2 -2
- package/dist/es/es2018/makeDurable/revive.d.ts +14 -3
- package/dist/es/es2018/makeDurable/utils.d.ts +2 -0
- package/dist/es/es2018/makeDurable.d.ts +5 -0
- package/dist/umd/es2018/DurableTTLStore.d.ts +25 -0
- package/dist/umd/es2018/environments.js +229 -29
- package/dist/umd/es2018/main.d.ts +2 -0
- package/dist/umd/es2018/makeDurable/cachepolicy.d.ts +2 -0
- package/dist/umd/es2018/makeDurable/flush.d.ts +4 -0
- package/dist/umd/es2018/makeDurable/refresh.d.ts +2 -2
- package/dist/umd/es2018/makeDurable/revive.d.ts +14 -3
- package/dist/umd/es2018/makeDurable/utils.d.ts +2 -0
- package/dist/umd/es2018/makeDurable.d.ts +5 -0
- package/dist/umd/es5/DurableTTLStore.d.ts +25 -0
- package/dist/umd/es5/environments.js +235 -29
- package/dist/umd/es5/main.d.ts +2 -0
- package/dist/umd/es5/makeDurable/cachepolicy.d.ts +2 -0
- package/dist/umd/es5/makeDurable/flush.d.ts +4 -0
- package/dist/umd/es5/makeDurable/refresh.d.ts +2 -2
- package/dist/umd/es5/makeDurable/revive.d.ts +14 -3
- package/dist/umd/es5/makeDurable/utils.d.ts +2 -0
- package/dist/umd/es5/makeDurable.d.ts +5 -0
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = global || self, factory(global.luvioEnvironments = {}));
|
|
5
|
-
}(this, (function (exports) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@luvio/engine')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@luvio/engine'], factory) :
|
|
4
|
+
(global = global || self, factory(global.luvioEnvironments = {}, global.luvioEngine));
|
|
5
|
+
}(this, (function (exports, engine) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
8
8
|
if (durableRecord.expiration !== undefined) {
|
|
@@ -55,6 +55,53 @@
|
|
|
55
55
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
56
56
|
var isArray = Array.isArray;
|
|
57
57
|
|
|
58
|
+
// cache policy implementations
|
|
59
|
+
function buildTTLStrategy(staleDuration) {
|
|
60
|
+
if (staleDuration === void 0) { staleDuration = 0; }
|
|
61
|
+
return function (timestamp, metadata, valueIsError) {
|
|
62
|
+
if (metadata !== undefined) {
|
|
63
|
+
var expirationTimestamp = metadata.expirationTimestamp;
|
|
64
|
+
if (timestamp > expirationTimestamp) {
|
|
65
|
+
if (timestamp <= expirationTimestamp + staleDuration && valueIsError !== true) {
|
|
66
|
+
return engine.StoreResolveResultState.Stale;
|
|
67
|
+
}
|
|
68
|
+
return engine.StoreResolveResultState.NotPresent;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (valueIsError === true) {
|
|
72
|
+
return engine.StoreResolveResultState.Error;
|
|
73
|
+
}
|
|
74
|
+
return engine.StoreResolveResultState.Found;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function appendTTLStrategy(storeLookup, ttlStrategy) {
|
|
78
|
+
return function (sel, refresh) {
|
|
79
|
+
return storeLookup(sel, refresh, ttlStrategy);
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function buildStaleWhileRevalidateImplementation(validateNotDisposed, resolveSnapshot, staleDuration) {
|
|
83
|
+
return function (args) {
|
|
84
|
+
validateNotDisposed();
|
|
85
|
+
var buildInMemorySnapshot = args.buildInMemorySnapshot, buildNetworkSnapshot = args.buildNetworkSnapshot, buildSnapshotContext = args.buildSnapshotContext, dispatchResourceRequest = args.dispatchResourceRequest, storeLookup = args.storeLookup;
|
|
86
|
+
var snapshot = buildInMemorySnapshot(buildSnapshotContext, appendTTLStrategy(storeLookup, buildTTLStrategy(staleDuration)));
|
|
87
|
+
if (snapshot !== undefined) {
|
|
88
|
+
if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
|
|
89
|
+
return snapshot;
|
|
90
|
+
}
|
|
91
|
+
if (snapshot.state === 'Stale') {
|
|
92
|
+
// offline environment is already doing this; uncomment once we get rid of offline environment
|
|
93
|
+
// buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
94
|
+
return snapshot;
|
|
95
|
+
}
|
|
96
|
+
return resolveSnapshot(snapshot, {
|
|
97
|
+
resolve: function () { return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest); },
|
|
98
|
+
config: undefined,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
58
105
|
//Durable store error instrumentation key
|
|
59
106
|
var DURABLE_STORE_ERROR = 'durable-store-error';
|
|
60
107
|
/**
|
|
@@ -244,8 +291,7 @@
|
|
|
244
291
|
}
|
|
245
292
|
promiseResolve(resolvedSnapshot);
|
|
246
293
|
});
|
|
247
|
-
|
|
248
|
-
resolve(config)
|
|
294
|
+
refresh()
|
|
249
295
|
.then(function (refreshedSnapshot) {
|
|
250
296
|
// if error, just return it, because there won't be a L2 flush/broadcast/rebuild
|
|
251
297
|
// (non-cached errors don't broadcast, and subscribing to an error snapshot
|
|
@@ -287,11 +333,23 @@
|
|
|
287
333
|
|
|
288
334
|
function isStoreEntryError(storeRecord) {
|
|
289
335
|
return storeRecord.__type === 'error';
|
|
290
|
-
}
|
|
336
|
+
}
|
|
337
|
+
|
|
291
338
|
function isStoreEntryExpiredAndError(storeRecord, expirationTimestamp, now) {
|
|
292
339
|
return isStoreEntryError(storeRecord) && expirationTimestamp < now;
|
|
293
340
|
}
|
|
294
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Takes a set of entries from DurableStore and publishes them via the passed in funcs.
|
|
343
|
+
* This respects expiration and checks for valid DurableStore data shapes. This should
|
|
344
|
+
* be used over manually parsing DurableStoreEntries
|
|
345
|
+
*
|
|
346
|
+
* @param durableRecords The DurableStoreEntries to parse
|
|
347
|
+
* @param publish A function to call with the data of each DurableStoreEntry
|
|
348
|
+
* @param publishMetadata A function to call with the metadata of each DurableStoreEntry
|
|
349
|
+
* @param pendingWriter the PendingWriter (this is going away soon)
|
|
350
|
+
* @returns
|
|
351
|
+
*/
|
|
352
|
+
function publishDurableStoreEntries(durableRecords, publish, publishMetadata, pendingWriter) {
|
|
295
353
|
var revivedKeys = create(null);
|
|
296
354
|
var hadUnexpectedShape = false;
|
|
297
355
|
if (durableRecords === undefined) {
|
|
@@ -319,13 +377,13 @@
|
|
|
319
377
|
}
|
|
320
378
|
if (metadata !== undefined) {
|
|
321
379
|
var expirationTimestamp = metadata.expirationTimestamp, staleTimestamp = metadata.staleTimestamp;
|
|
322
|
-
if (expirationTimestamp === undefined
|
|
380
|
+
if (expirationTimestamp === undefined) {
|
|
323
381
|
// if unexpected expiration data skip reviving
|
|
324
382
|
hadUnexpectedShape = true;
|
|
325
383
|
continue;
|
|
326
384
|
}
|
|
327
385
|
// if past stale TTL then don't revive
|
|
328
|
-
if (staleTimestamp < now) {
|
|
386
|
+
if (staleTimestamp !== undefined && staleTimestamp < now) {
|
|
329
387
|
continue;
|
|
330
388
|
}
|
|
331
389
|
// We don't want to revive a cached value if it's an error and it's
|
|
@@ -340,8 +398,7 @@
|
|
|
340
398
|
if (isStoreEntryExpiredAndError(data, expirationTimestamp, now)) {
|
|
341
399
|
continue;
|
|
342
400
|
}
|
|
343
|
-
|
|
344
|
-
environment.publishStoreMetadata(key, metadata);
|
|
401
|
+
publishMetadata(key, metadata);
|
|
345
402
|
}
|
|
346
403
|
if (isStoreEntryError(data)) {
|
|
347
404
|
// freeze errors on way into L1
|
|
@@ -351,8 +408,7 @@
|
|
|
351
408
|
// Note: this won't affect ingest (which ingests to L1 temporarily then
|
|
352
409
|
// flushes to L2) because that path is synchronous and atomic.
|
|
353
410
|
pendingWriter.removePendingWrite(key);
|
|
354
|
-
|
|
355
|
-
environment.storePublish(key, data);
|
|
411
|
+
publish(key, data);
|
|
356
412
|
revivedKeys[key] = true;
|
|
357
413
|
}
|
|
358
414
|
return { revivedKeys: revivedKeys, hadUnexpectedShape: hadUnexpectedShape };
|
|
@@ -364,14 +420,14 @@
|
|
|
364
420
|
* will refresh the snapshot from network, and then run the results from network
|
|
365
421
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
366
422
|
*/
|
|
367
|
-
function reviveSnapshot(
|
|
423
|
+
function reviveSnapshot(baseEnvironment, durableStore, pendingWriter, unavailableSnapshot, refresh, durableStoreErrorHandler, baseSnapshot) {
|
|
368
424
|
var _a;
|
|
369
425
|
var recordId = unavailableSnapshot.recordId, select = unavailableSnapshot.select, seenRecords = unavailableSnapshot.seenRecords, state = unavailableSnapshot.state;
|
|
370
426
|
// on rebuilds return the network snapshot on L2 miss
|
|
371
427
|
var refreshSnapshot = baseSnapshot !== undefined
|
|
372
428
|
? function () {
|
|
373
429
|
if (baseSnapshot.state !== 'Pending') {
|
|
374
|
-
return refresh
|
|
430
|
+
return refresh();
|
|
375
431
|
}
|
|
376
432
|
// A Pending snapshot could be in the store awaiting either a result
|
|
377
433
|
// from the network or L2. If another ingest brings in an overlapping key
|
|
@@ -384,17 +440,17 @@
|
|
|
384
440
|
}
|
|
385
441
|
// track the refresh operation to ensure no other refreshes kick off while in flight
|
|
386
442
|
snapshotRefreshMap.add(baseSnapshot);
|
|
387
|
-
return refresh
|
|
443
|
+
return refresh().finally(function () {
|
|
388
444
|
snapshotRefreshMap.delete(baseSnapshot);
|
|
389
445
|
});
|
|
390
446
|
}
|
|
391
|
-
: buildDurableStoreAwareRefresh(refresh, unavailableSnapshot,
|
|
447
|
+
: buildDurableStoreAwareRefresh(refresh, unavailableSnapshot, baseEnvironment, pendingWriter);
|
|
392
448
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
393
449
|
// info needed to revive (like missingLinks) and rebuild. Otherwise refresh.
|
|
394
450
|
if (state !== 'Unfulfilled' || select === undefined) {
|
|
395
451
|
return refreshSnapshot();
|
|
396
452
|
}
|
|
397
|
-
// in case L1
|
|
453
|
+
// in case L1 store changes/deallocs a record while we are doing the async read
|
|
398
454
|
// we attempt to read all keys from L2 - so combine recordId with any seenRecords
|
|
399
455
|
var keysToReviveSet = assign((_a = {}, _a[recordId] = true, _a), seenRecords);
|
|
400
456
|
var keysToRevive = keys(keysToReviveSet);
|
|
@@ -403,10 +459,10 @@
|
|
|
403
459
|
var paginationKey = paginationKeys[i];
|
|
404
460
|
keysToRevive.push(paginationKey);
|
|
405
461
|
}
|
|
406
|
-
var canonicalKeys = keysToRevive.map(function (x) { return
|
|
462
|
+
var canonicalKeys = keysToRevive.map(function (x) { return baseEnvironment.storeGetCanonicalKey(x); });
|
|
407
463
|
return durableStore.getEntries(canonicalKeys, DefaultDurableSegment).then(function (durableRecords) {
|
|
408
464
|
var _a;
|
|
409
|
-
var _b =
|
|
465
|
+
var _b = publishDurableStoreEntries(durableRecords, baseEnvironment.storePublish.bind(baseEnvironment), baseEnvironment.publishStoreMetadata.bind(baseEnvironment), pendingWriter), revivedKeys = _b.revivedKeys, hadUnexpectedShape = _b.hadUnexpectedShape;
|
|
410
466
|
// if the data coming back from DS had an unexpected shape then refresh
|
|
411
467
|
// data from network
|
|
412
468
|
if (hadUnexpectedShape === true) {
|
|
@@ -419,8 +475,8 @@
|
|
|
419
475
|
// attempt to lookup (or rebuild if baseSnapshot is provided) the snapshot
|
|
420
476
|
// now that we have revived the missingLinks
|
|
421
477
|
var snapshot = baseSnapshot === undefined
|
|
422
|
-
?
|
|
423
|
-
:
|
|
478
|
+
? baseEnvironment.storeLookup(unavailableSnapshot.select, baseEnvironment.createSnapshot, unavailableSnapshot.refresh)
|
|
479
|
+
: baseEnvironment.rebuildSnapshot(baseSnapshot, baseEnvironment.getStoreRecords(), baseEnvironment.getStoreMetadataMap(), baseEnvironment.getStoreRedirectKeys(), function () { });
|
|
424
480
|
// if snapshot is pending then some other in-flight refresh will broadcast
|
|
425
481
|
// later
|
|
426
482
|
if (snapshot.state === 'Pending') {
|
|
@@ -440,13 +496,13 @@
|
|
|
440
496
|
for (var i = 0, len = newKeys.length; i < len; i++) {
|
|
441
497
|
var newSnapshotSeenKey = newKeys[i];
|
|
442
498
|
if (alreadyRequestedOrRevivedSet[newSnapshotSeenKey] !== true) {
|
|
443
|
-
return reviveSnapshot(
|
|
499
|
+
return reviveSnapshot(baseEnvironment, durableStore, pendingWriter, snapshot, refresh, durableStoreErrorHandler, baseSnapshot);
|
|
444
500
|
}
|
|
445
501
|
}
|
|
446
502
|
// otherwise it's an L2 cache miss, so refresh
|
|
447
503
|
return refreshSnapshot();
|
|
448
504
|
}
|
|
449
|
-
if (
|
|
505
|
+
if (baseEnvironment.snapshotAvailable(snapshot)) {
|
|
450
506
|
return snapshot;
|
|
451
507
|
}
|
|
452
508
|
// all other scenarios we just refresh
|
|
@@ -458,6 +514,86 @@
|
|
|
458
514
|
});
|
|
459
515
|
}
|
|
460
516
|
|
|
517
|
+
var TTL_DURABLE_SEGMENT = 'TTL_DURABLE_SEGMENT';
|
|
518
|
+
var TTL_DEFAULT_KEY = 'TTL_DEFAULT_KEY';
|
|
519
|
+
function buildDurableTTLOverrideStoreKey(namespace, representationName) {
|
|
520
|
+
return namespace + "::" + representationName;
|
|
521
|
+
}
|
|
522
|
+
function isEntryDurableTTLOverride(entry) {
|
|
523
|
+
if (typeof entry === 'object' && entry !== undefined && entry !== null) {
|
|
524
|
+
var data = entry.data;
|
|
525
|
+
if (data !== undefined) {
|
|
526
|
+
return (data.namespace !== undefined &&
|
|
527
|
+
data.representationName !== undefined &&
|
|
528
|
+
data.ttl !== undefined);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
function isDefaultDurableTTLOverride(override) {
|
|
534
|
+
return (override.namespace === TTL_DEFAULT_KEY && override.representationName === TTL_DEFAULT_KEY);
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Class to set and get the TTL override values in the Durable Store
|
|
538
|
+
*/
|
|
539
|
+
var DurableTTLStore = /** @class */ (function () {
|
|
540
|
+
function DurableTTLStore(durableStore) {
|
|
541
|
+
this.durableStore = durableStore;
|
|
542
|
+
}
|
|
543
|
+
DurableTTLStore.prototype.setDefaultDurableTTLOverrides = function (ttl) {
|
|
544
|
+
var _a;
|
|
545
|
+
return this.durableStore.setEntries((_a = {},
|
|
546
|
+
_a[buildDurableTTLOverrideStoreKey(TTL_DEFAULT_KEY, TTL_DEFAULT_KEY)] = {
|
|
547
|
+
data: {
|
|
548
|
+
namespace: TTL_DEFAULT_KEY,
|
|
549
|
+
representationName: TTL_DEFAULT_KEY,
|
|
550
|
+
ttl: ttl,
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
_a), TTL_DURABLE_SEGMENT);
|
|
554
|
+
};
|
|
555
|
+
DurableTTLStore.prototype.setDurableTTLOverride = function (namespace, representationName, ttl) {
|
|
556
|
+
var _a;
|
|
557
|
+
return this.durableStore.setEntries((_a = {},
|
|
558
|
+
_a[buildDurableTTLOverrideStoreKey(namespace, representationName)] = {
|
|
559
|
+
data: { namespace: namespace, representationName: representationName, ttl: ttl },
|
|
560
|
+
},
|
|
561
|
+
_a), TTL_DURABLE_SEGMENT);
|
|
562
|
+
};
|
|
563
|
+
DurableTTLStore.prototype.getDurableTTLOverrides = function () {
|
|
564
|
+
return this.durableStore
|
|
565
|
+
.getAllEntries(TTL_DURABLE_SEGMENT)
|
|
566
|
+
.then(function (entries) {
|
|
567
|
+
var overrides = [];
|
|
568
|
+
var defaultTTL = undefined;
|
|
569
|
+
if (entries === undefined) {
|
|
570
|
+
return {
|
|
571
|
+
defaultTTL: defaultTTL,
|
|
572
|
+
overrides: overrides,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
var keys$1 = keys(entries);
|
|
576
|
+
for (var i = 0, len = keys$1.length; i < len; i++) {
|
|
577
|
+
var key = keys$1[i];
|
|
578
|
+
var entry = entries[key];
|
|
579
|
+
if (entry !== undefined && isEntryDurableTTLOverride(entry)) {
|
|
580
|
+
if (isDefaultDurableTTLOverride(entry.data)) {
|
|
581
|
+
defaultTTL = entry.data;
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
overrides.push(entry.data);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return {
|
|
589
|
+
defaultTTL: defaultTTL,
|
|
590
|
+
overrides: overrides,
|
|
591
|
+
};
|
|
592
|
+
});
|
|
593
|
+
};
|
|
594
|
+
return DurableTTLStore;
|
|
595
|
+
}());
|
|
596
|
+
|
|
461
597
|
var AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
462
598
|
var ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
463
599
|
function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, onContextLoaded) {
|
|
@@ -505,6 +641,7 @@
|
|
|
505
641
|
*/
|
|
506
642
|
function makeDurable(environment, _a) {
|
|
507
643
|
var durableStore = _a.durableStore, instrumentation = _a.instrumentation, _b = _a.pendingWriter, pendingWriter = _b === void 0 ? buildPendingWriter() : _b;
|
|
644
|
+
var durableTTLStore = new DurableTTLStore(durableStore);
|
|
508
645
|
//instrumentation for durable store errors
|
|
509
646
|
var durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
|
|
510
647
|
var disposed = false;
|
|
@@ -565,6 +702,19 @@
|
|
|
565
702
|
pendingWriter.addPendingWrite(recordId);
|
|
566
703
|
environment.publishStoreMetadata(recordId, storeMetadata);
|
|
567
704
|
};
|
|
705
|
+
var storeIngestError = function (key, errorSnapshot, storeMetadataParams, _storeOverride) {
|
|
706
|
+
validateNotDisposed();
|
|
707
|
+
// TODO [W-9680660]: this will get cleaned up in next PR to use staging store
|
|
708
|
+
var store = {
|
|
709
|
+
publish: function (key, data) {
|
|
710
|
+
storePublish(key, data);
|
|
711
|
+
},
|
|
712
|
+
publishMetadata: function (key, storeMetadata) {
|
|
713
|
+
publishStoreMetadata(key, storeMetadata);
|
|
714
|
+
},
|
|
715
|
+
};
|
|
716
|
+
environment.storeIngestError(key, errorSnapshot, storeMetadataParams, store);
|
|
717
|
+
};
|
|
568
718
|
var storeBroadcast = function (_rebuildSnapshot, _snapshotDataAvailable) {
|
|
569
719
|
// don't await the DS write - DS implementation will take care of R/W
|
|
570
720
|
// synchronization
|
|
@@ -597,7 +747,9 @@
|
|
|
597
747
|
if (snapshot.state === 'Pending') {
|
|
598
748
|
return environment.resolvePendingSnapshot(snapshot);
|
|
599
749
|
}
|
|
600
|
-
|
|
750
|
+
var resolve = refresh.resolve, config = refresh.config;
|
|
751
|
+
var refreshFunc = function () { return resolve(config); };
|
|
752
|
+
return reviveSnapshot(environment, durableStore, pendingWriter, snapshot, refreshFunc, durableStoreErrorHandler);
|
|
601
753
|
};
|
|
602
754
|
var rebuildSnapshot = function (snapshot, records, storeMetadataMap, redirects, onAsyncRebuild) {
|
|
603
755
|
validateNotDisposed();
|
|
@@ -613,9 +765,11 @@
|
|
|
613
765
|
if (refresh === undefined) {
|
|
614
766
|
return rebuilt;
|
|
615
767
|
}
|
|
768
|
+
var resolve = refresh.resolve, config = refresh.config;
|
|
769
|
+
var refreshFunc = function () { return resolve(config); };
|
|
616
770
|
// Do an L2 revive (which will refresh from network on L2 miss) and if
|
|
617
771
|
// it results in an available snapshot emit to subscriber using the callback.
|
|
618
|
-
reviveSnapshot(environment, durableStore, pendingWriter, rebuilt,
|
|
772
|
+
reviveSnapshot(environment, durableStore, pendingWriter, rebuilt, refreshFunc, durableStoreErrorHandler, snapshot).then(function (revivedSnapshot) {
|
|
619
773
|
if (environment.snapshotAvailable(revivedSnapshot) === true) {
|
|
620
774
|
onAsyncRebuild(revivedSnapshot);
|
|
621
775
|
}
|
|
@@ -659,19 +813,67 @@
|
|
|
659
813
|
return result;
|
|
660
814
|
});
|
|
661
815
|
};
|
|
816
|
+
var storeSetTTLOverride = function (namespace, representationName, ttl) {
|
|
817
|
+
validateNotDisposed();
|
|
818
|
+
durableTTLStore.setDurableTTLOverride(namespace, representationName, ttl);
|
|
819
|
+
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
820
|
+
};
|
|
821
|
+
var storeSetDefaultTTLOverride = function (ttl) {
|
|
822
|
+
validateNotDisposed();
|
|
823
|
+
durableTTLStore.setDefaultDurableTTLOverrides(ttl);
|
|
824
|
+
environment.storeSetDefaultTTLOverride(ttl);
|
|
825
|
+
};
|
|
826
|
+
var getDurableTTLOverrides = function () {
|
|
827
|
+
validateNotDisposed();
|
|
828
|
+
return durableTTLStore.getDurableTTLOverrides();
|
|
829
|
+
};
|
|
830
|
+
var defaultCachePolicy = buildStaleWhileRevalidateImplementation(validateNotDisposed, resolveSnapshot, Number.MAX_SAFE_INTEGER);
|
|
831
|
+
function resolveCachePolicy(cachePolicy, defaultCachePolicy) {
|
|
832
|
+
if (cachePolicy === undefined) {
|
|
833
|
+
return defaultCachePolicy;
|
|
834
|
+
}
|
|
835
|
+
switch (cachePolicy.type) {
|
|
836
|
+
case 'stale-while-revalidate':
|
|
837
|
+
return buildStaleWhileRevalidateImplementation(validateNotDisposed, resolveSnapshot, cachePolicy.staleDuration);
|
|
838
|
+
default: {
|
|
839
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
840
|
+
throw new Error("unrecognized cache policy: " + JSON.stringify(cachePolicy));
|
|
841
|
+
}
|
|
842
|
+
return defaultCachePolicy;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
var applyCachePolicy = function (cachePolicy, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
|
|
847
|
+
validateNotDisposed();
|
|
848
|
+
var cachePolicyImpl = resolveCachePolicy(cachePolicy, defaultCachePolicy);
|
|
849
|
+
var storeLookup = function (sel, refresh, ttlStrategy) { return environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy); };
|
|
850
|
+
return cachePolicyImpl({
|
|
851
|
+
buildInMemorySnapshot: buildInMemorySnapshot,
|
|
852
|
+
buildNetworkSnapshot: buildNetworkSnapshot,
|
|
853
|
+
buildSnapshotContext: buildSnapshotContext,
|
|
854
|
+
storeLookup: storeLookup,
|
|
855
|
+
dispatchResourceRequest: dispatchResourceRequest,
|
|
856
|
+
});
|
|
857
|
+
};
|
|
662
858
|
return create(environment, {
|
|
663
859
|
publishStoreMetadata: { value: publishStoreMetadata },
|
|
860
|
+
storeIngestError: { value: storeIngestError },
|
|
664
861
|
storeBroadcast: { value: storeBroadcast },
|
|
665
862
|
storeReset: { value: storeReset },
|
|
666
863
|
resolveSnapshot: { value: resolveSnapshot },
|
|
667
864
|
storeEvict: { value: storeEvict },
|
|
668
865
|
withContext: { value: withContext },
|
|
669
866
|
rebuildSnapshot: { value: rebuildSnapshot },
|
|
867
|
+
storeSetTTLOverride: { value: storeSetTTLOverride },
|
|
868
|
+
storeSetDefaultTTLOverride: { value: storeSetDefaultTTLOverride },
|
|
670
869
|
storePublish: { value: storePublish },
|
|
671
870
|
storeRedirect: { value: storeRedirect },
|
|
672
871
|
dispatchResourceRequest: { value: dispatchResourceRequest },
|
|
673
872
|
dispose: { value: dispose },
|
|
674
873
|
publishChangesToDurableStore: { value: publishChangesToDurableStore },
|
|
874
|
+
getDurableTTLOverrides: { value: getDurableTTLOverrides },
|
|
875
|
+
defaultCachePolicy: { value: defaultCachePolicy },
|
|
876
|
+
applyCachePolicy: { value: applyCachePolicy },
|
|
675
877
|
});
|
|
676
878
|
}
|
|
677
879
|
|
|
@@ -687,8 +889,8 @@
|
|
|
687
889
|
* cause a network refresh to happen).
|
|
688
890
|
*/
|
|
689
891
|
function makeOffline(environment) {
|
|
690
|
-
var storeLookup = function (sel, createSnapshot, refresh) {
|
|
691
|
-
var snapshot = environment.storeLookup(sel, createSnapshot, refresh);
|
|
892
|
+
var storeLookup = function (sel, createSnapshot, refresh, ttlStrategy) {
|
|
893
|
+
var snapshot = environment.storeLookup(sel, createSnapshot, refresh, ttlStrategy);
|
|
692
894
|
// if the snapshot is stale we want to kick off a refresh
|
|
693
895
|
if (snapshot.state === 'Stale') {
|
|
694
896
|
if (refresh !== undefined) {
|
|
@@ -708,6 +910,9 @@
|
|
|
708
910
|
environment.publishStoreMetadata(recordId, __assign(__assign({}, storeMetadata), { staleTimestamp: Number.MAX_SAFE_INTEGER }));
|
|
709
911
|
};
|
|
710
912
|
return create(environment, {
|
|
913
|
+
defaultCachePolicy: {
|
|
914
|
+
value: engine.buildStaleWhileRevalidateImplementation(Number.MAX_SAFE_INTEGER),
|
|
915
|
+
},
|
|
711
916
|
storeLookup: { value: storeLookup },
|
|
712
917
|
snapshotAvailable: {
|
|
713
918
|
value: snapshotAvailable,
|
|
@@ -721,6 +926,7 @@
|
|
|
721
926
|
exports.DefaultDurableSegment = DefaultDurableSegment;
|
|
722
927
|
exports.makeDurable = makeDurable;
|
|
723
928
|
exports.makeOffline = makeOffline;
|
|
929
|
+
exports.publishDurableStoreEntries = publishDurableStoreEntries;
|
|
724
930
|
|
|
725
931
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
726
932
|
|
package/dist/umd/es5/main.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { DurableStore, DurableStoreEntries, DurableStoreEntry, DurableStoreChange, OnDurableStoreChangedListener, DefaultDurableSegment, DurableStoreOperation, DurableStoreOperationType, } from './DurableStore';
|
|
2
|
+
export { DurableTTLOverride, DefaultDurableTTLOverride } from './DurableTTLStore';
|
|
2
3
|
export { makeDurable, DurableEnvironment } from './makeDurable';
|
|
4
|
+
export { publishDurableStoreEntries } from './makeDurable/revive';
|
|
3
5
|
export { makeOffline } from './makeOffline';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { CachePolicyImplementationArgs, Environment, Snapshot } from '@luvio/engine';
|
|
2
|
+
export declare function buildStaleWhileRevalidateImplementation(validateNotDisposed: () => void, resolveSnapshot: Environment['resolveSnapshot'], staleDuration: 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,4 @@
|
|
|
1
|
+
import { Store } from '@luvio/engine';
|
|
2
|
+
import { DurableStore } from '../DurableStore';
|
|
3
|
+
import { DurableStoreRejectionHandler } from './error';
|
|
4
|
+
export declare function flushStoreValuesToDurableStore(store: Store, durableStore: DurableStore, durableStoreErrorHandler: DurableStoreRejectionHandler): Promise<void>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Environment, Snapshot,
|
|
1
|
+
import { Environment, Snapshot, UnAvailableSnapshot } from '@luvio/engine';
|
|
2
2
|
import { PendingWriter } from './pendingWriter';
|
|
3
|
-
export declare function buildDurableStoreAwareRefresh<ResponseType>(refresh:
|
|
3
|
+
export declare function buildDurableStoreAwareRefresh<ResponseType, V = unknown>(refresh: () => Promise<Snapshot<ResponseType, V>>, snapshot: UnAvailableSnapshot<ResponseType, V>, environment: Environment, pendingWriter: PendingWriter): () => Promise<Snapshot<ResponseType, V>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Environment,
|
|
1
|
+
import { Environment, Snapshot, UnAvailableSnapshot, DataSnapshot, StoreMetadata } from '@luvio/engine';
|
|
2
2
|
import { DurableStore, DurableStoreEntries } from '../DurableStore';
|
|
3
3
|
import { DurableStoreRejectionHandler } from './error';
|
|
4
4
|
import { PendingWriter } from './pendingWriter';
|
|
@@ -9,12 +9,23 @@ declare type ReviveResponse = {
|
|
|
9
9
|
revivedKeys: ObjectAsSet;
|
|
10
10
|
hadUnexpectedShape: boolean;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Takes a set of entries from DurableStore and publishes them via the passed in funcs.
|
|
14
|
+
* This respects expiration and checks for valid DurableStore data shapes. This should
|
|
15
|
+
* be used over manually parsing DurableStoreEntries
|
|
16
|
+
*
|
|
17
|
+
* @param durableRecords The DurableStoreEntries to parse
|
|
18
|
+
* @param publish A function to call with the data of each DurableStoreEntry
|
|
19
|
+
* @param publishMetadata A function to call with the metadata of each DurableStoreEntry
|
|
20
|
+
* @param pendingWriter the PendingWriter (this is going away soon)
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
export declare function publishDurableStoreEntries(durableRecords: DurableStoreEntries<unknown> | undefined, publish: (key: string, record: unknown) => void, publishMetadata: (key: string, metadata: StoreMetadata) => void, pendingWriter: PendingWriter): ReviveResponse;
|
|
13
24
|
/**
|
|
14
25
|
* This method returns a Promise to a snapshot that is revived from L2 cache. If
|
|
15
26
|
* L2 does not have the entries necessary to fulfill the snapshot then this method
|
|
16
27
|
* will refresh the snapshot from network, and then run the results from network
|
|
17
28
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
18
29
|
*/
|
|
19
|
-
export declare function reviveSnapshot<D>(
|
|
30
|
+
export declare function reviveSnapshot<D, V = unknown>(baseEnvironment: Environment, durableStore: DurableStore, pendingWriter: PendingWriter, unavailableSnapshot: UnAvailableSnapshot<D, V>, refresh: () => Promise<Snapshot<D, V>>, durableStoreErrorHandler: DurableStoreRejectionHandler, baseSnapshot?: DataSnapshot<D, V>): Promise<Snapshot<D, V>>;
|
|
20
31
|
export {};
|
|
@@ -2,6 +2,7 @@ import { Environment } from '@luvio/engine';
|
|
|
2
2
|
import { DurableStore } from './DurableStore';
|
|
3
3
|
import { InstrumentationFunction } from './makeDurable/error';
|
|
4
4
|
import { PendingWriter } from './makeDurable/pendingWriter';
|
|
5
|
+
import { TTLOverridesMap } from './DurableTTLStore';
|
|
5
6
|
export interface DurableEnvironment extends Environment {
|
|
6
7
|
/**
|
|
7
8
|
* Disposes the environment and detaches the durable store listener
|
|
@@ -11,6 +12,10 @@ export interface DurableEnvironment extends Environment {
|
|
|
11
12
|
* publishes the pending changes to the durable store
|
|
12
13
|
*/
|
|
13
14
|
publishChangesToDurableStore(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* gets all the stored ttl overrides stored in the durable store
|
|
17
|
+
*/
|
|
18
|
+
getDurableTTLOverrides(): Promise<TTLOverridesMap>;
|
|
14
19
|
}
|
|
15
20
|
export declare const AdapterContextSegment = "ADAPTER-CONTEXT";
|
|
16
21
|
export declare const ADAPTER_CONTEXT_ID_SUFFIX = "__NAMED_CONTEXT";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luvio/environments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.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,6 @@
|
|
|
16
16
|
"dist/"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@luvio/engine": "0.
|
|
19
|
+
"@luvio/engine": "0.55.0"
|
|
20
20
|
}
|
|
21
21
|
}
|