diff --git a/assets/dot-example.dot b/assets/dot-example.dot
deleted file mode 100644
index b2af0bf274..0000000000
--- a/assets/dot-example.dot
+++ /dev/null
@@ -1,21 +0,0 @@
-digraph g {
-rankdir="LR";
-fontname="Inconsolata";
-fontsize="9";
-fontcolor="gray";
-label="Generated with @thi.ng/dot";
-labeljust="l";
-labelloc="b";
-node[style="filled", fontname="Inconsolata", fontsize="11"];
-edge[arrowsize="0.75", fontname="Inconsolata", fontsize="9"];
-"x"[color="black", fontcolor="white", label="x (12)"];
-"y"[color="black", fontcolor="white", label="y (23)"];
-"res"[color="black", fontcolor="white", label="res (8050)", peripheries="2"];
-"op1"[fillcolor="green", shape="Mrecord", label="{ <0> a | <1> b } | op1\n(+) | { out }"];
-"op2"[fillcolor="yellow", shape="Mrecord", label="{ <0> a | <1> b } | op2\n(*) | { out }"];
-"x" -> "op1":"1";
-"y" -> "op1":"0";
-"y" -> "op2":"0"[label="xform", color="blue"];
-"op1":"out" -> "op2":"1";
-"op2":"out" -> "res";
-}
\ No newline at end of file
diff --git a/assets/dot/hdom-canvas-shapes.dot b/assets/dot/hdom-canvas-shapes.dot
new file mode 100644
index 0000000000..454d350a5f
--- /dev/null
+++ b/assets/dot/hdom-canvas-shapes.dot
@@ -0,0 +1,16 @@
+digraph g {
+ rankdir=LR;
+ node[fontname=Inconsolata,fontsize=11];
+ edge[fontname=Inconsolata,fontsize=9];
+
+ selection -> scene;
+ fromRAF -> scene;
+
+ scene -> ui;
+ scene -> exporter;
+ trigger -> exporter;
+
+ exporter -> file[style=dashed,label="download"];
+ ui -> selection[style=dashed,label="onchange"];
+ ui -> trigger[style=dashed,label="onclick"];
+}
\ No newline at end of file
diff --git a/assets/dot/hdom-v5.xml b/assets/dot/hdom-v5.xml
new file mode 100644
index 0000000000..14ee4334ed
--- /dev/null
+++ b/assets/dot/hdom-v5.xml
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/assets/dot/hdom.xml b/assets/dot/hdom.xml
new file mode 100644
index 0000000000..ffc99f9a27
--- /dev/null
+++ b/assets/dot/hdom.xml
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/assets/dot/iceps-dataflow.xml b/assets/dot/iceps-dataflow.xml
new file mode 100644
index 0000000000..083ed7334e
--- /dev/null
+++ b/assets/dot/iceps-dataflow.xml
@@ -0,0 +1 @@
+7VnJbtswEP0aA+0l0GYnOSaO3RZoiwIO0ObISLTEhtKoFBXb/fqS0lAbnSBNvBSFdTCox+E2bx6HlEf+NF1/ECRPvkBE+chzovXIvxl53tgP1K8GNjUQXI5rIBYsqiG3BRbsN0XQQbRkES16hhKAS5b3wRCyjIayhxEhYNU3WwLvj5qTmFrAIiTcRr+zSCY1ejF2WvwjZXFiRnYdrLkn4UMsoMxwvJHnL6unrk6J6Qvti4REsOpA/mzkTwWArEvpekq5dq1xW91u/kRtM29BM/mSBuc4DbkxS6eR8gS+gpAJxJARPmvR62p5VHfgqrdEphyLdM3kj075TpWds7F+y6TY6CrHvHTroitNmQLuOYQPtwnLanjOuOn6J5Vyg3FCSgkKaif3GSBHu0IKeKBT4CCq5fiX1dPUGDaVo6+XkMk5SRnXQXpLEkgJotva147S3nnS1QgVUIoQrTwMXiJiilZ+Q7NSD4WUKm8oE0E5keyx3zvBOI4bu5ZLVUA6t1OLQz8SXmKns0c9Vc/5VVIFeROuZnR9L1Qpls0KO6HQJ3qVMEkXOamWtlKy75PfRLKmOOakKLBsUTKvHu1qxW8Hd5yJel5KTNMLLpMKSdfPU2M7HRsEqEbcrVyjzlWr/QZLOrqfOG+nabwPBTpn5+OOCN1/XmYNm+1OceY1O4dZw+s06O9eg9j0G7BKUBhG3mU/jryLQXzUU8BWbYgoXsimY5Zrg+Ivxhlu8kN7/1l7Vahn0MZr45MXhfDFKYnsNYlsCeDgQEnEt5LIp0xSNbNcgrBTSC4gpEXBsviUXjr6c46YXwKLwYU6W+soXC710dniia5pWEoG2YnClkJ/ckQKJxaFEStyIsPkK6zevbdYUcuUA9f3PJxBRgfORYhwFqt98yakWuUK0E5j6l50hRUpi6Jq/97GdRsNznN0v2bLfJv+Bue7Jh92yAu2cOftgDvXtejZyfnOPt4156bescn535Oj+WTQzY7egbKjGbujTBJFehH6plXoGkbsbdSoV0v3KFvslg2g/lDhheExBDrU5wH3VndP96+TPo3VET+BmLFP+tztAfagAg1OAt2vQI94vXTt++VJoDu4nuxRoOq1/Xui/ljU/gXkz/4A
\ No newline at end of file
diff --git a/assets/dot/rstream-constructs.xml b/assets/dot/rstream-constructs.xml
new file mode 100644
index 0000000000..4217f16a0d
--- /dev/null
+++ b/assets/dot/rstream-constructs.xml
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/assets/hdom-dataflow.png b/assets/hdom-dataflow.png
index 820ae33df9..ef4580b723 100644
Binary files a/assets/hdom-dataflow.png and b/assets/hdom-dataflow.png differ
diff --git a/assets/rstream-merge.png b/assets/rstream-merge.png
new file mode 100644
index 0000000000..3dbc03fd1f
Binary files /dev/null and b/assets/rstream-merge.png differ
diff --git a/assets/rstream-pubsub.png b/assets/rstream-pubsub.png
new file mode 100644
index 0000000000..9e4f78554a
Binary files /dev/null and b/assets/rstream-pubsub.png differ
diff --git a/assets/rstream-sidechain-partition.png b/assets/rstream-sidechain-partition.png
new file mode 100644
index 0000000000..ef69d523cc
Binary files /dev/null and b/assets/rstream-sidechain-partition.png differ
diff --git a/assets/rstream-sidechain-toggle.png b/assets/rstream-sidechain-toggle.png
new file mode 100644
index 0000000000..9667eb0ea9
Binary files /dev/null and b/assets/rstream-sidechain-toggle.png differ
diff --git a/assets/rstream-sync.png b/assets/rstream-sync.png
new file mode 100644
index 0000000000..0402eb91bf
Binary files /dev/null and b/assets/rstream-sync.png differ
diff --git a/assets/screenshots/gesture-analysis.png b/assets/screenshots/gesture-analysis.png
new file mode 100644
index 0000000000..ae9f0c9446
Binary files /dev/null and b/assets/screenshots/gesture-analysis.png differ
diff --git a/assets/screenshots/svg-barchart.png b/assets/screenshots/svg-barchart.png
new file mode 100644
index 0000000000..055185d2ed
Binary files /dev/null and b/assets/screenshots/svg-barchart.png differ
diff --git a/examples/async-effect/package.json b/examples/async-effect/package.json
index c3ee841618..0098aeece5 100644
--- a/examples/async-effect/package.json
+++ b/examples/async-effect/package.json
@@ -5,8 +5,9 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "prepare": "mkdir -p out && cp foo.json out",
- "build": "yarn prepare && parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "prepare": "yarn clean && mkdir -p out && cp foo.json out",
+ "build": "yarn prepare && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "yarn prepare && parcel index.html -p 8080 --open -d out"
},
"devDependencies": {
diff --git a/examples/canvas-dial/package.json b/examples/canvas-dial/package.json
index 341bf44c6b..be616f6292 100644
--- a/examples/canvas-dial/package.json
+++ b/examples/canvas-dial/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/cellular-automata/package.json b/examples/cellular-automata/package.json
index 6076fd1208..5e02a14723 100644
--- a/examples/cellular-automata/package.json
+++ b/examples/cellular-automata/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/commit-table-ssr/README.md b/examples/commit-table-ssr/README.md
index ee39157b5c..7e69aab4ed 100644
--- a/examples/commit-table-ssr/README.md
+++ b/examples/commit-table-ssr/README.md
@@ -8,6 +8,17 @@ server-side rendering, static file generation and an extended
interactive browser version of a git repo commit log. The server is a
simple [express](https://expressjs.com/) app.
+There're 3 versions in this example:
+
+1) A server app which generates a static HTML version of the commit
+ table, performs caching and provides a route for retrieving
+ the commits as JSON. This server also includes the [Parcel
+ middleware](https://parceljs.org/api.html#middleware) to allow
+ editing the client without having to restart the server.
+2) A browser app which constructs the table client-side from the JSON
+ version of the commits
+3) A node app which generates a static HTML file
+
All of the UI components used on the server side too work in the browser
without change, though the browser version has additional functionality
(i.e. interactive filtering of commits via user provided search filter).
@@ -35,10 +46,10 @@ See [/src/server/index.ts](./src/server/index.ts) for details...
git clone https://github.com/thi-ng/umbrella.git
cd umbrella/examples/commit-table-ssr
yarn install
-yarn dev
+yarn start
```
-Then open http://localhost:3000/ssr in your browser.
+Then open http://localhost:8080/ssr in your browser.
### Browser version
@@ -47,8 +58,8 @@ The browser version uses the same UI components, but realizes them via
In addition to the SSR version above, this version displays additional
repo stats and allows for interactive filtering of the commits. The
-commits themselves are loaded as JSON and therefore also require the
-server app.
+commits themselves are loaded as JSON which are provided by the server
+app above.
Furthermore, this version utilizes
[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/master/packages/rstream)
@@ -58,11 +69,11 @@ various reactive stream constructs. Comments are included.
See [/src/client/index.ts](./src/client/index.ts) for details...
```
-yarn dev-client
+yarn start
```
-Once you see a message that the server is running, open
-http://localhost:3000 in your browser.
+Once you see a message that the server is running and the client app has
+been built, open http://localhost:8080 in your browser.
### Static file generation
diff --git a/examples/commit-table-ssr/package.json b/examples/commit-table-ssr/package.json
index 959c0f50c7..eb6e093ae1 100644
--- a/examples/commit-table-ssr/package.json
+++ b/examples/commit-table-ssr/package.json
@@ -5,10 +5,11 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
+ "clean": "rm -rf .cache build out",
+ "prepare": "yarn clean && mkdir -p out && cp commits.json out",
"build-static": "tsc && node build/server/static.js",
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
- "start-server": "tsc && node build/server/index.js",
- "start": "yarn build-client && yarn start-server"
+ "build": "yarn prepare && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
+ "start": "tsc && node build/server/index.js"
},
"devDependencies": {
"parcel-bundler": "^1.9.7",
diff --git a/examples/commit-table-ssr/src/client/index.ts b/examples/commit-table-ssr/src/client/index.ts
index 453fa9887d..0a9bb6abca 100644
--- a/examples/commit-table-ssr/src/client/index.ts
+++ b/examples/commit-table-ssr/src/client/index.ts
@@ -17,6 +17,11 @@ import { link } from "../common/components/link";
import { repoTable } from "../common/components/repo-table";
import { ctx } from "../common/config";
+const COMMITS_URL =
+ process.env.NODE_ENV === "production" ?
+ "./commits.json" :
+ "/commits";
+
// UI root component
const app = (state) =>
["div",
@@ -83,7 +88,7 @@ error.subscribe({ next: (e) => alert(`An error occurred:\n${e}`) });
const commits = fromInterval(60 * 60 * 1000)
// fetch commits from server
.transform(
- map(() => fetch("./commits").then(
+ map(() => fetch(COMMITS_URL).then(
(res) => res.ok ? res.json() : error.next("error loading commits"),
(e) => error.next(e.message)
))
diff --git a/examples/commit-table-ssr/src/server/index.ts b/examples/commit-table-ssr/src/server/index.ts
index 302ed03339..5ac57b254e 100644
--- a/examples/commit-table-ssr/src/server/index.ts
+++ b/examples/commit-table-ssr/src/server/index.ts
@@ -1,11 +1,11 @@
import { TLRUCache } from "@thi.ng/cache";
import * as express from "express";
+import * as Bundler from "parcel-bundler";
import { Commit } from "../common/api";
import { ctx } from "../common/config";
import { buildRepoTableHTML } from "./build-table";
import { repoCommits } from "./git";
-import { html, script } from "./html";
// building the repo commit table takes quite some time
// therefore we cache results with 1h expiry time
@@ -13,24 +13,19 @@ import { html, script } from "./html";
const rawCache = new TLRUCache(null, { ttl: 60 * 60 * 1000 });
const htmlCache = new TLRUCache(null, { ttl: 60 * 60 * 1000 });
-const app = express();
+// console.log("parcel:", Object.keys(parcel));
+const bundler = new Bundler("index.html", {
+ outDir: "./out",
+ outFile: "index.html",
+ publicUrl: "/out",
+});
-app.use(express.static("."));
+const app = express();
// route for browser version
-// here we simply return a barebone html doc
-// with a reference to the built client JS
+// here we simply redirect to the Parcel managed client version
app.get("/", (_, res) => {
- res.send(html({
- ctx,
- head: {
- title: "commit-table-hdom",
- },
- body: [
- ["div#app"],
- [script, { src: "bundle.js" }]
- ],
- }));
+ res.redirect("/out/");
});
// route for the client to retrieve the commit log as JSON
@@ -61,5 +56,8 @@ app.get("/ssr", (_, res) => {
).then((doc) => res.send(doc))
});
-console.log("starting server @ http://localhost:3000");
-app.listen(3000);
+app.use(express.static("."));
+app.use(bundler.middleware());
+
+console.log("starting server @ http://localhost:8080");
+app.listen(8080);
diff --git a/examples/crypto-chart/package.json b/examples/crypto-chart/package.json
index 93e88fc0db..57b9a3e6ed 100644
--- a/examples/crypto-chart/package.json
+++ b/examples/crypto-chart/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/dashboard/package.json b/examples/dashboard/package.json
index c3681aeb92..322a34ab95 100644
--- a/examples/dashboard/package.json
+++ b/examples/dashboard/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/devcards/package.json b/examples/devcards/package.json
index cc98b2d0a3..954172b0e2 100644
--- a/examples/devcards/package.json
+++ b/examples/devcards/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/gesture-analysis/package.json b/examples/gesture-analysis/package.json
index 406e35b016..0bc1934693 100644
--- a/examples/gesture-analysis/package.json
+++ b/examples/gesture-analysis/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-basics/package.json b/examples/hdom-basics/package.json
index f20547086a..c462f92b8d 100644
--- a/examples/hdom-basics/package.json
+++ b/examples/hdom-basics/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-benchmark/package.json b/examples/hdom-benchmark/package.json
index 7cb7a22eb5..ceb4964fd5 100644
--- a/examples/hdom-benchmark/package.json
+++ b/examples/hdom-benchmark/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-canvas-clock/README.md b/examples/hdom-canvas-clock/README.md
index 54dbea8f58..c5b92f327a 100644
--- a/examples/hdom-canvas-clock/README.md
+++ b/examples/hdom-canvas-clock/README.md
@@ -3,12 +3,13 @@
[Live demo](http://demo.thi.ng/umbrella/hdom-canvas-clock/)
Declarative canvas drawing using the upcoming
-[@thi.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom-canvas)
+[@thi.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/master/packages/hdom-canvas)
package.
Related examples:
-- [hdom-canvas-shapes](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-shapes)
+- [hdom-canvas-draw](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-draw)
+- [hdom-canvas-shapes](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-shapes)
## Building
@@ -19,7 +20,7 @@ The example project also assumes that [Parcel](https://parceljs.org) is
installed globally.
```bash
-git clone -b develop https://github.com/thi-ng/umbrella.git
+git clone https://github.com/thi-ng/umbrella.git
cd umbrella/examples/hdom-canvas-clock
yarn install
yarn start
diff --git a/examples/hdom-canvas-clock/package.json b/examples/hdom-canvas-clock/package.json
index 4577259ed2..056802a80e 100644
--- a/examples/hdom-canvas-clock/package.json
+++ b/examples/hdom-canvas-clock/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-canvas-clock/src/index.ts b/examples/hdom-canvas-clock/src/index.ts
index 2d6533f319..4b3feb3083 100644
--- a/examples/hdom-canvas-clock/src/index.ts
+++ b/examples/hdom-canvas-clock/src/index.ts
@@ -45,7 +45,7 @@ const cancel = start(() => {
// applied in a nested manner...
//
// see here for a list of all supported attribs:
- // https://github.com/thi-ng/umbrella/blob/develop/packages/hdom-canvas/src/index.ts#L35
+ // https://github.com/thi-ng/umbrella/blob/master/packages/hdom-canvas/src/index.ts#L35
["g",
{
translate: [100, 100],
@@ -72,7 +72,7 @@ const cancel = start(() => {
}),
["circle", {}, [0, 0], 5]]]],
["a.link",
- { href: "https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-clock" },
+ { href: "https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-clock" },
"Source code"]];
});
diff --git a/examples/hdom-canvas-draw/.gitignore b/examples/hdom-canvas-draw/.gitignore
new file mode 100644
index 0000000000..0c5abcab62
--- /dev/null
+++ b/examples/hdom-canvas-draw/.gitignore
@@ -0,0 +1,5 @@
+.cache
+out
+node_modules
+yarn.lock
+*.js
diff --git a/examples/hdom-canvas-draw/README.md b/examples/hdom-canvas-draw/README.md
new file mode 100644
index 0000000000..5ca912c7a2
--- /dev/null
+++ b/examples/hdom-canvas-draw/README.md
@@ -0,0 +1,18 @@
+# hdom-canvas-draw
+
+[Live demo](http://demo.thi.ng/umbrella/hdom-canvas-draw/)
+
+```bash
+git clone https://github.com/thi-ng/umbrella.git
+cd umbrella/examples/hdom-canvas-draw
+yarn install
+yarn start
+```
+
+## Authors
+
+- Karsten Schmidt
+
+## License
+
+© 2018 Karsten Schmidt // Apache Software License 2.0
diff --git a/examples/hdom-canvas-draw/index.html b/examples/hdom-canvas-draw/index.html
new file mode 100644
index 0000000000..cdb4c7ffa6
--- /dev/null
+++ b/examples/hdom-canvas-draw/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ hdom-canvas-draw
+
+
+
+
+
+
+
+
diff --git a/examples/hdom-canvas-draw/package.json b/examples/hdom-canvas-draw/package.json
new file mode 100644
index 0000000000..f456ec6f02
--- /dev/null
+++ b/examples/hdom-canvas-draw/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "hdom-canvas-draw",
+ "version": "0.0.1",
+ "repository": "https://github.com/thi-ng/umbrella",
+ "author": "Karsten Schmidt ",
+ "license": "Apache-2.0",
+ "scripts": {
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
+ "start": "parcel index.html -p 8080 --open"
+ },
+ "devDependencies": {
+ "parcel-bundler": "^1.9.7",
+ "terser": "^3.8.2",
+ "typescript": "^3.0.1"
+ },
+ "dependencies": {
+ "@thi.ng/hdom-canvas": "latest",
+ "@thi.ng/rstream": "latest",
+ "@thi.ng/rstream-gestures": "latest",
+ "@thi.ng/transducers": "latest",
+ "@thi.ng/transducers-hdom": "latest",
+ "@thi.ng/vectors": "latest"
+ },
+ "browserslist": [
+ "last 3 Chrome versions"
+ ],
+ "browser": {
+ "process": false
+ }
+}
\ No newline at end of file
diff --git a/examples/hdom-canvas-draw/src/index.ts b/examples/hdom-canvas-draw/src/index.ts
new file mode 100644
index 0000000000..b26f773d3f
--- /dev/null
+++ b/examples/hdom-canvas-draw/src/index.ts
@@ -0,0 +1,127 @@
+import { canvas } from "@thi.ng/hdom-canvas";
+import { GestureEvent, gestureStream, GestureType } from "@thi.ng/rstream-gestures";
+import { sync } from "@thi.ng/rstream/stream-sync";
+import { trigger } from "@thi.ng/rstream/trigger";
+import { updateDOM } from "@thi.ng/transducers-hdom";
+import { normRange } from "@thi.ng/transducers/iter/norm-range";
+import { repeat } from "@thi.ng/transducers/iter/repeat";
+import { tuples } from "@thi.ng/transducers/iter/tuples";
+import { filter } from "@thi.ng/transducers/xform/filter";
+import { map } from "@thi.ng/transducers/xform/map";
+import { mapcat } from "@thi.ng/transducers/xform/mapcat";
+import { partition } from "@thi.ng/transducers/xform/partition";
+import { HALF_PI, PI } from "@thi.ng/vectors/math";
+import { dist2 } from "@thi.ng/vectors/vec2";
+
+// canvas size
+const W = 480;
+
+// higher order line/shape component function
+// takes a tuple of 2 points and returns a component fn
+const line = ([a, b]: number[][]) =>
+ (_, attribs) =>
+ ["line", { ...attribs, weight: dist2(a, b) / 4 }, a, b];
+
+// higher order root component function. takes a @thi.ng/rstream
+// `StreamSync` instance as argument to dynamically add a new input
+// stream to later
+const app = (main) => {
+ // augment hdom-canvas component w/ `init` lifecycle method: this is
+ // method is called when the canvas DOM element is first created and
+ // used to attach a mouse & touch event stream to it. this stream is
+ // then transformed using a number of transducers and eventually
+ // outputs a series of `line` components. furthermore this
+ // transformed stream is added as new input to the `main` stream
+ // combinator below...
+ const _canvas = {
+ ...canvas,
+ init: (el: HTMLCanvasElement) =>
+ main.add(
+ gestureStream(el)
+ .transform(
+ // only interested in some gesture types
+ filter((e: GestureEvent) =>
+ e[0] === GestureType.START ||
+ e[0] === GestureType.DRAG
+ ),
+ // get current mouse / touch position
+ map((e) => e[1].pos),
+ // form consecutive line pairs
+ partition(2, 1),
+ // transform into pre-curried line component
+ map(line)
+ ),
+ // name of the new input
+ "gesture"
+ )
+ };
+ // this root component function will produce the actual UI and
+ // will be attached to the `main` stream combinator below and executes
+ // each time any inputs have changed...
+ // the only input used here is the above stream of mouse events
+ // transformed into line components
+ return ({ gesture }) =>
+ ["div.sans-serif.ma2", "Click & draw in the box below...",
+ // all child elements of the canvas component
+ // are NOT real DOM elements, but are translated into
+ // canvas API draw calls
+ [_canvas, { class: "mv2 db", width: W, height: W, __clear: false },
+ // semi-transparent bg
+ ["rect",
+ {
+ fill: "rgba(255,255,255,0.1)",
+ stroke: "black",
+ dash: [1, 1]
+ },
+ [0, 0], W, W
+ ],
+ // use a group node to assign attributes common to all children
+ ["g", { lineCap: "round" },
+ // `mapcat` here returns an iterator of fully
+ // configured line components
+ mapcat((attribs) =>
+ map(([[h, translate, theta], delta]: any[]) =>
+ // the `gesture` value is a pre-curried component fn
+ // (built by the the above transducer chain). we can
+ // configure it further using additional attributes to
+ // draw multiple instances.
+ [gesture,
+ {
+ stroke: `hsl(${h + (delta - 0.5) * 40},100%,50%)`,
+ rotate: theta + (delta - 0.5) * 0.3,
+ translate
+ }
+ ],
+ // iterator which forms tuples of `[attribs, counter]`
+ tuples(repeat(attribs), normRange(6))
+ ),
+ // configurations for the replicated strokes
+ [
+ [30, [0, 0], 0],
+ [120, [W, W], PI],
+ [210, [W, 0], HALF_PI],
+ [300, [0, W], -HALF_PI]
+ ]
+ )
+ ]
+ ],
+ // back in normal DOM
+ ["a.db.link",
+ { href: "https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-draw" },
+ "Source code"]
+ ];
+};
+
+// main stream combinator: initially only a single dummy `trigger` input
+// is assigned to kick off rendering... in the 1st frame the canvas
+// component's `init` method is called which attaches the above gesture
+// stream dynamically. the entire UI then only updates when there are new
+// user interactions...
+const main = sync({ src: { trigger: trigger() } });
+// transform result stream using the
+// root component fn and the hdom differential
+// update transducer
+main.transform(
+ map(app(main)),
+ updateDOM()
+);
diff --git a/examples/hdom-canvas-draw/tsconfig.json b/examples/hdom-canvas-draw/tsconfig.json
new file mode 100644
index 0000000000..bbf112cc18
--- /dev/null
+++ b/examples/hdom-canvas-draw/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": ".",
+ "target": "es6",
+ "sourceMap": true
+ },
+ "include": [
+ "./src/**/*.ts"
+ ]
+}
diff --git a/examples/hdom-canvas-shapes/README.md b/examples/hdom-canvas-shapes/README.md
index 01c0111db1..9ff45425fd 100644
--- a/examples/hdom-canvas-shapes/README.md
+++ b/examples/hdom-canvas-shapes/README.md
@@ -3,33 +3,34 @@
[Live demo](http://demo.thi.ng/umbrella/hdom-canvas-shapes/)
This example demonstrates different features of the upcoming
-[@thi.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom-canvas)
+[@thi.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/master/packages/hdom-canvas)
package to declare canvas scenegraphs using the same hiccup syntax as
the rest of the UI. These shape elements (children of the `canvas`
component) are defined via a SVG-like approach (though not using
stringified geometry) and, using the new branch-local behavior feature
of
-[@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom),
+[@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom),
are translated into canvas API draw calls. Shapes can be grouped and any
attributes defined on group nodes will be inherited by all children
(same as in SVG).
Furthermore, this example acts as a test bed for
-[@thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-svg)'s
+[@thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-svg)'s
`convertTree()` function to translate and then serialize these scene
trees to downloadable SVG files.
See the [@thi.ng/hdom-canvas
-readme](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom-canvas)
+readme](https://github.com/thi-ng/umbrella/tree/master/packages/hdom-canvas)
for further details.
Related examples:
-- [hdom-canvas-clock](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-clock)
+- [hdom-canvas-clock](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-clock)
+- [hdom-canvas-draw](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-draw)
Dataflow diagram:
-![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/hdom-canvas-shapes.png)
+![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/hdom-canvas-shapes.png)
## Building
@@ -40,7 +41,7 @@ The example project also assumes that [Parcel](https://parceljs.org) is
installed globally.
```bash
-git clone -b develop https://github.com/thi-ng/umbrella.git
+git clone https://github.com/thi-ng/umbrella.git
cd umbrella/examples/hdom-canvas-shapes
yarn install
yarn start
diff --git a/examples/hdom-canvas-shapes/package.json b/examples/hdom-canvas-shapes/package.json
index ce4d870d9e..f8cb57e562 100644
--- a/examples/hdom-canvas-shapes/package.json
+++ b/examples/hdom-canvas-shapes/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open --no-cache"
},
"devDependencies": {
diff --git a/examples/hdom-canvas-shapes/src/index.ts b/examples/hdom-canvas-shapes/src/index.ts
index 952b509677..6c43014dda 100644
--- a/examples/hdom-canvas-shapes/src/index.ts
+++ b/examples/hdom-canvas-shapes/src/index.ts
@@ -11,7 +11,7 @@ import { map } from "@thi.ng/transducers/xform/map";
import { Mat23 } from "@thi.ng/vectors/mat23";
// for testing SVG conversion
-import { serialize } from "@thi.ng/hiccup";
+import { COMMENT, serialize } from "@thi.ng/hiccup";
import { convertTree } from "@thi.ng/hiccup-svg/convert";
import { svg } from "@thi.ng/hiccup-svg/svg";
@@ -271,7 +271,7 @@ scene.transform(
["div.ma2.tc", TESTS[id].desc],
["a.link",
- { href: "https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-shapes" },
+ { href: "https://github.com/thi-ng/umbrella/tree/master/examples/hdom-canvas-shapes" },
"Source code"]
]
),
@@ -289,6 +289,7 @@ sync({
serialize(
svg(
{ width: 300, height: 300, stroke: "none", fill: "none" },
+ [COMMENT, `generated by @thi.ng/hiccup-svg @ ${new Date()}`],
convertTree(scene.shapes)
)
)
diff --git a/examples/hdom-dropdown-fuzzy/package.json b/examples/hdom-dropdown-fuzzy/package.json
index 8c7f24f438..daf8a0cf02 100644
--- a/examples/hdom-dropdown-fuzzy/package.json
+++ b/examples/hdom-dropdown-fuzzy/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-dropdown/package.json b/examples/hdom-dropdown/package.json
index 383df85b36..2038080090 100644
--- a/examples/hdom-dropdown/package.json
+++ b/examples/hdom-dropdown/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-theme-adr-0003/README.md b/examples/hdom-theme-adr-0003/README.md
index 7927f0a027..7d42d4a39c 100644
--- a/examples/hdom-theme-adr-0003/README.md
+++ b/examples/hdom-theme-adr-0003/README.md
@@ -3,7 +3,7 @@
[Live demo](https://demo.thi.ng/umbrella/hdom-theme-adr-0003/)
WIP demo of themed component proposal discussed in
-[ADR-0003](https://github.com/thi-ng/umbrella/blob/develop/packages/hdom-components/adr/0003-component-configuration-via-context.md).
+[ADR-0003](https://github.com/thi-ng/umbrella/blob/master/packages/hdom-components/adr/0003-component-configuration-via-context.md).
```bash
git clone https://github.com/thi-ng/umbrella.git
diff --git a/examples/hdom-theme-adr-0003/package.json b/examples/hdom-theme-adr-0003/package.json
index 2a356de8ab..f96eeb0a32 100644
--- a/examples/hdom-theme-adr-0003/package.json
+++ b/examples/hdom-theme-adr-0003/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hdom-theme-adr-0003/src/index.ts b/examples/hdom-theme-adr-0003/src/index.ts
index 17f9fada5f..9e0b6e2735 100644
--- a/examples/hdom-theme-adr-0003/src/index.ts
+++ b/examples/hdom-theme-adr-0003/src/index.ts
@@ -140,8 +140,8 @@ const app = (ctx) =>
[btFixed, { onclick: () => alert("hi"), selected: true }, "Selected"],
[btFixed, { disabled: true }, "Disabled"]],
["p",
- "Please see ", [link, "https://github.com/thi-ng/umbrella/blob/develop/packages/hdom-components/adr/0003-component-configuration-via-context.md", "ADR-0003"], " for details of this approach."],
- ["p", [link, "https://github.com/thi-ng/umbrella/blob/develop/examples/hdom-theme-adr-0003", "Source"]]
+ "Please see ", [link, "https://github.com/thi-ng/umbrella/blob/master/packages/hdom-components/adr/0003-component-configuration-via-context.md", "ADR-0003"], " for details of this approach."],
+ ["p", [link, "https://github.com/thi-ng/umbrella/blob/master/examples/hdom-theme-adr-0003", "Source"]]
];
start(app, { ctx });
diff --git a/examples/hmr-basics/package.json b/examples/hmr-basics/package.json
index 73520958a1..60d17697e2 100644
--- a/examples/hmr-basics/package.json
+++ b/examples/hmr-basics/package.json
@@ -5,8 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "clean": "rm -rf out",
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/hydrate-basics/package.json b/examples/hydrate-basics/package.json
index 97e6f64cfd..85c6f882db 100644
--- a/examples/hydrate-basics/package.json
+++ b/examples/hydrate-basics/package.json
@@ -5,7 +5,8 @@
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
- "build": "parcel build index.html -d out --no-source-maps --no-cache --detailed-report",
+ "clean": "rm -rf .cache build out",
+ "build": "yarn clean && parcel build index.html -d out --no-source-maps --no-cache --detailed-report --public-url ./",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
diff --git a/examples/interceptor-basics/README.md b/examples/interceptor-basics/README.md
index e8e4ec03df..17744b1f5c 100644
--- a/examples/interceptor-basics/README.md
+++ b/examples/interceptor-basics/README.md
@@ -1,6 +1,6 @@
# interceptor-basics
-[Live demo](https://demo.thi.ng/umbrella/interceptor-basics/)
+[Live demo](http://demo.thi.ng/umbrella/interceptor-basics/)
```bash
git clone https://github.com/thi-ng/umbrella.git
@@ -8,3 +8,11 @@ cd umbrella/examples/interceptor-basics
yarn install
yarn start
```
+
+## Authors
+
+- Karsten Schmidt
+
+## License
+
+© 2018 Karsten Schmidt // Apache Software License 2.0
diff --git a/examples/interceptor-basics/index.html b/examples/interceptor-basics/index.html
index 854663bf78..e6fa25117b 100644
--- a/examples/interceptor-basics/index.html
+++ b/examples/interceptor-basics/index.html
@@ -1,57 +1,16 @@
-
interceptor-basics
+
-
- This example demonstrates the use of @thi.ng/atom's event bus and interceptor driven event handling features.
- See sources for detailed comments (blog post forthcoming):
-
-
-
+
-
-
\ No newline at end of file
+