Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@data-eden/cache

Package Overview
Dependencies
Maintainers
3
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.2.1 to 0.2.2-beta.1

__tests__/tsconfig.json

763

__tests__/index-test.ts
import { describe, it, expect } from 'vitest';
// TODO: add a tests tsconfig so we can import properly
import { buildCache } from '@data-eden/cache';
// TODO: add tests for types
// TODO test live trasaction where original cache has enitiy that is GCd (memory management tests)
describe('@data-eden/cache', function () {
it('can run tests', function () {
expect(true).toBe(true);
describe('cache with no user registry', function () {
it('can be built', async function () {
// TODO: this valid call fails if we switch module resolution to node16
// see #36
let cache = buildCache();
expect(await cache.get('missing-key')).toBeUndefined();
});
it('can load serialized values', async function () {
let cache = buildCache();
// without a serializer, cache.load assumes serialized entries have values that are structured-cloneable
// TODO: update to put these in the LRU
await cache.load([
['book:1', { title: 'A History of the English speaking peoples' }],
['book:2', { title: 'Marlborough: his life and times' }],
]);
let book1 = await cache.get('book:1');
expect(book1).toMatchInlineSnapshot(`
{
"title": "A History of the English speaking peoples",
}
`);
});
it('test iterable cache.entries', async function () {
let cache = buildCache();
await cache.load([
['book:1', { title: 'A History of the English speaking peoples' }],
['book:2', { title: 'Marlborough: his life and times' }],
]);
const entries = cache.entries();
const entry1 = await entries.next();
const defaultEntryState = { retained: { lru: false, ttl: 60000 } };
// TODO setup & validate weekly held and strongly held entries
expect(entry1.value).toEqual([
'book:1',
{ title: 'A History of the English speaking peoples' },
defaultEntryState,
]);
const entry2 = await entries.next();
expect(entry2.value).toEqual([
'book:2',
{ title: 'Marlborough: his life and times' },
defaultEntryState,
]);
for await (const [key, value] of cache.entries()) {
expect(key).toBeTypeOf('string');
expect(value).toBeTypeOf('object');
}
});
it('test keys iterator', async function () {
let cache = buildCache();
await cache.load([
['book:1', { title: 'A History of the English speaking peoples' }],
['book:2', { title: 'Marlborough: his life and times' }],
]);
const entryKeys = cache.keys();
const entryKey1 = await entryKeys.next();
expect(entryKey1.value).toEqual('book:1');
const entryKey2 = await entryKeys.next();
expect(entryKey2.value).toEqual('book:2');
for await (const key of cache.keys()) {
expect(key).toBeTypeOf('string');
}
});
it('test values iterator', async function () {
let cache = buildCache();
await cache.load([
['book:1', { title: 'A History of the English speaking peoples' }],
['book:2', { title: 'Marlborough: his life and times' }],
]);
const entryValues = cache.values();
const entryValue1 = await entryValues.next();
expect(entryValue1.value).toEqual({
title: 'A History of the English speaking peoples',
});
const entryValue2 = await entryValues.next();
expect(entryValue2.value).toEqual({
title: 'Marlborough: his life and times',
});
for await (const value of cache.values()) {
expect(value).toBeTypeOf('object');
}
});
it('test cache.save returns array of cache entry tuple', async function () {
let cache = buildCache();
await cache.load([
['book:1', { title: 'A History of the English speaking peoples' }],
['book:2', { title: 'Marlborough: his life and times' }],
]);
const arrayOfCacheEntryTuples = await cache.save();
const cacheEntryTuple1 = arrayOfCacheEntryTuples[0];
const cacheEntryTuple2 = arrayOfCacheEntryTuples[1];
expect(arrayOfCacheEntryTuples.length).toEqual(2);
expect(cacheEntryTuple1?.length).toEqual(3);
expect(cacheEntryTuple1[0]).toEqual('book:1');
expect(cacheEntryTuple1[0]).toBeTypeOf('string');
expect(cacheEntryTuple1[1]).toEqual({
title: 'A History of the English speaking peoples',
});
expect(cacheEntryTuple1[1]).toBeTypeOf('object');
expect(cacheEntryTuple2?.length).toEqual(3);
expect(cacheEntryTuple2[0]).toEqual('book:2');
expect(cacheEntryTuple2[0]).toBeTypeOf('string');
expect(cacheEntryTuple2[1]).toEqual({
title: 'Marlborough: his life and times',
});
expect(cacheEntryTuple2[1]).toBeTypeOf('object');
// TODO verify cache entry state
});
it('test cache.load w/o serializer throws error when values are not structured clonable', async () => {
let cache = buildCache();
void expect(async () => {
await cache.load([['book:1', function () {}]]);
}).rejects.toThrow(
'The cache value is not structured clonable use `save` with serializer'
);
});
it('test cache.clear (load, get, clear, get)', async function () {
let cache = buildCache();
await cache.load([
['book:1', { title: 'A History of the English speaking peoples' }],
['book:2', { title: 'Marlborough: his life and times' }],
]);
expect(await cache.get('book:1')).toEqual({
title: 'A History of the English speaking peoples',
});
expect(await cache.get('book:2')).toEqual({
title: 'Marlborough: his life and times',
});
await cache.clear();
expect(await cache.get('book:1')).toEqual(undefined);
expect(await cache.get('book:2')).toEqual(undefined);
});
// TODO: test clear (load, get, clear, get)
// TODO: test save (with values, save then clear, then load, values should be restored)
// transaction testing ----------------
// TODO: test transactions
// memory testing -------------------
// TODO: test lru (unit test lru)
// TODO: test ttl?
// TODO: --expose-gc + setTimeout global.gc() + another setTimeout() + assert weakly held things are cleaned up
// TODO: requires fixing up types &c. but otherwise illustrates how a user
// could have a very simple cache that differentiated between types
//
// it('enables custom user retention -- retention-by-type', function() {
// async function awaitAll(itr: AsyncIterableIterator<unknown>) {
// let result = []
// for await (let item of itr) {
// result.push(item);
// }
// return result;
// }
// type CachedTypes = 'book' | 'author';
// let typeCacheMap = new Map<CachedTypes, unknown>([
// 'book', null,
// 'author', null,
// ]);
// function typeBasedLRU(tx) {
// for (let [key, value] of tx.entries()) {
// let match = /(book|author):/i.exec(key);
// if (match) {
// // TODO: assert match[1] is a CachedTypes
// typeCacheMap.set(match[1], value);
// }
// }
// }
// let cache = buildCache({
// hooks: {
// commit: typeBasedLRU
// }
// });
// let tx = cache.beginTransaction();
// tx.set('book:1', { title: 'Marlborough: His Life and Times Volume I' });
// tx.set('book:2', { title: 'Marlborough: His Life and Times Volume II' });
// tx.set('author:1', { name: 'Winston Churchill' });
// tx.set('character:1', { name: 'John Churchill' });
// await tx.commit();
// expect([...typeCacheMap.values()]).toMatchInlineSnapshot([{
// title: 'Marlborough: His Life and Times Volume II'
// }, {
// name: 'Winston Churchill'
// }]);
// expect(awaitAll(cache.values())).toMatchInlineSnapshot([{
// title: 'Marlborough: His Life and Times Volume I'
// }, {
// title: 'Marlborough: His Life and Times Volume II'
// }, {
// name: 'Winston Churchill'
// }, {
// name: 'John Churchill'
// }]);
// // TODO: gc?
// expect(awaitAll(cache.values())).toMatchInlineSnapshot([{
// title: 'Marlborough: His Life and Times Volume II'
// }, {
// name: 'Winston Churchill'
// }]);
// });
});
describe('with a user registry', function () {
// let cache = buildCache<UserRegistry>()
// see https:/tsplay.dev/NrnDlN
// TODO: try to test the types with expect-type
it('can be built', function () {});
});
describe('with a user registry and user extension data', function () {
it('can be built', function () {});
});
describe('test live transactions', function () {
it('test single transaction with commit', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{ 'book:1': { title: 'A History of the English speaking peoples' } },
],
['book:2', { 'book:2': { title: 'Marlborough: his life and times' } }],
]);
// transaction 1 starts
let tx = await cache.beginTransaction();
await tx.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book' } },
revision: 1,
});
await tx.merge('book:1', {
entity: { 'book:1': { title: 'Conflict', sub: 'j3' } },
revision: 1,
});
// Validate Transactional entries
expect(tx.get('book:1')).toEqual({
'book:1': { title: 'Conflict', sub: 'j3' },
});
expect(tx.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx.get('book:3')).toEqual({
'book:3': { title: 'New Merged book' },
});
// Validate Cache before commit
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'A History of the English speaking peoples' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual(undefined);
const cacheEntriesBeforeCommit = await cache.save();
expect(cacheEntriesBeforeCommit.length).toEqual(2);
await tx.commit();
// Validate Cache after commit
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'Conflict', sub: 'j3' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual({
'book:3': { title: 'New Merged book' },
});
});
it('test single transaction with commit & rollback', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{ 'book:1': { title: 'A History of the English speaking peoples' } },
],
['book:2', { 'book:2': { title: 'Marlborough: his life and times' } }],
]);
// transaction 1 starts
let tx = await cache.beginTransaction();
await tx.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book' } },
revision: 1,
});
await tx.merge('book:1', {
entity: { 'book:1': { title: 'Conflict', sub: 'j3' } },
revision: 1,
});
// Validate Transactional entries
expect(tx.get('book:1')).toEqual({
'book:1': { title: 'Conflict', sub: 'j3' },
});
expect(tx.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx.get('book:3')).toEqual({
'book:3': { title: 'New Merged book' },
});
// Validate Cache before commit
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'A History of the English speaking peoples' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual(undefined);
const cacheEntriesBeforeCommit = await cache.save();
expect(cacheEntriesBeforeCommit.length).toEqual(2);
await tx.commit();
// Validate Cache after commit
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'Conflict', sub: 'j3' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual({
'book:3': { title: 'New Merged book' },
});
await tx.rollback();
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'A History of the English speaking peoples' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual(undefined);
});
it('test cache with multiple transaction commits is masked from trasaction changes', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{ 'book:1': { title: 'A History of the English speaking peoples' } },
],
['book:2', { 'book:2': { title: 'Marlborough: his life and times' } }],
]);
// transaction 1 starts
let tx1 = await cache.beginTransaction();
// transaction 2 starts
let tx2 = await cache.beginTransaction();
// Merge entities from transaction 1
await tx1.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book TX1' } },
revision: 1,
});
await tx1.merge('book:1', {
entity: { 'book:1': { title: 'original book Conflict', sub: 'j3' } },
revision: 1,
});
// Merge entities from transaction 2
await tx2.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book by TX2' } },
revision: 1,
});
await tx2.merge('book:1', {
entity: {
'book:1': {
title: 'Conflict updated by TX2',
sub: 'j32',
sub2: '12',
},
},
revision: 1,
});
await tx2.merge('book:4', {
entity: { 'book:4': { title: 'new book 4', sub: 'j32', sub2: '12' } },
revision: 1,
});
// Validate entries in Transaction 1
expect(tx1.get('book:1')).toEqual({
'book:1': { title: 'original book Conflict', sub: 'j3' },
});
expect(tx1.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx1.get('book:3')).toEqual({
'book:3': { title: 'New Merged book TX1' },
});
// Validate entries in Transaction 2
expect(tx2.get('book:1')).toEqual({
'book:1': { title: 'Conflict updated by TX2', sub: 'j32', sub2: '12' },
});
expect(tx2.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx2.get('book:3')).toEqual({
'book:3': { title: 'New Merged book by TX2' },
});
expect(tx2.get('book:4')).toEqual({
'book:4': { title: 'new book 4', sub: 'j32', sub2: '12' },
});
// Validate entries in original Cache
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'A History of the English speaking peoples' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual(undefined);
// commit transaction 1
await tx1.commit();
// Validate entries in original Cache after 1st commit
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'original book Conflict', sub: 'j3' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual({
'book:3': { title: 'New Merged book TX1' },
});
expect(await cache.get('book:4')).toEqual(undefined);
// Validate entries in Transaction 2 Cache after 1st transaction commit and it remains masked
expect(tx2.get('book:1')).toEqual({
'book:1': { title: 'Conflict updated by TX2', sub: 'j32', sub2: '12' },
});
expect(tx2.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx2.get('book:3')).toEqual({
'book:3': { title: 'New Merged book by TX2' },
});
expect(tx2.get('book:4')).toEqual({
'book:4': { title: 'new book 4', sub: 'j32', sub2: '12' },
});
// commit transaction 1
await tx2.commit();
// Validate entries in original Cache after 2nd commit
expect(await cache.get('book:1')).toEqual({
'book:1': { title: 'Conflict updated by TX2', sub: 'j32', sub2: '12' },
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual({
'book:3': { title: 'New Merged book by TX2' },
});
expect(await cache.get('book:4')).toEqual({
'book:4': { title: 'new book 4', sub: 'j32', sub2: '12' },
});
});
it('test local entries', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{ 'book:1': { title: 'A History of the English speaking peoples' } },
],
['book:2', { 'book:2': { title: 'Marlborough: his life and times' } }],
]);
let tx = await cache.beginTransaction();
await tx.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book' } },
revision: 1,
});
await tx.merge('book:1', {
entity: { 'book:1': { title: 'Conflict', sub: 'j3' } },
revision: 1,
});
const localEntries = [];
for await (const [key, value, state] of tx.localEntries()) {
localEntries.push([key, value, state]);
}
expect(localEntries[0][1]).toEqual({
'book:3': { title: 'New Merged book' },
});
expect(localEntries[1][1]).toEqual({
'book:1': { title: 'Conflict', sub: 'j3' },
});
});
it('test merging entities with array values', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{
'book:1': {
title: 'A History of the English speaking peoples',
subjects: [{ a: 1 }],
},
},
],
['book:2', { 'book:2': { title: 'Marlborough: his life and times' } }],
]);
// transaction 1 starts
let tx = await cache.beginTransaction();
await tx.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book' } },
revision: 1,
});
await tx.merge('book:1', {
entity: {
'book:1': {
title: 'Conflict',
sub: 'j3',
subjects: [{ a: 1 }, { b: 2 }],
},
},
revision: 1,
});
// Validate Transactional entries
expect(tx.get('book:1')).toEqual({
'book:1': {
title: 'Conflict',
sub: 'j3',
subjects: [{ a: 1 }, { b: 2 }],
},
});
expect(tx.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx.get('book:3')).toEqual({
'book:3': { title: 'New Merged book' },
});
// Validate Cache before commit
expect(await cache.get('book:1')).toEqual({
'book:1': {
title: 'A History of the English speaking peoples',
subjects: [{ a: 1 }],
},
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual(undefined);
const cacheEntriesBeforeCommit = await cache.save();
expect(cacheEntriesBeforeCommit.length).toEqual(2);
await tx.commit();
// Validate Cache after commit
expect(await cache.get('book:1')).toEqual({
'book:1': {
title: 'Conflict',
sub: 'j3',
subjects: [{ a: 1 }, { b: 2 }],
},
});
expect(await cache.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(await cache.get('book:3')).toEqual({
'book:3': { title: 'New Merged book' },
});
});
it('test delete', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{
'book:1': {
title: 'A History of the English speaking peoples',
subjects: [{ a: 1 }],
},
},
],
['book:2', { 'book:2': { title: 'Marlborough: his life and times' } }],
]);
// transaction 1 starts
let tx = await cache.beginTransaction();
await tx.merge('book:3', {
entity: { 'book:3': { title: 'New Merged book' } },
revision: 1,
});
await tx.delete('book:1');
expect(tx.get('book:2')).toEqual({
'book:2': { title: 'Marlborough: his life and times' },
});
expect(tx.get('book:1')).toEqual(undefined);
});
});
describe('test revision strategy', function () {
it('test entry revisions are merged correctly', async function () {
let cache = buildCache();
await cache.load([
[
'book:1',
{ 'book:1': { title: 'A History of the English speaking peoples' } },
],
]);
let tx = await cache.beginTransaction();
await tx.merge('book:1', {
entity: { 'book:1': { title: 'Conflict', sub: 'j3' } },
revision: 2,
});
await tx.commit();
const entryRevisions = cache.entryRevisions('book:1');
const revisions = [];
for await (const entry of entryRevisions) {
revisions.push(entry);
}
expect(revisions.length).toEqual(3);
expect(
revisions.includes({
entity: {
'book:1': { title: 'A History of the English speaking peoples' },
},
revision: 1,
})
);
expect(
revisions.includes({
entity: { 'book:1': { title: 'Conflict', sub: 'j3' } },
revision: 2,
})
);
expect(
revisions.includes({
entity: { 'book:1': { title: 'Conflict', sub: 'j3' } },
revision: 3,
})
);
});
});
describe('test LRU', function () {
it('test LRU policy', async function () {
let cache = buildCache({ expiration: { lru: 4, ttl: 5000 } });
await cache.load([
['book:1', { 'book:1': { title: 'A History1' } }],
['book:2', { 'book:2': { title: 'A History2' } }],
['book:3', { 'book:3': { title: 'A History3' } }],
['book:4', { 'book:4': { title: 'A History4' } }],
]);
let tx = await cache.beginTransaction();
tx.set('book:5', { 'book:5': { title: 'A History5_lru' } });
tx.get('book:3');
await tx.merge('book:4', {
entity: { 'book:4': { title: 'A History4_lru' } },
revision: 2,
});
await tx.merge('book:1', {
entity: { 'book:1': { title: 'A History1_lru' } },
revision: 1,
});
await tx.commit();
const cacheEntries = await cache.save();
const lru = cacheEntries.filter((entry) => {
const entryState = entry[2] as { retained: { lru: true | false } };
if (entry[2]) {
return entryState.retained?.lru === true;
}
});
expect(lru[0][0]).toEqual('book:1');
expect(lru[1][0]).toEqual('book:4');
expect(lru[2][0]).toEqual('book:5');
});
});
});

