Skip to content

Commit c826d94

Browse files
committed
Add interactive Workflow Message Passing demo
1 parent 59e1e10 commit c826d94

12 files changed

Lines changed: 3938 additions & 0 deletions
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
id: workflow-message-passing-demo
3+
title: Workflow Message Passing - Interactive Demo
4+
sidebar_label: Workflow Message Passing
5+
description: An interactive walkthrough of Temporal Workflow message passing — Signals, Queries, and Updates — what they are, how they work, and how to build with them.
6+
slug: /workflow-message-passing-demo
7+
tags:
8+
- Workflow
9+
- Signals
10+
- Queries
11+
- Updates
12+
keywords:
13+
- temporal workflow message passing
14+
- signals queries updates
15+
- workflow messaging demo
16+
- temporal interactive
17+
hide_table_of_contents: true
18+
---
19+
20+
import WorkflowMessagingDemo from '@site/src/components/WorkflowMessagingDemo';
21+
22+
<WorkflowMessagingDemo />
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
import React, { useState } from 'react';
2+
import styles from './WorkflowMessagingDemo.module.css';
3+
import {
4+
LANGUAGES,
5+
MESSAGE_TYPE_DATA,
6+
type LangId,
7+
type MessageTypeId,
8+
} from './buildData';
9+
10+
type Props = { onNext: () => void };
11+
12+
const MESSAGE_TABS: { id: MessageTypeId; label: string }[] = [
13+
{ id: 'signal', label: 'Signal' },
14+
{ id: 'query', label: 'Query' },
15+
{ id: 'update', label: 'Update' },
16+
];
17+
18+
/* ── Line-highlighted code pane ── */
19+
function CodePane({
20+
title,
21+
code,
22+
activeLines,
23+
accentColor,
24+
}: {
25+
title: string;
26+
code: string;
27+
activeLines: Set<number>;
28+
accentColor: string;
29+
}) {
30+
const lines = code.split('\n');
31+
const hasActive = activeLines.size > 0;
32+
33+
return (
34+
<div style={{ minWidth: 0 }}>
35+
<div
36+
style={{
37+
fontSize: 11,
38+
fontWeight: 600,
39+
color: 'var(--nd-muted)',
40+
textTransform: 'uppercase',
41+
letterSpacing: '0.06em',
42+
marginBottom: 6,
43+
}}
44+
>
45+
{title}
46+
</div>
47+
<div
48+
style={{
49+
background: 'var(--nd-surface)',
50+
border: '1px solid var(--nd-border)',
51+
borderRadius: 8,
52+
overflow: 'auto',
53+
maxHeight: 480,
54+
}}
55+
>
56+
<pre
57+
style={{
58+
margin: 0,
59+
padding: '14px 0',
60+
fontSize: 12,
61+
fontFamily: 'var(--ifm-font-family-monospace)',
62+
lineHeight: 1.65,
63+
}}
64+
>
65+
{lines.map((line, i) => {
66+
const lineNum = i + 1;
67+
const isActive = activeLines.has(lineNum);
68+
return (
69+
<div
70+
key={i}
71+
style={{
72+
padding: '1px 16px',
73+
borderLeft: isActive
74+
? `3px solid ${accentColor}`
75+
: '3px solid transparent',
76+
background: isActive
77+
? `color-mix(in srgb, ${accentColor} 14%, transparent)`
78+
: 'transparent',
79+
opacity: hasActive && !isActive ? 0.28 : 1,
80+
transition: 'opacity 0.15s ease, background 0.15s ease',
81+
whiteSpace: 'pre',
82+
color: 'var(--ifm-font-color-base)',
83+
}}
84+
>
85+
{line || ' '}
86+
</div>
87+
);
88+
})}
89+
</pre>
90+
</div>
91+
</div>
92+
);
93+
}
94+
95+
export default function BuildIt({ onNext }: Props) {
96+
const [msgType, setMsgType] = useState<MessageTypeId>('signal');
97+
const [lang, setLang] = useState<LangId>('python');
98+
const [activeAnnotation, setActiveAnnotation] = useState<number | null>(null);
99+
100+
function selectMsgType(id: MessageTypeId) {
101+
setMsgType(id);
102+
setActiveAnnotation(null);
103+
}
104+
105+
function selectLang(id: LangId) {
106+
setLang(id);
107+
setActiveAnnotation(null);
108+
}
109+
110+
function toggleAnnotation(i: number) {
111+
setActiveAnnotation((prev) => (prev === i ? null : i));
112+
}
113+
114+
const data = MESSAGE_TYPE_DATA[msgType];
115+
const langCode = data.code[lang];
116+
const ann = activeAnnotation !== null ? data.annotations[activeAnnotation] : null;
117+
const annLines = ann?.lines[lang];
118+
const wfLines = new Set(annLines?.workflowLines ?? []);
119+
const clientLines = new Set(annLines?.clientLines ?? []);
120+
121+
return (
122+
<div className={styles.section}>
123+
<div className={styles.progressBar}>
124+
<div className={styles.progressFill} style={{ width: '80%' }} />
125+
</div>
126+
127+
<h1>Build It</h1>
128+
<p className={styles.lead}>
129+
Code examples for all five SDKs. Select a message type and language, then click an
130+
annotation to highlight the relevant lines.
131+
</p>
132+
133+
{/* Message type tabs */}
134+
<div className={styles.runTabs} style={{ marginBottom: 8 }}>
135+
{MESSAGE_TABS.map((t) => (
136+
<button
137+
key={t.id}
138+
className={`${styles.runTab} ${msgType === t.id ? styles.runTabActive : ''}`}
139+
onClick={() => selectMsgType(t.id)}
140+
>
141+
{t.label}
142+
</button>
143+
))}
144+
</div>
145+
146+
{/* Language tabs */}
147+
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 16 }}>
148+
{LANGUAGES.map((l) => (
149+
<button
150+
key={l.id}
151+
onClick={() => selectLang(l.id)}
152+
style={{
153+
padding: '4px 12px',
154+
borderRadius: 6,
155+
border: `1px solid ${lang === l.id ? data.accentColor : 'var(--nd-border)'}`,
156+
background: lang === l.id
157+
? `color-mix(in srgb, ${data.accentColor} 12%, transparent)`
158+
: 'transparent',
159+
color: lang === l.id ? data.accentColor : 'var(--nd-muted)',
160+
fontSize: 12,
161+
fontWeight: lang === l.id ? 600 : 400,
162+
cursor: 'pointer',
163+
transition: 'all 0.12s ease',
164+
}}
165+
>
166+
{l.label}
167+
</button>
168+
))}
169+
</div>
170+
171+
<p style={{ fontSize: 14, color: 'var(--ifm-font-color-base)', margin: '0 0 16px', lineHeight: 1.7 }}>
172+
{data.description}
173+
</p>
174+
175+
{/* Two-column code view */}
176+
<div
177+
style={{
178+
display: 'grid',
179+
gridTemplateColumns: '1fr 1fr',
180+
gap: 12,
181+
marginBottom: 16,
182+
}}
183+
>
184+
<CodePane
185+
title="Workflow definition"
186+
code={langCode.workflowCode}
187+
activeLines={wfLines}
188+
accentColor={data.accentColor}
189+
/>
190+
<CodePane
191+
title="Client code"
192+
code={langCode.clientCode}
193+
activeLines={clientLines}
194+
accentColor={data.accentColor}
195+
/>
196+
</div>
197+
198+
{/* Annotation pills */}
199+
<div style={{ marginBottom: 8 }}>
200+
<div
201+
style={{
202+
fontSize: 11,
203+
fontWeight: 600,
204+
color: 'var(--nd-muted)',
205+
textTransform: 'uppercase',
206+
letterSpacing: '0.06em',
207+
marginBottom: 8,
208+
}}
209+
>
210+
Highlight a concept
211+
</div>
212+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
213+
{data.annotations.map((a, i) => {
214+
const isActive = activeAnnotation === i;
215+
return (
216+
<button
217+
key={i}
218+
onClick={() => toggleAnnotation(i)}
219+
style={{
220+
padding: '6px 14px',
221+
borderRadius: 20,
222+
border: `1px solid ${isActive ? data.accentColor : 'var(--nd-border)'}`,
223+
background: isActive
224+
? `color-mix(in srgb, ${data.accentColor} 15%, transparent)`
225+
: 'var(--nd-surface)',
226+
color: isActive ? data.accentColor : 'var(--ifm-font-color-base)',
227+
fontSize: 12,
228+
fontWeight: isActive ? 600 : 400,
229+
cursor: 'pointer',
230+
transition: 'all 0.15s ease',
231+
}}
232+
>
233+
{a.label}
234+
</button>
235+
);
236+
})}
237+
</div>
238+
</div>
239+
240+
{/* Annotation description box */}
241+
<div
242+
style={{
243+
minHeight: 52,
244+
padding: ann ? '12px 16px' : '0',
245+
background: ann
246+
? `color-mix(in srgb, ${data.accentColor} 8%, transparent)`
247+
: 'transparent',
248+
border: ann
249+
? `1px solid color-mix(in srgb, ${data.accentColor} 50%, transparent)`
250+
: '1px solid transparent',
251+
borderRadius: 8,
252+
transition: 'all 0.15s ease',
253+
marginBottom: 16,
254+
}}
255+
>
256+
{ann && (
257+
<p style={{ margin: 0, fontSize: 13, color: 'var(--ifm-font-color-base)', lineHeight: 1.7 }}>
258+
{ann.description}
259+
</p>
260+
)}
261+
</div>
262+
263+
<div className={styles.buildNote}>{data.note}</div>
264+
265+
<div className={styles.nextRow}>
266+
<button className={styles.btn} onClick={onNext}>
267+
Next: Test Yourself →
268+
</button>
269+
</div>
270+
</div>
271+
);
272+
}

0 commit comments

Comments
 (0)