-
-
Notifications
You must be signed in to change notification settings - Fork 98
Expand file tree
/
Copy pathinterface.ts
More file actions
149 lines (136 loc) · 4.06 KB
/
interface.ts
File metadata and controls
149 lines (136 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
export type Schema =
| null
| string
| { [K: string]: any }
| Schema[]
| SchemaSimple
| Serializable;
export interface Queryable<Args extends readonly any[] = readonly any[]> {
queryKey(
args: Args,
unvisit: (...args: any) => any,
delegate: { getEntity: any; getIndex: any },
// Must be non-void
): {};
}
export type Serializable<
T extends { toJSON(): string } = { toJSON(): string },
> = (value: any) => T;
export interface SchemaSimple<T = any, Args extends readonly any[] = any[]> {
normalize(
input: any,
parent: any,
key: any,
args: any[],
visit: (...args: any) => any,
delegate: { getEntity: any; setEntity: any },
): any;
denormalize(
input: {},
args: readonly any[],
unvisit: (schema: any, input: any) => any,
): T;
queryKey(
args: Args,
unvisit: (...args: any) => any,
delegate: { getEntity: any; getIndex: any },
): any;
}
export interface SchemaClass<T = any, Args extends readonly any[] = any[]>
extends SchemaSimple<T, Args> {
// this is not an actual member, but is needed for the recursive NormalizeNullable<> type algo
_normalizeNullable(): any;
// this is not an actual member, but is needed for the recursive DenormalizeNullable<> type algo
_denormalizeNullable(): any;
}
export interface EntityInterface<T = any> extends SchemaSimple {
createIfValid(props: any): any;
pk(
params: any,
parent: any,
key: string | undefined,
args: readonly any[],
): string | number | undefined;
readonly key: string;
indexes?: any;
schema: Record<string, Schema>;
prototype: T;
cacheWith?: object;
}
export interface Mergeable {
key: string;
merge(existing: any, incoming: any): any;
mergeWithStore(
existingMeta: any,
incomingMeta: any,
existing: any,
incoming: any,
): any;
mergeMetaWithStore(
existingMeta: any,
incomingMeta: any,
existing: any,
incoming: any,
): any;
}
export interface NormalizedIndex {
readonly [entityKey: string]: {
readonly [indexName: string]: { readonly [lookup: string]: string };
};
}
export interface EntityTable {
[entityKey: string]:
| {
[pk: string]: unknown;
}
| undefined;
}
/** Visits next data + schema while recurisvely normalizing */
export interface Visit {
(schema: any, value: any, parent: any, key: any, args: readonly any[]): any;
}
/** Returns true if a circular reference is found */
export interface CheckLoop {
(entityKey: string, pk: string, input: object): boolean;
}
/** Get Array of entities with map function applied */
export interface GetEntity {
(entityKey: string | symbol): { readonly [pk: string]: any } | undefined;
(entityKey: string | symbol, pk: string | number): any;
}
/** Get PK using an Entity Index */
export interface GetIndex {
/** getIndex('User', 'username', 'ntucker') */
(entityKey: string, field: string, value: string): string | undefined;
}
/** Accessors to the currently processing state while building query */
export interface IQueryDelegate {
getEntity: GetEntity;
getIndex: GetIndex;
/** Return to consider results invalid */
INVALID: symbol;
}
/** Helpers during schema.normalize() */
export interface INormalizeDelegate {
/** Action meta-data for this normalize call */
readonly meta: { fetchedAt: number; date: number; expiresAt: number };
/** Gets any previously normalized entity from store */
getEntity: GetEntity;
/** Updates an entity using merge lifecycles when it has previously been set */
mergeEntity(
schema: Mergeable & { indexes?: any },
pk: string,
incomingEntity: any,
): void;
/** Sets an entity overwriting any previously set values */
setEntity(
schema: { key: string; indexes?: any },
pk: string,
entity: any,
meta?: { fetchedAt: number; date: number; expiresAt: number },
): void;
/** Invalidates an entity, potentially triggering suspense */
invalidate(schema: { key: string; indexes?: any }, pk: string): void;
/** Returns true when we're in a cycle, so we should not continue recursing */
checkLoop(key: string, pk: string, input: object): boolean;
}