/
schema-manager.ts
81 lines (67 loc) · 2.37 KB
/
schema-manager.ts
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
import type { GraphQLSchema } from 'graphql';
import { ExtensionManager } from './extension-manager';
import type { SchemaManagerHost } from './types';
export type SchemaBuildErrorInfo = {
message: string;
fileName: string;
fileContent: string;
locations?: ReadonlyArray<{ line: number; character: number }>;
};
export type OnChangeCallback = (errors: SchemaBuildErrorInfo[] | null, schema: GraphQLSchema | null) => void;
export abstract class SchemaManager {
private _onChanges: OnChangeCallback[];
private _extensionManager: ExtensionManager;
constructor(protected _host: SchemaManagerHost) {
this._onChanges = [];
this._extensionManager = new ExtensionManager(_host);
this._extensionManager.readExtensions();
}
abstract getBaseSchema(): GraphQLSchema | null;
protected abstract waitBaseSchema(): Promise<GraphQLSchema | null>;
protected abstract startWatch(interval?: number): void;
start(interval?: number) {
this._extensionManager.startWatch(() => this.emitChange(), interval);
this.startWatch(interval);
}
getSchema(): { schema: GraphQLSchema | null; errors: SchemaBuildErrorInfo[] | null } {
const baseSchema = this.getBaseSchema();
const schema = baseSchema && this._extensionManager.extendSchema(baseSchema);
if (schema) {
return { schema, errors: null };
} else {
return { schema: null, errors: this._extensionManager.getSchemaErrors() };
}
}
async waitSchema(): Promise<{ schema: GraphQLSchema | null; errors: SchemaBuildErrorInfo[] | null }> {
const baseSchema = await this.waitBaseSchema();
if (!baseSchema) return { schema: null, errors: null };
const schema = this._extensionManager.extendSchema(baseSchema);
if (schema) {
return { schema, errors: null };
} else {
return { schema: null, errors: this._extensionManager.getSchemaErrors() };
}
}
registerOnChange(cb: OnChangeCallback) {
this._onChanges.push(cb);
return () => {
this._onChanges = this._onChanges.filter(x => x !== cb);
};
}
protected emitChange() {
const { errors, schema } = this.getSchema();
this._onChanges.forEach(cb => cb(errors, schema));
}
protected log(msg: string) {
this._host.log(msg);
}
}
export class NoopSchemaManager extends SchemaManager {
startWatch() {}
async waitBaseSchema() {
return null;
}
getBaseSchema() {
return null;
}
}