UNPKG

@vendure/core

Version:

A modern, headless ecommerce framework

83 lines 5.14 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SubscribableJob = void 0; const generated_types_1 = require("@vendure/common/lib/generated-types"); const pick_1 = require("@vendure/common/lib/pick"); const shared_utils_1 = require("@vendure/common/lib/shared-utils"); const ms_1 = __importDefault(require("ms")); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const errors_1 = require("../common/error/errors"); const index_1 = require("../config/index"); const inspectable_job_queue_strategy_1 = require("../config/job-queue/inspectable-job-queue-strategy"); const job_1 = require("./job"); /** * @description * This is a type of Job object that allows you to subscribe to updates to the Job. It is returned * by the {@link JobQueue}'s `add()` method. Note that the subscription capability is only supported * if the {@link JobQueueStrategy} implements the {@link InspectableJobQueueStrategy} interface (e.g. * the {@link SqlJobQueueStrategy} does support this). * * @docsCategory JobQueue */ class SubscribableJob extends job_1.Job { constructor(job, jobQueueStrategy) { const config = Object.assign(Object.assign({}, job), { state: job.state, data: job.data, id: job.id || undefined }); super(config); this.jobQueueStrategy = jobQueueStrategy; } /** * @description * Returns an Observable stream of updates to the Job. Works by polling the current JobQueueStrategy's `findOne()` method * to obtain updates. If the updates are not subscribed to, then no polling occurs. * * Polling interval, timeout and other options may be configured with an options arguments {@link JobUpdateOptions}. * */ updates(options) { var _a, _b; const pollInterval = Math.max(50, (_a = options === null || options === void 0 ? void 0 : options.pollInterval) !== null && _a !== void 0 ? _a : 200); const timeoutMs = Math.max(1, (_b = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _b !== void 0 ? _b : (0, ms_1.default)('1h')); const strategy = this.jobQueueStrategy; if (!(0, inspectable_job_queue_strategy_1.isInspectableJobQueueStrategy)(strategy)) { throw new errors_1.InternalServerError(`The configured JobQueueStrategy (${strategy.constructor.name}) is not inspectable, so Job updates cannot be subscribed to`); } else { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const updates$ = (0, rxjs_1.interval)(pollInterval).pipe((0, operators_1.switchMap)(() => { const id = this.id; if (!id) { throw new Error('Cannot subscribe to update: Job does not have an ID'); } return strategy.findOne(id); }), (0, operators_1.filter)(shared_utils_1.notNullOrUndefined), (0, operators_1.distinctUntilChanged)((a, b) => (a === null || a === void 0 ? void 0 : a.progress) === (b === null || b === void 0 ? void 0 : b.progress) && (a === null || a === void 0 ? void 0 : a.state) === (b === null || b === void 0 ? void 0 : b.state)), (0, operators_1.takeWhile)(job => (job === null || job === void 0 ? void 0 : job.state) !== generated_types_1.JobState.FAILED && job.state !== generated_types_1.JobState.COMPLETED && job.state !== generated_types_1.JobState.CANCELLED, true), (0, operators_1.tap)(job => { var _a; if (job.state === generated_types_1.JobState.FAILED && ((_a = options === null || options === void 0 ? void 0 : options.errorOnFail) !== null && _a !== void 0 ? _a : true)) { throw new Error(job.error); } }), (0, operators_1.map)(job => (0, pick_1.pick)(job, ['id', 'state', 'progress', 'result', 'error', 'data']))); const timeout$ = (0, rxjs_1.timer)(timeoutMs).pipe((0, operators_1.tap)(i => { var _a; index_1.Logger.error(`Job ${(_a = this.id) !== null && _a !== void 0 ? _a : ''} SubscribableJob update polling timed out after ${timeoutMs}ms. The job may still be running.`); }), (0, operators_1.map)(() => ({ id: this.id, state: generated_types_1.JobState.RUNNING, data: this.data, error: this.error, progress: this.progress, result: 'Job subscription timed out. The job may still be running', }))); // Use race() to return whichever observable emits first and follow it to completion. // - If updates$ emits first, it will continue emitting until the job settles // - If timeout$ emits first, it will emit the timeout message and complete return (0, rxjs_1.race)(updates$, timeout$); } } } exports.SubscribableJob = SubscribableJob; //# sourceMappingURL=subscribable-job.js.map