UNPKG

@builder.io/mitosis

Version:

Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io

171 lines (170 loc) 8.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addCommonStyles = exports.renderUseLexicalScope = exports.addComponent = exports.createFileSet = void 0; const compile_away_builder_components_1 = require("../../plugins/compile-away-builder-components"); const on_mount_1 = require("../helpers/on-mount"); const directives_1 = require("./directives"); const handlers_1 = require("./helpers/handlers"); const stable_serialize_1 = require("./helpers/stable-serialize"); const styles_1 = require("./helpers/styles"); const jsx_1 = require("./jsx"); const src_generator_1 = require("./src-generator"); function createFileSet(options = {}) { const opts = { qwikLib: '@builder.io/qwik', qrlPrefix: './', output: 'ts', minify: false, jsx: true, ...options, }; const extension = (opts.output == 'mjs' ? 'js' : opts.output) + (opts.jsx ? 'x' : ''); const srcOptions = { isPretty: !opts.minify, isModule: opts.output != 'cjs', isTypeScript: opts.output == 'ts', isJSX: opts.jsx, isBuilder: true, }; const fileSet = { high: new src_generator_1.File('high.' + extension, srcOptions, opts.qwikLib, opts.qrlPrefix), med: new src_generator_1.File('med.' + extension, srcOptions, opts.qwikLib, opts.qrlPrefix), low: new src_generator_1.File('low.' + extension, srcOptions, opts.qwikLib, opts.qrlPrefix), }; Object.defineProperty(fileSet, 'CommonStyles', { enumerable: false, value: { styles: new Map(), symbolName: null }, }); return fileSet; } exports.createFileSet = createFileSet; function getCommonStyles(fileSet) { return fileSet['CommonStyles']; } function addComponent(fileSet, component, opts = {}) { const _opts = { isRoot: false, shareStyles: false, ...opts }; (0, compile_away_builder_components_1.compileAwayBuilderComponentsFromTree)(component, { ...compile_away_builder_components_1.components, // A set of components that should not be compiled away because they are implemented as runtime components. Image: undefined, CoreButton: undefined, }); addBuilderBlockClass(component.children); const componentName = component.name; const handlers = (0, handlers_1.renderHandlers)(fileSet.high, componentName, component.children); // If the component has no handlers, than it is probably static // and so it is unlikely to be re-rendered on the client, therefore // put it in a low priority bucket. const isStatic = Array.from(handlers.keys()).reduce((p, v) => p && v.indexOf('state') == -1, true); const onRenderFile = isStatic ? fileSet.low : fileSet.med; const componentFile = fileSet.med; const styles = _opts.shareStyles ? getCommonStyles(fileSet).styles : new Map(); (0, styles_1.collectStyles)(component.children, styles); let useStyles = () => null; if (styles.size) { if (_opts.shareStyles) { if (_opts.isRoot) { const symbolName = componentName + 'Styles'; getCommonStyles(fileSet).symbolName = symbolName; useStyles = generateStyles(onRenderFile, fileSet.low, symbolName, false); } } else { const symbolName = componentName + 'Styles'; onRenderFile.exportConst(symbolName, (0, styles_1.renderStyles)(styles)); useStyles = generateStyles(onRenderFile, onRenderFile, symbolName, true); } } if (component.meta.cssCode) { const symbolName = componentName + 'UsrStyles'; onRenderFile.exportConst(symbolName, (0, stable_serialize_1.stableJSONserialize)(component.meta.cssCode)); useStyles = ((fns) => function () { fns.forEach((fn) => fn.apply(this)); })([useStyles, generateStyles(onRenderFile, onRenderFile, symbolName, false)]); } const directives = new Map(); let rootChildren = component.children; addComponentOnMount(onRenderFile, function () { return this.emit('return ', (0, jsx_1.renderJSXNodes)(onRenderFile, directives, handlers, rootChildren, styles, null, {}), ';'); }, componentName, component, useStyles); componentFile.exportConst(componentName, (0, src_generator_1.invoke)(componentFile.import(componentFile.qwikModule, 'componentQrl'), [generateQrl(componentFile, onRenderFile, componentName + 'OnMount')], ['any', 'any'])); directives.forEach((code, name) => { fileSet.med.import(fileSet.med.qwikModule, 'h'); fileSet.med.exportConst(name, code, true); }); fileSet.low.exportConst('__proxyMerge__', directives_1.DIRECTIVES['__proxyMerge__'], true); fileSet.med.exportConst('__proxyMerge__', directives_1.DIRECTIVES['__proxyMerge__'], true); fileSet.high.exportConst('__proxyMerge__', directives_1.DIRECTIVES['__proxyMerge__'], true); } exports.addComponent = addComponent; function generateStyles(fromFile, dstFile, symbol, scoped) { return function () { if (this.file.options.isPretty) { this.emit('\n\n'); } this.emit((0, src_generator_1.invoke)(fromFile.import(fromFile.qwikModule, scoped ? 'useStylesScopedQrl' : 'useStylesQrl'), [ generateQrl(fromFile, dstFile, symbol), ]), ';'); if (this.file.options.isPretty) { this.emit('\n\n'); } }; } function addBuilderBlockClass(children) { children.forEach((child) => { const props = child.properties; if (props['builder-id']) { props.class = (props.class ? props.class + ' ' : '') + 'builder-block'; } }); } function renderUseLexicalScope(file) { return function () { if (this.file.options.isBuilder) { return this.emit('const [s,l]=', file.import(file.qwikModule, 'useLexicalScope').localName, '();', 'const state=__proxyMerge__(s,l);'); } else { return this.emit('const state=', file.import(file.qwikModule, 'useLexicalScope').localName, '()[0]'); } }; } exports.renderUseLexicalScope = renderUseLexicalScope; function addCommonStyles(fileSet) { const { styles, symbolName } = getCommonStyles(fileSet); const onRenderFile = fileSet.low; if (symbolName) { onRenderFile.exportConst(symbolName, (0, styles_1.renderStyles)(styles)); } } exports.addCommonStyles = addCommonStyles; function addComponentOnMount(componentFile, onRenderEmit, componentName, component, useStyles) { const inputInitializer = []; if (component.inputs) { component.inputs.forEach((input) => { input.defaultValue !== undefined && inputInitializer.push('if(!state.hasOwnProperty("', input.name, '"))state.', input.name, '=', (0, stable_serialize_1.stableJSONserialize)(input.defaultValue), ';'); }); } componentFile.exportConst(componentName + 'OnMount', function () { this.emit((0, src_generator_1.arrowFnValue)(['p'], () => this.emit('{', 'const s=', componentFile.import(componentFile.qwikModule, 'useStore').localName, '(()=>{', 'const state=Object.assign({},structuredClone(typeof __STATE__==="object"&&__STATE__[p.serverStateId]),p);', ...inputInitializer, inlineCode((0, on_mount_1.stringifySingleScopeOnMount)(component)), 'return state;', '},{deep:true});', 'const l={};', 'const state=__proxyMerge__(s,l);', useStyles, onRenderEmit, ';}'))); }); } function inlineCode(code) { return function () { if (code) { // HACK: remove the return value as it is not the state we are creating. code = code .trim() .replace(/return main\(\);?$/, '') .trim(); this.emit(code, ';'); } }; } function generateQrl(fromFile, dstFile, componentName, capture = []) { return (0, src_generator_1.invoke)(fromFile.import(fromFile.qwikModule, 'qrl'), [ dstFile.toQrlChunk(), (0, src_generator_1.quote)(componentName), `[${capture.join(',')}]`, ]); }