@bookbox/core
Version:
Bookbox — e-book format
167 lines (166 loc) • 6.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBookExternalBuilder = exports.createBookBuilder = exports.createBook = void 0;
const linkedSchema_1 = require("./linkedSchema");
const meta_1 = require("./meta");
const store_1 = require("./store");
const utils_1 = require("../utils");
const resources_1 = require("./resources");
const iterableBook_1 = require("./iterableBook");
const counters_1 = require("./counters");
/**
* Добавление ключей по умолчанию всем элементам
*/
function addKeysToSchema(schema, keys = new Map()) {
const bumpKey = (name) => {
var _a;
keys.set(name, ((_a = keys.get(name)) !== null && _a !== void 0 ? _a : 0) + 1);
};
for (const item of schema) {
if (typeof item === 'string') {
continue;
}
if (item.props.key === undefined) {
bumpKey(item.name);
// TODO: разобраться, почему мутация затрагивает все элементы
item.props = Object.assign(Object.assign({}, item.props), { key: `${item.name}-${keys.get(item.name)}` });
}
addKeysToSchema(item.children, keys);
}
}
const prepareBookElem = {
code: item => {
if ((item.props.block || item.props.position !== 'inline') &&
item.children.length === 1 &&
typeof item.children[0] === 'string') {
item.children[0] = item.children[0].trim();
}
},
};
function prepareSchema(schema) {
for (const item of (0, iterableBook_1.getIterableBook)(schema)) {
if (typeof item === 'string')
continue;
const { name } = item;
if (name in prepareBookElem) {
prepareBookElem[name](item);
}
}
}
function createBook({ schema: originalSchema, builder: builderParams, externalBuilder, resourceOptions, }) {
let schema = JSON.parse(JSON.stringify(originalSchema));
const builder = createBookBuilder(builderParams);
addKeysToSchema(schema);
(0, counters_1.calculateCounters)(schema);
(0, resources_1.calculateResources)(schema, (0, resources_1.getActualResourceMap)({ schema, resourceOptions }));
prepareSchema(schema);
const linkedSchema = (0, linkedSchema_1.getBookLinkedSchema)(schema, true);
const tokensSchema = (0, linkedSchema_1.getSchemaFromLinkedList)(linkedSchema.tree);
const getBuild = (currentStore) => (localSchema) => builder({ schema: localSchema, store: currentStore, externalBuilder, build: getBuild(currentStore) });
const store = (0, store_1.getStore)({ builder, schema, externalBuilder, getBuild });
const build = getBuild(store);
const meta = (0, meta_1.getBookMeta)({ schema, store, builder, build });
schema = tokensSchema;
return {
tokens: builder({ schema, store, externalBuilder, build }),
meta,
store,
};
}
exports.createBook = createBook;
const synteticElementNameSet = new Set(['text', 'page', 'error', 'empty']);
const emptyElementNameSet = new Set(['resource']);
const prepareElementNameSet = new Set(['code']);
function createBookBuilder({ elements, synteticElements, }) {
const builder = ({ schema, store, externalBuilder, parents = [], build }) => {
const getItemBuilder = store => item => {
// leaf case
if (typeof item === 'string') {
return synteticElements.text({ raw: item, key: '' })({
children: [],
store,
parents,
build,
});
}
// choose name
let { name } = item;
if (emptyElementNameSet.has(name)) {
name = 'empty';
}
// choose namespace
let targetElements = elements;
if (synteticElementNameSet.has(name)) {
targetElements = synteticElements;
}
let elemBuilder;
if (name === 'external') {
if (externalBuilder) {
const { scope = 'custom', name: extName = 'local' } = item.props;
elemBuilder = (0, utils_1.getByPath)([`${scope}`, `${extName}`], externalBuilder);
}
// default external builder
if (typeof elemBuilder !== 'function') {
elemBuilder = (0, utils_1.getByPath)([name], elements);
}
}
else {
const path = name.split('.');
elemBuilder = (0, utils_1.getByPath)(path, targetElements);
}
// error
const getError = (children, error) => {
elemBuilder = synteticElements.error;
return synteticElements.error({
props: item.props,
name: item.name,
error: error !== null && error !== void 0 ? error : 'error',
})({
children,
store,
parents,
build,
});
};
// render children
let childTokens = [];
try {
childTokens = builder({
schema: item.children,
store,
externalBuilder,
parents: [...parents, `${item.props.key}`],
build,
});
}
catch (e) {
console.error(e);
return getError([], String(e));
}
if (typeof elemBuilder !== 'function') {
return getError(childTokens, 'unknown element');
}
// ok
try {
return elemBuilder(item.props)({
children: childTokens,
store,
parents,
build,
});
}
catch (e) {
console.error(e);
return getError([], String(e));
}
};
const itemBuilder = getItemBuilder(store);
return (0, utils_1.flatList)(schema.map(itemBuilder));
};
return builder;
}
exports.createBookBuilder = createBookBuilder;
function createBookExternalBuilder({ element }) {
return { externalBuilder: element };
}
exports.createBookExternalBuilder = createBookExternalBuilder;