@luvio/environments 0.100.0 → 0.102.2
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/environments.js +61 -29
- package/dist/es/es2018/makeDurable/stagingStore.d.ts +7 -0
- package/dist/es/es2018/makeDurable/ttl.d.ts +3 -0
- package/dist/es/es2018/makeDurable.d.ts +1 -2
- package/dist/umd/es2018/environments.js +60 -28
- package/dist/umd/es2018/makeDurable/stagingStore.d.ts +7 -0
- package/dist/umd/es2018/makeDurable/ttl.d.ts +3 -0
- package/dist/umd/es2018/makeDurable.d.ts +1 -2
- package/dist/umd/es5/environments.js +115 -28
- package/dist/umd/es5/makeDurable/stagingStore.d.ts +7 -0
- package/dist/umd/es5/makeDurable/ttl.d.ts +3 -0
- package/dist/umd/es5/makeDurable.d.ts +1 -2
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { emitAdapterEvent,
|
|
1
|
+
import { emitAdapterEvent, InMemoryStore, buildStaleWhileRevalidateImplementation, Reader } from '@luvio/engine';
|
|
2
2
|
|
|
3
3
|
function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
4
4
|
if (durableRecord.expiration !== undefined) {
|
|
@@ -343,6 +343,31 @@ function emitDurableEnvironmentAdapterEvent(eventData, observers) {
|
|
|
343
343
|
}, observers);
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
async function reviveTTLOverrides(ttlStore, environment) {
|
|
347
|
+
const map = await ttlStore.getDurableTTLOverrides();
|
|
348
|
+
const { defaultTTL, overrides } = map;
|
|
349
|
+
if (defaultTTL !== undefined) {
|
|
350
|
+
environment.storeSetDefaultTTLOverride(defaultTTL.ttl);
|
|
351
|
+
}
|
|
352
|
+
for (let i = 0, len = overrides.length; i < len; i++) {
|
|
353
|
+
const { namespace, representationName, ttl } = overrides[i];
|
|
354
|
+
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Returns an empty InMemoryStore that can be used for ingestion. Copies over
|
|
360
|
+
* the TTLOverrides from the given Environment's Store.
|
|
361
|
+
*/
|
|
362
|
+
function buildIngestStagingStore(environment) {
|
|
363
|
+
const store = new InMemoryStore();
|
|
364
|
+
// need to make sure any TTL overrides are brought over from real L1
|
|
365
|
+
// because storePublishMetadata uses those overrides
|
|
366
|
+
store.ttlOverrides = environment.storeGetTTLOverrides();
|
|
367
|
+
store.defaultTTLOverride = environment.storeGetDefaultTTLOverride();
|
|
368
|
+
return store;
|
|
369
|
+
}
|
|
370
|
+
|
|
346
371
|
const AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
347
372
|
const ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
348
373
|
function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, onContextLoaded) {
|
|
@@ -399,20 +424,12 @@ function isUnfulfilledSnapshot(cachedSnapshotResult) {
|
|
|
399
424
|
function makeDurable(environment, { durableStore, instrumentation }) {
|
|
400
425
|
let ingestStagingStore = null;
|
|
401
426
|
const durableTTLStore = new DurableTTLStore(durableStore);
|
|
402
|
-
let
|
|
403
|
-
|
|
404
|
-
durableTTLStore.getDurableTTLOverrides().then((map) => {
|
|
405
|
-
const { defaultTTL, overrides } = map;
|
|
406
|
-
if (defaultTTL !== undefined) {
|
|
407
|
-
environment.storeSetDefaultTTLOverride(defaultTTL.ttl);
|
|
408
|
-
}
|
|
409
|
-
for (let i = 0, len = overrides.length; i < len; i++) {
|
|
410
|
-
const { namespace, representationName, ttl } = overrides[i];
|
|
411
|
-
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
412
|
-
}
|
|
427
|
+
let initializationPromise = new Promise((resolve) => {
|
|
428
|
+
const finish = () => {
|
|
413
429
|
resolve();
|
|
414
|
-
|
|
415
|
-
}
|
|
430
|
+
initializationPromise = undefined;
|
|
431
|
+
};
|
|
432
|
+
reviveTTLOverrides(durableTTLStore, environment).then(finish);
|
|
416
433
|
});
|
|
417
434
|
//instrumentation for durable store errors
|
|
418
435
|
const durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
|
|
@@ -464,7 +481,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
464
481
|
const storePublish = function (key, data) {
|
|
465
482
|
validateNotDisposed();
|
|
466
483
|
if (ingestStagingStore === null) {
|
|
467
|
-
ingestStagingStore =
|
|
484
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
468
485
|
}
|
|
469
486
|
ingestStagingStore.publish(key, data);
|
|
470
487
|
// remove record from main luvio L1 cache while we are on the synchronous path
|
|
@@ -476,7 +493,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
476
493
|
const publishStoreMetadata = function (recordId, storeMetadata) {
|
|
477
494
|
validateNotDisposed();
|
|
478
495
|
if (ingestStagingStore === null) {
|
|
479
|
-
ingestStagingStore =
|
|
496
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
480
497
|
}
|
|
481
498
|
ingestStagingStore.publishMetadata(recordId, storeMetadata);
|
|
482
499
|
};
|
|
@@ -485,14 +502,14 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
485
502
|
// we don't ingest to the luvio L1 store from network directly, we ingest to
|
|
486
503
|
// L2 and let DurableStore on change event revive keys into luvio L1 store
|
|
487
504
|
if (ingestStagingStore === null) {
|
|
488
|
-
ingestStagingStore =
|
|
505
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
489
506
|
}
|
|
490
507
|
environment.storeIngest(key, ingest, response, luvio, ingestStagingStore);
|
|
491
508
|
};
|
|
492
509
|
const storeIngestError = function (key, errorSnapshot, storeMetadataParams, _storeOverride) {
|
|
493
510
|
validateNotDisposed();
|
|
494
511
|
if (ingestStagingStore === null) {
|
|
495
|
-
ingestStagingStore =
|
|
512
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
496
513
|
}
|
|
497
514
|
environment.storeIngestError(key, errorSnapshot, storeMetadataParams, ingestStagingStore);
|
|
498
515
|
};
|
|
@@ -525,21 +542,21 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
525
542
|
const storeEvict = function (key) {
|
|
526
543
|
validateNotDisposed();
|
|
527
544
|
if (ingestStagingStore === null) {
|
|
528
|
-
ingestStagingStore =
|
|
545
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
529
546
|
}
|
|
530
547
|
ingestStagingStore.evict(key);
|
|
531
548
|
};
|
|
532
549
|
const getNode = function (key) {
|
|
533
550
|
validateNotDisposed();
|
|
534
551
|
if (ingestStagingStore === null) {
|
|
535
|
-
ingestStagingStore =
|
|
552
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
536
553
|
}
|
|
537
554
|
return environment.getNode(key, ingestStagingStore);
|
|
538
555
|
};
|
|
539
556
|
const wrapNormalizedGraphNode = function (normalized) {
|
|
540
557
|
validateNotDisposed();
|
|
541
558
|
if (ingestStagingStore === null) {
|
|
542
|
-
ingestStagingStore =
|
|
559
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
543
560
|
}
|
|
544
561
|
return environment.wrapNormalizedGraphNode(normalized, ingestStagingStore);
|
|
545
562
|
};
|
|
@@ -607,16 +624,28 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
607
624
|
validateNotDisposed();
|
|
608
625
|
return durableTTLStore.getDurableTTLOverrides();
|
|
609
626
|
};
|
|
627
|
+
const dispatchResourceRequest = async function (request, context, eventObservers) {
|
|
628
|
+
validateNotDisposed();
|
|
629
|
+
// non-GET adapters call dispatchResourceRequest before any other luvio
|
|
630
|
+
// function so this is our chance to ensure we're initialized
|
|
631
|
+
if (initializationPromise !== undefined) {
|
|
632
|
+
await initializationPromise;
|
|
633
|
+
}
|
|
634
|
+
return environment.dispatchResourceRequest(request, context, eventObservers);
|
|
635
|
+
};
|
|
636
|
+
// NOTE: we can't use "async" keyword on this function because that would
|
|
637
|
+
// force it to always be an async response. The signature is a union
|
|
638
|
+
// of sync/async so no "awaiting" in this function, just promise-chaining
|
|
610
639
|
const applyCachePolicy = function (luvio, adapterRequestContext, buildSnapshotContext, buildCachedSnapshot, buildNetworkSnapshot) {
|
|
611
640
|
validateNotDisposed();
|
|
612
|
-
const wrappedCacheLookup = (
|
|
613
|
-
const snapshot = buildCachedSnapshot(
|
|
641
|
+
const wrappedCacheLookup = (injectedBuildSnapshotContext, injectedStoreLookup) => {
|
|
642
|
+
const snapshot = buildCachedSnapshot(injectedBuildSnapshotContext, injectedStoreLookup, luvio);
|
|
614
643
|
// if the adapter attempted to do an L1 lookup and it was unfulfilled
|
|
615
644
|
// then we can attempt an L2 lookup
|
|
616
645
|
if (isUnfulfilledSnapshot(snapshot)) {
|
|
617
646
|
const start = Date.now();
|
|
618
647
|
emitDurableEnvironmentAdapterEvent({ type: 'l2-revive-start' }, adapterRequestContext.eventObservers);
|
|
619
|
-
const revivedSnapshot = reviveSnapshot(environment, durableStore, snapshot, durableStoreErrorHandler, () =>
|
|
648
|
+
const revivedSnapshot = reviveSnapshot(environment, durableStore, snapshot, durableStoreErrorHandler, () => injectedStoreLookup(snapshot.select, snapshot.refresh)).then((result) => {
|
|
620
649
|
emitDurableEnvironmentAdapterEvent({
|
|
621
650
|
type: 'l2-revive-end',
|
|
622
651
|
duration: Date.now() - start,
|
|
@@ -630,12 +659,14 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
630
659
|
// otherwise just return what buildCachedSnapshot gave us
|
|
631
660
|
return snapshot;
|
|
632
661
|
};
|
|
633
|
-
const
|
|
662
|
+
const wrappedApplyCachePolicy = () => {
|
|
634
663
|
return environment.applyCachePolicy(luvio, adapterRequestContext, buildSnapshotContext, wrappedCacheLookup, buildNetworkSnapshot);
|
|
635
664
|
};
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
665
|
+
// GET adapters call applyCachePolicy before any other luvio
|
|
666
|
+
// function so this is our chance to ensure we're initialized
|
|
667
|
+
return initializationPromise !== undefined
|
|
668
|
+
? initializationPromise.then(wrappedApplyCachePolicy)
|
|
669
|
+
: wrappedApplyCachePolicy();
|
|
639
670
|
};
|
|
640
671
|
const getIngestStagingStoreRecords = function () {
|
|
641
672
|
validateNotDisposed();
|
|
@@ -667,7 +698,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
667
698
|
const toPrime = existingRecords !== undefined
|
|
668
699
|
? { ...revivedRecords, ...existingRecords }
|
|
669
700
|
: revivedRecords;
|
|
670
|
-
ingestStagingStore =
|
|
701
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
671
702
|
ingestStagingStore.records = toPrime;
|
|
672
703
|
const snapshotFromMemoryIngest = ingestAndBroadcastFunc();
|
|
673
704
|
return publishChangesToDurableStore().then(() => {
|
|
@@ -737,6 +768,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
737
768
|
dispose: { value: dispose },
|
|
738
769
|
publishChangesToDurableStore: { value: publishChangesToDurableStore },
|
|
739
770
|
getDurableTTLOverrides: { value: getDurableTTLOverrides },
|
|
771
|
+
dispatchResourceRequest: { value: dispatchResourceRequest },
|
|
740
772
|
applyCachePolicy: { value: applyCachePolicy },
|
|
741
773
|
getIngestStagingStoreRecords: { value: getIngestStagingStoreRecords },
|
|
742
774
|
getIngestStagingStoreMetadata: { value: getIngestStagingStoreMetadata },
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { InMemoryStore } from '@luvio/engine';
|
|
2
|
+
import type { Environment } from '@luvio/engine';
|
|
3
|
+
/**
|
|
4
|
+
* Returns an empty InMemoryStore that can be used for ingestion. Copies over
|
|
5
|
+
* the TTLOverrides from the given Environment's Store.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildIngestStagingStore(environment: Environment): InMemoryStore;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { CacheKeySet, Environment, RecordSource, Snapshot } from '@luvio/engine';
|
|
2
|
-
import { InMemoryStore } from '@luvio/engine';
|
|
1
|
+
import type { CacheKeySet, Environment, RecordSource, Snapshot, InMemoryStore } from '@luvio/engine';
|
|
3
2
|
import type { DurableStore } from './DurableStore';
|
|
4
3
|
import type { InstrumentationFunction } from './makeDurable/error';
|
|
5
4
|
import type { TTLOverridesMap } from './DurableTTLStore';
|
|
@@ -347,6 +347,31 @@
|
|
|
347
347
|
}, observers);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
+
async function reviveTTLOverrides(ttlStore, environment) {
|
|
351
|
+
const map = await ttlStore.getDurableTTLOverrides();
|
|
352
|
+
const { defaultTTL, overrides } = map;
|
|
353
|
+
if (defaultTTL !== undefined) {
|
|
354
|
+
environment.storeSetDefaultTTLOverride(defaultTTL.ttl);
|
|
355
|
+
}
|
|
356
|
+
for (let i = 0, len = overrides.length; i < len; i++) {
|
|
357
|
+
const { namespace, representationName, ttl } = overrides[i];
|
|
358
|
+
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Returns an empty InMemoryStore that can be used for ingestion. Copies over
|
|
364
|
+
* the TTLOverrides from the given Environment's Store.
|
|
365
|
+
*/
|
|
366
|
+
function buildIngestStagingStore(environment) {
|
|
367
|
+
const store = new engine.InMemoryStore();
|
|
368
|
+
// need to make sure any TTL overrides are brought over from real L1
|
|
369
|
+
// because storePublishMetadata uses those overrides
|
|
370
|
+
store.ttlOverrides = environment.storeGetTTLOverrides();
|
|
371
|
+
store.defaultTTLOverride = environment.storeGetDefaultTTLOverride();
|
|
372
|
+
return store;
|
|
373
|
+
}
|
|
374
|
+
|
|
350
375
|
const AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
351
376
|
const ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
352
377
|
function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, onContextLoaded) {
|
|
@@ -403,20 +428,12 @@
|
|
|
403
428
|
function makeDurable(environment, { durableStore, instrumentation }) {
|
|
404
429
|
let ingestStagingStore = null;
|
|
405
430
|
const durableTTLStore = new DurableTTLStore(durableStore);
|
|
406
|
-
let
|
|
407
|
-
|
|
408
|
-
durableTTLStore.getDurableTTLOverrides().then((map) => {
|
|
409
|
-
const { defaultTTL, overrides } = map;
|
|
410
|
-
if (defaultTTL !== undefined) {
|
|
411
|
-
environment.storeSetDefaultTTLOverride(defaultTTL.ttl);
|
|
412
|
-
}
|
|
413
|
-
for (let i = 0, len = overrides.length; i < len; i++) {
|
|
414
|
-
const { namespace, representationName, ttl } = overrides[i];
|
|
415
|
-
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
416
|
-
}
|
|
431
|
+
let initializationPromise = new Promise((resolve) => {
|
|
432
|
+
const finish = () => {
|
|
417
433
|
resolve();
|
|
418
|
-
|
|
419
|
-
}
|
|
434
|
+
initializationPromise = undefined;
|
|
435
|
+
};
|
|
436
|
+
reviveTTLOverrides(durableTTLStore, environment).then(finish);
|
|
420
437
|
});
|
|
421
438
|
//instrumentation for durable store errors
|
|
422
439
|
const durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
|
|
@@ -468,7 +485,7 @@
|
|
|
468
485
|
const storePublish = function (key, data) {
|
|
469
486
|
validateNotDisposed();
|
|
470
487
|
if (ingestStagingStore === null) {
|
|
471
|
-
ingestStagingStore =
|
|
488
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
472
489
|
}
|
|
473
490
|
ingestStagingStore.publish(key, data);
|
|
474
491
|
// remove record from main luvio L1 cache while we are on the synchronous path
|
|
@@ -480,7 +497,7 @@
|
|
|
480
497
|
const publishStoreMetadata = function (recordId, storeMetadata) {
|
|
481
498
|
validateNotDisposed();
|
|
482
499
|
if (ingestStagingStore === null) {
|
|
483
|
-
ingestStagingStore =
|
|
500
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
484
501
|
}
|
|
485
502
|
ingestStagingStore.publishMetadata(recordId, storeMetadata);
|
|
486
503
|
};
|
|
@@ -489,14 +506,14 @@
|
|
|
489
506
|
// we don't ingest to the luvio L1 store from network directly, we ingest to
|
|
490
507
|
// L2 and let DurableStore on change event revive keys into luvio L1 store
|
|
491
508
|
if (ingestStagingStore === null) {
|
|
492
|
-
ingestStagingStore =
|
|
509
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
493
510
|
}
|
|
494
511
|
environment.storeIngest(key, ingest, response, luvio, ingestStagingStore);
|
|
495
512
|
};
|
|
496
513
|
const storeIngestError = function (key, errorSnapshot, storeMetadataParams, _storeOverride) {
|
|
497
514
|
validateNotDisposed();
|
|
498
515
|
if (ingestStagingStore === null) {
|
|
499
|
-
ingestStagingStore =
|
|
516
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
500
517
|
}
|
|
501
518
|
environment.storeIngestError(key, errorSnapshot, storeMetadataParams, ingestStagingStore);
|
|
502
519
|
};
|
|
@@ -529,21 +546,21 @@
|
|
|
529
546
|
const storeEvict = function (key) {
|
|
530
547
|
validateNotDisposed();
|
|
531
548
|
if (ingestStagingStore === null) {
|
|
532
|
-
ingestStagingStore =
|
|
549
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
533
550
|
}
|
|
534
551
|
ingestStagingStore.evict(key);
|
|
535
552
|
};
|
|
536
553
|
const getNode = function (key) {
|
|
537
554
|
validateNotDisposed();
|
|
538
555
|
if (ingestStagingStore === null) {
|
|
539
|
-
ingestStagingStore =
|
|
556
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
540
557
|
}
|
|
541
558
|
return environment.getNode(key, ingestStagingStore);
|
|
542
559
|
};
|
|
543
560
|
const wrapNormalizedGraphNode = function (normalized) {
|
|
544
561
|
validateNotDisposed();
|
|
545
562
|
if (ingestStagingStore === null) {
|
|
546
|
-
ingestStagingStore =
|
|
563
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
547
564
|
}
|
|
548
565
|
return environment.wrapNormalizedGraphNode(normalized, ingestStagingStore);
|
|
549
566
|
};
|
|
@@ -611,16 +628,28 @@
|
|
|
611
628
|
validateNotDisposed();
|
|
612
629
|
return durableTTLStore.getDurableTTLOverrides();
|
|
613
630
|
};
|
|
631
|
+
const dispatchResourceRequest = async function (request, context, eventObservers) {
|
|
632
|
+
validateNotDisposed();
|
|
633
|
+
// non-GET adapters call dispatchResourceRequest before any other luvio
|
|
634
|
+
// function so this is our chance to ensure we're initialized
|
|
635
|
+
if (initializationPromise !== undefined) {
|
|
636
|
+
await initializationPromise;
|
|
637
|
+
}
|
|
638
|
+
return environment.dispatchResourceRequest(request, context, eventObservers);
|
|
639
|
+
};
|
|
640
|
+
// NOTE: we can't use "async" keyword on this function because that would
|
|
641
|
+
// force it to always be an async response. The signature is a union
|
|
642
|
+
// of sync/async so no "awaiting" in this function, just promise-chaining
|
|
614
643
|
const applyCachePolicy = function (luvio, adapterRequestContext, buildSnapshotContext, buildCachedSnapshot, buildNetworkSnapshot) {
|
|
615
644
|
validateNotDisposed();
|
|
616
|
-
const wrappedCacheLookup = (
|
|
617
|
-
const snapshot = buildCachedSnapshot(
|
|
645
|
+
const wrappedCacheLookup = (injectedBuildSnapshotContext, injectedStoreLookup) => {
|
|
646
|
+
const snapshot = buildCachedSnapshot(injectedBuildSnapshotContext, injectedStoreLookup, luvio);
|
|
618
647
|
// if the adapter attempted to do an L1 lookup and it was unfulfilled
|
|
619
648
|
// then we can attempt an L2 lookup
|
|
620
649
|
if (isUnfulfilledSnapshot(snapshot)) {
|
|
621
650
|
const start = Date.now();
|
|
622
651
|
emitDurableEnvironmentAdapterEvent({ type: 'l2-revive-start' }, adapterRequestContext.eventObservers);
|
|
623
|
-
const revivedSnapshot = reviveSnapshot(environment, durableStore, snapshot, durableStoreErrorHandler, () =>
|
|
652
|
+
const revivedSnapshot = reviveSnapshot(environment, durableStore, snapshot, durableStoreErrorHandler, () => injectedStoreLookup(snapshot.select, snapshot.refresh)).then((result) => {
|
|
624
653
|
emitDurableEnvironmentAdapterEvent({
|
|
625
654
|
type: 'l2-revive-end',
|
|
626
655
|
duration: Date.now() - start,
|
|
@@ -634,12 +663,14 @@
|
|
|
634
663
|
// otherwise just return what buildCachedSnapshot gave us
|
|
635
664
|
return snapshot;
|
|
636
665
|
};
|
|
637
|
-
const
|
|
666
|
+
const wrappedApplyCachePolicy = () => {
|
|
638
667
|
return environment.applyCachePolicy(luvio, adapterRequestContext, buildSnapshotContext, wrappedCacheLookup, buildNetworkSnapshot);
|
|
639
668
|
};
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
669
|
+
// GET adapters call applyCachePolicy before any other luvio
|
|
670
|
+
// function so this is our chance to ensure we're initialized
|
|
671
|
+
return initializationPromise !== undefined
|
|
672
|
+
? initializationPromise.then(wrappedApplyCachePolicy)
|
|
673
|
+
: wrappedApplyCachePolicy();
|
|
643
674
|
};
|
|
644
675
|
const getIngestStagingStoreRecords = function () {
|
|
645
676
|
validateNotDisposed();
|
|
@@ -671,7 +702,7 @@
|
|
|
671
702
|
const toPrime = existingRecords !== undefined
|
|
672
703
|
? { ...revivedRecords, ...existingRecords }
|
|
673
704
|
: revivedRecords;
|
|
674
|
-
ingestStagingStore =
|
|
705
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
675
706
|
ingestStagingStore.records = toPrime;
|
|
676
707
|
const snapshotFromMemoryIngest = ingestAndBroadcastFunc();
|
|
677
708
|
return publishChangesToDurableStore().then(() => {
|
|
@@ -741,6 +772,7 @@
|
|
|
741
772
|
dispose: { value: dispose },
|
|
742
773
|
publishChangesToDurableStore: { value: publishChangesToDurableStore },
|
|
743
774
|
getDurableTTLOverrides: { value: getDurableTTLOverrides },
|
|
775
|
+
dispatchResourceRequest: { value: dispatchResourceRequest },
|
|
744
776
|
applyCachePolicy: { value: applyCachePolicy },
|
|
745
777
|
getIngestStagingStoreRecords: { value: getIngestStagingStoreRecords },
|
|
746
778
|
getIngestStagingStoreMetadata: { value: getIngestStagingStoreMetadata },
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { InMemoryStore } from '@luvio/engine';
|
|
2
|
+
import type { Environment } from '@luvio/engine';
|
|
3
|
+
/**
|
|
4
|
+
* Returns an empty InMemoryStore that can be used for ingestion. Copies over
|
|
5
|
+
* the TTLOverrides from the given Environment's Store.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildIngestStagingStore(environment: Environment): InMemoryStore;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { CacheKeySet, Environment, RecordSource, Snapshot } from '@luvio/engine';
|
|
2
|
-
import { InMemoryStore } from '@luvio/engine';
|
|
1
|
+
import type { CacheKeySet, Environment, RecordSource, Snapshot, InMemoryStore } from '@luvio/engine';
|
|
3
2
|
import type { DurableStore } from './DurableStore';
|
|
4
3
|
import type { InstrumentationFunction } from './makeDurable/error';
|
|
5
4
|
import type { TTLOverridesMap } from './DurableTTLStore';
|
|
@@ -44,6 +44,44 @@
|
|
|
44
44
|
return __assign.apply(this, arguments);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
48
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
49
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
50
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
51
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
52
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
53
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function __generator(thisArg, body) {
|
|
58
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
59
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
60
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
61
|
+
function step(op) {
|
|
62
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
63
|
+
while (_) try {
|
|
64
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
65
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
66
|
+
switch (op[0]) {
|
|
67
|
+
case 0: case 1: t = op; break;
|
|
68
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
69
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
70
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
71
|
+
default:
|
|
72
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
73
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
74
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
75
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
76
|
+
if (t[2]) _.ops.pop();
|
|
77
|
+
_.trys.pop(); continue;
|
|
78
|
+
}
|
|
79
|
+
op = body.call(thisArg, _);
|
|
80
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
81
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
47
85
|
function __spreadArray(to, from, pack) {
|
|
48
86
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
49
87
|
if (ar || !(i in from)) {
|
|
@@ -390,6 +428,41 @@
|
|
|
390
428
|
}, observers);
|
|
391
429
|
}
|
|
392
430
|
|
|
431
|
+
function reviveTTLOverrides(ttlStore, environment) {
|
|
432
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
433
|
+
var map, defaultTTL, overrides, i, len, _a, namespace, representationName, ttl;
|
|
434
|
+
return __generator(this, function (_b) {
|
|
435
|
+
switch (_b.label) {
|
|
436
|
+
case 0: return [4 /*yield*/, ttlStore.getDurableTTLOverrides()];
|
|
437
|
+
case 1:
|
|
438
|
+
map = _b.sent();
|
|
439
|
+
defaultTTL = map.defaultTTL, overrides = map.overrides;
|
|
440
|
+
if (defaultTTL !== undefined) {
|
|
441
|
+
environment.storeSetDefaultTTLOverride(defaultTTL.ttl);
|
|
442
|
+
}
|
|
443
|
+
for (i = 0, len = overrides.length; i < len; i++) {
|
|
444
|
+
_a = overrides[i], namespace = _a.namespace, representationName = _a.representationName, ttl = _a.ttl;
|
|
445
|
+
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
446
|
+
}
|
|
447
|
+
return [2 /*return*/];
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Returns an empty InMemoryStore that can be used for ingestion. Copies over
|
|
455
|
+
* the TTLOverrides from the given Environment's Store.
|
|
456
|
+
*/
|
|
457
|
+
function buildIngestStagingStore(environment) {
|
|
458
|
+
var store = new engine.InMemoryStore();
|
|
459
|
+
// need to make sure any TTL overrides are brought over from real L1
|
|
460
|
+
// because storePublishMetadata uses those overrides
|
|
461
|
+
store.ttlOverrides = environment.storeGetTTLOverrides();
|
|
462
|
+
store.defaultTTLOverride = environment.storeGetDefaultTTLOverride();
|
|
463
|
+
return store;
|
|
464
|
+
}
|
|
465
|
+
|
|
393
466
|
var AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
394
467
|
var ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
395
468
|
function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, onContextLoaded) {
|
|
@@ -448,20 +521,12 @@
|
|
|
448
521
|
var durableStore = _a.durableStore, instrumentation = _a.instrumentation;
|
|
449
522
|
var ingestStagingStore = null;
|
|
450
523
|
var durableTTLStore = new DurableTTLStore(durableStore);
|
|
451
|
-
var
|
|
452
|
-
|
|
453
|
-
durableTTLStore.getDurableTTLOverrides().then(function (map) {
|
|
454
|
-
var defaultTTL = map.defaultTTL, overrides = map.overrides;
|
|
455
|
-
if (defaultTTL !== undefined) {
|
|
456
|
-
environment.storeSetDefaultTTLOverride(defaultTTL.ttl);
|
|
457
|
-
}
|
|
458
|
-
for (var i = 0, len = overrides.length; i < len; i++) {
|
|
459
|
-
var _a = overrides[i], namespace = _a.namespace, representationName = _a.representationName, ttl = _a.ttl;
|
|
460
|
-
environment.storeSetTTLOverride(namespace, representationName, ttl);
|
|
461
|
-
}
|
|
524
|
+
var initializationPromise = new Promise(function (resolve) {
|
|
525
|
+
var finish = function () {
|
|
462
526
|
resolve();
|
|
463
|
-
|
|
464
|
-
}
|
|
527
|
+
initializationPromise = undefined;
|
|
528
|
+
};
|
|
529
|
+
reviveTTLOverrides(durableTTLStore, environment).then(finish);
|
|
465
530
|
});
|
|
466
531
|
//instrumentation for durable store errors
|
|
467
532
|
var durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
|
|
@@ -513,7 +578,7 @@
|
|
|
513
578
|
var storePublish = function (key, data) {
|
|
514
579
|
validateNotDisposed();
|
|
515
580
|
if (ingestStagingStore === null) {
|
|
516
|
-
ingestStagingStore =
|
|
581
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
517
582
|
}
|
|
518
583
|
ingestStagingStore.publish(key, data);
|
|
519
584
|
// remove record from main luvio L1 cache while we are on the synchronous path
|
|
@@ -525,7 +590,7 @@
|
|
|
525
590
|
var publishStoreMetadata = function (recordId, storeMetadata) {
|
|
526
591
|
validateNotDisposed();
|
|
527
592
|
if (ingestStagingStore === null) {
|
|
528
|
-
ingestStagingStore =
|
|
593
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
529
594
|
}
|
|
530
595
|
ingestStagingStore.publishMetadata(recordId, storeMetadata);
|
|
531
596
|
};
|
|
@@ -534,14 +599,14 @@
|
|
|
534
599
|
// we don't ingest to the luvio L1 store from network directly, we ingest to
|
|
535
600
|
// L2 and let DurableStore on change event revive keys into luvio L1 store
|
|
536
601
|
if (ingestStagingStore === null) {
|
|
537
|
-
ingestStagingStore =
|
|
602
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
538
603
|
}
|
|
539
604
|
environment.storeIngest(key, ingest, response, luvio, ingestStagingStore);
|
|
540
605
|
};
|
|
541
606
|
var storeIngestError = function (key, errorSnapshot, storeMetadataParams, _storeOverride) {
|
|
542
607
|
validateNotDisposed();
|
|
543
608
|
if (ingestStagingStore === null) {
|
|
544
|
-
ingestStagingStore =
|
|
609
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
545
610
|
}
|
|
546
611
|
environment.storeIngestError(key, errorSnapshot, storeMetadataParams, ingestStagingStore);
|
|
547
612
|
};
|
|
@@ -574,21 +639,21 @@
|
|
|
574
639
|
var storeEvict = function (key) {
|
|
575
640
|
validateNotDisposed();
|
|
576
641
|
if (ingestStagingStore === null) {
|
|
577
|
-
ingestStagingStore =
|
|
642
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
578
643
|
}
|
|
579
644
|
ingestStagingStore.evict(key);
|
|
580
645
|
};
|
|
581
646
|
var getNode = function (key) {
|
|
582
647
|
validateNotDisposed();
|
|
583
648
|
if (ingestStagingStore === null) {
|
|
584
|
-
ingestStagingStore =
|
|
649
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
585
650
|
}
|
|
586
651
|
return environment.getNode(key, ingestStagingStore);
|
|
587
652
|
};
|
|
588
653
|
var wrapNormalizedGraphNode = function (normalized) {
|
|
589
654
|
validateNotDisposed();
|
|
590
655
|
if (ingestStagingStore === null) {
|
|
591
|
-
ingestStagingStore =
|
|
656
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
592
657
|
}
|
|
593
658
|
return environment.wrapNormalizedGraphNode(normalized, ingestStagingStore);
|
|
594
659
|
};
|
|
@@ -654,16 +719,35 @@
|
|
|
654
719
|
validateNotDisposed();
|
|
655
720
|
return durableTTLStore.getDurableTTLOverrides();
|
|
656
721
|
};
|
|
722
|
+
var dispatchResourceRequest = function (request, context, eventObservers) {
|
|
723
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
724
|
+
return __generator(this, function (_a) {
|
|
725
|
+
switch (_a.label) {
|
|
726
|
+
case 0:
|
|
727
|
+
validateNotDisposed();
|
|
728
|
+
if (!(initializationPromise !== undefined)) return [3 /*break*/, 2];
|
|
729
|
+
return [4 /*yield*/, initializationPromise];
|
|
730
|
+
case 1:
|
|
731
|
+
_a.sent();
|
|
732
|
+
_a.label = 2;
|
|
733
|
+
case 2: return [2 /*return*/, environment.dispatchResourceRequest(request, context, eventObservers)];
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
});
|
|
737
|
+
};
|
|
738
|
+
// NOTE: we can't use "async" keyword on this function because that would
|
|
739
|
+
// force it to always be an async response. The signature is a union
|
|
740
|
+
// of sync/async so no "awaiting" in this function, just promise-chaining
|
|
657
741
|
var applyCachePolicy = function (luvio, adapterRequestContext, buildSnapshotContext, buildCachedSnapshot, buildNetworkSnapshot) {
|
|
658
742
|
validateNotDisposed();
|
|
659
|
-
var wrappedCacheLookup = function (
|
|
660
|
-
var snapshot = buildCachedSnapshot(
|
|
743
|
+
var wrappedCacheLookup = function (injectedBuildSnapshotContext, injectedStoreLookup) {
|
|
744
|
+
var snapshot = buildCachedSnapshot(injectedBuildSnapshotContext, injectedStoreLookup, luvio);
|
|
661
745
|
// if the adapter attempted to do an L1 lookup and it was unfulfilled
|
|
662
746
|
// then we can attempt an L2 lookup
|
|
663
747
|
if (isUnfulfilledSnapshot(snapshot)) {
|
|
664
748
|
var start_1 = Date.now();
|
|
665
749
|
emitDurableEnvironmentAdapterEvent({ type: 'l2-revive-start' }, adapterRequestContext.eventObservers);
|
|
666
|
-
var revivedSnapshot = reviveSnapshot(environment, durableStore, snapshot, durableStoreErrorHandler, function () { return
|
|
750
|
+
var revivedSnapshot = reviveSnapshot(environment, durableStore, snapshot, durableStoreErrorHandler, function () { return injectedStoreLookup(snapshot.select, snapshot.refresh); }).then(function (result) {
|
|
667
751
|
emitDurableEnvironmentAdapterEvent({
|
|
668
752
|
type: 'l2-revive-end',
|
|
669
753
|
duration: Date.now() - start_1,
|
|
@@ -677,12 +761,14 @@
|
|
|
677
761
|
// otherwise just return what buildCachedSnapshot gave us
|
|
678
762
|
return snapshot;
|
|
679
763
|
};
|
|
680
|
-
var
|
|
764
|
+
var wrappedApplyCachePolicy = function () {
|
|
681
765
|
return environment.applyCachePolicy(luvio, adapterRequestContext, buildSnapshotContext, wrappedCacheLookup, buildNetworkSnapshot);
|
|
682
766
|
};
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
767
|
+
// GET adapters call applyCachePolicy before any other luvio
|
|
768
|
+
// function so this is our chance to ensure we're initialized
|
|
769
|
+
return initializationPromise !== undefined
|
|
770
|
+
? initializationPromise.then(wrappedApplyCachePolicy)
|
|
771
|
+
: wrappedApplyCachePolicy();
|
|
686
772
|
};
|
|
687
773
|
var getIngestStagingStoreRecords = function () {
|
|
688
774
|
validateNotDisposed();
|
|
@@ -713,7 +799,7 @@
|
|
|
713
799
|
var ingestAndPublish = function (revivedRecords) {
|
|
714
800
|
var toPrime = existingRecords !== undefined
|
|
715
801
|
? __assign(__assign({}, revivedRecords), existingRecords) : revivedRecords;
|
|
716
|
-
ingestStagingStore =
|
|
802
|
+
ingestStagingStore = buildIngestStagingStore(environment);
|
|
717
803
|
ingestStagingStore.records = toPrime;
|
|
718
804
|
var snapshotFromMemoryIngest = ingestAndBroadcastFunc();
|
|
719
805
|
return publishChangesToDurableStore().then(function () {
|
|
@@ -785,6 +871,7 @@
|
|
|
785
871
|
dispose: { value: dispose },
|
|
786
872
|
publishChangesToDurableStore: { value: publishChangesToDurableStore },
|
|
787
873
|
getDurableTTLOverrides: { value: getDurableTTLOverrides },
|
|
874
|
+
dispatchResourceRequest: { value: dispatchResourceRequest },
|
|
788
875
|
applyCachePolicy: { value: applyCachePolicy },
|
|
789
876
|
getIngestStagingStoreRecords: { value: getIngestStagingStoreRecords },
|
|
790
877
|
getIngestStagingStoreMetadata: { value: getIngestStagingStoreMetadata },
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { InMemoryStore } from '@luvio/engine';
|
|
2
|
+
import type { Environment } from '@luvio/engine';
|
|
3
|
+
/**
|
|
4
|
+
* Returns an empty InMemoryStore that can be used for ingestion. Copies over
|
|
5
|
+
* the TTLOverrides from the given Environment's Store.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildIngestStagingStore(environment: Environment): InMemoryStore;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { CacheKeySet, Environment, RecordSource, Snapshot } from '@luvio/engine';
|
|
2
|
-
import { InMemoryStore } from '@luvio/engine';
|
|
1
|
+
import type { CacheKeySet, Environment, RecordSource, Snapshot, InMemoryStore } from '@luvio/engine';
|
|
3
2
|
import type { DurableStore } from './DurableStore';
|
|
4
3
|
import type { InstrumentationFunction } from './makeDurable/error';
|
|
5
4
|
import type { TTLOverridesMap } from './DurableTTLStore';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luvio/environments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.102.2",
|
|
4
4
|
"description": "Luvio Environments",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"watch": "yarn build --watch"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@luvio/engine": "0.
|
|
26
|
+
"@luvio/engine": "0.102.2"
|
|
27
27
|
},
|
|
28
28
|
"bundlesize": [
|
|
29
29
|
{
|