Add signal codegen for ReactiveScopes

Instead of emitting a memo block, emit a function expression and pass it as an
argument to derived (which will then create a computed).

The naming of 'derived' needs to be tweaked.
This commit is contained in:
Sathya Gunasekaran
2023-09-05 11:13:31 +01:00
parent 4571979e46
commit 2d3507b0e1
2 changed files with 51 additions and 1 deletions
@@ -185,6 +185,7 @@ export class Environment {
disableAllMemoization: boolean;
enableEmitFreeze: ExternalFunction | null;
assertValidMutableRanges: boolean;
enableForest: boolean;
#contextIdentifiers: Set<t.Identifier>;
@@ -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;
}
@@ -176,7 +176,7 @@ function wrapCacheDep(cx: Context, value: t.Expression): t.Expression {
}
}
function codegenReactiveScope(
function codegenMemoBlockForReactiveScope(
cx: Context,
statements: Array<t.Statement>,
scope: ReactiveScope,
@@ -319,6 +319,54 @@ function codegenReactiveScope(
statements.push(t.ifStatement(testCondition, computationBlock, memoBlock));
}
function codegenSignalBlockForReactiveScope(
cx: Context,
statements: Array<t.Statement>,
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<t.Statement>,
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