UNPKG

reactant-share

Version:

A framework for building shared web applications with Reactant

116 lines (113 loc) 5.59 kB
import { __awaiter, __generator, __values } from './node_modules/tslib/tslib.es6.js'; import { containerKey, actionIdentifier } from 'reactant'; import { LastAction } from 'reactant-last-action'; import { isClientName, loadFullStateActionName, proxyClientActionName, lastActionName } from './constants.js'; import { PortDetector } from './modules/portDetector.js'; import { PatchesChecker } from './modules/patchesChecker.js'; import { applyMethod } from './applyMethod.js'; import { isSharedWorker } from './utils.js'; var handleServer = function (_a) { var _b; var app = _a.app, transport = _a.transport, disposeServer = _a.disposeServer, disposeClient = _a.disposeClient, enablePatchesChecker = _a.enablePatchesChecker; if (!transport) { throw new Error("The server transport does not exist."); } disposeServer === null || disposeServer === void 0 ? void 0 : disposeServer(); disposeClient === null || disposeClient === void 0 ? void 0 : disposeClient(); var container = app.instance[containerKey]; var lastAction = container.get(LastAction); var portDetector = container.get(PortDetector); var patchesChecker = enablePatchesChecker ? container.get(PatchesChecker) : null; if (isSharedWorker) { var executed_1 = false; // before any other event, it should be connected with the first client globalThis.addEventListener('connect', function () { if (executed_1) return; executed_1 = true; portDetector.setPort({ server: app }, transport); }); } else { portDetector.setPort({ server: app }, transport); } var disposeListeners = []; disposeListeners.push(transport.listen(isClientName, function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, true]; }); }); })); disposeListeners.push(transport.listen(loadFullStateActionName, function (sequence) { return __awaiter(void 0, void 0, void 0, function () { var _a; return __generator(this, function (_b) { return [2 /*return*/, lastAction.sequence > sequence ? (_a = app.store) === null || _a === void 0 ? void 0 : _a.getState() : null]; }); }); })); disposeListeners.push(transport.listen(proxyClientActionName, function (options) { return __awaiter(void 0, void 0, void 0, function () { var hook, result_1, sequence_1, result, sequence; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!options.hook) return [3 /*break*/, 2]; hook = portDetector.serverHooks[options.hook]; if (!(typeof hook === 'function')) return [3 /*break*/, 2]; return [4 /*yield*/, hook(options)]; case 1: result_1 = _a.sent(); sequence_1 = portDetector.lastAction.sequence; return [2 /*return*/, [sequence_1, result_1]]; case 2: return [4 /*yield*/, applyMethod(app, options)]; case 3: result = _a.sent(); sequence = portDetector.lastAction.sequence; return [2 /*return*/, [sequence, result]]; } }); }); })); disposeListeners.push(function () { return transport.dispose(); }); var oldStateTree; if (process.env.NODE_ENV !== 'production') { oldStateTree = app.store.getState(); } disposeListeners.push((_b = app.store) === null || _b === void 0 ? void 0 : _b.subscribe(function () { var _a, _b; try { if (lastAction.action) { var action = lastAction.action; if (!((_b = (_a = portDetector.lastAction.options) === null || _a === void 0 ? void 0 : _a.ignoreAction) === null || _b === void 0 ? void 0 : _b.call(_a, action))) { if (process.env.NODE_ENV !== 'production' && enablePatchesChecker && patchesChecker && (action === null || action === void 0 ? void 0 : action._reactant) === actionIdentifier && action._patches) { patchesChecker.checkPatches(oldStateTree, action); } transport.emit({ name: lastActionName, respond: false }, action); } } } finally { if (process.env.NODE_ENV !== 'production') { oldStateTree = app.store.getState(); } } })); // app synchronizes state to all clients immediately after switching server port if (portDetector.previousPort === 'client') { portDetector.syncToClients(); } return function () { var e_1, _a; try { for (var disposeListeners_1 = __values(disposeListeners), disposeListeners_1_1 = disposeListeners_1.next(); !disposeListeners_1_1.done; disposeListeners_1_1 = disposeListeners_1.next()) { var dispose = disposeListeners_1_1.value; dispose === null || dispose === void 0 ? void 0 : dispose(); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (disposeListeners_1_1 && !disposeListeners_1_1.done && (_a = disposeListeners_1.return)) _a.call(disposeListeners_1); } finally { if (e_1) throw e_1.error; } } }; }; export { handleServer };