Skip to content

Commit 3a17dda

Browse files
Merge pull request #283 from RtlZeroMemory/codex/split-runtime-commit
refactor(core): split runtime commit pipeline by concern
2 parents 743e804 + 0921e82 commit 3a17dda

File tree

8 files changed

+1887
-1851
lines changed

8 files changed

+1887
-1851
lines changed

packages/core/src/runtime/commit.ts

Lines changed: 59 additions & 1851 deletions
Large diffs are not rendered by default.
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
import { describeThrown } from "../../debug/describeThrown.js";
2+
import type { ResponsiveViewportSnapshot } from "../../layout/responsive.js";
3+
import { defaultTheme } from "../../theme/defaultTheme.js";
4+
import { mergeThemeOverride } from "../../theme/interop.js";
5+
import type { Theme } from "../../theme/theme.js";
6+
import type { ColorTokens } from "../../theme/tokens.js";
7+
import {
8+
type CompositeWidgetMeta,
9+
type WidgetContext,
10+
getCompositeMeta,
11+
scopedId,
12+
} from "../../widgets/composition.js";
13+
import type { VNode } from "../../widgets/types.js";
14+
import type { InstanceId } from "../instance.js";
15+
import { type AppStateSelection, createHookContext } from "../instances.js";
16+
import { compositePropsEqual, evaluateAppStateSelections } from "./equality.js";
17+
import {
18+
type CommitContainerFn,
19+
type CommitCtx,
20+
type CommitNodeResult,
21+
EMPTY_CHILDREN,
22+
} from "./shared.js";
23+
import { isContainerVNode } from "./validation.js";
24+
25+
const MAX_COMPOSITE_RENDER_DEPTH = 100;
26+
const DEFAULT_VIEWPORT_SNAPSHOT: ResponsiveViewportSnapshot = Object.freeze({
27+
width: 0,
28+
height: 0,
29+
breakpoint: "sm",
30+
});
31+
32+
export function currentCompositeTheme(ctx: CommitCtx): Theme | null {
33+
if (ctx.compositeThemeStack.length === 0) return null;
34+
return ctx.compositeThemeStack[ctx.compositeThemeStack.length - 1] ?? null;
35+
}
36+
37+
export function resolveCompositeChildTheme(parentTheme: Theme, vnode: VNode): Theme {
38+
if (vnode.kind === "themed") {
39+
const props = vnode.props as { theme?: unknown };
40+
return mergeThemeOverride(parentTheme, props.theme);
41+
}
42+
43+
if (
44+
vnode.kind === "row" ||
45+
vnode.kind === "column" ||
46+
vnode.kind === "grid" ||
47+
vnode.kind === "box"
48+
) {
49+
const props = vnode.props as { theme?: unknown };
50+
return mergeThemeOverride(parentTheme, props.theme);
51+
}
52+
53+
return parentTheme;
54+
}
55+
56+
export function readCompositeColorTokens(ctx: CommitCtx): ColorTokens {
57+
const composite = ctx.composite;
58+
if (!composite) return defaultTheme.definition.colors;
59+
60+
const theme = currentCompositeTheme(ctx);
61+
if (theme !== null) {
62+
if (!composite.getColorTokens) return theme.definition.colors;
63+
return composite.getColorTokens(theme) ?? theme.definition.colors;
64+
}
65+
66+
return composite.colorTokens ?? defaultTheme.definition.colors;
67+
}
68+
69+
export function executeCompositeRender(
70+
instanceId: InstanceId,
71+
vnode: VNode,
72+
compositeMeta: CompositeWidgetMeta,
73+
ctx: CommitCtx,
74+
nodePath: string[],
75+
depth: number,
76+
commitContainer: CommitContainerFn,
77+
): CommitNodeResult {
78+
const prev =
79+
ctx.prevNodeStack.length > 0 ? (ctx.prevNodeStack[ctx.prevNodeStack.length - 1] ?? null) : null;
80+
const compositeRuntime = ctx.composite as NonNullable<CommitCtx["composite"]>;
81+
82+
let compositeChild: VNode | null = null;
83+
let popCompositeStack = false;
84+
try {
85+
const activeCompositeMeta = compositeMeta;
86+
const registry = compositeRuntime.registry;
87+
const existing = registry.get(instanceId);
88+
89+
if (existing && existing.widgetKey !== compositeMeta.widgetKey) {
90+
registry.incrementGeneration(instanceId);
91+
registry.delete(instanceId);
92+
}
93+
94+
if (!registry.get(instanceId)) {
95+
try {
96+
registry.create(instanceId, compositeMeta.widgetKey);
97+
} catch (e: unknown) {
98+
return {
99+
ok: false,
100+
fatal: {
101+
code: "ZRUI_USER_CODE_THROW",
102+
detail: describeThrown(e),
103+
},
104+
};
105+
}
106+
}
107+
108+
const state = registry.get(instanceId);
109+
if (!state) {
110+
return {
111+
ok: false,
112+
fatal: {
113+
code: "ZRUI_INVALID_PROPS",
114+
detail: `composite state missing for instanceId=${String(instanceId)}`,
115+
},
116+
};
117+
}
118+
119+
const invalidateInstance = () => {
120+
registry.invalidate(instanceId);
121+
ctx.composite?.onInvalidate(instanceId);
122+
};
123+
124+
const prevMeta = prev ? getCompositeMeta(prev.vnode) : null;
125+
const prevChild = prev?.children[0] ?? null;
126+
const previousSelections = registry.getAppStateSelections(instanceId);
127+
const skipRenderEligible =
128+
!state.needsRender &&
129+
previousSelections.length > 0 &&
130+
prevMeta !== null &&
131+
prevChild !== null &&
132+
prevMeta.widgetKey === activeCompositeMeta.widgetKey &&
133+
compositePropsEqual(prevMeta.props, activeCompositeMeta.props);
134+
135+
let canSkipCompositeRender = false;
136+
if (skipRenderEligible) {
137+
const evalRes = evaluateAppStateSelections(previousSelections, compositeRuntime.appState);
138+
if (evalRes.threw !== null) {
139+
return {
140+
ok: false,
141+
fatal: {
142+
code: "ZRUI_USER_CODE_THROW",
143+
detail: describeThrown(evalRes.threw),
144+
},
145+
};
146+
}
147+
canSkipCompositeRender = !evalRes.changed;
148+
}
149+
150+
if (canSkipCompositeRender && prevChild !== null) {
151+
compositeChild = prevChild.vnode;
152+
} else {
153+
let colorTokens: ColorTokens;
154+
try {
155+
colorTokens = readCompositeColorTokens(ctx);
156+
} catch (e: unknown) {
157+
return {
158+
ok: false,
159+
fatal: {
160+
code: "ZRUI_USER_CODE_THROW",
161+
detail: describeThrown(e),
162+
},
163+
};
164+
}
165+
const compositeDepth = ctx.compositeRenderStack.length + 1;
166+
if (compositeDepth > MAX_COMPOSITE_RENDER_DEPTH) {
167+
const chain = ctx.compositeRenderStack
168+
.map((entry) => entry.widgetKey)
169+
.concat(activeCompositeMeta.widgetKey)
170+
.join(" -> ");
171+
return {
172+
ok: false,
173+
fatal: {
174+
code: "ZRUI_INVALID_PROPS",
175+
detail: `ZRUI_MAX_DEPTH: composite render depth ${String(compositeDepth)} exceeds max ${String(
176+
MAX_COMPOSITE_RENDER_DEPTH,
177+
)}. Chain: ${chain}`,
178+
},
179+
};
180+
}
181+
registry.beginRender(instanceId);
182+
const hookCtx = createHookContext(state, invalidateInstance);
183+
const nextSelections: AppStateSelection[] = [];
184+
const widgetCtx: WidgetContext<unknown> = Object.freeze({
185+
id: (suffix: string) => scopedId(activeCompositeMeta.widgetKey, instanceId, suffix),
186+
useState: hookCtx.useState,
187+
useReducer: hookCtx.useReducer,
188+
useRef: hookCtx.useRef,
189+
useEffect: hookCtx.useEffect,
190+
useMemo: hookCtx.useMemo,
191+
useCallback: hookCtx.useCallback,
192+
useAppState: <T>(selector: (s: unknown) => T): T => {
193+
const selected = selector(compositeRuntime.appState);
194+
nextSelections.push({
195+
selector: selector as (state: unknown) => unknown,
196+
value: selected,
197+
});
198+
return selected;
199+
},
200+
useTheme: () => colorTokens,
201+
useViewport: () => {
202+
compositeRuntime.onUseViewport?.();
203+
return compositeRuntime.viewport ?? DEFAULT_VIEWPORT_SNAPSHOT;
204+
},
205+
invalidate: invalidateInstance,
206+
});
207+
208+
ctx.compositeRenderStack.push({
209+
widgetKey: activeCompositeMeta.widgetKey,
210+
instanceId,
211+
});
212+
popCompositeStack = true;
213+
try {
214+
compositeChild = activeCompositeMeta.render(widgetCtx);
215+
} catch (e: unknown) {
216+
return {
217+
ok: false,
218+
fatal: {
219+
code: "ZRUI_USER_CODE_THROW",
220+
detail: describeThrown(e),
221+
},
222+
};
223+
}
224+
225+
try {
226+
const pending = registry.endRender(instanceId);
227+
const pendingCleanups = registry.getPendingCleanups(instanceId);
228+
for (const cleanup of pendingCleanups) ctx.pendingCleanups.push(cleanup);
229+
for (const eff of pending) ctx.pendingEffects.push(eff);
230+
registry.setAppStateSelections(instanceId, nextSelections);
231+
} catch (e: unknown) {
232+
return {
233+
ok: false,
234+
fatal: {
235+
code: "ZRUI_USER_CODE_THROW",
236+
detail: describeThrown(e),
237+
},
238+
};
239+
}
240+
}
241+
242+
if (isContainerVNode(vnode)) {
243+
const childOverride = compositeChild ? ([compositeChild] as const) : null;
244+
if (childOverride) {
245+
ctx.containerChildOverrides.set(instanceId, childOverride);
246+
}
247+
try {
248+
return commitContainer(instanceId, vnode, prev, ctx, nodePath, depth);
249+
} finally {
250+
if (childOverride) {
251+
ctx.containerChildOverrides.delete(instanceId);
252+
}
253+
}
254+
}
255+
256+
return {
257+
ok: true,
258+
value: {
259+
root: {
260+
instanceId,
261+
vnode,
262+
children: EMPTY_CHILDREN,
263+
dirty: true,
264+
selfDirty: true,
265+
renderPacketKey: 0,
266+
renderPacket: null,
267+
},
268+
},
269+
};
270+
} finally {
271+
if (popCompositeStack) {
272+
ctx.compositeRenderStack.pop();
273+
}
274+
}
275+
}

0 commit comments

Comments
 (0)