2

dist/index.d.ts

@@ -1,2 +0,2 @@

export {};
export { buildCache } from './cache.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,2 +0,2 @@

export {};
export { buildCache } from './cache.js';
//# sourceMappingURL=index.js.map
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@data-eden/cache",
"version": "0.2.1",
"version": "0.2.2-beta.1",
"repository": {

@@ -14,4 +15,4 @@ "type": "git",

"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
"types": "./src/index.ts",
"default": "./src/index.ts"
}

@@ -23,3 +24,4 @@ }

"scripts": {
"test": "vitest run"
"test": "vitest run",
"test:debug": "node --inspect-brk --inspect ../../node_modules/.bin/vitest --threads=false"
},

@@ -26,0 +28,0 @@ "dependencies": {},

@@ -70,6 +70,11 @@ # @data-eden/cache

export interface Cache<CacheKeyRegistry, $Debug=unknown, UserExtensionData=unknown> {
export interface Cache<
CacheKeyRegistry extends DefaultRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> {
beginTransaction(): CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData>;
async get<Key extends keyof CacheKeyRegistry>(cacheKey: Key): CacheKeyRegistry[Key] | undefined;
async get(cacheKey: Key): CacheKeyRegistry[Key] | undefined;

@@ -81,3 +86,3 @@ /**

*/
[Symbol.asyncIterator]<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]>
[Symbol.asyncIterator](): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]>

