graphile-build 4.4.4 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -3
- package/README.md +2 -1
- package/node8plus/Live.d.ts +5 -2
- package/node8plus/Live.js +72 -77
- package/node8plus/Live.js.flow +72 -75
- package/node8plus/Live.js.map +1 -1
- package/node8plus/SchemaBuilder.d.ts +1 -0
- package/node8plus/SchemaBuilder.js +16 -3
- package/node8plus/SchemaBuilder.js.flow +14 -0
- package/node8plus/SchemaBuilder.js.map +1 -1
- package/node8plus/callbackToAsyncIterator.js.flow +2 -2
- package/node8plus/callbackToAsyncIterator.js.map +1 -1
- package/node8plus/extend.js +1 -3
- package/node8plus/extend.js.flow +1 -3
- package/node8plus/extend.js.map +1 -1
- package/node8plus/index.d.ts +3 -8
- package/node8plus/index.js +2 -1
- package/node8plus/index.js.flow +1 -0
- package/node8plus/index.js.map +1 -1
- package/node8plus/makeNewBuild.js +12 -6
- package/node8plus/makeNewBuild.js.flow +21 -27
- package/node8plus/makeNewBuild.js.map +1 -1
- package/node8plus/plugins/ClientMutationIdDescriptionPlugin.js.flow +2 -4
- package/node8plus/plugins/ClientMutationIdDescriptionPlugin.js.map +1 -1
- package/node8plus/plugins/NodePlugin.js.flow +1 -3
- package/node8plus/plugins/NodePlugin.js.map +1 -1
- package/node8plus/plugins/SwallowErrorsPlugin.js +0 -1
- package/node8plus/plugins/SwallowErrorsPlugin.js.flow +0 -1
- package/node8plus/plugins/SwallowErrorsPlugin.js.map +1 -1
- package/package.json +7 -13
package/LICENSE.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
The MIT License (MIT)
|
|
2
|
-
=====================
|
|
1
|
+
# The MIT License (MIT)
|
|
3
2
|
|
|
4
3
|
Copyright © `2018` Benjie Gillam
|
|
5
4
|
|
|
@@ -23,4 +22,3 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
23
22
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
24
23
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
25
24
|
OTHER DEALINGS IN THE SOFTWARE.
|
|
26
|
-
|
package/README.md
CHANGED
|
@@ -36,7 +36,8 @@ And please give some love to our featured sponsors 🤩:
|
|
|
36
36
|
|
|
37
37
|
<table><tr>
|
|
38
38
|
<td align="center"><a href="http://chads.website/"><img src="https://www.graphile.org/images/sponsors/chadf.png" width="90" height="90" alt="Chad Furman" /><br />Chad Furman</a></td>
|
|
39
|
-
<td align="center"><a href="https://
|
|
39
|
+
<td align="center"><a href="https://storyscript.io/?utm_source=postgraphile"><img src="https://www.graphile.org/images/sponsors/storyscript.png" width="90" height="90" alt="Storyscript" /><br />Storyscript</a></td>
|
|
40
|
+
<td align="center"><a href="http://p72.vc/"><img src="https://www.graphile.org/images/sponsors/p72.png" width="90" height="90" alt="Point72 Ventures" /><br />Point72 Ventures</a></td>
|
|
40
41
|
</tr></table>
|
|
41
42
|
|
|
42
43
|
<!-- SPONSORS_END -->
|
package/node8plus/Live.d.ts
CHANGED
|
@@ -41,12 +41,15 @@ export abstract class LiveProvider {
|
|
|
41
41
|
export class LiveMonitor {
|
|
42
42
|
providers: { [namespace: string]: LiveProvider };
|
|
43
43
|
subscriptionReleasersByCounter: {
|
|
44
|
-
[counter: string]: (() => void)[]
|
|
44
|
+
[counter: string]: (() => void)[];
|
|
45
45
|
};
|
|
46
46
|
liveConditionsByCounter: { [counter: string]: Array<PredicateGenerator> };
|
|
47
47
|
changeCounter: number;
|
|
48
48
|
|
|
49
|
-
constructor(
|
|
49
|
+
constructor(
|
|
50
|
+
providers: { [namespace: string]: LiveProvider },
|
|
51
|
+
extraRootValue: any
|
|
52
|
+
);
|
|
50
53
|
|
|
51
54
|
resetBefore(currentCounter: number): void;
|
|
52
55
|
release(): void;
|
package/node8plus/Live.js
CHANGED
|
@@ -77,9 +77,76 @@ class LiveMonitor {
|
|
|
77
77
|
this.changeCounter = 0;
|
|
78
78
|
this.liveConditionsByCounter = {};
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
this.handleChange = function () {
|
|
81
|
+
/* This function is throttled to ~25ms (see constructor); it's purpose is
|
|
82
|
+
* to bundle up all the changes that occur in a small window into the same
|
|
83
|
+
* handle change flow, so _reallyHandleChange doesn't get called twice in
|
|
84
|
+
* quick succession. _reallyHandleChange is then further throttled with a
|
|
85
|
+
* larger window, BUT it triggers on both leading and trailing edge,
|
|
86
|
+
* whereas this only triggers on the trailing edge.
|
|
87
|
+
*/
|
|
88
|
+
if (this._reallyHandleChange) {
|
|
89
|
+
this._reallyHandleChange();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
this._reallyHandleChange = function () {
|
|
94
|
+
// This function is throttled to MONITOR_THROTTLE_DURATION (see constructor)
|
|
95
|
+
if (this.changeCallback) {
|
|
96
|
+
// Convince Flow this won't suddenly become null
|
|
97
|
+
const cb = this.changeCallback;
|
|
98
|
+
const counter = this.changeCounter++;
|
|
99
|
+
/*
|
|
100
|
+
* In live queries we need to know when the current result set has
|
|
101
|
+
* finished being calculated so that we know we've received all the
|
|
102
|
+
* liveRecord / liveCollection calls and can release the out of date
|
|
103
|
+
* ones. To achieve this, we use a custom `subscribe` function which
|
|
104
|
+
* calls `rootValue.release()` once the result set has been calculated.
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
this.subscriptionReleasersByCounter[String(counter)] = [];
|
|
108
|
+
this.liveConditionsByCounter[String(counter)] = [];
|
|
109
|
+
const changeRootValue = { ...this.extraRootValue,
|
|
110
|
+
counter,
|
|
111
|
+
liveCollection: this.liveCollection.bind(this, counter),
|
|
112
|
+
liveRecord: this.liveRecord.bind(this, counter),
|
|
113
|
+
liveConditions: this.liveConditionsByCounter[String(counter)],
|
|
114
|
+
release: () => {
|
|
115
|
+
// Despite it's name, this means that the execution has complete, which means we're actually releasing everything *before* this.
|
|
116
|
+
this.resetBefore(counter);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
cb(changeRootValue);
|
|
120
|
+
} else {
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.warn("Change occurred, but no-one was listening");
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
this.onChange = function (callback) {
|
|
127
|
+
if (this.released) {
|
|
128
|
+
throw new Error("Monitors cannot be reused.");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (this.changeCallback) {
|
|
132
|
+
throw new Error("Already monitoring for changes");
|
|
133
|
+
} // Throttle to every 250ms
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
this.changeCallback = callback;
|
|
137
|
+
|
|
138
|
+
if (this.handleChange) {
|
|
139
|
+
setImmediate(this.handleChange);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return () => {
|
|
143
|
+
if (this.changeCallback === callback) {
|
|
144
|
+
this.changeCallback = null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.release();
|
|
148
|
+
};
|
|
149
|
+
};
|
|
83
150
|
|
|
84
151
|
this.handleChange = (0, _lodash.throttle)(this.handleChange.bind(this), DEBOUNCE_DURATION, {
|
|
85
152
|
leading: false,
|
|
@@ -122,12 +189,14 @@ class LiveMonitor {
|
|
|
122
189
|
|
|
123
190
|
release() {
|
|
124
191
|
if (this.handleChange) {
|
|
192
|
+
// $FlowFixMe: throttled function
|
|
125
193
|
this.handleChange.cancel();
|
|
126
194
|
}
|
|
127
195
|
|
|
128
196
|
this.handleChange = null;
|
|
129
197
|
|
|
130
198
|
if (this._reallyHandleChange) {
|
|
199
|
+
// $FlowFixMe: throttled function
|
|
131
200
|
this._reallyHandleChange.cancel();
|
|
132
201
|
}
|
|
133
202
|
|
|
@@ -135,80 +204,6 @@ class LiveMonitor {
|
|
|
135
204
|
this.resetBefore(Infinity);
|
|
136
205
|
this.providers = {};
|
|
137
206
|
this.released = true;
|
|
138
|
-
} // Tell Flow that we're okay with overwriting this
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
handleChange() {
|
|
142
|
-
/* This function is throttled to ~25ms (see constructor); it's purpose is
|
|
143
|
-
* to bundle up all the changes that occur in a small window into the same
|
|
144
|
-
* handle change flow, so _reallyHandleChange doesn't get called twice in
|
|
145
|
-
* quick succession. _reallyHandleChange is then further throttled with a
|
|
146
|
-
* larger window, BUT it triggers on both leading and trailing edge,
|
|
147
|
-
* whereas this only triggers on the trailing edge.
|
|
148
|
-
*/
|
|
149
|
-
if (this._reallyHandleChange) {
|
|
150
|
-
this._reallyHandleChange();
|
|
151
|
-
}
|
|
152
|
-
} // Tell Flow that we're okay with overwriting this
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
_reallyHandleChange() {
|
|
156
|
-
// This function is throttled to MONITOR_THROTTLE_DURATION (see constructor)
|
|
157
|
-
if (this.changeCallback) {
|
|
158
|
-
// Convince Flow this won't suddenly become null
|
|
159
|
-
const cb = this.changeCallback;
|
|
160
|
-
const counter = this.changeCounter++;
|
|
161
|
-
/*
|
|
162
|
-
* In live queries we need to know when the current result set has
|
|
163
|
-
* finished being calculated so that we know we've received all the
|
|
164
|
-
* liveRecord / liveCollection calls and can release the out of date
|
|
165
|
-
* ones. To achieve this, we use a custom `subscribe` function which
|
|
166
|
-
* calls `rootValue.release()` once the result set has been calculated.
|
|
167
|
-
*/
|
|
168
|
-
|
|
169
|
-
this.subscriptionReleasersByCounter[String(counter)] = [];
|
|
170
|
-
this.liveConditionsByCounter[String(counter)] = [];
|
|
171
|
-
const changeRootValue = { ...this.extraRootValue,
|
|
172
|
-
counter,
|
|
173
|
-
liveCollection: this.liveCollection.bind(this, counter),
|
|
174
|
-
liveRecord: this.liveRecord.bind(this, counter),
|
|
175
|
-
liveConditions: this.liveConditionsByCounter[String(counter)],
|
|
176
|
-
release: () => {
|
|
177
|
-
// Despite it's name, this means that the execution has complete, which means we're actually releasing everything *before* this.
|
|
178
|
-
this.resetBefore(counter);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
cb(changeRootValue);
|
|
182
|
-
} else {
|
|
183
|
-
// eslint-disable-next-line no-console
|
|
184
|
-
console.warn("Change occurred, but no-one was listening");
|
|
185
|
-
}
|
|
186
|
-
} // Tell Flow that we're okay with overwriting this
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
onChange(callback) {
|
|
190
|
-
if (this.released) {
|
|
191
|
-
throw new Error("Monitors cannot be reused.");
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (this.changeCallback) {
|
|
195
|
-
throw new Error("Already monitoring for changes");
|
|
196
|
-
} // Throttle to every 250ms
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this.changeCallback = callback;
|
|
200
|
-
|
|
201
|
-
if (this.handleChange) {
|
|
202
|
-
setImmediate(this.handleChange);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return () => {
|
|
206
|
-
if (this.changeCallback === callback) {
|
|
207
|
-
this.changeCallback = null;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
this.release();
|
|
211
|
-
};
|
|
212
207
|
}
|
|
213
208
|
|
|
214
209
|
liveCollection(counter, namespace, collectionIdentifier, predicate = () => true) {
|
package/node8plus/Live.js.flow
CHANGED
|
@@ -85,6 +85,10 @@ export class LiveMonitor {
|
|
|
85
85
|
changeCounter: number;
|
|
86
86
|
extraRootValue: any;
|
|
87
87
|
|
|
88
|
+
handleChange: (() => void) | null;
|
|
89
|
+
_reallyHandleChange: (() => void) | null;
|
|
90
|
+
onChange: (callback: () => void) => () => void;
|
|
91
|
+
|
|
88
92
|
constructor(
|
|
89
93
|
providers: { [namespace: string]: LiveProvider },
|
|
90
94
|
extraRootValue: any
|
|
@@ -96,9 +100,72 @@ export class LiveMonitor {
|
|
|
96
100
|
this.changeCallback = null;
|
|
97
101
|
this.changeCounter = 0;
|
|
98
102
|
this.liveConditionsByCounter = {};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
103
|
+
this.handleChange = function() {
|
|
104
|
+
/* This function is throttled to ~25ms (see constructor); it's purpose is
|
|
105
|
+
* to bundle up all the changes that occur in a small window into the same
|
|
106
|
+
* handle change flow, so _reallyHandleChange doesn't get called twice in
|
|
107
|
+
* quick succession. _reallyHandleChange is then further throttled with a
|
|
108
|
+
* larger window, BUT it triggers on both leading and trailing edge,
|
|
109
|
+
* whereas this only triggers on the trailing edge.
|
|
110
|
+
*/
|
|
111
|
+
if (this._reallyHandleChange) {
|
|
112
|
+
this._reallyHandleChange();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
this._reallyHandleChange = function() {
|
|
117
|
+
// This function is throttled to MONITOR_THROTTLE_DURATION (see constructor)
|
|
118
|
+
if (this.changeCallback) {
|
|
119
|
+
// Convince Flow this won't suddenly become null
|
|
120
|
+
const cb = this.changeCallback;
|
|
121
|
+
const counter = this.changeCounter++;
|
|
122
|
+
/*
|
|
123
|
+
* In live queries we need to know when the current result set has
|
|
124
|
+
* finished being calculated so that we know we've received all the
|
|
125
|
+
* liveRecord / liveCollection calls and can release the out of date
|
|
126
|
+
* ones. To achieve this, we use a custom `subscribe` function which
|
|
127
|
+
* calls `rootValue.release()` once the result set has been calculated.
|
|
128
|
+
*/
|
|
129
|
+
this.subscriptionReleasersByCounter[String(counter)] = [];
|
|
130
|
+
this.liveConditionsByCounter[String(counter)] = [];
|
|
131
|
+
const changeRootValue = {
|
|
132
|
+
...this.extraRootValue,
|
|
133
|
+
counter,
|
|
134
|
+
liveCollection: this.liveCollection.bind(this, counter),
|
|
135
|
+
liveRecord: this.liveRecord.bind(this, counter),
|
|
136
|
+
liveConditions: this.liveConditionsByCounter[String(counter)],
|
|
137
|
+
release: () => {
|
|
138
|
+
// Despite it's name, this means that the execution has complete, which means we're actually releasing everything *before* this.
|
|
139
|
+
this.resetBefore(counter);
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
cb(changeRootValue);
|
|
143
|
+
} else {
|
|
144
|
+
// eslint-disable-next-line no-console
|
|
145
|
+
console.warn("Change occurred, but no-one was listening");
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
this.onChange = function(callback: () => void) {
|
|
150
|
+
if (this.released) {
|
|
151
|
+
throw new Error("Monitors cannot be reused.");
|
|
152
|
+
}
|
|
153
|
+
if (this.changeCallback) {
|
|
154
|
+
throw new Error("Already monitoring for changes");
|
|
155
|
+
}
|
|
156
|
+
// Throttle to every 250ms
|
|
157
|
+
this.changeCallback = callback;
|
|
158
|
+
if (this.handleChange) {
|
|
159
|
+
setImmediate(this.handleChange);
|
|
160
|
+
}
|
|
161
|
+
return () => {
|
|
162
|
+
if (this.changeCallback === callback) {
|
|
163
|
+
this.changeCallback = null;
|
|
164
|
+
}
|
|
165
|
+
this.release();
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
|
|
102
169
|
this.handleChange = throttle(
|
|
103
170
|
this.handleChange.bind(this),
|
|
104
171
|
DEBOUNCE_DURATION,
|
|
@@ -149,10 +216,12 @@ export class LiveMonitor {
|
|
|
149
216
|
|
|
150
217
|
release() {
|
|
151
218
|
if (this.handleChange) {
|
|
219
|
+
// $FlowFixMe: throttled function
|
|
152
220
|
this.handleChange.cancel();
|
|
153
221
|
}
|
|
154
222
|
this.handleChange = null;
|
|
155
223
|
if (this._reallyHandleChange) {
|
|
224
|
+
// $FlowFixMe: throttled function
|
|
156
225
|
this._reallyHandleChange.cancel();
|
|
157
226
|
}
|
|
158
227
|
this._reallyHandleChange = null;
|
|
@@ -161,78 +230,6 @@ export class LiveMonitor {
|
|
|
161
230
|
this.released = true;
|
|
162
231
|
}
|
|
163
232
|
|
|
164
|
-
// Tell Flow that we're okay with overwriting this
|
|
165
|
-
handleChange: (() => void) | null;
|
|
166
|
-
handleChange() {
|
|
167
|
-
/* This function is throttled to ~25ms (see constructor); it's purpose is
|
|
168
|
-
* to bundle up all the changes that occur in a small window into the same
|
|
169
|
-
* handle change flow, so _reallyHandleChange doesn't get called twice in
|
|
170
|
-
* quick succession. _reallyHandleChange is then further throttled with a
|
|
171
|
-
* larger window, BUT it triggers on both leading and trailing edge,
|
|
172
|
-
* whereas this only triggers on the trailing edge.
|
|
173
|
-
*/
|
|
174
|
-
if (this._reallyHandleChange) {
|
|
175
|
-
this._reallyHandleChange();
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Tell Flow that we're okay with overwriting this
|
|
180
|
-
_reallyHandleChange: (() => void) | null;
|
|
181
|
-
_reallyHandleChange() {
|
|
182
|
-
// This function is throttled to MONITOR_THROTTLE_DURATION (see constructor)
|
|
183
|
-
if (this.changeCallback) {
|
|
184
|
-
// Convince Flow this won't suddenly become null
|
|
185
|
-
const cb = this.changeCallback;
|
|
186
|
-
const counter = this.changeCounter++;
|
|
187
|
-
/*
|
|
188
|
-
* In live queries we need to know when the current result set has
|
|
189
|
-
* finished being calculated so that we know we've received all the
|
|
190
|
-
* liveRecord / liveCollection calls and can release the out of date
|
|
191
|
-
* ones. To achieve this, we use a custom `subscribe` function which
|
|
192
|
-
* calls `rootValue.release()` once the result set has been calculated.
|
|
193
|
-
*/
|
|
194
|
-
this.subscriptionReleasersByCounter[String(counter)] = [];
|
|
195
|
-
this.liveConditionsByCounter[String(counter)] = [];
|
|
196
|
-
const changeRootValue = {
|
|
197
|
-
...this.extraRootValue,
|
|
198
|
-
counter,
|
|
199
|
-
liveCollection: this.liveCollection.bind(this, counter),
|
|
200
|
-
liveRecord: this.liveRecord.bind(this, counter),
|
|
201
|
-
liveConditions: this.liveConditionsByCounter[String(counter)],
|
|
202
|
-
release: () => {
|
|
203
|
-
// Despite it's name, this means that the execution has complete, which means we're actually releasing everything *before* this.
|
|
204
|
-
this.resetBefore(counter);
|
|
205
|
-
},
|
|
206
|
-
};
|
|
207
|
-
cb(changeRootValue);
|
|
208
|
-
} else {
|
|
209
|
-
// eslint-disable-next-line no-console
|
|
210
|
-
console.warn("Change occurred, but no-one was listening");
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Tell Flow that we're okay with overwriting this
|
|
215
|
-
onChange: (callback: () => void) => void;
|
|
216
|
-
onChange(callback: () => void) {
|
|
217
|
-
if (this.released) {
|
|
218
|
-
throw new Error("Monitors cannot be reused.");
|
|
219
|
-
}
|
|
220
|
-
if (this.changeCallback) {
|
|
221
|
-
throw new Error("Already monitoring for changes");
|
|
222
|
-
}
|
|
223
|
-
// Throttle to every 250ms
|
|
224
|
-
this.changeCallback = callback;
|
|
225
|
-
if (this.handleChange) {
|
|
226
|
-
setImmediate(this.handleChange);
|
|
227
|
-
}
|
|
228
|
-
return () => {
|
|
229
|
-
if (this.changeCallback === callback) {
|
|
230
|
-
this.changeCallback = null;
|
|
231
|
-
}
|
|
232
|
-
this.release();
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
233
|
liveCollection(
|
|
237
234
|
counter: number,
|
|
238
235
|
namespace: string,
|
package/node8plus/Live.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Live.js"],"names":["DEBOUNCE_DURATION","MONITOR_THROTTLE_DURATION","Math","max","parseInt","process","env","LIVE_THROTTLE","LiveSource","subscribeCollection","_callback","_collectionIdentifier","_predicate","subscribeRecord","_recordIdentifier","LiveProvider","constructor","namespace","sources","registerSource","source","push","collectionIdentifierIsValid","recordIdentifierIsValid","LiveMonitor","providers","extraRootValue","released","subscriptionReleasersByCounter","changeCallback","changeCounter","liveConditionsByCounter","handleChange","Error","bind","leading","trailing","_reallyHandleChange","onChange","resetBefore","currentCounter","oldCounters","Object","keys","filter","n","oldCounter","releaser","release","cancel","Infinity","cb","counter","String","changeRootValue","liveCollection","liveRecord","liveConditions","console","warn","callback","setImmediate","collectionIdentifier","predicate","provider","length","recordIdentifier","LiveCoordinator","subscribe","registerProvider","getMonitor","_parent","_args","_context","_info","monitor","liveAbort","e","iterator","throw","makeAsyncIteratorFromMonitor","onClose"],"mappings":"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","sourcesContent":["// @flow\n/* eslint-disable flowtype/no-weak-types */\nimport callbackToAsyncIterator from \"./callbackToAsyncIterator\";\nimport type { GraphQLResolveInfo } from \"graphql\";\nimport { throttle } from \"lodash\";\n\ntype SubscriptionReleaser = () => void;\ntype SubscriptionCallback = () => void;\n\ntype Predicate = (record: any) => boolean;\ntype PredicateGenerator = (data: any) => Predicate;\n\nconst DEBOUNCE_DURATION = 25;\n\nconst MONITOR_THROTTLE_DURATION = Math.max(\n DEBOUNCE_DURATION + 1,\n parseInt(process.env.LIVE_THROTTLE || \"\", 10) || 500\n);\n\n/*\n * Sources are long-lived (i.e. in \"watch\" mode you just re-use the same one\n * over and over) because there is no release for them\n */\nexport class LiveSource {\n subscribeCollection(\n _callback: SubscriptionCallback,\n _collectionIdentifier: any,\n _predicate?: Predicate\n ): SubscriptionReleaser | null {\n return null;\n }\n\n subscribeRecord(\n _callback: SubscriptionCallback,\n _collectionIdentifier: any,\n _recordIdentifier: any\n ): SubscriptionReleaser | null {\n return null;\n }\n}\n\n/*\n * Providers enable a namespace, perform validation, and track the sources used\n * by that namespace within one single schema build. The should not directly use\n * any long-lived features as they do not have an explicit \"release\"/\"close\"\n * command when a new schema is built.\n */\nexport class LiveProvider {\n sources: Array<LiveSource>;\n namespace: string;\n\n constructor(namespace: string) {\n this.namespace = namespace;\n this.sources = [];\n }\n\n registerSource(source: LiveSource) {\n this.sources.push(source);\n }\n\n collectionIdentifierIsValid(_collectionIdentifier: any): boolean {\n return false;\n }\n\n recordIdentifierIsValid(\n _collectionIdentifier: any,\n _recordIdentifier: any\n ): boolean {\n return false;\n }\n}\n\n/*\n * During a single execution of GraphQL (specifically a subscription request),\n * the LiveMonitor tracks the resources viewed and subscribes to updates in them.\n */\nexport class LiveMonitor {\n released: boolean;\n providers: { [namespace: string]: LiveProvider };\n subscriptionReleasersByCounter: {\n [counter: string]: (() => void)[],\n };\n liveConditionsByCounter: { [counter: string]: Array<PredicateGenerator> };\n changeCallback: ((arg: any) => void) | null;\n changeCounter: number;\n extraRootValue: any;\n\n constructor(\n providers: { [namespace: string]: LiveProvider },\n extraRootValue: any\n ) {\n this.extraRootValue = extraRootValue;\n this.released = false;\n this.providers = providers;\n this.subscriptionReleasersByCounter = {};\n this.changeCallback = null;\n this.changeCounter = 0;\n this.liveConditionsByCounter = {};\n if (!this.handleChange) {\n throw new Error(\"This is just to make flow happy\");\n }\n this.handleChange = throttle(\n this.handleChange.bind(this),\n DEBOUNCE_DURATION,\n {\n leading: false,\n trailing: true,\n }\n );\n if (!this._reallyHandleChange) {\n throw new Error(\"This is just to make flow happy\");\n }\n this._reallyHandleChange = throttle(\n this._reallyHandleChange.bind(this),\n MONITOR_THROTTLE_DURATION - DEBOUNCE_DURATION,\n {\n leading: true,\n trailing: true,\n }\n );\n this.onChange = this.onChange.bind(this);\n }\n\n resetBefore(currentCounter: number) {\n // Clear out of date subscriptionReleasers\n {\n const oldCounters = Object.keys(\n this.subscriptionReleasersByCounter\n ).filter(n => parseInt(n, 10) < currentCounter);\n for (const oldCounter of oldCounters) {\n for (const releaser of this.subscriptionReleasersByCounter[\n oldCounter\n ]) {\n releaser();\n }\n delete this.subscriptionReleasersByCounter[oldCounter];\n }\n }\n // Clear out of date liveConditions\n {\n const oldCounters = Object.keys(this.liveConditionsByCounter).filter(\n n => parseInt(n, 10) < currentCounter\n );\n for (const oldCounter of oldCounters) {\n delete this.liveConditionsByCounter[oldCounter];\n }\n }\n }\n\n release() {\n if (this.handleChange) {\n this.handleChange.cancel();\n }\n this.handleChange = null;\n if (this._reallyHandleChange) {\n this._reallyHandleChange.cancel();\n }\n this._reallyHandleChange = null;\n this.resetBefore(Infinity);\n this.providers = {};\n this.released = true;\n }\n\n // Tell Flow that we're okay with overwriting this\n handleChange: (() => void) | null;\n handleChange() {\n /* This function is throttled to ~25ms (see constructor); it's purpose is\n * to bundle up all the changes that occur in a small window into the same\n * handle change flow, so _reallyHandleChange doesn't get called twice in\n * quick succession. _reallyHandleChange is then further throttled with a\n * larger window, BUT it triggers on both leading and trailing edge,\n * whereas this only triggers on the trailing edge.\n */\n if (this._reallyHandleChange) {\n this._reallyHandleChange();\n }\n }\n\n // Tell Flow that we're okay with overwriting this\n _reallyHandleChange: (() => void) | null;\n _reallyHandleChange() {\n // This function is throttled to MONITOR_THROTTLE_DURATION (see constructor)\n if (this.changeCallback) {\n // Convince Flow this won't suddenly become null\n const cb = this.changeCallback;\n const counter = this.changeCounter++;\n /*\n * In live queries we need to know when the current result set has\n * finished being calculated so that we know we've received all the\n * liveRecord / liveCollection calls and can release the out of date\n * ones. To achieve this, we use a custom `subscribe` function which\n * calls `rootValue.release()` once the result set has been calculated.\n */\n this.subscriptionReleasersByCounter[String(counter)] = [];\n this.liveConditionsByCounter[String(counter)] = [];\n const changeRootValue = {\n ...this.extraRootValue,\n counter,\n liveCollection: this.liveCollection.bind(this, counter),\n liveRecord: this.liveRecord.bind(this, counter),\n liveConditions: this.liveConditionsByCounter[String(counter)],\n release: () => {\n // Despite it's name, this means that the execution has complete, which means we're actually releasing everything *before* this.\n this.resetBefore(counter);\n },\n };\n cb(changeRootValue);\n } else {\n // eslint-disable-next-line no-console\n console.warn(\"Change occurred, but no-one was listening\");\n }\n }\n\n // Tell Flow that we're okay with overwriting this\n onChange: (callback: () => void) => void;\n onChange(callback: () => void) {\n if (this.released) {\n throw new Error(\"Monitors cannot be reused.\");\n }\n if (this.changeCallback) {\n throw new Error(\"Already monitoring for changes\");\n }\n // Throttle to every 250ms\n this.changeCallback = callback;\n if (this.handleChange) {\n setImmediate(this.handleChange);\n }\n return () => {\n if (this.changeCallback === callback) {\n this.changeCallback = null;\n }\n this.release();\n };\n }\n\n liveCollection(\n counter: number,\n namespace: string,\n collectionIdentifier: any,\n predicate: (record: any) => boolean = () => true\n ) {\n const handleChange = this.handleChange;\n if (this.released || !handleChange) {\n return;\n }\n const provider = this.providers[namespace];\n if (!provider || provider.sources.length === 0) return;\n if (!provider.collectionIdentifierIsValid(collectionIdentifier)) {\n throw new Error(\n `Invalid collection identifier passed to LiveMonitor[${namespace}]: ${collectionIdentifier}`\n );\n }\n for (const source of provider.sources) {\n const releaser = source.subscribeCollection(\n handleChange,\n collectionIdentifier,\n predicate\n );\n if (releaser) {\n this.subscriptionReleasersByCounter[String(counter)].push(releaser);\n }\n }\n }\n\n liveRecord(\n counter: number,\n namespace: string,\n collectionIdentifier: any,\n recordIdentifier: any\n ) {\n const handleChange = this.handleChange;\n if (this.released || !handleChange) {\n return;\n }\n // TODO: if (recordIdentifier == null) {return}\n const provider = this.providers[namespace];\n if (!provider || provider.sources.length === 0) return;\n if (!provider.collectionIdentifierIsValid(collectionIdentifier)) {\n throw new Error(\n `Invalid collection identifier passed to LiveMonitor[${namespace}]: ${collectionIdentifier}`\n );\n }\n if (\n !provider.recordIdentifierIsValid(collectionIdentifier, recordIdentifier)\n ) {\n throw new Error(\n `Invalid record identifier passed to LiveMonitor[${namespace}]: ${collectionIdentifier}`\n );\n }\n for (const source of provider.sources) {\n const releaser = source.subscribeRecord(\n handleChange,\n collectionIdentifier,\n recordIdentifier\n );\n if (releaser) {\n this.subscriptionReleasersByCounter[String(counter)].push(releaser);\n }\n }\n }\n}\n\n/*\n * There is one coordinator for each build of the GraphQL schema, it tracks the providers\n * and gives a handy `subscribe` method that can be used for live queries (assuming\n * that the `resolve` is provided the same as in a Query).\n */\nexport class LiveCoordinator {\n providers: { [namespace: string]: LiveProvider };\n\n constructor() {\n this.providers = {};\n this.subscribe = this.subscribe.bind(this);\n }\n\n registerProvider(provider: LiveProvider) {\n const { namespace } = provider;\n if (this.providers[namespace]) {\n throw new Error(`Namespace ${namespace} already registered with Live`);\n }\n this.providers[namespace] = provider;\n }\n\n registerSource(namespace: string, source: LiveSource) {\n if (!this.providers[namespace]) {\n // eslint-disable-next-line no-console\n console.warn(\n `LiveProvider '${namespace}' is not registered, skipping live source.`\n );\n return;\n }\n this.providers[namespace].registerSource(source);\n }\n\n getMonitor(extraRootValue: any) {\n return new LiveMonitor(this.providers, extraRootValue);\n }\n\n // Tell Flow that we're okay with overwriting this\n subscribe: (\n _parent: any,\n _args: any,\n context: any,\n _info: GraphQLResolveInfo\n ) => any;\n subscribe(\n _parent: any,\n _args: any,\n _context: any,\n _info: GraphQLResolveInfo\n ) {\n const monitor = this.getMonitor({\n liveAbort: e => {\n if (iterator) iterator.throw(e);\n },\n });\n const iterator = makeAsyncIteratorFromMonitor(monitor);\n return iterator;\n }\n}\n\nexport function makeAsyncIteratorFromMonitor(monitor: LiveMonitor) {\n return callbackToAsyncIterator(monitor.onChange, {\n onClose: release => {\n if (release) release();\n },\n });\n}\n"],"file":"Live.js"}
|
|
1
|
+
{"version":3,"sources":["../src/Live.js"],"names":["DEBOUNCE_DURATION","MONITOR_THROTTLE_DURATION","Math","max","parseInt","process","env","LIVE_THROTTLE","LiveSource","subscribeCollection","_callback","_collectionIdentifier","_predicate","subscribeRecord","_recordIdentifier","LiveProvider","constructor","namespace","sources","registerSource","source","push","collectionIdentifierIsValid","recordIdentifierIsValid","LiveMonitor","providers","extraRootValue","released","subscriptionReleasersByCounter","changeCallback","changeCounter","liveConditionsByCounter","handleChange","_reallyHandleChange","cb","counter","String","changeRootValue","liveCollection","bind","liveRecord","liveConditions","release","resetBefore","console","warn","onChange","callback","Error","setImmediate","leading","trailing","currentCounter","oldCounters","Object","keys","filter","n","oldCounter","releaser","cancel","Infinity","collectionIdentifier","predicate","provider","length","recordIdentifier","LiveCoordinator","subscribe","registerProvider","getMonitor","_parent","_args","_context","_info","monitor","liveAbort","e","iterator","throw","makeAsyncIteratorFromMonitor","onClose"],"mappings":"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","sourcesContent":["// @flow\n/* eslint-disable flowtype/no-weak-types */\nimport callbackToAsyncIterator from \"./callbackToAsyncIterator\";\nimport type { GraphQLResolveInfo } from \"graphql\";\nimport { throttle } from \"lodash\";\n\ntype SubscriptionReleaser = () => void;\ntype SubscriptionCallback = () => void;\n\ntype Predicate = (record: any) => boolean;\ntype PredicateGenerator = (data: any) => Predicate;\n\nconst DEBOUNCE_DURATION = 25;\n\nconst MONITOR_THROTTLE_DURATION = Math.max(\n DEBOUNCE_DURATION + 1,\n parseInt(process.env.LIVE_THROTTLE || \"\", 10) || 500\n);\n\n/*\n * Sources are long-lived (i.e. in \"watch\" mode you just re-use the same one\n * over and over) because there is no release for them\n */\nexport class LiveSource {\n subscribeCollection(\n _callback: SubscriptionCallback,\n _collectionIdentifier: any,\n _predicate?: Predicate\n ): SubscriptionReleaser | null {\n return null;\n }\n\n subscribeRecord(\n _callback: SubscriptionCallback,\n _collectionIdentifier: any,\n _recordIdentifier: any\n ): SubscriptionReleaser | null {\n return null;\n }\n}\n\n/*\n * Providers enable a namespace, perform validation, and track the sources used\n * by that namespace within one single schema build. The should not directly use\n * any long-lived features as they do not have an explicit \"release\"/\"close\"\n * command when a new schema is built.\n */\nexport class LiveProvider {\n sources: Array<LiveSource>;\n namespace: string;\n\n constructor(namespace: string) {\n this.namespace = namespace;\n this.sources = [];\n }\n\n registerSource(source: LiveSource) {\n this.sources.push(source);\n }\n\n collectionIdentifierIsValid(_collectionIdentifier: any): boolean {\n return false;\n }\n\n recordIdentifierIsValid(\n _collectionIdentifier: any,\n _recordIdentifier: any\n ): boolean {\n return false;\n }\n}\n\n/*\n * During a single execution of GraphQL (specifically a subscription request),\n * the LiveMonitor tracks the resources viewed and subscribes to updates in them.\n */\nexport class LiveMonitor {\n released: boolean;\n providers: { [namespace: string]: LiveProvider };\n subscriptionReleasersByCounter: {\n [counter: string]: (() => void)[],\n };\n liveConditionsByCounter: { [counter: string]: Array<PredicateGenerator> };\n changeCallback: ((arg: any) => void) | null;\n changeCounter: number;\n extraRootValue: any;\n\n handleChange: (() => void) | null;\n _reallyHandleChange: (() => void) | null;\n onChange: (callback: () => void) => () => void;\n\n constructor(\n providers: { [namespace: string]: LiveProvider },\n extraRootValue: any\n ) {\n this.extraRootValue = extraRootValue;\n this.released = false;\n this.providers = providers;\n this.subscriptionReleasersByCounter = {};\n this.changeCallback = null;\n this.changeCounter = 0;\n this.liveConditionsByCounter = {};\n this.handleChange = function() {\n /* This function is throttled to ~25ms (see constructor); it's purpose is\n * to bundle up all the changes that occur in a small window into the same\n * handle change flow, so _reallyHandleChange doesn't get called twice in\n * quick succession. _reallyHandleChange is then further throttled with a\n * larger window, BUT it triggers on both leading and trailing edge,\n * whereas this only triggers on the trailing edge.\n */\n if (this._reallyHandleChange) {\n this._reallyHandleChange();\n }\n };\n\n this._reallyHandleChange = function() {\n // This function is throttled to MONITOR_THROTTLE_DURATION (see constructor)\n if (this.changeCallback) {\n // Convince Flow this won't suddenly become null\n const cb = this.changeCallback;\n const counter = this.changeCounter++;\n /*\n * In live queries we need to know when the current result set has\n * finished being calculated so that we know we've received all the\n * liveRecord / liveCollection calls and can release the out of date\n * ones. To achieve this, we use a custom `subscribe` function which\n * calls `rootValue.release()` once the result set has been calculated.\n */\n this.subscriptionReleasersByCounter[String(counter)] = [];\n this.liveConditionsByCounter[String(counter)] = [];\n const changeRootValue = {\n ...this.extraRootValue,\n counter,\n liveCollection: this.liveCollection.bind(this, counter),\n liveRecord: this.liveRecord.bind(this, counter),\n liveConditions: this.liveConditionsByCounter[String(counter)],\n release: () => {\n // Despite it's name, this means that the execution has complete, which means we're actually releasing everything *before* this.\n this.resetBefore(counter);\n },\n };\n cb(changeRootValue);\n } else {\n // eslint-disable-next-line no-console\n console.warn(\"Change occurred, but no-one was listening\");\n }\n };\n\n this.onChange = function(callback: () => void) {\n if (this.released) {\n throw new Error(\"Monitors cannot be reused.\");\n }\n if (this.changeCallback) {\n throw new Error(\"Already monitoring for changes\");\n }\n // Throttle to every 250ms\n this.changeCallback = callback;\n if (this.handleChange) {\n setImmediate(this.handleChange);\n }\n return () => {\n if (this.changeCallback === callback) {\n this.changeCallback = null;\n }\n this.release();\n };\n };\n\n this.handleChange = throttle(\n this.handleChange.bind(this),\n DEBOUNCE_DURATION,\n {\n leading: false,\n trailing: true,\n }\n );\n if (!this._reallyHandleChange) {\n throw new Error(\"This is just to make flow happy\");\n }\n this._reallyHandleChange = throttle(\n this._reallyHandleChange.bind(this),\n MONITOR_THROTTLE_DURATION - DEBOUNCE_DURATION,\n {\n leading: true,\n trailing: true,\n }\n );\n this.onChange = this.onChange.bind(this);\n }\n\n resetBefore(currentCounter: number) {\n // Clear out of date subscriptionReleasers\n {\n const oldCounters = Object.keys(\n this.subscriptionReleasersByCounter\n ).filter(n => parseInt(n, 10) < currentCounter);\n for (const oldCounter of oldCounters) {\n for (const releaser of this.subscriptionReleasersByCounter[\n oldCounter\n ]) {\n releaser();\n }\n delete this.subscriptionReleasersByCounter[oldCounter];\n }\n }\n // Clear out of date liveConditions\n {\n const oldCounters = Object.keys(this.liveConditionsByCounter).filter(\n n => parseInt(n, 10) < currentCounter\n );\n for (const oldCounter of oldCounters) {\n delete this.liveConditionsByCounter[oldCounter];\n }\n }\n }\n\n release() {\n if (this.handleChange) {\n // $FlowFixMe: throttled function\n this.handleChange.cancel();\n }\n this.handleChange = null;\n if (this._reallyHandleChange) {\n // $FlowFixMe: throttled function\n this._reallyHandleChange.cancel();\n }\n this._reallyHandleChange = null;\n this.resetBefore(Infinity);\n this.providers = {};\n this.released = true;\n }\n\n liveCollection(\n counter: number,\n namespace: string,\n collectionIdentifier: any,\n predicate: (record: any) => boolean = () => true\n ) {\n const handleChange = this.handleChange;\n if (this.released || !handleChange) {\n return;\n }\n const provider = this.providers[namespace];\n if (!provider || provider.sources.length === 0) return;\n if (!provider.collectionIdentifierIsValid(collectionIdentifier)) {\n throw new Error(\n `Invalid collection identifier passed to LiveMonitor[${namespace}]: ${collectionIdentifier}`\n );\n }\n for (const source of provider.sources) {\n const releaser = source.subscribeCollection(\n handleChange,\n collectionIdentifier,\n predicate\n );\n if (releaser) {\n this.subscriptionReleasersByCounter[String(counter)].push(releaser);\n }\n }\n }\n\n liveRecord(\n counter: number,\n namespace: string,\n collectionIdentifier: any,\n recordIdentifier: any\n ) {\n const handleChange = this.handleChange;\n if (this.released || !handleChange) {\n return;\n }\n // TODO: if (recordIdentifier == null) {return}\n const provider = this.providers[namespace];\n if (!provider || provider.sources.length === 0) return;\n if (!provider.collectionIdentifierIsValid(collectionIdentifier)) {\n throw new Error(\n `Invalid collection identifier passed to LiveMonitor[${namespace}]: ${collectionIdentifier}`\n );\n }\n if (\n !provider.recordIdentifierIsValid(collectionIdentifier, recordIdentifier)\n ) {\n throw new Error(\n `Invalid record identifier passed to LiveMonitor[${namespace}]: ${collectionIdentifier}`\n );\n }\n for (const source of provider.sources) {\n const releaser = source.subscribeRecord(\n handleChange,\n collectionIdentifier,\n recordIdentifier\n );\n if (releaser) {\n this.subscriptionReleasersByCounter[String(counter)].push(releaser);\n }\n }\n }\n}\n\n/*\n * There is one coordinator for each build of the GraphQL schema, it tracks the providers\n * and gives a handy `subscribe` method that can be used for live queries (assuming\n * that the `resolve` is provided the same as in a Query).\n */\nexport class LiveCoordinator {\n providers: { [namespace: string]: LiveProvider };\n\n constructor() {\n this.providers = {};\n this.subscribe = this.subscribe.bind(this);\n }\n\n registerProvider(provider: LiveProvider) {\n const { namespace } = provider;\n if (this.providers[namespace]) {\n throw new Error(`Namespace ${namespace} already registered with Live`);\n }\n this.providers[namespace] = provider;\n }\n\n registerSource(namespace: string, source: LiveSource) {\n if (!this.providers[namespace]) {\n // eslint-disable-next-line no-console\n console.warn(\n `LiveProvider '${namespace}' is not registered, skipping live source.`\n );\n return;\n }\n this.providers[namespace].registerSource(source);\n }\n\n getMonitor(extraRootValue: any) {\n return new LiveMonitor(this.providers, extraRootValue);\n }\n\n // Tell Flow that we're okay with overwriting this\n subscribe: (\n _parent: any,\n _args: any,\n context: any,\n _info: GraphQLResolveInfo\n ) => any;\n subscribe(\n _parent: any,\n _args: any,\n _context: any,\n _info: GraphQLResolveInfo\n ) {\n const monitor = this.getMonitor({\n liveAbort: e => {\n if (iterator) iterator.throw(e);\n },\n });\n const iterator = makeAsyncIteratorFromMonitor(monitor);\n return iterator;\n }\n}\n\nexport function makeAsyncIteratorFromMonitor(monitor: LiveMonitor) {\n return callbackToAsyncIterator(monitor.onChange, {\n onClose: release => {\n if (release) release();\n },\n });\n}\n"],"file":"Live.js"}
|
|
@@ -15,7 +15,9 @@ var graphql = _interopRequireWildcard(require("graphql"));
|
|
|
15
15
|
|
|
16
16
|
var _events = _interopRequireDefault(require("events"));
|
|
17
17
|
|
|
18
|
-
function
|
|
18
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
19
|
+
|
|
20
|
+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
21
|
|
|
20
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
23
|
|
|
@@ -344,9 +346,16 @@ class SchemaBuilder extends _events.default {
|
|
|
344
346
|
|
|
345
347
|
try {
|
|
346
348
|
this._busy = true;
|
|
347
|
-
this._explicitSchemaListener = listener;
|
|
349
|
+
this._explicitSchemaListener = listener; // We want to ignore `triggerChange` calls that occur whilst we're setting
|
|
350
|
+
// up the listeners to prevent an unnecessary double schema build.
|
|
351
|
+
|
|
352
|
+
let ignoreChangeTriggers = true;
|
|
348
353
|
|
|
349
354
|
this.triggerChange = () => {
|
|
355
|
+
if (ignoreChangeTriggers) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
350
359
|
this._generatedSchema = null; // XXX: optionally debounce
|
|
351
360
|
|
|
352
361
|
try {
|
|
@@ -364,7 +373,11 @@ class SchemaBuilder extends _events.default {
|
|
|
364
373
|
|
|
365
374
|
for (const fn of this.watchers) {
|
|
366
375
|
await fn(this.triggerChange);
|
|
367
|
-
}
|
|
376
|
+
} // Now we're about to build the first schema, any further `triggerChange`
|
|
377
|
+
// calls should be honoured.
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
ignoreChangeTriggers = false;
|
|
368
381
|
|
|
369
382
|
if (listener) {
|
|
370
383
|
this.on("schema", listener);
|
|
@@ -510,7 +510,15 @@ class SchemaBuilder extends EventEmitter {
|
|
|
510
510
|
try {
|
|
511
511
|
this._busy = true;
|
|
512
512
|
this._explicitSchemaListener = listener;
|
|
513
|
+
|
|
514
|
+
// We want to ignore `triggerChange` calls that occur whilst we're setting
|
|
515
|
+
// up the listeners to prevent an unnecessary double schema build.
|
|
516
|
+
let ignoreChangeTriggers = true;
|
|
517
|
+
|
|
513
518
|
this.triggerChange = () => {
|
|
519
|
+
if (ignoreChangeTriggers) {
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
514
522
|
this._generatedSchema = null;
|
|
515
523
|
// XXX: optionally debounce
|
|
516
524
|
try {
|
|
@@ -530,10 +538,16 @@ class SchemaBuilder extends EventEmitter {
|
|
|
530
538
|
for (const fn of this.watchers) {
|
|
531
539
|
await fn(this.triggerChange);
|
|
532
540
|
}
|
|
541
|
+
|
|
542
|
+
// Now we're about to build the first schema, any further `triggerChange`
|
|
543
|
+
// calls should be honoured.
|
|
544
|
+
ignoreChangeTriggers = false;
|
|
545
|
+
|
|
533
546
|
if (listener) {
|
|
534
547
|
this.on("schema", listener);
|
|
535
548
|
}
|
|
536
549
|
this.emit("schema", this.buildSchema());
|
|
550
|
+
|
|
537
551
|
this._watching = true;
|
|
538
552
|
} finally {
|
|
539
553
|
this._busy = false;
|