@joenoon/mobx-react-hooks
Version:
React Hooks for MobX
56 lines • 3.25 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
const babel_plugin_macros_1 = require("babel-plugin-macros");
const path_1 = __importDefault(require("path"));
function createUseObserver(config) {
return babel_plugin_macros_1.createMacro(function useObserverMacro({ references, state: { file: { opts: { filename } } }, babel: { types: t } }) {
// transform the importSource to a relative path if its not a library
let { importSource } = config;
if (path_1.default.isAbsolute(importSource)) {
importSource = `./${path_1.default.relative(path_1.default.dirname(filename), importSource)}`;
}
const { useObserver = [] } = references;
useObserver.forEach((referencePath) => {
// program is the top scope of the file
const program = referencePath.scope.getProgramParent().path;
const line = referencePath.getStatementParent();
if (line.key !== 0) {
throw new babel_plugin_macros_1.MacroError(`${path_1.default.basename(filename)}:${line.node.loc.start.line}: ` +
"useObserver() provided by the macro must be the first line of the FunctionComponent.");
}
// lineVars is the `{a, b}` in: const {a, b} = useObserver();
const lineVars = line.node.declarations ? line.node.declarations[0].id : null;
const lineArgs = referencePath.container.arguments;
// get all lines in the scope that follow. these get moved automatically
const linesAfter = line.container.splice(line.key + 1, line.container.length - line.key - 1);
// return a new function taking lineVars as args, containing linesAfter.
// the name `useObserverRenderHook` is not important.
line.insertAfter(t.returnStatement(t.callExpression(t.identifier(config.importSpecifier), [
t.functionExpression(t.identifier("useObserverRenderHook"), lineVars ? [lineVars] : [], t.blockStatement(linesAfter), false, false),
...lineArgs
])));
// remove the original line
line.remove();
// check to see if we've already added the real import line to this file
const foundImport = program.get("body").filter((x) => {
if (t.isImportDeclaration(x) && x.node.source.value === importSource) {
return (x.node.specifiers.filter((s) => s.local.name === config.importSpecifier).length > 0);
}
return false;
}).length > 0;
// if not, add it, i.e.:
// import { importSpecifier } from importSource
if (!foundImport) {
program.unshiftContainer("body", t.importDeclaration([
t.importSpecifier(t.identifier(config.importSpecifier), t.identifier(config.importSpecifier))
], t.stringLiteral(importSource)));
}
});
});
}
exports.createUseObserver = createUseObserver;
//# sourceMappingURL=createUseObserver.js.map
;