UNPKG

@ortoo/angular-resource

Version:

Magical CRUD resource management for angular

315 lines (262 loc) 9.2 kB
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; }