@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.
@@ -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) {
@@ -21,6 +21,50 @@
21
21
  const { hasOwnProperty } = Object.prototype;
22
22
  const { isArray } = Array;
23
23
 
24
+ // cache policy implementations
25
+ function buildTTLStrategy(staleDuration = 0) {
26
+ return (timestamp, metadata, valueIsError) => {
27
+ if (metadata !== undefined) {
28
+ const { expirationTimestamp } = metadata;
29
+ if (timestamp > expirationTimestamp) {
30
+ if (timestamp <= expirationTimestamp + staleDuration && valueIsError !== true) {
31
+ return engine.StoreResolveResultState.Stale;
32
+ }
33
+ return engine.StoreResolveResultState.NotPresent;
34
+ }
35
+ }
36
+ if (valueIsError === true) {
37
+ return engine.StoreResolveResultState.Error;
38
+ }
39
+ return engine.StoreResolveResultState.Found;
40
+ };
41
+ }
42
+ function appendTTLStrategy(storeLookup, ttlStrategy) {
43
+ return (sel, refresh) => storeLookup(sel, refresh, ttlStrategy);
44
+ }
45
+ function buildStaleWhileRevalidateImplementation(validateNotDisposed, resolveSnapshot, staleDuration) {
46
+ return function (args) {
47
+ validateNotDisposed();
48
+ const { buildInMemorySnapshot, buildNetworkSnapshot, buildSnapshotContext, dispatchResourceRequest, storeLookup, } = args;
49
+ const snapshot = buildInMemorySnapshot(buildSnapshotContext, appendTTLStrategy(storeLookup, buildTTLStrategy(staleDuration)));
50
+ if (snapshot !== undefined) {
51
+ if (snapshot.state === 'Fulfilled' || snapshot.state === 'Error') {
52
+ return snapshot;
53
+ }
54
+ if (snapshot.state === 'Stale') {
55
+ // offline environment is already doing this; uncomment once we get rid of offline environment
56
+ // buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
57
+ return snapshot;
58
+ }
59
+ return resolveSnapshot(snapshot, {
60
+ resolve: () => buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest),
61
+ config: undefined,
62
+ });
63
+ }
64
+ return buildNetworkSnapshot(buildSnapshotContext, dispatchResourceRequest);
65
+ };
66
+ }
67
+
24
68
  //Durable store error instrumentation key
25
69
  const DURABLE_STORE_ERROR = 'durable-store-error';
