tinycoll
Version:
A minimal reactive document store with Mongo-like querying, reactivity, TTL support, and optional persistence.
115 lines (114 loc) • 4.32 kB
TypeScript
import { Query } from './internal/match.js';
import { StorageAdapter } from './storage.js';
import { Modifier } from './internal/modifier.js';
type Projected<TDoc, TPrj> = keyof TPrj extends never ? TDoc : Pick<TDoc, Extract<keyof TPrj, keyof TDoc>>;
type Projection<TDoc> = Partial<Record<keyof TDoc, 1>>;
type Sort<TDoc> = Partial<Record<keyof TDoc, 1 | -1>>;
type WithId<T = {}> = T & {
id: string;
};
type WithoutId<T = {}> = Omit<T, 'id'>;
type WithOptionalId<T = {}> = WithoutId<T> & {
id?: string;
};
export type Document = WithId<Record<string, any>>;
export interface Observer {
id: string;
stop: () => void;
}
interface UpdateResult<T> {
matchedCount: number;
modifiedCount: number;
upsertedCount: number;
upsertedId: string | null;
}
interface FindOptions<TDoc extends Document, TPrj = Projection<TDoc>> {
projection?: TPrj;
sort?: Sort<TDoc>;
skip?: number;
limit?: number;
}
interface UpdateOptions {
upsert?: boolean;
}
interface TtlIndex {
field: string;
expireAfterSeconds: number;
}
interface Change<T> {
type: 'added' | 'removed' | 'changed';
doc: T;
}
declare class Cursor<TDoc extends Document, TOut = TDoc> {
#private;
constructor(queryFn: () => Array<TDoc>, options?: FindOptions<TDoc>);
sort(sort: Sort<TDoc>): Cursor<TDoc, TOut>;
limit(limit: number): Cursor<TDoc, TOut>;
skip(skip: number): Cursor<TDoc, TOut>;
project<TProjection = Projection<TDoc>, TOut = Cursor<TDoc, Projected<TDoc, TProjection>>>(projection: TProjection): TOut;
paginate(page: number, perPage: number): Cursor<TDoc, TOut>;
observe(fn: (change: Change<TDoc>) => void): Observer;
watch(callback: (results: TOut[]) => void, options?: {
immediate?: boolean;
}): Observer;
toArray(): Array<TOut>;
map<U>(fn: (doc: TDoc) => U): Array<U>;
forEach(fn: (doc: TDoc) => void): void;
count(): number;
first(): TOut | undefined;
last(): TOut | undefined;
exists(): boolean;
group<TGroup extends GroupExpression<TDoc>, TOut = GroupResult<TDoc, TGroup>>(group: TGroup): Cursor<TDoc, TOut>;
distinct<K extends keyof TOut>(key: K): Array<TOut[K]>;
}
export declare class Collection<TDoc extends Document, TMeta extends WithoutId<Document> = {}> {
#private;
get meta(): Meta<WithId<TMeta>>;
constructor(name: string, options?: {
storage?: StorageAdapter;
ttlIndexes?: TtlIndex[];
ttlInterval?: number;
});
dispose(): void;
onReady(callback: () => void): void;
get ready(): Promise<void>;
batch<Fn extends () => any>(fn: Fn): ReturnType<Fn> extends Promise<any> ? Promise<void> : void;
insert(doc: WithOptionalId<TDoc>): void;
update(query: Query<TDoc>, modifier: Modifier<TDoc>, opts?: UpdateOptions): UpdateResult<TDoc>;
remove(query: Query<TDoc>): void;
transaction(fn: () => Promise<void>): Promise<void>;
find<TPrj extends Projection<TDoc> = {}, TOut = Projected<TDoc, TPrj>>(query?: Query<TDoc>, opts?: FindOptions<TDoc, TPrj>): Cursor<TDoc, TOut>;
findOne<TPrj extends Projection<TDoc> = {}, TOut = Projected<TDoc, TPrj>>(query: Query<TDoc>, opts?: FindOptions<TDoc, TPrj>): TOut | undefined;
count(query?: Query<TDoc>): number;
}
type SumAccumulator = {
$sum: 1;
};
type PushAccumulator<T extends Document> = {
$push: '$$ROOT';
} | {
$push: keyof T;
};
type GroupAccumulator<T extends Document> = SumAccumulator | PushAccumulator<T>;
type GroupExpression<T extends Document> = {
key: Extract<keyof T, string>;
[key: string]: GroupAccumulator<T> | keyof T;
};
type GroupResult<TDoc extends Document, TGroup extends GroupExpression<TDoc>> = {
[K in keyof TGroup]: K extends 'key' ? TGroup[K] extends keyof TDoc ? TDoc[TGroup[K]] : unknown : TGroup[K] extends {
$sum: 1;
} ? number : TGroup[K] extends {
$push: '$$ROOT';
} ? TDoc[] : TGroup[K] extends {
$push: keyof TDoc;
} ? Array<TDoc[TGroup[K]['$push']]> : never;
};
declare class Meta<TMeta extends Document> extends Collection<WithId<TMeta>, {}> {
#private;
constructor(name: string, options: {
storage?: StorageAdapter;
});
get<K extends keyof TMeta>(key: K): TMeta[K] | undefined;
set<K extends keyof TMeta>(key: K, value: TMeta[K]): void;
}
export {};