Sets up global cache and uses it to fetch sessions
This commit is contained in:
81
src/lib/recordCache.ts
Normal file
81
src/lib/recordCache.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import {
|
||||
type CollectionId,
|
||||
type AnyDocument,
|
||||
CollectionIds,
|
||||
type Relationship,
|
||||
type DocumentId,
|
||||
type RelationshipId,
|
||||
} from "./types";
|
||||
|
||||
type CacheKey<C extends CollectionId = CollectionId> = `${C}:${string}`;
|
||||
type DocumentKey = CacheKey<typeof CollectionIds.Documents>;
|
||||
type RelationshipKey = CacheKey<typeof CollectionIds.Relationships>;
|
||||
|
||||
export class RecordCache {
|
||||
private cache: Record<
|
||||
`${CollectionId}:${string}`,
|
||||
{
|
||||
record: AnyDocument | Relationship;
|
||||
subscriptions: ((record: AnyDocument | Relationship | null) => void)[];
|
||||
}
|
||||
> = {};
|
||||
|
||||
private makeKey<C extends CollectionId>(
|
||||
collectionId: C,
|
||||
id: string,
|
||||
): CacheKey<C> {
|
||||
return `${collectionId}:${id}`;
|
||||
}
|
||||
|
||||
private docKey = (id: DocumentId): DocumentKey =>
|
||||
this.makeKey(CollectionIds.Documents, id);
|
||||
|
||||
private relationKey = (id: RelationshipId): RelationshipKey =>
|
||||
this.makeKey(CollectionIds.Relationships, id);
|
||||
|
||||
get = (key: CacheKey): AnyDocument | Relationship | undefined =>
|
||||
this.cache[key]?.record;
|
||||
|
||||
set = (record: AnyDocument | Relationship) => {
|
||||
const key = this.makeKey(record.collectionName, record.id);
|
||||
if (this.cache[key] === undefined) {
|
||||
this.cache[key] = {
|
||||
record,
|
||||
subscriptions: [],
|
||||
};
|
||||
}
|
||||
const entry = this.cache[key];
|
||||
|
||||
entry.record = record;
|
||||
|
||||
for (const subscription of entry.subscriptions) {
|
||||
subscription(record);
|
||||
}
|
||||
|
||||
for (const doc of record.expand?.secondary ?? []) {
|
||||
this.set(doc);
|
||||
}
|
||||
for (const rel of record.expand?.relationships_via_primary ?? []) {
|
||||
this.set(rel);
|
||||
}
|
||||
};
|
||||
|
||||
remove = (key: CacheKey) => {
|
||||
const entry = this.cache[key];
|
||||
delete this.cache[key];
|
||||
for (const subscription of entry.subscriptions) {
|
||||
subscription(null);
|
||||
}
|
||||
};
|
||||
|
||||
getDocument = (id: DocumentId): AnyDocument | undefined =>
|
||||
this.get(this.docKey(id)) as AnyDocument | undefined;
|
||||
|
||||
getRelationship = (id: RelationshipId): Relationship | undefined =>
|
||||
this.get(this.relationKey(id)) as Relationship | undefined;
|
||||
|
||||
removeDocument = (id: DocumentId) => this.remove(this.docKey(id));
|
||||
|
||||
removeRelationship = (id: RelationshipId) =>
|
||||
this.remove(this.relationKey(id));
|
||||
}
|
||||
Reference in New Issue
Block a user