Files
personal_site/frontend/node_modules/@cdklabs/tskb/lib/database.d.ts
T

96 lines
4.0 KiB
TypeScript

import { Entity, EntityCollection, EntityIndex, Plain, Reference } from './entity';
import { Relationship, RelationshipCollection } from './relationship';
export interface RelationshipsBuilder<ES extends object> {
relationship<R extends Relationship<any, any, any>>(fromKey: KeysFor<ES, EntityCollection<R['from'], any>>, toKey: KeysFor<ES, EntityCollection<R['to'], any>>): RelationshipCollection<R>;
}
export declare class Database<ES extends object, RS extends object> {
static entitiesOnly<ES extends object>(entities: ES): Database<ES, {}>;
private readonly schema;
private idCtr;
constructor(entities: ES, relationships: (x: RelationshipsBuilder<ES>) => RS);
id(): string;
/**
* Allocate an ID and store
*/
allocate<K extends keyof ES>(key: K, entity: Plain<EntityType<ES[K]>>): EntityType<ES[K]>;
/**
* Store with a preallocated ID
*/
store<K extends keyof ES>(key: K, entity: EntityType<ES[K]>): EntityType<ES[K]>;
/**
* Get an entity by key
*/
get<K extends keyof ES>(key: K, id: string | Reference<EntityType<ES[K]>>): EntityType<ES[K]>;
/**
* All entities of a given type
*/
all<K extends keyof ES>(key: K): Array<EntityType<ES[K]>>;
/**
* Lookup an entity by index
*/
lookup<K extends keyof ES, I extends IndexNamesOf<ES[K]>>(key: K, index: I, lookup: IndexOf<ES[K], I>['lookups'], value: IndexOf<ES[K], I>['valueType']): RichReadonlyArray<EntityType<ES[K]>>;
/**
* Allocate an ID and store if the entity does not yet exist
*/
findOrAllocate<K extends keyof ES, I extends keyof Plain<EntityType<ES[K]>> & IndexNamesOf<ES[K]>>(key: K, index: I, lookup: IndexOf<ES[K], I>['lookups'], entity: Plain<EntityType<ES[K]>>): EntityType<ES[K]>;
/**
* Record a relationship between two entities
*
* Overload to account for whether we have attributes or not.
*/
link<K extends RelWAttrs<RS>>(key: K, from: RelType<RS[K]>['from'], to: RelType<RS[K]>['to'], attributes: RelType<RS[K]>['attr']): void;
link<K extends RelWoAttrs<RS>>(key: K, from: RelType<RS[K]>['from'], to: RelType<RS[K]>['to']): void;
/**
* Follow a link
*/
follow<K extends keyof RS>(key: K, from: RelType<RS[K]>['from']): RichReadonlyArray<Link<RelType<RS[K]>['to'], RelType<RS[K]>['attr']>>;
/**
* Follow incoming links backwards
*/
incoming<K extends keyof RS>(key: K, to: RelType<RS[K]>['to']): RichReadonlyArray<Link<RelType<RS[K]>['from'], RelType<RS[K]>['attr']>>;
e<E extends Entity>(entity: Plain<E>): E;
/**
* Turn the current database collection into something that can be stored.
*/
save(): DehydratedDatabase;
load(db: DehydratedDatabase): void;
}
interface DehydratedDatabase {
readonly idCtr: number;
readonly schema: any;
}
export type Link<E, A> = {
readonly entity: E;
} & A;
type RelWAttrs<RS> = {
[K in keyof RS]: {} extends RelType<RS[K]>['attr'] ? never : K;
}[keyof RS];
type RelWoAttrs<RS> = {
[K in keyof RS]: {} extends RelType<RS[K]>['attr'] ? K : never;
}[keyof RS];
type IndexNamesOf<A> = A extends EntityCollection<any> ? KeysOfUnion<A['indexes']> : never;
type IndexOf<EC, I extends IndexNamesOf<EC>> = EC extends EntityCollection<any> ? EC['indexes'][I] extends EntityIndex<any, infer IndexType> ? {
valueType: IndexType;
lookups: keyof EC['indexes'][I]['lookups'];
} : never : never;
type EntityType<A> = A extends EntityCollection<infer B> ? B : never;
type RelType<A> = A extends RelationshipCollection<infer R> ? R : never;
type ResolveUnion<T> = T extends T ? T : never;
type KeysOfUnion<T> = keyof ResolveUnion<T>;
export type EntitiesOf<DB> = DB extends Database<infer ES, any> ? {
[k in keyof ES]: EntityType<ES[k]>;
} : {};
export interface RichReadonlyArray<A> extends ReadonlyArray<A> {
/**
* Return the first and only element, throwing if there are != 1 elements
*/
only(): A;
}
/**
* Return the keys of an object that map to a particular type
*/
type KeysFor<O extends object, T> = {
[k in keyof O]: O[k] extends T ? k : never;
}[keyof O];
export {};