-
-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into feature/hiccup-svg-deref-attribs
* develop: (38 commits) Publish feat(csp): update Mult/PubSub unsub handling, add docs minor(csp): rename MAX_QUEUE => MAX_WRITES docs(csp): add various doc strings fix(csp): update select() docs(csp): add docs for all Channel ops docs(csp): update readme example docs(csp): update/extend readme (update example) docs(csp): update/extend readme Publish docs: update main readme docs: regen readmes docs(csp): update readme (example, doc links) refactor(examples): update csp-bus feat(csp): add into() to feed (async) iterables into a channel feat(meta-css): add color-scheme, light-dark() and appearance rules/tpls fix(rdom): update $compile() async-iterable attrib handling feat(csp): add opt. generics for PubSub.subscribe()/unsubscribe() feat(examples): add csp-bus example docs(examples): update table ...
- Loading branch information
Showing
190 changed files
with
2,819 additions
and
2,663 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# csp-bus | ||
|
||
![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/csp-bus.png) | ||
|
||
[Live demo](http://demo.thi.ng/umbrella/csp-bus/) | ||
|
||
## Developing & building | ||
|
||
Please refer to the instructions on the wiki: | ||
|
||
- [Development](https://github.com/thi-ng/umbrella/wiki/Development-mode-for-examples-using-thi.ng-meta%E2%80%90css) | ||
- [Production build](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) | ||
|
||
## Authors | ||
|
||
- Karsten Schmidt | ||
|
||
## License | ||
|
||
© 2024 Karsten Schmidt // Apache Software License 2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"tables": {}, | ||
"vars": {}, | ||
"decls": [], | ||
"specs": [], | ||
"templates": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// list of CSS class names to force-include in generated CSS | ||
// (one class per line, basic wildcards supported) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// thi.ng/meta-css stylesheet | ||
// see package readme for more details/usage | ||
// use `yarn css:build` or `yarn css:watch` to transpile to CSS | ||
// also see component-specific *.mcss files in /src folder | ||
|
||
:root { | ||
color-scheme-light-dark | ||
bg=#fff | ||
text=#000 | ||
log=#777 | ||
dark:bg=#000 | ||
dark:text=#fff | ||
dark:log=#999 | ||
} | ||
|
||
body { system-sans-serif ma3 bg-color(bg) color(text) } | ||
|
||
textarea[disabled] { w-100 pa2 bw0 bg-color(bg) color(log) } | ||
|
||
button.stop { db w-100 bg-color-orange color-white h2 bw0 mb3 cursor-pointer } | ||
|
||
a.link { color(text) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<link | ||
rel="icon" | ||
href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">⛱️</text></svg>' | ||
/> | ||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>csp-bus · @thi.ng/umbrella</title> | ||
<link href="/css/style.css" rel="stylesheet"> | ||
<script>window.goatcounter = { path: (p) => location.host + p };</script> | ||
<script data-goatcounter="https://thing.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
<div><a class="link" href="https://github.com/thi-ng/umbrella/tree/develop/examples/csp-bus">Source code</a></div> | ||
<script type="module" src="/src/index.ts"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"name": "@example/csp-bus", | ||
"version": "0.0.1", | ||
"private": true, | ||
"description": "CSP channel-based event handling, async transducers & reactive UI components", | ||
"repository": "https://github.com/thi-ng/umbrella", | ||
"author": "Karsten Schmidt <k+npm@thi.ng>", | ||
"license": "Apache-2.0", | ||
"scripts": { | ||
"start": "yarn css:build && yarn start:only", | ||
"start:only": "vite --host --open", | ||
"css:watch": "../../node_modules/.bin/metacss develop --bundle --watch --pretty --out-specs css/framework.json --out-css css/style.css --force @css/includes.txt ../../packages/meta-css/specs/*.mcss.json css/*.mcss.json css/*.mcss src/*.mcss", | ||
"css:build": "../../node_modules/.bin/metacss develop --bundle --out-specs css/framework.json --out-css css/style.css --force @css/includes.txt ../../packages/meta-css/specs/*.mcss.json css/*.mcss.json css/*.mcss src/*.mcss", | ||
"build": "yarn css:build && tsc && vite build --base='./'", | ||
"preview": "vite preview --host --open" | ||
}, | ||
"devDependencies": { | ||
"@thi.ng/meta-css": "workspace:^", | ||
"typescript": "^5.4.3", | ||
"vite": "^5.2.6" | ||
}, | ||
"dependencies": { | ||
"@thi.ng/api": "workspace:^", | ||
"@thi.ng/csp": "workspace:^", | ||
"@thi.ng/date": "workspace:^", | ||
"@thi.ng/hiccup-html": "workspace:^", | ||
"@thi.ng/rdom": "workspace:^", | ||
"@thi.ng/system": "workspace:^", | ||
"@thi.ng/transducers": "workspace:^", | ||
"@thi.ng/transducers-async": "workspace:^" | ||
}, | ||
"browser": { | ||
"process": false | ||
}, | ||
"thi.ng": { | ||
"readme": [ | ||
"csp", | ||
"date", | ||
"hiccup-html", | ||
"rdom", | ||
"system", | ||
"transducers-async" | ||
], | ||
"screenshot": "examples/csp-bus.png" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type { Channel, PubSub } from "@thi.ng/csp"; | ||
import type { ILifecycle } from "@thi.ng/system"; | ||
import type { Counter, CounterGroup } from "./counter.js"; | ||
|
||
export type StartCounterEvent = ["start-counter", Counter]; | ||
export type StopAllEvent = ["stop"]; | ||
export type LogEvent = ["log", string]; | ||
|
||
export type Event = StartCounterEvent | StopAllEvent | LogEvent; | ||
|
||
export type EventBus = PubSub<Event>; | ||
|
||
// our app consists of multiple app components | ||
export interface App { | ||
bus: EventBus; | ||
counters: CounterGroup; | ||
logger: Channel<string>; | ||
ui: ILifecycle; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// put component specific thi.ng/meta-css style defs here... | ||
// these will be included in the generated CSS via the `css:build` | ||
// and `css:watch` script aliases in `package.json` | ||
|
||
.counter { | ||
bg=#ccc | ||
text=#333 | ||
bt-bg=#000 | ||
bt-text=#fff | ||
bt-bg-disabled=#aaa | ||
bt-text-disabled=#ccc | ||
prog-bg=#99a | ||
prog-val=#d5008f | ||
|
||
dark:bg=#333 | ||
dark:text=#ccc | ||
dark:bt-bg=#fff | ||
dark:bt-text=#000 | ||
dark:bt-bg-disabled=#555 | ||
dark:bt-text-disabled=#333 | ||
dark:prog-bg=#556 | ||
dark:prog-val=#ff41b4 | ||
|
||
pa2 mb2 grid grid-cols(4rem 1fr 4rem) | ||
bg-color(bg) color(text) | ||
{ | ||
button { | ||
bg-color(bt-bg) color(bt-text) bw0 h2 pa2 mr3 cursor-pointer | ||
{ &[disabled] { bg-color(bt-bg-disabled) color(bt-text-disabled) cursor-auto } } | ||
} | ||
progress { | ||
w-100 h2 ma0 pa0 mr3 bw0 appearance(none) bg-color(prog-bg) | ||
{ | ||
[value]::-webkit-progress-value { bg-color(prog-val) } | ||
[value]::-webkit-progress-bar { bg-color(prog-bg) } | ||
[value]::-moz-progress-bar { bg-color(prog-val) } | ||
} | ||
} | ||
>span { mt2 tr } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import type { Maybe } from "@thi.ng/api"; | ||
import { Channel, Mult, channel, mult } from "@thi.ng/csp"; | ||
import { button, div, progress } from "@thi.ng/hiccup-html"; | ||
import { Component, type NumOrElement } from "@thi.ng/rdom"; | ||
import { map } from "@thi.ng/transducers-async"; | ||
import type { EventBus } from "./api.js"; | ||
|
||
// counter component with local state in the form of CSP channels | ||
export class Counter extends Component { | ||
value: Mult<number>; | ||
disabled: Channel<boolean>; | ||
|
||
constructor(public bus: EventBus, public delay: number, public id: number) { | ||
super(); | ||
this.value = mult<any>(); | ||
this.disabled = channel<boolean>(); | ||
this.value.write(0); | ||
this.disabled.write(false); | ||
} | ||
|
||
// thi.ng/rdom component lifecycle hook | ||
// called when this component is mounted in the browser DOM | ||
async mount(parent: ParentNode, index?: Maybe<NumOrElement>) { | ||
return (this.el = await this.$compile( | ||
div( | ||
".counter", | ||
{}, | ||
button( | ||
{ | ||
disabled: this.disabled, | ||
onclick: () => this.bus.write(["start-counter", this]), | ||
}, | ||
"start" | ||
), | ||
progress({ | ||
max: 100, | ||
value: this.value.subscribe(), | ||
}), | ||
map((x) => `${x}%`, this.value.subscribe()) | ||
) | ||
).mount(parent, index)); | ||
} | ||
} | ||
|
||
// simple wrapper component for multiple counters (configurable number) | ||
export class CounterGroup extends Component { | ||
constructor(public config: number[], public bus: EventBus) { | ||
super(); | ||
} | ||
|
||
async mount(parent: ParentNode, index?: Maybe<NumOrElement>) { | ||
return (this.el = await this.$compile( | ||
div( | ||
{}, | ||
...this.config.map( | ||
(delay, i) => new Counter(this.bus, delay, i + 1) | ||
) | ||
) | ||
).mount(parent, index)); | ||
} | ||
} | ||
|
||
// syntax sugar for CounterGroup ctor | ||
export const initCounters = async (config: number[], bus: EventBus) => | ||
new CounterGroup(config, bus); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { consumeWith, into, pubsub } from "@thi.ng/csp"; | ||
import { FMT_HHmmss, FMT_yyyyMMdd } from "@thi.ng/date"; | ||
import { concat, delayed, range } from "@thi.ng/transducers-async"; | ||
import type { | ||
App, | ||
Event, | ||
EventBus, | ||
LogEvent, | ||
StartCounterEvent, | ||
StopAllEvent, | ||
} from "./api"; | ||
|
||
export const initEvents = async ({ logger }: App) => { | ||
// the event bus is a simple pubsub CSP channel construct | ||
// events are triggered by writing a new value in this channel | ||
|
||
// event handlers (below) are subscribing to specific topics (via filtered | ||
// topic based CSP channels) and each handler is running in its own channel | ||
// consumer... the topic function used here simply extracts the event name | ||
// from incoming event tuples (see event definition in /api.ts) | ||
const bus: EventBus = pubsub<Event>((x) => x[0]); | ||
|
||
// async event handler & channel consumer to handle counter events in the | ||
// form: `["start-counter", counterInstance]` | ||
consumeWith( | ||
// create a topic subscription channel for this specific event type | ||
bus.subscribeTopic<StartCounterEvent>("start-counter"), | ||
// this function is called for side effects of each counter event received, | ||
// we make it async here to simplify animating the counter | ||
async ([_, { value, disabled, id, delay }]) => { | ||
// we *could* use the logger directly here, but instead utilize the | ||
// bus for demo purposes and trigger a logging event (its handler is | ||
// further below) | ||
bus.write(["log", `starting counter #${id}`]); | ||
// temporarily disable the counter button | ||
disabled.write(true); | ||
// animate by feeding an async iterable into the counter's value channel | ||
await into( | ||
value, | ||
// concatenate multiple async iterables to animate value | ||
concat( | ||
// count [0..100] | ||
range(101, delay), | ||
// short wait | ||
(async function* () { | ||
yield await delayed(100, 500); | ||
})(), | ||
// (faster) countdown to 0 | ||
range(100, -1, -10, 10) | ||
) | ||
); | ||
// re-enable counter button | ||
disabled.write(false); | ||
// another logging event | ||
bus.write(["log", `counter #${id} done`]); | ||
} | ||
); | ||
|
||
// stop the entire event bus if the `stop` event has been triggered. once | ||
// the bus channel is closed, all further events will be ignored and all | ||
// topic subscriptions should have been closed too (automatically) | ||
consumeWith(bus.subscribeTopic<StopAllEvent>("stop"), async () => { | ||
await bus.write(["log", "stopping event bus..."]); | ||
bus.close(); | ||
}); | ||
|
||
// to avoid direct dependencies on the logger in other parts of the app | ||
// enable logging via sending events to the bus | ||
consumeWith(bus.subscribeTopic<LogEvent>("log"), ([_, msg]) => | ||
logger.write(`${FMT_yyyyMMdd()} ${FMT_HHmmss()}: ${msg}`) | ||
); | ||
|
||
bus.write(["log", "eventbus ready..."]); | ||
|
||
return bus; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { defSystem } from "@thi.ng/system"; | ||
import type { App } from "./api.js"; | ||
import { initCounters } from "./counter.js"; | ||
import { initEvents } from "./events.js"; | ||
import { initLogger } from "./logger.js"; | ||
import { initUI } from "./ui.js"; | ||
|
||
// initialize the app components in dependency order | ||
// see thi.ng/system readme for details | ||
defSystem<App>({ | ||
logger: { factory: initLogger }, | ||
bus: { factory: initEvents, deps: ["logger"] }, | ||
ui: { factory: initUI, deps: ["bus", "counters", "logger"] }, | ||
counters: { | ||
factory: async ({ bus }) => initCounters([50, 10, 25], bus), | ||
deps: ["bus"], | ||
}, | ||
}).start(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { channel } from "@thi.ng/csp"; | ||
|
||
// app logger component is a simple CSP channel | ||
export const initLogger = async () => channel<string>(); |
Oops, something went wrong.