diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts index c89fe379a2..ffd4d43ae7 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts @@ -185,6 +185,7 @@ export class Environment { disableAllMemoization: boolean; enableEmitFreeze: ExternalFunction | null; assertValidMutableRanges: boolean; + enableForest: boolean; #contextIdentifiers: Set; @@ -233,6 +234,7 @@ export class Environment { this.assertValidMutableRanges = config?.assertValidMutableRanges ?? false; this.validateNoSetStateInRender = config?.validateNoSetStateInRender ?? false; + this.enableForest = config?.enableForest ?? false; this.#contextIdentifiers = contextIdentifiers; } diff --git a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts index 9eccb4a8ac..aa249e6577 100644 --- a/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -176,7 +176,7 @@ function wrapCacheDep(cx: Context, value: t.Expression): t.Expression { } } -function codegenReactiveScope( +function codegenMemoBlockForReactiveScope( cx: Context, statements: Array, scope: ReactiveScope, @@ -319,6 +319,54 @@ function codegenReactiveScope( statements.push(t.ifStatement(testCondition, computationBlock, memoBlock)); } +function codegenSignalBlockForReactiveScope( + cx: Context, + statements: Array, + scope: ReactiveScope, + block: ReactiveBlock +): void { + CompilerError.invariant(scope.reassignments.size === 0, { + reason: "Add support for reassignments in a derived computation block", + loc: null, + suggestions: null, + }); + CompilerError.invariant(scope.declarations.size === 1, { + reason: + "Add support for multiple declarations in a derived computation block", + loc: null, + suggestions: null, + }); + const [_, { identifier }] = [...scope.declarations][0]; + const name = convertIdentifier(identifier); + + const derivedBlock = codegenBlock(cx, block); + derivedBlock.body.push(t.returnStatement(name)); + + const derivedLambda = t.functionExpression(null, [], derivedBlock, false); + const derivedComputationCall = t.callExpression(t.identifier("derived"), [ + derivedLambda, + ]); + + statements.push( + t.variableDeclaration("const", [ + t.variableDeclarator(name, derivedComputationCall), + ]) + ); +} + +function codegenReactiveScope( + cx: Context, + statements: Array, + scope: ReactiveScope, + block: ReactiveBlock +): void { + if (cx.env.enableForest) { + codegenSignalBlockForReactiveScope(cx, statements, scope, block); + } else { + codegenMemoBlockForReactiveScope(cx, statements, scope, block); + } +} + function codegenTerminal( cx: Context, terminal: ReactiveTerminal