1- import React from 'react' ;
1+ import React , { useState } from 'react' ;
22import styles from './NexusDemo.module.css' ;
33
44type Props = { onNext : ( ) => void } ;
55
6- const components = [
7- {
8- tag : 'tagBlue' as const ,
9- tagLabel : 'Endpoint' ,
10- title : 'Nexus Endpoint' ,
11- desc : 'A named, versioned router configured in the Temporal control plane. It maps a name (e.g. "fraud-service-endpoint") to a target namespace and task queue. This is the only thing Team A needs to know about Team B\'s infrastructure.' ,
12- example : '"my-nexus-endpoint"' ,
13- } ,
14- {
15- tag : 'tagPurple' as const ,
16- tagLabel : 'Service' ,
17- title : 'Nexus Service' ,
18- desc : 'A named collection of operations defined by an interface (Go) or decorated class (TypeScript, .NET). Think of it like a gRPC service definition or a typed REST API contract — it describes what\'s callable without exposing how.' ,
19- example : '[NexusService] IHelloService' ,
20- } ,
21- {
22- tag : 'tagGreen' as const ,
23- tagLabel : 'Operation' ,
24- title : 'Nexus Operation' ,
25- desc : 'A single callable unit within a service. Operations are either synchronous (run inline, return in < 10s) or asynchronous (start a Temporal Workflow, can run for days). The caller\'s code looks the same either way — just await the result.' ,
26- example : 'Echo() | SayHello()' ,
27- } ,
28- {
29- tag : 'tagBlue' as const ,
30- tagLabel : 'Registry' ,
31- title : 'Nexus Registry' ,
32- desc : 'The Temporal Cloud control plane (or OSS server config) that stores endpoint definitions, access policies, and routing rules. Admins configure which caller namespaces can reach which handler namespaces through which endpoints.' ,
33- example : 'Temporal Cloud UI / tcld' ,
34- } ,
35- ] ;
36-
376export default function ComponentsSection ( { onNext } : Props ) {
7+ const [ opTab , setOpTab ] = useState < 'sync' | 'async' > ( 'sync' ) ;
8+
389 return (
3910 < div className = { styles . section } >
4011 < div className = { styles . progressBar } >
@@ -43,33 +14,163 @@ export default function ComponentsSection({ onNext }: Props) {
4314
4415 < h1 > The Four Building Blocks</ h1 >
4516 < p className = { styles . lead } >
46- Nexus is composed of four concepts. Once you understand these, the rest falls into place .
17+ Nexus has four key concepts. These four concepts are the foundation of everything in Nexus .
4718 </ p >
4819
49- < div className = { styles . cardGrid } >
50- { components . map ( ( c ) => (
51- < div key = { c . title } className = { styles . card } >
52- < div className = { `${ styles . tag } ${ styles [ c . tag ] } ` } > { c . tagLabel } </ div >
53- < h3 style = { { fontSize : 15 , marginBottom : 8 } } > { c . title } </ h3 >
54- < p style = { { fontSize : 13 , color : 'var(--nd-muted)' , margin : '0 0 10px' , lineHeight : 1.6 } } >
55- { c . desc }
56- </ p >
57- < code
58- style = { {
59- fontSize : 11 ,
60- color : 'var(--nd-muted)' ,
61- background : 'var(--nd-surface2)' ,
62- padding : '2px 6px' ,
63- borderRadius : 4 ,
64- } }
20+ < div className = { styles . componentLayout } >
21+
22+ { /* 1 — Endpoint */ }
23+ < div className = { styles . card } style = { { borderLeft : '4px solid var(--ifm-color-primary)' } } >
24+ < div className = { styles . componentRow } >
25+ < div
26+ className = { styles . componentNum }
27+ style = { { background : 'var(--nd-primary-bg)' , color : 'var(--ifm-color-primary)' } }
28+ >
29+ 1
30+ </ div >
31+ < div className = { styles . componentContent } >
32+ < h2 className = { styles . componentTitle } > Nexus Endpoint</ h2 >
33+ < p className = { styles . componentRole } > The address you publish and route through</ p >
34+ < p >
35+ Think of an Endpoint like a < strong > URL for your team's services</ strong > . It's a
36+ named entry point registered in the Nexus Registry that routes requests to a
37+ specific namespace and task queue.
38+ </ p >
39+ < p >
40+ It's < em > not</ em > a general HTTP proxy — it's specifically designed for Nexus, with
41+ built-in auth, retries, and observability.
42+ </ p >
43+ < div className = { styles . componentCode } >
44+ Endpoint:{ ' ' }
45+ < span style = { { color : 'var(--ifm-color-primary)' } } > fraud-detection-prod</ span >
46+ < br />
47+ Routes to:{ ' ' }
48+ < span style = { { color : 'var(--nd-purple)' } } > fraud-ns / fraud-task-queue</ span >
49+ </ div >
50+ </ div >
51+ </ div >
52+ </ div >
53+
54+ { /* 2 — Service */ }
55+ < div className = { styles . card } style = { { borderLeft : '4px solid var(--nd-purple)' } } >
56+ < div className = { styles . componentRow } >
57+ < div
58+ className = { styles . componentNum }
59+ style = { { background : 'var(--nd-purple-bg)' , color : 'var(--nd-purple)' } }
6560 >
66- { c . example }
67- </ code >
61+ 2
62+ </ div >
63+ < div className = { styles . componentContent } >
64+ < h2 className = { styles . componentTitle } > Nexus Service</ h2 >
65+ < p className = { styles . componentRole } > The contract you publish for others to consume</ p >
66+ < p >
67+ A Service is a < strong > named collection of Nexus Operations</ strong > — like an API
68+ interface. Multiple services can run in the same worker. Callers import the service
69+ definition to get type safety.
70+ </ p >
71+ < p >
72+ Example:{ ' ' }
73+ < code style = { { color : 'var(--nd-purple)' } } > fraud.v1</ code > service exposes{ ' ' }
74+ < code > checkTransaction</ code > , < code > flagUser</ code > , and < code > getScore</ code > { ' ' }
75+ operations.
76+ </ p >
77+ </ div >
6878 </ div >
69- ) ) }
79+ </ div >
80+
81+ { /* 3 — Operation */ }
82+ < div className = { styles . card } style = { { borderLeft : '4px solid var(--nd-green)' } } >
83+ < div className = { styles . componentRow } >
84+ < div
85+ className = { styles . componentNum }
86+ style = { { background : 'var(--nd-green-bg)' , color : 'var(--nd-green)' } }
87+ >
88+ 3
89+ </ div >
90+ < div className = { styles . componentContent } >
91+ < h2 className = { styles . componentTitle } > Nexus Operation</ h2 >
92+ < p className = { styles . componentRole } > The individual action — sync or async</ p >
93+
94+ < div className = { styles . opTabs } >
95+ < button
96+ className = { `${ styles . opTab } ${ opTab === 'sync' ? styles . opTabActive : '' } ` }
97+ onClick = { ( ) => setOpTab ( 'sync' ) }
98+ >
99+ Synchronous
100+ </ button >
101+ < button
102+ className = { `${ styles . opTab } ${ opTab === 'async' ? styles . opTabActive : '' } ` }
103+ onClick = { ( ) => setOpTab ( 'async' ) }
104+ >
105+ Asynchronous
106+ </ button >
107+ </ div >
108+
109+ { opTab === 'sync' ? (
110+ < >
111+ < p >
112+ < strong > Synchronous</ strong > operations complete in under 10 seconds. The
113+ result comes back in the same HTTP round-trip. Great for quick lookups, scoring,
114+ or validations.
115+ </ p >
116+ < div className = { styles . componentCode } >
117+ Caller → [Nexus RPC] → Handler → result → Caller
118+ < br />
119+ Duration: milliseconds to <10 seconds
120+ </ div >
121+ </ >
122+ ) : (
123+ < >
124+ < p >
125+ < strong > Asynchronous</ strong > operations start a Workflow and return an
126+ operation token. The caller workflow is suspended. When the handler workflow
127+ completes, a callback delivers the result.
128+ </ p >
129+ < div className = { styles . componentCode } >
130+ Caller → [start] → Handler starts Workflow → [token]
131+ < br />
132+ ...time passes (up to 60 days)...
133+ < br />
134+ Handler Workflow completes → [callback] → Caller resumes
135+ </ div >
136+ </ >
137+ ) }
138+ </ div >
139+ </ div >
140+ </ div >
141+
142+ { /* 4 — Registry */ }
143+ < div className = { styles . card } style = { { borderLeft : '4px solid var(--nd-amber)' } } >
144+ < div className = { styles . componentRow } >
145+ < div
146+ className = { styles . componentNum }
147+ style = { { background : 'var(--nd-amber-bg)' , color : 'var(--nd-amber)' } }
148+ >
149+ 4
150+ </ div >
151+ < div className = { styles . componentContent } >
152+ < h2 className = { styles . componentTitle } > Nexus Registry</ h2 >
153+ < p className = { styles . componentRole } > The directory of all Endpoints in your account</ p >
154+ < p >
155+ Scoped to your Temporal Cloud account or self-hosted cluster. Teams register
156+ Endpoints here. The Registry is the source of truth for endpoint discovery, access
157+ control, and audit logging.
158+ </ p >
159+ < div className = { styles . componentPills } >
160+ < div className = { styles . componentPill } > fraud-detection-prod</ div >
161+ < div className = { styles . componentPill } > kyc-verification-v2</ div >
162+ < div className = { styles . componentPill } > notifications-global</ div >
163+ < div className = { `${ styles . componentPill } ${ styles . componentPillNew } ` } >
164+ + register new
165+ </ div >
166+ </ div >
167+ </ div >
168+ </ div >
169+ </ div >
170+
70171 </ div >
71172
72- < h2 className = { styles . sectionHeading } > Nexus vs. the Alternatives</ h2 >
173+ < h2 className = { styles . sectionHeading } style = { { marginTop : 32 } } > Nexus vs. the Alternatives</ h2 >
73174 < table className = { styles . table } >
74175 < thead >
75176 < tr >
@@ -83,57 +184,18 @@ export default function ComponentsSection({ onNext }: Props) {
83184 </ thead >
84185 < tbody >
85186 { [
86- {
87- name : 'Shared namespace' ,
88- durable : true ,
89- typed : false ,
90- cross : false ,
91- retry : true ,
92- cancel : false ,
93- } ,
94- {
95- name : 'HTTP between teams' ,
96- durable : false ,
97- typed : false ,
98- cross : true ,
99- retry : false ,
100- cancel : false ,
101- } ,
102- {
103- name : 'Child workflows' ,
104- durable : true ,
105- typed : true ,
106- cross : false ,
107- retry : true ,
108- cancel : true ,
109- } ,
110- {
111- name : 'Temporal Nexus' ,
112- durable : true ,
113- typed : true ,
114- cross : true ,
115- retry : true ,
116- cancel : true ,
117- highlight : true ,
118- } ,
187+ { name : 'Shared namespace' , durable : true , typed : false , cross : false , retry : true , cancel : false } ,
188+ { name : 'HTTP between teams' , durable : false , typed : false , cross : true , retry : false , cancel : false } ,
189+ { name : 'Child workflows' , durable : true , typed : true , cross : false , retry : true , cancel : true } ,
190+ { name : 'Temporal Nexus' , durable : true , typed : true , cross : true , retry : true , cancel : true , highlight : true } ,
119191 ] . map ( ( row ) => (
120192 < tr key = { row . name } style = { row . highlight ? { background : 'var(--nd-primary-bg)' } : { } } >
121193 < td style = { { fontWeight : row . highlight ? 700 : 400 } } > { row . name } </ td >
122- < td className = { row . durable ? styles . check : styles . cross } >
123- { row . durable ? '✓' : '—' }
124- </ td >
125- < td className = { row . typed ? styles . check : styles . cross } >
126- { row . typed ? '✓' : '—' }
127- </ td >
128- < td className = { row . cross ? styles . check : styles . cross } >
129- { row . cross ? '✓' : '—' }
130- </ td >
131- < td className = { row . retry ? styles . check : styles . cross } >
132- { row . retry ? '✓' : '—' }
133- </ td >
134- < td className = { row . cancel ? styles . check : styles . cross } >
135- { row . cancel ? '✓' : '—' }
136- </ td >
194+ < td className = { row . durable ? styles . check : styles . cross } > { row . durable ? '✓' : '—' } </ td >
195+ < td className = { row . typed ? styles . check : styles . cross } > { row . typed ? '✓' : '—' } </ td >
196+ < td className = { row . cross ? styles . check : styles . cross } > { row . cross ? '✓' : '—' } </ td >
197+ < td className = { row . retry ? styles . check : styles . cross } > { row . retry ? '✓' : '—' } </ td >
198+ < td className = { row . cancel ? styles . check : styles . cross } > { row . cancel ? '✓' : '—' } </ td >
137199 </ tr >
138200 ) ) }
139201 </ tbody >
0 commit comments