@@ -89,6 +94,6 @@ /**

*/
entries<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]>
entryRevisions<Key extends keyof CacheKeyRegistry>(cacheKey: Key): AsyncIterableIterator<[entity: CacheKeyRegistry[Key], revision: number][]>;
keys<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<Key>
values<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<CacheKeyRegistry[Key]>
entries(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]>
entryRevisions(cacheKey: Key): AsyncIterableIterator<[entity: CacheKeyRegistry[Key], revision: number][]>;
keys(): AsyncIterableIterator<Key>
values(): AsyncIterableIterator<CacheKeyRegistry[Key]>

@@ -106,3 +111,3 @@ /**

*/
async save<Key extends keyof CacheKeyRegistry>(): [Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>][];
async save(): [Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>][];

@@ -122,3 +127,3 @@ /**

*/
async save<Key extends keyof CacheKeyRegistry>(serializer: CacheEntrySerializer): ReturnType<CacheEntrySerializer>[];
async save(serializer: CacheEntrySerializer): ReturnType<CacheEntrySerializer>[];

@@ -131,3 +136,4 @@ /**

*/
async load<Key extends keyof CacheKeyRegistry>(entries: CacheEntry<CacheKeyRegistry>[]): void;
async load<Key extends keyof CacheKeyRegistry>(entries: CacheEntry<CacheKeyRegistry, Key, UserExtensionData>[]): void;
// TODO: needs entries
async load<Key extends keyof CacheKeyRegistry>(serializer: CacheEntrySerializer): ReturnType<CacheEntrySerializer>[];

