UNPKG

4.58 kBPlain TextView Raw
1//import 'reflect-metadata'
2import {Repo} from "./Repo"
3import {NoReflectionMetataError} from './Errors'
4import {IModel, IModelType} from "./ModelTypes"
5import {IIndexOptions,IPlugin} from "./PluginTypes";
6import {isNumber} from './Util'
7
8
9export * from './ModelTypes'
10export * from './PluginTypes'
11
12
13export enum ModelPersistenceEventType {
14 Save = 1,
15 Remove
16}
17
18export type ModelPersistenceEventCallback<M> = (type:ModelPersistenceEventType,...models:M[]) => void
19
20/**
21 * Options for repo decorations
22 */
23export interface IRepoOptions {
24 indexes?:Array<IIndexOptions>
25}
26
27/**
28 * Options for finder decorations
29 */
30export interface IFinderOptions {
31 optional?:boolean
32 single?:boolean
33}
34
35
36
37/**
38 * Finder request for paging, etc
39 */
40export class FinderRequest {
41 extra:any
42 limit:number = -1
43 offset:number = 0
44 sort:string[]
45 sortDirection:'desc'|'asc'
46 includeModels:boolean = null
47
48 constructor(obj:any)
49 constructor(limit:number,offset:number,includeModels?:boolean,sort?:string[],sortDirection?:'asc'|'desc',extra?:any)
50 constructor(limitOrObject,offset = 0,includeModels:boolean = null,sort:string[] = null,sortDirection:'asc'|'desc' = 'asc',extra:any = null) {
51 if (typeof limitOrObject === 'number') {
52 Object.assign(this,{
53 limit:limitOrObject,
54 offset,
55 includeModels,
56 sort,
57 sortDirection,
58 extra
59 })
60 } else {
61 Object.assign(this,limitOrObject)
62 }
63 }
64}
65
66export interface IFinderItemMetadata {
67 score?:number
68 finderName?:string
69}
70
71/**
72 * Finder result array - not implemented yet, mostly
73 */
74export class FinderResultArray<T> extends Array<T> {
75
76 pageNumber:number = -1
77 pageCount:number = -1
78
79 constructor(
80 items:T[],
81 public total:number,
82 public request:FinderRequest = null,
83 public itemMetadata:IFinderItemMetadata[] = null
84 ) {
85 super(items.length)
86 items.forEach((item,index) => this[index] = item)
87
88 if (request) {
89 this.pageCount = Math.ceil(total / request.limit)
90 this.pageNumber = isNumber(request.offset) ?
91 Math.floor(request.offset / request.limit) :
92 -1
93 }
94 }
95}
96
97/**
98 * Simple base model implementation
99 * uses reflection to determine type
100 */
101export class DefaultModel implements IModel {
102 get clazzType() {
103 const type = Reflect.getOwnMetadata('design:type',this)
104 if (!type)
105 throw new NoReflectionMetataError('Unable to reflect type information')
106
107 return type.name
108 }
109
110}
111
112/**
113 * Sync strategy for updating models in the store
114 */
115export enum SyncStrategy {
116 Overwrite,
117 Update,
118 None
119}
120
121export namespace SyncStrategy {
122 export const toString = (strategy:SyncStrategy):string => {
123 return SyncStrategy[strategy]
124 }
125}
126/**
127 * Coordinator configuration, this is usually extend
128 * by individual store providers
129 */
130
131export interface ICoordinatorOptions {
132 immutable?:boolean
133 syncStrategy?: SyncStrategy
134 autoRegisterModels?: boolean
135}
136
137/**
138 * Coordinator options default implementation
139 */
140export class CoordinatorOptions implements ICoordinatorOptions {
141
142 /**
143 * Default manager options
144 *
145 * @type {{autoRegisterModules: boolean, syncStrategy: SyncStrategy, immutable: boolean}}
146 */
147 static Defaults = {
148 autoRegisterModules:true,
149 syncStrategy: SyncStrategy.None,
150 immutable: false
151 }
152
153 constructor(opts = {}) {
154 Object.assign(this,opts,CoordinatorOptions.Defaults)
155 }
156}
157
158
159export interface IModelMapperDecorator<M> {
160 (json:any,model:M):M
161}
162/**
163 * Mapper interface for transforming objects back and forth between json
164 * and their respective models
165 */
166export interface IModelMapper<M extends IModel> {
167 toObject(o:M):Object
168 toJson(o:M):string
169 fromObject(json:Object,decorator?:IModelMapperDecorator<M>):M
170 fromJson(json:string,decorator?:IModelMapperDecorator<M>):M
171}
172
173/**
174 * Predicate for searching
175 */
176export interface IPredicate {
177 (val:any):boolean
178}
179
180/**
181 * Makes a predicate for reuse
182 */
183export interface IPredicateFactory {
184 (...args:any[]):IPredicate
185}
186
187/**
188 * Predicate for searching
189 */
190export interface ITypedPredicate<T> {
191 (val:T):boolean
192}
193
194/**
195 * Makes a predicate for reuse
196 */
197export interface ITypedPredicateFactory<T> {
198 (type:{new():T},...args:any[]):ITypedPredicate<T>
199}
200
201
202/**
203 * Coordinator interface for store provider development
204 * and end user management
205 *
206 * TODO: Rename coordinator
207 */
208export interface ICoordinator {
209 getOptions():ICoordinatorOptions
210 getModels():IModelType[]
211 getModel(clazz:any):IModelType
212 getModelByName(name:string)
213 start(...models):Promise<ICoordinator>
214 init(opts:ICoordinatorOptions, ...plugins:IPlugin[]):Promise<ICoordinator>
215 reset():Promise<ICoordinator>
216 getRepo<T extends Repo<M>,M extends IModel>(clazz:{new(): T; }):T
217}
218
219