From 19b0a55448a319bd2b7e07aad852d49516a3fb40 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 9 Dec 2018 15:06:29 +0000 Subject: [PATCH 01/35] perf(diff): further array caching/reuse --- packages/diff/src/array.ts | 43 ++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/packages/diff/src/array.ts b/packages/diff/src/array.ts index 0ba79798f2..d0f8d6d17d 100644 --- a/packages/diff/src/array.ts +++ b/packages/diff/src/array.ts @@ -1,6 +1,24 @@ import { equiv as _equiv } from "@thi.ng/equiv"; import { ArrayDiff, DiffMode } from "./api"; +let _cachedFP: Int32Array; +let _cachedPath: Int32Array; + +let _cachedEPC: number[] = []; +let _cachedPathPos: number[] = []; + +const cachedFP = + (size: number) => + _cachedFP && _cachedFP.length >= size ? + _cachedFP : + (_cachedFP = new Int32Array(size)); + +const cachedPath = + (size: number) => + _cachedPath && _cachedPath.length >= size ? + _cachedPath : + (_cachedPath = new Int32Array(size)); + const simpleDiff = ( state: ArrayDiff, src: ArrayLike, @@ -36,6 +54,11 @@ const simpleDiff = ( * * Various optimizations, fixes & refactorings. * By default uses `@thi.ng/equiv` for equality checks. + * + * @param a "old" array + * @param b "new" array + * @param mode result mode + * @param equiv equality predicate function */ export const diffArray = ( a: ArrayLike, @@ -76,10 +99,12 @@ export const diffArray = ( const delta = nb - na; const doff = delta + offset; const size = na + nb + 3; - const path = new Array(size).fill(-1); - const fp = new Array(size).fill(-1); - const epc = []; - const pathPos = []; + const path = cachedPath(size).fill(-1, 0, size); + const fp = cachedFP(size).fill(-1, 0, size); + const epc = _cachedEPC; + const pathPos = _cachedPathPos; + epc.length = 0; + pathPos.length = 0; const snake = (k, p, pp) => { const koff = k + offset; @@ -159,22 +184,18 @@ const buildFullLog = ( const ppx = pathPos[e]; const ppy = pathPos[e + 1]; const d = ppy - ppx; - let v; while (px < ppx || py < ppy) { const dp = py - px; if (d > dp) { - adds[py] = v = b[py]; - linear.push(aID, py, v); + linear.push(aID, py, adds[py] = b[py]); py++; } else if (d < dp) { - dels[px] = v = a[px]; - linear.push(dID, px, v); + linear.push(dID, px, dels[px] = a[px]); px++; } else { - _const[px] = v = a[px]; - linear.push(0, px, v); + linear.push(0, px, _const[px] = a[px]); px++; py++; } From 20e0884bc3f8946415a5c5f2e3e04e00b08ef736 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 9 Dec 2018 15:09:02 +0000 Subject: [PATCH 02/35] Publish - @thi.ng/diff@2.0.1 - @thi.ng/hdom-canvas@0.1.14 - @thi.ng/hdom@5.2.2 - @thi.ng/transducers-hdom@1.2.5 --- packages/diff/CHANGELOG.md | 11 +++++++++++ packages/diff/package.json | 2 +- packages/hdom-canvas/CHANGELOG.md | 8 ++++++++ packages/hdom-canvas/package.json | 6 +++--- packages/hdom/CHANGELOG.md | 8 ++++++++ packages/hdom/package.json | 4 ++-- packages/transducers-hdom/CHANGELOG.md | 8 ++++++++ packages/transducers-hdom/package.json | 4 ++-- 8 files changed, 43 insertions(+), 8 deletions(-) diff --git a/packages/diff/CHANGELOG.md b/packages/diff/CHANGELOG.md index 77c30fc02e..845fed649a 100644 --- a/packages/diff/CHANGELOG.md +++ b/packages/diff/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@2.0.0...@thi.ng/diff@2.0.1) (2018-12-09) + + +### Performance Improvements + +* **diff:** further array caching/reuse ([19b0a55](https://github.com/thi-ng/umbrella/commit/19b0a55)) + + + + + # [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.1.4...@thi.ng/diff@2.0.0) (2018-12-08) diff --git a/packages/diff/package.json b/packages/diff/package.json index 8d6c9dabb1..edf78b8d80 100644 --- a/packages/diff/package.json +++ b/packages/diff/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/diff", - "version": "2.0.0", + "version": "2.0.1", "description": "Array & object Diff", "main": "./index.js", "typings": "./index.d.ts", diff --git a/packages/hdom-canvas/CHANGELOG.md b/packages/hdom-canvas/CHANGELOG.md index e5bee8fc8b..c290631a5a 100644 --- a/packages/hdom-canvas/CHANGELOG.md +++ b/packages/hdom-canvas/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@0.1.13...@thi.ng/hdom-canvas@0.1.14) (2018-12-09) + +**Note:** Version bump only for package @thi.ng/hdom-canvas + + + + + ## [0.1.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@0.1.12...@thi.ng/hdom-canvas@0.1.13) (2018-12-08) diff --git a/packages/hdom-canvas/package.json b/packages/hdom-canvas/package.json index 83d632b5a2..e9c80ca1f3 100644 --- a/packages/hdom-canvas/package.json +++ b/packages/hdom-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-canvas", - "version": "0.1.13", + "version": "0.1.14", "description": "Declarative canvas scenegraph & visualization for @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -30,8 +30,8 @@ "dependencies": { "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", - "@thi.ng/diff": "^2.0.0", - "@thi.ng/hdom": "^5.2.1" + "@thi.ng/diff": "^2.0.1", + "@thi.ng/hdom": "^5.2.2" }, "keywords": [ "ES6", diff --git a/packages/hdom/CHANGELOG.md b/packages/hdom/CHANGELOG.md index 3f2bbe8a3d..3f57c01f89 100644 --- a/packages/hdom/CHANGELOG.md +++ b/packages/hdom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@5.2.1...@thi.ng/hdom@5.2.2) (2018-12-09) + +**Note:** Version bump only for package @thi.ng/hdom + + + + + ## [5.2.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@5.2.0...@thi.ng/hdom@5.2.1) (2018-12-08) **Note:** Version bump only for package @thi.ng/hdom diff --git a/packages/hdom/package.json b/packages/hdom/package.json index 79f42ac170..131947c3b6 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom", - "version": "5.2.1", + "version": "5.2.2", "description": "Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors", "main": "./index.js", "typings": "./index.d.ts", @@ -31,7 +31,7 @@ "dependencies": { "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", - "@thi.ng/diff": "^2.0.0", + "@thi.ng/diff": "^2.0.1", "@thi.ng/equiv": "^0.1.14", "@thi.ng/hiccup": "^2.6.1" }, diff --git a/packages/transducers-hdom/CHANGELOG.md b/packages/transducers-hdom/CHANGELOG.md index 94eec2b033..29b464410d 100644 --- a/packages/transducers-hdom/CHANGELOG.md +++ b/packages/transducers-hdom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@1.2.4...@thi.ng/transducers-hdom@1.2.5) (2018-12-09) + +**Note:** Version bump only for package @thi.ng/transducers-hdom + + + + + ## [1.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@1.2.3...@thi.ng/transducers-hdom@1.2.4) (2018-12-08) **Note:** Version bump only for package @thi.ng/transducers-hdom diff --git a/packages/transducers-hdom/package.json b/packages/transducers-hdom/package.json index df3a2275e1..025d368337 100644 --- a/packages/transducers-hdom/package.json +++ b/packages/transducers-hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-hdom", - "version": "1.2.4", + "version": "1.2.5", "description": "Transducer based UI updater for @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/checks": "^1.5.13", - "@thi.ng/hdom": "^5.2.1", + "@thi.ng/hdom": "^5.2.2", "@thi.ng/transducers": "^2.2.4" }, "keywords": [ From 71300e927c39483af0de91caa7fdeb6f5385851a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 9 Dec 2018 18:00:26 +0000 Subject: [PATCH 03/35] docs: update main readme --- README.md | 157 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 97 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 9e05146fff..ddd104b1eb 100644 --- a/README.md +++ b/README.md @@ -37,66 +37,103 @@ packages) in the [examples](./examples) directory. ## Projects -| Projects | Version | Changelog | Description | -|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|-----------------------------------------------| -| [`@thi.ng/api`](./packages/api) | [![version](https://img.shields.io/npm/v/@thi.ng/api.svg)](https://www.npmjs.com/package/@thi.ng/api) | [changelog](./packages/api/CHANGELOG.md) | Common types, decorators, mixins | -| [`@thi.ng/associative`](./packages/associative) | [![version](https://img.shields.io/npm/v/@thi.ng/associative.svg)](https://www.npmjs.com/package/@thi.ng/associative) | [changelog](./packages/associative/CHANGELOG.md) | Alt Set & Map implementations | -| [`@thi.ng/atom`](./packages/atom) | [![version](https://img.shields.io/npm/v/@thi.ng/atom.svg)](https://www.npmjs.com/package/@thi.ng/atom) | [changelog](./packages/atom/CHANGELOG.md) | Immutable value wrappers, views, history | -| [`@thi.ng/bench`](./packages/bench) | [![version](https://img.shields.io/npm/v/@thi.ng/bench.svg)](https://www.npmjs.com/package/@thi.ng/bench) | [changelog](./packages/bench/CHANGELOG.md) | Basic benchmarking helpers | -| [`@thi.ng/binary`](./packages/binary) | [![version](https://img.shields.io/npm/v/@thi.ng/binary.svg)](https://www.npmjs.com/package/@thi.ng/binary) | [changelog](./packages/binary/CHANGELOG.md) | Assorted binary / bitwise ops, utilities | -| [`@thi.ng/bitstream`](./packages/bitstream) | [![version](https://img.shields.io/npm/v/@thi.ng/bitstream.svg)](https://www.npmjs.com/package/@thi.ng/bitstream) | [changelog](./packages/bitstream/CHANGELOG.md) | Bitwise input / output streams | -| [`@thi.ng/cache`](./packages/cache) | [![version](https://img.shields.io/npm/v/@thi.ng/cache.svg)](https://www.npmjs.com/package/@thi.ng/cache) | [changelog](./packages/cache/CHANGELOG.md) | In-memory caches / strategies | -| [`@thi.ng/checks`](./packages/checks) | [![version](https://img.shields.io/npm/v/@thi.ng/checks.svg)](https://www.npmjs.com/package/@thi.ng/checks) | [changelog](./packages/checks/CHANGELOG.md) | Type & value checks | -| [`@thi.ng/compare`](./packages/compare) | [![version](https://img.shields.io/npm/v/@thi.ng/compare.svg)](https://www.npmjs.com/package/@thi.ng/compare) | [changelog](./packages/compare/CHANGELOG.md) | Comparator | -| [`@thi.ng/csp`](./packages/csp) | [![version](https://img.shields.io/npm/v/@thi.ng/csp.svg)](https://www.npmjs.com/package/@thi.ng/csp) | [changelog](./packages/csp/CHANGELOG.md) | Channel based async ops | -| [`@thi.ng/dcons`](./packages/dcons) | [![version](https://img.shields.io/npm/v/@thi.ng/dcons.svg)](https://www.npmjs.com/package/@thi.ng/dcons) | [changelog](./packages/dcons/CHANGELOG.md) | Doubly-linked list | -| [`@thi.ng/defmulti`](./packages/defmulti) | [![version](https://img.shields.io/npm/v/@thi.ng/defmulti.svg)](https://www.npmjs.com/package/@thi.ng/defmulti) | [changelog](./packages/defmulti/CHANGELOG.md) | Dynamic multiple dispatch | -| [`@thi.ng/dgraph`](./packages/dgraph) | [![version](https://img.shields.io/npm/v/@thi.ng/dgraph.svg)](https://www.npmjs.com/package/@thi.ng/dgraph) | [changelog](./packages/dgraph/CHANGELOG.md) | Dependency graph | -| [`@thi.ng/diff`](./packages/diff) | [![version](https://img.shields.io/npm/v/@thi.ng/diff.svg)](https://www.npmjs.com/package/@thi.ng/diff) | [changelog](./packages/diff/CHANGELOG.md) | Array & object diffing | -| [`@thi.ng/dlogic`](./packages/dlogic) | [![version](https://img.shields.io/npm/v/@thi.ng/dlogic.svg)](https://www.npmjs.com/package/@thi.ng/dlogic) | [changelog](./packages/dlogic/CHANGELOG.md) | Digital logic ops / constructs | -| [`@thi.ng/dot`](./packages/dot) | [![version](https://img.shields.io/npm/v/@thi.ng/dot.svg)](https://www.npmjs.com/package/@thi.ng/dot) | [changelog](./packages/dot/CHANGELOG.md) | Graphviz DOM & export | -| [`@thi.ng/dsp`](./packages/dsp) | [![version](https://img.shields.io/npm/v/@thi.ng/dsp.svg)](https://www.npmjs.com/package/@thi.ng/dsp) | [changelog](./packages/dsp/CHANGELOG.md) | DSP utils, oscillators | -| [`@thi.ng/equiv`](./packages/equiv) | [![version](https://img.shields.io/npm/v/@thi.ng/equiv.svg)](https://www.npmjs.com/package/@thi.ng/equiv) | [changelog](./packages/equiv/CHANGELOG.md) | Deep value equivalence checking | -| [`@thi.ng/errors`](./packages/errors) | [![version](https://img.shields.io/npm/v/@thi.ng/errors.svg)](https://www.npmjs.com/package/@thi.ng/errors) | [changelog](./packages/errors/CHANGELOG.md) | Custom error types | -| [`@thi.ng/geom`](./packages/geom) | [![version](https://img.shields.io/npm/v/@thi.ng/geom.svg)](https://www.npmjs.com/package/@thi.ng/geom) | [changelog](./packages/geom/CHANGELOG.md) | 2D geometry types & operations | -| [`@thi.ng/geom-accel`](./packages/geom-accel) | [![version](https://img.shields.io/npm/v/@thi.ng/geom-accel.svg)](https://www.npmjs.com/package/@thi.ng/geom-accel) | [changelog](./packages/geom-accel/CHANGELOG.md) | Spatial indexing data structures | -| [`@thi.ng/hdom`](./packages/hdom) | [![version](https://img.shields.io/npm/v/@thi.ng/hdom.svg)](https://www.npmjs.com/package/@thi.ng/hdom) | [changelog](./packages/hdom/CHANGELOG.md) | Hiccup based VDOM & diffing | -| [`@thi.ng/hdom-canvas`](./packages/hdom-canvas) | [![version](https://img.shields.io/npm/v/@thi.ng/hdom-canvas.svg)](https://www.npmjs.com/package/@thi.ng/hdom-canvas) | [changelog](./packages/hdom-canvas/CHANGELOG.md) | hdom based declarative canvas drawing | -| [`@thi.ng/hdom-components`](./packages/hdom-components) | [![version](https://img.shields.io/npm/v/@thi.ng/hdom-components.svg)](https://www.npmjs.com/package/@thi.ng/hdom-components) | [changelog](./packages/hdom-components/CHANGELOG.md) | hdom based UI components | -| [`@thi.ng/heaps`](./packages/heaps) | [![version](https://img.shields.io/npm/v/@thi.ng/heaps.svg)](https://www.npmjs.com/package/@thi.ng/heaps) | [changelog](./packages/heaps/CHANGELOG.md) | Binary & d-ary heap impls | -| [`@thi.ng/hiccup`](./packages/hiccup) | [![version](https://img.shields.io/npm/v/@thi.ng/hiccup.svg)](https://www.npmjs.com/package/@thi.ng/hiccup) | [changelog](./packages/hiccup/CHANGELOG.md) | S-expression based HTML/XML serialization | -| [`@thi.ng/hiccup-css`](./packages/hiccup-css) | [![version](https://img.shields.io/npm/v/@thi.ng/hiccup-css.svg)](https://www.npmjs.com/package/@thi.ng/hiccup-css) | [changelog](./packages/hiccup-css/CHANGELOG.md) | CSS from nested JS data structures | -| [`@thi.ng/hiccup-svg`](./packages/hiccup-svg) | [![version](https://img.shields.io/npm/v/@thi.ng/hiccup-svg.svg)](https://www.npmjs.com/package/@thi.ng/hiccup-svg) | [changelog](./packages/hiccup-svg/CHANGELOG.md) | hiccup based SVG vocab | -| [`@thi.ng/iges`](./packages/iges) | [![version](https://img.shields.io/npm/v/@thi.ng/iges.svg)](https://www.npmjs.com/package/@thi.ng/iges) | [changelog](./packages/iges/CHANGELOG.md) | IGES format geometry serialization | -| [`@thi.ng/interceptors`](./packages/interceptors) | [![version](https://img.shields.io/npm/v/@thi.ng/interceptors.svg)](https://www.npmjs.com/package/@thi.ng/interceptors) | [changelog](./packages/interceptors/CHANGELOG.md) | Composable event handlers & processor | -| [`@thi.ng/iterators`](./packages/iterators) | [![version](https://img.shields.io/npm/v/@thi.ng/iterators.svg)](https://www.npmjs.com/package/@thi.ng/iterators) | [changelog](./packages/iterators/CHANGELOG.md) | ES6 generators / iterators | -| [`@thi.ng/malloc`](./packages/malloc) | [![version](https://img.shields.io/npm/v/@thi.ng/malloc.svg)](https://www.npmjs.com/package/@thi.ng/malloc) | [changelog](./packages/malloc/CHANGELOG.md) | Raw & typed array memory pool & allocator | -| [`@thi.ng/math`](./packages/math) | [![version](https://img.shields.io/npm/v/@thi.ng/math.svg)](https://www.npmjs.com/package/@thi.ng/math) | [changelog](./packages/math/CHANGELOG.md) | Assorted common math functions & utilities | -| [`@thi.ng/memoize`](./packages/memoize) | [![version](https://img.shields.io/npm/v/@thi.ng/memoize.svg)](https://www.npmjs.com/package/@thi.ng/memoize) | [changelog](./packages/memoize/CHANGELOG.md) | Function memoization w/ customizable caching | -| [`@thi.ng/morton`](./packages/morton) | [![version](https://img.shields.io/npm/v/@thi.ng/morton.svg)](https://www.npmjs.com/package/@thi.ng/morton) | [changelog](./packages/morton/CHANGELOG.md) | Z-order-curve / Morton coding | -| [`@thi.ng/paths`](./packages/paths) | [![version](https://img.shields.io/npm/v/@thi.ng/paths.svg)](https://www.npmjs.com/package/@thi.ng/paths) | [changelog](./packages/paths/CHANGELOG.md) | Immutable nested object accessors | -| [`@thi.ng/pointfree`](./packages/pointfree) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree.svg)](https://www.npmjs.com/package/@thi.ng/pointfree) | [changelog](./packages/pointfree/CHANGELOG.md) | stack-based DSL & functional composition | -| [`@thi.ng/pointfree-lang`](./packages/pointfree-lang) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree-lang.svg)](https://www.npmjs.com/package/@thi.ng/pointfree-lang) | [changelog](./packages/pointfree-lang/CHANGELOG.md) | Forth-like syntax layer for @thi.ng/pointfree | -| [`@thi.ng/random`](./packages/random) | [![version](https://img.shields.io/npm/v/@thi.ng/random.svg)](https://www.npmjs.com/package/@thi.ng/random) | [changelog](./packages/random/CHANGELOG.md) | Seedable PRNG implementations w/ unified API | -| [`@thi.ng/range-coder`](./packages/range-coder) | [![version](https://img.shields.io/npm/v/@thi.ng/range-coder.svg)](https://www.npmjs.com/package/@thi.ng/range-coder) | [changelog](./packages/range-coder/CHANGELOG.md) | Binary data Range encoder / decoder | -| [`@thi.ng/rle-pack`](./packages/rle-pack) | [![version](https://img.shields.io/npm/v/@thi.ng/rle-pack.svg)](https://www.npmjs.com/package/@thi.ng/rle-pack) | [changelog](./packages/rle-pack/CHANGELOG.md) | Run-length encoding data compression | -| [`@thi.ng/resolve-map`](./packages/resolve-map) | [![version](https://img.shields.io/npm/v/@thi.ng/resolve-map.svg)](https://www.npmjs.com/package/@thi.ng/resolve-map) | [changelog](./packages/resolve-map/CHANGELOG.md) | DAG computations & value resolution | -| [`@thi.ng/router`](./packages/router) | [![version](https://img.shields.io/npm/v/@thi.ng/router.svg)](https://www.npmjs.com/package/@thi.ng/router) | [changelog](./packages/router/CHANGELOG.md) | Customizable browser & non-browser router | -| [`@thi.ng/rstream`](./packages/rstream) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream.svg)](https://www.npmjs.com/package/@thi.ng/rstream) | [changelog](./packages/rstream/CHANGELOG.md) | Push-based, reactive event stream primitves | -| [`@thi.ng/rstream-csp`](./packages/rstream-csp) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-csp.svg)](https://www.npmjs.com/package/@thi.ng/rstream-csp) | [changelog](./packages/rstream-csp/CHANGELOG.md) | Adapter bridge CSP -> rstream | -| [`@thi.ng/rstream-dot`](./packages/rstream-dot) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-dot.svg)](https://www.npmjs.com/package/@thi.ng/rstream-dot) | [changelog](./packages/rstream-dot/CHANGELOG.md) | Graphviz visualization of rstream topologies | -| [`@thi.ng/rstream-gestures`](./packages/rstream-gestures) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-gestures.svg)](https://www.npmjs.com/package/@thi.ng/rstream-gestures) | [changelog](./packages/rstream-gestures/CHANGELOG.md) | Mouse & touch event stream abstraction | -| [`@thi.ng/rstream-graph`](./packages/rstream-graph) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-graph.svg)](https://www.npmjs.com/package/@thi.ng/rstream-graph) | [changelog](./packages/rstream-graph/CHANGELOG.md) | Declarative dataflow graph construction | -| [`@thi.ng/rstream-log`](./packages/rstream-log) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-log.svg)](https://www.npmjs.com/package/@thi.ng/rstream-log) | [changelog](./packages/rstream-log/CHANGELOG.md) | Hierarchical structured data logging | -| [`@thi.ng/rstream-query`](./packages/rstream-query) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-query.svg)](https://www.npmjs.com/package/@thi.ng/rstream-query) | [changelog](./packages/rstream-query/CHANGELOG.md) | Triple store & query engine | -| [`@thi.ng/sax`](./packages/sax) | [![version](https://img.shields.io/npm/v/@thi.ng/sax.svg)](https://www.npmjs.com/package/@thi.ng/sax) | [changelog](./packages/sax/CHANGELOG.md) | SAX-like XML parser / transducer | -| [`@thi.ng/strings`](./packages/strings) | [![version](https://img.shields.io/npm/v/@thi.ng/strings.svg)](https://www.npmjs.com/package/@thi.ng/strings) | [changelog](./packages/strings/CHANGELOG.md) | Higher-order string formatting utils | -| [`@thi.ng/transducers`](./packages/transducers) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers.svg)](https://www.npmjs.com/package/@thi.ng/transducers) | [changelog](./packages/transducers/CHANGELOG.md) | Composable data transformations | -| [`@thi.ng/transducers-fsm`](./packages/transducers-fsm) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers-fsm.svg)](https://www.npmjs.com/package/@thi.ng/transducers-fsm) | [changelog](./packages/transducers-fsm/CHANGELOG.md) | Finite State Machine | -| [`@thi.ng/transducers-hdom`](./packages/transducers-hdom) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers-hdom.svg)](https://www.npmjs.com/package/@thi.ng/transducers-hdom) | [changelog](./packages/transducers-hdom/CHANGELOG.md) | Transducer based hdom UI updates | -| [`@thi.ng/transducers-stats`](./packages/transducers-stats) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers-stats.svg)](https://www.npmjs.com/package/@thi.ng/transducers-stats) | [changelog](./packages/transducers-stats/CHANGELOG.md) | Technical / statistical analysis | -| [`@thi.ng/unionstruct`](./packages/unionstruct) | [![version](https://img.shields.io/npm/v/@thi.ng/unionstruct.svg)](https://www.npmjs.com/package/@thi.ng/unionstruct) | [changelog](./packages/unionstruct/CHANGELOG.md) | Wrapper for C-like structs / unions | -| [`@thi.ng/vectors`](./packages/vectors) | [![version](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) | [changelog](./packages/vectors/CHANGELOG.md) | Memory-mapped vector & matrix operations | +### Fundamentals + +| Project | Version | Changelog | Description | +|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------|-----------------------------------------------|----------------------------------------------| +| [`@thi.ng/api`](./packages/api) | [![version](https://img.shields.io/npm/v/@thi.ng/api.svg)](https://www.npmjs.com/package/@thi.ng/api) | [changelog](./packages/api/CHANGELOG.md) | Common types, decorators, mixins | +| [`@thi.ng/bench`](./packages/bench) | [![version](https://img.shields.io/npm/v/@thi.ng/bench.svg)](https://www.npmjs.com/package/@thi.ng/bench) | [changelog](./packages/bench/CHANGELOG.md) | Basic benchmarking helpers | +| [`@thi.ng/checks`](./packages/checks) | [![version](https://img.shields.io/npm/v/@thi.ng/checks.svg)](https://www.npmjs.com/package/@thi.ng/checks) | [changelog](./packages/checks/CHANGELOG.md) | Type & value checks | +| [`@thi.ng/compare`](./packages/compare) | [![version](https://img.shields.io/npm/v/@thi.ng/compare.svg)](https://www.npmjs.com/package/@thi.ng/compare) | [changelog](./packages/compare/CHANGELOG.md) | Comparator | +| [`@thi.ng/defmulti`](./packages/defmulti) | [![version](https://img.shields.io/npm/v/@thi.ng/defmulti.svg)](https://www.npmjs.com/package/@thi.ng/defmulti) | [changelog](./packages/defmulti/CHANGELOG.md) | Dynamic multiple dispatch | +| [`@thi.ng/dsp`](./packages/dsp) | [![version](https://img.shields.io/npm/v/@thi.ng/dsp.svg)](https://www.npmjs.com/package/@thi.ng/dsp) | [changelog](./packages/dsp/CHANGELOG.md) | DSP utils, oscillators | +| [`@thi.ng/equiv`](./packages/equiv) | [![version](https://img.shields.io/npm/v/@thi.ng/equiv.svg)](https://www.npmjs.com/package/@thi.ng/equiv) | [changelog](./packages/equiv/CHANGELOG.md) | Deep value equivalence checking | +| [`@thi.ng/errors`](./packages/errors) | [![version](https://img.shields.io/npm/v/@thi.ng/errors.svg)](https://www.npmjs.com/package/@thi.ng/errors) | [changelog](./packages/errors/CHANGELOG.md) | Custom error types | +| [`@thi.ng/math`](./packages/math) | [![version](https://img.shields.io/npm/v/@thi.ng/math.svg)](https://www.npmjs.com/package/@thi.ng/math) | [changelog](./packages/math/CHANGELOG.md) | Assorted common math functions & utilities | +| [`@thi.ng/memoize`](./packages/memoize) | [![version](https://img.shields.io/npm/v/@thi.ng/memoize.svg)](https://www.npmjs.com/package/@thi.ng/memoize) | [changelog](./packages/memoize/CHANGELOG.md) | Function memoization w/ customizable caching | +| [`@thi.ng/paths`](./packages/paths) | [![version](https://img.shields.io/npm/v/@thi.ng/paths.svg)](https://www.npmjs.com/package/@thi.ng/paths) | [changelog](./packages/paths/CHANGELOG.md) | Immutable nested object accessors | +| [`@thi.ng/random`](./packages/random) | [![version](https://img.shields.io/npm/v/@thi.ng/random.svg)](https://www.npmjs.com/package/@thi.ng/random) | [changelog](./packages/random/CHANGELOG.md) | Seedable PRNG implementations w/ unified API | +| [`@thi.ng/strings`](./packages/strings) | [![version](https://img.shields.io/npm/v/@thi.ng/strings.svg)](https://www.npmjs.com/package/@thi.ng/strings) | [changelog](./packages/strings/CHANGELOG.md) | Higher-order string formatting utils | + +### Iterator, stream & sequence processing + +| Project | Version | Changelog | Description | +|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|----------------------------------| +| [`@thi.ng/csp`](./packages/csp) | [![version](https://img.shields.io/npm/v/@thi.ng/csp.svg)](https://www.npmjs.com/package/@thi.ng/csp) | [changelog](./packages/csp/CHANGELOG.md) | Channel based async ops | +| [`@thi.ng/iterators`](./packages/iterators) | [![version](https://img.shields.io/npm/v/@thi.ng/iterators.svg)](https://www.npmjs.com/package/@thi.ng/iterators) | [changelog](./packages/iterators/CHANGELOG.md) | ES6 generators / iterators | +| [`@thi.ng/sax`](./packages/sax) | [![version](https://img.shields.io/npm/v/@thi.ng/sax.svg)](https://www.npmjs.com/package/@thi.ng/sax) | [changelog](./packages/sax/CHANGELOG.md) | SAX-like XML parser / transducer | +| [`@thi.ng/transducers`](./packages/transducers) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers.svg)](https://www.npmjs.com/package/@thi.ng/transducers) | [changelog](./packages/transducers/CHANGELOG.md) | Composable data transformations | +| [`@thi.ng/transducers-fsm`](./packages/transducers-fsm) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers-fsm.svg)](https://www.npmjs.com/package/@thi.ng/transducers-fsm) | [changelog](./packages/transducers-fsm/CHANGELOG.md) | Finite state transducer | +| [`@thi.ng/transducers-hdom`](./packages/transducers-hdom) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers-hdom.svg)](https://www.npmjs.com/package/@thi.ng/transducers-hdom) | [changelog](./packages/transducers-hdom/CHANGELOG.md) | Transducer based hdom UI updates | +| [`@thi.ng/transducers-stats`](./packages/transducers-stats) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers-stats.svg)](https://www.npmjs.com/package/@thi.ng/transducers-stats) | [changelog](./packages/transducers-stats/CHANGELOG.md) | Technical / statistical analysis | + +### Reactive programming + +| Project | Version | Changelog | Description | +|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|----------------------------------------------| +| [`@thi.ng/rstream`](./packages/rstream) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream.svg)](https://www.npmjs.com/package/@thi.ng/rstream) | [changelog](./packages/rstream/CHANGELOG.md) | Push-based, reactive event stream primitves | +| [`@thi.ng/rstream-csp`](./packages/rstream-csp) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-csp.svg)](https://www.npmjs.com/package/@thi.ng/rstream-csp) | [changelog](./packages/rstream-csp/CHANGELOG.md) | Adapter bridge CSP -> rstream | +| [`@thi.ng/rstream-dot`](./packages/rstream-dot) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-dot.svg)](https://www.npmjs.com/package/@thi.ng/rstream-dot) | [changelog](./packages/rstream-dot/CHANGELOG.md) | Graphviz visualization of rstream topologies | +| [`@thi.ng/rstream-gestures`](./packages/rstream-gestures) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-gestures.svg)](https://www.npmjs.com/package/@thi.ng/rstream-gestures) | [changelog](./packages/rstream-gestures/CHANGELOG.md) | Mouse & touch event stream abstraction | +| [`@thi.ng/rstream-graph`](./packages/rstream-graph) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-graph.svg)](https://www.npmjs.com/package/@thi.ng/rstream-graph) | [changelog](./packages/rstream-graph/CHANGELOG.md) | Declarative dataflow graph construction | +| [`@thi.ng/rstream-log`](./packages/rstream-log) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-log.svg)](https://www.npmjs.com/package/@thi.ng/rstream-log) | [changelog](./packages/rstream-log/CHANGELOG.md) | Hierarchical structured data logging | +| [`@thi.ng/rstream-query`](./packages/rstream-query) | [![version](https://img.shields.io/npm/v/@thi.ng/rstream-query.svg)](https://www.npmjs.com/package/@thi.ng/rstream-query) | [changelog](./packages/rstream-query/CHANGELOG.md) | Triple store & query engine | + +### Data structures + +| Project | Version | Changelog | Description | +|-------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|------------------------------------------| +| [`@thi.ng/associative`](./packages/associative) | [![version](https://img.shields.io/npm/v/@thi.ng/associative.svg)](https://www.npmjs.com/package/@thi.ng/associative) | [changelog](./packages/associative/CHANGELOG.md) | Alt Set & Map implementations | +| [`@thi.ng/atom`](./packages/atom) | [![version](https://img.shields.io/npm/v/@thi.ng/atom.svg)](https://www.npmjs.com/package/@thi.ng/atom) | [changelog](./packages/atom/CHANGELOG.md) | Immutable value wrappers, views, history | +| [`@thi.ng/cache`](./packages/cache) | [![version](https://img.shields.io/npm/v/@thi.ng/cache.svg)](https://www.npmjs.com/package/@thi.ng/cache) | [changelog](./packages/cache/CHANGELOG.md) | In-memory caches / strategies | +| [`@thi.ng/dcons`](./packages/dcons) | [![version](https://img.shields.io/npm/v/@thi.ng/dcons.svg)](https://www.npmjs.com/package/@thi.ng/dcons) | [changelog](./packages/dcons/CHANGELOG.md) | Doubly-linked list | +| [`@thi.ng/diff`](./packages/diff) | [![version](https://img.shields.io/npm/v/@thi.ng/diff.svg)](https://www.npmjs.com/package/@thi.ng/diff) | [changelog](./packages/diff/CHANGELOG.md) | Array & object diffing | +| [`@thi.ng/dgraph`](./packages/dgraph) | [![version](https://img.shields.io/npm/v/@thi.ng/dgraph.svg)](https://www.npmjs.com/package/@thi.ng/dgraph) | [changelog](./packages/dgraph/CHANGELOG.md) | Dependency graph | +| [`@thi.ng/heaps`](./packages/heaps) | [![version](https://img.shields.io/npm/v/@thi.ng/heaps.svg)](https://www.npmjs.com/package/@thi.ng/heaps) | [changelog](./packages/heaps/CHANGELOG.md) | Binary & d-ary heap impls | +| [`@thi.ng/resolve-map`](./packages/resolve-map) | [![version](https://img.shields.io/npm/v/@thi.ng/resolve-map.svg)](https://www.npmjs.com/package/@thi.ng/resolve-map) | [changelog](./packages/resolve-map/CHANGELOG.md) | DAG computations & value resolution | + +### Frontend / UI + +| Project | Version | Changelog | Description | +|---------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|-------------------------------------------| +| [`@thi.ng/hdom`](./packages/hdom) | [![version](https://img.shields.io/npm/v/@thi.ng/hdom.svg)](https://www.npmjs.com/package/@thi.ng/hdom) | [changelog](./packages/hdom/CHANGELOG.md) | Hiccup based VDOM & diffing | +| [`@thi.ng/hdom-canvas`](./packages/hdom-canvas) | [![version](https://img.shields.io/npm/v/@thi.ng/hdom-canvas.svg)](https://www.npmjs.com/package/@thi.ng/hdom-canvas) | [changelog](./packages/hdom-canvas/CHANGELOG.md) | hdom based declarative canvas drawing | +| [`@thi.ng/hdom-components`](./packages/hdom-components) | [![version](https://img.shields.io/npm/v/@thi.ng/hdom-components.svg)](https://www.npmjs.com/package/@thi.ng/hdom-components) | [changelog](./packages/hdom-components/CHANGELOG.md) | hdom based UI components | +| [`@thi.ng/hiccup`](./packages/hiccup) | [![version](https://img.shields.io/npm/v/@thi.ng/hiccup.svg)](https://www.npmjs.com/package/@thi.ng/hiccup) | [changelog](./packages/hiccup/CHANGELOG.md) | S-expression based HTML/XML serialization | +| [`@thi.ng/hiccup-css`](./packages/hiccup-css) | [![version](https://img.shields.io/npm/v/@thi.ng/hiccup-css.svg)](https://www.npmjs.com/package/@thi.ng/hiccup-css) | [changelog](./packages/hiccup-css/CHANGELOG.md) | CSS from nested JS data structures | +| [`@thi.ng/hiccup-svg`](./packages/hiccup-svg) | [![version](https://img.shields.io/npm/v/@thi.ng/hiccup-svg.svg)](https://www.npmjs.com/package/@thi.ng/hiccup-svg) | [changelog](./packages/hiccup-svg/CHANGELOG.md) | hiccup based SVG vocab | +| [`@thi.ng/interceptors`](./packages/interceptors) | [![version](https://img.shields.io/npm/v/@thi.ng/interceptors.svg)](https://www.npmjs.com/package/@thi.ng/interceptors) | [changelog](./packages/interceptors/CHANGELOG.md) | Composable event handlers & processor | +| [`@thi.ng/router`](./packages/router) | [![version](https://img.shields.io/npm/v/@thi.ng/router.svg)](https://www.npmjs.com/package/@thi.ng/router) | [changelog](./packages/router/CHANGELOG.md) | Customizable browser & non-browser router | + +### Geometry & visualization + +| Project | Version | Changelog | Description | +|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|------------------------------------------| +| [`@thi.ng/dot`](./packages/dot) | [![version](https://img.shields.io/npm/v/@thi.ng/dot.svg)](https://www.npmjs.com/package/@thi.ng/dot) | [changelog](./packages/dot/CHANGELOG.md) | Graphviz DOM & export | +| [`@thi.ng/geom`](./packages/geom) | [![version](https://img.shields.io/npm/v/@thi.ng/geom.svg)](https://www.npmjs.com/package/@thi.ng/geom) | [changelog](./packages/geom/CHANGELOG.md) | 2D geometry types & operations | +| [`@thi.ng/geom-accel`](./packages/geom-accel) | [![version](https://img.shields.io/npm/v/@thi.ng/geom-accel.svg)](https://www.npmjs.com/package/@thi.ng/geom-accel) | [changelog](./packages/geom-accel/CHANGELOG.md) | Spatial indexing data structures | +| [`@thi.ng/iges`](./packages/iges) | [![version](https://img.shields.io/npm/v/@thi.ng/iges.svg)](https://www.npmjs.com/package/@thi.ng/iges) | [changelog](./packages/iges/CHANGELOG.md) | IGES format geometry serialization | +| [`@thi.ng/vectors`](./packages/vectors) | [![version](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) | [changelog](./packages/vectors/CHANGELOG.md) | Memory-mapped vector & matrix operations | + +## Low-level, binary, memory management + +| Project | Version | Changelog | Description | +|-------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|-------------------------------------------| +| [`@thi.ng/binary`](./packages/binary) | [![version](https://img.shields.io/npm/v/@thi.ng/binary.svg)](https://www.npmjs.com/package/@thi.ng/binary) | [changelog](./packages/binary/CHANGELOG.md) | Assorted binary / bitwise ops, utilities | +| [`@thi.ng/bitstream`](./packages/bitstream) | [![version](https://img.shields.io/npm/v/@thi.ng/bitstream.svg)](https://www.npmjs.com/package/@thi.ng/bitstream) | [changelog](./packages/bitstream/CHANGELOG.md) | Bitwise input / output streams | +| [`@thi.ng/dlogic`](./packages/dlogic) | [![version](https://img.shields.io/npm/v/@thi.ng/dlogic.svg)](https://www.npmjs.com/package/@thi.ng/dlogic) | [changelog](./packages/dlogic/CHANGELOG.md) | Digital logic ops / constructs | +| [`@thi.ng/malloc`](./packages/malloc) | [![version](https://img.shields.io/npm/v/@thi.ng/malloc.svg)](https://www.npmjs.com/package/@thi.ng/malloc) | [changelog](./packages/malloc/CHANGELOG.md) | Raw & typed array memory pool & allocator | +| [`@thi.ng/morton`](./packages/morton) | [![version](https://img.shields.io/npm/v/@thi.ng/morton.svg)](https://www.npmjs.com/package/@thi.ng/morton) | [changelog](./packages/morton/CHANGELOG.md) | Z-order-curve / Morton coding | +| [`@thi.ng/range-coder`](./packages/range-coder) | [![version](https://img.shields.io/npm/v/@thi.ng/range-coder.svg)](https://www.npmjs.com/package/@thi.ng/range-coder) | [changelog](./packages/range-coder/CHANGELOG.md) | Binary data Range encoder / decoder | +| [`@thi.ng/rle-pack`](./packages/rle-pack) | [![version](https://img.shields.io/npm/v/@thi.ng/rle-pack.svg)](https://www.npmjs.com/package/@thi.ng/rle-pack) | [changelog](./packages/rle-pack/CHANGELOG.md) | Run-length encoding data compression | +| [`@thi.ng/unionstruct`](./packages/unionstruct) | [![version](https://img.shields.io/npm/v/@thi.ng/unionstruct.svg)](https://www.npmjs.com/package/@thi.ng/unionstruct) | [changelog](./packages/unionstruct/CHANGELOG.md) | Wrapper for C-like structs / unions | + +## DSLs + +| Project | Version | Changelog | Description | +|-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------| +| [`@thi.ng/pointfree`](./packages/pointfree) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree.svg)](https://www.npmjs.com/package/@thi.ng/pointfree) | [changelog](./packages/pointfree/CHANGELOG.md) | Stack-based DSL & functional composition | +| [`@thi.ng/pointfree-lang`](./packages/pointfree-lang) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree-lang.svg)](https://www.npmjs.com/package/@thi.ng/pointfree-lang) | [changelog](./packages/pointfree-lang/CHANGELOG.md) | Forth-like syntax layer for @thi.ng/pointfree | ## Building From 6726925bc01937582088c46ad0fe010908a6ef80 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 9 Dec 2018 18:04:17 +0000 Subject: [PATCH 04/35] docs: add links to WIP packages --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ddd104b1eb..328b7a6fa0 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ packages) in the [examples](./examples) directory. | [`@thi.ng/iges`](./packages/iges) | [![version](https://img.shields.io/npm/v/@thi.ng/iges.svg)](https://www.npmjs.com/package/@thi.ng/iges) | [changelog](./packages/iges/CHANGELOG.md) | IGES format geometry serialization | | [`@thi.ng/vectors`](./packages/vectors) | [![version](https://img.shields.io/npm/v/@thi.ng/vectors.svg)](https://www.npmjs.com/package/@thi.ng/vectors) | [changelog](./packages/vectors/CHANGELOG.md) | Memory-mapped vector & matrix operations | -## Low-level, binary, memory management +### Low-level, binary, memory management | Project | Version | Changelog | Description | |-------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|-------------------------------------------| @@ -128,13 +128,20 @@ packages) in the [examples](./examples) directory. | [`@thi.ng/rle-pack`](./packages/rle-pack) | [![version](https://img.shields.io/npm/v/@thi.ng/rle-pack.svg)](https://www.npmjs.com/package/@thi.ng/rle-pack) | [changelog](./packages/rle-pack/CHANGELOG.md) | Run-length encoding data compression | | [`@thi.ng/unionstruct`](./packages/unionstruct) | [![version](https://img.shields.io/npm/v/@thi.ng/unionstruct.svg)](https://www.npmjs.com/package/@thi.ng/unionstruct) | [changelog](./packages/unionstruct/CHANGELOG.md) | Wrapper for C-like structs / unions | -## DSLs +### DSLs | Project | Version | Changelog | Description | |-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------| | [`@thi.ng/pointfree`](./packages/pointfree) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree.svg)](https://www.npmjs.com/package/@thi.ng/pointfree) | [changelog](./packages/pointfree/CHANGELOG.md) | Stack-based DSL & functional composition | | [`@thi.ng/pointfree-lang`](./packages/pointfree-lang) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree-lang.svg)](https://www.npmjs.com/package/@thi.ng/pointfree-lang) | [changelog](./packages/pointfree-lang/CHANGELOG.md) | Forth-like syntax layer for @thi.ng/pointfree | +### Experimental packages (WIP / unreleased) + +- [@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) +- [@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) +- [@thi.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vector-pools) +- [@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) + ## Building ```bash From ceb404c468e114cf4676f0d709f1c4f6fc9422ff Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 9 Dec 2018 18:08:51 +0000 Subject: [PATCH 05/35] doc(geom): update readme (add note about geom2) --- packages/geom/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/geom/README.md b/packages/geom/README.md index 7107802064..61c8f20ce5 100644 --- a/packages/geom/README.md +++ b/packages/geom/README.md @@ -26,6 +26,10 @@ thi.ng/geom](https://github.com/thi-ng/geom), as well as [c.thi.ng](https://github.com/thi-ng/c-thing). Currently only 2D shapes & operations are supported. +**This package will soon be replaced by the currently still unreleased +[@thi.ng/geom2](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/geom2) +package** + ## Status ALPHA - major breaking changes forthcoming... From 97bf837ea46f1f525f93370e93027cb946ea754d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Sun, 9 Dec 2018 18:09:14 +0000 Subject: [PATCH 06/35] doc(vectors): update readme (add note about vectors3 & matrices) --- packages/vectors/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/vectors/README.md b/packages/vectors/README.md index cadf12f341..cc8b5bc054 100644 --- a/packages/vectors/README.md +++ b/packages/vectors/README.md @@ -33,6 +33,12 @@ flexible data layouts, incl. [AOS / SOA](https://en.wikipedia.org/wiki/AOS_and_SOA), striped, interleaved, aligned etc. +**This package will soon be replaced by the currently still unreleased +[@thi.ng/vectors3](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/vectors3) +and +[@thi.ng/matrices](https://github.com/thi-ng/umbrella/tree/feature/vec-refactor/packages/matrices) +packages** + ### Vectors In addition to [arbitrary sized From a4e6736201e791aa6ebed95a2740240073a369d3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 10 Dec 2018 12:05:03 +0000 Subject: [PATCH 07/35] feat(hdom): add initial __skip ctrl attrib handling in diffTree() --- packages/hdom/src/diff.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/hdom/src/diff.ts b/packages/hdom/src/diff.ts index 10fe83528f..44607facd6 100644 --- a/packages/hdom/src/diff.ts +++ b/packages/hdom/src/diff.ts @@ -54,6 +54,9 @@ export const diffTree = ( child: number) => { const attribs = curr[1]; + if (attribs.__skip) { + return; + } // always replace element if __diff = false if (attribs.__diff === false) { releaseTree(prev); From 6d387dbd42bf21d7059f618f1a2ad65a560b4c53 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 10 Dec 2018 12:06:03 +0000 Subject: [PATCH 08/35] feat(examples): add hdom-skip example --- examples/hdom-skip/.gitignore | 5 +++ examples/hdom-skip/README.md | 21 ++++++++++++ examples/hdom-skip/index.html | 16 +++++++++ examples/hdom-skip/package.json | 29 ++++++++++++++++ examples/hdom-skip/src/index.ts | 57 ++++++++++++++++++++++++++++++++ examples/hdom-skip/tsconfig.json | 11 ++++++ 6 files changed, 139 insertions(+) create mode 100644 examples/hdom-skip/.gitignore create mode 100644 examples/hdom-skip/README.md create mode 100644 examples/hdom-skip/index.html create mode 100644 examples/hdom-skip/package.json create mode 100644 examples/hdom-skip/src/index.ts create mode 100644 examples/hdom-skip/tsconfig.json diff --git a/examples/hdom-skip/.gitignore b/examples/hdom-skip/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/hdom-skip/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/hdom-skip/README.md b/examples/hdom-skip/README.md new file mode 100644 index 0000000000..6dbd95f5f0 --- /dev/null +++ b/examples/hdom-skip/README.md @@ -0,0 +1,21 @@ +# hdom-skip + +[Live demo](http://demo.thi.ng/umbrella/hdom-skip/) + +Minimal example demonstrating use of the hdom `__skip` control attribute +to selectively skip diffing & updating DOM tree branches. + +```bash +git clone https://github.com/thi-ng/umbrella.git +cd umbrella/examples/hdom-skip +yarn install +yarn start +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/hdom-skip/index.html b/examples/hdom-skip/index.html new file mode 100644 index 0000000000..31b19184e1 --- /dev/null +++ b/examples/hdom-skip/index.html @@ -0,0 +1,16 @@ + + + + + + + hdom-skip + + + + +
+ + + diff --git a/examples/hdom-skip/package.json b/examples/hdom-skip/package.json new file mode 100644 index 0000000000..43ef027dc4 --- /dev/null +++ b/examples/hdom-skip/package.json @@ -0,0 +1,29 @@ +{ + "name": "hdom-skip", + "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 --public-url ./ --no-source-maps --no-cache --detailed-report", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.10.3", + "terser": "^3.10.1", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "latest", + "@thi.ng/atom": "latest", + "@thi.ng/rstream": "latest", + "@thi.ng/transducers-hdom": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} diff --git a/examples/hdom-skip/src/index.ts b/examples/hdom-skip/src/index.ts new file mode 100644 index 0000000000..5cd9d7e5df --- /dev/null +++ b/examples/hdom-skip/src/index.ts @@ -0,0 +1,57 @@ +import { start } from "@thi.ng/hdom"; + +const timer = + (period, name = `${period}ms`) => { + return { + // life cycle init method + // called when the component is being added to the real DOM + init() { + this.inited = true; + this.val = 0; + }, + render() { + // Key part of this example: + + // Here we check the current time stamp for timer `period` + // crossings and only return an actual new tree/content iff + // the time stamp is within 16ms of the period. In all other + // cases, we return some dummy content with the root element + // using the hdom `__skip` control attribute to skip diffing + // of this branch and not apply the given tree/branch. + + // IMPORTANT: the element type of the skipped branch MUST + // match the type of the real content (e.g. here `div`) + const t = Date.now(); + return !this.inited || (t % period) < 16 ? + ["div.sans-serif", `${name} @ ${this.val++ || 0}`] : + // dummy content (could be an empty div) + ["div", { __skip: true }, "I should be never seen"]; + } + }; + }; + +// root component object w/ life cycle methods +const app = { + init() { + // create timer component instances + this.timers = [[timer(1000)], [timer(500)], [timer(250)]]; + }, + render() { + return ["div.ma3.sans-serif", + ["h1", "Selective component updates"], + this.timers, + ["a.db.mt3.link", + { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-skip)" }, + "Source code"] + ]; + } +}; + +// kick off +const cancel = start([app]); + +// HMR handling +if (process.env.NODE_ENV !== "production") { + const hot = (module).hot; + hot && hot.dispose(cancel); +} diff --git a/examples/hdom-skip/tsconfig.json b/examples/hdom-skip/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/hdom-skip/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} From 8dc755d9686619e4d7c9f1323f59a3d5a44239a3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Mon, 10 Dec 2018 12:47:43 +0000 Subject: [PATCH 09/35] minor(examples): fix typo --- examples/hdom-skip/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hdom-skip/src/index.ts b/examples/hdom-skip/src/index.ts index 5cd9d7e5df..ccf31dff9e 100644 --- a/examples/hdom-skip/src/index.ts +++ b/examples/hdom-skip/src/index.ts @@ -41,7 +41,7 @@ const app = { ["h1", "Selective component updates"], this.timers, ["a.db.mt3.link", - { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-skip)" }, + { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-skip" }, "Source code"] ]; } From 6f2e8ee079e2138e4215a72991fc5c710734df03 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 11 Dec 2018 14:57:32 +0000 Subject: [PATCH 10/35] refactor(hdom): extend & simplify HDOMImplementation, update DEFAULT_IMPL BREAKING CHANGE: extend & simplify HDOMImplementation - update args for HDOMImplementation methods - add createElement(), createTextElement() & getElementById() methods to HDOMImplementation - rename createDOM() => createTree(), make generic - rename hydrateDOM() => hydrateTree(), make generic - update / fix diffTree() __impl attrib handling: only delegate if __impl != current impl - update resolveRoot() to require impl arg & delegate --- packages/hdom/src/api.ts | 83 ++++++++++---- packages/hdom/src/default.ts | 44 ++++++-- packages/hdom/src/diff.ts | 7 +- packages/hdom/src/dom.ts | 181 +++++++++++++++++-------------- packages/hdom/src/render-once.ts | 5 +- packages/hdom/src/start.ts | 49 +++++---- packages/hdom/src/utils.ts | 5 +- 7 files changed, 231 insertions(+), 143 deletions(-) diff --git a/packages/hdom/src/api.ts b/packages/hdom/src/api.ts index dae0a5b99e..5e114adef6 100644 --- a/packages/hdom/src/api.ts +++ b/packages/hdom/src/api.ts @@ -217,11 +217,12 @@ export interface HDOMImplementation { * @param opts */ normalizeTree(opts: Partial, tree: any): any[]; + /** * Realizes the given hdom tree in the target below the `parent` * node, e.g. in the case of the browser DOM, creates all required * DOM elements encoded by the given hdom tree. If `parent` is null - * the result tree won't be attached to any parent. If `insert` is + * the result tree won't be attached to any parent. If `child` is * given, the new elements will be inserted at given child index. * * For any components with `init` life cycle methods, the @@ -241,9 +242,10 @@ export interface HDOMImplementation { * * @param parent * @param tree - * @param insert + * @param child */ - createTree(opts: Partial, parent: T, tree: any, insert?: number): T | T[]; + createTree(opts: Partial, parent: T, tree: any, child?: number): T | T[]; + /** * Takes a target root element and normalized hdom tree, then walks * tree and initializes any event listeners and components with life @@ -261,15 +263,16 @@ export interface HDOMImplementation { * @param opts * @param parent * @param tree - * @param idx + * @param child */ - hydrateTree(opts: Partial, parent: T, tree: any, idx?: number); + hydrateTree(opts: Partial, parent: T, tree: any, child?: number); + /** - * Takes an `HDOMOpts` options object, an `HDOMImplementation` and - * two normalized hiccup trees, `prev` and `curr`. Recursively - * computes diff between both trees and applies any necessary - * changes to reflect `curr` tree, based on the differences to - * `prev`, in target (browser DOM when using the `DEFAULT_IMPL` + * Takes an `HDOMOpts` options object, a `parent` element and two + * normalized hiccup trees, `prev` and `curr`. Recursively computes + * diff between both trees and applies any necessary changes to + * reflect `curr` tree, based on the differences to `prev`, in + * target (browser DOM when using the `DEFAULT_IMPL` * implementation). * * All target modification operations are delegated to the given @@ -278,13 +281,13 @@ export interface HDOMImplementation { * involves any form of tracking of the actual underlying target * data structure (e.g. the real browser DOM). hdom in general and * `diffTree()` specifically are stateless. The only state available - * is that of the two trees given (prev / curr). + * is implicitly defined by the two trees given (prev / curr). * * Implementations MUST check for the presence of the `__impl` - * control attribute on each branch. If given, the current - * implementation MUST delegate to the `diffTree()` method of the - * specified implementation and not descent into that branch further - * itself. + * control attribute on each branch. If present AND different than + * the current implementation, the latter MUST delegate to the + * `diffTree()` method of the specified implementation and not + * descent into that branch further itself. * * Furthermore, if (and only if) an element has the `__diff` control * attribute set to `false`, then: @@ -303,19 +306,48 @@ export interface HDOMImplementation { * replace the old element / branch with the new one. * * @param opts - * @param impl * @param parent * @param prev * @param curr * @param child */ - diffTree( - opts: Partial, - impl: HDOMImplementation, - parent: T, - prev: any[], - curr: any[], - child: number); + diffTree(opts: Partial, parent: T, prev: any[], curr: any[], child?: number): void; + + /** + * Creates a new element of type `tag` with optional `attribs`. If + * `parent` is not `null`, the new element will be inserted as child + * at given `insert` index. If `child` is missing, the element will + * be appended to the `parent`'s list of children. Returns new + * target DOM node. + * + * In the default implementation, if `tag` is a known SVG element + * name, the new element will be created with the proper SVG XML + * namespace. + * + * @param parent + * @param tag + * @param attribs + * @param child + */ + createElement(parent: T, tag: string, attribs?: any, child?: number): T; + + /** + * + * @param parent + * @param content + * @param child + */ + createTextElement(parent: T, content: string, child?: number): T; + + /** + * Attempts to find an element with the given `id` attribute in the + * implementation's tree. In the default implementation this is + * merely delegated to `document.getElementById()`. + * + * @param id + */ + getElementById(id: string): T; + /** * A (potentially) optimized version of these 2 operations in * sequence: @@ -330,6 +362,7 @@ export interface HDOMImplementation { * @param newTree */ replaceChild?(opts: Partial, parent: T, child: number, newTree: any); + /** * Retrieves child of `parent` node at index `i`. * @@ -337,6 +370,7 @@ export interface HDOMImplementation { * @param i */ getChild?(parent: T, i: number): T; + /** * Removes the child of `parent` at index `i` in the target. * @@ -344,6 +378,7 @@ export interface HDOMImplementation { * @param i */ removeChild?(parent: T, i: number); + /** * Sets the given attribute `id` to new `value`. Note: `value` * itself can be a function and if so, the default behavior is to @@ -357,6 +392,7 @@ export interface HDOMImplementation { * @param attribs */ setAttrib?(element: T, id: string, value: any, attribs?: any); + /** * Removes given `attribs` from target `element`. The attributes * from the previous tree are provided for reference (e.g. to be @@ -367,6 +403,7 @@ export interface HDOMImplementation { * @param prevAttribs */ removeAttribs?(element: T, attribs: string[], prevAttribs: any); + /** * Sets target `element`'s text / body content. * diff --git a/packages/hdom/src/default.ts b/packages/hdom/src/default.ts index dc5ffa3347..57d599aa68 100644 --- a/packages/hdom/src/default.ts +++ b/packages/hdom/src/default.ts @@ -1,29 +1,57 @@ import { HDOMImplementation } from "./api"; import { diffTree } from "./diff"; -import { normalizeTree } from "./normalize"; import { - createDOM, + createTree, + createElement, + createTextElement, getChild, - hydrateDOM, + hydrateTree, removeAttribs, removeChild, replaceChild, setAttrib, - setContent, + setContent } from "./dom"; +import { normalizeTree } from "./normalize"; /** * Default target implementation to manipulate browser DOM. */ export const DEFAULT_IMPL: HDOMImplementation = { - createTree: createDOM, - hydrateTree: hydrateDOM, - diffTree, + + createTree(opts, parent, tree, child?) { + return createTree(opts, this, parent, tree, child); + }, + + hydrateTree(opts, parent, tree, child?) { + return hydrateTree(opts, this, parent, tree, child); + }, + + diffTree(opts, parent, prev, curr, child?) { + diffTree(opts, this, parent, prev, curr, child); + }, + normalizeTree, + + getElementById(id: string) { + return document.getElementById(id); + }, + getChild, - replaceChild, + + createElement, + + createTextElement, + + replaceChild(opts, parent, child, tree) { + replaceChild(opts, this, parent, child, tree); + }, + removeChild, + setContent, + removeAttribs, + setAttrib, }; diff --git a/packages/hdom/src/diff.ts b/packages/hdom/src/diff.ts index 44607facd6..e99db62c08 100644 --- a/packages/hdom/src/diff.ts +++ b/packages/hdom/src/diff.ts @@ -51,7 +51,7 @@ export const diffTree = ( parent: T, prev: any[], curr: any[], - child: number) => { + child: number = 0) => { const attribs = curr[1]; if (attribs.__skip) { @@ -64,8 +64,9 @@ export const diffTree = ( return; } // delegate to branch-local implementation - if (attribs.__impl) { - return attribs.__impl.diffTree(opts, attribs.__impl, parent, prev, curr, child); + let _impl = attribs.__impl; + if (_impl && _impl !== impl) { + return _impl.diffTree(opts, _impl, parent, prev, curr, child); } const delta = diffArray(prev, curr, DiffMode.ONLY_DISTANCE_LINEAR, equiv); if (delta.distance === 0) { diff --git a/packages/hdom/src/dom.ts b/packages/hdom/src/dom.ts index 14fbad9032..a3546829c2 100644 --- a/packages/hdom/src/dom.ts +++ b/packages/hdom/src/dom.ts @@ -15,51 +15,57 @@ const isNotStringAndIterable = isi.isNotStringAndIterable * @param tree * @param insert */ -export const createDOM = - (opts: Partial, parent: Element, tree: any, insert?: number) => { - if (isArray(tree)) { - const tag = tree[0]; - if (typeof tag === "function") { - return createDOM( - opts, - parent, - tag.apply(null, [opts.ctx, ...tree.slice(1)]), - insert - ); - } - const attribs = tree[1]; - if (attribs.__impl) { - return (>attribs.__impl) - .createTree(opts, parent, tree, insert); - } - const el = createElement(parent, tag, attribs, insert); - if ((tree).__init) { - // TODO hdom ctx? - (tree).__init.apply( - (tree).__this, - [el, ...(tree).__args] - ); - } - if (tree.length > 2) { - const n = tree.length; - for (let i = 2; i < n; i++) { - createDOM(opts, el, tree[i]); - } - } - return el; +export const createTree = ( + opts: Partial, + impl: HDOMImplementation, + parent: T, + tree: any, + insert?: number +) => { + if (isArray(tree)) { + const tag = tree[0]; + if (typeof tag === "function") { + return createTree( + opts, + impl, + parent, + tag.apply(null, [opts.ctx, ...tree.slice(1)]), + insert + ); + } + const attribs = tree[1]; + if (attribs.__impl) { + return (>attribs.__impl) + .createTree(opts, parent, tree, insert); } - if (isNotStringAndIterable(tree)) { - const res = []; - for (let t of tree) { - res.push(createDOM(opts, parent, t)); + const el = impl.createElement(parent, tag, attribs, insert); + if ((tree).__init) { + // TODO hdom ctx? + (tree).__init.apply( + (tree).__this, + [el, ...(tree).__args] + ); + } + if (tree.length > 2) { + const n = tree.length; + for (let i = 2; i < n; i++) { + createTree(opts, impl, el, tree[i]); } - return res; } - if (tree == null) { - return parent; + return el; + } + if (isNotStringAndIterable(tree)) { + const res = []; + for (let t of tree) { + res.push(createTree(opts, impl, parent, t)); } - return createTextElement(parent, tree); - }; + return res; + } + if (tree == null) { + return parent; + } + return impl.createTextElement(parent, tree); +}; /** * See `HDOMImplementation` interface for further details. @@ -69,44 +75,50 @@ export const createDOM = * @param tree * @param index */ -export const hydrateDOM = - (opts: Partial, parent: Element, tree: any, index = 0) => { - if (isArray(tree)) { - const el = parent.children[index]; - if (typeof tree[0] === "function") { - hydrateDOM( - opts, - parent, - tree[0].apply(null, [opts.ctx, ...tree.slice(1)]), - index - ); - } - const attribs = tree[1]; - if (attribs.__impl) { - return (>attribs.__impl) - .hydrateTree(opts, parent, tree, index); - } - if ((tree).__init) { - (tree).__init.apply( - (tree).__this, - [el, ...(tree).__args] - ); - } - for (let a in attribs) { - if (a.indexOf("on") === 0) { - el.addEventListener(a.substr(2), attribs[a]); - } - } - for (let n = tree.length, i = 2; i < n; i++) { - hydrateDOM(opts, el, tree[i], i - 2); - } - } else if (isNotStringAndIterable(tree)) { - for (let t of tree) { - hydrateDOM(opts, parent, t, index); - index++; +export const hydrateTree = ( + opts: Partial, + impl: HDOMImplementation, + parent: T, + tree: any, + index = 0 +) => { + if (isArray(tree)) { + const el = impl.getChild(parent, index); + if (typeof tree[0] === "function") { + hydrateTree( + opts, + impl, + parent, + tree[0].apply(null, [opts.ctx, ...tree.slice(1)]), + index + ); + } + const attribs = tree[1]; + if (attribs.__impl) { + return (>attribs.__impl) + .hydrateTree(opts, parent, tree, index); + } + if ((tree).__init) { + (tree).__init.apply( + (tree).__this, + [el, ...(tree).__args] + ); + } + for (let a in attribs) { + if (a.indexOf("on") === 0) { + impl.setAttrib(el, a, attribs[a]); } } - }; + for (let n = tree.length, i = 2; i < n; i++) { + hydrateTree(opts, impl, el, tree[i], i - 2); + } + } else if (isNotStringAndIterable(tree)) { + for (let t of tree) { + hydrateTree(opts, impl, parent, t, index); + index++; + } + } +}; /** * Creates a new DOM element of type `tag` with optional `attribs`. If @@ -156,11 +168,16 @@ export const createTextElement = export const getChild = (parent: Element, child: number) => parent.children[child]; -export const replaceChild = - (opts: Partial, parent: Element, child: number, tree: any) => { - removeChild(parent, child); - createDOM(opts, parent, tree, child); - }; +export const replaceChild = ( + opts: Partial, + impl: HDOMImplementation, + parent: Element, + child: number, + tree: any +) => ( + impl.removeChild(parent, child), + impl.createTree(opts, parent, tree, child) + ); export const cloneWithNewAttribs = (el: Element, attribs: any) => { diff --git a/packages/hdom/src/render-once.ts b/packages/hdom/src/render-once.ts index 6af7568439..740f558a29 100644 --- a/packages/hdom/src/render-once.ts +++ b/packages/hdom/src/render-once.ts @@ -16,11 +16,12 @@ import { resolveRoot } from "./utils"; export const renderOnce = ( tree: any, opts: Partial = {}, - impl: HDOMImplementation = DEFAULT_IMPL) => { + impl: HDOMImplementation = DEFAULT_IMPL +) => { opts = { root: "app", ...opts }; opts.ctx = derefContext(opts.ctx, opts.autoDerefKeys); - const root = resolveRoot(opts.root); + const root = resolveRoot(opts.root, impl); tree = impl.normalizeTree(opts, tree); if (!tree) return; opts.hydrate ? diff --git a/packages/hdom/src/start.ts b/packages/hdom/src/start.ts index 6defe5fb75..6478803a9a 100644 --- a/packages/hdom/src/start.ts +++ b/packages/hdom/src/start.ts @@ -47,29 +47,32 @@ import { resolveRoot } from "./utils"; * @param opts options * @param impl hdom target implementation */ -export const start = - (tree: any, opts: Partial = {}, impl: HDOMImplementation = DEFAULT_IMPL) => { - const _opts = { root: "app", ...opts }; - let prev = []; - let isActive = true; - const root = resolveRoot(_opts.root); - const update = () => { - if (isActive) { - _opts.ctx = derefContext(opts.ctx, _opts.autoDerefKeys); - const curr = impl.normalizeTree(_opts, tree); - if (curr != null) { - if (_opts.hydrate) { - impl.hydrateTree(_opts, root, curr); - _opts.hydrate = false; - } else { - impl.diffTree(_opts, impl, root, prev, curr, 0); - } - prev = curr; +export const start = ( + tree: any, + opts: Partial = {}, + impl: HDOMImplementation = DEFAULT_IMPL +) => { + const _opts = { root: "app", ...opts }; + let prev = []; + let isActive = true; + const root = resolveRoot(_opts.root, impl); + const update = () => { + if (isActive) { + _opts.ctx = derefContext(opts.ctx, _opts.autoDerefKeys); + const curr = impl.normalizeTree(_opts, tree); + if (curr != null) { + if (_opts.hydrate) { + impl.hydrateTree(_opts, root, curr); + _opts.hydrate = false; + } else { + impl.diffTree(_opts, root, prev, curr); } - // check again in case one of the components called cancel - isActive && requestAnimationFrame(update); + prev = curr; } - }; - requestAnimationFrame(update); - return () => (isActive = false); + // check again in case one of the components called cancel + isActive && requestAnimationFrame(update); + } }; + requestAnimationFrame(update); + return () => (isActive = false); +}; diff --git a/packages/hdom/src/utils.ts b/packages/hdom/src/utils.ts index e881fe76fc..c2b1cdf99c 100644 --- a/packages/hdom/src/utils.ts +++ b/packages/hdom/src/utils.ts @@ -1,7 +1,8 @@ import { isString } from "@thi.ng/checks/is-string"; +import { HDOMImplementation } from "./api"; export const resolveRoot = - (root: any) => + (root: any, impl: HDOMImplementation) => isString(root) ? - document.getElementById(root) : + impl.getElementById(root) : root; From 69b29ad7ca9620767a118b7662d04f25070f4faa Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 11 Dec 2018 17:23:59 +0000 Subject: [PATCH 11/35] docs(hdom): add __skip attrib docstring --- packages/hdom/src/api.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/hdom/src/api.ts b/packages/hdom/src/api.ts index 5e114adef6..919ac7e5ee 100644 --- a/packages/hdom/src/api.ts +++ b/packages/hdom/src/api.ts @@ -46,6 +46,15 @@ export interface HDOMBehaviorAttribs { * the currently active hdom target implementation. */ __diff?: boolean; + /** + * HDOM behavior control attribute. If true, the element will not be + * diffed and simply skipped. IMPORTANT: This attribute is only + * intended for cases when a component / tree branch should not be + * updated, but MUST NEVER be enabled when that component is first + * included in the tree. Doing so will result in undefined future + * behavior. + */ + __skip?: boolean; /** * HDOM behavior control attribute. If present, the element and all * of its children will be processed by the given From 43327c9e216c34eb982d23c7326d58067b64cf77 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 11 Dec 2018 17:56:24 +0000 Subject: [PATCH 12/35] refactor(hdom-canvas): update HDOMImplementation, add __skip support, reformat --- packages/hdom-canvas/src/index.ts | 369 +++++++++++++++++------------- 1 file changed, 207 insertions(+), 162 deletions(-) diff --git a/packages/hdom-canvas/src/index.ts b/packages/hdom-canvas/src/index.ts index af3aaecaa4..30f88e22eb 100644 --- a/packages/hdom-canvas/src/index.ts +++ b/packages/hdom-canvas/src/index.ts @@ -18,6 +18,9 @@ type ReadonlyVec = ArrayLike & Iterable; const TAU = Math.PI * 2; +const FN = "function"; +const STR = "string"; + const DEFAULTS = { align: "left", alpha: 1, @@ -128,68 +131,76 @@ export const canvas = { } }; -export const createTree = (_: Partial, canvas: HTMLCanvasElement, tree: any) => { - // console.log(Date.now(), "draw"); - const ctx = canvas.getContext("2d"); - const attribs = tree[1]; - if (attribs && attribs.__clear !== false) { - ctx.clearRect(0, 0, canvas.width, canvas.height); - } - walk(ctx, tree, { attribs: {} }); -}; +export const createTree = + (_: Partial, canvas: HTMLCanvasElement, tree: any) => { + // console.log(Date.now(), "draw"); + const ctx = canvas.getContext("2d"); + const attribs = tree[1]; + if (attribs) { + if (attribs.__skip) return; + if (attribs.__clear !== false) { + ctx.clearRect(0, 0, canvas.width, canvas.height); + } + } + walk(ctx, tree, { attribs: {} }); + }; -export const normalizeTree = (opts: Partial, tree: any) => { - if (tree == null) { - return tree; - } - if (isArray(tree)) { - const tag = tree[0]; - if (typeof tag === "function") { - return normalizeTree(opts, tag.apply(null, [opts.ctx, ...tree.slice(1)])); +export const normalizeTree = + (opts: Partial, tree: any) => { + if (tree == null) { + return tree; } - if (typeof tag === "string") { - const attribs = tree[1]; - if (attribs && attribs.__normalize === false) { - return tree; + if (isArray(tree)) { + const tag = tree[0]; + if (typeof tag === FN) { + return normalizeTree(opts, tag.apply(null, [opts.ctx, ...tree.slice(1)])); + } + if (typeof tag === STR) { + const attribs = tree[1]; + if (attribs && attribs.__normalize === false) { + return tree; + } + const res = [tree[0], attribs] + for (let i = 2, n = tree.length; i < n; i++) { + const n = normalizeTree(opts, tree[i]); + n != null && res.push(n); + } + return res; } - const res = [tree[0], attribs] - for (let i = 2, n = tree.length; i < n; i++) { - const n = normalizeTree(opts, tree[i]); + } else if (typeof tree === FN) { + return normalizeTree(opts, tree(opts.ctx)); + } else if (typeof tree.toHiccup === FN) { + return normalizeTree(opts, tree.toHiccup(opts.ctx)); + } else if (typeof tree.deref === FN) { + return normalizeTree(opts, tree.deref()); + } else if (isNotStringAndIterable(tree)) { + const res = []; + for (let t of tree) { + const n = normalizeTree(opts, t); n != null && res.push(n); } return res; } - } else if (typeof tree === "function") { - return normalizeTree(opts, tree(opts.ctx)); - } else if (typeof tree.toHiccup === "function") { - return normalizeTree(opts, tree.toHiccup(opts.ctx)); - } else if (typeof tree.deref === "function") { - return normalizeTree(opts, tree.deref()); - } else if (isNotStringAndIterable(tree)) { - const res = []; - for (let t of tree) { - const n = normalizeTree(opts, t); - n != null && res.push(n); - } - return res; - } - return tree; -}; + return tree; + }; -export const diffTree = (opts: Partial, - _: HDOMImplementation, +export const diffTree = ( + opts: Partial, parent: HTMLCanvasElement, prev: any[], curr: any[], - child: number) => { + child: number +) => { const attribs = curr[1]; + if (attribs.__skip) return; if (attribs.__diff === false) { releaseTree(prev); return createTree(opts, parent, curr); } // delegate to branch-local implementation - if (attribs.__impl && attribs.__impl !== IMPL) { - return attribs.__impl.diffTree(opts, attribs.__impl, parent, prev, curr, child); + let impl: HDOMImplementation = attribs.__impl; + if (impl && impl !== IMPL) { + return impl.diffTree(opts, parent, prev, curr, child); } const delta = diffArray(prev, curr, DiffMode.ONLY_DISTANCE, equiv); if (delta.distance > 0) { @@ -197,81 +208,90 @@ export const diffTree = (opts: Partial, } } +const NOOP = () => { }; + export const IMPL: HDOMImplementation = { createTree, normalizeTree, diffTree, - hydrateTree: () => { }, + hydrateTree: NOOP, + getElementById: NOOP, + createElement: NOOP, + createTextElement: NOOP, }; -const walk = (ctx: CanvasRenderingContext2D, shape: any[], pstate: DrawState) => { - if (!shape) return; - if (isArray(shape[0])) { - for (let s of shape) { - walk(ctx, s, pstate); - } - return; - } - const state = mergeState(ctx, pstate, shape[1]); - const attribs = state ? state.attribs : pstate.attribs; - switch (shape[0]) { - case "g": - case "defs": - for (let i = 2, n = shape.length, - __state = shape[0] === "g" ? state || pstate : pstate; - i < n; i++) { - walk(ctx, shape[i], __state); +const walk = + (ctx: CanvasRenderingContext2D, shape: any[], pstate: DrawState) => { + if (!shape) return; + if (isArray(shape[0])) { + for (let s of shape) { + walk(ctx, s, pstate); } - break; - case "linearGradient": - defLinearGradient(ctx, pstate, shape[1], shape[2]); - break; - case "radialGradient": - defRadialGradient(ctx, pstate, shape[1], shape[2]); - break; - case "points": - points(ctx, attribs, shape[1], shape[2]); - break; - case "line": - line(ctx, attribs, shape[2], shape[3]); - break; - case "hline": - line(ctx, attribs, [-1e6, shape[2]], [1e6, shape[2]]); - break; - case "vline": - line(ctx, attribs, [shape[2], -1e6], [shape[2], 1e6]); - break; - case "polyline": - polyline(ctx, attribs, shape[2]); - break; - case "polygon": - polygon(ctx, attribs, shape[2]); - break; - case "path": - path(ctx, attribs, shape[2]); - break; - case "rect": - rect(ctx, attribs, shape[2], shape[3], shape[4], shape[5]); - break; - case "circle": - circularArc(ctx, attribs, shape[2], shape[3]); - break; - case "arc": - circularArc(ctx, attribs, shape[2], shape[3], shape[4], shape[5]); - break; - case "text": - text(ctx, attribs, shape[2], shape[3], shape[4]); - break; - case "img": - image(ctx, attribs, shape[2], shape[3]); - default: - } - state && restoreState(ctx, pstate, state); -}; + return; + } + const state = mergeState(ctx, pstate, shape[1]); + const attribs = state ? state.attribs : pstate.attribs; + if (attribs.__skip) return; + switch (shape[0]) { + case "g": + case "defs": + for (let i = 2, n = shape.length, + __state = shape[0] === "g" ? state || pstate : pstate; + i < n; i++) { + walk(ctx, shape[i], __state); + } + break; + case "linearGradient": + defLinearGradient(ctx, pstate, shape[1], shape[2]); + break; + case "radialGradient": + defRadialGradient(ctx, pstate, shape[1], shape[2]); + break; + case "points": + points(ctx, attribs, shape[1], shape[2]); + break; + case "line": + line(ctx, attribs, shape[2], shape[3]); + break; + case "hline": + line(ctx, attribs, [-1e6, shape[2]], [1e6, shape[2]]); + break; + case "vline": + line(ctx, attribs, [shape[2], -1e6], [shape[2], 1e6]); + break; + case "polyline": + polyline(ctx, attribs, shape[2]); + break; + case "polygon": + polygon(ctx, attribs, shape[2]); + break; + case "path": + path(ctx, attribs, shape[2]); + break; + case "rect": + rect(ctx, attribs, shape[2], shape[3], shape[4], shape[5]); + break; + case "circle": + circularArc(ctx, attribs, shape[2], shape[3]); + break; + case "arc": + circularArc(ctx, attribs, shape[2], shape[3], shape[4], shape[5]); + break; + case "text": + text(ctx, attribs, shape[2], shape[3], shape[4]); + break; + case "img": + image(ctx, attribs, shape[2], shape[3]); + default: + } + state && restoreState(ctx, pstate, state); + }; -const mergeState = (ctx: CanvasRenderingContext2D, +const mergeState = ( + ctx: CanvasRenderingContext2D, state: DrawState, - attribs: IObjectOf) => { + attribs: IObjectOf +) => { let res: DrawState; if (!attribs) return; @@ -304,9 +324,11 @@ const mergeState = (ctx: CanvasRenderingContext2D, return res; }; -const restoreState = (ctx: CanvasRenderingContext2D, +const restoreState = ( + ctx: CanvasRenderingContext2D, prev: DrawState, - curr: DrawState) => { + curr: DrawState +) => { if (curr.restore) { ctx.restore(); @@ -322,11 +344,13 @@ const restoreState = (ctx: CanvasRenderingContext2D, } }; -const setAttrib = (ctx: CanvasRenderingContext2D, +const setAttrib = ( + ctx: CanvasRenderingContext2D, state: DrawState, id: string, k: string, - val: any) => { + val: any +) => { switch (id) { case "fill": @@ -343,40 +367,44 @@ const setAttrib = (ctx: CanvasRenderingContext2D, } }; -const applyTransform = (ctx: CanvasRenderingContext2D, attribs: IObjectOf) => { - let v: any; - if ((v = attribs.transform) || - attribs.translate || - attribs.scale || - attribs.rotate) { - - ctx.save(); - if (v) { - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - } else { - (v = attribs.translate) && ctx.translate(v[0], v[1]); - (v = attribs.rotate) && ctx.rotate(v); - (v = attribs.scale) && (isArrayLike(v) ? ctx.scale(v[0], v[1]) : ctx.scale(v, v)); +const applyTransform = + (ctx: CanvasRenderingContext2D, attribs: IObjectOf) => { + let v: any; + if ((v = attribs.transform) || + attribs.translate || + attribs.scale || + attribs.rotate) { + + ctx.save(); + if (v) { + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + } else { + (v = attribs.translate) && ctx.translate(v[0], v[1]); + (v = attribs.rotate) && ctx.rotate(v); + (v = attribs.scale) && (isArrayLike(v) ? ctx.scale(v[0], v[1]) : ctx.scale(v, v)); + } + return true; } - return true; - } - return false; -}; - -const endShape = (ctx: CanvasRenderingContext2D, attribs: IObjectOf) => { - let v: any; - if ((v = attribs.fill) && v !== "none") { - ctx.fill(); - } - if ((v = attribs.stroke) && v !== "none") { - ctx.stroke(); - } -}; + return false; + }; + +const endShape = + (ctx: CanvasRenderingContext2D, attribs: IObjectOf) => { + let v: any; + if ((v = attribs.fill) && v !== "none") { + ctx.fill(); + } + if ((v = attribs.stroke) && v !== "none") { + ctx.stroke(); + } + }; -const defLinearGradient = (ctx: CanvasRenderingContext2D, +const defLinearGradient = ( + ctx: CanvasRenderingContext2D, state: DrawState, { id, from, to }: any, - stops: any[][]) => { + stops: any[][] +) => { const g = ctx.createLinearGradient(from[0], from[1], to[0], to[1]); for (let s of stops) { @@ -386,10 +414,12 @@ const defLinearGradient = (ctx: CanvasRenderingContext2D, state.grads[id] = g; }; -const defRadialGradient = (ctx: CanvasRenderingContext2D, +const defRadialGradient = ( + ctx: CanvasRenderingContext2D, state: DrawState, { id, from, to, r1, r2 }: any, - stops: any[][]) => { + stops: any[][] +) => { const g = ctx.createRadialGradient(from[0], from[1], r1, to[0], to[1], r2); for (let s of stops) { @@ -399,10 +429,12 @@ const defRadialGradient = (ctx: CanvasRenderingContext2D, state.grads[id] = g; }; -const line = (ctx: CanvasRenderingContext2D, +const line = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, a: ReadonlyVec, - b: ReadonlyVec) => { + b: ReadonlyVec +) => { if (attribs.stroke === "none") return; ctx.beginPath(); @@ -411,9 +443,11 @@ const line = (ctx: CanvasRenderingContext2D, ctx.stroke(); }; -const polyline = (ctx: CanvasRenderingContext2D, +const polyline = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, - pts: ReadonlyVec[]) => { + pts: ReadonlyVec[] +) => { if (pts.length < 2 || attribs.stroke == "none") return; let p: ReadonlyVec = pts[0]; @@ -426,9 +460,11 @@ const polyline = (ctx: CanvasRenderingContext2D, ctx.stroke(); }; -const polygon = (ctx: CanvasRenderingContext2D, +const polygon = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, - pts: ReadonlyVec[]) => { + pts: ReadonlyVec[] +) => { if (pts.length < 2) return; let p: ReadonlyVec = pts[0]; @@ -442,9 +478,11 @@ const polygon = (ctx: CanvasRenderingContext2D, endShape(ctx, attribs); }; -const path = (ctx: CanvasRenderingContext2D, +const path = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, - segments: any[]) => { + segments: any[] +) => { ctx.beginPath(); let a: ReadonlyVec = [0, 0]; @@ -557,13 +595,15 @@ const path = (ctx: CanvasRenderingContext2D, endShape(ctx, attribs); }; -const circularArc = (ctx: CanvasRenderingContext2D, +const circularArc = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, pos: ReadonlyVec, r: number, start = 0, end = TAU, - antiCCW = false) => { + antiCCW = false +) => { ctx.beginPath(); ctx.arc(pos[0], pos[1], r, start, end, antiCCW); @@ -598,10 +638,12 @@ const rect = (ctx: CanvasRenderingContext2D, } }; -const points = (ctx: CanvasRenderingContext2D, +const points = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, opts: IObjectOf, - pts: Iterable) => { + pts: Iterable +) => { const s = (opts && opts.size) || 1; let v: any; @@ -633,11 +675,13 @@ const points = (ctx: CanvasRenderingContext2D, } }; -const text = (ctx: CanvasRenderingContext2D, +const text = ( + ctx: CanvasRenderingContext2D, attribs: IObjectOf, pos: ReadonlyVec, body: any, - maxWidth?: number) => { + maxWidth?: number +) => { let v: any; if ((v = attribs.fill) && v !== "none") { @@ -652,7 +696,8 @@ const image = ( ctx: CanvasRenderingContext2D, _: IObjectOf, pos: ReadonlyVec, - img: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap) => { + img: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap +) => { ctx.drawImage(img, pos[0], pos[1]); }; From 6db317087b7b1b6088367781864208d35b7c55b4 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 11 Dec 2018 17:57:26 +0000 Subject: [PATCH 13/35] fix(transducers-hdom): integrate recent hdom updates --- packages/transducers-hdom/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/transducers-hdom/src/index.ts b/packages/transducers-hdom/src/index.ts index c7a0ce975e..a7fcbb037d 100644 --- a/packages/transducers-hdom/src/index.ts +++ b/packages/transducers-hdom/src/index.ts @@ -43,7 +43,7 @@ import { scan } from "@thi.ng/transducers/xform/scan"; export const updateDOM = (opts: Partial = {}, impl: HDOMImplementation = DEFAULT_IMPL): Transducer => { const _opts = { root: "app", ...opts }; - const root = resolveRoot(_opts.root); + const root = resolveRoot(_opts.root, impl); return scan( reducer( () => [], @@ -55,7 +55,7 @@ export const updateDOM = impl.hydrateTree(_opts, root, curr); _opts.hydrate = false; } else { - impl.diffTree(_opts, impl, root, prev, curr, 0); + impl.diffTree(_opts, root, prev, curr, 0); } return curr; } From fe9a3120607e302173b725fff6fa9345a4f41912 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 11 Dec 2018 22:04:02 +0000 Subject: [PATCH 14/35] refactor(hdom): update createTextElement() sig, update docstrings --- packages/hdom/src/api.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/hdom/src/api.ts b/packages/hdom/src/api.ts index 919ac7e5ee..a25d7d5f2e 100644 --- a/packages/hdom/src/api.ts +++ b/packages/hdom/src/api.ts @@ -341,12 +341,13 @@ export interface HDOMImplementation { createElement(parent: T, tag: string, attribs?: any, child?: number): T; /** + * Creates and appends the given `content` as text child node to + * `parent` in the target. * * @param parent * @param content - * @param child */ - createTextElement(parent: T, content: string, child?: number): T; + createTextElement(parent: T, content: string): T; /** * Attempts to find an element with the given `id` attribute in the @@ -391,9 +392,9 @@ export interface HDOMImplementation { /** * Sets the given attribute `id` to new `value`. Note: `value` * itself can be a function and if so, the default behavior is to - * call this function with also provided `attribs` object to allow - * it to produce a derived value. See `setAttrib()` (dom.ts) for - * details. + * call this function with the also provided `attribs` object to + * allow it to produce a derived value. See `setAttrib()` (dom.ts) + * for details. * * @param element * @param id @@ -414,7 +415,12 @@ export interface HDOMImplementation { removeAttribs?(element: T, attribs: string[], prevAttribs: any); /** - * Sets target `element`'s text / body content. + * Sets target `element`'s text / body content. Note: In the default + * browser DOM implementation, this will implicitly remove any + * existing child elements in the target. In practice this function + * is only applied to `["span"]` elements, since (by default) any + * body content is automatically wrapped in such by + * `normalizeTree()`. * * @param element * @param value From 5609d24aacca582d3b6c79b9ddd5b6f5dac96d83 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Tue, 11 Dec 2018 22:05:00 +0000 Subject: [PATCH 15/35] feat(hdom-mock): add hdom-mock package and implementation, add initial tests --- packages/hdom-mock/.npmignore | 11 ++ packages/hdom-mock/LICENSE | 201 +++++++++++++++++++++++ packages/hdom-mock/README.md | 40 +++++ packages/hdom-mock/package.json | 41 +++++ packages/hdom-mock/src/index.ts | 225 ++++++++++++++++++++++++++ packages/hdom-mock/test/index.ts | 46 ++++++ packages/hdom-mock/test/tsconfig.json | 10 ++ packages/hdom-mock/tsconfig.json | 9 ++ 8 files changed, 583 insertions(+) create mode 100644 packages/hdom-mock/.npmignore create mode 100644 packages/hdom-mock/LICENSE create mode 100644 packages/hdom-mock/README.md create mode 100644 packages/hdom-mock/package.json create mode 100644 packages/hdom-mock/src/index.ts create mode 100644 packages/hdom-mock/test/index.ts create mode 100644 packages/hdom-mock/test/tsconfig.json create mode 100644 packages/hdom-mock/tsconfig.json diff --git a/packages/hdom-mock/.npmignore b/packages/hdom-mock/.npmignore new file mode 100644 index 0000000000..ec83d74c9d --- /dev/null +++ b/packages/hdom-mock/.npmignore @@ -0,0 +1,11 @@ +build +coverage +dev +doc +export +src* +test +.nyc_output +tsconfig.json +*.tgz +*.html diff --git a/packages/hdom-mock/LICENSE b/packages/hdom-mock/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/hdom-mock/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/hdom-mock/README.md b/packages/hdom-mock/README.md new file mode 100644 index 0000000000..409a86fb4f --- /dev/null +++ b/packages/hdom-mock/README.md @@ -0,0 +1,40 @@ +# @thi.ng/hdom-mock + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/hdom-mock.svg)](https://www.npmjs.com/package/@thi.ng/hdom-mock) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/hdom-mock.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + + + +## About + +TODO... + +## Installation + +```bash +yarn add @thi.ng/hdom-mock +``` + +## Dependencies + +- TODO... + +## Usage examples + +```ts +import * as hm from "@thi.ng/hdom-mock"; +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/hdom-mock/package.json b/packages/hdom-mock/package.json new file mode 100644 index 0000000000..b633109436 --- /dev/null +++ b/packages/hdom-mock/package.json @@ -0,0 +1,41 @@ +{ + "name": "@thi.ng/hdom-mock", + "version": "0.0.1", + "description": "TODO", + "main": "./index.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/hdom-mock", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn run clean && tsc --declaration", + "clean": "rm -rf *.js *.d.ts .nyc_output build coverage doc", + "cover": "yarn test && nyc report --reporter=lcov", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn run build && yarn publish --access public", + "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" + }, + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^10.12.0", + "mocha": "^5.2.0", + "nyc": "^13.1.0", + "typedoc": "^0.13.0", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/api": "^4.2.3", + "@thi.ng/hdom": "^5.2.2" + }, + "keywords": [ + "ES6", + "typescript" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/hdom-mock/src/index.ts b/packages/hdom-mock/src/index.ts new file mode 100644 index 0000000000..db481bf372 --- /dev/null +++ b/packages/hdom-mock/src/index.ts @@ -0,0 +1,225 @@ +import { IObjectOf } from "@thi.ng/api/api"; +import { isFunction } from "@thi.ng/checks/is-function"; +import { HDOMImplementation, HDOMOpts } from "@thi.ng/hdom/api"; +import { diffTree } from "@thi.ng/hdom/diff"; +import { createTree, hydrateTree } from "@thi.ng/hdom/dom"; +import { normalizeTree } from "@thi.ng/hdom/normalize"; + +export class HDOMNode { + parent: HDOMNode; + children: HDOMNode[]; + _children: HDOMNode[]; + + listeners: IObjectOf; + + value: any; + checked: boolean; + + tag: string; + attribs: IObjectOf; + style: IObjectOf; + body: string; + + constructor(tag: string, attribs = {}) { + this.tag = tag; + this.children = []; + this._children = []; + this.attribs = attribs; + this.listeners = {}; + } + + get textContent() { + const res = []; + for (let c of this._children) { + if (c.tag == "#") { + res.push(c.body); + } + } + return res.join(""); + } + + set textContent(body: string) { + const txt = new HDOMNode("#"); + txt.body = body; + this._children = [txt]; + this.children = []; + } + + insertBefore(c: HDOMNode, i: number) { + const existing = this.children[i]; + if (existing) { + c.tag !== "#" && this.children.splice(i, 0, c); + this._children.splice(this._children.indexOf(existing), 0, c); + } else { + this.appendChild(c); + } + return c; + } + + appendChild(c: HDOMNode) { + c.tag !== "#" && this.children.push(c); + this._children.push(c); + return c; + } + + removeChild(i: number) { + const c = this.children[i]; + if (c) { + this.children.splice(i, 1); + this._children.splice(this._children.indexOf(c), 1); + } + } + + getElementById(id: string) { + if (this.attribs.id === id) return this; + for (let c of this.children) { + c = c.getElementById(id); + if (c) return c; + } + } + + toHiccup() { + if (this.tag === "#") { + return this.body; + } + const attr = { ...this.attribs }; + this.style && (attr.style = this.style); + this.value != null && (attr.value = this.value); + this.checked && (attr.checked = true); + return [this.tag, attr, ...this._children.map((c) => c.toHiccup())]; + } +} + +export class MockImpl implements HDOMImplementation { + + root: HDOMNode; + + constructor(root: HDOMNode) { + this.root = root; + } + + normalizeTree(opts: Partial, tree: any): any[] { + return normalizeTree(opts, tree); + } + + createTree(opts: Partial, parent: HDOMNode, tree: any, child?: number) { + return createTree(opts, this, parent, tree, child); + } + + hydrateTree(opts: Partial, parent: HDOMNode, tree: any, child?: number) { + return hydrateTree(opts, this, parent, tree, child); + } + + diffTree(opts: Partial, parent: HDOMNode, prev: any[], curr: any[], child?: number) { + diffTree(opts, this, parent, prev, curr, child); + } + + createElement(parent: HDOMNode, tag: string, attribs?: any, insert?: number) { + const el = new HDOMNode(tag); + if (parent) { + if (insert == null) { + parent.appendChild(el); + } else { + parent.insertBefore(el, insert); + } + } + if (attribs) { + this.setAttribs(el, attribs); + } + return el; + } + + createTextElement(parent: HDOMNode, content: string) { + const el = new HDOMNode("#"); + el.body = content; + parent && parent.appendChild(el); + return el; + } + + getElementById(id: string): HDOMNode { + return this.root.getElementById(id); + } + + replaceChild(opts: Partial, parent: HDOMNode, child: number, tree: any) { + this.removeChild(parent, child); + this.createTree(opts, parent, tree, child); + } + + getChild(parent: HDOMNode, i: number) { + return parent.children[i]; + } + + removeChild(parent: HDOMNode, i: number) { + parent.removeChild(i); + } + + setAttribs(el: HDOMNode, attribs: any) { + for (let k in attribs) { + this.setAttrib(el, k, attribs[k], attribs); + } + return el; + } + + setAttrib(el: HDOMNode, id: string, val: any, attribs?: any) { + if (id.startsWith("__")) return; + const isListener = id.indexOf("on") === 0; + if (!isListener && typeof val === "function") { + val = val(attribs); + } + if (val !== undefined && val !== false) { + switch (id) { + case "style": + this.setStyle(el, val); + break; + case "value": + el.value = val; + break; + case "checked": + el[id] = val; + break; + default: + if (isListener) { + const lid = id.substr(2); + const listeners = el.listeners[lid]; + (listeners || (el.listeners[lid] = [])).push(val); + } else { + el.attribs[id] = val; + } + } + } else { + el[id] != null ? (el[id] = null) : (delete el.attribs[id]); + } + return el; + } + + removeAttribs(el: HDOMNode, attribs: string[], prev: any) { + for (let i = attribs.length; --i >= 0;) { + const a = attribs[i]; + if (a.indexOf("on") === 0) { + const listeners = el.listeners[a.substr(2)]; + if (listeners) { + const i = listeners.indexOf(prev[a]); + i >= 0 && listeners.splice(i, 1); + } + } else { + el[a] ? (el[a] = null) : (delete el.attribs[a]); + } + } + } + + setContent(el: HDOMNode, value: any) { + el.textContent = value; + } + + setStyle(el: HDOMNode, rules: IObjectOf) { + for (let r in rules) { + let v = rules[r]; + if (isFunction(v)) { + v = v(rules); + } + if (v != null) { + (el.style || (el.style = {}))[r] = v; + } + } + } +} diff --git a/packages/hdom-mock/test/index.ts b/packages/hdom-mock/test/index.ts new file mode 100644 index 0000000000..a0c3790d61 --- /dev/null +++ b/packages/hdom-mock/test/index.ts @@ -0,0 +1,46 @@ +import * as assert from "assert"; +import { HDOMNode, MockImpl } from "../src/index"; + +describe("hdom-mock", () => { + + it("node", () => { + const a = new HDOMNode("div"); + const impl = new MockImpl(a); + impl.createTextElement(a, "foo"); + a.appendChild(new HDOMNode("span")); + impl.createTextElement(a, "bar"); + assert.deepEqual(a.toHiccup(), ["div", {}, "foo", ["span", {}], "bar"]); + assert.deepEqual(impl.getChild(a, 0).toHiccup(), ["span", {}]); + a.textContent = "foobar"; + assert.strictEqual(impl.getChild(a, 0), undefined); + assert.deepEqual(a.toHiccup(), ["div", {}, "foobar"]); + }); + + it("basic diff", () => { + const opts = { ctx: { button: { class: "bt" } } }; + const app = new HDOMNode("root"); + const impl = new MockImpl(app); + const a = impl.normalizeTree(opts, ["div#foo.bar", [(ctx, label) => ["button", { ...ctx.button }, label], "hi"]]); + const b = impl.normalizeTree(opts, ["div#foo2.bar.baz", [(ctx, label) => ["button", { ...ctx.button }, label], "hello"], ["div", "extra"]]); + const c = impl.normalizeTree(opts, ["div#foo3.baz.bux", ["div", "extra"]]); + impl.diffTree(opts, app, [], a); + assert.deepEqual(app.toHiccup(), + ["root", {}, + ["div", { id: "foo", class: "bar", key: "0" }, + ["button", { class: "bt", key: "0-0" }, "hi"]]] + ); + impl.diffTree(opts, app, a, b); + assert.deepEqual(app.toHiccup(), + ["root", {}, + ["div", { id: "foo2", class: "bar baz", key: "0" }, + ["button", { class: "bt", key: "0-0" }, "hello"], + ["div", { key: "0-1" }, ["span", { key: "0-1-0" }, "extra"]]]] + ); + impl.diffTree(opts, app, b, c); + assert.deepEqual(app.toHiccup(), + ["root", {}, + ["div", { id: "foo3", class: "baz bux", key: "0" }, + ["div", { key: "0-0" }, ["span", { key: "0-0-0" }, "extra"]]]] + ); + }); +}); diff --git a/packages/hdom-mock/test/tsconfig.json b/packages/hdom-mock/test/tsconfig.json new file mode 100644 index 0000000000..bcf29ace54 --- /dev/null +++ b/packages/hdom-mock/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/hdom-mock/tsconfig.json b/packages/hdom-mock/tsconfig.json new file mode 100644 index 0000000000..bd6481a5a6 --- /dev/null +++ b/packages/hdom-mock/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "." + }, + "include": [ + "./src/**/*.ts" + ] +} From d3500df58dde64a2bac8bf4db471e04f2672623e Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 12 Dec 2018 09:10:48 +0000 Subject: [PATCH 16/35] feat(hiccup): add __skip support, add test, update readme --- packages/hiccup/README.md | 19 +++++++++++++++++++ packages/hiccup/src/serialize.ts | 2 +- packages/hiccup/test/index.ts | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/hiccup/README.md b/packages/hiccup/README.md index 82526e8c29..5c9fb88867 100644 --- a/packages/hiccup/README.md +++ b/packages/hiccup/README.md @@ -26,6 +26,7 @@ This project is part of the - [Data-driven component composition](#data-driven-component-composition) - [Stateful component](#stateful-component) - [Component objects](#component-objects) + - [Behavior control attributes](#behavior-control-attributes) - [API](#api) - [serialize(tree: any, ctx?: any, escape = false): string](#serializetree-any-ctx-any-escape--false-string) - [escape(str: string): string](#escapestr-string-string) @@ -59,6 +60,7 @@ rendering etc. For interactive use cases, please see companion package - Dynamic element attribute value generation via function values - CSS formatting of `style` attribute objects - Optional HTML entity encoding +- Branch-local behavior control attributes to control serialization - Small (2.2KB minified) & fast *) Lazy composition here means that functions are only executed at @@ -450,6 +452,20 @@ const component = { serialize([component, "Hello world", "Body"]); ``` +### Behavior control attributes + +The following attributes can be used to control the serialization +behavior of individual elements / tree branches: + +- **`__skip`** - if true, skips serialization (also used by + [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom)) +- **`__serialize`** - if false, skips serialization (hiccup only) + +```ts +serialize(["div.container", ["div", {__skip: true}, "ignore me"]]); +//
+``` + ## API The library exposes these two functions: @@ -521,6 +537,9 @@ context arg and can return any (serializable) value (i.e. new trees, strings, numbers, iterables or any type with a suitable .toString() implementation). +Please also see list of supported [behavior control +attributes](#behavior-control-attributes). + ### escape(str: string): string Helper function. Applies HTML entity replacement on given string. If diff --git a/packages/hiccup/src/serialize.ts b/packages/hiccup/src/serialize.ts index 3bf616b380..aa749d6e03 100644 --- a/packages/hiccup/src/serialize.ts +++ b/packages/hiccup/src/serialize.ts @@ -148,7 +148,7 @@ const _serialize = (tree: any, ctx: any, esc: boolean, span: boolean, keys: bool tree = normalize(tree); tag = tree[0]; const attribs = tree[1]; - if (attribs.__serialize === false) { + if (attribs.__skip || attribs.__serialize === false) { return ""; } let body = tree[2]; diff --git a/packages/hiccup/test/index.ts b/packages/hiccup/test/index.ts index 4a83c9e6fb..c6a9f85a24 100644 --- a/packages/hiccup/test/index.ts +++ b/packages/hiccup/test/index.ts @@ -263,4 +263,10 @@ describe("serialize", () => { ["div", { style: { a: (x) => x.b, b: 2 } }], `
` ); + + check( + "__skip", + ["a", ["b", { __skip: true }, "bb"], ["b", "bbb"]], + `bbb` + ); }); From 046ab206136f5b60031f711e54fb2e88784a3c9d Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 12 Dec 2018 09:23:37 +0000 Subject: [PATCH 17/35] minor(hiccup): reformat --- packages/hiccup/src/css.ts | 21 ++++---- packages/hiccup/src/escape.ts | 3 +- packages/hiccup/src/serialize.ts | 91 ++++++++++++++++++++------------ 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/packages/hiccup/src/css.ts b/packages/hiccup/src/css.ts index 0065a3a2f5..dee596eb47 100644 --- a/packages/hiccup/src/css.ts +++ b/packages/hiccup/src/css.ts @@ -1,13 +1,14 @@ import { isFunction } from "@thi.ng/checks/is-function"; -export const css = (rules: any) => { - let css = "", v; - for (let r in rules) { - v = rules[r]; - if (isFunction(v)) { - v = v(rules); +export const css = + (rules: any) => { + let css = "", v; + for (let r in rules) { + v = rules[r]; + if (isFunction(v)) { + v = v(rules); + } + v != null && (css += `${r}:${v};`); } - v != null && (css += `${r}:${v};`); - } - return css; -}; + return css; + }; diff --git a/packages/hiccup/src/escape.ts b/packages/hiccup/src/escape.ts index 954527dbf2..03735d5105 100644 --- a/packages/hiccup/src/escape.ts +++ b/packages/hiccup/src/escape.ts @@ -1,3 +1,4 @@ import { ENTITIES, ENTITY_RE } from "./api"; -export const escape = (x: string) => x.replace(ENTITY_RE, (y) => ENTITIES[y]); +export const escape = + (x: string) => x.replace(ENTITY_RE, (y) => ENTITIES[y]); diff --git a/packages/hiccup/src/serialize.ts b/packages/hiccup/src/serialize.ts index aa749d6e03..cd03ec3b16 100644 --- a/packages/hiccup/src/serialize.ts +++ b/packages/hiccup/src/serialize.ts @@ -121,10 +121,23 @@ import { escape } from "./escape"; * @param span use spans for text content * @param keys attach key attribs */ -export const serialize = (tree: any, ctx?: any, escape = false, span = false, keys = span, path = [0]) => - _serialize(tree, ctx, escape, span, keys, path); +export const serialize = ( + tree: any, + ctx?: any, + escape = false, + span = false, + keys = span, + path = [0] +) => _serialize(tree, ctx, escape, span, keys, path); -const _serialize = (tree: any, ctx: any, esc: boolean, span: boolean, keys: boolean, path: any[]) => { +const _serialize = ( + tree: any, + ctx: any, + esc: boolean, + span: boolean, + keys: boolean, + path: any[] +) => { if (tree == null) { return ""; } @@ -215,7 +228,14 @@ const _serialize = (tree: any, ctx: any, esc: boolean, span: boolean, keys: bool tree; }; -const _serializeIter = (iter: Iterable, ctx: any, esc: boolean, span: boolean, keys: boolean, path: any[]) => { +const _serializeIter = ( + iter: Iterable, + ctx: any, + esc: boolean, + span: boolean, + keys: boolean, + path: any[] +) => { const res = []; const p = path.slice(0, path.length - 1); let k = 0; @@ -223,38 +243,39 @@ const _serializeIter = (iter: Iterable, ctx: any, esc: boolean, span: boole res.push(_serialize(i, ctx, esc, span, keys, [...p, k++])); } return res.join(""); -} +}; -const normalize = (tag: any[]) => { - let el = tag[0]; - let match, id, clazz; - const hasAttribs = isPlainObject(tag[1]); - const attribs: any = hasAttribs ? { ...tag[1] } : {}; - if (!isString(el) || !(match = TAG_REGEXP.exec(el))) { - illegalArgs(`"${el}" is not a valid tag name`); - } - el = match[1]; - id = match[2]; - clazz = match[3]; - if (id) { - attribs.id = id; - } - if (clazz) { - clazz = clazz.replace(/\./g, " "); - if (attribs.class) { - attribs.class += " " + clazz; - } else { - attribs.class = clazz; +const normalize = + (tag: any[]) => { + let el = tag[0]; + let match, id, clazz; + const hasAttribs = isPlainObject(tag[1]); + const attribs: any = hasAttribs ? { ...tag[1] } : {}; + if (!isString(el) || !(match = TAG_REGEXP.exec(el))) { + illegalArgs(`"${el}" is not a valid tag name`); } - } - if (tag.length > 1) { - if (isPlainObject(attribs.style)) { - attribs.style = css(attribs.style); + el = match[1]; + id = match[2]; + clazz = match[3]; + if (id) { + attribs.id = id; + } + if (clazz) { + clazz = clazz.replace(/\./g, " "); + if (attribs.class) { + attribs.class += " " + clazz; + } else { + attribs.class = clazz; + } } - tag = tag.slice(hasAttribs ? 2 : 1).filter((x) => x != null); - if (tag.length > 0) { - return [el, attribs, tag]; + if (tag.length > 1) { + if (isPlainObject(attribs.style)) { + attribs.style = css(attribs.style); + } + tag = tag.slice(hasAttribs ? 2 : 1).filter((x) => x != null); + if (tag.length > 0) { + return [el, attribs, tag]; + } } - } - return [el, attribs]; -}; + return [el, attribs]; + }; From 1dc6e721ffd151e30675b54dc01dc904930b962a Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 12 Dec 2018 10:55:43 +0000 Subject: [PATCH 18/35] minor(hdom): intern strings --- packages/hdom/src/diff.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/hdom/src/diff.ts b/packages/hdom/src/diff.ts index e99db62c08..896627a5ce 100644 --- a/packages/hdom/src/diff.ts +++ b/packages/hdom/src/diff.ts @@ -235,6 +235,9 @@ const extractEquivElements = const OBJP = Object.getPrototypeOf({}); +const FN = "function"; +const STR = "string"; + /** * Customized version @thi.ng/equiv which takes `__diff` attributes into * account (at any nesting level). If an hdom element's attribute object @@ -251,20 +254,20 @@ export const equiv = return true; } if (a != null) { - if (typeof a.equiv === "function") { + if (typeof a.equiv === FN) { return a.equiv(b); } } else { return a == b; } if (b != null) { - if (typeof b.equiv === "function") { + if (typeof b.equiv === FN) { return b.equiv(a); } } else { return a == b; } - if (typeof a === "string" || typeof b === "string") { + if (typeof a === STR || typeof b === STR) { return false; } if ((proto = Object.getPrototypeOf(a), proto == null || proto === OBJP) && @@ -272,8 +275,8 @@ export const equiv = return !((a).__diff === false || (b).__diff === false) && equivObject(a, b, equiv); } - if (typeof a !== "function" && a.length !== undefined && - typeof b !== "function" && b.length !== undefined) { + if (typeof a !== FN && a.length !== undefined && + typeof b !== FN && b.length !== undefined) { return equivArrayLike(a, b, equiv); } if (a instanceof Set && b instanceof Set) { From c1fecc4df056bdd5fabb6c50056ce1e56f9034a3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Wed, 12 Dec 2018 13:31:55 +0000 Subject: [PATCH 19/35] refactor(hdom-mock): update text node handling, tests, add readme --- packages/hdom-mock/README.md | 57 ++++++++++++++++++++++++++++++-- packages/hdom-mock/src/index.ts | 42 ++++++++++++++--------- packages/hdom-mock/test/index.ts | 27 +++++++++------ 3 files changed, 96 insertions(+), 30 deletions(-) diff --git a/packages/hdom-mock/README.md b/packages/hdom-mock/README.md index 409a86fb4f..b7c66b1efb 100644 --- a/packages/hdom-mock/README.md +++ b/packages/hdom-mock/README.md @@ -9,11 +9,21 @@ This project is part of the +- [About](#about) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + ## About -TODO... +This package provides a mock implementation of the +[`HDOMImplementation`](https://github.com/thi-ng/umbrella/tree/master/packages/hdom/src/api.ts) +interface for testing and prototyping purposes of potential basis of +custom target implementations. ## Installation @@ -23,12 +33,53 @@ yarn add @thi.ng/hdom-mock ## Dependencies -- TODO... +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom) ## Usage examples ```ts -import * as hm from "@thi.ng/hdom-mock"; +import { HDOMNode, MockHDOM } from "@thi.ng/hdom-mock"; + +const title = (ctx, body) => ["h1", ctx.ui.title, body]; + +const ctx = { ui: { title: { class: "f1 lh-headline" } } }; +const opts = { ctx }; + +// target implementation +const impl = new MockHDOM(new HDOMNode("root", { id: "app" })); + +// some trees +const tree1 = impl.normalizeTree(opts, ["div#foo.bar", [title, "hello world"]]); +const tree2 = impl.normalizeTree(opts, ["div", [title, "hi hdom"], ["p.red", "Lorem ipsum"]]); + +// render hdom tree w/ mock implementation +impl.createTree(opts, impl.root, tree1)); + +// convert result DOM back to hiccup (for better clarity) +impl.root.toHiccup(); +// [ 'root', +// { id: 'app' }, +// [ 'div', +// { id: 'foo', class: 'bar', key: '0' }, +// [ 'h1', +// { class: 'f1 lh-headline', key: '0-0' }, +// [ 'span', { key: '0-0-0' }, 'hello world' ] ] ] ] + +// apply diff from tree1 -> tree2 +impl.diffTree(opts, impl.root, tree1, tree2); + +impl.root.children[0].toHiccup(); +// [ 'root', +// { id: 'app' }, +// [ 'div', +// { key: '0' }, +// [ 'h1', +// { class: 'f1 lh-headline', key: '0-0' }, +// [ 'span', { key: '0-0-0' }, 'hi hdom' ] ], +// [ 'p', +// { class: 'red', key: '0-1' }, +// [ 'span', { key: '0-1-0' }, 'Lorem ipsum' ] ] ] ] ``` ## Authors diff --git a/packages/hdom-mock/src/index.ts b/packages/hdom-mock/src/index.ts index db481bf372..5c9cc3f1f9 100644 --- a/packages/hdom-mock/src/index.ts +++ b/packages/hdom-mock/src/index.ts @@ -5,9 +5,17 @@ import { diffTree } from "@thi.ng/hdom/diff"; import { createTree, hydrateTree } from "@thi.ng/hdom/dom"; import { normalizeTree } from "@thi.ng/hdom/normalize"; +export const TEXT = Symbol(); + export class HDOMNode { parent: HDOMNode; + /** + * Only real child nodes + */ children: HDOMNode[]; + /** + * Includes real children AND text nodes + */ _children: HDOMNode[]; listeners: IObjectOf; @@ -15,12 +23,12 @@ export class HDOMNode { value: any; checked: boolean; - tag: string; + tag: string | symbol; attribs: IObjectOf; style: IObjectOf; body: string; - constructor(tag: string, attribs = {}) { + constructor(tag: string | symbol, attribs = {}) { this.tag = tag; this.children = []; this._children = []; @@ -31,7 +39,7 @@ export class HDOMNode { get textContent() { const res = []; for (let c of this._children) { - if (c.tag == "#") { + if (c.isText()) { res.push(c.body); } } @@ -39,16 +47,20 @@ export class HDOMNode { } set textContent(body: string) { - const txt = new HDOMNode("#"); + const txt = new HDOMNode(TEXT); txt.body = body; this._children = [txt]; this.children = []; } + isText() { + return this.tag === TEXT; + } + insertBefore(c: HDOMNode, i: number) { const existing = this.children[i]; if (existing) { - c.tag !== "#" && this.children.splice(i, 0, c); + !this.isText() && this.children.splice(i, 0, c); this._children.splice(this._children.indexOf(existing), 0, c); } else { this.appendChild(c); @@ -57,7 +69,7 @@ export class HDOMNode { } appendChild(c: HDOMNode) { - c.tag !== "#" && this.children.push(c); + !c.isText() && this.children.push(c); this._children.push(c); return c; } @@ -79,7 +91,7 @@ export class HDOMNode { } toHiccup() { - if (this.tag === "#") { + if (this.isText()) { return this.body; } const attr = { ...this.attribs }; @@ -90,7 +102,7 @@ export class HDOMNode { } } -export class MockImpl implements HDOMImplementation { +export class MockHDOM implements HDOMImplementation { root: HDOMNode; @@ -130,7 +142,7 @@ export class MockImpl implements HDOMImplementation { } createTextElement(parent: HDOMNode, content: string) { - const el = new HDOMNode("#"); + const el = new HDOMNode(TEXT); el.body = content; parent && parent.appendChild(el); return el; @@ -187,7 +199,9 @@ export class MockImpl implements HDOMImplementation { } } } else { - el[id] != null ? (el[id] = null) : (delete el.attribs[id]); + el[id] != null ? + (el[id] = null) : + (delete el.attribs[id]); } return el; } @@ -214,12 +228,8 @@ export class MockImpl implements HDOMImplementation { setStyle(el: HDOMNode, rules: IObjectOf) { for (let r in rules) { let v = rules[r]; - if (isFunction(v)) { - v = v(rules); - } - if (v != null) { - (el.style || (el.style = {}))[r] = v; - } + isFunction(v) && (v = v(rules)); + v != null && ((el.style || (el.style = {}))[r] = v); } } } diff --git a/packages/hdom-mock/test/index.ts b/packages/hdom-mock/test/index.ts index a0c3790d61..87744b74d9 100644 --- a/packages/hdom-mock/test/index.ts +++ b/packages/hdom-mock/test/index.ts @@ -1,11 +1,11 @@ import * as assert from "assert"; -import { HDOMNode, MockImpl } from "../src/index"; +import { HDOMNode, MockHDOM } from "../src/index"; describe("hdom-mock", () => { it("node", () => { const a = new HDOMNode("div"); - const impl = new MockImpl(a); + const impl = new MockHDOM(a); impl.createTextElement(a, "foo"); a.appendChild(new HDOMNode("span")); impl.createTextElement(a, "bar"); @@ -18,26 +18,31 @@ describe("hdom-mock", () => { it("basic diff", () => { const opts = { ctx: { button: { class: "bt" } } }; - const app = new HDOMNode("root"); - const impl = new MockImpl(app); - const a = impl.normalizeTree(opts, ["div#foo.bar", [(ctx, label) => ["button", { ...ctx.button }, label], "hi"]]); + const impl = new MockHDOM(new HDOMNode("root")); + + const step = (prev: any[], curr: any[], expected: any[]) => { + impl.diffTree(opts, impl.root, prev, curr); + assert.deepEqual(impl.root.toHiccup(), expected); + }; + + const a = impl.normalizeTree(opts, (ctx) => ["div#foo.bar", ["button", { ...ctx.button }, "hi"]]); const b = impl.normalizeTree(opts, ["div#foo2.bar.baz", [(ctx, label) => ["button", { ...ctx.button }, label], "hello"], ["div", "extra"]]); const c = impl.normalizeTree(opts, ["div#foo3.baz.bux", ["div", "extra"]]); - impl.diffTree(opts, app, [], a); - assert.deepEqual(app.toHiccup(), + + step([], a, ["root", {}, ["div", { id: "foo", class: "bar", key: "0" }, ["button", { class: "bt", key: "0-0" }, "hi"]]] ); - impl.diffTree(opts, app, a, b); - assert.deepEqual(app.toHiccup(), + + step(a, b, ["root", {}, ["div", { id: "foo2", class: "bar baz", key: "0" }, ["button", { class: "bt", key: "0-0" }, "hello"], ["div", { key: "0-1" }, ["span", { key: "0-1-0" }, "extra"]]]] ); - impl.diffTree(opts, app, b, c); - assert.deepEqual(app.toHiccup(), + + step(b, c, ["root", {}, ["div", { id: "foo3", class: "baz bux", key: "0" }, ["div", { key: "0-0" }, ["span", { key: "0-0-0" }, "extra"]]]] From ebd33808672ed83f96fe3049279106c3af7c45f9 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 00:13:20 +0000 Subject: [PATCH 20/35] feat(hdom-components): add FPS counter & sparkline components, update deps - add mergeAttribs() helper --- packages/hdom-components/package.json | 4 +- packages/hdom-components/src/fps-counter.ts | 71 ++++++++++++++++++ packages/hdom-components/src/index.ts | 4 + packages/hdom-components/src/sparkline.ts | 74 +++++++++++++++++++ .../src/utils/merge-attribs.ts | 16 ++++ 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 packages/hdom-components/src/fps-counter.ts create mode 100644 packages/hdom-components/src/sparkline.ts create mode 100644 packages/hdom-components/src/utils/merge-attribs.ts diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index a54890f6a6..bd1f401303 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -30,7 +30,9 @@ "dependencies": { "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", + "@thi.ng/math": "^0.2.1", "@thi.ng/transducers": "^2.2.4", + "@thi.ng/transducers-stats": "^0.4.16", "@types/webgl2": "^0.0.4" }, "keywords": [ @@ -40,4 +42,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/hdom-components/src/fps-counter.ts b/packages/hdom-components/src/fps-counter.ts new file mode 100644 index 0000000000..cb6380b4a2 --- /dev/null +++ b/packages/hdom-components/src/fps-counter.ts @@ -0,0 +1,71 @@ +import { sma } from "@thi.ng/transducers-stats/sma"; +import { step } from "@thi.ng/transducers/step"; +import { sparkline, SparklineOpts } from "./sparkline"; + +export interface FpsCounterOpts { + /** + * Number of recorded samples. + * Default: 25 + */ + history: number; + /** + * Moving average smoothing period. + * Default: 5 + */ + smooth: number; + /** + * Period (in ms) between label updates. + * Default: 250 + */ + labelPeriod: number; + /** + * Sparkline config options. + * Default: sparkline defaults + */ + sparkline?: Partial; +} + +/** + * Customizable FPS counter with sparkline visualization of N previous + * frames. + * + * @param opts + */ +export const fpsCounter = + (opts?: Partial) => { + opts = { + history: 25, + smooth: 5, + labelPeriod: 100, + sparkline: {}, + ...opts + }; + return { + init() { + this.last = Date.now(); + this.lastLabel = this.last; + this.buffer = []; + this.ma = step(sma(opts.smooth)); + }, + render() { + const t = Date.now(); + const fps = 1000 / (t - this.last); + this.last = t; + if (!this.buffer) return ["div"]; + const smoothFps = this.ma(fps); + if (!smoothFps) return ["div"]; + this.buffer.push(smoothFps); + this.buffer.length > opts.history && this.buffer.shift(); + const updateLabel = t - this.lastLabel > opts.labelPeriod; + updateLabel && (this.lastLabel = t); + return ["div", + [sparkline, + { min: 0, max: 65, ...opts.sparkline }, + this.buffer], + ["span", + { __skip: !updateLabel }, + smoothFps ? smoothFps.toFixed(2) + "fps" : ""] + ]; + } + }; + }; diff --git a/packages/hdom-components/src/index.ts b/packages/hdom-components/src/index.ts index e20ce3cc2f..303a7bde1d 100644 --- a/packages/hdom-components/src/index.ts +++ b/packages/hdom-components/src/index.ts @@ -2,7 +2,11 @@ export * from "./button"; export * from "./button-group"; export * from "./canvas"; export * from "./dropdown"; +export * from "./fps-counter"; export * from "./link"; export * from "./notification"; export * from "./pager"; +export * from "./sparkline"; export * from "./title"; + +export * from "./utils/merge-attribs"; diff --git a/packages/hdom-components/src/sparkline.ts b/packages/hdom-components/src/sparkline.ts new file mode 100644 index 0000000000..ee66c7a27b --- /dev/null +++ b/packages/hdom-components/src/sparkline.ts @@ -0,0 +1,74 @@ +import { fitClamped } from "@thi.ng/math/fit"; +import { str } from "@thi.ng/transducers/rfn/str"; +import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; + +export interface SparklineOpts { + /** + * Sparkline width + * Default: 50 + */ + width: number; + /** + * Sparkline height + * Default: 16 + */ + height: number; + /** + * Min domain value. + * Default: 0 + */ + min: number; + /** + * Max domain value. + * Default: 100 + */ + max: number; + /** + * Sparkline CSS color + * Default: red + */ + col: string; + /** + * Radius of sparkline head marker circle. + * Default: 1.5 + */ + r: number; +} + +/** + * Customizable, stateless SVG sparkline component. + * + * @param _ hdom context object (ignored) + * @param opts config options + * @param vals data values + */ +export const sparkline = + (_, opts: Partial, vals: number[]) => { + opts = { + min: 0, + max: 100, + width: 50, + height: 16, + col: "red", + r: 1.5, + ...opts + }; + const n = vals.length; + const s = opts.width / n; + const r = opts.r; + const h = opts.height - r; + return ["svg", + { + width: opts.width + 2 * r, + height: opts.height, + stroke: opts.col, + fill: "none" + }, + ["polyline", + { + points: str(",", mapIndexed((i, y: number) => [i * s, fitClamped(y, opts.min, opts.max, h, r)], 0, vals)) + }], + ["circle", + { cx: (n - 1) * s, cy: fitClamped(vals[n - 1], opts.min, opts.max, h, r), r, fill: opts.col }] + ]; + }; diff --git a/packages/hdom-components/src/utils/merge-attribs.ts b/packages/hdom-components/src/utils/merge-attribs.ts new file mode 100644 index 0000000000..1c45ada7bf --- /dev/null +++ b/packages/hdom-components/src/utils/merge-attribs.ts @@ -0,0 +1,16 @@ +/** + * Helper function to immutably merge attribs from two sources and + * concatenate their `class` values and merge their `style` maps (if + * present). Returns merged result object. + * + * @param base base attribs + * @param xs overrides + */ +export const mergeAttribs = + (base: any, xs: any) => { + if (!xs) return base; + const res = { ...base, ...xs }; + base.class && xs.class && (res.class = base.class + " " + xs.class); + base.style && xs.style && (res.style = { ...base.style, ...xs.style }); + return res; + }; From baa1dfef8542e7ed8fd0e9272a4620a4a975a99b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 00:38:52 +0000 Subject: [PATCH 21/35] feat(examples): add hdom-benchmark2 example --- examples/hdom-benchmark2/.gitignore | 5 ++ examples/hdom-benchmark2/README.md | 18 +++++ examples/hdom-benchmark2/index.html | 19 +++++ examples/hdom-benchmark2/package.json | 31 +++++++ examples/hdom-benchmark2/src/index.ts | 108 +++++++++++++++++++++++++ examples/hdom-benchmark2/tsconfig.json | 11 +++ 6 files changed, 192 insertions(+) create mode 100644 examples/hdom-benchmark2/.gitignore create mode 100644 examples/hdom-benchmark2/README.md create mode 100644 examples/hdom-benchmark2/index.html create mode 100644 examples/hdom-benchmark2/package.json create mode 100644 examples/hdom-benchmark2/src/index.ts create mode 100644 examples/hdom-benchmark2/tsconfig.json diff --git a/examples/hdom-benchmark2/.gitignore b/examples/hdom-benchmark2/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/hdom-benchmark2/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/hdom-benchmark2/README.md b/examples/hdom-benchmark2/README.md new file mode 100644 index 0000000000..f08f0c4cff --- /dev/null +++ b/examples/hdom-benchmark2/README.md @@ -0,0 +1,18 @@ +# hdom-benchmark2 + +[Live demo](http://demo.thi.ng/umbrella/hdom-benchmark2/) + +```bash +git clone https://github.com/thi-ng/umbrella.git +cd umbrella/examples/hdom-benchmark2 +yarn install +yarn start +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/hdom-benchmark2/index.html b/examples/hdom-benchmark2/index.html new file mode 100644 index 0000000000..b07d62700c --- /dev/null +++ b/examples/hdom-benchmark2/index.html @@ -0,0 +1,19 @@ + + + + + + + + hdom-benchmark2 + + + + + +
+ + + + \ No newline at end of file diff --git a/examples/hdom-benchmark2/package.json b/examples/hdom-benchmark2/package.json new file mode 100644 index 0000000000..c5e1f9fd97 --- /dev/null +++ b/examples/hdom-benchmark2/package.json @@ -0,0 +1,31 @@ +{ + "name": "hdom-benchmark2", + "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 --public-url ./ --no-source-maps --no-cache --detailed-report", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.10.3", + "terser": "^3.10.1", + "typescript": "^3.1.3" + }, + "dependencies": { + "@thi.ng/binary": "latest", + "@thi.ng/hdom": "latest", + "@thi.ng/hdom-components": "latest", + "@thi.ng/hiccup-css": "latest", + "@thi.ng/strings": "latest", + "@thi.ng/transducers": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} \ No newline at end of file diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts new file mode 100644 index 0000000000..719a3f5f40 --- /dev/null +++ b/examples/hdom-benchmark2/src/index.ts @@ -0,0 +1,108 @@ +import { splat4_24 } from "@thi.ng/binary/splat"; +import { dropdown } from "@thi.ng/hdom-components/dropdown"; +import { fpsCounter } from "@thi.ng/hdom-components/fps-counter"; +import { start } from "@thi.ng/hdom/start"; +import { css } from "@thi.ng/hiccup-css/css"; +import { injectStyleSheet } from "@thi.ng/hiccup-css/inject"; +import { U24 } from "@thi.ng/strings/radix"; +import { comp } from "@thi.ng/transducers/func/comp"; +import { range } from "@thi.ng/transducers/iter/range"; +import { push } from "@thi.ng/transducers/rfn/push"; +import { transduce } from "@thi.ng/transducers/transduce"; +import { map } from "@thi.ng/transducers/xform/map"; +import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; +import { partition } from "@thi.ng/transducers/xform/partition"; + +const SIZE = "0.5rem"; +const RES = 32; +const DELTA = 1024; + +injectStyleSheet( + css([ + map( + (x: number) => + [`.cell-${x}`, { + background: `#${U24(splat4_24(x))}` + }], + range(16) + ), + map( + (x: number) => + [`.xcell-${x}`, { + background: `#${U24(splat4_24(x) | 0x00ff00)}` + }], + range(16) + ), + [".cell", { + display: "inline-block", + width: SIZE, + height: SIZE, + }], + [".row", { + height: SIZE + }], + ]) +); + +const grid = (w, numChanges) => ({ + init() { + this.cells = new Array(w * w).fill(0); + this.frame = 0; + }, + render(_, interlace) { + if (!this.cells) return ["div"]; + const num = w * w; + const changed = new Set(); + for (let i = 0; i < numChanges; i++) { + const idx = (Math.random() * num) | 0; + changed.add(idx); + this.cells[idx] = (this.cells[idx] + 1) % 16; + } + const isFirst = this.frame == 0; + const body = transduce( + comp( + mapIndexed((i, x) => { + const diff = isFirst || changed.has(i); + return ["span", { key: "c" + i, __diff: diff, class: `cell ${diff ? "x" : ""}cell-${x}` }]; + } + ), + partition(w), + mapIndexed((i, row) => + ["div.row", { key: "r" + i, __skip: !isFirst && ((i + this.frame) & interlace) }, ...row] + ) + ), + push(), + ["div"], + this.cells + ); + this.frame++; + return body; + } +}); + +const grid1 = grid(RES, DELTA); +const stats = fpsCounter({ history: 50, sparkline: { width: 100 } }); + +let interlace = 1; + +const cancel = start( + () => ["div.ma3.code", + ["div", [grid1, interlace]], + ["div.mt3", [stats]], + ["div.mt3", + "Interlace: ", + [dropdown, + { class: "code", onchange: (e) => interlace = parseInt(e.target.value) }, + [[0, "None"], [1, 1], [3, 3], [7, 7], [15, 15], [31, 31]], + interlace + ] + ], + ["div.mt3", `~${DELTA / (interlace + 1) + RES / (interlace + 1) + 20} nodes diffed per frame, ${RES * RES + RES + 20} total`] + ]); + +// window["stop"] = cancel; + +const hot = (module).hot; +if (hot) { + hot.dispose(cancel); +} diff --git a/examples/hdom-benchmark2/tsconfig.json b/examples/hdom-benchmark2/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/hdom-benchmark2/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} From 73a298df98bf0dacaf7f1dd3706aa4f53b00612b Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 01:27:41 +0000 Subject: [PATCH 22/35] refactor(hdom-components): emit int coords for sparkline --- packages/hdom-components/src/sparkline.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hdom-components/src/sparkline.ts b/packages/hdom-components/src/sparkline.ts index ee66c7a27b..d322b3e6b5 100644 --- a/packages/hdom-components/src/sparkline.ts +++ b/packages/hdom-components/src/sparkline.ts @@ -66,9 +66,9 @@ export const sparkline = }, ["polyline", { - points: str(",", mapIndexed((i, y: number) => [i * s, fitClamped(y, opts.min, opts.max, h, r)], 0, vals)) + points: str(",", mapIndexed((i, y: number) => [(i * s) | 0, fitClamped(y, opts.min, opts.max, h, r) | 0], 0, vals)) }], ["circle", - { cx: (n - 1) * s, cy: fitClamped(vals[n - 1], opts.min, opts.max, h, r), r, fill: opts.col }] + { cx: ((n - 1) * s) | 0, cy: fitClamped(vals[n - 1], opts.min, opts.max, h, r) | 0, r, fill: opts.col }] ]; }; From ba0d5e5cd4a3d781cc67c6a6c4e3c643b8ac7909 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 01:38:26 +0000 Subject: [PATCH 23/35] docs(examples): update readme list --- examples/README.md | 60 ++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/examples/README.md b/examples/README.md index 5b41e4baaf..2472d69dad 100644 --- a/examples/README.md +++ b/examples/README.md @@ -13,31 +13,35 @@ If you want to [contribute](../CONTRIBUTING.md) an example, please get in touch | 5 | [crypto-chart](./crypto-chart) | Interactive rstream & transducer based SVG chart | hdom, hiccup-svg, rstream, transducers | advanced | | 6 | [dashboard](./dashboard) | Barebones components w/ local state | hdom, transducers | basic | | 7 | [devcards](./devcards) | Multiple app instances with/without shared state | atom, hdom | intermediate | -| 8 | [geom-tessel](./geom-tessel) | @thi.ng/geom shape tesselations & hdom-canvas drawing | geom, hdom-canvas, vectors | intermediate | -| 9 | [gesture-analysis](./gesture-analysis) | Mouse/touch gesture processing, analysis & visualization | rstream, rstream-gestures, transducers, hiccup-svg | intermediate | -| 10 | [hdom-basics](./hdom-basics) | Hello world | hdom, hiccup | basic | -| 11 | [hdom-benchmark](./hdom-benchmark) | hdom rendering perf / stress test, FPS counter | hdom, rstream, transducers | intermediate | -| 12 | [hdom-canvas-clock](./hdom-canvas-clock) | hdom-canvas rendered clock | hdom, hdom-canvas, transducers | basic | -| 13 | [hdom-canvas-draw](./hdom-canvas-draw) | hdom-canvas mouse / touch gesture drawing | hdom, hdom-canvas, transducers | intermediate | -| 14 | [hdom-canvas-shapes](./hdom-canvas-shapes) | various hdom-canvas shape tests | hdom, hdom-canvas, rstream, transducers | basic | -| 15 | [hdom-dyn-context](./hdom-dyn-context) | dynamic hdom user context / theming | atom, hdom | basic | -| 16 | [hdom-theme-adr-0003](./hdom-theme-adr-0003) | hdom themed components proposal | hdom | intermediate | -| 17 | [hmr-basics](./hmr-basics) | hdom & hot module replacement | hdom, memoize | basic | -| 18 | [hydrate-basics](./hydrate-basics) | hiccup / hdom DOM hydration | hiccup, hdom | intermediate | -| 19 | [interceptor-basics](./interceptor-basics) | Event handling w/ interceptors and side effects | atom, hdom, interceptors | intermediate | -| 20 | [json-components](./json-components) | JSON->component transformation, live editor | hdom, transducers | intermediate | -| 21 | [login-form](./login-form) | Basic SPA without router | atom, hdom | intermediate | -| 22 | [mandelbrot](./mandelbrot) | Worker-based mandelbrot fractal renderer | rstream, rstream-gestures, transducers-hdom | advanced | -| 23 | [pointfree-svg](./pointfree-svg) | Generate SVG using pointfree DSL | hiccup, hiccup-svg, pointfree-lang | intermediate | -| 24 | [router-basics](./router-basics) | Complete mini SPA | atom, hdom, interceptors, router | advanced | -| 25 | [rstream-dataflow](./rstream-dataflow) | Dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate | -| 26 | [rstream-grid](./rstream-grid) | Dataflow graph SVG grid | atom, hdom, hiccup-svg, interceptors, rstream-graph, transducers | advanced | -| 27 | [rstream-hdom](./rstream-hdom) | rstream based UI updates & state handling | hdom, rstream, transducers | intermediate | -| 28 | [svg-barchart](./svg-barchart) | hdom SVG barchart component | hdom, transducers | basic | -| 29 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic | -| 30 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate | -| 31 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate | -| 32 | [transducers-hdom](./transducers-hdom) | Transducer & rstream based hdom UI updates | hdom, rstream, transducers-hdom | basic | -| 33 | [triple-query](./triple-query) | Triple store query results & sortable table | atom, hdom, hdom-components, rstream-query, transducers | intermediate | -| 34 | [webgl](./webgl) | Canvas component handling | hdom, hdom-components | basic | -| 35 | [xml-converter](./xml-converter) | XML/HTML/SVG to hiccup conversion as you type | rstream, sax, transducers, transducers-hdom | advanced | +| 8 | [geom-knn](./geom-knn) | @thi.ng/geom-accel k-D tree | geom, geom-accel, hdom-canvas, vectors | intermediate | +| 9 | [geom-tessel](./geom-tessel) | @thi.ng/geom shape tesselations & hdom-canvas drawing | geom, hdom-canvas, vectors | intermediate | +| 10 | [gesture-analysis](./gesture-analysis) | Mouse/touch gesture processing, analysis & visualization | rstream, rstream-gestures, transducers, hiccup-svg | intermediate | +| 11 | [hdom-basics](./hdom-basics) | Hello world | hdom, hiccup | basic | +| 12 | [hdom-benchmark](./hdom-benchmark) | hdom rendering perf / stress test, FPS counter | hdom, rstream, transducers | intermediate | +| 13 | [hdom-benchmark2](./hdom-benchmark2) | hdom rendering perf / stress test, FPS counter | hdom, hdom-components, hiccup-css, transducers, stats | intermediate | +| 14 | [hdom-canvas-clock](./hdom-canvas-clock) | hdom-canvas rendered clock | hdom, hdom-canvas, transducers | basic | +| 15 | [hdom-canvas-draw](./hdom-canvas-draw) | hdom-canvas mouse / touch gesture drawing | hdom, hdom-canvas, transducers | intermediate | +| 16 | [hdom-canvas-shapes](./hdom-canvas-shapes) | various hdom-canvas shape tests | hdom, hdom-canvas, rstream, transducers | basic | +| 17 | [hdom-dyn-context](./hdom-dyn-context) | dynamic hdom user context / theming | atom, hdom | basic | +| 18 | [hdom-skip](./hdom-skip) | selective component updates | hdom | basic | +| 19 | [hdom-theme-adr-0003](./hdom-theme-adr-0003) | hdom themed components proposal | hdom | intermediate | +| 20 | [hmr-basics](./hmr-basics) | hdom & hot module replacement | hdom, memoize | basic | +| 21 | [hydrate-basics](./hydrate-basics) | hiccup / hdom DOM hydration | hiccup, hdom | intermediate | +| 22 | [interceptor-basics](./interceptor-basics) | Event handling w/ interceptors and side effects | atom, hdom, interceptors | basic | +| 23 | [interceptor-basics2](./interceptor-basics2) | Event handling w/ interceptors and side effects | atom, hdom, interceptors | intermediate | +| 24 | [json-components](./json-components) | JSON->component transformation, live editor | hdom, transducers | intermediate | +| 25 | [login-form](./login-form) | Basic SPA without router | atom, hdom | intermediate | +| 26 | [mandelbrot](./mandelbrot) | Worker-based mandelbrot fractal renderer | rstream, rstream-gestures, transducers-hdom | advanced | +| 27 | [pointfree-svg](./pointfree-svg) | Generate SVG using pointfree DSL | hiccup, hiccup-svg, pointfree-lang | intermediate | +| 28 | [router-basics](./router-basics) | Complete mini SPA | atom, hdom, interceptors, router | advanced | +| 29 | [rstream-dataflow](./rstream-dataflow) | Dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate | +| 30 | [rstream-grid](./rstream-grid) | Dataflow graph SVG grid | atom, hdom, hiccup-svg, interceptors, rstream-graph, transducers | advanced | +| 31 | [rstream-hdom](./rstream-hdom) | rstream based UI updates & state handling | hdom, rstream, transducers | intermediate | +| 32 | [svg-barchart](./svg-barchart) | hdom SVG barchart component | hdom, transducers | basic | +| 33 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic | +| 34 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate | +| 35 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate | +| 36 | [transducers-hdom](./transducers-hdom) | Transducer & rstream based hdom UI updates | hdom, rstream, transducers-hdom | basic | +| 37 | [triple-query](./triple-query) | Triple store query results & sortable table | atom, hdom, hdom-components, rstream-query, transducers | intermediate | +| 38 | [webgl](./webgl) | Canvas component handling | hdom, hdom-components | basic | +| 39 | [xml-converter](./xml-converter) | XML/HTML/SVG to hiccup conversion as you type | rstream, sax, transducers, transducers-hdom | advanced | \ No newline at end of file From 8dcc73a1527edde463c36cb642c5df370cd032b8 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 01:40:11 +0000 Subject: [PATCH 24/35] feat(strings): add slugify() --- packages/strings/src/index.ts | 1 + packages/strings/src/slugify.ts | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 packages/strings/src/slugify.ts diff --git a/packages/strings/src/index.ts b/packages/strings/src/index.ts index 578bb17200..ea90fc1018 100644 --- a/packages/strings/src/index.ts +++ b/packages/strings/src/index.ts @@ -9,6 +9,7 @@ export * from "./parse"; export * from "./percent"; export * from "./radix"; export * from "./repeat"; +export * from "./slugify"; export * from "./splice"; export * from "./truncate"; export * from "./truncate-left"; diff --git a/packages/strings/src/slugify.ts b/packages/strings/src/slugify.ts new file mode 100644 index 0000000000..086bcbc358 --- /dev/null +++ b/packages/strings/src/slugify.ts @@ -0,0 +1,24 @@ +import { Stringer } from "./api"; + +const src = "àáäâãåèéëêìíïîòóöôùúüûñçßÿœæŕśńṕẃǵǹḿǘẍźḧ·/_,:;" +const dest = "aaaaaaeeeeiiiioooouuuuncsyoarsnpwgnmuxzh------"; +const re = new RegExp(src.split("").join("|"), "g") + +/** + * Based on: + * https://medium.com/@matthagemann/the-ultimate-way-to-slugify-a-url-string-in-javascript-b8e4a0d849e1 + * + * @param str + */ +export const slugify: Stringer = + (str: string) => { + return str + .toLowerCase() + .replace(/\s+/g, "-") + .replace(re, c => dest[src.indexOf(c)]) + .replace(/&+/g, "-and-") + .replace(/[^\w\-]+/g, "") + .replace(/\-{2,}/g, "-") + .replace(/^-+/, "") + .replace(/-+$/, ""); + }; From 1b298f76ab267fdb8db6a0a90e4524bd50222c0c Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 01:41:39 +0000 Subject: [PATCH 25/35] fix(strings): update kebab() - fix initial capital handling - add (partial) UTF-8 support - add note about Safari / FF --- packages/strings/src/case.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/strings/src/case.ts b/packages/strings/src/case.ts index 7bccb526d5..2a2c6d82ba 100644 --- a/packages/strings/src/case.ts +++ b/packages/strings/src/case.ts @@ -28,6 +28,11 @@ export const capitalize: Stringer = * Converts a CamelCase string into kebab case, with optional custom * delimiter (`-` by default). * + * TODO: Currently broken in Safari & FF due to usage of TC39 stage 4 + * RegEx look-behind expression: + * + * https://github.com/tc39/proposal-regexp-lookbehind + * * ``` * kebab("FooBar23Baz"); * // "foo-bar23-baz" @@ -38,7 +43,12 @@ export const capitalize: Stringer = */ export const kebab: Stringer = (x: string, delim = "-") => - lower(x.replace(/(?<=\w)(?=[A-Z])/g, delim)); + lower( + x.replace( + /(?<=[a-z0-9\u00e0-\u00fd])(?=[A-Z\u00c0-\u00dd])/g, + (_, i) => (i ? delim : "") + ) + ); /** * Short for `kebab` using `_` as delimiter. From 10afa0d58a4d85cf30c2bb92376f8492d2c73e45 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 12:00:52 +0000 Subject: [PATCH 26/35] docs(examples): update hdom-skip comments --- examples/hdom-skip/src/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/hdom-skip/src/index.ts b/examples/hdom-skip/src/index.ts index ccf31dff9e..64ad9c36f3 100644 --- a/examples/hdom-skip/src/index.ts +++ b/examples/hdom-skip/src/index.ts @@ -12,12 +12,14 @@ const timer = render() { // Key part of this example: - // Here we check the current time stamp for timer `period` - // crossings and only return an actual new tree/content iff - // the time stamp is within 16ms of the period. In all other - // cases, we return some dummy content with the root element - // using the hdom `__skip` control attribute to skip diffing - // of this branch and not apply the given tree/branch. + // Here we check the current time stamp for timer + // `period` crossings and only return an actual new + // tree/content iff the time stamp is within 16ms of the + // period (i.e. in the 1 frame following the timer + // period). In all other cases, we return some dummy + // content with the root element using the hdom `__skip` + // control attribute to skip diffing of this branch and + // not apply the given tree/branch. // IMPORTANT: the element type of the skipped branch MUST // match the type of the real content (e.g. here `div`) From a40c0f5efed910dd4af693c92f5c6bf54a4659a2 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 12:01:17 +0000 Subject: [PATCH 27/35] minor(hdom-components): minor updates fpsCounter() --- packages/hdom-components/src/fps-counter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hdom-components/src/fps-counter.ts b/packages/hdom-components/src/fps-counter.ts index cb6380b4a2..695272d16e 100644 --- a/packages/hdom-components/src/fps-counter.ts +++ b/packages/hdom-components/src/fps-counter.ts @@ -36,7 +36,7 @@ export const fpsCounter = opts = { history: 25, smooth: 5, - labelPeriod: 100, + labelPeriod: 250, sparkline: {}, ...opts }; @@ -64,7 +64,7 @@ export const fpsCounter = this.buffer], ["span", { __skip: !updateLabel }, - smoothFps ? smoothFps.toFixed(2) + "fps" : ""] + smoothFps ? smoothFps.toFixed(2) + " fps" : ""] ]; } }; From c3b1528fb782ecc48b13f8e96b480ec8cb3aada0 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 12:02:00 +0000 Subject: [PATCH 28/35] feat(examples): add more UI & controls to hdom-benchmark2 --- examples/hdom-benchmark2/src/index.ts | 137 ++++++++++++++++++-------- 1 file changed, 94 insertions(+), 43 deletions(-) diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts index 719a3f5f40..2426a808d3 100644 --- a/examples/hdom-benchmark2/src/index.ts +++ b/examples/hdom-benchmark2/src/index.ts @@ -14,8 +14,6 @@ import { mapIndexed } from "@thi.ng/transducers/xform/map-indexed"; import { partition } from "@thi.ng/transducers/xform/partition"; const SIZE = "0.5rem"; -const RES = 32; -const DELTA = 1024; injectStyleSheet( css([ @@ -44,61 +42,114 @@ injectStyleSheet( ]) ); -const grid = (w, numChanges) => ({ - init() { - this.cells = new Array(w * w).fill(0); - this.frame = 0; - }, - render(_, interlace) { - if (!this.cells) return ["div"]; +const grid = + (_, cells, w, numChanges, frame, interlace) => { + if (!frame) return ["div"]; + const isFirst = frame === 1; const num = w * w; const changed = new Set(); for (let i = 0; i < numChanges; i++) { const idx = (Math.random() * num) | 0; changed.add(idx); - this.cells[idx] = (this.cells[idx] + 1) % 16; + cells[idx] = (cells[idx] + 1) % 16; } - const isFirst = this.frame == 0; - const body = transduce( - comp( - mapIndexed((i, x) => { - const diff = isFirst || changed.has(i); - return ["span", { key: "c" + i, __diff: diff, class: `cell ${diff ? "x" : ""}cell-${x}` }]; - } + const body = + transduce( + comp( + mapIndexed((i, x) => { + const diff = isFirst || changed.has(i); + return ["span", { + key: "c" + i, + __diff: diff, + class: `cell ${diff ? "x" : ""}cell-${x}` + }]; + } + ), + partition(w), + mapIndexed((i, row) => + ["div.row", { + key: "r" + i, + __skip: !isFirst && ((i + frame) & interlace) + }, row] + ) ), - partition(w), - mapIndexed((i, row) => - ["div.row", { key: "r" + i, __skip: !isFirst && ((i + this.frame) & interlace) }, ...row] - ) - ), - push(), - ["div"], - this.cells - ); - this.frame++; + push(), + ["div"], + cells + ); return body; - } -}); + }; + +const formatInterlace = (x) => { + const res = x ? "but only every" : "and every"; + return x === 0 ? + res : + x === 1 ? + res + " 2nd" : + `${res} ${x + 1}th`; +}; + +const newCells = (res) => new Array(res * res).fill(0); -const grid1 = grid(RES, DELTA); const stats = fpsCounter({ history: 50, sparkline: { width: 100 } }); +let cells = newCells(32); let interlace = 1; +let res = 32; +let delta = 1024; +let frame = -1; + +const resOpts = [[24, 24], [32, 32], [40, 40], [48, 48], [56, 56], [64, 64]]; +const deltaOpts = [[64, 64], [128, 128], [256, 256], [512, 512], [1024, 1024]]; +const interlaceOpts = [[0, "None"], [1, 2], [3, 4], [7, 8], [15, 16], [31, 32]]; const cancel = start( - () => ["div.ma3.code", - ["div", [grid1, interlace]], - ["div.mt3", [stats]], - ["div.mt3", - "Interlace: ", - [dropdown, - { class: "code", onchange: (e) => interlace = parseInt(e.target.value) }, - [[0, "None"], [1, 1], [3, 3], [7, 7], [15, 15], [31, 31]], - interlace - ] - ], - ["div.mt3", `~${DELTA / (interlace + 1) + RES / (interlace + 1) + 20} nodes diffed per frame, ${RES * RES + RES + 20} total`] - ]); + () => { + frame++; + const total = res * res + res + 24; + const estimate = Math.min(delta / (interlace + 1) + res / (interlace + 1) + 24, total); + return ["div.ma3.code.f7", + ["div.measure.lh-copy", + `Each grid cell is one element. + ${delta} random cell states will be updated each frame, + ${formatInterlace(interlace)} row will be updated in the browser DOM.`], + ["div.mt3", ["span.pink", `~${estimate}`], " real node updates/frame, ", ["span.pink", total], " DOM nodes total"], + ["div.mt3", [grid, cells, res, delta, frame, interlace]], + ["div.mt3", [stats]], + ["div.mt3", + ["span.w5.dib", "Resolution: "], + [dropdown, + { + class: "w3 code", + onchange: (e) => (res = parseInt(e.target.value), frame = -1, cells = newCells(res)) + }, + resOpts, + res] + ], + ["div.mt3", + ["span.w5.dib", "Random updates/frame: "], + [dropdown, + { + class: "w3 code", + onchange: (e) => (delta = parseInt(e.target.value)) + }, + deltaOpts, + delta] + ], + ["div.mt3", + ["span.w5.dib", "Interlace rows: "], + [dropdown, + { + class: "w3 code", + onchange: (e) => (interlace = parseInt(e.target.value)) + }, + interlaceOpts, + interlace] + ], + ["div.mt3", + ["a", { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-benchmark2" }, "Source"]] + ]; + }); // window["stop"] = cancel; From 92c1110766acc793b44bbdd972e633a7af2fbf44 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 12:03:14 +0000 Subject: [PATCH 29/35] feat(examples): improve axis tick resolution estimate in crypto-chart --- examples/crypto-chart/src/index.ts | 32 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/examples/crypto-chart/src/index.ts b/examples/crypto-chart/src/index.ts index 98e5827b28..9566131cb8 100644 --- a/examples/crypto-chart/src/index.ts +++ b/examples/crypto-chart/src/index.ts @@ -243,7 +243,9 @@ const chart = sync({ xform: map(({ data, window, theme }) => { let [width, height] = window; const ohlc: OHLC[] = data.ohlc; - const w = Math.max(3, (width - 2 * MARGIN_X) / ohlc.length); + const chartW = width - 2 * MARGIN_X; + const chartH = height - 2 * MARGIN_Y; + const bw = Math.max(3, chartW / ohlc.length); const by = height - MARGIN_Y; const mapX = (x: number) => fit(x, 0, ohlc.length, MARGIN_X, width - MARGIN_X); @@ -256,13 +258,27 @@ const chart = sync({ ); // use preset time precisions based on current chart period - const tickX = TIME_TICKS[data.period]; + let tickX: number = TIME_TICKS[data.period]; + const timeRange = data.tbounds[1] - data.tbounds[0]; + while (chartW / (timeRange / tickX) < 60) { + tickX *= 2; + } const fmtTime: (t: number) => string = TIME_FORMATS[data.period]; - // price resolution estimation based on actual OHLC interval - let tickY = Math.pow(10, Math.floor(Math.log(data.max - data.min) / Math.log(10))) / 2; - while (tickY < (data.max - data.min) / 20) { + + // price tick resolution estimation based on actual OHLC interval & window height + const domain = data.max - data.min; + // min tick in currency + const minTickY = 0.0025; + // min tick in screen coords + const minProjTickY = Math.max(chartH / 8, 50); + let tickY = Math.pow(10, Math.floor(Math.log(domain) / Math.log(10))) / 2; + while (tickY > minTickY && chartH / (domain / tickY) > minProjTickY) { + tickY /= 2; + } + while (chartH / (domain / tickY) < minProjTickY) { tickY *= 2; } + const lastPrice = ohlc[ohlc.length - 1].close; const closeX = width - MARGIN_X; const closeY = mapY(lastPrice); @@ -293,7 +309,7 @@ const chart = sync({ // X axis ticks mapcat( (t: number) => { - const x = fit(t, data.tbounds[0], data.tbounds[1], MARGIN_X + w / 2, width - MARGIN_X - w / 2); + const x = fit(t, data.tbounds[0], data.tbounds[1], MARGIN_X + bw / 2, width - MARGIN_X - bw / 2); return [ line([x, by], [x, by + 10]), line([x, MARGIN_Y], [x, by], { stroke: theme.chart.gridMinor, "stroke-dasharray": 2 }), @@ -322,7 +338,7 @@ const chart = sync({ } return group({ fill: col, stroke: col }, line([mapX(i + 0.5), mapY(candle.low)], [mapX(i + 0.5), mapY(candle.high)]), - rect([mapX(i) + 1, y], w - 2, h), + rect([mapX(i) + 1, y], bw - 2, h), ); }, ohlc @@ -396,7 +412,7 @@ sync({ { class: `mr3 b link ${theme.body}`, href: "https://github.com/thi-ng/umbrella/tree/master/examples/crypto-chart/" - }, "Source code"] + }, "Source"] ] ] ), From 2ff75609b4b43daad24a766766df13387d6243c7 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 12:43:37 +0000 Subject: [PATCH 30/35] perf(examples): update __skip handling in hdom-benchmark2 --- examples/hdom-benchmark2/src/index.ts | 34 +++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts index 2426a808d3..61731436f4 100644 --- a/examples/hdom-benchmark2/src/index.ts +++ b/examples/hdom-benchmark2/src/index.ts @@ -42,10 +42,13 @@ injectStyleSheet( ]) ); -const grid = - (_, cells, w, numChanges, frame, interlace) => { - if (!frame) return ["div"]; - const isFirst = frame === 1; +const grid = { + render(_, cells, w, numChanges, frame, interlace) { + if (!frame) { + this.prevChanged = null; + return ["div"]; + } + const isFirst = !this.prevChanged; const num = w * w; const changed = new Set(); for (let i = 0; i < numChanges; i++) { @@ -56,14 +59,17 @@ const grid = const body = transduce( comp( - mapIndexed((i, x) => { - const diff = isFirst || changed.has(i); - return ["span", { - key: "c" + i, - __diff: diff, - class: `cell ${diff ? "x" : ""}cell-${x}` - }]; - } + mapIndexed((i, x) => + ["span", + isFirst || this.prevChanged.has(i) ? + { key: "c" + i, class: `cell cell-${x}` } : + changed.has(i) ? + { + key: "c" + i, + class: `cell xcell-${x}` + } : + { key: "c" + i, __skip: true } + ] ), partition(w), mapIndexed((i, row) => @@ -77,8 +83,10 @@ const grid = ["div"], cells ); + this.prevChanged = changed; return body; - }; + } +}; const formatInterlace = (x) => { const res = x ? "but only every" : "and every"; From 8155bf4b43b1e3a75871f67acffaf7437d8273a3 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 14:01:42 +0000 Subject: [PATCH 31/35] feat(examples): add proper DOM stats calculation, remove interlacing (obsolete) --- examples/hdom-benchmark2/src/index.ts | 72 +++++++++++++++------------ 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts index 61731436f4..e6eb53f03f 100644 --- a/examples/hdom-benchmark2/src/index.ts +++ b/examples/hdom-benchmark2/src/index.ts @@ -43,17 +43,20 @@ injectStyleSheet( ); const grid = { - render(_, cells, w, numChanges, frame, interlace) { + render(_, cells, w, numChanges, frame) { if (!frame) { this.prevChanged = null; + this.prevChangedRows = null; return ["div"]; } const isFirst = !this.prevChanged; const num = w * w; const changed = new Set(); + const changedRows = new Set(); for (let i = 0; i < numChanges; i++) { const idx = (Math.random() * num) | 0; changed.add(idx); + changedRows.add(~~(idx / w)); cells[idx] = (cells[idx] + 1) % 16; } const body = @@ -75,7 +78,7 @@ const grid = { mapIndexed((i, row) => ["div.row", { key: "r" + i, - __skip: !isFirst && ((i + frame) & interlace) + __skip: !isFirst && !(this.prevChangedRows.has(i) || changedRows.has(i)) }, row] ) ), @@ -83,46 +86,63 @@ const grid = { ["div"], cells ); + let mergedCells = new Set(changed); + if (this.prevChanged) { + for (let x of this.prevChanged) { + mergedCells.add(x); + } + } + const mergedRows = new Set(changedRows); + if (this.prevChangedRows) { + for (let x of this.prevChangedRows) { + mergedRows.add(x); + } + } + this.stats = { + cells: mergedCells.size, + rows: mergedRows.size, + total: mergedCells.size + mergedRows.size + }; this.prevChanged = changed; + this.prevChangedRows = changedRows; return body; } }; -const formatInterlace = (x) => { - const res = x ? "but only every" : "and every"; - return x === 0 ? - res : - x === 1 ? - res + " 2nd" : - `${res} ${x + 1}th`; -}; +const domStats = (_, grid, res, _static) => + grid && grid.stats ? + ["div", + ["div", ["span.pink", grid.stats.cells], " cells updated"], + ["div", ["span.pink", grid.stats.rows], " rows updated"], + ["div", ["span.pink", res * res + res + _static], " DOM nodes total"]] : + null; const newCells = (res) => new Array(res * res).fill(0); const stats = fpsCounter({ history: 50, sparkline: { width: 100 } }); let cells = newCells(32); -let interlace = 1; +// let interlace = 0; let res = 32; let delta = 1024; let frame = -1; const resOpts = [[24, 24], [32, 32], [40, 40], [48, 48], [56, 56], [64, 64]]; -const deltaOpts = [[64, 64], [128, 128], [256, 256], [512, 512], [1024, 1024]]; -const interlaceOpts = [[0, "None"], [1, 2], [3, 4], [7, 8], [15, 16], [31, 32]]; +const deltaOpts = [...map((i) => [i, i], [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024])]; +// const interlaceOpts = [[0, "None"], [1, 2], [3, 4], [7, 8], [15, 16], [31, 32]]; + +// 38 const cancel = start( () => { frame++; - const total = res * res + res + 24; - const estimate = Math.min(delta / (interlace + 1) + res / (interlace + 1) + 24, total); return ["div.ma3.code.f7", ["div.measure.lh-copy", - `Each grid cell is one element. - ${delta} random cell states will be updated each frame, - ${formatInterlace(interlace)} row will be updated in the browser DOM.`], - ["div.mt3", ["span.pink", `~${estimate}`], " real node updates/frame, ", ["span.pink", total], " DOM nodes total"], - ["div.mt3", [grid, cells, res, delta, frame, interlace]], + `Each grid cell is one element. Each frame ${delta} random cell states + will be updated (highlighted in green), resulting approx. twice as many DOM updates + (due to resetting of updated cells from previous frame).`], + ["div.mt3", [grid, cells, res, delta, frame]], + ["div.mt3", [domStats, grid, res, 46]], ["div.mt3", [stats]], ["div.mt3", ["span.w5.dib", "Resolution: "], @@ -144,23 +164,11 @@ const cancel = start( deltaOpts, delta] ], - ["div.mt3", - ["span.w5.dib", "Interlace rows: "], - [dropdown, - { - class: "w3 code", - onchange: (e) => (interlace = parseInt(e.target.value)) - }, - interlaceOpts, - interlace] - ], ["div.mt3", ["a", { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-benchmark2" }, "Source"]] ]; }); -// window["stop"] = cancel; - const hot = (module).hot; if (hot) { hot.dispose(cancel); From fea3d7779dd501f864d2ee8594aee17e0fc33045 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 14:17:51 +0000 Subject: [PATCH 32/35] fix(examples): minor update hdom-benchmark2 --- examples/hdom-benchmark2/src/index.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts index e6eb53f03f..cfda8b86d3 100644 --- a/examples/hdom-benchmark2/src/index.ts +++ b/examples/hdom-benchmark2/src/index.ts @@ -121,17 +121,13 @@ const newCells = (res) => new Array(res * res).fill(0); const stats = fpsCounter({ history: 50, sparkline: { width: 100 } }); -let cells = newCells(32); -// let interlace = 0; -let res = 32; -let delta = 1024; +let res = 48; +let delta = 256; let frame = -1; +let cells = newCells(res); const resOpts = [[24, 24], [32, 32], [40, 40], [48, 48], [56, 56], [64, 64]]; const deltaOpts = [...map((i) => [i, i], [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024])]; -// const interlaceOpts = [[0, "None"], [1, 2], [3, 4], [7, 8], [15, 16], [31, 32]]; - -// 38 const cancel = start( () => { @@ -139,8 +135,8 @@ const cancel = start( return ["div.ma3.code.f7", ["div.measure.lh-copy", `Each grid cell is one element. Each frame ${delta} random cell states - will be updated (highlighted in green), resulting approx. twice as many DOM updates - (due to resetting of updated cells from previous frame).`], + will be updated (highlighted in green), resulting in approx. twice as many + DOM updates (due to resetting of updated cells from previous frame).`], ["div.mt3", [grid, cells, res, delta, frame]], ["div.mt3", [domStats, grid, res, 46]], ["div.mt3", [stats]], From fbbf5f90dd8d4e508fdd7c7ca6bc3d182a4fa1a6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 16:04:33 +0000 Subject: [PATCH 33/35] minor(examples): update source links --- examples/hdom-benchmark2/src/index.ts | 2 +- examples/hdom-skip/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hdom-benchmark2/src/index.ts b/examples/hdom-benchmark2/src/index.ts index cfda8b86d3..3b9328f071 100644 --- a/examples/hdom-benchmark2/src/index.ts +++ b/examples/hdom-benchmark2/src/index.ts @@ -161,7 +161,7 @@ const cancel = start( delta] ], ["div.mt3", - ["a", { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-benchmark2" }, "Source"]] + ["a", { href: "https://github.com/thi-ng/umbrella/tree/master/examples/hdom-benchmark2" }, "Source"]] ]; }); diff --git a/examples/hdom-skip/src/index.ts b/examples/hdom-skip/src/index.ts index 64ad9c36f3..34a952537f 100644 --- a/examples/hdom-skip/src/index.ts +++ b/examples/hdom-skip/src/index.ts @@ -43,7 +43,7 @@ const app = { ["h1", "Selective component updates"], this.timers, ["a.db.mt3.link", - { href: "https://github.com/thi-ng/umbrella/tree/feature/hdom-skip/examples/hdom-skip" }, + { href: "https://github.com/thi-ng/umbrella/tree/master/examples/hdom-skip" }, "Source code"] ]; } From 151e14228deddaac08469d20fb539e4624a606c5 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 16:05:41 +0000 Subject: [PATCH 34/35] docs(hdom): update readme --- packages/hdom/README.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/hdom/README.md b/packages/hdom/README.md index 764e6c0841..8e7f54e64b 100644 --- a/packages/hdom/README.md +++ b/packages/hdom/README.md @@ -49,7 +49,7 @@ This project is part of the - [hydrateTree()](#hydratetree) - [User context](#user-context) - [Behavior control attributes](#behavior-control-attributes) - - [Benchmark](#benchmark) + - [Benchmarks](#benchmarks) - [Authors](#authors) - [License](#license) @@ -70,26 +70,28 @@ Benefits: - Use the full expressiveness of ES6 / TypeScript to define user interfaces - No enforced opinion about state handling, very flexible -- Clean, functional component composition & reuse +- Clean, functional component composition & reuse, optionally w/ lazy + evaluation - No source pre-processing, transpiling or string interpolation - Less verbose than HTML / JSX, resulting in smaller file sizes - Supports arbitrary elements (incl. SVG), attributes and events in uniform, S-expression based syntax - Supports branch-local custom update behaviors & arbitrary (e.g. non-DOM) target data structures to which tree diffs are applied to +- Component life cycle methods & behavior control attributes - Suitable for server-side rendering and then "hydrating" listeners and components with life cycle methods on the client side - Can use JSON for static components (or component templates) -- Optional user context injection (an arbitrary object/value passed to - all component functions embedded in the tree) +- Optional dynamic user context injection (an arbitrary object/value + passed to all component functions embedded in the tree) - Default implementation supports CSS conversion from JS objects for `style` attribs (also see: [@thi.ng/hiccup-css](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-css)) - Auto-expansion of embedded values / types which implement the [`IToHiccup`](https://github.com/thi-ng/umbrella/tree/master/packages/api/src/api.ts#L415) or [`IDeref`](https://github.com/thi-ng/umbrella/tree/master/packages/api/src/api.ts#L166) interfaces (e.g. [atoms, cursors, derived views](https://github.com/thi-ng/umbrella/tree/master/packages/atom), [streams](https://github.com/thi-ng/umbrella/tree/master/packages/rstream) etc.) -- Fast (see benchmark example below) -- Only ~5.5KB gzipped +- Fast (see [benchmark examples](#benchmarks) below) +- Only ~6.2KB gzipped ### Minimal example #1: Local state, RAF update @@ -1158,21 +1160,22 @@ on this element or any of its children. only. If `false`, this element and its children will be omitted from the serialized output. -### Benchmark +#### __skip -A stress test benchmark is here: -[/examples/benchmark](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-benchmark) +If `true`, the element will not be diffed and simply skipped. IMPORTANT: +This attribute is only intended for cases when a component / tree branch +should NOT be updated, but MUST NOT be enabled when that component is +first introduced / included in the tree. Doing so will result in +undefined future update behavior. -[Live version](https://demo.thi.ng/umbrella/hdom-benchmark/) +### Benchmarks -Based on [user feedback collected via -Twitter](https://twitter.com/toxi/status/959246871339454464), -performance should be more than acceptable for even quite demanding UIs. -In the 192 / 256 cells configurations **this stress test causes approx. -600 / 800 DOM every single frame**, very unlikely for a typical web app. -In Chrome 68 on a MBP2016 this still runs at a stable 60fps (192 cells) -/ 35fps (256 cells). Both FPS readings are based the 50 frame -[SMA](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average). +Some stress test benchmarks are here: + +- [/examples/hdom-benchmark](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-benchmark) + | [Live version](https://demo.thi.ng/umbrella/hdom-benchmark/) (naive updates) +- [/examples/hdom-benchmark2](https://github.com/thi-ng/umbrella/tree/master/examples/hdom-benchmark2) + | [Live version](https://demo.thi.ng/umbrella/hdom-benchmark2/) (w/ selective updates) ## Authors From e36a7ee080147d3ccbb464b0536c0ccc74ae1d01 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Thu, 13 Dec 2018 16:13:38 +0000 Subject: [PATCH 35/35] Publish - @thi.ng/associative@0.6.17 - @thi.ng/cache@0.2.34 - @thi.ng/csp@0.3.73 - @thi.ng/dcons@1.1.17 - @thi.ng/dgraph@0.2.29 - @thi.ng/geom-accel@0.1.5 - @thi.ng/geom@0.2.5 - @thi.ng/hdom-canvas@0.1.15 - @thi.ng/hdom-components@2.3.0 - @thi.ng/hdom-mock@0.1.0 - @thi.ng/hdom@6.0.0 - @thi.ng/hiccup-css@0.2.32 - @thi.ng/hiccup-svg@2.0.8 - @thi.ng/hiccup@2.7.0 - @thi.ng/iges@0.2.23 - @thi.ng/iterators@4.1.38 - @thi.ng/range-coder@0.1.22 - @thi.ng/rstream-csp@0.1.119 - @thi.ng/rstream-dot@0.2.58 - @thi.ng/rstream-gestures@0.6.3 - @thi.ng/rstream-graph@2.1.44 - @thi.ng/rstream-log@1.0.70 - @thi.ng/rstream-query@0.3.57 - @thi.ng/rstream@1.14.3 - @thi.ng/sax@0.5.7 - @thi.ng/strings@0.7.0 - @thi.ng/transducers-fsm@0.2.30 - @thi.ng/transducers-hdom@1.2.6 - @thi.ng/transducers-stats@0.4.17 - @thi.ng/transducers@2.2.5 - @thi.ng/vectors@1.4.6 --- packages/associative/CHANGELOG.md | 8 +++++++ packages/associative/package.json | 6 ++--- packages/cache/CHANGELOG.md | 8 +++++++ packages/cache/package.json | 6 ++--- packages/csp/CHANGELOG.md | 8 +++++++ packages/csp/package.json | 6 ++--- packages/dcons/CHANGELOG.md | 8 +++++++ packages/dcons/package.json | 4 ++-- packages/dgraph/CHANGELOG.md | 8 +++++++ packages/dgraph/package.json | 6 ++--- packages/geom-accel/CHANGELOG.md | 8 +++++++ packages/geom-accel/package.json | 4 ++-- packages/geom/CHANGELOG.md | 8 +++++++ packages/geom/package.json | 6 ++--- packages/hdom-canvas/CHANGELOG.md | 8 +++++++ packages/hdom-canvas/package.json | 4 ++-- packages/hdom-components/CHANGELOG.md | 11 +++++++++ packages/hdom-components/package.json | 8 +++---- packages/hdom-mock/CHANGELOG.md | 11 +++++++++ packages/hdom-mock/package.json | 4 ++-- packages/hdom/CHANGELOG.md | 30 +++++++++++++++++++++++++ packages/hdom/package.json | 4 ++-- packages/hiccup-css/CHANGELOG.md | 8 +++++++ packages/hiccup-css/package.json | 4 ++-- packages/hiccup-svg/CHANGELOG.md | 8 +++++++ packages/hiccup-svg/package.json | 4 ++-- packages/hiccup/CHANGELOG.md | 11 +++++++++ packages/hiccup/package.json | 2 +- packages/iges/CHANGELOG.md | 8 +++++++ packages/iges/package.json | 6 ++--- packages/iterators/CHANGELOG.md | 8 +++++++ packages/iterators/package.json | 4 ++-- packages/range-coder/CHANGELOG.md | 8 +++++++ packages/range-coder/package.json | 4 ++-- packages/rstream-csp/CHANGELOG.md | 8 +++++++ packages/rstream-csp/package.json | 6 ++--- packages/rstream-dot/CHANGELOG.md | 8 +++++++ packages/rstream-dot/package.json | 4 ++-- packages/rstream-gestures/CHANGELOG.md | 8 +++++++ packages/rstream-gestures/package.json | 6 ++--- packages/rstream-graph/CHANGELOG.md | 8 +++++++ packages/rstream-graph/package.json | 6 ++--- packages/rstream-log/CHANGELOG.md | 8 +++++++ packages/rstream-log/package.json | 6 ++--- packages/rstream-query/CHANGELOG.md | 8 +++++++ packages/rstream-query/package.json | 10 ++++----- packages/rstream/CHANGELOG.md | 8 +++++++ packages/rstream/package.json | 6 ++--- packages/sax/CHANGELOG.md | 8 +++++++ packages/sax/package.json | 6 ++--- packages/strings/CHANGELOG.md | 16 +++++++++++++ packages/strings/package.json | 2 +- packages/transducers-fsm/CHANGELOG.md | 8 +++++++ packages/transducers-fsm/package.json | 4 ++-- packages/transducers-hdom/CHANGELOG.md | 11 +++++++++ packages/transducers-hdom/package.json | 6 ++--- packages/transducers-stats/CHANGELOG.md | 8 +++++++ packages/transducers-stats/package.json | 6 ++--- packages/transducers/CHANGELOG.md | 8 +++++++ packages/transducers/package.json | 4 ++-- packages/vectors/CHANGELOG.md | 8 +++++++ packages/vectors/package.json | 4 ++-- 62 files changed, 369 insertions(+), 79 deletions(-) create mode 100644 packages/hdom-mock/CHANGELOG.md diff --git a/packages/associative/CHANGELOG.md b/packages/associative/CHANGELOG.md index 8246781cfa..fea9cd7140 100644 --- a/packages/associative/CHANGELOG.md +++ b/packages/associative/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.6.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.6.16...@thi.ng/associative@0.6.17) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/associative + + + + + ## [0.6.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.6.15...@thi.ng/associative@0.6.16) (2018-12-08) **Note:** Version bump only for package @thi.ng/associative diff --git a/packages/associative/package.json b/packages/associative/package.json index e6d9737625..3b74f9c2f9 100644 --- a/packages/associative/package.json +++ b/packages/associative/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/associative", - "version": "0.6.16", + "version": "0.6.17", "description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations", "main": "./index.js", "typings": "./index.d.ts", @@ -31,10 +31,10 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/compare": "^0.1.11", - "@thi.ng/dcons": "^1.1.16", + "@thi.ng/dcons": "^1.1.17", "@thi.ng/equiv": "^0.1.14", "@thi.ng/errors": "^0.1.11", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "data structures", diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md index e25809f0d5..fe28390454 100644 --- a/packages/cache/CHANGELOG.md +++ b/packages/cache/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.34](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.33...@thi.ng/cache@0.2.34) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/cache + + + + + ## [0.2.33](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.32...@thi.ng/cache@0.2.33) (2018-12-08) **Note:** Version bump only for package @thi.ng/cache diff --git a/packages/cache/package.json b/packages/cache/package.json index 6923deffbd..e0850c59d2 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/cache", - "version": "0.2.33", + "version": "0.2.34", "description": "In-memory cache implementations with ES6 Map-like API and different eviction strategies", "main": "./index.js", "typings": "./index.d.ts", @@ -29,8 +29,8 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/dcons": "^1.1.16", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/dcons": "^1.1.17", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "cache", diff --git a/packages/csp/CHANGELOG.md b/packages/csp/CHANGELOG.md index f71b1a4eab..6d6660b0a5 100644 --- a/packages/csp/CHANGELOG.md +++ b/packages/csp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.73](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.72...@thi.ng/csp@0.3.73) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/csp + + + + + ## [0.3.72](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.71...@thi.ng/csp@0.3.72) (2018-12-08) **Note:** Version bump only for package @thi.ng/csp diff --git a/packages/csp/package.json b/packages/csp/package.json index 7d0d26afc9..32459c8409 100644 --- a/packages/csp/package.json +++ b/packages/csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/csp", - "version": "0.3.72", + "version": "0.3.73", "description": "ES6 promise based CSP implementation", "main": "./index.js", "typings": "./index.d.ts", @@ -34,9 +34,9 @@ "dependencies": { "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", - "@thi.ng/dcons": "^1.1.16", + "@thi.ng/dcons": "^1.1.17", "@thi.ng/errors": "^0.1.11", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "async", diff --git a/packages/dcons/CHANGELOG.md b/packages/dcons/CHANGELOG.md index 3813870ebd..870a28b2cb 100644 --- a/packages/dcons/CHANGELOG.md +++ b/packages/dcons/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.1.16...@thi.ng/dcons@1.1.17) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/dcons + + + + + ## [1.1.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.1.15...@thi.ng/dcons@1.1.16) (2018-12-08) **Note:** Version bump only for package @thi.ng/dcons diff --git a/packages/dcons/package.json b/packages/dcons/package.json index 353d4794aa..989d51513b 100644 --- a/packages/dcons/package.json +++ b/packages/dcons/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dcons", - "version": "1.1.16", + "version": "1.1.17", "description": "Comprehensive doubly linked list structure w/ iterator support", "main": "./index.js", "typings": "./index.d.ts", @@ -33,7 +33,7 @@ "@thi.ng/compare": "^0.1.11", "@thi.ng/equiv": "^0.1.14", "@thi.ng/errors": "^0.1.11", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "datastructure", diff --git a/packages/dgraph/CHANGELOG.md b/packages/dgraph/CHANGELOG.md index 09917c5a82..d4e08e1768 100644 --- a/packages/dgraph/CHANGELOG.md +++ b/packages/dgraph/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.29](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.28...@thi.ng/dgraph@0.2.29) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/dgraph + + + + + ## [0.2.28](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.27...@thi.ng/dgraph@0.2.28) (2018-12-08) **Note:** Version bump only for package @thi.ng/dgraph diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json index 09f08e668d..575e139a8f 100644 --- a/packages/dgraph/package.json +++ b/packages/dgraph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dgraph", - "version": "0.2.28", + "version": "0.2.29", "description": "Type-agnostic directed acyclic graph (DAG) & graph operations", "main": "./index.js", "typings": "./index.d.ts", @@ -29,10 +29,10 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/associative": "^0.6.16", + "@thi.ng/associative": "^0.6.17", "@thi.ng/equiv": "^0.1.14", "@thi.ng/errors": "^0.1.11", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "data structure", diff --git a/packages/geom-accel/CHANGELOG.md b/packages/geom-accel/CHANGELOG.md index 302dbe0407..93757080af 100644 --- a/packages/geom-accel/CHANGELOG.md +++ b/packages/geom-accel/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-accel@0.1.4...@thi.ng/geom-accel@0.1.5) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/geom-accel + + + + + ## [0.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-accel@0.1.3...@thi.ng/geom-accel@0.1.4) (2018-12-08) **Note:** Version bump only for package @thi.ng/geom-accel diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index b1617c73cb..ad0a5bed05 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-accel", - "version": "0.1.4", + "version": "0.1.5", "description": "TODO", "main": "./index.js", "typings": "./index.d.ts", @@ -31,7 +31,7 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/heaps": "^0.3.0", "@thi.ng/math": "^0.2.1", - "@thi.ng/vectors": "^1.4.5" + "@thi.ng/vectors": "^1.4.6" }, "keywords": [ "ES6", diff --git a/packages/geom/CHANGELOG.md b/packages/geom/CHANGELOG.md index f8093f166b..f639e67693 100644 --- a/packages/geom/CHANGELOG.md +++ b/packages/geom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom@0.2.4...@thi.ng/geom@0.2.5) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/geom + + + + + ## [0.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom@0.2.3...@thi.ng/geom@0.2.4) (2018-12-08) **Note:** Version bump only for package @thi.ng/geom diff --git a/packages/geom/package.json b/packages/geom/package.json index f84d3d3618..d1e434ce3f 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom", - "version": "0.2.4", + "version": "0.2.5", "description": "2D/3D geometry primitives", "main": "./index.js", "typings": "./index.d.ts", @@ -31,8 +31,8 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/math": "^0.2.1", - "@thi.ng/transducers": "^2.2.4", - "@thi.ng/vectors": "^1.4.5" + "@thi.ng/transducers": "^2.2.5", + "@thi.ng/vectors": "^1.4.6" }, "keywords": [ "ES6", diff --git a/packages/hdom-canvas/CHANGELOG.md b/packages/hdom-canvas/CHANGELOG.md index c290631a5a..63fde53944 100644 --- a/packages/hdom-canvas/CHANGELOG.md +++ b/packages/hdom-canvas/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@0.1.14...@thi.ng/hdom-canvas@0.1.15) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/hdom-canvas + + + + + ## [0.1.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@0.1.13...@thi.ng/hdom-canvas@0.1.14) (2018-12-09) **Note:** Version bump only for package @thi.ng/hdom-canvas diff --git a/packages/hdom-canvas/package.json b/packages/hdom-canvas/package.json index e9c80ca1f3..62df7974b0 100644 --- a/packages/hdom-canvas/package.json +++ b/packages/hdom-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-canvas", - "version": "0.1.14", + "version": "0.1.15", "description": "Declarative canvas scenegraph & visualization for @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -31,7 +31,7 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/diff": "^2.0.1", - "@thi.ng/hdom": "^5.2.2" + "@thi.ng/hdom": "^6.0.0" }, "keywords": [ "ES6", diff --git a/packages/hdom-components/CHANGELOG.md b/packages/hdom-components/CHANGELOG.md index e1a836ad9c..c1e1c436b7 100644 --- a/packages/hdom-components/CHANGELOG.md +++ b/packages/hdom-components/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.2.15...@thi.ng/hdom-components@2.3.0) (2018-12-13) + + +### Features + +* **hdom-components:** add FPS counter & sparkline components, update deps ([ebd3380](https://github.com/thi-ng/umbrella/commit/ebd3380)) + + + + + ## [2.2.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.2.14...@thi.ng/hdom-components@2.2.15) (2018-12-08) **Note:** Version bump only for package @thi.ng/hdom-components diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index bd1f401303..57b7528244 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-components", - "version": "2.2.15", + "version": "2.3.0", "description": "Raw, skinnable UI & SVG components for @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -31,8 +31,8 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/math": "^0.2.1", - "@thi.ng/transducers": "^2.2.4", - "@thi.ng/transducers-stats": "^0.4.16", + "@thi.ng/transducers": "^2.2.5", + "@thi.ng/transducers-stats": "^0.4.17", "@types/webgl2": "^0.0.4" }, "keywords": [ @@ -42,4 +42,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/packages/hdom-mock/CHANGELOG.md b/packages/hdom-mock/CHANGELOG.md new file mode 100644 index 0000000000..5fc84e5a13 --- /dev/null +++ b/packages/hdom-mock/CHANGELOG.md @@ -0,0 +1,11 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2018-12-13) + + +### Features + +* **hdom-mock:** add hdom-mock package and implementation, add initial tests ([5609d24](https://github.com/thi-ng/umbrella/commit/5609d24)) diff --git a/packages/hdom-mock/package.json b/packages/hdom-mock/package.json index b633109436..1ff287725e 100644 --- a/packages/hdom-mock/package.json +++ b/packages/hdom-mock/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-mock", - "version": "0.0.1", + "version": "0.1.0", "description": "TODO", "main": "./index.js", "typings": "./index.d.ts", @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/hdom": "^5.2.2" + "@thi.ng/hdom": "^6.0.0" }, "keywords": [ "ES6", diff --git a/packages/hdom/CHANGELOG.md b/packages/hdom/CHANGELOG.md index 3f57c01f89..4320efa8ce 100644 --- a/packages/hdom/CHANGELOG.md +++ b/packages/hdom/CHANGELOG.md @@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [6.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@5.2.2...@thi.ng/hdom@6.0.0) (2018-12-13) + + +### Code Refactoring + +* **hdom:** extend & simplify HDOMImplementation, update DEFAULT_IMPL ([6f2e8ee](https://github.com/thi-ng/umbrella/commit/6f2e8ee)) + + +### Features + +* **hdom:** add initial __skip ctrl attrib handling in diffTree() ([a4e6736](https://github.com/thi-ng/umbrella/commit/a4e6736)) + + +### BREAKING CHANGES + +* **hdom:** extend & simplify HDOMImplementation + +- update args for HDOMImplementation methods +- add createElement(), createTextElement() & getElementById() methods + to HDOMImplementation +- rename createDOM() => createTree(), make generic +- rename hydrateDOM() => hydrateTree(), make generic +- update / fix diffTree() __impl attrib handling: + only delegate if __impl != current impl +- update resolveRoot() to require impl arg & delegate + + + + + ## [5.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@5.2.1...@thi.ng/hdom@5.2.2) (2018-12-09) **Note:** Version bump only for package @thi.ng/hdom diff --git a/packages/hdom/package.json b/packages/hdom/package.json index 131947c3b6..41944de336 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom", - "version": "5.2.2", + "version": "6.0.0", "description": "Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors", "main": "./index.js", "typings": "./index.d.ts", @@ -33,7 +33,7 @@ "@thi.ng/checks": "^1.5.13", "@thi.ng/diff": "^2.0.1", "@thi.ng/equiv": "^0.1.14", - "@thi.ng/hiccup": "^2.6.1" + "@thi.ng/hiccup": "^2.7.0" }, "keywords": [ "browser", diff --git a/packages/hiccup-css/CHANGELOG.md b/packages/hiccup-css/CHANGELOG.md index da0a42aba0..8eda4c66df 100644 --- a/packages/hiccup-css/CHANGELOG.md +++ b/packages/hiccup-css/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.32](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.2.31...@thi.ng/hiccup-css@0.2.32) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/hiccup-css + + + + + ## [0.2.31](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.2.30...@thi.ng/hiccup-css@0.2.31) (2018-12-08) **Note:** Version bump only for package @thi.ng/hiccup-css diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json index 7c6a5adc78..e3256ddcbb 100644 --- a/packages/hiccup-css/package.json +++ b/packages/hiccup-css/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-css", - "version": "0.2.31", + "version": "0.2.32", "description": "CSS from nested JS data structures", "main": "./index.js", "typings": "./index.d.ts", @@ -31,7 +31,7 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/errors": "^0.1.11", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "clojure", diff --git a/packages/hiccup-svg/CHANGELOG.md b/packages/hiccup-svg/CHANGELOG.md index d9f505af0e..70980e5fba 100644 --- a/packages/hiccup-svg/CHANGELOG.md +++ b/packages/hiccup-svg/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@2.0.7...@thi.ng/hiccup-svg@2.0.8) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/hiccup-svg + + + + + ## [2.0.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@2.0.6...@thi.ng/hiccup-svg@2.0.7) (2018-12-08) **Note:** Version bump only for package @thi.ng/hiccup-svg diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index 3b29076517..c0771b6a76 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-svg", - "version": "2.0.7", + "version": "2.0.8", "description": "SVG element functions for @thi.ng/hiccup & @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -28,7 +28,7 @@ "typescript": "^3.1.3" }, "dependencies": { - "@thi.ng/hiccup": "^2.6.1" + "@thi.ng/hiccup": "^2.7.0" }, "keywords": [ "components", diff --git a/packages/hiccup/CHANGELOG.md b/packages/hiccup/CHANGELOG.md index 24baa7fe08..8ca46dec71 100644 --- a/packages/hiccup/CHANGELOG.md +++ b/packages/hiccup/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.7.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.6.1...@thi.ng/hiccup@2.7.0) (2018-12-13) + + +### Features + +* **hiccup:** add __skip support, add test, update readme ([d3500df](https://github.com/thi-ng/umbrella/commit/d3500df)) + + + + + ## [2.6.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.6.0...@thi.ng/hiccup@2.6.1) (2018-12-08) **Note:** Version bump only for package @thi.ng/hiccup diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json index 64f24b8d64..c09e08f61e 100644 --- a/packages/hiccup/package.json +++ b/packages/hiccup/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup", - "version": "2.6.1", + "version": "2.7.0", "description": "HTML/SVG/XML serialization of nested data structures, iterables & closures", "main": "./index.js", "typings": "./index.d.ts", diff --git a/packages/iges/CHANGELOG.md b/packages/iges/CHANGELOG.md index 1f4acbbe27..e5f8d4cacb 100644 --- a/packages/iges/CHANGELOG.md +++ b/packages/iges/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/iges@0.2.22...@thi.ng/iges@0.2.23) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/iges + + + + + ## [0.2.22](https://github.com/thi-ng/umbrella/compare/@thi.ng/iges@0.2.21...@thi.ng/iges@0.2.22) (2018-12-08) **Note:** Version bump only for package @thi.ng/iges diff --git a/packages/iges/package.json b/packages/iges/package.json index fd7315a6de..e62c9e1c88 100644 --- a/packages/iges/package.json +++ b/packages/iges/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iges", - "version": "0.2.22", + "version": "0.2.23", "description": "IGES 5.3 serializer for (currently only) polygonal geometry, both open & closed", "main": "./index.js", "typings": "./index.d.ts", @@ -30,8 +30,8 @@ "dependencies": { "@thi.ng/api": "^4.2.3", "@thi.ng/defmulti": "^0.5.0", - "@thi.ng/strings": "^0.6.0", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/strings": "^0.7.0", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "CAD", diff --git a/packages/iterators/CHANGELOG.md b/packages/iterators/CHANGELOG.md index 3508a9db5e..b468d2d7ff 100644 --- a/packages/iterators/CHANGELOG.md +++ b/packages/iterators/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.38](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.37...@thi.ng/iterators@4.1.38) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/iterators + + + + + ## [4.1.37](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.36...@thi.ng/iterators@4.1.37) (2018-12-08) **Note:** Version bump only for package @thi.ng/iterators diff --git a/packages/iterators/package.json b/packages/iterators/package.json index 82100d4623..591f851523 100644 --- a/packages/iterators/package.json +++ b/packages/iterators/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iterators", - "version": "4.1.37", + "version": "4.1.38", "description": "clojure.core inspired, composable ES6 iterators & generators", "main": "./index.js", "typings": "./index.d.ts", @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/dcons": "^1.1.16", + "@thi.ng/dcons": "^1.1.17", "@thi.ng/errors": "^0.1.11" }, "keywords": [ diff --git a/packages/range-coder/CHANGELOG.md b/packages/range-coder/CHANGELOG.md index 282b6e2e42..25f5c93d67 100644 --- a/packages/range-coder/CHANGELOG.md +++ b/packages/range-coder/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.22](https://github.com/thi-ng/umbrella/compare/@thi.ng/range-coder@0.1.21...@thi.ng/range-coder@0.1.22) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/range-coder + + + + + ## [0.1.21](https://github.com/thi-ng/umbrella/compare/@thi.ng/range-coder@0.1.20...@thi.ng/range-coder@0.1.21) (2018-12-08) **Note:** Version bump only for package @thi.ng/range-coder diff --git a/packages/range-coder/package.json b/packages/range-coder/package.json index de5063444c..81d545da92 100644 --- a/packages/range-coder/package.json +++ b/packages/range-coder/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/range-coder", - "version": "0.1.21", + "version": "0.1.22", "description": "Binary data range encoder / decoder", "main": "./index.js", "typings": "./index.d.ts", @@ -20,7 +20,7 @@ "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { - "@thi.ng/transducers": "^2.2.4", + "@thi.ng/transducers": "^2.2.5", "@types/mocha": "^5.2.5", "@types/node": "^10.12.0", "mocha": "^5.2.0", diff --git a/packages/rstream-csp/CHANGELOG.md b/packages/rstream-csp/CHANGELOG.md index 6a91c9a9b1..e304814d46 100644 --- a/packages/rstream-csp/CHANGELOG.md +++ b/packages/rstream-csp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.119](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.118...@thi.ng/rstream-csp@0.1.119) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream-csp + + + + + ## [0.1.118](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.117...@thi.ng/rstream-csp@0.1.118) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream-csp diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json index d38da379a0..ced044ba37 100644 --- a/packages/rstream-csp/package.json +++ b/packages/rstream-csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-csp", - "version": "0.1.118", + "version": "0.1.119", "description": "@thi.ng/csp bridge module for @thi.ng/rstream", "main": "./index.js", "typings": "./index.d.ts", @@ -28,8 +28,8 @@ "typescript": "^3.1.3" }, "dependencies": { - "@thi.ng/csp": "^0.3.72", - "@thi.ng/rstream": "^1.14.2" + "@thi.ng/csp": "^0.3.73", + "@thi.ng/rstream": "^1.14.3" }, "keywords": [ "bridge", diff --git a/packages/rstream-dot/CHANGELOG.md b/packages/rstream-dot/CHANGELOG.md index bbd2f73d97..40a22a9ca4 100644 --- a/packages/rstream-dot/CHANGELOG.md +++ b/packages/rstream-dot/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.58](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.57...@thi.ng/rstream-dot@0.2.58) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream-dot + + + + + ## [0.2.57](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.56...@thi.ng/rstream-dot@0.2.57) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream-dot diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json index 6601d44ec5..56c608f90d 100644 --- a/packages/rstream-dot/package.json +++ b/packages/rstream-dot/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-dot", - "version": "0.2.57", + "version": "0.2.58", "description": "Graphviz DOT conversion of @thi.ng/rstream dataflow graph topologies", "main": "./index.js", "typings": "./index.d.ts", @@ -28,7 +28,7 @@ "typescript": "^3.1.3" }, "dependencies": { - "@thi.ng/rstream": "^1.14.2" + "@thi.ng/rstream": "^1.14.3" }, "keywords": [ "conversion", diff --git a/packages/rstream-gestures/CHANGELOG.md b/packages/rstream-gestures/CHANGELOG.md index e28968d02e..d3cf2a8a94 100644 --- a/packages/rstream-gestures/CHANGELOG.md +++ b/packages/rstream-gestures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.6.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.6.2...@thi.ng/rstream-gestures@0.6.3) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream-gestures + + + + + ## [0.6.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.6.1...@thi.ng/rstream-gestures@0.6.2) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream-gestures diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json index 0dccad55d1..f683fd2bbb 100644 --- a/packages/rstream-gestures/package.json +++ b/packages/rstream-gestures/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-gestures", - "version": "0.6.2", + "version": "0.6.3", "description": "Unified mouse, mouse wheel & single-touch event stream abstraction", "main": "./index.js", "typings": "./index.d.ts", @@ -29,8 +29,8 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/rstream": "^1.14.2", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/rstream": "^1.14.3", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "dataflow", diff --git a/packages/rstream-graph/CHANGELOG.md b/packages/rstream-graph/CHANGELOG.md index 7eb4235f45..ab341bde2d 100644 --- a/packages/rstream-graph/CHANGELOG.md +++ b/packages/rstream-graph/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.1.44](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.1.43...@thi.ng/rstream-graph@2.1.44) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream-graph + + + + + ## [2.1.43](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.1.42...@thi.ng/rstream-graph@2.1.43) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream-graph diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json index 0b63d6ee52..bc0ee3442f 100644 --- a/packages/rstream-graph/package.json +++ b/packages/rstream-graph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-graph", - "version": "2.1.43", + "version": "2.1.44", "description": "Declarative dataflow graph construction for @thi.ng/rstream", "main": "./index.js", "typings": "./index.d.ts", @@ -33,8 +33,8 @@ "@thi.ng/errors": "^0.1.11", "@thi.ng/paths": "^1.6.5", "@thi.ng/resolve-map": "^3.0.15", - "@thi.ng/rstream": "^1.14.2", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/rstream": "^1.14.3", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "compute", diff --git a/packages/rstream-log/CHANGELOG.md b/packages/rstream-log/CHANGELOG.md index 2f6c8d2022..5d0c9beaa4 100644 --- a/packages/rstream-log/CHANGELOG.md +++ b/packages/rstream-log/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.70](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.69...@thi.ng/rstream-log@1.0.70) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream-log + + + + + ## [1.0.69](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.68...@thi.ng/rstream-log@1.0.69) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream-log diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json index 5dda7c9e9a..8332ad335a 100644 --- a/packages/rstream-log/package.json +++ b/packages/rstream-log/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-log", - "version": "1.0.69", + "version": "1.0.70", "description": "Structured, multilevel & hierarchical loggers based on @thi.ng/rstream", "main": "./index.js", "typings": "./index.d.ts", @@ -31,8 +31,8 @@ "@thi.ng/api": "^4.2.3", "@thi.ng/checks": "^1.5.13", "@thi.ng/errors": "^0.1.11", - "@thi.ng/rstream": "^1.14.2", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/rstream": "^1.14.3", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "ES6", diff --git a/packages/rstream-query/CHANGELOG.md b/packages/rstream-query/CHANGELOG.md index 8a3b0fd9fd..e439741039 100644 --- a/packages/rstream-query/CHANGELOG.md +++ b/packages/rstream-query/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.57](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.56...@thi.ng/rstream-query@0.3.57) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream-query + + + + + ## [0.3.56](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.55...@thi.ng/rstream-query@0.3.56) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream-query diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json index 79b34bfb38..4f2486cdca 100644 --- a/packages/rstream-query/package.json +++ b/packages/rstream-query/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-query", - "version": "0.3.56", + "version": "0.3.57", "description": "@thi.ng/rstream based triple store & reactive query engine", "main": "./index.js", "typings": "./index.d.ts", @@ -29,13 +29,13 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/associative": "^0.6.16", + "@thi.ng/associative": "^0.6.17", "@thi.ng/checks": "^1.5.13", "@thi.ng/equiv": "^0.1.14", "@thi.ng/errors": "^0.1.11", - "@thi.ng/rstream": "^1.14.2", - "@thi.ng/rstream-dot": "^0.2.57", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/rstream": "^1.14.3", + "@thi.ng/rstream-dot": "^0.2.58", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "dataflow", diff --git a/packages/rstream/CHANGELOG.md b/packages/rstream/CHANGELOG.md index 3d7f4dafa9..7a94f78073 100644 --- a/packages/rstream/CHANGELOG.md +++ b/packages/rstream/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.14.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.14.2...@thi.ng/rstream@1.14.3) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/rstream + + + + + ## [1.14.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.14.1...@thi.ng/rstream@1.14.2) (2018-12-08) **Note:** Version bump only for package @thi.ng/rstream diff --git a/packages/rstream/package.json b/packages/rstream/package.json index 339f3da273..a0b85730d3 100644 --- a/packages/rstream/package.json +++ b/packages/rstream/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream", - "version": "1.14.2", + "version": "1.14.3", "description": "Reactive multi-tap streams, dataflow & transformation pipeline constructs", "main": "./index.js", "typings": "./index.d.ts", @@ -29,12 +29,12 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/associative": "^0.6.16", + "@thi.ng/associative": "^0.6.17", "@thi.ng/atom": "^1.5.7", "@thi.ng/checks": "^1.5.13", "@thi.ng/errors": "^0.1.11", "@thi.ng/paths": "^1.6.5", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "datastructure", diff --git a/packages/sax/CHANGELOG.md b/packages/sax/CHANGELOG.md index e6505fd2d3..5b206cd56d 100644 --- a/packages/sax/CHANGELOG.md +++ b/packages/sax/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.5.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/sax@0.5.6...@thi.ng/sax@0.5.7) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/sax + + + + + ## [0.5.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/sax@0.5.5...@thi.ng/sax@0.5.6) (2018-12-08) **Note:** Version bump only for package @thi.ng/sax diff --git a/packages/sax/package.json b/packages/sax/package.json index b32b2fc8b2..8da788fab0 100644 --- a/packages/sax/package.json +++ b/packages/sax/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/sax", - "version": "0.5.6", + "version": "0.5.7", "description": "Transducer-based, SAX-like, non-validating, speedy & tiny XML parser", "main": "./index.js", "typings": "./index.d.ts", @@ -29,8 +29,8 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/transducers": "^2.2.4", - "@thi.ng/transducers-fsm": "^0.2.29" + "@thi.ng/transducers": "^2.2.5", + "@thi.ng/transducers-fsm": "^0.2.30" }, "keywords": [ "ES6", diff --git a/packages/strings/CHANGELOG.md b/packages/strings/CHANGELOG.md index 2d86326866..13d6b91c94 100644 --- a/packages/strings/CHANGELOG.md +++ b/packages/strings/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.7.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/strings@0.6.0...@thi.ng/strings@0.7.0) (2018-12-13) + + +### Bug Fixes + +* **strings:** update kebab() ([1b298f7](https://github.com/thi-ng/umbrella/commit/1b298f7)) + + +### Features + +* **strings:** add slugify() ([8dcc73a](https://github.com/thi-ng/umbrella/commit/8dcc73a)) + + + + + # [0.6.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/strings@0.5.2...@thi.ng/strings@0.6.0) (2018-11-08) diff --git a/packages/strings/package.json b/packages/strings/package.json index fb830afec4..d06afdf5b7 100644 --- a/packages/strings/package.json +++ b/packages/strings/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/strings", - "version": "0.6.0", + "version": "0.7.0", "description": "Various string formatting & utility functions", "main": "./index.js", "typings": "./index.d.ts", diff --git a/packages/transducers-fsm/CHANGELOG.md b/packages/transducers-fsm/CHANGELOG.md index 91685d87e6..c51eb4a4f4 100644 --- a/packages/transducers-fsm/CHANGELOG.md +++ b/packages/transducers-fsm/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.30](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-fsm@0.2.29...@thi.ng/transducers-fsm@0.2.30) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/transducers-fsm + + + + + ## [0.2.29](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-fsm@0.2.28...@thi.ng/transducers-fsm@0.2.29) (2018-12-08) **Note:** Version bump only for package @thi.ng/transducers-fsm diff --git a/packages/transducers-fsm/package.json b/packages/transducers-fsm/package.json index 596d80b77d..78e40d58ae 100644 --- a/packages/transducers-fsm/package.json +++ b/packages/transducers-fsm/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-fsm", - "version": "0.2.29", + "version": "0.2.30", "description": "Transducer-based Finite State Machine transformer", "main": "./index.js", "typings": "./index.d.ts", @@ -29,7 +29,7 @@ }, "dependencies": { "@thi.ng/api": "^4.2.3", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "ES6", diff --git a/packages/transducers-hdom/CHANGELOG.md b/packages/transducers-hdom/CHANGELOG.md index 29b464410d..7ef19df0d9 100644 --- a/packages/transducers-hdom/CHANGELOG.md +++ b/packages/transducers-hdom/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.2.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@1.2.5...@thi.ng/transducers-hdom@1.2.6) (2018-12-13) + + +### Bug Fixes + +* **transducers-hdom:** integrate recent hdom updates ([6db3170](https://github.com/thi-ng/umbrella/commit/6db3170)) + + + + + ## [1.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@1.2.4...@thi.ng/transducers-hdom@1.2.5) (2018-12-09) **Note:** Version bump only for package @thi.ng/transducers-hdom diff --git a/packages/transducers-hdom/package.json b/packages/transducers-hdom/package.json index 025d368337..90fd95202e 100644 --- a/packages/transducers-hdom/package.json +++ b/packages/transducers-hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-hdom", - "version": "1.2.5", + "version": "1.2.6", "description": "Transducer based UI updater for @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -29,8 +29,8 @@ }, "dependencies": { "@thi.ng/checks": "^1.5.13", - "@thi.ng/hdom": "^5.2.2", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/hdom": "^6.0.0", + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "diff", diff --git a/packages/transducers-stats/CHANGELOG.md b/packages/transducers-stats/CHANGELOG.md index f16ef16800..999a598b76 100644 --- a/packages/transducers-stats/CHANGELOG.md +++ b/packages/transducers-stats/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.4.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-stats@0.4.16...@thi.ng/transducers-stats@0.4.17) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/transducers-stats + + + + + ## [0.4.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-stats@0.4.15...@thi.ng/transducers-stats@0.4.16) (2018-12-08) **Note:** Version bump only for package @thi.ng/transducers-stats diff --git a/packages/transducers-stats/package.json b/packages/transducers-stats/package.json index 769378e333..8cd4eef249 100644 --- a/packages/transducers-stats/package.json +++ b/packages/transducers-stats/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-stats", - "version": "0.4.16", + "version": "0.4.17", "description": "Transducers for statistical / technical analysis", "main": "./index.js", "typings": "./index.d.ts", @@ -28,9 +28,9 @@ "typescript": "^3.1.3" }, "dependencies": { - "@thi.ng/dcons": "^1.1.16", + "@thi.ng/dcons": "^1.1.17", "@thi.ng/errors": "^0.1.11", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "ES6", diff --git a/packages/transducers/CHANGELOG.md b/packages/transducers/CHANGELOG.md index 48aeae1757..c7fba30589 100644 --- a/packages/transducers/CHANGELOG.md +++ b/packages/transducers/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@2.2.4...@thi.ng/transducers@2.2.5) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/transducers + + + + + ## [2.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@2.2.3...@thi.ng/transducers@2.2.4) (2018-12-08) **Note:** Version bump only for package @thi.ng/transducers diff --git a/packages/transducers/package.json b/packages/transducers/package.json index 795add3f38..863f0eba02 100644 --- a/packages/transducers/package.json +++ b/packages/transducers/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers", - "version": "2.2.4", + "version": "2.2.5", "description": "Lightweight transducer implementations for ES6 / TypeScript", "main": "./index.js", "typings": "./index.d.ts", @@ -34,7 +34,7 @@ "@thi.ng/compose": "^0.2.1", "@thi.ng/equiv": "^0.1.14", "@thi.ng/errors": "^0.1.11", - "@thi.ng/strings": "^0.6.0" + "@thi.ng/strings": "^0.7.0" }, "keywords": [ "ES6", diff --git a/packages/vectors/CHANGELOG.md b/packages/vectors/CHANGELOG.md index 61cdfaf3e9..6a92baa74d 100644 --- a/packages/vectors/CHANGELOG.md +++ b/packages/vectors/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.4.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/vectors@1.4.5...@thi.ng/vectors@1.4.6) (2018-12-13) + +**Note:** Version bump only for package @thi.ng/vectors + + + + + ## [1.4.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/vectors@1.4.4...@thi.ng/vectors@1.4.5) (2018-12-08) **Note:** Version bump only for package @thi.ng/vectors diff --git a/packages/vectors/package.json b/packages/vectors/package.json index 8b2de3bcb1..0e19324dcb 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/vectors", - "version": "1.4.5", + "version": "1.4.6", "description": "Vector algebra for fixed & variable sizes, memory mapped, flexible layouts", "main": "./index.js", "typings": "./index.d.ts", @@ -33,7 +33,7 @@ "@thi.ng/checks": "^1.5.13", "@thi.ng/errors": "^0.1.11", "@thi.ng/math": "^0.2.1", - "@thi.ng/transducers": "^2.2.4" + "@thi.ng/transducers": "^2.2.5" }, "keywords": [ "ES6",