New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@data-eden/cache

Package Overview
Dependencies
Maintainers
4
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@data-eden/cache - npm Package Compare versions

Comparing version 0.7.2 to 0.8.0

dist/cache-revision.d.ts

2

__tests__/index-test.ts

@@ -296,3 +296,3 @@ import { describe, it, expect } from 'vitest';

//Validate Cache before commit
// Validate Cache before commit
expect(await cache.get('book:1')).toEqual({

@@ -299,0 +299,0 @@ 'book:1': { title: 'A History of the English speaking peoples' },

import type { Cache, CacheOptions, DefaultRegistry } from './index.js';
export declare const DEFAULT_EXPIRATION: {
lru: number;
ttl: number;
};
export declare const DEFAULT_ENTRY_STATE: {
retained: {
lru: boolean;
ttl: number;
};
};
export declare function buildCache<CacheKeyRegistry extends DefaultRegistry = DefaultRegistry, Key extends keyof CacheKeyRegistry = keyof CacheKeyRegistry, $Debug = unknown, UserExtensionData = unknown>(options?: CacheOptions<CacheKeyRegistry, Key, $Debug, UserExtensionData>): Cache<CacheKeyRegistry, Key, $Debug, UserExtensionData>;
export declare function assert<T>(value: T, message: string | (() => string)): asserts value;
//# sourceMappingURL=cache.d.ts.map

@@ -12,4 +12,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {

};
var _CacheImpl_instances, _CacheImpl_weakCache, _CacheImpl_entryRevisions, _CacheImpl_cacheOptions, _CacheImpl_cacheEntryState, _CacheImpl_lruCache, _CacheImpl_lruPolicy, _CacheImpl_txCommitLockOwner, _CacheImpl_txCommitLockQueue, _CacheImpl_deferTxLock, _CacheImpl_aquireTxCommitLock, _CacheImpl_releaseTxCommitLock, _CacheImpl_commitUpdatesAndReleaseLock, _LiveCacheTransactionImpl_instances, _LiveCacheTransactionImpl_originalCacheReference, _LiveCacheTransactionImpl_transactionalCache, _LiveCacheTransactionImpl_commitingTransaction, _LiveCacheTransactionImpl_cacheEntryState, _LiveCacheTransactionImpl_userOptionRetentionPolicy, _LiveCacheTransactionImpl_ttlPolicy, _LiveCacheTransactionImpl_lruPolicy, _LiveCacheTransactionImpl_localRevisions, _LiveCacheTransactionImpl_entryRevisions, _LiveCacheTransactionImpl_transactionOperations, _LiveCacheTransactionImpl_getMergeStrategy, _LiveCacheTransactionImpl_getRevisionStrategy, _LiveCacheTransactionImpl_prepareTransaction, _CommittingTransactionImpl_mergedRevisions, _LruCacheImpl_max, _LruCacheImpl_lruCache;
let REVISION_COUNTER = 0;
var _CacheImpl_instances, _CacheImpl_weakCache, _CacheImpl_entryRevisions, _CacheImpl_cacheOptions, _CacheImpl_cacheEntryState, _CacheImpl_lruCache, _CacheImpl_lruPolicy, _CacheImpl_cleanup, _CacheImpl_cacheRevisionTransaction, _CacheImpl_txCommitLockOwner, _CacheImpl_txCommitLockQueue, _CacheImpl_deferTxLock, _CacheImpl_aquireTxCommitLock, _CacheImpl_releaseTxCommitLock, _CacheImpl_applyRetentionPolicies, _CacheImpl_commitUpdatesAndReleaseLock, _CacheImpl_updateSavedRevisions, _LruCacheImpl_max, _LruCacheImpl_lruCache;
import { LiveCacheTransactionImpl } from './live-transaction.js';
import { CommittingTransactionImpl } from './cache-revision.js';
export const DEFAULT_EXPIRATION = { lru: 10000, ttl: 60000 };
export const DEFAULT_ENTRY_STATE = {
retained: { lru: false, ttl: DEFAULT_EXPIRATION.ttl },
};
class CacheImpl {

@@ -24,6 +29,15 @@ constructor(options) {

_CacheImpl_lruPolicy.set(this, void 0);
_CacheImpl_cleanup.set(this, void 0);
_CacheImpl_cacheRevisionTransaction.set(this, void 0);
_CacheImpl_txCommitLockOwner.set(this, void 0);
_CacheImpl_txCommitLockQueue.set(this, void 0);
__classPrivateFieldSet(this, _CacheImpl_weakCache, new Map(), "f");
__classPrivateFieldSet(this, _CacheImpl_cacheOptions, options, "f");
__classPrivateFieldSet(this, _CacheImpl_cacheOptions, {
hooks: {
commit: options?.hooks?.commit,
entitymergeStrategy: options?.hooks?.entitymergeStrategy || defaultMergeStrategy,
revisionMergeStrategy: options?.hooks?.revisionMergeStrategy || defaultRetensionStrategy,
},
expiration: options?.expiration || DEFAULT_EXPIRATION,
}, "f");
__classPrivateFieldSet(this, _CacheImpl_lruPolicy, DEFAULT_EXPIRATION.lru, "f");

@@ -39,2 +53,10 @@ __classPrivateFieldSet(this, _CacheImpl_entryRevisions, new Map(), "f");

__classPrivateFieldSet(this, _CacheImpl_txCommitLockQueue, [], "f");
// A `FinalizationRegistry` is created to remove the strongly held keys after the value is garbage-collected.
__classPrivateFieldSet(this, _CacheImpl_cleanup, new FinalizationRegistry((key) => {
// See note below on concurrency considerations.
const cache = __classPrivateFieldGet(this, _CacheImpl_weakCache, "f");
const ref = cache.get(key);
if (ref && !ref.deref())
cache.delete(key);
}), "f");
}

@@ -80,5 +102,6 @@ /**

let [key, value, state] = entry;
// TODO: finalizregistry
let clone = structuredClone(value);
__classPrivateFieldGet(this, _CacheImpl_weakCache, "f").set(key, new WeakRef(clone));
// Register FinalizationRegistry so strongly held keys are removed
__classPrivateFieldGet(this, _CacheImpl_cleanup, "f").register(clone, key);
__classPrivateFieldGet(this, _CacheImpl_lruCache, "f").set(key, clone);

@@ -104,3 +127,3 @@ __classPrivateFieldGet(this, _CacheImpl_cacheEntryState, "f").set(key, state);

*/
async *[(_CacheImpl_weakCache = new WeakMap(), _CacheImpl_entryRevisions = new WeakMap(), _CacheImpl_cacheOptions = new WeakMap(), _CacheImpl_cacheEntryState = new WeakMap(), _CacheImpl_lruCache = new WeakMap(), _CacheImpl_lruPolicy = new WeakMap(), _CacheImpl_txCommitLockOwner = new WeakMap(), _CacheImpl_txCommitLockQueue = new WeakMap(), _CacheImpl_instances = new WeakSet(), Symbol.asyncIterator)]() {
async *[(_CacheImpl_weakCache = new WeakMap(), _CacheImpl_entryRevisions = new WeakMap(), _CacheImpl_cacheOptions = new WeakMap(), _CacheImpl_cacheEntryState = new WeakMap(), _CacheImpl_lruCache = new WeakMap(), _CacheImpl_lruPolicy = new WeakMap(), _CacheImpl_cleanup = new WeakMap(), _CacheImpl_cacheRevisionTransaction = new WeakMap(), _CacheImpl_txCommitLockOwner = new WeakMap(), _CacheImpl_txCommitLockQueue = new WeakMap(), _CacheImpl_instances = new WeakSet(), Symbol.asyncIterator)]() {
// yield weekly held values

@@ -157,7 +180,26 @@ for await (const [key] of __classPrivateFieldGet(this, _CacheImpl_weakCache, "f")) {

const commitUpdatesAndReleaseLock = (transaction, txUpdates) => __classPrivateFieldGet(this, _CacheImpl_instances, "m", _CacheImpl_commitUpdatesAndReleaseLock).call(this, transaction, txUpdates);
return new LiveCacheTransactionImpl(this, {
const applyRetentionPolicies = (cacheKey, liveTx) => __classPrivateFieldGet(this, _CacheImpl_instances, "m", _CacheImpl_applyRetentionPolicies).call(this, cacheKey, liveTx);
const updateSavedRevisions = (localRevisionsMap) => __classPrivateFieldGet(this, _CacheImpl_instances, "m", _CacheImpl_updateSavedRevisions).call(this, localRevisionsMap);
const cacheEntriesBeforeTransaction = new Map();
const cacheRevisionsBeforeTransaction = new Map();
for await (const [cacheKey, value] of this.entries()) {
cacheEntriesBeforeTransaction.set(cacheKey, value);
}
for await (const [cacheKey] of this.entries()) {
const revisions = [];
for await (const revision of this.entryRevisions(cacheKey)) {
revisions.push(revision);
}
cacheRevisionsBeforeTransaction.set(cacheKey, revisions);
}
const transactionOperations = {
aquireTxCommitLock,
releaseTxCommitLock,
applyRetentionPolicies,
updateSavedRevisions,
commitUpdatesAndReleaseLock,
});
};
__classPrivateFieldSet(this, _CacheImpl_cacheRevisionTransaction, new CommittingTransactionImpl(this, cacheRevisionsBeforeTransaction), "f");
const liveTx = new LiveCacheTransactionImpl(this, cacheEntriesBeforeTransaction, cacheRevisionsBeforeTransaction, transactionOperations);
return liveTx;
}

@@ -178,3 +220,3 @@ }

};
}, _CacheImpl_aquireTxCommitLock = function _CacheImpl_aquireTxCommitLock(transaction) {
}, _CacheImpl_aquireTxCommitLock = async function _CacheImpl_aquireTxCommitLock(transaction) {
if (__classPrivateFieldGet(this, _CacheImpl_txCommitLockOwner, "f") === null) {

@@ -200,2 +242,6 @@ __classPrivateFieldSet(this, _CacheImpl_txCommitLockOwner, transaction, "f");

}
}, _CacheImpl_applyRetentionPolicies = async function _CacheImpl_applyRetentionPolicies(cacheKey, liveTx) {
const revisionStrategy = __classPrivateFieldGet(this, _CacheImpl_cacheOptions, "f")?.hooks?.revisionMergeStrategy ||
defaultRetensionStrategy;
await revisionStrategy(cacheKey, __classPrivateFieldGet(this, _CacheImpl_cacheRevisionTransaction, "f"));
}, _CacheImpl_commitUpdatesAndReleaseLock = function _CacheImpl_commitUpdatesAndReleaseLock(transaction, txUpdates) {

@@ -206,4 +252,5 @@ assert(__classPrivateFieldGet(this, _CacheImpl_txCommitLockOwner, "f") === transaction, 'transaction owner incorrectly assigned when commiting updates');

const [key, value, state] = entry;
// TODO: finalizregistry
__classPrivateFieldGet(this, _CacheImpl_weakCache, "f").set(key, new WeakRef(value));
// Register FinalizationRegistry so strongly held keys are removed
__classPrivateFieldGet(this, _CacheImpl_cleanup, "f").register(value, key);
__classPrivateFieldGet(this, _CacheImpl_cacheEntryState, "f").set(key, state);

@@ -215,10 +262,4 @@ if (state?.retained.lru) {

// Write transaction revisions entries to the main cache
for (const [cacheKey, revision] of txUpdates.entryRevisions) {
if (__classPrivateFieldGet(this, _CacheImpl_entryRevisions, "f").has(cacheKey)) {
const revisions = __classPrivateFieldGet(this, _CacheImpl_entryRevisions, "f").get(cacheKey)?.concat(revision) || [];
__classPrivateFieldGet(this, _CacheImpl_entryRevisions, "f").set(cacheKey, revisions);
}
else {
__classPrivateFieldGet(this, _CacheImpl_entryRevisions, "f").set(cacheKey, revision);
}
for (const [cacheKey, revision,] of __classPrivateFieldGet(this, _CacheImpl_cacheRevisionTransaction, "f").mergedEntryRevisions()) {
__classPrivateFieldGet(this, _CacheImpl_entryRevisions, "f").set(cacheKey, revision);
}

@@ -234,251 +275,5 @@ __classPrivateFieldGet(this, _CacheImpl_instances, "m", _CacheImpl_releaseTxCommitLock).call(this, transaction);

}
}, _CacheImpl_updateSavedRevisions = function _CacheImpl_updateSavedRevisions(localRevisionsMap) {
__classPrivateFieldGet(this, _CacheImpl_cacheRevisionTransaction, "f")?.updateRevisions(localRevisionsMap);
};
class LiveCacheTransactionImpl {
constructor(originalCache, transactionOperations) {
_LiveCacheTransactionImpl_instances.add(this);
_LiveCacheTransactionImpl_originalCacheReference.set(this, void 0);
_LiveCacheTransactionImpl_transactionalCache.set(this, void 0);
_LiveCacheTransactionImpl_commitingTransaction.set(this, void 0);
_LiveCacheTransactionImpl_cacheEntryState.set(this, void 0);
_LiveCacheTransactionImpl_userOptionRetentionPolicy.set(this, void 0);
_LiveCacheTransactionImpl_ttlPolicy.set(this, void 0);
_LiveCacheTransactionImpl_lruPolicy.set(this, void 0);
_LiveCacheTransactionImpl_localRevisions.set(this, void 0);
_LiveCacheTransactionImpl_entryRevisions.set(this, void 0);
_LiveCacheTransactionImpl_transactionOperations.set(this, void 0);
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_originalCacheReference, originalCache, "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_transactionalCache, new Map(), "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_cacheEntryState, new Map(), "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_ttlPolicy, DEFAULT_EXPIRATION.ttl, "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_lruPolicy, DEFAULT_EXPIRATION.lru, "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_localRevisions, new Map(), "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_entryRevisions, new Map(), "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").getCacheOptions()?.expiration ||
DEFAULT_EXPIRATION, "f");
if (__classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f") &&
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f")?.lru &&
typeof __classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f").lru === 'number') {
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_lruPolicy, __classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f").lru, "f");
}
if (__classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f") &&
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f")?.ttl &&
typeof __classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f").ttl === 'number') {
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_ttlPolicy, __classPrivateFieldGet(this, _LiveCacheTransactionImpl_userOptionRetentionPolicy, "f").ttl, "f");
}
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_commitingTransaction, new CommittingTransactionImpl(), "f");
__classPrivateFieldSet(this, _LiveCacheTransactionImpl_transactionOperations, transactionOperations, "f");
}
async *[(_LiveCacheTransactionImpl_originalCacheReference = new WeakMap(), _LiveCacheTransactionImpl_transactionalCache = new WeakMap(), _LiveCacheTransactionImpl_commitingTransaction = new WeakMap(), _LiveCacheTransactionImpl_cacheEntryState = new WeakMap(), _LiveCacheTransactionImpl_userOptionRetentionPolicy = new WeakMap(), _LiveCacheTransactionImpl_ttlPolicy = new WeakMap(), _LiveCacheTransactionImpl_lruPolicy = new WeakMap(), _LiveCacheTransactionImpl_localRevisions = new WeakMap(), _LiveCacheTransactionImpl_entryRevisions = new WeakMap(), _LiveCacheTransactionImpl_transactionOperations = new WeakMap(), _LiveCacheTransactionImpl_instances = new WeakSet(), Symbol.asyncIterator)]() {
for await (const [key, value] of this.localEntries()) {
const state = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_cacheEntryState, "f").get(key);
yield [key, value, state];
}
}
async get(cacheKey) {
// will check the transaction entries and fall back to the cache if the transaction hasn't written to the key yet.
let cachedValue;
for await (const [key, value] of this.localEntries()) {
if (key === cacheKey) {
cachedValue = value;
break;
}
}
return cachedValue || (await __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").get(cacheKey));
}
localEntries() {
const localEntriesIterator = {
async *[Symbol.asyncIterator](localEntryMap) {
for (const [key, value] of localEntryMap) {
yield [key, value];
}
},
};
return localEntriesIterator[Symbol.asyncIterator](__classPrivateFieldGet(this, _LiveCacheTransactionImpl_transactionalCache, "f"));
}
async entries() {
const entriesIterator = {
async *[Symbol.asyncIterator](localEntriesIterator, cacheRef) {
for await (const [key, transactionValue] of localEntriesIterator) {
yield [key, transactionValue];
const cacheValue = await cacheRef.get(key);
if (cacheValue) {
yield [key, cacheValue];
}
}
},
};
return entriesIterator[Symbol.asyncIterator](this.localEntries(), __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f"));
}
localRevisions(cacheKey) {
const entryRevisionIterator = {
async *[Symbol.asyncIterator](revisions) {
for (const revision of revisions) {
yield revision;
}
},
};
const revisions = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").get(cacheKey) || [];
return entryRevisionIterator[Symbol.asyncIterator](revisions);
}
entryRevisions(cacheKey) {
const entryRevisionIterator = {
async *[Symbol.asyncIterator](revisions) {
for (const revision of revisions) {
yield revision;
}
},
};
const entryRevisions = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_entryRevisions, "f").get(cacheKey) || [];
const localRevisions = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").get(cacheKey) || [];
return entryRevisionIterator[Symbol.asyncIterator](entryRevisions.concat(localRevisions));
}
async set(cacheKey, value) {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_transactionalCache, "f").set(cacheKey, value);
// Update cache entry state
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_cacheEntryState, "f").set(cacheKey, {
retained: { lru: true, ttl: __classPrivateFieldGet(this, _LiveCacheTransactionImpl_ttlPolicy, "f") },
lastAccessed: Date.now(),
});
return (await this.get(cacheKey));
}
async delete(cacheKey) {
// tx.delete will actually need to write a tombstone in the transaction entries and the actual delete will occur when the transaction is committed to the cache.
// The semantics of tx.delete's return value should be "did i delete something?"
if (await this.get(cacheKey)) {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_transactionalCache, "f").delete(cacheKey);
// Update cache entry state to indicate as delete in order to actually be deleted from cache when commit
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_cacheEntryState, "f").set(cacheKey, {
retained: { lru: false, ttl: 0 },
deletedRecordInTransaction: true,
lastAccessed: Date.now(),
});
return true;
}
return false;
}
async merge(cacheKey, entity, options) {
const mergeStrategy = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_instances, "m", _LiveCacheTransactionImpl_getMergeStrategy).call(this, options?.entityMergeStrategy);
// get current cache value within this transaction
const currentValue = await __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").get(cacheKey);
const revisionCounter = REVISION_COUNTER++;
// get merged entity
const mergedEntity = currentValue
? entity
: mergeStrategy(cacheKey, {
entity,
revision: REVISION_COUNTER++,
revisionContext: options?.revisionContext,
}, currentValue, this);
// Update transactional cache with merged entity
// Calling set here will in turn also update cacheEntryState
await this.set(cacheKey, mergedEntity);
// Update local & entry revisions with new revision values
const revision = {
entity: mergedEntity,
revision: revisionCounter,
revisionContext: options?.revisionContext,
};
if (__classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").has(cacheKey)) {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").get(cacheKey)?.push(revision);
}
else {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").set(cacheKey, [revision]);
}
return mergedEntity;
}
async commit(options) {
await __classPrivateFieldGet(this, _LiveCacheTransactionImpl_transactionOperations, "f").aquireTxCommitLock(this);
let transactionUpdates;
try {
transactionUpdates = await __classPrivateFieldGet(this, _LiveCacheTransactionImpl_instances, "m", _LiveCacheTransactionImpl_prepareTransaction).call(this);
return __classPrivateFieldGet(this, _LiveCacheTransactionImpl_transactionOperations, "f").commitUpdatesAndReleaseLock(this, transactionUpdates);
}
catch (e) {
throw new Error('Failed to prepare transaction updates');
}
finally {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_transactionOperations, "f").releaseTxCommitLock(this);
}
}
}
_LiveCacheTransactionImpl_getMergeStrategy = function _LiveCacheTransactionImpl_getMergeStrategy(transactionMergeStrategy) {
const cacheWideMergeStrategy = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").getCacheOptions()?.hooks
?.entitymergeStrategy;
return (transactionMergeStrategy || cacheWideMergeStrategy || defaultMergeStrategy);
}, _LiveCacheTransactionImpl_getRevisionStrategy = function _LiveCacheTransactionImpl_getRevisionStrategy() {
const cacheWideRevisionStrategy = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").getCacheOptions()?.hooks
?.revisionMergeStrategy;
return cacheWideRevisionStrategy || defaultRevisionStrategy;
}, _LiveCacheTransactionImpl_prepareTransaction = async function _LiveCacheTransactionImpl_prepareTransaction() {
const trasactionCacheEntries = [];
for await (const [cacheKey, value] of this.localEntries()) {
const latestCacheValue = await __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").get(cacheKey);
let mergedEntityToCommit;
const mergeStrategy = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_instances, "m", _LiveCacheTransactionImpl_getMergeStrategy).call(this);
if (latestCacheValue) {
// TODO fix revision
mergedEntityToCommit = mergeStrategy(cacheKey, { entity: value, revision: 3 }, latestCacheValue, this);
}
else {
mergedEntityToCommit = value;
}
const structuredClonedValue = structuredClone(mergedEntityToCommit);
const state = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_cacheEntryState, "f").get(cacheKey) || DEFAULT_ENTRY_STATE;
trasactionCacheEntries.push([cacheKey, structuredClonedValue, state]);
// Update saved revisions of the entity
const localRevisions = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").get(cacheKey);
let revisionNumber = localRevisions && localRevisions[localRevisions.length - 1].revision
? localRevisions[localRevisions.length - 1].revision
: 0;
const entityRevision = {
entity: mergedEntityToCommit,
revision: ++revisionNumber,
};
if (__classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").has(cacheKey)) {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").get(cacheKey)?.push(entityRevision);
}
else {
__classPrivateFieldGet(this, _LiveCacheTransactionImpl_localRevisions, "f").set(cacheKey, [entityRevision]);
}
const revisionStrategy = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_instances, "m", _LiveCacheTransactionImpl_getRevisionStrategy).call(this);
// Update revisions based on revision strategy
await revisionStrategy(cacheKey, __classPrivateFieldGet(this, _LiveCacheTransactionImpl_commitingTransaction, "f"), this);
}
// Call commit hook to apply custom retention policies before commit (if passed by cache options)
const commitCallback = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_originalCacheReference, "f").getCacheOptions()?.hooks?.commit;
if (commitCallback) {
await commitCallback(this);
}
const mergedRevisions = __classPrivateFieldGet(this, _LiveCacheTransactionImpl_commitingTransaction, "f").mergedRevisions();
return {
entries: trasactionCacheEntries,
entryRevisions: mergedRevisions,
};
};
class CommittingTransactionImpl {
constructor() {
_CommittingTransactionImpl_mergedRevisions.set(this, void 0);
this.cache = {
clearRevisions(tx, id) {
__classPrivateFieldGet(tx, _CommittingTransactionImpl_mergedRevisions, "f").delete(id);
},
appendRevisions(tx, id, revisions) {
if (__classPrivateFieldGet(tx, _CommittingTransactionImpl_mergedRevisions, "f").has(id)) {
const appendedRevisions = __classPrivateFieldGet(tx, _CommittingTransactionImpl_mergedRevisions, "f").get(id)?.concat(revisions) || [];
__classPrivateFieldGet(tx, _CommittingTransactionImpl_mergedRevisions, "f").set(id, appendedRevisions);
}
else {
__classPrivateFieldGet(tx, _CommittingTransactionImpl_mergedRevisions, "f").set(id, revisions);
}
},
};
__classPrivateFieldSet(this, _CommittingTransactionImpl_mergedRevisions, new Map(), "f");
}
[(_CommittingTransactionImpl_mergedRevisions = new WeakMap(), Symbol.asyncIterator)]() {
throw new Error('Method not implemented.');
}
mergedRevisions() {
return __classPrivateFieldGet(this, _CommittingTransactionImpl_mergedRevisions, "f");
}
}
export function buildCache(options) {

@@ -511,5 +306,8 @@ return new CacheImpl(options);

_LruCacheImpl_max = new WeakMap(), _LruCacheImpl_lruCache = new WeakMap();
const DEFAULT_EXPIRATION = { lru: 10000, ttl: 60000 };
const DEFAULT_ENTRY_STATE = {
retained: { lru: false, ttl: DEFAULT_EXPIRATION.ttl },
const defaultRetensionStrategy = async function retainAllRevisions(id, commitingRevisionTx) {
const revisions = [];
for await (const revision of commitingRevisionTx.entryRevisions(id)) {
revisions.push(revision);
}
commitingRevisionTx.cache.appendRevisions(id, [...revisions]);
};

@@ -519,9 +317,2 @@ const defaultMergeStrategy = function deepMergeStratey(id, { entity }, current, tx) {

};
const defaultRevisionStrategy = async function retainAllRevisions(id, commitTx, liveTx) {
const revisions = [];
for await (const revision of liveTx.localRevisions(id)) {
revisions.push(revision);
}
commitTx.cache.appendRevisions(commitTx, id, [...revisions]);
};
// eslint-disable-next-line

@@ -528,0 +319,0 @@ const isObject = function isObject(obj) {

{
"$schema": "https://json.schemastore.org/package.json",
"name": "@data-eden/cache",
"version": "0.7.2",
"version": "0.8.0",
"repository": {

@@ -6,0 +6,0 @@ "type": "git",

@@ -0,1 +1,3 @@

import { LiveCacheTransactionImpl } from './live-transaction.js';
import { CommittingTransactionImpl } from './cache-revision.js';
import type {

@@ -10,16 +12,15 @@ Cache,

CachedEntityRevision,
ExpirationPolicy,
CacheOptions,
DefaultRegistry,
LruCache,
CacheTransactionDebugAPIs,
EntityMergeStrategy,
// RevisionMergeStrategy,
TransactionUpdates,
TransactionOperations,
DeferredTransactionLock,
} from './index.js';
let REVISION_COUNTER = 0;
export const DEFAULT_EXPIRATION = { lru: 10000, ttl: 60000 };
export const DEFAULT_ENTRY_STATE = {
retained: { lru: false, ttl: DEFAULT_EXPIRATION.ttl },
};
class CacheImpl<

@@ -40,2 +41,9 @@ CacheKeyRegistry extends DefaultRegistry,

#lruPolicy: number;
#cleanup: FinalizationRegistry<Key>;
#cacheRevisionTransaction!: CommittingTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>;

@@ -62,3 +70,14 @@ #txCommitLockOwner: LiveCacheTransaction<

this.#weakCache = new Map<Key, WeakRef<CacheKeyRegistry[Key]>>();
this.#cacheOptions = options;
this.#cacheOptions = {
hooks: {
commit: options?.hooks?.commit,
entitymergeStrategy:
options?.hooks?.entitymergeStrategy || defaultMergeStrategy,
revisionMergeStrategy:
options?.hooks?.revisionMergeStrategy || defaultRetensionStrategy,
},
expiration: options?.expiration || DEFAULT_EXPIRATION,
};
this.#lruPolicy = DEFAULT_EXPIRATION.lru;

@@ -82,2 +101,10 @@ this.#entryRevisions = new Map<

this.#txCommitLockQueue = [];
// A `FinalizationRegistry` is created to remove the strongly held keys after the value is garbage-collected.
this.#cleanup = new FinalizationRegistry((key: Key) => {
// See note below on concurrency considerations.
const cache = this.#weakCache;
const ref = cache.get(key);
if (ref && !ref.deref()) cache.delete(key);
});
}

@@ -145,6 +172,8 @@

// TODO: finalizregistry
let clone = structuredClone(value) as CacheKeyRegistry[Key];
this.#weakCache.set(key, new WeakRef(clone));
// Register FinalizationRegistry so strongly held keys are removed
this.#cleanup.register(clone, key);
this.#lruCache.set(key, clone);

@@ -157,2 +186,3 @@ this.#cacheEntryState.set(key, state);

};
if (this.#entryRevisions.has(key)) {

@@ -261,3 +291,3 @@ const revisions =

#aquireTxCommitLock(
async #aquireTxCommitLock(
transaction: LiveCacheTransaction<

@@ -302,2 +332,18 @@ CacheKeyRegistry,

async #applyRetentionPolicies(
cacheKey: Key,
liveTx: LiveCacheTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>
): Promise<void> {
const revisionStrategy =
this.#cacheOptions?.hooks?.revisionMergeStrategy ||
defaultRetensionStrategy;
await revisionStrategy(cacheKey, this.#cacheRevisionTransaction);
}
#commitUpdatesAndReleaseLock(

@@ -325,5 +371,7 @@ transaction: LiveCacheTransaction<

// TODO: finalizregistry
this.#weakCache.set(key, new WeakRef(value));
// Register FinalizationRegistry so strongly held keys are removed
this.#cleanup.register(value, key);
this.#cacheEntryState.set(key, state);

@@ -337,10 +385,7 @@

// Write transaction revisions entries to the main cache
for (const [cacheKey, revision] of txUpdates.entryRevisions) {
if (this.#entryRevisions.has(cacheKey)) {
const revisions =
this.#entryRevisions.get(cacheKey)?.concat(revision) || [];
this.#entryRevisions.set(cacheKey, revisions);
} else {
this.#entryRevisions.set(cacheKey, revision);
}
for (const [
cacheKey,
revision,
] of this.#cacheRevisionTransaction.mergedEntryRevisions()) {
this.#entryRevisions.set(cacheKey, revision);
}

@@ -373,2 +418,8 @@

#updateSavedRevisions(
localRevisionsMap: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>
) {
this.#cacheRevisionTransaction?.updateRevisions(localRevisionsMap);
}
async beginTransaction(): Promise<

@@ -405,239 +456,48 @@ LiveCacheTransaction<CacheKeyRegistry, Key, $Debug, UserExtensionData>

return new LiveCacheTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>(this, {
aquireTxCommitLock,
releaseTxCommitLock,
commitUpdatesAndReleaseLock,
});
}
}
const applyRetentionPolicies = (
cacheKey: Key,
liveTx: LiveCacheTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>
) => this.#applyRetentionPolicies(cacheKey, liveTx);
class LiveCacheTransactionImpl<
CacheKeyRegistry extends DefaultRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> implements
LiveCacheTransaction<CacheKeyRegistry, Key, $Debug, UserExtensionData>
{
#originalCacheReference: CacheImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>;
#transactionalCache: Map<Key, CacheKeyRegistry[Key]>;
#commitingTransaction: CommittingTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>;
#cacheEntryState: Map<Key, CacheEntryState<UserExtensionData>>;
#userOptionRetentionPolicy: ExpirationPolicy;
#ttlPolicy: number;
#lruPolicy: number;
#localRevisions: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>;
#entryRevisions: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>;
#transactionOperations: TransactionOperations<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>;
const updateSavedRevisions = (
localRevisionsMap: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>
) => this.#updateSavedRevisions(localRevisionsMap);
constructor(
originalCache: CacheImpl<CacheKeyRegistry, Key, $Debug, UserExtensionData>,
transactionOperations: TransactionOperations<
CacheKeyRegistry,
const cacheEntriesBeforeTransaction = new Map<Key, CacheKeyRegistry[Key]>();
const cacheRevisionsBeforeTransaction = new Map<
Key,
$Debug,
UserExtensionData
>
) {
this.#originalCacheReference = originalCache;
this.#transactionalCache = new Map<Key, CacheKeyRegistry[Key]>();
this.#cacheEntryState = new Map<Key, CacheEntryState<UserExtensionData>>();
this.#ttlPolicy = DEFAULT_EXPIRATION.ttl;
this.#lruPolicy = DEFAULT_EXPIRATION.lru;
this.#localRevisions = new Map<
Key,
CachedEntityRevision<CacheKeyRegistry, Key>[]
>();
this.#entryRevisions = new Map<
Key,
CachedEntityRevision<CacheKeyRegistry, Key>[]
>();
this.#userOptionRetentionPolicy =
this.#originalCacheReference.getCacheOptions()?.expiration ||
DEFAULT_EXPIRATION;
if (
this.#userOptionRetentionPolicy &&
this.#userOptionRetentionPolicy?.lru &&
typeof this.#userOptionRetentionPolicy.lru === 'number'
) {
this.#lruPolicy = this.#userOptionRetentionPolicy.lru;
for await (const [cacheKey, value] of this.entries()) {
cacheEntriesBeforeTransaction.set(cacheKey, value);
}
if (
this.#userOptionRetentionPolicy &&
this.#userOptionRetentionPolicy?.ttl &&
typeof this.#userOptionRetentionPolicy.ttl === 'number'
) {
this.#ttlPolicy = this.#userOptionRetentionPolicy.ttl;
}
this.#commitingTransaction = new CommittingTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>();
this.#transactionOperations = transactionOperations;
}
async *[Symbol.asyncIterator](): AsyncIterableIterator<
[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]
> {
for await (const [key, value] of this.localEntries()) {
const state = this.#cacheEntryState.get(
key
) as CacheEntryState<UserExtensionData>;
yield [key, value, state];
}
}
async get(cacheKey: Key): Promise<CacheKeyRegistry[Key] | undefined> {
// will check the transaction entries and fall back to the cache if the transaction hasn't written to the key yet.
let cachedValue;
for await (const [key, value] of this.localEntries()) {
if (key === cacheKey) {
cachedValue = value;
break;
for await (const [cacheKey] of this.entries()) {
const revisions: CachedEntityRevision<CacheKeyRegistry, Key>[] = [];
for await (const revision of this.entryRevisions(cacheKey)) {
revisions.push(revision);
}
cacheRevisionsBeforeTransaction.set(cacheKey, revisions);
}
return cachedValue || (await this.#originalCacheReference.get(cacheKey));
}
localEntries(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key]]> {
const localEntriesIterator = {
async *[Symbol.asyncIterator](
localEntryMap: Map<Key, CacheKeyRegistry[Key]>
): AsyncIterableIterator<[Key, CacheKeyRegistry[Key]]> {
for (const [key, value] of localEntryMap) {
yield [key, value];
}
},
const transactionOperations = {
aquireTxCommitLock,
releaseTxCommitLock,
applyRetentionPolicies,
updateSavedRevisions,
commitUpdatesAndReleaseLock,
};
return localEntriesIterator[Symbol.asyncIterator](this.#transactionalCache);
}
async entries(): Promise<
AsyncIterableIterator<[Key, CacheKeyRegistry[Key]]>
> {
const entriesIterator = {
async *[Symbol.asyncIterator](
localEntriesIterator: AsyncIterableIterator<
[Key, CacheKeyRegistry[Key]]
>,
cacheRef: CacheImpl<CacheKeyRegistry, Key, $Debug, UserExtensionData>
): AsyncIterableIterator<[Key, CacheKeyRegistry[Key]]> {
for await (const [key, transactionValue] of localEntriesIterator) {
yield [key, transactionValue];
const cacheValue = await cacheRef.get(key);
if (cacheValue) {
yield [key, cacheValue];
}
}
},
};
return entriesIterator[Symbol.asyncIterator](
this.localEntries(),
this.#originalCacheReference
this.#cacheRevisionTransaction = new CommittingTransactionImpl(
this,
cacheRevisionsBeforeTransaction
);
}
localRevisions(
cacheKey: Key
): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry, Key>> {
const entryRevisionIterator = {
async *[Symbol.asyncIterator](
revisions: CachedEntityRevision<CacheKeyRegistry, Key>[]
): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry, Key>> {
for (const revision of revisions) {
yield revision;
}
},
};
const revisions = this.#localRevisions.get(cacheKey) || [];
return entryRevisionIterator[Symbol.asyncIterator](revisions);
}
entryRevisions(
cacheKey: Key
): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry, Key>> {
const entryRevisionIterator = {
async *[Symbol.asyncIterator](
revisions: CachedEntityRevision<CacheKeyRegistry, Key>[]
): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry, Key>> {
for (const revision of revisions) {
yield revision;
}
},
};
const entryRevisions = this.#entryRevisions.get(cacheKey) || [];
const localRevisions = this.#localRevisions.get(cacheKey) || [];
return entryRevisionIterator[Symbol.asyncIterator](
entryRevisions.concat(localRevisions)
);
}
async set(
cacheKey: Key,
value: CacheKeyRegistry[Key]
): Promise<CacheKeyRegistry[Key]> {
this.#transactionalCache.set(cacheKey, value);
// Update cache entry state
this.#cacheEntryState.set(cacheKey, {
retained: { lru: true, ttl: this.#ttlPolicy },
lastAccessed: Date.now(),
});
return (await this.get(cacheKey)) as CacheKeyRegistry[Key];
}
async delete(cacheKey: Key): Promise<boolean> {
// tx.delete will actually need to write a tombstone in the transaction entries and the actual delete will occur when the transaction is committed to the cache.
// The semantics of tx.delete's return value should be "did i delete something?"
if (await this.get(cacheKey)) {
this.#transactionalCache.delete(cacheKey);
// Update cache entry state to indicate as delete in order to actually be deleted from cache when commit
this.#cacheEntryState.set(cacheKey, {
retained: { lru: false, ttl: 0 },
deletedRecordInTransaction: true,
lastAccessed: Date.now(),
});
return true;
}
return false;
}
// assign transaction or cache level overriden merge strategy else use default
#getMergeStrategy(
transactionMergeStrategy?: EntityMergeStrategy<
const liveTx = new LiveCacheTransactionImpl<
CacheKeyRegistry,

@@ -647,243 +507,13 @@ Key,

UserExtensionData
>
) {
const cacheWideMergeStrategy =
this.#originalCacheReference.getCacheOptions()?.hooks
?.entitymergeStrategy;
return (
transactionMergeStrategy || cacheWideMergeStrategy || defaultMergeStrategy
>(
this,
cacheEntriesBeforeTransaction,
cacheRevisionsBeforeTransaction,
transactionOperations
);
}
#getRevisionStrategy() {
const cacheWideRevisionStrategy =
this.#originalCacheReference.getCacheOptions()?.hooks
?.revisionMergeStrategy;
return cacheWideRevisionStrategy || defaultRevisionStrategy;
return liveTx;
}
async merge(
cacheKey: Key,
entity: CacheKeyRegistry[Key],
options?: {
entityMergeStrategy: EntityMergeStrategy<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>;
revisionContext: string;
$debug: $Debug;
}
): Promise<CacheKeyRegistry[Key] | CacheKeyValue> {
const mergeStrategy = this.#getMergeStrategy(options?.entityMergeStrategy);
// get current cache value within this transaction
const currentValue = await this.#originalCacheReference.get(cacheKey);
const revisionCounter = REVISION_COUNTER++;
// get merged entity
const mergedEntity = currentValue
? entity
: mergeStrategy(
cacheKey,
{
entity,
revision: REVISION_COUNTER++,
revisionContext: options?.revisionContext,
},
currentValue,
this
);
// Update transactional cache with merged entity
// Calling set here will in turn also update cacheEntryState
await this.set(cacheKey, mergedEntity as CacheKeyRegistry[Key]);
// Update local & entry revisions with new revision values
const revision = {
entity: mergedEntity as CacheKeyRegistry[Key],
revision: revisionCounter,
revisionContext: options?.revisionContext,
};
if (this.#localRevisions.has(cacheKey)) {
this.#localRevisions.get(cacheKey)?.push(revision);
} else {
this.#localRevisions.set(cacheKey, [revision]);
}
return mergedEntity;
}
async #prepareTransaction(): Promise<
TransactionUpdates<CacheKeyRegistry, Key, UserExtensionData>
> {
const trasactionCacheEntries: [
Key,
CacheKeyRegistry[Key],
CacheEntryState<UserExtensionData>
][] = [];
for await (const [cacheKey, value] of this.localEntries()) {
const latestCacheValue = await this.#originalCacheReference.get(cacheKey);
let mergedEntityToCommit;
const mergeStrategy = this.#getMergeStrategy();
if (latestCacheValue) {
// TODO fix revision
mergedEntityToCommit = mergeStrategy(
cacheKey,
{ entity: value, revision: 3 },
latestCacheValue,
this
);
} else {
mergedEntityToCommit = value;
}
const structuredClonedValue = structuredClone(
mergedEntityToCommit
) as CacheKeyRegistry[Key];
const state = this.#cacheEntryState.get(cacheKey) || DEFAULT_ENTRY_STATE;
trasactionCacheEntries.push([cacheKey, structuredClonedValue, state]);
// Update saved revisions of the entity
const localRevisions = this.#localRevisions.get(cacheKey);
let revisionNumber =
localRevisions && localRevisions[localRevisions.length - 1].revision
? localRevisions[localRevisions.length - 1].revision
: 0;
const entityRevision = {
entity: mergedEntityToCommit as CacheKeyRegistry[Key],
revision: ++revisionNumber,
};
if (this.#localRevisions.has(cacheKey)) {
this.#localRevisions.get(cacheKey)?.push(entityRevision);
} else {
this.#localRevisions.set(cacheKey, [entityRevision]);
}
const revisionStrategy = this.#getRevisionStrategy();
// Update revisions based on revision strategy
await revisionStrategy(cacheKey, this.#commitingTransaction, this);
}
// Call commit hook to apply custom retention policies before commit (if passed by cache options)
const commitCallback =
this.#originalCacheReference.getCacheOptions()?.hooks?.commit;
if (commitCallback) {
await commitCallback(this);
}
const mergedRevisions = this.#commitingTransaction.mergedRevisions();
return {
entries: trasactionCacheEntries,
entryRevisions: mergedRevisions,
};
}
async commit(options?: { timeout: number | false }): Promise<void> {
await this.#transactionOperations.aquireTxCommitLock(this);
let transactionUpdates;
try {
transactionUpdates = await this.#prepareTransaction();
return this.#transactionOperations.commitUpdatesAndReleaseLock(
this,
transactionUpdates
);
} catch (e) {
throw new Error('Failed to prepare transaction updates');
} finally {
this.#transactionOperations.releaseTxCommitLock(this);
}
}
}
class CommittingTransactionImpl<
CacheKeyRegistry extends DefaultRegistry,
Key extends keyof CacheKeyRegistry = keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> implements
CommittingTransaction<CacheKeyRegistry, Key, $Debug, UserExtensionData>
{
$debug?: ($Debug & CacheTransactionDebugAPIs) | undefined;
#mergedRevisions: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>;
cache: {
clearRevisions(
tx: CommittingTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>,
id: Key
): void;
appendRevisions(
tx: CommittingTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>,
id: Key,
revisions: CachedEntityRevision<CacheKeyRegistry, Key>[]
): void;
} = {
clearRevisions(
tx: CommittingTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>,
id: Key
): void {
tx.#mergedRevisions.delete(id);
},
appendRevisions(
tx: CommittingTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>,
id: Key,
revisions: CachedEntityRevision<CacheKeyRegistry, Key>[]
): void {
if (tx.#mergedRevisions.has(id)) {
const appendedRevisions =
tx.#mergedRevisions.get(id)?.concat(revisions) || [];
tx.#mergedRevisions.set(id, appendedRevisions);
} else {
tx.#mergedRevisions.set(id, revisions);
}
},
};
constructor() {
this.#mergedRevisions = new Map<
Key,
CachedEntityRevision<CacheKeyRegistry, Key>[]
>();
}
[Symbol.asyncIterator](): AsyncIterableIterator<
[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]
> {
throw new Error('Method not implemented.');
}
mergedRevisions(): Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]> {
return this.#mergedRevisions;
}
}
export function buildCache<

