Skip to content

Commit

Permalink
various reactivity fixes and perf improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
XiNiHa committed Nov 11, 2024
1 parent 4f8d33b commit 155ffa4
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 68 deletions.
5 changes: 5 additions & 0 deletions .changeset/young-suits-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@contentstech/stackflow-plugin-omniflow": patch
---

Make child reactive
19 changes: 9 additions & 10 deletions example/src/stackflow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from "@contentstech/stackflow-solid/future";
import type { RegisteredActivityName } from "@stackflow/config";
import { type JSXElement, Show } from "solid-js";
import { unwrap } from "solid-js/store";
import config from "./config";

declare module "@stackflow/config" {
Expand Down Expand Up @@ -76,13 +75,13 @@ const components: Record<RegisteredActivityName, ActivityComponentType<any>> = {
</button>
<Show when={child !== undefined}>
<div class="border rounded p-2">
<p>Child ({child?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.render()}</div>
<p>Child ({child?.()?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.()?.render()}</div>
</div>
</Show>
</div>
<div class="min-h-0 h-full overflow-auto flex-1">
<pre>{JSON.stringify(unwrap(stack().activities), null, 2)}</pre>
<pre>{JSON.stringify(stack().activities, null, 2)}</pre>
</div>
</div>
);
Expand All @@ -103,8 +102,8 @@ const components: Record<RegisteredActivityName, ActivityComponentType<any>> = {
</Show>
<Show when={child !== undefined}>
<div class="border rounded p-2">
<p>Child ({child?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.render()}</div>
<p>Child ({child?.()?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.()?.render()}</div>
</div>
</Show>
<button
Expand Down Expand Up @@ -133,8 +132,8 @@ const components: Record<RegisteredActivityName, ActivityComponentType<any>> = {
</Show>
<Show when={child !== undefined}>
<div class="border rounded p-2">
<p>Child ({child?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.render()}</div>
<p>Child ({child?.()?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.()?.render()}</div>
</div>
</Show>
<button
Expand Down Expand Up @@ -163,8 +162,8 @@ const components: Record<RegisteredActivityName, ActivityComponentType<any>> = {
</Show>
<Show when={child !== undefined}>
<div class="border rounded p-2">
<p>Child ({child?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.render()}</div>
<p>Child ({child?.()?.name}) will be rendered here</p>
<div class="border border-red p-2 rounded">{child?.()?.render()}</div>
</div>
</Show>
<button
Expand Down
9 changes: 5 additions & 4 deletions src/child.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ export type Child = {
render: () => JSXElement;
};

const ChildContext = createContext<Child | null>();
const ChildContext = createContext<() => Child | null>();

export const ChildProvider: ContextProviderComponent<Child | null | undefined> =
ChildContext.Provider;
export const ChildProvider: ContextProviderComponent<
(() => Child | null) | undefined
> = ChildContext.Provider;

export const useChild = (): Child | null | undefined =>
export const useChild = (): (() => Child | null) | undefined =>
useContext(ChildContext);
109 changes: 55 additions & 54 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
Config,
} from "@stackflow/config";
import { type Activity, id } from "@stackflow/core";
import type { JSXElement } from "solid-js";
import { createMemo, type JSXElement } from "solid-js";
import { Dynamic, Show } from "solid-js/web";
import { ChildProvider } from "./child.js";
import { ParentProvider, useParent } from "./parent.js";
Expand Down Expand Up @@ -227,68 +227,69 @@ export function omniflow<ActivityName extends string>({
);
}

const child = () =>
components[props.childNameStack[0]] as
| ActivityComponentType<ActivityName>
| undefined;
const childParams = () => props.childParamsStack[0];
const childName = createMemo(() => props.childNameStack[0]);
const childComponent = createMemo(
() =>
components[childName()] as
| ActivityComponentType<ActivityName>
| undefined,
);
const childParams = createMemo(() => props.childParamsStack[0]);
const childValue = createMemo(() => {
const name = childName();
if (name == null) return null;
return {
name,
render: () => (
<Show when={childComponent()}>
{(child) => (
<ParentProvider
value={{
activityName: props.parentName,
activityParams: props.parentParams,
parent: useParent(),
}}
>
<Wrapped
parentName={childName()}
parentParams={childParams() ?? {}}
childNameStack={props.childNameStack.slice(1)}
childParamsStack={props.childParamsStack.slice(1)}
>
<Dynamic
component={child()}
params={childParams() ?? {}}
/>
</Wrapped>
</ParentProvider>
)}
</Show>
),
};
});

return (
<ChildProvider
value={
props.childNameStack[0] != null
? {
name: props.childNameStack[0],
render: () => (
<Show when={child()}>
{(child) => (
<ParentProvider
value={{
activityName: props.parentName,
activityParams: props.parentParams,
parent: useParent(),
}}
>
<Wrapped
parentName={props.childNameStack[0]}
parentParams={childParams() ?? {}}
childNameStack={props.childNameStack.slice(1)}
childParamsStack={props.childParamsStack.slice(1)}
>
<Dynamic
component={child()}
params={childParams() ?? {}}
/>
</Wrapped>
</ParentProvider>
)}
</Show>
),
}
: null
}
>
{props.children}
</ChildProvider>
<ChildProvider value={childValue}>{props.children}</ChildProvider>
);
}

const childName = createMemo(() => activity.params.OMNI_childName);
const childNameStack = createMemo(() => {
const name = childName();
return name ? (JSON.parse(name) as ActivityName[]) : [];
});
const childParams = createMemo(() => activity.params.OMNI_childParams);
const childParamsStack = createMemo(() => {
const params = childParams();
return params ? (JSON.parse(params) as ActivityBaseParams[]) : [];
});

return (
<Wrapped
parentName={activity.name as ActivityName}
parentParams={activity.params}
childNameStack={
activity.params.OMNI_childName
? (JSON.parse(activity.params.OMNI_childName) as ActivityName[])
: []
}
childParamsStack={
activity.params.OMNI_childParams
? (JSON.parse(
activity.params.OMNI_childParams,
) as ActivityBaseParams[])
: []
}
childNameStack={childNameStack()}
childParamsStack={childParamsStack()}
>
{activity.render()}
</Wrapped>
Expand Down

0 comments on commit 155ffa4

Please sign in to comment.