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; export type ObjectId = string; export interface Deferred { promise: Promise; resolve: (val?: T) => void; reject: (err: Error) => void; } export interface ArrayEmitter extends Array { $emitter: EventEmitter; $subject: BehaviorSubject>; 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; $subject: BehaviorSubject; $resolvedSubject: Subject; $deferred: Deferred; $resolved: boolean; $loc: LocalModel; $id: string; $save: {(): Promise}; $remove: {(noPrompt?: boolean, skipLocal?: boolean): Promise}; $delete: {(): Promise}; $type: {(): string}; $reset: {(): void}; $refresh: {(): void}; $toObject: {(): any}; $updateServer: {(val: any): void}; } export interface Resource { get?: { (id: string, force?: boolean): T, (ids: string[], force?: boolean): ModelArray, (ids: string | string[], force?: boolean): (ModelArray | T), }; query?: {(qry: any, limit?: number): Query}; chain?: ChainFunction; type?: {(): string}; collect?: {(seeds: Model | ModelArray, relation: CollectionSearcher): Collection}; 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 { (url: string, rootKey: string, rootKeyPlural?: string): Resource; Chain?: Chain; } export interface LocalModel { _id?: ObjectId; $emitter: EventEmitter; $created: boolean; $createdAt: number; $deleted: boolean; $promise: Promise; $deferred: Deferred; $resolved: boolean; $resync: any[]; $dbsync: Promise; $saveprom: Promise; $mod: Model; $id: string; $dbresync: boolean; $serv: ServerModel; $save: {(vals: any): Promise}; $remove: {(skipServer?: boolean): Promise}; $delete: {(): Promise}; $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)}; query?: {(qry: any, limit: number, Resource: any): Query}; collect?: {(Resource: Resource, seeds: Model | ModelArray, relation: CollectionSearcher): Collection}; } export interface LocalResourceFactory { (url: string, rootKey: string, rootKeyPlural: string): LocalResource; } export interface ServerModel { _id?: ObjectId; $id: string; $emitter: EventEmitter; $deleted: boolean; $promise: Promise; $resolved: boolean; $fetching: boolean; $deferred: Deferred; $save: {(patch: JSONPatch): Promise}; $remove: {(): Promise}; $delete: {(): Promise}; $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 extends Array { $promise?: Promise>; } export interface Query extends ArrayEmitter { $refresh: {(force?: boolean): Promise>}; $promise: Promise>; $subject: BehaviorSubject>; $resolvedSubject: Subject>; $resolved: boolean; $Model: any; $serverResults?: Query; $skip?: number; $hasNext: boolean; $hasPrev: boolean; extend: {(obj: any, noSanitize?: boolean, retServer?: boolean): Promise>}; replace: {(qry: any, retServer?: boolean): Promise>}; get: {(...args: any[]): any}; next: {(num?: number): Promise>}; prev: {(num?: number): Promise>}; chain: {(Model: any, qryFn: QueryFunction): Query}; 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; refresh?: {(): any}; } export interface QueryFactory { (url: string, rootKey: string, rootKeyPlural: string, db: Database): QueryList; } export type QueryFunction = (this: Query, results: Model[]) => any; export type MultiQueryFunction = (this: Query, results: Model[][]) => any; export interface ChainFunction { (origQry: ChainableQuery, modelOrQryFn: (Resource | QueryFunction), qryFn?: QueryFunction): Query; } export interface Chain extends ChainFunction { all?: {(origQueries: Array>, Model: Resource, qryFn: MultiQueryFunction): Query}; } export interface ChainableQuery extends Array { $emitter: EventEmitter; $promise: Promise; } export interface Seeds extends Array { on?: {(name: string, handler: Handler): void}; removeListener?: {(name: string, handler: Handler): void}; } export interface CollectionFactory { (): CollectionStatic; } export interface CollectionStatic { new (Resource: Resource, seeds: Model | Seeds, searcherOrProp: CollectionSearcher): Collection; } export interface Collection extends ArrayEmitter { $promise: Promise>; $resolved: boolean; chain: {(Model: any, qryFn: QueryFunction): Query}; 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}; query: {(query: any): Promise}; patch: {(id: string, patch: JSONPatch): Promise}; create: {(data: any): Promise}; remove: {(id: string): Promise}; } export interface DatabaseFactory { (): Database; } export abstract class Database { public abstract update(res: LocalModel): Promise; public abstract query(qry: any): Promise; 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(key: string): Promise; getItem(key: string, callback: (err: any, value: T) => void): void; setItem(key: string, value: T): Promise; setItem(key: string, value: T, callback: (err: any, value: T) => void): void; removeItem(key: string): Promise; removeItem(key: string, callback: (err: any) => void): void; clear(): Promise; clear(callback: (err: any) => void): void; length(): Promise; length(callback: (err: any, numberOfKeys: number) => void): void; key(keyIndex: number): Promise; key(keyIndex: number, callback: (err: any, key: string) => void): void; keys(): Promise; keys(callback: (err: any, keys: string[]) => void): void; iterate(iteratee: (value: any, key: string, iterationNumber: number) => any): Promise; iterate(iteratee: (value: any, key: string, iterationNumber: number) => any, callback: (err: any, result: any) => void): void; driver(): string; } export interface Plugin { (Resource: Resource, modelName: string): void; }