grafast
Version:
Cutting edge GraphQL planning and execution engine
112 lines • 4.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ListenStep = void 0;
exports.listen = listen;
const dev_js_1 = require("../dev.js");
const index_js_1 = require("../index.js");
const step_js_1 = require("../step.js");
const constant_js_1 = require("./constant.js");
/**
* Subscribes to the given `pubsubOrPlan` to get realtime updates on a given
* topic (`topicOrPlan`), mapping the resulting event via the `itemPlan`
* callback.
*/
class ListenStep extends step_js_1.Step {
static { this.$$export = {
moduleName: "grafast",
exportName: "ListenStep",
}; }
constructor(pubsubOrPlan, topicOrPlan, itemPlan = ($item) => $item, $initialEvent) {
super();
this.itemPlan = itemPlan;
this.isSyncAndSafe = true;
this.initialEventDep = null;
const $topic = typeof topicOrPlan === "string" ? (0, constant_js_1.constant)(topicOrPlan) : topicOrPlan;
const $pubsub = (0, step_js_1.isExecutableStep)(pubsubOrPlan)
? pubsubOrPlan
: (0, constant_js_1.constant)(pubsubOrPlan, false);
this.pubsubDep = this.addDependency($pubsub);
this.topicDep = this.addDependency($topic);
if ($initialEvent) {
this.initialEventDep = this.addDependency($initialEvent);
}
}
execute({ indexMap, values, stream, }) {
if (!stream) {
throw new Error("ListenStep must be streamed, never merely executed");
}
const pubsubValue = values[this.pubsubDep];
const topicValue = values[this.topicDep];
const initialEventValue = this.initialEventDep !== null ? values[this.initialEventDep] : null;
return indexMap((i) => {
const pubsub = pubsubValue.at(i);
if (!pubsub) {
throw new index_js_1.SafeError("Subscription not supported", dev_js_1.isDev
? {
hint: `${this.dependencies[this.pubsubDep]} did not provide a GrafastSubscriber; perhaps you forgot to add the relevant property to context?`,
}
: {});
}
const topic = topicValue.at(i);
const stream = pubsub.subscribe(topic);
const initialEvent = initialEventValue?.at(i);
if (initialEvent === undefined) {
return stream;
}
else {
return Promise.resolve(stream).then((stream) => withInitialValue(initialEvent, stream));
}
});
}
}
exports.ListenStep = ListenStep;
/**
* Subscribes to the given `pubsubOrPlan` to get realtime updates on a given
* topic (`topicOrPlan`), mapping the resulting event via the `itemPlan`
* callback.
*/
function listen(pubsubOrPlan, topicOrPlan, itemPlan, $initialEvent) {
return new ListenStep(pubsubOrPlan, topicOrPlan, itemPlan, $initialEvent);
}
const DONE = Object.freeze({ value: undefined, done: true });
const withInitialValue = (initialVal, source) => ({
[Symbol.asyncIterator]() {
const sourceIterator = source[Symbol.asyncIterator]();
let first = true;
let done = null;
return {
async next() {
if (done)
return done;
if (first) {
first = false;
return { value: initialVal, done: false };
}
const res = await sourceIterator.next();
if (res.done)
done = res;
return res;
},
async return(value) {
done ??= { value: value, done: true };
if (typeof sourceIterator.return === "function") {
try {
await sourceIterator.return();
}
catch {
/* noop */
}
}
return done;
},
async throw(err) {
done ??= DONE;
if (typeof sourceIterator.throw === "function") {
return sourceIterator.throw(err);
}
throw err;
},
};
},
});
//# sourceMappingURL=listen.js.map