UNPKG

10.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const lifecycle_1 = require("@stoplight/lifecycle");
4const uuidv4 = require("uuid/v4");
5const errorReporter_1 = require("./errorReporter");
6const graph_1 = require("./graph");
7const dom_1 = require("./graph/dom");
8const nodes_1 = require("./graph/nodes");
9const notifier_1 = require("./notifier");
10const resolver_1 = require("./resolver");
11const scheduler_1 = require("./scheduler");
12const taskHandler_1 = require("./scheduler/taskHandler");
13const specProviderRegistry_1 = require("./services/specProviderRegistry");
14function createGraphite(props = {}) {
15 return new Graphite(props);
16}
17exports.createGraphite = createGraphite;
18class Graphite {
19 constructor(props) {
20 this._disposables = new lifecycle_1.DisposableCollection();
21 this.dispose = () => {
22 this._disposables.dispose();
23 };
24 this.id = props.id || uuidv4();
25 this.notifier = (props.graph && props.graph.notifier) || props.notifier || notifier_1.createNotifier();
26 this.graph =
27 props.graph ||
28 graph_1.createGraph({
29 id: this.id,
30 idGenerator: props.idGenerator,
31 notifier: this.notifier,
32 });
33 this.resolver = resolver_1.createResolver(new resolver_1.ResolveCache(), this.graph.getNodeByUri);
34 this.scheduler =
35 props.scheduler ||
36 scheduler_1.createScheduler({
37 graph: this.graph,
38 resolver: this.resolver,
39 });
40 this._disposables.pushAll([this.graph, this.notifier]);
41 this._disposables.pushAll(this.scheduleSerialize());
42 this._disposables.pushAll(this.scheduleDeserialize());
43 this._disposables.pushAll(this.scheduleComputeSourceMap());
44 this._disposables.pushAll(this.scheduleTransformations());
45 if (!props.isMirror) {
46 this._disposables.pushAll(this.scheduleValidateSourceNode());
47 this._disposables.pushAll(this.scheduleResolveSourceNode(props.resolveEagerly));
48 }
49 const sourceNodeDataHandler = (op) => {
50 const node = this.graph.getNodeById(op.id);
51 if (!node) {
52 console.debug(`${dom_1.GraphOp[op.op]} node with id ${op.id} not found.`);
53 return;
54 }
55 this.notifier.emit(notifier_1.GraphiteEvent.DidChangeSourceNode, {
56 node: node.dehydrate(),
57 change: op,
58 });
59 };
60 this._disposables.pushAll([
61 this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, sourceNodeDataHandler),
62 this.notifier.on(notifier_1.GraphiteEvent.DidPatchSourceNodeProp, sourceNodeDataHandler),
63 ]);
64 this._disposables.push(errorReporter_1.errorReporter.onError(result => {
65 this.notifier.emit(notifier_1.GraphiteEvent.DidError, result);
66 }));
67 }
68 registerPlugins(...plugins) {
69 const disposables = new lifecycle_1.DisposableCollection();
70 plugins.forEach(plugin => {
71 plugin.tasks.forEach(task => {
72 disposables.push(this.scheduler.registerHandler(task.operation, task.handler));
73 });
74 if (plugin.specProvider) {
75 disposables.push(specProviderRegistry_1.registry.register(plugin.specProvider));
76 }
77 });
78 return disposables;
79 }
80 scheduleTransformations() {
81 return [
82 this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, ({ id, prop, trace = {}, previousValue }) => {
83 if (prop === 'spec') {
84 this.scheduler.queue({
85 op: scheduler_1.GraphTaskOp.TransformParsed,
86 nodeId: id,
87 trace,
88 });
89 }
90 else if (prop === 'data.resolved') {
91 this.scheduler.queue({
92 op: scheduler_1.GraphTaskOp.TransformParsed,
93 nodeId: id,
94 trace,
95 oldValue: previousValue,
96 });
97 }
98 }),
99 this.notifier.on(notifier_1.GraphiteEvent.DidUpdateSourceMapNodeResolved, ({ id, oldValue, trace }) => {
100 this.scheduler.queue({
101 op: scheduler_1.GraphTaskOp.TransformParsed,
102 nodeId: id,
103 trace,
104 oldValue,
105 });
106 }),
107 ];
108 }
109 scheduleDeserialize() {
110 const handler = (op) => {
111 const { id, prop, trace = {} } = op;
112 if (prop !== 'data.raw' && prop !== 'data.original' && prop !== 'data.parsed')
113 return;
114 this.scheduler
115 .queue({
116 op: scheduler_1.GraphTaskOp.DeserializeSourceNode,
117 nodeId: id,
118 trace,
119 recomputeOnly: prop === 'data.parsed',
120 })
121 .then(() => {
122 this.notifier.emit(notifier_1.GraphiteEvent.DidPatchSourceNodePropComplete, op);
123 });
124 };
125 return [
126 this.notifier.on(notifier_1.GraphiteEvent.DidAddNode, ({ node, trace = {} }) => {
127 if (node.category !== nodes_1.NodeCategory.Source || !node.data || !node.data.raw)
128 return;
129 this.scheduler.queue({
130 op: scheduler_1.GraphTaskOp.DeserializeSourceNode,
131 nodeId: node.id,
132 trace,
133 });
134 }),
135 this.notifier.on(notifier_1.GraphiteEvent.DidPatchSourceNodeProp, handler),
136 this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, handler),
137 ];
138 }
139 scheduleSerialize() {
140 const handler = ({ id, prop, trace = {} }) => {
141 if (prop !== 'data.parsed' || trace.sourceOp === scheduler_1.GraphTaskOp.DeserializeSourceNode)
142 return;
143 this.scheduler.queue({
144 op: scheduler_1.GraphTaskOp.SerializeSourceNode,
145 nodeId: id,
146 trace,
147 });
148 };
149 return [
150 this.notifier.on(notifier_1.GraphiteEvent.DidPatchSourceNodeProp, handler),
151 this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, handler),
152 ];
153 }
154 scheduleComputeSourceMap() {
155 return [
156 this.notifier.on(notifier_1.GraphiteEvent.DidPatchSourceNodeProp, ({ id, prop, trace = {}, value }) => {
157 if (prop !== 'data.parsed')
158 return;
159 this.scheduler.queue({
160 op: scheduler_1.GraphTaskOp.ComputeSourceMap,
161 nodeId: id,
162 patch: value,
163 trace,
164 });
165 }),
166 this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, ({ id, prop, trace = {}, value }) => {
167 if (prop !== 'data.parsed')
168 return;
169 this.scheduler.queue({
170 op: scheduler_1.GraphTaskOp.ComputeSourceMap,
171 nodeId: id,
172 trace,
173 });
174 }),
175 this.notifier.on(notifier_1.GraphiteEvent.DidAddNode, ({ node, trace }) => {
176 if (node.category !== nodes_1.NodeCategory.Source || !node.data || !node.data.parsed)
177 return;
178 this.scheduler.queue({
179 op: scheduler_1.GraphTaskOp.ComputeSourceMap,
180 nodeId: node.id,
181 trace,
182 });
183 }),
184 ];
185 }
186 scheduleResolveSourceNode(eager) {
187 const disposables = [
188 this.scheduler.registerHandler(scheduler_1.GraphTaskOp.ResolveSourceNode, taskHandler_1.createTaskHandler({
189 selector: node => node.category === nodes_1.NodeCategory.Source,
190 run: scheduler_1.resolveSourceNodeHandler,
191 }, 'resolver-handler')),
192 ];
193 const isCustomized = Array.isArray(eager) && eager.length > 0;
194 const shouldResolve = isCustomized
195 ? (id) => {
196 const node = this.graph.getNodeById(id);
197 return (node !== void 0 &&
198 node.category === nodes_1.NodeCategory.Source &&
199 node.spec !== void 0 &&
200 eager.includes(node.spec));
201 }
202 : null;
203 if (eager !== false || isCustomized) {
204 const scheduleResolving = ({ id, trace = {} }) => {
205 return this.scheduler.queue({
206 op: scheduler_1.GraphTaskOp.ResolveSourceNode,
207 nodeId: id,
208 trace,
209 });
210 };
211 const handler = (op) => {
212 if (op.prop !== 'data.parsed' || (shouldResolve !== null && !shouldResolve(op.id)))
213 return;
214 return scheduleResolving(op);
215 };
216 disposables.push(this.notifier.on(notifier_1.GraphiteEvent.DidPatchSourceNodeProp, handler), this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, handler));
217 if (isCustomized) {
218 disposables.push(this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, op => {
219 if (op.prop !== 'spec')
220 return;
221 const node = this.graph.getNodeById(op.id);
222 if (node === void 0 || node.category !== nodes_1.NodeCategory.Source) {
223 throw new Error('Invalid node given');
224 }
225 if (node.data.resolved !== void 0) {
226 return;
227 }
228 return scheduleResolving(op);
229 }));
230 }
231 }
232 return disposables;
233 }
234 scheduleValidateSourceNode() {
235 const handler = ({ id, prop, trace = {} }) => {
236 if (prop !== 'data.parsed')
237 return;
238 this.scheduler.queue({
239 op: scheduler_1.GraphTaskOp.ValidateSourceNode,
240 nodeId: id,
241 trace,
242 });
243 };
244 return [
245 this.notifier.on(notifier_1.GraphiteEvent.DidSetSourceNodeProp, handler),
246 this.notifier.on(notifier_1.GraphiteEvent.DidPatchSourceNodeProp, handler),
247 ];
248 }
249}
250//# sourceMappingURL=graphite.js.map
\No newline at end of file