@@ -933,22 +563,4 @@ CacheKeyRegistry extends DefaultRegistry = DefaultRegistry,

const DEFAULT_EXPIRATION = { lru: 10000, ttl: 60000 };
const DEFAULT_ENTRY_STATE = {
retained: { lru: false, ttl: DEFAULT_EXPIRATION.ttl },
};
const defaultMergeStrategy = function deepMergeStratey<
const defaultRetensionStrategy = async function retainAllRevisions<
CacheKeyRegistry extends DefaultRegistry,
Key extends keyof CacheKeyRegistry
>(
id: Key,
{ entity }: CachedEntityRevision<CacheKeyRegistry, Key>,
current: CacheKeyRegistry[Key] | undefined,
tx: CacheTransaction<CacheKeyRegistry, Key>
): CacheKeyValue {
return deepMerge(current as CacheKeyValue, entity as CacheKeyValue);
};
const defaultRevisionStrategy = async function retainAllRevisions<
CacheKeyRegistry extends DefaultRegistry,
Key extends keyof CacheKeyRegistry,

@@ -959,3 +571,3 @@ $Debug = unknown,

id: Key,
commitTx: CommittingTransactionImpl<
commitingRevisionTx: CommittingTransaction<
CacheKeyRegistry,

@@ -965,8 +577,2 @@ Key,

