@ortoo/angular-resource
Version:
Magical CRUD resource management for angular
315 lines (262 loc) • 9.2 kB
text/typescript
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import {EventEmitter, Handler, Subscription} from './emitter';
export { Handler as EventHandler } from './emitter';
export type ModelOrModelArray = Model | ModelArray<Model>;
export type ObjectId = string;
export interface Deferred<T> {
promise: Promise<T>;
resolve: (val?: T) => void;
reject: (err: Error) => void;
}
export interface ArrayEmitter<T> extends Array<T> {
$emitter: EventEmitter;
$subject: BehaviorSubject<ArrayEmitter<T>>;
on: {(name: string, handler: Handler): void};
off: {(name: string, handler: Handler): void};
listen: {(name: string, handler: Handler): Subscription};
once: {(name: string, handler: Handler): void};
addListener: {(name: string, handler: Handler): void};
removeListener: {(name: string, handler: Handler): void};
}
export interface Model {
_id?: ObjectId;
$created: boolean;
$deleted: boolean;
$promise: Promise<Model>;
$subject: BehaviorSubject<Model>;
$resolvedSubject: Subject<Model>;
$deferred: Deferred<Model>;
$resolved: boolean;
$loc: LocalModel;
$id: string;
$save: {(): Promise<Model>};
$remove: {(noPrompt?: boolean, skipLocal?: boolean): Promise<boolean>};
$delete: {(): Promise<boolean>};
$type: {(): string};
$reset: {(): void};
$refresh: {(): void};
$toObject: {(): any};
$updateServer: {(val: any): void};
}
export interface Resource<T> {
get?: {
(id: string, force?: boolean): T,
(ids: string[], force?: boolean): ModelArray<T>,
(ids: string | string[], force?: boolean): (ModelArray<T> | T),
};
query?: {(qry: any, limit?: number): Query<T>};
chain?: ChainFunction;
type?: {(): string};
collect?: {(seeds: Model | ModelArray<T>, relation: CollectionSearcher): Collection<T>};
updateOrCreate?: {(val: any): T};
// Event emitter methods
dispose: {(): void};
addListener: {(name: string, handler: Handler): void};
emit: {(fnName: string, ...data: any[]): void};
listen: {(name: string, handler: Handler): Subscription};
off: {(name: string, handler: Handler): void};
on: {(name: string, handler: Handler): void};
once: {(name: string, handler: Handler): void};
removeListener: {(name: string, handler: Handler): void};
new (val?: any, fromLoc?: boolean, lastRequested?: (number | Date)): T;
}
export interface ResourceFactory<T> {
(url: string, rootKey: string, rootKeyPlural?: string): Resource<T>;
Chain?: Chain;
}
export interface LocalModel {
_id?: ObjectId;
$emitter: EventEmitter;
$created: boolean;
$createdAt: number;
$deleted: boolean;
$promise: Promise<LocalModel>;
$deferred: Deferred<LocalModel>;
$resolved: boolean;
$resync: any[];
$dbsync: Promise<void>;
$saveprom: Promise<any>;
$mod: Model;
$id: string;
$dbresync: boolean;
$serv: ServerModel;
$save: {(vals: any): Promise<LocalModel>};
$remove: {(skipServer?: boolean): Promise<boolean>};
$delete: {(): Promise<boolean>};
$refresh: {(): void};
$toObject: {(): any};
$updateServer: {(val: any): void};
}
export interface LocalResource {
(val: any, fromServ?: boolean, mod?: any, lastRequested?: (Date | number)): void;
get?: {(ids: (string[] | string), force?: boolean, transform?: Function): (ModelArray<Model> | Model)};
query?: {(qry: any, limit: number, Resource: any): Query<Model>};
collect?: {(Resource: Resource<Model>,
seeds: Model | ModelArray<Model>,
relation: CollectionSearcher): Collection<Model>};
}
export interface LocalResourceFactory {
(url: string, rootKey: string, rootKeyPlural: string): LocalResource;
}
export interface ServerModel {
_id?: ObjectId;
$id: string;
$emitter: EventEmitter;
$deleted: boolean;
$promise: Promise<ServerModel>;
$resolved: boolean;
$fetching: boolean;
$deferred: Deferred<ServerModel>;
$save: {(patch: JSONPatch): Promise<ServerModel>};
$remove: {(): Promise<boolean>};
$delete: {(): Promise<boolean>};
$refresh: {(): void};
$toObject: {(): any};
$updateServer: {(val: any): void};
$updateVal: {(val: any): void};
}
export interface ServerResource {
(val?: any, id?: string): void;
get?: {(ids: (string[] | string), force?: boolean, transform?: Function): (any[] | any)};
}
export interface ServerResourceFactory {
(url: string, rootKey: string, rootKeyPlural: string): ServerResource;
}
export interface ModelArray<T> extends Array<T> {
$promise?: Promise<ModelArray<T>>;
}
export interface Query<T> extends ArrayEmitter<T> {
$refresh: {(force?: boolean): Promise<Query<T>>};
$promise: Promise<Query<T>>;
$subject: BehaviorSubject<Query<T>>;
$resolvedSubject: Subject<Query<T>>;
$resolved: boolean;
$Model: any;
$serverResults?: Query<T>;
$skip?: number;
$hasNext: boolean;
$hasPrev: boolean;
extend: {(obj: any, noSanitize?: boolean, retServer?: boolean): Promise<Query<T>>};
replace: {(qry: any, retServer?: boolean): Promise<Query<T>>};
get: {(...args: any[]): any};
next: {(num?: number): Promise<Query<T>>};
prev: {(num?: number): Promise<Query<T>>};
chain: {(Model: any, qryFn: QueryFunction): Query<Model>};
transform: Function;
currentLimit: number;
currentSkip: number;
loading: boolean;
hasNext: boolean;
hasPrev: boolean;
}
export interface QueryList {
(qry: any, limit: number, Resource: any, toRes: {(id: string): Model}): Query<Model>;
refresh?: {(): any};
}
export interface QueryFactory {
(url: string, rootKey: string, rootKeyPlural: string, db: Database): QueryList;
}
export type QueryFunction = (this: Query<Model>, results: Model[]) => any;
export type MultiQueryFunction = (this: Query<Model>, results: Model[][]) => any;
export interface ChainFunction {
(origQry: ChainableQuery<Model>,
modelOrQryFn: (Resource<Model> | QueryFunction),
qryFn?: QueryFunction): Query<Model>;
}
export interface Chain extends ChainFunction {
all?: {(origQueries: Array<ChainableQuery<Model>>, Model: Resource<Model>, qryFn: MultiQueryFunction): Query<Model>};
}
export interface ChainableQuery<T> extends Array<T> {
$emitter: EventEmitter;
$promise: Promise<T[]>;
}
export interface Seeds extends Array<Model> {
on?: {(name: string, handler: Handler): void};
removeListener?: {(name: string, handler: Handler): void};
}
export interface CollectionFactory<T> {
(): CollectionStatic<T>;
}
export interface CollectionStatic<T> {
new (Resource: Resource<T>, seeds: Model | Seeds, searcherOrProp: CollectionSearcher): Collection<T>;
}
export interface Collection<T> extends ArrayEmitter<T> {
$promise: Promise<Collection<T>>;
$resolved: boolean;
chain: {(Model: any, qryFn: QueryFunction): Query<T>};
check: {(): void};
}
export interface CollectionSearcher {
(objs: Model[]): Observable<(Model[] | string[])>;
}
export interface SocketFactory {
(url: string, rootKey: string, rootKeyPlural?: string): Socket;
}
export interface Socket {
get: {(ids: string[]): Promise<any>};
query: {(query: any): Promise<any>};
patch: {(id: string, patch: JSONPatch): Promise<any>};
create: {(data: any): Promise<any>};
remove: {(id: string): Promise<any>};
}
export interface DatabaseFactory {
(): Database;
}
export abstract class Database {
public abstract update(res: LocalModel): Promise<any>;
public abstract query(qry: any): Promise<string[]>;
public abstract qryIsSimple(qry: any): boolean;
}
export type JSONPatch = (OpPatch | OpPatch[]);
export type OpPatch = AddPath | RemovePath | ReplacePath | MovePath | CopyPath | TestPath;
export interface Patch {
op: string;
}
export interface AddPath extends Patch {
path: string;
value: any;
}
export interface RemovePath extends Patch {
path: string;
}
export interface ReplacePath extends Patch {
path: string;
value: any;
}
export interface MovePath extends Patch {
from: string;
path: string;
}
export interface CopyPath extends Patch {
from: string;
path: string;
}
export interface TestPath extends Patch {
path: string;
value: any;
}
export interface LocalForage {
getItem<T>(key: string): Promise<T>;
getItem<T>(key: string, callback: (err: any, value: T) => void): void;
setItem<T>(key: string, value: T): Promise<T>;
setItem<T>(key: string, value: T, callback: (err: any, value: T) => void): void;
removeItem(key: string): Promise<void>;
removeItem(key: string, callback: (err: any) => void): void;
clear(): Promise<void>;
clear(callback: (err: any) => void): void;
length(): Promise<number>;
length(callback: (err: any, numberOfKeys: number) => void): void;
key(keyIndex: number): Promise<string>;
key(keyIndex: number, callback: (err: any, key: string) => void): void;
keys(): Promise<string[]>;
keys(callback: (err: any, keys: string[]) => void): void;
iterate(iteratee: (value: any, key: string, iterationNumber: number) => any): Promise<any>;
iterate(iteratee: (value: any, key: string, iterationNumber: number) => any,
callback: (err: any, result: any) => void): void;
driver(): string;
}
export interface Plugin<T> {
(Resource: Resource<T>, modelName: string): void;
}