UNPKG

grafast

Version:

Cutting edge GraphQL planning and execution engine

112 lines 4.28 kB
"use strict"; 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