From 24a048979656902e2cab6c76d93a2ac585c5b816 Mon Sep 17 00:00:00 2001 From: Misael dos Santos Date: Mon, 25 Nov 2024 22:36:39 -0300 Subject: [PATCH 1/2] feat: directive $observe to wrap component in a Memo --- src/babel/observe | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/babel/observe diff --git a/src/babel/observe b/src/babel/observe new file mode 100644 index 00000000..f55e1ea6 --- /dev/null +++ b/src/babel/observe @@ -0,0 +1,71 @@ +const { addNamed } = require("@babel/helper-module-imports"); + +const OBSERVER_PROP = "$observe"; + +module.exports = function jcsPlugin(api) { + const { types: t } = api; + + let root = null; + let imported = false; + + const visitor = { + Program(path) { + root = path; + imported = false; + }, + JSXElement(path) { + const { openingElement } = path.node; + const ObserverIdentifier = t.jsxIdentifier("_Memo"); + + const removeDirectiveAttrs = () => + (openingElement.attributes = openingElement.attributes.filter( + (node) => node.name && !directives.includes(node.name.name) + )); + + const makeImports = () => { + if (root && !imported) { + addNamed(root, "Memo", "@legendapp/state/react"); + imported = true; + } + }; + + const hasObserver = openingElement.attributes.find( + (node) => node.name && node.name.name === OBSERVER_PROP + ); + + if (hasObserver) { + makeImports(); + removeDirectiveAttrs(); + path.replaceWith( + wrapInMemo({ + t, + ObserverIdentifier, + path, + }) + ); + } + }, + }; + + return { + visitor, + }; +}; + +const directives = [OBSERVER_PROP]; + +function wrapInMemo({ t, ObserverIdentifier, path, block = [] }) { + return t.jsxElement( + t.jsxOpeningElement(ObserverIdentifier, [], false), + t.jsxClosingElement(ObserverIdentifier), + [ + t.jsxExpressionContainer( + t.arrowFunctionExpression( + [], + t.blockStatement([...block, t.returnStatement(path.node)]) + ) + ), + ], + false + ); +} From 5a999897e6f56d00eb75c25c227842763ae812e0 Mon Sep 17 00:00:00 2001 From: Misael dos Santos Date: Mon, 25 Nov 2024 22:48:27 -0300 Subject: [PATCH 2/2] fix: extension renamed to ts (I forgot) --- src/babel/{observe => observe.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/babel/{observe => observe.ts} (100%) diff --git a/src/babel/observe b/src/babel/observe.ts similarity index 100% rename from src/babel/observe rename to src/babel/observe.ts