@builder.io/mitosis
Version:
Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io
112 lines (111 loc) • 5 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getStateMethodsAndGetters = exports.getLexicalScopeVars = exports.emitStateMethodsAndRewriteBindings = exports.emitUseStore = void 0;
const legacy_1 = __importDefault(require("neotraverse/legacy"));
const babel_transform_1 = require("../../../helpers/babel-transform");
const convert_method_to_function_1 = require("./convert-method-to-function");
const stable_inject_1 = require("./stable-inject");
/**
* @param file
* @param stateInit
*/
function emitUseStore({ file, stateInit, isDeep, }) {
const state = stateInit[0];
const hasState = state && Object.keys(state).length > 0;
if (hasState) {
file.src.emit('const state=', file.import(file.qwikModule, 'useStore').localName);
if (file.options.isTypeScript) {
file.src.emit('<any>');
}
const fnArgs = [(0, stable_inject_1.stableInject)(state), isDeep ? '{deep: true}' : undefined].filter(Boolean);
file.src.emit(`(${fnArgs});`);
}
else {
// TODO hack for now so that `state` variable is defined, even though it is never read.
file.src.emit(`const state${file.options.isTypeScript ? ': any' : ''} = {};`);
}
}
exports.emitUseStore = emitUseStore;
function emitStateMethods(file, componentState, lexicalArgs) {
const stateValues = {};
const stateInit = [stateValues];
const methodMap = getStateMethodsAndGetters(componentState);
for (const key in componentState) {
const stateValue = componentState[key];
switch (stateValue === null || stateValue === void 0 ? void 0 : stateValue.type) {
case 'method':
case 'function':
let code = stateValue.code;
const isAsync = code.startsWith('async');
if (!isAsync) {
let prefixIdx = 0;
if (stateValue.type === 'function') {
prefixIdx += 'function '.length;
}
code = code.substring(prefixIdx);
code = (0, convert_method_to_function_1.convertMethodToFunction)(code, methodMap, lexicalArgs).replace('(', `(${lexicalArgs.join(',')},`);
}
const functionName = code.split(/\(/)[0];
if (!file.options.isTypeScript) {
// Erase type information
code = (0, babel_transform_1.convertTypeScriptToJS)(code);
}
file.exportConst(isAsync ? key : functionName, isAsync ? code : 'function ' + code, true);
continue;
case 'property':
stateValues[key] = stateValue.code;
continue;
}
}
return stateInit;
}
function emitStateMethodsAndRewriteBindings(file, component, metadata) {
var _a;
const lexicalArgs = getLexicalScopeVars(component);
const state = emitStateMethods(file, component.state, lexicalArgs);
const methodMap = getStateMethodsAndGetters(component.state);
rewriteCodeExpr(component, methodMap, lexicalArgs, (_a = metadata === null || metadata === void 0 ? void 0 : metadata.qwik) === null || _a === void 0 ? void 0 : _a.replace);
return state;
}
exports.emitStateMethodsAndRewriteBindings = emitStateMethodsAndRewriteBindings;
const checkIsObjectWithCodeBlock = (obj) => {
return typeof obj == 'object' && (obj === null || obj === void 0 ? void 0 : obj.code) && typeof obj.code === 'string';
};
function getLexicalScopeVars(component) {
const newLocal = [
'props',
'state',
// all `useComputed` values
...Object.keys(component.state).filter((k) => component.state[k].type === 'getter'),
...Object.keys(component.refs),
...Object.keys(component.context.get),
];
return newLocal;
}
exports.getLexicalScopeVars = getLexicalScopeVars;
function rewriteCodeExpr(component, methodMap, lexicalArgs, replace = {}) {
(0, legacy_1.default)(component).forEach(function (item) {
if (!checkIsObjectWithCodeBlock(item)) {
return;
}
let code = (0, convert_method_to_function_1.convertMethodToFunction)(item.code, methodMap, lexicalArgs);
Object.keys(replace).forEach((key) => {
code = code.replace(key, replace[key]);
});
item.code = code;
});
}
function getStateMethodsAndGetters(state) {
const methodMap = {};
Object.keys(state).forEach((key) => {
const stateVal = state[key];
if ((stateVal === null || stateVal === void 0 ? void 0 : stateVal.type) === 'getter' || (stateVal === null || stateVal === void 0 ? void 0 : stateVal.type) === 'method') {
methodMap[key] = stateVal.type;
}
});
return methodMap;
}
exports.getStateMethodsAndGetters = getStateMethodsAndGetters;
;