@foxpage/foxpage-node-sdk
Version:
foxpage node sdk
132 lines (131 loc) • 5.38 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderToHTML = exports.loadComponents = void 0;
const lodash_1 = __importDefault(require("lodash"));
const common_1 = require("../common");
const logger_1 = require("../logger");
const loader_1 = require("./loader");
const pre_1 = require("./pre");
const BLANK_NODE = 'system.inherit-blank-node'; // blank node
/**
* load page component
* @param schemas page schemas
* @param app application object
* @param opt ComponentLoad option
* @returns {Promise<Map<string, FoxpageComponent>>}
*/
const loadComponents = async (schemas, appId, opt) => {
const loader = new loader_1.ComponentLoaderImpl(appId, opt);
await loader.load(schemas);
const components = lodash_1.default.cloneDeep(loader.getLoadedComponents());
const dependencies = lodash_1.default.cloneDeep(loader.getLoadedDependencies());
loader.destroy();
return [components, dependencies];
};
exports.loadComponents = loadComponents;
/**
* render to html
* @param dsl page dsl
* @param ctx render context
* @param opt render options
* @returns html string
*/
const renderToHTML = async (dsl, ctx, opt) => {
const { logger = (0, logger_1.loggerCreate)('render') } = ctx;
logger.info('render DSL:', JSON.stringify(dsl));
if (dsl && dsl.length > 0) {
const { dsl: newDSL, structureMap } = prepareDSL(dsl, ctx);
let preparedDSL = newDSL;
ctx.page.schemas = preparedDSL;
ctx.structureMap = structureMap;
// load components
const { isCanary = false, isPreviewMode = false, isSemver = true, reLoadComponent = false } = ctx;
const loadCost = ctx.performanceLogger('componentLoadTime');
const [components, dependencies] = await (0, exports.loadComponents)(preparedDSL, ctx.appId, Object.assign(Object.assign({}, opt), { isPreviewMode,
isCanary,
isSemver,
reLoadComponent }));
loadCost();
ctx.componentMap = components;
ctx.dependencies = dependencies;
logger.debug('loaded components: ', Array.from(new Set(Array.from(components === null || components === void 0 ? void 0 : components.values()).map(item => item.name))));
await (0, pre_1.preprocess)(preparedDSL, ctx, {});
let html = '';
const renderHookCost = ctx.performanceLogger('renderHookTime');
const { beforePageRender, onPageRender, afterPageRender } = ctx.hooks || {};
if (typeof beforePageRender === 'function') {
preparedDSL = await beforePageRender(ctx);
logger.info('do beforePageRender');
logger.debug('beforePageRender hook get the dsl: ', JSON.stringify(preparedDSL));
}
// render
if (typeof onPageRender === 'function') {
html = await onPageRender(ctx, preparedDSL);
logger.info('do onPageRender');
logger.debug(`onPageRender hook get the html ${htmlStatus(html)}`);
}
else if (typeof ctx.render === 'function') {
html = await ctx.render(preparedDSL, ctx);
logger.info('do render');
logger.debug(`render html ${htmlStatus(html)}`);
}
else {
logger.error('render is invalid.');
}
if (typeof afterPageRender === 'function') {
html = await afterPageRender(ctx, html);
logger.debug('do afterPageRender');
logger.debug(`afterPageRender hook get the html ${htmlStatus(html)}`);
}
renderHookCost();
logger.debug('rendered');
logger.debug(`rendered html ${htmlStatus(html)}`);
return html && html.startsWith('<html') ? common_1.DOCTYPE + html : html || '';
}
return '';
};
exports.renderToHTML = renderToHTML;
function htmlStatus(html) {
return html ? 'succeed' : 'empty';
}
/**
* filter no show node & generate structureMap
*
* @param {StructureNode[]} schemas
* @return {*}
*/
function prepareDSL(schemas, ctx) {
const structureMap = new Map();
function doPrepare(dsl) {
const newDSL = [];
dsl.forEach(item => {
var _a;
const { id, name, label, type, version, props, show = true, children = [], extension } = item;
if ((!ctx.disableConditionRender && !show) || name === BLANK_NODE) {
(_a = ctx.logger) === null || _a === void 0 ? void 0 : _a.info(`node ${name}@${id} not show`);
}
else {
const childList = children.length > 0 ? doPrepare(children) : [];
// push new dsl nodes
newDSL.push(Object.assign(Object.assign({}, item), { children: childList }));
// set to structureMap
structureMap === null || structureMap === void 0 ? void 0 : structureMap.set(id, {
id,
name,
label,
version,
type,
props,
extension,
childrenIds: childList.map(child => child.id),
});
}
});
return newDSL;
}
const dsl = doPrepare(schemas);
return { dsl, structureMap };
}