UserExtensionData
>,
liveTx: LiveCacheTransactionImpl<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>

@@ -976,9 +582,21 @@ ): Promise<void> {

for await (const revision of liveTx.localRevisions(id)) {
for await (const revision of commitingRevisionTx.entryRevisions(id)) {
revisions.push(revision);
}
commitTx.cache.appendRevisions(commitTx, id, [...revisions]);
commitingRevisionTx.cache.appendRevisions(id, [...revisions]);
};
const defaultMergeStrategy = function deepMergeStratey<
CacheKeyRegistry extends DefaultRegistry,
Key extends keyof CacheKeyRegistry
>(
id: Key,
{ entity }: CachedEntityRevision<CacheKeyRegistry, Key>,
current: CacheKeyRegistry[Key] | undefined,
tx: CacheTransaction<CacheKeyRegistry, Key>
): CacheKeyValue {
return deepMerge(current as CacheKeyValue, entity as CacheKeyValue);
};
// eslint-disable-next-line

@@ -985,0 +603,0 @@ const isObject = function isObject(obj: any): obj is Record<string, any> {

@@ -159,3 +159,3 @@ export { buildCache } from '../src/cache.js';

>;
revisionContext?: string;
revisionContext?: unknown;
$debug?: $Debug;

@@ -189,23 +189,6 @@ }

UserExtensionData = unknown
> extends Omit<
CacheTransaction<CacheKeyRegistry, Key, $Debug, UserExtensionData>,
'get' | 'entries' | 'localEntries' | 'localRevisions' | 'entryRevisions'
> {
> extends CacheTransaction<CacheKeyRegistry, Key, $Debug, UserExtensionData> {
cache: {
clearRevisions(
tx: CommittingTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>,
id: Key
): void;
clearRevisions(id: Key): void;
appendRevisions(
tx: CommittingTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>,
id: Key,

@@ -215,3 +198,9 @@ revisions: CachedEntityRevision<CacheKeyRegistry, Key>[]

};
mergedRevisions(): Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>;
mergedEntryRevisions(): Map<
Key,
CachedEntityRevision<CacheKeyRegistry, Key>[]
>;
updateRevisions(
localRevisionsMap: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>
): void;
}

@@ -282,4 +271,9 @@

cacheKey: Key,
tx: CommittingTransaction<CacheKeyRegistry, Key, $Debug, UserExtensionData>
): void;
commitingRevisionTx: CommittingTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>
): Promise<void>;
}

@@ -293,3 +287,3 @@

revision: number;
revisionContext?: string; // Use to store queryIds that can be used for debugging
revisionContext?: unknown; // Use to store queryIds that can be used for debugging
}

@@ -365,3 +359,3 @@

entries: [Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>][];
entryRevisions: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>;
//entryRevisions: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>;
}

@@ -392,2 +386,14 @@

) => void;
applyRetentionPolicies: (
cacheKey: Key,
transaction: LiveCacheTransaction<
CacheKeyRegistry,
Key,
$Debug,
UserExtensionData
>
) => Promise<void>;
updateSavedRevisions: (
localRevisionsMap: Map<Key, CachedEntityRevision<CacheKeyRegistry, Key>[]>
) => void;
commitUpdatesAndReleaseLock: (

@@ -394,0 +400,0 @@ transaction: LiveCacheTransaction<

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc