@sigi/ssr
Version:
Server side rendering support for sigi framework
187 lines • 7.86 kB
JavaScript
import { __read, __spreadArray, __values } from "tslib";
import { TERMINATE_ACTION_TYPE_SYMBOL, getSSREffectMeta, RETRY_ACTION_TYPE_SYMBOL } from '@sigi/core';
import { rootInjector } from '@sigi/di';
import { StateToPersist } from './state-to-persist';
export var SKIP_SYMBOL = Symbol('skip-symbol');
export var runSSREffects = function (ctx, modules, config) {
if (config === void 0) { config = {}; }
var stateToSerialize = {};
var actionsToRetry = {};
var providers = config.providers, _a = config.timeout, timeout = _a === void 0 ? 1 : _a;
var injector = rootInjector.createChild(__spreadArray(__spreadArray([], __read(modules), false), __read((providers !== null && providers !== void 0 ? providers : [])), false));
var cleanupFns = [];
var timer;
var terminatedCount = 0;
var effectsCount = 0;
var moduleInstanceCache = new Map();
injector.serverCache = moduleInstanceCache;
var pendingState = new Promise(function (resolve, reject) {
var e_1, _a;
if (!modules.length) {
return resolve();
}
timer = setTimeout(function () {
reject(new Error('Terminate timeout'));
}, timeout * 1000);
var _loop_1 = function (constructor) {
var e_2, _b;
var isAllSkipped = true;
var ssrActionsMeta = getSSREffectMeta(constructor.prototype, []);
var effectModuleInstance = injector.getInstance(constructor);
moduleInstanceCache.set(constructor, effectModuleInstance);
var store = effectModuleInstance.store, moduleName = effectModuleInstance.moduleName;
effectsCount += ssrActionsMeta.length;
var subscription = store.action$.subscribe({
next: function (_a) {
var type = _a.type, payload = _a.payload;
isAllSkipped = false;
if (type === RETRY_ACTION_TYPE_SYMBOL) {
var name_1 = payload.name;
if (!actionsToRetry[moduleName]) {
actionsToRetry[moduleName] = [name_1];
}
else {
actionsToRetry[moduleName].push(name_1);
}
}
if (type === TERMINATE_ACTION_TYPE_SYMBOL) {
terminatedCount++;
}
if (terminatedCount === effectsCount) {
resolve();
}
},
error: function (e) {
reject(e);
},
});
var _loop_2 = function (ssrActionMeta) {
if (ssrActionMeta.payloadGetter) {
var maybeDeferredPayload = void 0;
try {
maybeDeferredPayload = ssrActionMeta.payloadGetter(ctx, SKIP_SYMBOL);
}
catch (e) {
return { value: reject(e) };
}
Promise.resolve(maybeDeferredPayload)
.then(function (payload) {
if (payload !== SKIP_SYMBOL) {
isAllSkipped = false;
store.dispatch({
type: ssrActionMeta.action,
payload: payload,
store: store,
});
}
else {
if (!actionsToRetry[moduleName]) {
actionsToRetry[moduleName] = [ssrActionMeta.action];
}
else {
actionsToRetry[moduleName].push(ssrActionMeta.action);
}
effectsCount--;
if (terminatedCount === effectsCount) {
resolve();
}
}
})
.catch(function (e) {
reject(e);
});
}
else {
isAllSkipped = false;
store.dispatch({
type: ssrActionMeta.action,
payload: undefined,
store: store,
});
}
};
try {
for (var ssrActionsMeta_1 = (e_2 = void 0, __values(ssrActionsMeta)), ssrActionsMeta_1_1 = ssrActionsMeta_1.next(); !ssrActionsMeta_1_1.done; ssrActionsMeta_1_1 = ssrActionsMeta_1.next()) {
var ssrActionMeta = ssrActionsMeta_1_1.value;
var state_2 = _loop_2(ssrActionMeta);
if (typeof state_2 === "object")
return state_2;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (ssrActionsMeta_1_1 && !ssrActionsMeta_1_1.done && (_b = ssrActionsMeta_1.return)) _b.call(ssrActionsMeta_1);
}
finally { if (e_2) throw e_2.error; }
}
cleanupFns.push(function () {
subscription.unsubscribe();
store.dispose();
!isAllSkipped && (stateToSerialize[moduleName] = store.state);
});
};
try {
for (var modules_1 = __values(modules), modules_1_1 = modules_1.next(); !modules_1_1.done; modules_1_1 = modules_1.next()) {
var constructor = modules_1_1.value;
var state_1 = _loop_1(constructor);
if (typeof state_1 === "object")
return state_1.value;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (modules_1_1 && !modules_1_1.done && (_a = modules_1.return)) _a.call(modules_1);
}
finally { if (e_1) throw e_1.error; }
}
if (!effectsCount) {
resolve();
}
})
.then(function () {
var e_3, _a;
if (timer) {
clearTimeout(timer);
timer = undefined;
}
try {
for (var cleanupFns_1 = __values(cleanupFns), cleanupFns_1_1 = cleanupFns_1.next(); !cleanupFns_1_1.done; cleanupFns_1_1 = cleanupFns_1.next()) {
var cleanup = cleanupFns_1_1.value;
cleanup();
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (cleanupFns_1_1 && !cleanupFns_1_1.done && (_a = cleanupFns_1.return)) _a.call(cleanupFns_1);
}
finally { if (e_3) throw e_3.error; }
}
return new StateToPersist(stateToSerialize, actionsToRetry);
})
.catch(function (e) {
var e_4, _a;
if (timer) {
clearTimeout(timer);
timer = undefined;
}
try {
for (var cleanupFns_2 = __values(cleanupFns), cleanupFns_2_1 = cleanupFns_2.next(); !cleanupFns_2_1.done; cleanupFns_2_1 = cleanupFns_2.next()) {
var cleanup = cleanupFns_2_1.value;
cleanup();
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (cleanupFns_2_1 && !cleanupFns_2_1.done && (_a = cleanupFns_2.return)) _a.call(cleanupFns_2);
}
finally { if (e_4) throw e_4.error; }
}
throw e;
});
return { injector: injector, pendingState: pendingState };
};
//# sourceMappingURL=run.js.map