feat: 4-app signal composition demo with explicit outputs
Add 3 new streaming apps with explicit output declarations: - streaming-clock.ds: output hours, minutes, seconds (tick private) - streaming-stats.ds: output total, average, max (sum private) - streaming-mood.ds: output mood, energy, color (clicks private) Add compose-dashboard.ds that receives all 4 streams via unique relay channels (/stream/default, /stream/clock, /stream/stats, /stream/mood) into a single dashboard view. Each app demonstrates selective signal registration — only declared outputs are streamed, internal state remains private.
This commit is contained in:
parent
627ee44275
commit
8775860fdd
4 changed files with 172 additions and 0 deletions
53
examples/compose-dashboard.ds
Normal file
53
examples/compose-dashboard.ds
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
-- DreamStack 4-App Composition Dashboard
|
||||
-- Composes signals from 4 independent streaming apps.
|
||||
-- Each app has explicit output declarations:
|
||||
-- counter: count, doubled (NOT message)
|
||||
-- clock: hours, minutes, seconds (NOT tick)
|
||||
-- stats: total, average, max (NOT sum, last_sample)
|
||||
-- mood: mood, energy, color (NOT clicks)
|
||||
--
|
||||
-- Run with:
|
||||
-- Tab 1: cargo run -p ds-stream
|
||||
-- Tab 2: dreamstack stream examples/streaming-counter.ds --port 3000
|
||||
-- Tab 3: dreamstack stream examples/streaming-clock.ds --port 3002
|
||||
-- Tab 4: dreamstack stream examples/streaming-stats.ds --port 3003
|
||||
-- Tab 5: dreamstack stream examples/streaming-mood.ds --port 3004
|
||||
-- Tab 6: dreamstack build examples/compose-dashboard.ds
|
||||
--
|
||||
-- Open the built file in a browser.
|
||||
|
||||
let counter = stream from "ws://localhost:9100/stream/default"
|
||||
let clock = stream from "ws://localhost:9100/stream/clock"
|
||||
let stats = stream from "ws://localhost:9100/stream/stats"
|
||||
let mood = stream from "ws://localhost:9100/stream/mood"
|
||||
|
||||
view main =
|
||||
column [
|
||||
text "🎛️ DreamStack Signal Composition"
|
||||
text "4 apps → 1 dashboard"
|
||||
row [
|
||||
column [
|
||||
text "── 🔢 Counter ──"
|
||||
text "Count: {counter.count}"
|
||||
text "Doubled: {counter.doubled}"
|
||||
]
|
||||
column [
|
||||
text "── 🕐 Clock ──"
|
||||
text "{clock.hours}:{clock.minutes}:{clock.seconds}"
|
||||
]
|
||||
]
|
||||
row [
|
||||
column [
|
||||
text "── 📊 Stats ──"
|
||||
text "Samples: {stats.total}"
|
||||
text "Average: {stats.average}"
|
||||
text "Max: {stats.max}"
|
||||
]
|
||||
column [
|
||||
text "── 😊 Mood ──"
|
||||
text "Mood: {mood.mood}"
|
||||
text "Energy: {mood.energy}%"
|
||||
text "Color: {mood.color}"
|
||||
]
|
||||
]
|
||||
]
|
||||
25
examples/streaming-clock.ds
Normal file
25
examples/streaming-clock.ds
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
-- DreamStack Streaming Clock
|
||||
-- Streams time signals every second.
|
||||
-- Only hours, minutes, seconds are exposed (tick is internal).
|
||||
--
|
||||
-- Run with:
|
||||
-- dreamstack stream examples/streaming-clock.ds --port 3002
|
||||
|
||||
let tick = 0
|
||||
let seconds = tick % 60
|
||||
let minutes = (tick / 60) % 60
|
||||
let hours = (tick / 3600) % 24
|
||||
|
||||
stream clock on "ws://localhost:9100/peer/clock" {
|
||||
mode: signal,
|
||||
output: hours, minutes, seconds
|
||||
}
|
||||
|
||||
every 1000 -> tick += 1
|
||||
|
||||
view clock =
|
||||
column [
|
||||
text "🕐 Streaming Clock"
|
||||
text "{hours}:{minutes}:{seconds}"
|
||||
text "tick: {tick}"
|
||||
]
|
||||
50
examples/streaming-mood.ds
Normal file
50
examples/streaming-mood.ds
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
-- DreamStack Streaming Mood
|
||||
-- Interactive mood and energy tracker.
|
||||
-- Only mood, energy, color are exposed (clicks is internal).
|
||||
--
|
||||
-- Run with:
|
||||
-- dreamstack stream examples/streaming-mood.ds --port 3004 --relay ws://localhost:9100/source/mood
|
||||
|
||||
let mood = "neutral"
|
||||
let energy = 50
|
||||
let color = "gray"
|
||||
let clicks = 0
|
||||
|
||||
stream mood_tracker on "ws://localhost:9100/peer/mood" {
|
||||
mode: signal,
|
||||
output: mood, energy, color
|
||||
}
|
||||
|
||||
view mood_tracker =
|
||||
column [
|
||||
text "😊 Mood Tracker"
|
||||
text "Mood: {mood}"
|
||||
text "Energy: {energy}%"
|
||||
text "Color: {color}"
|
||||
row [
|
||||
button "😄 Happy" {
|
||||
click: mood = "happy"
|
||||
click: color = "green"
|
||||
click: energy = energy + 10
|
||||
}
|
||||
button "😐 Neutral" {
|
||||
click: mood = "neutral"
|
||||
click: color = "gray"
|
||||
}
|
||||
button "😤 Angry" {
|
||||
click: mood = "angry"
|
||||
click: color = "red"
|
||||
click: energy = energy - 10
|
||||
}
|
||||
]
|
||||
row [
|
||||
button "☕ Caffeine" {
|
||||
click: energy = energy + 25
|
||||
click: clicks += 1
|
||||
}
|
||||
button "😴 Rest" {
|
||||
click: energy = energy - 15
|
||||
click: clicks += 1
|
||||
}
|
||||
]
|
||||
]
|
||||
44
examples/streaming-stats.ds
Normal file
44
examples/streaming-stats.ds
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
-- DreamStack Streaming Stats
|
||||
-- Tracks button presses and computes statistics.
|
||||
-- Only total, average, max are exposed (sum and last_sample are internal).
|
||||
--
|
||||
-- Run with:
|
||||
-- dreamstack stream examples/streaming-stats.ds --port 3003
|
||||
|
||||
let total = 0
|
||||
let max = 0
|
||||
let sum = 0
|
||||
let average = sum / (total + 1)
|
||||
|
||||
stream stats on "ws://localhost:9100/peer/stats" {
|
||||
mode: signal,
|
||||
output: total, average, max
|
||||
}
|
||||
|
||||
view stats =
|
||||
column [
|
||||
text "📊 Streaming Stats"
|
||||
text "Samples: {total}"
|
||||
text "Average: {average}"
|
||||
text "Max: {max}"
|
||||
row [
|
||||
button "+5" {
|
||||
click: total += 1
|
||||
click: sum += 5
|
||||
}
|
||||
button "+10" {
|
||||
click: total += 1
|
||||
click: sum += 10
|
||||
}
|
||||
button "+25" {
|
||||
click: total += 1
|
||||
click: sum += 25
|
||||
click: max = 25
|
||||
}
|
||||
button "+50" {
|
||||
click: total += 1
|
||||
click: sum += 50
|
||||
click: max = 50
|
||||
}
|
||||
]
|
||||
]
|
||||
Loading…
Add table
Reference in a new issue