graphile-build
Version:
Build a GraphQL schema from plugins
105 lines (104 loc) • 2.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = callbackToAsyncIterator;
var _iterall = require("iterall");
/* eslint-disable flowtype/no-weak-types */
// Turn a callback-based listener into an async iterator
// From https://raw.githubusercontent.com/withspectrum/callback-to-async-iterator/master/src/index.js
// License MIT (Copyright (c) 2017 Maximilian Stoiber)
// Based on https://github.com/apollographql/graphql-subscriptions/blob/master/src/event-emitter-to-async-iterator.ts
const defaultOnError = err => {
throw err;
};
function callbackToAsyncIterator(listener, options = {}) {
const {
onError = defaultOnError,
buffering = true,
onClose
} = options;
let pullQueue = [];
let pushQueue = [];
let listening = true;
let listenerReturnValue;
function pushValue(value) {
if (pullQueue.length !== 0) {
pullQueue.shift()({
value,
done: false
});
} else if (buffering === true) {
pushQueue.push(value);
}
}
function pullValue() {
return new Promise(resolve => {
if (pushQueue.length !== 0) {
resolve({
value: pushQueue.shift(),
done: false
});
} else {
pullQueue.push(resolve);
}
});
}
function emptyQueue() {
if (listening) {
listening = false;
pullQueue.forEach(resolve => resolve({
value: undefined,
done: true
}));
pullQueue = [];
pushQueue = [];
onClose && onClose(listenerReturnValue);
}
}
try {
// Start listener
Promise.resolve(listener(value => pushValue(value))).then(a => {
listenerReturnValue = a;
}).catch(err => {
onError(err);
});
return {
next() {
return listening ? pullValue() : this.return();
},
return() {
emptyQueue();
return Promise.resolve({
value: undefined,
done: true
});
},
throw(error) {
emptyQueue();
onError(error);
return Promise.reject(error);
},
[_iterall.$$asyncIterator]() {
return this;
}
};
} catch (err) {
onError(err);
return {
next() {
return Promise.reject(err);
},
return() {
return Promise.reject(err);
},
throw(error) {
return Promise.reject(error);
},
[_iterall.$$asyncIterator]() {
return this;
}
};
}
}
//# sourceMappingURL=callbackToAsyncIterator.js.map