@@ -184,11 +190,21 @@

export interface EntityMergeStrategy<CacheKeyRegistry, $Debug=unknown, UserExtensionData=unknown> {
<Key extends keyof CacheKeyRegistry>(cacheKey: Key, newEntityRevision: CachedEntityRevision<CacheKeyRegistry[Key]>, current: CacheKeyRegistry[Key] | undefined, tx: CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData>): CacheKeyValue;
export interface EntityMergeStrategy<
CacheKeyRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> {
(cacheKey: Key, newEntityRevision: CachedEntityRevision<CacheKeyRegistry[Key]>, current: CacheKeyRegistry[Key] | undefined, tx: CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData>): CacheKeyValue;
}
export interface RevisionMergeStrategy<CacheKeyRegistry, $Debug=unknown, UserExtensionData=unknown> {
<Key extends keyof CacheKeyRegistry>(cacheKey: Key, tx: CommittingTransaction<CacheKeyRegistry, $Debug, UserExtensionData>): void;
export interface RevisionMergeStrategy<
CacheKeyRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> {
(cacheKey: Key, tx: CommittingTransaction<CacheKeyRegistry, $Debug, UserExtensionData>): void;
}
export interface CacheEntryState<UserExtenionData=unknown> {
export interface CacheEntryState<UserExtensionData=unknown> {
retained: {

@@ -223,3 +239,8 @@ lru: boolean;

export interface CacheTransaction<CacheKeyRegistry, $Debug=unknown, UserExtensionData=unknown> {
export interface CacheTransaction<
CacheKeyRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> {
/**

@@ -231,13 +252,13 @@ Get the value of `cacheKey` in the cache. If `key` has been modified in this

*/
async get<Key extends keyof CacheKeyRegistry>(cacheKey: Key): CacheKeyRegistry[Key] | undefined;
localEntries<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState]>
entries<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState]>
async get(cacheKey: Key): CacheKeyRegistry[Key] | undefined;
localEntries(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState]>
entries(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState]>
/**
Generator function that yields each of the transaction local entries.
*/
[Symbol.asyncIterator]<Key extends keyof CacheKeyRegistry>(): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]>
[Symbol.asyncIterator](): AsyncIterableIterator<[Key, CacheKeyRegistry[Key], CacheEntryState<UserExtensionData>]>
/**
An async generator that produces the revisions of `key` within this transaction.
*/
localRevisions<Key extends keyof CacheKeyRegistry>(cacheKey: Key): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry[Key]>>;
localRevisions(cacheKey: Key): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry[Key]>>;
/**

@@ -248,14 +269,27 @@ An async generator that produces the complete list of revisions for `key`,

*/
entryRevisions<Key extends keyof CacheKeyRegistry>(cacheKey: Key): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry[Key]>>;
entryRevisions(cacheKey: Key): AsyncIterableIterator<CachedEntityRevision<CacheKeyRegistry[Key]>>;
$debug: $Debug & CacheTransactionDebugAPIs;
}
export interface CommittingTransaction<CacheKeyRegistry, $Debug=unknown, UserExtensionData=unknown> extends CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData> {
export interface CommittingTransaction<
CacheKeyRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> extends CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData> {
cache: {
clearRevisions<Key extends keyof CacheKeyRegistry>(id: Key): void;
appendRevisions<Key extends keyof CacheKeyRegistry>(id: Key, revisions: CachedEntityRevision<CacheKeyRegistry[Key]>[]): void;
clearRevisions(id: Key): void;
appendRevisions(id: Key, revisions: CachedEntityRevision<CacheKeyRegistry[Key]>[]): void;
}
}
export interface LiveCacheTransaction<CacheKeyRegistry, $Debug=unknown, UserExtensionData=unknown> extends CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData> {
async merge<Key extends keyof CacheKeyRegistry>(cacheKey: Key, value: CachedEntityRevision<CacheKeyRegistry[Key]>, options?: {
export interface LiveCacheTransaction<
CacheKeyRegistry,
Key extends keyof CacheKeyRegistry,
$Debug = unknown,
UserExtensionData = unknown
> extends CacheTransaction<CacheKeyRegistry, $Debug, UserExtensionData> {
// let mergedEntity = await tx.merge(id, entity, { revision, entityMergeStrategy, revisionMergeStrategy, $debug: { rawDocument } });
async merge(cacheKey: Key, value: CachedEntityRevision<CacheKeyRegistry[Key]>, options?: {
entityMergeStrategy: EntityMergeStrategy<CacheKeyRegistry, $Debug, UserExtensionData>;

@@ -265,4 +299,4 @@ revisionMergeStrategy: RevisionMergeStrategy<CacheKeyRegistry, $Debug, UserExtensionData>;

}): Promise<CacheKeyRegistry[Key]>;
async set<Key extends keyof CacheKeyRegistry>(cacheKey: Key, value: CacheKeyRegistry[Key]): Promise<CacheKeyRegistry[Key]>;
async delete<Key extends keyof CacheKeyRegistry>(cacheKey: Key): Promise<boolean>;
async set(cacheKey: Key, value: CacheKeyRegistry[Key]): Promise<CacheKeyRegistry[Key]>;
async delete(cacheKey: Key): Promise<boolean>;

@@ -425,3 +459,3 @@ /**

// For example, parent === book, prop === 'author'
// Because all userland calls go through GraphQL operations, we have
// Because all userland calls go through Graphql operations, we have
// the metadata necessary to differentiate strings from references

@@ -438,3 +472,2 @@ parent[prop] = id;

// override any previous item for this documentKey
await tx.set(documentKey, document);

@@ -452,2 +485,7 @@ await tx.commit();

// Popopulating transaction ids
// entityUrn_a ... timestamp1 transactionId1
// entityUrn_a ... timestamp2 transactionId2
const defaultMergeStrategy = deepMergeStrategy;

@@ -454,0 +492,0 @@ async function shallowMergeStrategy<CacheKeyRegistry>(id, { entity, revision }, current: CacheKeyValue | undefined, tx: CacheTransaction<CacheKeyRegistry>) {

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

export {};
export { buildCache } from './cache.js';

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