@luvio/environments 0.145.4 → 0.146.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/environments.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StoreKeySet, deepFreeze, serializeStructuredKey, emitAdapterEvent, Reader } from '@luvio/engine';
|
|
1
|
+
import { StoreKeySet, deepFreeze, serializeStructuredKey, emitAdapterEvent, StringKeyInMemoryStore, Reader } from '@luvio/engine';
|
|
2
2
|
|
|
3
3
|
// the last version the metadata shape was altered
|
|
4
4
|
const DURABLE_METADATA_VERSION = '0.111.0';
|
|
@@ -112,7 +112,7 @@ function publishDurableStoreEntries(durableRecords, put, publishMetadata) {
|
|
|
112
112
|
* will refresh the snapshot from network, and then run the results from network
|
|
113
113
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
114
114
|
*/
|
|
115
|
-
function reviveSnapshot(baseEnvironment, durableStore, unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot, reviveMetrics = { l2Trips: [] }) {
|
|
115
|
+
function reviveSnapshot(baseEnvironment, durableStore, unavailableSnapshot, durableStoreErrorHandler, buildL1Snapshot, revivingStore, reviveMetrics = { l2Trips: [] }) {
|
|
116
116
|
const { recordId, select, missingLinks, seenRecords, state } = unavailableSnapshot;
|
|
117
117
|
// L2 can only revive Unfulfilled snapshots that have a selector since they have the
|
|
118
118
|
// info needed to revive (like missingLinks) and rebuild. Otherwise return L1 snapshot.
|
|
@@ -122,10 +122,21 @@ function reviveSnapshot(baseEnvironment, durableStore, unavailableSnapshot, dura
|
|
|
122
122
|
metrics: reviveMetrics,
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
const keysToReviveSet = new StoreKeySet();
|
|
126
|
+
if (revivingStore) {
|
|
127
|
+
// Any stale keys since the last l2 read should be cleared and fetched again
|
|
128
|
+
for (const staleKey of revivingStore.staleEntries) {
|
|
129
|
+
keysToReviveSet.add(staleKey);
|
|
130
|
+
}
|
|
131
|
+
revivingStore.clearStale();
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
// when not using a reviving store:
|
|
135
|
+
// in case L1 store changes/deallocs a record while we are doing the async read
|
|
136
|
+
// we attempt to read all keys from L2 - so combine recordId with any seenRecords
|
|
137
|
+
keysToReviveSet.add(recordId);
|
|
138
|
+
keysToReviveSet.merge(seenRecords);
|
|
139
|
+
}
|
|
129
140
|
keysToReviveSet.merge(missingLinks);
|
|
130
141
|
const keysToRevive = keysToReviveSet.keysAsArray();
|
|
131
142
|
const canonicalKeys = keysToRevive.map((x) => serializeStructuredKey(baseEnvironment.storeGetCanonicalKey(x)));
|
|
@@ -175,7 +186,7 @@ function reviveSnapshot(baseEnvironment, durableStore, unavailableSnapshot, dura
|
|
|
175
186
|
for (let i = 0, len = newKeys.length; i < len; i++) {
|
|
176
187
|
const newSnapshotSeenKey = newKeys[i];
|
|
177
188
|
if (!alreadyRequestedOrRevivedSet.has(newSnapshotSeenKey)) {
|
|
178
|
-
return reviveSnapshot(baseEnvironment, durableStore, snapshot, durableStoreErrorHandler, buildL1Snapshot, reviveMetrics);
|
|
189
|
+
return reviveSnapshot(baseEnvironment, durableStore, snapshot, durableStoreErrorHandler, buildL1Snapshot, revivingStore, reviveMetrics);
|
|
179
190
|
}
|
|
180
191
|
}
|
|
181
192
|
}
|
|
@@ -374,6 +385,50 @@ async function reviveRedirects(durableStore, env) {
|
|
|
374
385
|
}
|
|
375
386
|
}
|
|
376
387
|
|
|
388
|
+
function buildRevivingStagingStore(upstreamStore) {
|
|
389
|
+
const localStore = new StringKeyInMemoryStore();
|
|
390
|
+
const staleEntries = new Set();
|
|
391
|
+
function readEntry(key) {
|
|
392
|
+
if (typeof key !== 'string') {
|
|
393
|
+
return upstreamStore.readEntry(key);
|
|
394
|
+
}
|
|
395
|
+
let storeEntry = localStore.readEntry(key);
|
|
396
|
+
if (!storeEntry) {
|
|
397
|
+
// read from upstream store...
|
|
398
|
+
storeEntry = upstreamStore.readEntry(key);
|
|
399
|
+
// put it in our store to avoid it getting evicted prior to the next durable store read
|
|
400
|
+
localStore.put(key, storeEntry);
|
|
401
|
+
}
|
|
402
|
+
return storeEntry;
|
|
403
|
+
}
|
|
404
|
+
// Entries are marked stale by the durable store change listener. They are not
|
|
405
|
+
// immediately evicted so as to not result in a cache miss during a rebuild.
|
|
406
|
+
// The revive process will clear stale entries and read them from the durable store
|
|
407
|
+
// on the next revive loop.
|
|
408
|
+
function markStale(key) {
|
|
409
|
+
staleEntries.add(key);
|
|
410
|
+
}
|
|
411
|
+
// The revive loop clears stale entries right before reading from the durable store.
|
|
412
|
+
// Any stale entries will be revived to ensure they are present in L1 and match the
|
|
413
|
+
// latest data.
|
|
414
|
+
function clearStale() {
|
|
415
|
+
for (const key of staleEntries) {
|
|
416
|
+
localStore.dealloc(key);
|
|
417
|
+
}
|
|
418
|
+
staleEntries.clear();
|
|
419
|
+
}
|
|
420
|
+
// All functions other than `readEntry` pass through to the upstream store.
|
|
421
|
+
// A reviving store is only "active" during a call to `environment.storeLookup`, and will
|
|
422
|
+
// be used by the reader attempting to build an L1 snapshot. Immediately after the L1 rebuild
|
|
423
|
+
// the reviving store becomes inactive other than receiving change notifications.
|
|
424
|
+
return create(upstreamStore, {
|
|
425
|
+
readEntry: { value: readEntry },
|
|
426
|
+
markStale: { value: markStale },
|
|
427
|
+
clearStale: { value: clearStale },
|
|
428
|
+
staleEntries: { value: staleEntries },
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
377
432
|
const AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
378
433
|
const ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
379
434
|
async function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, contextStores, pendingContextStoreKeys, onContextLoaded) {
|
|
@@ -429,14 +484,16 @@ function isUnfulfilledSnapshot(cachedSnapshotResult) {
|
|
|
429
484
|
* @param durableStore A DurableStore implementation
|
|
430
485
|
* @param instrumentation An instrumentation function implementation
|
|
431
486
|
*/
|
|
432
|
-
function makeDurable(environment, { durableStore, instrumentation }) {
|
|
433
|
-
let
|
|
487
|
+
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore }) {
|
|
488
|
+
let stagingStore = null;
|
|
434
489
|
const durableTTLStore = new DurableTTLStore(durableStore);
|
|
435
490
|
const mergeKeysPromiseMap = new Map();
|
|
436
491
|
// When a context store is mutated we write it to L2, which causes DS on change
|
|
437
492
|
// event. If this instance of makeDurable caused that L2 write we can ignore that
|
|
438
493
|
// on change event. This Set helps us do that.
|
|
439
494
|
const pendingContextStoreKeys = new Set();
|
|
495
|
+
// Reviving stores are tracked so that they can be notified of durable store change notifications.
|
|
496
|
+
const revivingStores = new Set();
|
|
440
497
|
// redirects that need to be flushed to the durable store
|
|
441
498
|
const pendingStoreRedirects = new Map();
|
|
442
499
|
const contextStores = create(null);
|
|
@@ -533,6 +590,9 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
533
590
|
// and go through an entire broadcast/revive cycle for unchanged data
|
|
534
591
|
// call base environment storeEvict so this evict is not tracked for durable deletion
|
|
535
592
|
environment.storeEvict(key);
|
|
593
|
+
for (const revivingStore of revivingStores) {
|
|
594
|
+
revivingStore.markStale(key);
|
|
595
|
+
}
|
|
536
596
|
}
|
|
537
597
|
shouldBroadcast = true;
|
|
538
598
|
}
|
|
@@ -561,10 +621,10 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
561
621
|
};
|
|
562
622
|
const storePublish = function (key, data) {
|
|
563
623
|
validateNotDisposed();
|
|
564
|
-
if (
|
|
565
|
-
|
|
624
|
+
if (stagingStore === null) {
|
|
625
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
566
626
|
}
|
|
567
|
-
|
|
627
|
+
stagingStore.publish(key, data);
|
|
568
628
|
// remove record from main luvio L1 cache while we are on the synchronous path
|
|
569
629
|
// because we do not want some other code attempting to use the
|
|
570
630
|
// in-memory values before the durable store onChanged handler
|
|
@@ -573,26 +633,26 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
573
633
|
};
|
|
574
634
|
const publishStoreMetadata = function (recordId, storeMetadata) {
|
|
575
635
|
validateNotDisposed();
|
|
576
|
-
if (
|
|
577
|
-
|
|
636
|
+
if (stagingStore === null) {
|
|
637
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
578
638
|
}
|
|
579
|
-
|
|
639
|
+
stagingStore.publishMetadata(recordId, storeMetadata);
|
|
580
640
|
};
|
|
581
641
|
const storeIngest = function (key, ingest, response, luvio) {
|
|
582
642
|
validateNotDisposed();
|
|
583
643
|
// we don't ingest to the luvio L1 store from network directly, we ingest to
|
|
584
644
|
// L2 and let DurableStore on change event revive keys into luvio L1 store
|
|
585
|
-
if (
|
|
586
|
-
|
|
645
|
+
if (stagingStore === null) {
|
|
646
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
587
647
|
}
|
|
588
|
-
environment.storeIngest(key, ingest, response, luvio,
|
|
648
|
+
environment.storeIngest(key, ingest, response, luvio, stagingStore);
|
|
589
649
|
};
|
|
590
650
|
const storeIngestError = function (key, errorSnapshot, storeMetadataParams, _storeOverride) {
|
|
591
651
|
validateNotDisposed();
|
|
592
|
-
if (
|
|
593
|
-
|
|
652
|
+
if (stagingStore === null) {
|
|
653
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
594
654
|
}
|
|
595
|
-
environment.storeIngestError(key, errorSnapshot, storeMetadataParams,
|
|
655
|
+
environment.storeIngestError(key, errorSnapshot, storeMetadataParams, stagingStore);
|
|
596
656
|
};
|
|
597
657
|
const storeBroadcast = function (_rebuildSnapshot, _snapshotDataAvailable) {
|
|
598
658
|
validateNotDisposed();
|
|
@@ -603,19 +663,19 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
603
663
|
};
|
|
604
664
|
const publishChangesToDurableStore = function (additionalDurableStoreOperations) {
|
|
605
665
|
validateNotDisposed();
|
|
606
|
-
if (
|
|
666
|
+
if (stagingStore === null) {
|
|
607
667
|
return Promise.resolve();
|
|
608
668
|
}
|
|
609
|
-
const promise = flushInMemoryStoreValuesToDurableStore(
|
|
669
|
+
const promise = flushInMemoryStoreValuesToDurableStore(stagingStore, durableStore, durableStoreErrorHandler, new Map(pendingStoreRedirects), additionalDurableStoreOperations);
|
|
610
670
|
pendingStoreRedirects.clear();
|
|
611
|
-
|
|
671
|
+
stagingStore = null;
|
|
612
672
|
return promise;
|
|
613
673
|
};
|
|
614
674
|
const storeLookup = function (sel, createSnapshot, refresh, ttlStrategy) {
|
|
615
675
|
validateNotDisposed();
|
|
616
|
-
// if this lookup is right after an ingest there will be a staging store
|
|
617
|
-
if (
|
|
618
|
-
const reader = new Reader(
|
|
676
|
+
// if this lookup is right after an ingest or during a revive there will be a staging store
|
|
677
|
+
if (stagingStore !== null) {
|
|
678
|
+
const reader = new Reader(stagingStore, sel.variables, refresh, undefined, ttlStrategy);
|
|
619
679
|
return reader.read(sel);
|
|
620
680
|
}
|
|
621
681
|
// otherwise this is from buildCachedSnapshot and we should use the luvio
|
|
@@ -624,24 +684,24 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
624
684
|
};
|
|
625
685
|
const storeEvict = function (key) {
|
|
626
686
|
validateNotDisposed();
|
|
627
|
-
if (
|
|
628
|
-
|
|
687
|
+
if (stagingStore === null) {
|
|
688
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
629
689
|
}
|
|
630
|
-
|
|
690
|
+
stagingStore.evict(key);
|
|
631
691
|
};
|
|
632
692
|
const getNode = function (key) {
|
|
633
693
|
validateNotDisposed();
|
|
634
|
-
if (
|
|
635
|
-
|
|
694
|
+
if (stagingStore === null) {
|
|
695
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
636
696
|
}
|
|
637
|
-
return environment.getNode(key,
|
|
697
|
+
return environment.getNode(key, stagingStore);
|
|
638
698
|
};
|
|
639
699
|
const wrapNormalizedGraphNode = function (normalized) {
|
|
640
700
|
validateNotDisposed();
|
|
641
|
-
if (
|
|
642
|
-
|
|
701
|
+
if (stagingStore === null) {
|
|
702
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
643
703
|
}
|
|
644
|
-
return environment.wrapNormalizedGraphNode(normalized,
|
|
704
|
+
return environment.wrapNormalizedGraphNode(normalized, stagingStore);
|
|
645
705
|
};
|
|
646
706
|
const rebuildSnapshot = function (snapshot, onRebuild) {
|
|
647
707
|
validateNotDisposed();
|
|
@@ -653,7 +713,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
653
713
|
return;
|
|
654
714
|
}
|
|
655
715
|
// Do an L2 revive and emit to subscriber using the callback.
|
|
656
|
-
|
|
716
|
+
reviveSnapshotWrapper(rebuilt, () => {
|
|
657
717
|
// reviveSnapshot will revive into L1, and since "records" is a reference
|
|
658
718
|
// (and not a copy) to the L1 records we can use it for rebuild
|
|
659
719
|
let rebuiltSnap;
|
|
@@ -694,10 +754,10 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
694
754
|
// the next publishChangesToDurableStore. NOTE: we don't need to call
|
|
695
755
|
// redirect on the base environment store because staging store and base
|
|
696
756
|
// L1 store share the same redirect and reverseRedirectKeys
|
|
697
|
-
if (
|
|
698
|
-
|
|
757
|
+
if (stagingStore === null) {
|
|
758
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
699
759
|
}
|
|
700
|
-
|
|
760
|
+
stagingStore.redirect(existingKey, canonicalKey);
|
|
701
761
|
};
|
|
702
762
|
const storeSetTTLOverride = function (namespace, representationName, ttl) {
|
|
703
763
|
validateNotDisposed();
|
|
@@ -738,7 +798,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
738
798
|
if (isUnfulfilledSnapshot(snapshot)) {
|
|
739
799
|
const start = Date.now();
|
|
740
800
|
emitDurableEnvironmentAdapterEvent({ type: 'l2-revive-start' }, adapterRequestContext.eventObservers);
|
|
741
|
-
const revivedSnapshot =
|
|
801
|
+
const revivedSnapshot = reviveSnapshotWrapper(snapshot, () => injectedStoreLookup(snapshot.select, snapshot.refresh)).then((result) => {
|
|
742
802
|
emitDurableEnvironmentAdapterEvent({
|
|
743
803
|
type: 'l2-revive-end',
|
|
744
804
|
snapshot: result.snapshot,
|
|
@@ -763,15 +823,15 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
763
823
|
};
|
|
764
824
|
const getIngestStagingStoreRecords = function () {
|
|
765
825
|
validateNotDisposed();
|
|
766
|
-
if (
|
|
767
|
-
return
|
|
826
|
+
if (stagingStore !== null) {
|
|
827
|
+
return stagingStore.fallbackStringKeyInMemoryStore.records;
|
|
768
828
|
}
|
|
769
829
|
return {};
|
|
770
830
|
};
|
|
771
831
|
const getIngestStagingStoreMetadata = function () {
|
|
772
832
|
validateNotDisposed();
|
|
773
|
-
if (
|
|
774
|
-
return
|
|
833
|
+
if (stagingStore !== null) {
|
|
834
|
+
return stagingStore.fallbackStringKeyInMemoryStore.metadata;
|
|
775
835
|
}
|
|
776
836
|
return {};
|
|
777
837
|
};
|
|
@@ -810,22 +870,20 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
810
870
|
}
|
|
811
871
|
await Promise.all(pendingPromises);
|
|
812
872
|
const entries = await durableStore.getEntries(keysToReviveAsArray, DefaultDurableSegment);
|
|
813
|
-
|
|
873
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
814
874
|
publishDurableStoreEntries(entries, (key, record) => {
|
|
815
875
|
if (typeof key === 'string') {
|
|
816
|
-
|
|
817
|
-
record;
|
|
876
|
+
stagingStore.fallbackStringKeyInMemoryStore.records[key] = record;
|
|
818
877
|
}
|
|
819
878
|
else {
|
|
820
|
-
|
|
879
|
+
stagingStore.recordsMap.set(key, record);
|
|
821
880
|
}
|
|
822
881
|
}, (key, metadata) => {
|
|
823
882
|
if (typeof key === 'string') {
|
|
824
|
-
|
|
825
|
-
metadata;
|
|
883
|
+
stagingStore.fallbackStringKeyInMemoryStore.metadata[key] = metadata;
|
|
826
884
|
}
|
|
827
885
|
else {
|
|
828
|
-
|
|
886
|
+
stagingStore.metadataMap.set(key, metadata);
|
|
829
887
|
}
|
|
830
888
|
});
|
|
831
889
|
snapshotFromMemoryIngest = await ingestAndBroadcastFunc();
|
|
@@ -854,7 +912,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
854
912
|
// we aren't doing any merging so we don't have to synchronize, the
|
|
855
913
|
// underlying DurableStore implementation takes care of R/W sync
|
|
856
914
|
// so all we have to do is ingest then write to L2
|
|
857
|
-
|
|
915
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
858
916
|
snapshotFromMemoryIngest = await ingestAndBroadcastFunc();
|
|
859
917
|
}
|
|
860
918
|
if (snapshotFromMemoryIngest === undefined) {
|
|
@@ -865,12 +923,12 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
865
923
|
}
|
|
866
924
|
// if snapshot from staging store lookup is unfulfilled then do an L2 lookup
|
|
867
925
|
const { select, refresh } = snapshotFromMemoryIngest;
|
|
868
|
-
const result = await
|
|
926
|
+
const result = await reviveSnapshotWrapper(snapshotFromMemoryIngest, () => environment.storeLookup(select, environment.createSnapshot, refresh));
|
|
869
927
|
return result.snapshot;
|
|
870
928
|
};
|
|
871
929
|
const handleErrorResponse = async function (ingestAndBroadcastFunc) {
|
|
872
930
|
validateNotDisposed();
|
|
873
|
-
|
|
931
|
+
stagingStore = buildIngestStagingStore(environment);
|
|
874
932
|
return ingestAndBroadcastFunc();
|
|
875
933
|
};
|
|
876
934
|
const getNotifyChangeStoreEntries = function (keys) {
|
|
@@ -921,6 +979,27 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
921
979
|
await durableStore.setEntries({ notifyStoreUpdateAvailable: { data: entryKeys } }, MessagingDurableSegment);
|
|
922
980
|
return Promise.resolve(undefined);
|
|
923
981
|
};
|
|
982
|
+
const reviveSnapshotWrapper = function (unavailableSnapshot, buildL1Snapshot) {
|
|
983
|
+
let revivingStore = undefined;
|
|
984
|
+
if (useRevivingStore) {
|
|
985
|
+
// NOTE: `store` is private, there doesn't seem to be a better,
|
|
986
|
+
// cleaner way of accessing it from a derived environment.
|
|
987
|
+
let baseStore = environment.store;
|
|
988
|
+
// If we're rebuilding during an ingest, the existing staging store should be the base store.
|
|
989
|
+
if (stagingStore) {
|
|
990
|
+
baseStore = stagingStore;
|
|
991
|
+
}
|
|
992
|
+
let revivingStore = buildRevivingStagingStore(baseStore);
|
|
993
|
+
revivingStores.add(revivingStore);
|
|
994
|
+
}
|
|
995
|
+
return reviveSnapshot(environment, durableStore, unavailableSnapshot, durableStoreErrorHandler, () => {
|
|
996
|
+
const tempStore = stagingStore;
|
|
997
|
+
const result = buildL1Snapshot();
|
|
998
|
+
stagingStore = tempStore;
|
|
999
|
+
return result;
|
|
1000
|
+
}, revivingStore).finally(() => {
|
|
1001
|
+
});
|
|
1002
|
+
};
|
|
924
1003
|
// set the default cache policy of the base environment
|
|
925
1004
|
environment.setDefaultCachePolicy({
|
|
926
1005
|
type: 'stale-while-revalidate',
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InMemoryStore } from '@luvio/engine';
|
|
2
|
+
export interface RevivingStore extends InMemoryStore {
|
|
3
|
+
staleEntries: Set<string>;
|
|
4
|
+
markStale(key: string): void;
|
|
5
|
+
clearStale(): void;
|
|
6
|
+
}
|
|
7
|
+
export declare function buildRevivingStagingStore(upstreamStore: InMemoryStore): RevivingStore;
|
|
@@ -2,6 +2,7 @@ import type { Environment, Snapshot, StoreMetadata, NormalizedKeyMetadata, Unful
|
|
|
2
2
|
import type { DurableStore, DurableStoreEntries } from '../DurableStore';
|
|
3
3
|
import type { DurableStoreRejectionHandler } from './error';
|
|
4
4
|
import { StoreKeySet } from '@luvio/engine';
|
|
5
|
+
import type { RevivingStore } from './RevivingStore';
|
|
5
6
|
type ReviveResponse = {
|
|
6
7
|
revivedKeys: StoreKeySet<string | NormalizedKeyMetadata>;
|
|
7
8
|
hadUnexpectedShape: boolean;
|
|
@@ -18,13 +19,13 @@ type ReviveResponse = {
|
|
|
18
19
|
* @returns
|
|
19
20
|
*/
|
|
20
21
|
export declare function publishDurableStoreEntries(durableRecords: DurableStoreEntries<unknown> | undefined, put: (key: string | NormalizedKeyMetadata, record: unknown) => void, publishMetadata: (key: string, metadata: StoreMetadata) => void): ReviveResponse;
|
|
21
|
-
interface ReviveMetrics {
|
|
22
|
+
export interface ReviveMetrics {
|
|
22
23
|
l2Trips: {
|
|
23
24
|
keysRequestedCount: number;
|
|
24
25
|
duration: number;
|
|
25
26
|
}[];
|
|
26
27
|
}
|
|
27
|
-
interface ReviveResult<D, V> {
|
|
28
|
+
export interface ReviveResult<D, V> {
|
|
28
29
|
snapshot: Snapshot<D, V>;
|
|
29
30
|
metrics: ReviveMetrics;
|
|
30
31
|
}
|
|
@@ -34,5 +35,5 @@ interface ReviveResult<D, V> {
|
|
|
34
35
|
* will refresh the snapshot from network, and then run the results from network
|
|
35
36
|
* through L2 ingestion, returning the subsequent revived snapshot.
|
|
36
37
|
*/
|
|
37
|
-
export declare function reviveSnapshot<D, V = unknown>(baseEnvironment: Environment, durableStore: DurableStore, unavailableSnapshot: UnfulfilledSnapshot<D, V>, durableStoreErrorHandler: DurableStoreRejectionHandler, buildL1Snapshot: () => Snapshot<D, V>, reviveMetrics?: ReviveMetrics): Promise<ReviveResult<D, V>>;
|
|
38
|
+
export declare function reviveSnapshot<D, V = unknown>(baseEnvironment: Environment, durableStore: DurableStore, unavailableSnapshot: UnfulfilledSnapshot<D, V>, durableStoreErrorHandler: DurableStoreRejectionHandler, buildL1Snapshot: () => Snapshot<D, V>, revivingStore: RevivingStore | undefined, reviveMetrics?: ReviveMetrics): Promise<ReviveResult<D, V>>;
|
|
38
39
|
export {};
|
|
@@ -34,6 +34,7 @@ export declare const ADAPTER_CONTEXT_ID_SUFFIX = "__NAMED_CONTEXT";
|
|
|
34
34
|
interface MakeDurableOptions {
|
|
35
35
|
durableStore: DurableStore;
|
|
36
36
|
instrumentation?: InstrumentationFunction;
|
|
37
|
+
useRevivingStore?: boolean;
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Configures the environment to persist data into a durable store and attempt to resolve
|
|
@@ -44,5 +45,5 @@ interface MakeDurableOptions {
|
|
|
44
45
|
* @param durableStore A DurableStore implementation
|
|
45
46
|
* @param instrumentation An instrumentation function implementation
|
|
46
47
|
*/
|
|
47
|
-
export declare function makeDurable(environment: Environment, { durableStore, instrumentation }: MakeDurableOptions): DurableEnvironment;
|
|
48
|
+
export declare function makeDurable(environment: Environment, { durableStore, instrumentation, useRevivingStore }: MakeDurableOptions): DurableEnvironment;
|
|
48
49
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luvio/environments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.146.0",
|
|
4
4
|
"description": "Luvio Environments",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"watch": "yarn build --watch"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@luvio/engine": "^0.
|
|
30
|
+
"@luvio/engine": "^0.146.0"
|
|
31
31
|
},
|
|
32
32
|
"volta": {
|
|
33
33
|
"extends": "../../../package.json"
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
{
|
|
37
37
|
"path": "./dist/environments.js",
|
|
38
38
|
"maxSize": {
|
|
39
|
-
"none": "
|
|
40
|
-
"min": "
|
|
41
|
-
"compressed": "8.
|
|
39
|
+
"none": "45.5 kB",
|
|
40
|
+
"min": "13.0 kB",
|
|
41
|
+
"compressed": "8.8 kB"
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
],
|