UNPKG

@netlify/content-engine

Version:
88 lines 3.66 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.syncLedger = syncLedger; const got_1 = __importDefault(require("got")); const fastq_1 = __importDefault(require("fastq")); const stream_1 = __importDefault(require("stream")); const util_1 = __importDefault(require("util")); const Parser_1 = require("stream-json/jsonl/Parser"); const redux_1 = require("../redux"); const cache_lmdb_1 = __importDefault(require("./cache-lmdb")); const pipeline = util_1.default.promisify(stream_1.default.pipeline); async function syncLedger({ dataLayerId, sourcingConfigurationId, cacheSourceVersionId, blockVersionId, directory, onAction, }) { let synchronizerCache; synchronizerCache = synchronizerCache || new cache_lmdb_1.default({ name: `ledger-cache`, encoding: `json`, directory, }).init(); const ledgerApiUrl = `${process.env.CONTENT_ENGINE_SYNC_URL}/${dataLayerId}/${sourcingConfigurationId}/${cacheSourceVersionId}`; const lastSourcingUlid = await synchronizerCache.get(`lastSourcingUlid`); console.log(`[content-engine] synchronizing data from ${ledgerApiUrl} from version ${lastSourcingUlid}`); const httpStream = got_1.default.stream(ledgerApiUrl, { headers: { "x-consumer-offset": lastSourcingUlid || "0", "x-end-offset": blockVersionId, "x-resource-auth-jwt": process.env.RESOURCE_AUTH_JWT, "x-site-auth-jwt": process.env.RESOURCE_AUTH_JWT, "x-resource-type": process.env.RESOURCE_TYPE, }, }); httpStream.on(`response`, (res) => { if (process.env.DEBUG_MERLIN_SYNCHRONIZER) { console.info(`Synchronizer ledger response status code`, res.statusCode); } const newLastSourcingUlid = res.headers[`x-consumer-offset`]; if (newLastSourcingUlid) { console.log(`[content-engine] synchronized data up until version ${newLastSourcingUlid}`); synchronizerCache.set(`lastSourcingUlid`, newLastSourcingUlid); } }); let dispatchCount = 0; let lastEmittedAction; const handleActionQueue = (0, fastq_1.default)((entry, cb) => { lastEmittedAction = entry.value; if (onAction) { onAction(entry.value); } redux_1.store.dispatch(entry.value); // Do not block task queue of the event loop for too long: if (dispatchCount++ % 100 === 0) { setImmediate(() => { cb(null); }); } else { cb(null); } }, 1); const decode = (0, Parser_1.parser)(); decode.on(`data`, (data) => handleActionQueue.push(data)); let decodeError = null; decode.on(`error`, (e) => { handleActionQueue.kill(); decodeError = e; }); await pipeline(httpStream, decode); if (decodeError) { throw decodeError; } if (!handleActionQueue.idle()) { await new Promise((res) => { handleActionQueue.drain = () => res(null); }); } handleActionQueue.kill(); if (lastEmittedAction && lastEmittedAction?.payload?.event !== `END_SOURCING`) { throw Error(`ledger stream closed but didn't receive an END_SOURCING action`); } console.info(`[content-engine] Total actions synced from ledger: ${dispatchCount > 0 ? dispatchCount - 2 : dispatchCount}`); return dispatchCount; } //# sourceMappingURL=synchronize.js.map