26
70
  /**
@@ -218,8 +262,7 @@
218
262
  }
219
263
  promiseResolve(resolvedSnapshot);
220
264
  });
221
- const { resolve, config } = refresh;
222
- resolve(config)
265
+ refresh()
223
266
  .then((refreshedSnapshot) => {
224
267
  // if error, just return it, because there won't be a L2 flush/broadcast/rebuild
225
268
  // (non-cached errors don't broadcast, and subscribing to an error snapshot
@@ -261,11 +304,23 @@
261
304
 
262
305
  function isStoreEntryError(storeRecord) {
263
306
  return storeRecord.__type === 'error';
264
- }
307
+ }
308
+
265
309
  function isStoreEntryExpiredAndError(storeRecord, expirationTimestamp, now) {
266
310
  return isStoreEntryError(storeRecord) && expirationTimestamp < now;
267
311
  }
268
- function reviveDurableEntriesToStore(durableRecords, environment, pendingWriter) {
312
+ /**
313
+ * Takes a set of entries from DurableStore and publishes them via the passed in funcs.
314
+ * This respects expiration and checks for valid DurableStore data shapes. This should
315
+ * be used over manually parsing DurableStoreEntries
316
+ *
317
+ * @param durableRecords The DurableStoreEntries to parse
318
+ * @param publish A function to call with the data of each DurableStoreEntry
319
+ * @param publishMetadata A function to call with the metadata of each DurableStoreEntry
320
+ * @param pendingWriter the PendingWriter (this is going away soon)
321
+ * @returns
322
+ */
323
+ function publishDurableStoreEntries(durableRecords, publish, publishMetadata, pendingWriter) {
269
324
  const revivedKeys = create(null);
270
325
  let hadUnexpectedShape = false;
271
326
  if (durableRecords === undefined) {
@@ -293,13 +348,13 @@
293
348
  }
294
349
  if (metadata !== undefined) {
295
350
  const { expirationTimestamp, staleTimestamp } = metadata;
296
- if (expirationTimestamp === undefined || staleTimestamp === undefined) {
351
+ if (expirationTimestamp === undefined) {
297
352
  // if unexpected expiration data skip reviving
298
353
  hadUnexpectedShape = true;
299
354
  continue;
300
355
  }
301
356
  // if past stale TTL then don't revive
302
- if (staleTimestamp < now) {
357
+ if (staleTimestamp !== undefined && staleTimestamp < now) {
303
358
  continue;
304
359
  }
305
360
  // We don't want to revive a cached value if it's an error and it's
@@ -314,8 +369,7 @@
314
369
  if (isStoreEntryExpiredAndError(data, expirationTimestamp, now)) {
315
370
  continue;
316
371
  }
317
- // call base publishStoreMetadata so we don't add the key to pendingWriters
318
- environment.publishStoreMetadata(key, metadata);
372
+ publishMetadata(key, metadata);
319
373
  }
320
374
  if (isStoreEntryError(data)) {
321
375
  // freeze errors on way into L1
@@ -325,8 +379,7 @@
325
379
  // Note: this won't affect ingest (which ingests to L1 temporarily then
326
380
  // flushes to L2) because that path is synchronous and atomic.
327
381
  pendingWriter.removePendingWrite(key);
328
- // call base storePublish so we don't add the key to pendingWriters
329
- environment.storePublish(key, data);
382
+ publish(key, data);
330
383
  revivedKeys[key] = true;
331
384
  }
332
385
  return { revivedKeys, hadUnexpectedShape };
@@ -338,13 +391,13 @@
338
391
  * will refresh the snapshot from network, and then run the results from network
339
392
  * through L2 ingestion, returning the subsequent revived snapshot.
340
393
  */
341
- function reviveSnapshot(environment, durableStore, pendingWriter, unavailableSnapshot, refresh, durableStoreErrorHandler, baseSnapshot) {
394
+ function reviveSnapshot(baseEnvironment, durableStore, pendingWriter, unavailableSnapshot, refresh, durableStoreErrorHandler, baseSnapshot) {
342
395
  const { recordId, select, seenRecords, state } = unavailableSnapshot;
343
396
  // on rebuilds return the network snapshot on L2 miss
344
397
  const refreshSnapshot = baseSnapshot !== undefined
345
398
  ? () => {
346
399
  if (baseSnapshot.state !== 'Pending') {
347
- return refresh.resolve(refresh.config);
400
+ return refresh();
348
401
  }
349
402
  // A Pending snapshot could be in the store awaiting either a result
350
403
  // from the network or L2. If another ingest brings in an overlapping key
@@ -357,17 +410,17 @@
357
410
  }
358
411
  // track the refresh operation to ensure no other refreshes kick off while in flight
359
412
  snapshotRefreshMap.add(baseSnapshot);
360
- return refresh.resolve(refresh.config).finally(() => {
413
+ return refresh().finally(() => {
361
414
  snapshotRefreshMap.delete(baseSnapshot);
362
415
  });
363
416
  }
364
- : buildDurableStoreAwareRefresh(refresh, unavailableSnapshot, environment, pendingWriter);
417
+ : buildDurableStoreAwareRefresh(refresh, unavailableSnapshot, baseEnvironment, pendingWriter);
365
418
  // L2 can only revive Unfulfilled snapshots that have a selector since they have the
366
419
  // info needed to revive (like missingLinks) and rebuild. Otherwise refresh.
367
420
  if (state !== 'Unfulfilled' || select === undefined) {
368
421
  return refreshSnapshot();
369
422
  }
370
- // in case L1 cache changes/deallocs a record while we are doing the async read
423
+ // in case L1 store changes/deallocs a record while we are doing the async read
371
424
  // we attempt to read all keys from L2 - so combine recordId with any seenRecords
372
425
  const keysToReviveSet = assign({ [recordId]: true }, seenRecords);
373
426
  const keysToRevive = keys(keysToReviveSet);
@@ -376,9 +429,9 @@
376
429
  const paginationKey = paginationKeys[i];
377
430
  keysToRevive.push(paginationKey);
378
431
  }
379
- const canonicalKeys = keysToRevive.map((x) => environment.storeGetCanonicalKey(x));
432
+ const canonicalKeys = keysToRevive.map((x) => baseEnvironment.storeGetCanonicalKey(x));
380
433
  return durableStore.getEntries(canonicalKeys, DefaultDurableSegment).then((durableRecords) => {
381
- const { revivedKeys, hadUnexpectedShape } = reviveDurableEntriesToStore(durableRecords, environment, pendingWriter);
434
+ const { revivedKeys, hadUnexpectedShape } = publishDurableStoreEntries(durableRecords, baseEnvironment.storePublish.bind(baseEnvironment), baseEnvironment.publishStoreMetadata.bind(baseEnvironment), pendingWriter);
382
435
  // if the data coming back from DS had an unexpected shape then refresh
383
436
  // data from network
384
437
  if (hadUnexpectedShape === true) {
@@ -391,8 +444,8 @@
391
444
  // attempt to lookup (or rebuild if baseSnapshot is provided) the snapshot
392
445
  // now that we have revived the missingLinks
393
446
  const snapshot = baseSnapshot === undefined
394
- ? environment.storeLookup(unavailableSnapshot.select, environment.createSnapshot, unavailableSnapshot.refresh)
395
- : environment.rebuildSnapshot(baseSnapshot, environment.getStoreRecords(), environment.getStoreMetadataMap(), environment.getStoreRedirectKeys(), () => { });
447
+ ? baseEnvironment.storeLookup(unavailableSnapshot.select, baseEnvironment.createSnapshot, unavailableSnapshot.refresh)
448
+ : baseEnvironment.rebuildSnapshot(baseSnapshot, baseEnvironment.getStoreRecords(), baseEnvironment.getStoreMetadataMap(), baseEnvironment.getStoreRedirectKeys(), () => { });
396
449
  // if snapshot is pending then some other in-flight refresh will broadcast
397
450
  // later
398
451
  if (snapshot.state === 'Pending') {
@@ -412,13 +465,13 @@
412
465
  for (let i = 0, len = newKeys.length; i < len; i++) {
413
466
  const newSnapshotSeenKey = newKeys[i];
414
467
  if (alreadyRequestedOrRevivedSet[newSnapshotSeenKey] !== true) {
415
- return reviveSnapshot(environment, durableStore, pendingWriter, snapshot, refresh, durableStoreErrorHandler, baseSnapshot);
468
+ return reviveSnapshot(baseEnvironment, durableStore, pendingWriter, snapshot, refresh, durableStoreErrorHandler, baseSnapshot);
416
469
  }
417
470
  }
418
471
  // otherwise it's an L2 cache miss, so refresh
419
472
  return refreshSnapshot();
420
473
  }
421
- if (environment.snapshotAvailable(snapshot)) {
474
+ if (baseEnvironment.snapshotAvailable(snapshot)) {
422
475
  return snapshot;
423
476
  }
424
477
  // all other scenarios we just refresh
@@ -430,6 +483,83 @@
430
483
  });
431
484
  }
432
485
 
486
+ const TTL_DURABLE_SEGMENT = 'TTL_DURABLE_SEGMENT';
487
+ const TTL_DEFAULT_KEY = 'TTL_DEFAULT_KEY';
488
+ function buildDurableTTLOverrideStoreKey(namespace, representationName) {
489
+ return `${namespace}::${representationName}`;
490
+ }
491
+ function isEntryDurableTTLOverride(entry) {
492
+ if (typeof entry === 'object' && entry !== undefined && entry !== null) {
493
+ const data = entry.data;
494
+ if (data !== undefined) {
495
+ return (data.namespace !== undefined &&
496
+ data.representationName !== undefined &&
497
+ data.ttl !== undefined);
498
+ }
499
+ }
500
+ return false;
501
+ }
502
+ function isDefaultDurableTTLOverride(override) {
503
+ return (override.namespace === TTL_DEFAULT_KEY && override.representationName === TTL_DEFAULT_KEY);
504
+ }
505
+ /**
506
+ * Class to set and get the TTL override values in the Durable Store
507
+ */
508
+ class DurableTTLStore {
509
+ constructor(durableStore) {
510
+ this.durableStore = durableStore;
511
+ }
512
+ setDefaultDurableTTLOverrides(ttl) {
513
+ return this.durableStore.setEntries({
514
+ [buildDurableTTLOverrideStoreKey(TTL_DEFAULT_KEY, TTL_DEFAULT_KEY)]: {
515
+ data: {
516
+ namespace: TTL_DEFAULT_KEY,
517
+ representationName: TTL_DEFAULT_KEY,
518
+ ttl,
519
+ },
520
+ },
521
+ }, TTL_DURABLE_SEGMENT);
522
+ }
523
+ setDurableTTLOverride(namespace, representationName, ttl) {
524
+ return this.durableStore.setEntries({
525
+ [buildDurableTTLOverrideStoreKey(namespace, representationName)]: {
526
+ data: { namespace, representationName, ttl },
527
+ },
528
+ }, TTL_DURABLE_SEGMENT);
529
+ }
530
+ getDurableTTLOverrides() {
531
+ return this.durableStore
532
+ .getAllEntries(TTL_DURABLE_SEGMENT)
533
+ .then((entries) => {
534
+ const overrides = [];
535
+ let defaultTTL = undefined;
536
+ if (entries === undefined) {
537
+ return {
538
+ defaultTTL,
539
+ overrides,
540
+ };
541
+ }
542
+ const keys$1 = keys(entries);
543
+ for (let i = 0, len = keys$1.length; i < len; i++) {
544
+ const key = keys$1[i];
545
+ const entry = entries[key];
546
+ if (entry !== undefined && isEntryDurableTTLOverride(entry)) {
547
+ if (isDefaultDurableTTLOverride(entry.data)) {
548
+ defaultTTL = entry.data;
549
+ }
550
+ else {
551
+ overrides.push(entry.data);
552
+ }
553
+ }
554
+ }
555
+ return {
556
+ defaultTTL,
557
+ overrides,
558
+ };
559
+ });
560
+ }
561
+ }
562
+
433
563
  const AdapterContextSegment = 'ADAPTER-CONTEXT';
434
564
  const ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
435
565
  function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, onContextLoaded) {
@@ -475,6 +605,7 @@
475
605
  * @param instrumentation An instrumentation function implementation
476
606
  */
477
607
  function makeDurable(environment, { durableStore, instrumentation, pendingWriter = buildPendingWriter() }) {
608
+ const durableTTLStore = new DurableTTLStore(durableStore);
478
609
  //instrumentation for durable store errors
479
610
  const durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
480
611
  let disposed = false;
@@ -535,6 +666,19 @@
535
666
  pendingWriter.addPendingWrite(recordId);
536
667
  environment.publishStoreMetadata(recordId, storeMetadata);
537
668
  };
669
+ const storeIngestError = function (key, errorSnapshot, storeMetadataParams, _storeOverride) {
670
+ validateNotDisposed();
671
+ // TODO [W-9680660]: this will get cleaned up in next PR to use staging store
672
+ const store = {
673
+ publish: function (key, data) {
674
+ storePublish(key, data);
675
+ },
676
+ publishMetadata: function (key, storeMetadata) {
677
+ publishStoreMetadata(key, storeMetadata);
678
+ },
679
+ };
680
+ environment.storeIngestError(key, errorSnapshot, storeMetadataParams, store);
681
+ };
538
682
  const storeBroadcast = function (_rebuildSnapshot, _snapshotDataAvailable) {
539
683
  // don't await the DS write - DS implementation will take care of R/W
540
684
  // synchronization
@@ -567,7 +711,9 @@
567
711
  if (snapshot.state === 'Pending') {
568
712
  return environment.resolvePendingSnapshot(snapshot);
569
713
  }
570
- return reviveSnapshot(environment, durableStore, pendingWriter, snapshot, refresh, durableStoreErrorHandler);
714
+ const { resolve, config } = refresh;
715
+ const refreshFunc = () => resolve(config);
716
+ return reviveSnapshot(environment, durableStore, pendingWriter, snapshot, refreshFunc, durableStoreErrorHandler);
571
717
  };
572
718
  const rebuildSnapshot = function (snapshot, records, storeMetadataMap, redirects, onAsyncRebuild) {
573
719
  validateNotDisposed();
@@ -583,9 +729,11 @@
583
729
  if (refresh === undefined) {
584
730
  return rebuilt;
585
731
  }
732
+ const { resolve, config } = refresh;
733
+ const refreshFunc = () => resolve(config);
586
734
  // Do an L2 revive (which will refresh from network on L2 miss) and if
587
735
  // it results in an available snapshot emit to subscriber using the callback.
588
- reviveSnapshot(environment, durableStore, pendingWriter, rebuilt, refresh, durableStoreErrorHandler, snapshot).then((revivedSnapshot) => {
736
+ reviveSnapshot(environment, durableStore, pendingWriter, rebuilt, refreshFunc, durableStoreErrorHandler, snapshot).then((revivedSnapshot) => {
589
737
  if (environment.snapshotAvailable(revivedSnapshot) === true) {
590
738
  onAsyncRebuild(revivedSnapshot);
591
739
  }
@@ -631,19 +779,67 @@
631
779
  return result;
632
780
  });
633
781
  };
782
+ const storeSetTTLOverride = function (namespace, representationName, ttl) {
783
+ validateNotDisposed();
784
+ durableTTLStore.setDurableTTLOverride(namespace, representationName, ttl);
785
+ environment.storeSetTTLOverride(namespace, representationName, ttl);
786
+ };
787
+ const storeSetDefaultTTLOverride = function (ttl) {
788
+ validateNotDisposed();
789
+ durableTTLStore.setDefaultDurableTTLOverrides(ttl);
790
+ environment.storeSetDefaultTTLOverride(ttl);
791
+ };
792
+ const getDurableTTLOverrides = function () {
793
+ validateNotDisposed();
794
+ return durableTTLStore.getDurableTTLOverrides();
795
+ };
796
+ const defaultCachePolicy = buildStaleWhileRevalidateImplementation(validateNotDisposed, resolveSnapshot, Number.MAX_SAFE_INTEGER);
797
+ function resolveCachePolicy(cachePolicy, defaultCachePolicy) {
798
+ if (cachePolicy === undefined) {
799
+ return defaultCachePolicy;
800
+ }
801
+ switch (cachePolicy.type) {
802
+ case 'stale-while-revalidate':
803
+ return buildStaleWhileRevalidateImplementation(validateNotDisposed, resolveSnapshot, cachePolicy.staleDuration);
804
+ default: {
805
+ if (process.env.NODE_ENV !== 'production') {
806
+ throw new Error(`unrecognized cache policy: ${JSON.stringify(cachePolicy)}`);
807
+ }
808
+ return defaultCachePolicy;
809
+ }
810
+ }
811
+ }
812
+ const applyCachePolicy = function (cachePolicy, buildSnapshotContext, buildInMemorySnapshot, buildNetworkSnapshot) {
813
+ validateNotDisposed();
814
+ const cachePolicyImpl = resolveCachePolicy(cachePolicy, defaultCachePolicy);
815
+ const storeLookup = (sel, refresh, ttlStrategy) => environment.storeLookup(sel, environment.createSnapshot, refresh, ttlStrategy);
816
+ return cachePolicyImpl({
817
+ buildInMemorySnapshot,
818
+ buildNetworkSnapshot,
819
+ buildSnapshotContext,
820
+ storeLookup,
821
+ dispatchResourceRequest,
822
+ });
823
+ };
634
824
  return create(environment, {
635
825
  publishStoreMetadata: { value: publishStoreMetadata },
826
+ storeIngestError: { value: storeIngestError },
636
827
  storeBroadcast: { value: storeBroadcast },
637
828
  storeReset: { value: storeReset },
638
829
  resolveSnapshot: { value: resolveSnapshot },
639
830
  storeEvict: { value: storeEvict },
640
831
  withContext: { value: withContext },
641
832
  rebuildSnapshot: { value: rebuildSnapshot },
833
+ storeSetTTLOverride: { value: storeSetTTLOverride },
834
+ storeSetDefaultTTLOverride: { value: storeSetDefaultTTLOverride },
642
835
  storePublish: { value: storePublish },
643
836
  storeRedirect: { value: storeRedirect },
644
837
  dispatchResourceRequest: { value: dispatchResourceRequest },
645
838
  dispose: { value: dispose },
646
839
  publishChangesToDurableStore: { value: publishChangesToDurableStore },
840
+ getDurableTTLOverrides: { value: getDurableTTLOverrides },
841
+ defaultCachePolicy: { value: defaultCachePolicy },
842
+ applyCachePolicy: { value: applyCachePolicy },
647
843
  });
648
844
  }
649
845
 
@@ -659,8 +855,8 @@
659
855
  * cause a network refresh to happen).
660
856
  */
661
857
  function makeOffline(environment) {
662
- const storeLookup = function (sel, createSnapshot, refresh) {
663
- const snapshot = environment.storeLookup(sel, createSnapshot, refresh);
858
+ const storeLookup = function (sel, createSnapshot, refresh, ttlStrategy) {
859
+ const snapshot = environment.storeLookup(sel, createSnapshot, refresh, ttlStrategy);
664
860
  // if the snapshot is stale we want to kick off a refresh
665
861
  if (snapshot.state === 'Stale') {
666
862
  if (refresh !== undefined) {
@@ -683,6 +879,9 @@
683
879
  });
684
880
  };
685
881
  return create(environment, {
882
+ defaultCachePolicy: {
883
+ value: engine.buildStaleWhileRevalidateImplementation(Number.MAX_SAFE_INTEGER),
884
+ },
686
885
  storeLookup: { value: storeLookup },
687
886
  snapshotAvailable: {
688
887
  value: snapshotAvailable,
@@ -696,6 +895,7 @@
696
895
  exports.DefaultDurableSegment = DefaultDurableSegment;
697
896
  exports.makeDurable = makeDurable;
698
897
  exports.makeOffline = makeOffline;
898
+ exports.publishDurableStoreEntries = publishDurableStoreEntries;
699
899
 
700
900
  Object.defineProperty(exports, '__esModule', { value: true });
701
901
 
@@ -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, SnapshotRefresh, UnAvailableSnapshot } from '@luvio/engine';
1
+ import { Environment, Snapshot, UnAvailableSnapshot } from '@luvio/engine';
2
2
  import { PendingWriter } from './pendingWriter';
3
- export declare function buildDurableStoreAwareRefresh<ResponseType>(refresh: SnapshotRefresh<ResponseType>, snapshot: UnAvailableSnapshot<ResponseType>, environment: Environment, pendingWriter: PendingWriter): () => Promise<Snapshot<ResponseType>>;
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, SnapshotRefresh, Snapshot, UnAvailableSnapshot, DataSnapshot } from '@luvio/engine';
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
- export declare function reviveDurableEntriesToStore(durableRecords: DurableStoreEntries<unknown> | undefined, environment: Environment, pendingWriter: PendingWriter): ReviveResponse;
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>(environment: Environment, durableStore: DurableStore, pendingWriter: PendingWriter, unavailableSnapshot: UnAvailableSnapshot<D>, refresh: SnapshotRefresh<D>, durableStoreErrorHandler: DurableStoreRejectionHandler, baseSnapshot?: DataSnapshot<D>): Promise<Snapshot<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 {};
@@ -0,0 +1,2 @@
1
+ import { StoreRecordError } from '@luvio/engine';
2
+ export declare function isStoreEntryError(storeRecord: unknown): storeRecord is StoreRecordError;
@@ -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";
@@ -0,0 +1,25 @@
1
+ import { DurableStore } from './DurableStore';
2
+ export declare const TTL_DURABLE_SEGMENT = "TTL_DURABLE_SEGMENT";
3
+ export interface DefaultDurableTTLOverride extends DurableTTLOverride {
4
+ namespace: 'TTL_DEFAULT_KEY';
5
+ representationName: 'TTL_DEFAULT_KEY';
6
+ }
7
+ export interface DurableTTLOverride {
8
+ namespace: string;
9
+ representationName: string;
10
+ ttl: number;
11
+ }
12
+ export interface TTLOverridesMap {
13
+ defaultTTL: DefaultDurableTTLOverride | undefined;
14
+ overrides: DurableTTLOverride[];
15
+ }
16
+ /**
17
+ * Class to set and get the TTL override values in the Durable Store
18
+ */
19
+ export declare class DurableTTLStore {
20
+ private durableStore;
21
+ constructor(durableStore: DurableStore);
22
+ setDefaultDurableTTLOverrides(ttl: number): Promise<void>;
23
+ setDurableTTLOverride(namespace: string, representationName: string, ttl: number): Promise<void>;
24
+ getDurableTTLOverrides(): Promise<TTLOverridesMap>;
25
+ }