reactant-share
Version:
A framework for building shared web applications with Reactant
116 lines (113 loc) • 5.59 kB
JavaScript
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 };