Skip to content

Commit 78963bc

Browse files
committed
Added tutorial html reference directory
1 parent 57cd18b commit 78963bc

File tree

1 file changed

+357
-0
lines changed

1 file changed

+357
-0
lines changed
Lines changed: 357 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>DAO to Sink Flow</title>
7+
<style>
8+
body {
9+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10+
max-width: 1200px;
11+
margin: 40px auto;
12+
padding: 20px;
13+
background: #f5f5f5;
14+
}
15+
16+
.container {
17+
background: white;
18+
border-radius: 12px;
19+
padding: 30px;
20+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
21+
margin-bottom: 30px;
22+
}
23+
24+
h1 {
25+
color: #2c3e50;
26+
margin-top: 0;
27+
border-bottom: 3px solid #3498db;
28+
padding-bottom: 10px;
29+
}
30+
31+
h2 {
32+
color: #34495e;
33+
margin-top: 30px;
34+
font-size: 1.3em;
35+
}
36+
37+
.diagram {
38+
margin: 30px 0;
39+
overflow-x: auto;
40+
}
41+
42+
svg {
43+
display: block;
44+
margin: 0 auto;
45+
}
46+
47+
.box {
48+
cursor: pointer;
49+
transition: all 0.3s;
50+
}
51+
52+
.box:hover rect {
53+
filter: brightness(0.9);
54+
}
55+
56+
.arrow {
57+
fill: none;
58+
stroke: #34495e;
59+
stroke-width: 2;
60+
marker-end: url(#arrowhead);
61+
}
62+
63+
.flow-arrow {
64+
fill: none;
65+
stroke: #3498db;
66+
stroke-width: 3;
67+
marker-end: url(#arrowhead-blue);
68+
}
69+
70+
.label {
71+
font-family: 'Courier New', monospace;
72+
font-size: 13px;
73+
}
74+
75+
.title-text {
76+
font-weight: bold;
77+
font-size: 14px;
78+
}
79+
80+
.description {
81+
font-size: 12px;
82+
fill: #7f8c8d;
83+
}
84+
85+
.pipe-symbol {
86+
font-family: 'Courier New', monospace;
87+
font-size: 24px;
88+
font-weight: bold;
89+
fill: #e74c3c;
90+
}
91+
92+
.code-example {
93+
background: #2c3e50;
94+
color: #ecf0f1;
95+
padding: 20px;
96+
border-radius: 8px;
97+
font-family: 'Courier New', monospace;
98+
font-size: 14px;
99+
line-height: 1.8;
100+
overflow-x: auto;
101+
margin: 20px 0;
102+
}
103+
104+
.code-comment {
105+
color: #95a5a6;
106+
}
107+
108+
.code-keyword {
109+
color: #e74c3c;
110+
}
111+
112+
.code-method {
113+
color: #3498db;
114+
}
115+
116+
.code-string {
117+
color: #2ecc71;
118+
}
119+
120+
.highlight {
121+
animation: pulse 2s infinite;
122+
}
123+
124+
@keyframes pulse {
125+
0%, 100% { opacity: 1; }
126+
50% { opacity: 0.6; }
127+
}
128+
129+
.note {
130+
background: #e8f4f8;
131+
border-left: 4px solid #3498db;
132+
padding: 15px;
133+
margin: 20px 0;
134+
border-radius: 4px;
135+
}
136+
137+
.note strong {
138+
color: #2980b9;
139+
}
140+
</style>
141+
</head>
142+
<body>
143+
<div class="container">
144+
<h1>DAO → Sink Architecture: The FOAM Pipeline</h1>
145+
146+
<div class="note">
147+
<strong>Key Concept:</strong> Just like Unix pipes chain commands to process data, FOAM chains DAOs and streams results to a Sink. Data flows from left to right through decorators, then into the output Sink.
148+
</div>
149+
150+
<h2>Unix Pipe Analogy</h2>
151+
<div class="diagram">
152+
<svg width="1100" height="180" xmlns="http://www.w3.org/2000/svg">
153+
<defs>
154+
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
155+
<polygon points="0 0, 10 3, 0 6" fill="#34495e" />
156+
</marker>
157+
<marker id="arrowhead-blue" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
158+
<polygon points="0 0, 10 3, 0 6" fill="#3498db" />
159+
</marker>
160+
</defs>
161+
162+
<!-- Unix command boxes -->
163+
<g class="box">
164+
<rect x="20" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
165+
<text x="90" y="65" text-anchor="middle" class="title-text">cat users.txt</text>
166+
<text x="90" y="85" text-anchor="middle" class="description">Read file</text>
167+
<text x="90" y="100" text-anchor="middle" class="description">(data source)</text>
168+
</g>
169+
170+
<text x="175" y="80" class="pipe-symbol">|</text>
171+
172+
<g class="box">
173+
<rect x="200" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
174+
<text x="270" y="65" text-anchor="middle" class="title-text">grep "active"</text>
175+
<text x="270" y="85" text-anchor="middle" class="description">Filter rows</text>
176+
</g>
177+
178+
<text x="355" y="80" class="pipe-symbol">|</text>
179+
180+
<g class="box">
181+
<rect x="380" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
182+
<text x="450" y="65" text-anchor="middle" class="title-text">sort</text>
183+
<text x="450" y="85" text-anchor="middle" class="description">Order results</text>
184+
</g>
185+
186+
<text x="535" y="80" class="pipe-symbol">|</text>
187+
188+
<g class="box">
189+
<rect x="560" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
190+
<text x="630" y="65" text-anchor="middle" class="title-text">head -n 20</text>
191+
<text x="630" y="85" text-anchor="middle" class="description">Limit results</text>
192+
</g>
193+
194+
<text x="715" y="80" class="pipe-symbol">></text>
195+
196+
<g class="box">
197+
<rect x="740" y="40" width="140" height="70" fill="#2ecc71" stroke="#27ae60" stroke-width="2" rx="5"/>
198+
<text x="810" y="65" text-anchor="middle" class="title-text" fill="white">output.txt</text>
199+
<text x="810" y="85" text-anchor="middle" class="description" fill="white">Destination</text>
200+
<text x="810" y="100" text-anchor="middle" class="description" fill="white">(Sink)</text>
201+
</g>
202+
203+
<!-- Flow arrow -->
204+
<path d="M 90 130 L 270 130 L 450 130 L 630 130 L 810 130"
205+
class="flow-arrow" stroke-dasharray="5,5">
206+
<animate attributeName="stroke-dashoffset" from="10" to="0" dur="1s" repeatCount="indefinite"/>
207+
</path>
208+
<text x="450" y="155" text-anchor="middle" fill="#3498db" font-weight="bold">Data flows through pipeline →</text>
209+
</svg>
210+
</div>
211+
212+
<h2>FOAM DAO → Sink Pipeline</h2>
213+
<div class="diagram">
214+
<svg width="1100" height="180" xmlns="http://www.w3.org/2000/svg">
215+
<!-- FOAM DAO boxes -->
216+
<g class="box">
217+
<rect x="20" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
218+
<text x="90" y="65" text-anchor="middle" class="title-text">userDAO</text>
219+
<text x="90" y="85" text-anchor="middle" class="description">Storage layer</text>
220+
<text x="90" y="100" text-anchor="middle" class="description">(data source)</text>
221+
</g>
222+
223+
<text x="175" y="80" class="pipe-symbol">.</text>
224+
225+
<g class="box">
226+
<rect x="200" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
227+
<text x="270" y="65" text-anchor="middle" class="title-text">.where(EQ(...))</text>
228+
<text x="270" y="85" text-anchor="middle" class="description">Filter predicate</text>
229+
</g>
230+
231+
<text x="355" y="80" class="pipe-symbol">.</text>
232+
233+
<g class="box">
234+
<rect x="380" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
235+
<text x="450" y="65" text-anchor="middle" class="title-text">.orderBy(...)</text>
236+
<text x="450" y="85" text-anchor="middle" class="description">Sort comparator</text>
237+
</g>
238+
239+
<text x="535" y="80" class="pipe-symbol">.</text>
240+
241+
<g class="box">
242+
<rect x="560" y="40" width="140" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
243+
<text x="630" y="65" text-anchor="middle" class="title-text">.limit(20)</text>
244+
<text x="630" y="85" text-anchor="middle" class="description">Limit count</text>
245+
</g>
246+
247+
<text x="715" y="80" class="pipe-symbol"></text>
248+
249+
<g class="box">
250+
<rect x="740" y="40" width="140" height="70" fill="#2ecc71" stroke="#27ae60" stroke-width="2" rx="5"/>
251+
<text x="810" y="65" text-anchor="middle" class="title-text" fill="white">.select(sink)</text>
252+
<text x="810" y="85" text-anchor="middle" class="description" fill="white">Result processor</text>
253+
<text x="810" y="100" text-anchor="middle" class="description" fill="white">(Sink)</text>
254+
</g>
255+
256+
<!-- Flow arrow -->
257+
<path d="M 90 130 L 270 130 L 450 130 L 630 130 L 810 130"
258+
class="flow-arrow" stroke-dasharray="5,5">
259+
<animate attributeName="stroke-dashoffset" from="10" to="0" dur="1s" repeatCount="indefinite"/>
260+
</path>
261+
<text x="450" y="155" text-anchor="middle" fill="#3498db" font-weight="bold">Data streams through decorated DAOs →</text>
262+
</svg>
263+
</div>
264+
265+
<h2>Code Examples</h2>
266+
267+
<div class="code-example">
268+
<span class="code-comment">// Unix-style thinking</span>
269+
cat users.txt | grep "active" | sort | head -n 20 > output.txt
270+
271+
<span class="code-comment">// FOAM equivalent - fluent DAO chaining</span>
272+
userDAO
273+
.<span class="code-method">where</span>(<span class="code-keyword">this</span>.EQ(User.STATUS, <span class="code-string">'active'</span>))
274+
.<span class="code-method">orderBy</span>(User.NAME)
275+
.<span class="code-method">limit</span>(20)
276+
.<span class="code-method">select</span>(ArraySink.create()) <span class="code-comment">// ← The "output" (Sink)</span>
277+
.<span class="code-method">then</span>((sink) => {
278+
console.log(sink.array); <span class="code-comment">// Access collected results</span>
279+
});
280+
</div>
281+
282+
<h2>Sink Delegation (Multi-Stage Processing)</h2>
283+
<div class="diagram">
284+
<svg width="1100" height="220" xmlns="http://www.w3.org/2000/svg">
285+
<!-- Decorated DAO chain -->
286+
<g class="box">
287+
<rect x="20" y="40" width="180" height="70" fill="#ecf0f1" stroke="#34495e" stroke-width="2" rx="5"/>
288+
<text x="110" y="65" text-anchor="middle" class="title-text">userDAO.where(...)</text>
289+
<text x="110" y="85" text-anchor="middle" class="description">Decorated DAO</text>
290+
<text x="110" y="100" text-anchor="middle" class="description">(query spec)</text>
291+
</g>
292+
293+
<path d="M 200 75 L 240 75" class="flow-arrow"/>
294+
<text x="220" y="65" text-anchor="middle" fill="#3498db" font-size="12px">.select()</text>
295+
296+
<!-- Sink chain with delegation -->
297+
<g class="box">
298+
<rect x="240" y="30" width="180" height="90" fill="#e8f4f8" stroke="#3498db" stroke-width="2" rx="5"/>
299+
<text x="330" y="55" text-anchor="middle" class="title-text">PredicatedSink</text>
300+
<text x="330" y="75" text-anchor="middle" class="description">Filter in Sink</text>
301+
<text x="330" y="105" text-anchor="middle" class="description" font-style="italic">delegates to →</text>
302+
</g>
303+
304+
<path d="M 420 75 L 460 75" class="flow-arrow"/>
305+
306+
<g class="box">
307+
<rect x="460" y="30" width="180" height="90" fill="#e8f4f8" stroke="#3498db" stroke-width="2" rx="5"/>
308+
<text x="550" y="55" text-anchor="middle" class="title-text">Map</text>
309+
<text x="550" y="75" text-anchor="middle" class="description">Transform results</text>
310+
<text x="550" y="105" text-anchor="middle" class="description" font-style="italic">delegates to →</text>
311+
</g>
312+
313+
<path d="M 640 75 L 680 75" class="flow-arrow"/>
314+
315+
<g class="box">
316+
<rect x="680" y="30" width="180" height="90" fill="#2ecc71" stroke="#27ae60" stroke-width="2" rx="5"/>
317+
<text x="770" y="55" text-anchor="middle" class="title-text" fill="white">ArraySink</text>
318+
<text x="770" y="75" text-anchor="middle" class="description" fill="white">Collect final</text>
319+
<text x="770" y="95" text-anchor="middle" class="description" fill="white">results into</text>
320+
<text x="770" y="110" text-anchor="middle" class="description" fill="white">array</text>
321+
</g>
322+
323+
<!-- Labels -->
324+
<text x="110" y="150" text-anchor="middle" fill="#34495e" font-weight="bold">DAO Composition</text>
325+
<text x="110" y="170" text-anchor="middle" fill="#7f8c8d" font-size="12px">(Decorators stack)</text>
326+
327+
<text x="550" y="150" text-anchor="middle" fill="#34495e" font-weight="bold">Sink Delegation</text>
328+
<text x="550" y="170" text-anchor="middle" fill="#7f8c8d" font-size="12px">(Processing chain)</text>
329+
330+
<!-- Overall flow -->
331+
<path d="M 110 190 L 770 190" class="flow-arrow" stroke-width="2"/>
332+
<text x="440" y="210" text-anchor="middle" fill="#3498db" font-weight="bold">Complete data flow: Source → Processing → Output</text>
333+
</svg>
334+
</div>
335+
336+
<div class="code-example">
337+
<span class="code-comment">// Sink delegation example</span>
338+
<span class="code-keyword">var</span> sink = PredicatedSink.create({
339+
predicate: someCondition, <span class="code-comment">// Filter in the sink</span>
340+
<span class="code-keyword">delegate</span>: Map.create({
341+
arg1: User.NAME, <span class="code-comment">// Transform (extract name)</span>
342+
<span class="code-keyword">delegate</span>: ArraySink.create() <span class="code-comment">// Final output</span>
343+
})
344+
});
345+
346+
userDAO.<span class="code-method">select</span>(sink); <span class="code-comment">// Start the flow</span>
347+
</div>
348+
349+
<div class="note">
350+
<strong>Key Difference:</strong><br>
351+
<strong>DAO Composition</strong> (left side): Query specification - describes WHAT data to retrieve and HOW to filter/sort it<br>
352+
<strong>Sink Delegation</strong> (right side): Result processing - describes HOW to process the results once retrieved<br><br>
353+
Think of it as: <code>where/limit/orderBy</code> build the query, <code>select(sink)</code> executes it and streams to the output processor.
354+
</div>
355+
</div>
356+
</body>
357+
</html>

0 commit comments

Comments
 (0)