UNPKG

@builder.io/mitosis

Version:

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

89 lines (88 loc) 4.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateStateCode = exports.getStateTypeForValue = exports.getStateSetterName = void 0; const core_1 = require("@babel/core"); const function_1 = require("fp-ts/lib/function"); const capitalize_1 = require("../../../helpers/capitalize"); const replace_identifiers_1 = require("../../../helpers/replace-identifiers"); const strip_state_and_props_refs_1 = require("../../../helpers/strip-state-and-props-refs"); const transform_state_setters_1 = require("../../../helpers/transform-state-setters"); const getStateSetterName = (stateName) => `set${(0, capitalize_1.capitalize)(stateName)}`; exports.getStateSetterName = getStateSetterName; const getStateTypeForValue = ({ value, component, options, }) => { var _a, _b, _c, _d; // e.g. state.useContent?.blocks[0].id => useContent const extractStateSliceName = (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(value).split('.')[0].split('?')[0]; const stateOverrideForValue = (_d = (_c = (_b = (_a = component.meta) === null || _a === void 0 ? void 0 : _a.useMetadata) === null || _b === void 0 ? void 0 : _b.solid) === null || _c === void 0 ? void 0 : _c.state) === null || _d === void 0 ? void 0 : _d[extractStateSliceName]; const stateType = stateOverrideForValue || options.state; return stateType; }; exports.getStateTypeForValue = getStateTypeForValue; const getNewStateSetterExpression = (stateType) => ({ path, propertyName, }) => { /** * passes the value to the setter function * ```ts * // BEFORE * state.count = newCount * // AFTER * setCount(newCount) * ``` */ const callValueSetter = (args) => core_1.types.callExpression(core_1.types.identifier((0, exports.getStateSetterName)(propertyName)), [args]); switch (stateType) { case 'signals': return callValueSetter(path.node.right); case 'store': /** * Wrap value in a reconcile() call for Stores updates * ```ts * // BEFORE * state.count = newCount * // AFTER * setCount(reconcile(newCount)) * ``` */ return callValueSetter(core_1.types.callExpression(core_1.types.identifier('reconcile'), [path.node.right])); } }; const updateStateSettersInCode = ({ options, component }) => (value) => { const stateType = (0, exports.getStateTypeForValue)({ value, component, options }); switch (stateType) { case 'mutable': return value; case 'store': case 'signals': try { return (0, transform_state_setters_1.transformStateSetters)({ value, transformer: getNewStateSetterExpression(stateType), }); } catch (error) { console.error(`[Solid.js]: could not update state setters in ${stateType} code`, value); throw error; } } }; const updateStateGettersInCode = (options, component) => (0, replace_identifiers_1.replaceStateIdentifier)((name) => { const stateType = (0, exports.getStateTypeForValue)({ value: name, component, options }); const state = component.state[name]; switch (stateType) { case 'signals': if ( // signal accessors are lazy, so we need to add a function call to property calls (state === null || state === void 0 ? void 0 : state.type) === 'property' || // getters become plain functions, requiring a function call to access their value (state === null || state === void 0 ? void 0 : state.type) === 'getter') { return `${name}()`; } else { return name; } case 'store': case 'mutable': return name; } }); const updateStateCode = ({ options, component, updateSetters = true, }) => (0, function_1.flow)(updateSetters ? updateStateSettersInCode({ options, component }) : function_1.identity, updateStateGettersInCode(options, component), (x) => x.trim()); exports.updateStateCode = updateStateCode;