UNPKG

prostgles-client

Version:

Reactive client for Postgres

177 lines (176 loc) 6.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSyncHandler = void 0; const prostgles_types_1 = require("prostgles-types"); const FunctionQueuer_1 = require("./FunctionQueuer"); const prostgles_1 = require("./prostgles"); const preffix = prostgles_types_1.CHANNELS._preffix; const getSyncHandler = ({ socket }) => { let syncedTables = {}; let syncs = {}; const destroySyncs = async () => { (0, prostgles_1.debug)("destroySyncs", { syncedTables }); syncs = {}; Object.values(syncedTables).forEach((s) => { s.destroy(); }); syncedTables = {}; }; function _unsync(channelName, triggers) { (0, prostgles_1.debug)("_unsync", { channelName, triggers }); return new Promise((resolve, reject) => { if (syncs[channelName]) { syncs[channelName].triggers = syncs[channelName].triggers.filter((tr) => tr.onPullRequest !== triggers.onPullRequest && tr.onSyncRequest !== triggers.onSyncRequest && tr.onUpdates !== triggers.onUpdates); if (!syncs[channelName].triggers.length) { socket.emit(channelName + "unsync", {}, (err, res) => { if (err) reject(err); else resolve(res); }); socket.removeListener(channelName, syncs[channelName].onCall); delete syncs[channelName]; } } }); } function addServerSync({ tableName, command, param1, param2 }, onSyncRequest) { return new Promise((resolve, reject) => { socket.emit(preffix, { tableName, command, param1, param2 }, (err, res) => { if (err) { console.error(err); reject(err); } else if (res) { const { id_fields, synced_field, channelName } = res; socket.emit(channelName, { onSyncRequest: onSyncRequest({}) }, (response) => { console.log(response); }); resolve({ id_fields, synced_field, channelName }); } }); }); } const addSyncQueuer = new FunctionQueuer_1.FunctionQueuer(_addSync, ([{ tableName }]) => tableName); async function addSync(params, triggers) { return addSyncQueuer.run([params, triggers]); } async function _addSync({ tableName, command, param1, param2 }, triggers) { const { onSyncRequest } = triggers; function makeHandler(channelName) { const unsync = function () { _unsync(channelName, triggers); }; const syncData = function (data, deleted, cb) { socket.emit(channelName, { onSyncRequest: { ...onSyncRequest({}), ...{ data }, ...{ deleted }, }, }, !cb ? null : ((response) => { cb(response); })); }; return Object.freeze({ unsync, syncData }); } const existingChannel = Object.keys(syncs).find((ch) => { const s = syncs[ch]; return (s && s.tableName === tableName && s.command === command && (0, prostgles_types_1.isEqual)(s.param1, param1) && (0, prostgles_types_1.isEqual)(s.param2, param2)); }); if (existingChannel) { syncs[existingChannel].triggers.push(triggers); return makeHandler(existingChannel); } else { const sync_info = await addServerSync({ tableName, command, param1, param2 }, onSyncRequest); const { channelName } = sync_info; const onCall = function (data, cb) { /* Client will: 1. Send last_synced on(onSyncRequest) 2. Send data >= server_synced on(onPullRequest) 3. Send data on CRUD emit(data.data) 4. Upsert data.data on(data.data) */ if (!data) return; if (!syncs[channelName]) return; syncs[channelName].triggers.map(({ onUpdates, onSyncRequest, onPullRequest }) => { if (data.data) { Promise.resolve(onUpdates(data)) .then(() => { cb({ ok: true }); }) .catch((err) => { cb({ err }); }); } else if (data.onSyncRequest) { Promise.resolve(onSyncRequest(data.onSyncRequest)) .then((res) => cb({ onSyncRequest: res })) .catch((err) => { cb({ err }); }); } else if (data.onPullRequest) { Promise.resolve(onPullRequest(data.onPullRequest)) .then((result) => { cb(result); }) .catch((err) => { cb({ err }); }); } else { console.log("unexpected response"); } }); }; syncs[channelName] = { tableName, command, param1, param2, triggers: [triggers], syncInfo: sync_info, onCall, }; socket.on(channelName, onCall); return makeHandler(channelName); } } const reAttachAll = async () => { let reAttached = 0; Object.entries(syncs).forEach(async ([ch, s]) => { const firstTrigger = s.triggers[0]; if (firstTrigger) { try { await addServerSync(s, firstTrigger.onSyncRequest); socket.on(ch, s.onCall); reAttached++; } catch (err) { console.error("There was an issue reconnecting olf subscriptions", err); } } }); if (reAttached) { console.log("reAttached", reAttached, " syncs", syncs); } }; return { destroySyncs, syncedTables, addSync, reAttachAll, }; }; exports.getSyncHandler = getSyncHandler;