diff --git a/README.md b/README.md
index 398737ad49..857e540d7d 100644
--- a/README.md
+++ b/README.md
@@ -2,25 +2,25 @@
[![Travis status](https://api.travis-ci.org/thi-ng/umbrella.svg?branch=master)](https://travis-ci.org/thi-ng/umbrella)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org/)
+[![Discord chat](https://img.shields.io/discord/445761008837984256.svg)](https://discord.gg/JhYcmBw)
Mono-repository for thi.ng TypeScript/ES6 projects, a collection of largely
-data / transformation oriented packages and building blocks reactive
-applications, components (not just UI related), dataflow.
+data / transformation oriented packages and building blocks for reactive
+applications, dataflow graphs, components (not just UI related).
-All/most packages:
+Most packages:
- have detailed, individual README files w/ small usage examples
- versioned independently
-- distributed as ES6 (CommonJS modules) with bundled TypeScript typings
- & changelogs
+- distributed as ES6 (CommonJS modules) with doc comments (incl. example
+ code snippets), bundled TypeScript typings & changelogs
- highly modular with largely only a few closely related functions /
single class per file to help w/ tree shaking
- provide re-exports of all their publics for full library imports
-- have either none or only @thi.ng internal runtime dependencies (see
- graph below)
+- have either none or only @thi.ng internal runtime dependencies
- declare public interfaces, enums & types in an `src/api.ts` file
(larger packages only)
-- autogenerated online documentation at [docs.thi.ng](http://docs.thi.ng)
+- auto-generated online documentation at [docs.thi.ng](http://docs.thi.ng)
- licensed under Apache Software License 2.0
There's a steadily growing number of standalone examples (different
@@ -29,47 +29,49 @@ difficulties, many combining functionality from several packages) in the
## Projects
-| Projects | Version | Changelog | Description |
-|----|----|----|----|
-| [`@thi.ng/api`](./packages/api) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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/bitstream`](./packages/bitstream) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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/dot`](./packages/dot) | [![npm (scoped)](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/equiv`](./packages/equiv) | [![npm (scoped)](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) | [![npm (scoped)](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/hdom`](./packages/hdom) | [![npm (scoped)](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-components`](./packages/hdom-components) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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/paths`](./packages/paths) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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/rle-pack`](./packages/rle-pack) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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) | [![npm (scoped)](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/transducers`](./packages/transducers) | [![npm (scoped)](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/unionstruct`](./packages/unionstruct) | [![npm (scoped)](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 |
+| 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/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/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/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/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-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/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/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/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/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/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 |
## Dependency graph
diff --git a/examples/hdom-dropdown-fuzzy/.gitignore b/examples/hdom-dropdown-fuzzy/.gitignore
new file mode 100644
index 0000000000..9c418ce79f
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+yarn.lock
+*.js
diff --git a/examples/hdom-dropdown-fuzzy/README.md b/examples/hdom-dropdown-fuzzy/README.md
new file mode 100644
index 0000000000..861253b871
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/README.md
@@ -0,0 +1,21 @@
+# hdom-dropdown-fuzzy
+
+[Live demo](http://demo.thi.ng/umbrella/hdom-dropdown-fuzzy/)
+
+**This example is a work-in-progress trying out different ideas. Do not
+(yet) take as reference for your own projects.**
+
+```
+git clone https://github.com/thi-ng/umbrella.git
+cd umbrella/examples/hdom-dropdown-fuzzy
+yarn install
+yarn start
+```
+
+## Authors
+
+- Karsten Schmidt
+
+## License
+
+© 2018 Karsten Schmidt // Apache Software License 2.0
diff --git a/examples/hdom-dropdown-fuzzy/index.html b/examples/hdom-dropdown-fuzzy/index.html
new file mode 100644
index 0000000000..d58b6fa6d9
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ hdom-dropdown-fuzzy
+
+
+
+
+
+
+
+ WIP customizable dropdown component w/ fuzzy filter.
+
Source
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/hdom-dropdown-fuzzy/package.json b/examples/hdom-dropdown-fuzzy/package.json
new file mode 100644
index 0000000000..513d7f148b
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "hdom-dropdown-fuzzy",
+ "version": "0.0.1",
+ "repository": "https://github.com/thi-ng/umbrella",
+ "author": "Karsten Schmidt ",
+ "license": "Apache-2.0",
+ "scripts": {
+ "build": "webpack --mode production --display-reasons --display-modules",
+ "start": "webpack-dev-server --open --mode development --devtool inline-source-map"
+ },
+ "devDependencies": {
+ "ts-loader": "^4.3.0",
+ "typescript": "^2.8.3",
+ "webpack": "^4.8.1",
+ "webpack-cli": "^2.1.3",
+ "webpack-dev-server": "^3.1.4"
+ },
+ "dependencies": {
+ "@thi.ng/api": "latest",
+ "@thi.ng/hdom": "latest",
+ "@thi.ng/hdom-components": "latest",
+ "@thi.ng/interceptors": "latest",
+ "@thi.ng/paths": "latest",
+ "@thi.ng/transducers": "latest"
+ }
+}
\ No newline at end of file
diff --git a/examples/hdom-dropdown-fuzzy/src/config.ts b/examples/hdom-dropdown-fuzzy/src/config.ts
new file mode 100644
index 0000000000..815dfc3342
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/src/config.ts
@@ -0,0 +1,241 @@
+export const state = {
+ countries: {
+ open: false,
+ filter: "",
+ items: [
+ "Afghanistan",
+ "Albania",
+ "Algeria",
+ "Andorra",
+ "Angola",
+ "Antigua and Barbuda",
+ "Argentina",
+ "Armenia",
+ "Australia",
+ "Austria",
+ "Azerbaijan",
+ "Bahamas",
+ "Bahrain",
+ "Bangladesh",
+ "Barbados",
+ "Belarus",
+ "Belgium",
+ "Belize",
+ "Benin",
+ "Bhutan",
+ "Bolivia",
+ "Bosnia and Herzegovina",
+ "Botswana",
+ "Brazil",
+ "Brunei",
+ "Bulgaria",
+ "Burkina Faso",
+ "Burundi",
+ "Cabo Verde",
+ "Cambodia",
+ "Cameroon",
+ "Canada",
+ "Central African Republic (CAR)",
+ "Chad",
+ "Chile",
+ "China",
+ "Colombia",
+ "Comoros",
+ "Democratic Republic of the Congo",
+ "Republic of the Congo",
+ "Costa Rica",
+ "Cote d'Ivoire",
+ "Croatia",
+ "Cuba",
+ "Cyprus",
+ "Czech Republic",
+ "Denmark",
+ "Djibouti",
+ "Dominica",
+ "Dominican Republic",
+ "Ecuador",
+ "Egypt",
+ "El Salvador",
+ "Equatorial Guinea",
+ "Eritrea",
+ "Estonia",
+ "Eswatini (formerly Swaziland)",
+ "Ethiopia",
+ "Fiji",
+ "Finland",
+ "France",
+ "Gabon",
+ "Gambia",
+ "Georgia",
+ "Germany",
+ "Ghana",
+ "Greece",
+ "Grenada",
+ "Guatemala",
+ "Guinea",
+ "Guinea-Bissau",
+ "Guyana",
+ "Haiti",
+ "Honduras",
+ "Hungary",
+ "Iceland",
+ "India",
+ "Indonesia",
+ "Iran",
+ "Iraq",
+ "Ireland",
+ "Israel",
+ "Italy",
+ "Jamaica",
+ "Japan",
+ "Jordan",
+ "Kazakhstan",
+ "Kenya",
+ "Kiribati",
+ "Kosovo",
+ "Kuwait",
+ "Kyrgyzstan",
+ "Laos",
+ "Latvia",
+ "Lebanon",
+ "Lesotho",
+ "Liberia",
+ "Libya",
+ "Liechtenstein",
+ "Lithuania",
+ "Luxembourg",
+ "Macedonia (FYROM)",
+ "Madagascar",
+ "Malawi",
+ "Malaysia",
+ "Maldives",
+ "Mali",
+ "Malta",
+ "Marshall Islands",
+ "Mauritania",
+ "Mauritius",
+ "Mexico",
+ "Micronesia",
+ "Moldova",
+ "Monaco",
+ "Mongolia",
+ "Montenegro",
+ "Morocco",
+ "Mozambique",
+ "Myanmar (formerly Burma)",
+ "Namibia",
+ "Nauru",
+ "Nepal",
+ "Netherlands",
+ "New Zealand",
+ "Nicaragua",
+ "Niger",
+ "Nigeria",
+ "North Korea",
+ "Norway",
+ "Oman",
+ "Pakistan",
+ "Palau",
+ "Palestine",
+ "Panama",
+ "Papua New Guinea",
+ "Paraguay",
+ "Peru",
+ "Philippines",
+ "Poland",
+ "Portugal",
+ "Qatar",
+ "Romania",
+ "Russia",
+ "Rwanda",
+ "Saint Kitts and Nevis",
+ "Saint Lucia",
+ "Saint Vincent and the Grenadines",
+ "Samoa",
+ "San Marino",
+ "Sao Tome and Principe",
+ "Saudi Arabia",
+ "Senegal",
+ "Serbia",
+ "Seychelles",
+ "Sierra Leone",
+ "Singapore",
+ "Slovakia",
+ "Slovenia",
+ "Solomon Islands",
+ "Somalia",
+ "South Africa",
+ "South Korea",
+ "South Sudan",
+ "Spain",
+ "Sri Lanka",
+ "Sudan",
+ "Suriname",
+ "Sweden",
+ "Switzerland",
+ "Syria",
+ "Taiwan",
+ "Tajikistan",
+ "Tanzania",
+ "Thailand",
+ "Timor-Leste",
+ "Togo",
+ "Tonga",
+ "Trinidad and Tobago",
+ "Tunisia",
+ "Turkey",
+ "Turkmenistan",
+ "Tuvalu",
+ "Uganda",
+ "Ukraine",
+ "United Arab Emirates (UAE)",
+ "United Kingdom (UK)",
+ "United States of America (USA)",
+ "Uruguay",
+ "Uzbekistan",
+ "Vanuatu",
+ "Vatican City (Holy See)",
+ "Venezuela",
+ "Vietnam",
+ "Yemen",
+ "Zambia",
+ "Zimbabwe"
+ ].map((x, i) => [i, x])
+ }
+};
+
+export const theme = {
+ root: {
+ class: "sans-serif"
+ },
+ column: {
+ class: "fl w-100 w-50-ns w-33-l pa2"
+ },
+ input: {
+ class: "bg-transparent w-100 bn pa2"
+ },
+ dd: {
+ root: { class: "" },
+ bodyClosed: {
+ style: {
+ "max-height": 0,
+ "overflow-y": "hidden",
+ opacity: 0
+ }
+ },
+ bodyOpen: {
+ style: {
+ "max-height": "calc(11 * 1.8rem)",
+ "overflow-y": "scroll",
+ opacity: 1,
+ transition: "all 100ms ease-in"
+ }
+ },
+ item: { class: "pointer link db w-100 ph3 pv2 black hover-bg-washed-green bg-animate bb b--moon-gray" },
+ itemSelected: { class: "pointer link db w-100 ph3 pv2 black hover-bg-light-gray bg-animate bb b--moon-gray b" },
+ itemDisabled: { class: "db w-100 ph3 pv2 gray bb b--moon-gray" },
+ },
+ fuzzy: {
+ class: "b underline"
+ }
+};
diff --git a/examples/hdom-dropdown-fuzzy/src/dropdown.ts b/examples/hdom-dropdown-fuzzy/src/dropdown.ts
new file mode 100644
index 0000000000..44640e3708
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/src/dropdown.ts
@@ -0,0 +1,89 @@
+import { IObjectOf } from "@thi.ng/api/api";
+import { ReadonlyAtom } from "@thi.ng/atom/api";
+import { isString } from "@thi.ng/checks";
+import { appLink } from "@thi.ng/hdom-components/link";
+import { EV_SET_VALUE, EV_TOGGLE_VALUE } from "@thi.ng/interceptors/api";
+import { EventBus } from "@thi.ng/interceptors/event-bus";
+import { getIn, Path } from "@thi.ng/paths";
+
+export interface BaseContext {
+ bus: EventBus;
+ state: ReadonlyAtom;
+}
+
+export interface DropdownArgs {
+ state: DropdownState;
+ statePath: Path;
+ ontoggle: EventListener;
+ onchange: (id: any) => EventListener;
+ attribs: IObjectOf;
+ hoverLabel: any;
+ openLabel: any;
+ noItems: any;
+ onmouseover: EventListener;
+ onmouseleave: EventListener;
+}
+
+export interface DropdownState {
+ open: boolean;
+ hover: boolean;
+ selected: any;
+ items: DropdownItem[];
+}
+
+export type DropdownItem = [any, any];
+
+export interface DropdownTheme {
+ root: IObjectOf;
+ bodyOpen: IObjectOf;
+ bodyClosed: IObjectOf;
+ item: IObjectOf;
+ itemSelected: IObjectOf;
+ itemDisabled: IObjectOf;
+}
+
+export function dropdown(themeCtxPath: Path) {
+ return (ctx: any, opts: Partial) => {
+ const ui: DropdownTheme = getIn(ctx, themeCtxPath);
+ const state = opts.statePath ? getIn(ctx, opts.statePath) : opts.state;
+ const hattribs = {
+ onmouseover: opts.onmouseover,
+ onmouseleave: opts.onmouseleave,
+ };
+ return state.open ?
+ ["div", { ...ui.root, onkeydown: (e) => console.log(e) },
+ [appLink, { ...hattribs, ...ui.itemSelected }, opts.ontoggle, opts.openLabel || opts.hoverLabel],
+ ["div", ui.bodyOpen,
+ state.items.length ?
+ state.items.map(
+ (x) =>
+ ["a",
+ {
+ ...x[0] === state.selected ? ui.itemSelected : ui.item,
+ href: "#",
+ onclick: opts.onchange(x[0]),
+ },
+ ...(isString(x[1]) ? [x[1]] : x[1])]
+ ) :
+ ["span", ui.itemDisabled, opts.noItems]]] :
+ ["div", ui.root,
+ [appLink, { ...hattribs, ...ui.item }, opts.ontoggle,
+ state.hover ?
+ opts.hoverLabel :
+ (state.items.find((x) => x[0] === state.selected) ||
+ [, opts.hoverLabel])[1]],
+ ["div", ui.bodyClosed]];
+ };
+}
+
+export const dropdownListeners = (ctx: BaseContext, basePath: PropertyKey[]) => ({
+ onmouseover: () => ctx.bus.dispatch([EV_SET_VALUE, [[...basePath, "hover"], true]]),
+ onmouseleave: () => ctx.bus.dispatch([EV_SET_VALUE, [[...basePath, "hover"], false]]),
+ ontoggle: () => ctx.bus.dispatch([EV_TOGGLE_VALUE, [...basePath, "open"]]),
+ onchange: (x) => () => {
+ ctx.bus.dispatch(
+ [EV_SET_VALUE, [[...basePath, "selected"], x]],
+ [EV_SET_VALUE, [[...basePath, "open"], false]]
+ );
+ }
+});
diff --git a/examples/hdom-dropdown-fuzzy/src/fuzzy.ts b/examples/hdom-dropdown-fuzzy/src/fuzzy.ts
new file mode 100644
index 0000000000..dc36c3e4b8
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/src/fuzzy.ts
@@ -0,0 +1,70 @@
+import { IView } from "@thi.ng/atom/api";
+import { EV_SET_VALUE } from "@thi.ng/interceptors/api";
+import { comp } from "@thi.ng/transducers/func/comp";
+import { iterator } from "@thi.ng/transducers/iterator";
+import { filterFuzzy } from "@thi.ng/transducers/xform/filter-fuzzy";
+import { map } from "@thi.ng/transducers/xform/map";
+
+import { dropdownListeners, DropdownState, DropdownItem } from "./dropdown";
+
+export interface FuzzyArgs {
+ state: IView;
+ filter: IView;
+ dropdown: any;
+ input: any;
+ hoverLabel: any;
+ placeholder: string;
+}
+
+export const fuzzyDropdown = (ctx, opts: FuzzyArgs) => {
+ const close = () => ctx.bus.dispatch([EV_SET_VALUE, [opts.state.path + ".open", false]]);
+ const filterInput = [opts.input, {
+ state: opts.filter.deref(),
+ placeholder: opts.placeholder,
+ oninput: (e) => ctx.bus.dispatch([EV_SET_VALUE, [opts.filter.path, e.target.value]]),
+ onclear: () => ctx.bus.dispatch([EV_SET_VALUE, [opts.filter.path, ""]]),
+ oncancel: close,
+ onconfirm: close,
+ }];
+ return () => {
+ const state = { ...opts.state.deref() };
+ const filter = opts.filter.deref().toLowerCase();
+ if (filter && state.open) {
+ state.items = [
+ ...iterator(
+ comp(
+ filterFuzzy(filter, (x: DropdownItem) => x[1].toLowerCase()),
+ map(([id, x]) =>
+ [
+ id,
+ highlightMatches((y) => ["span", ctx.theme.fuzzy, y], x, filter)
+ ])
+ ),
+ state.items)
+ ];
+ }
+ return [opts.dropdown, {
+ ...dropdownListeners(ctx, opts.state.path),
+ openLabel: filterInput,
+ hoverLabel: opts.hoverLabel,
+ noItems: "no matches",
+ state
+ }];
+ };
+};
+
+const highlightMatches = (fn: (x: string) => any, x: string, filter: string) => {
+ const res: any[] = [];
+ let prev = -1, n = x.length - 1, m = filter.length;
+ for (let i = 0, j = 0; i <= n && j < m; i++) {
+ const c = x.charAt(i);
+ if (c.toLowerCase() === filter.charAt(j)) {
+ i - prev > 1 && res.push(x.substring(prev + 1, i));
+ res.push(fn(c));
+ prev = i;
+ j++;
+ }
+ }
+ prev < n && res.push(x.substr(prev + 1));
+ return res;
+};
diff --git a/examples/hdom-dropdown-fuzzy/src/index.ts b/examples/hdom-dropdown-fuzzy/src/index.ts
new file mode 100644
index 0000000000..9298463047
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/src/index.ts
@@ -0,0 +1,44 @@
+import { Atom } from "@thi.ng/atom/atom";
+import { start } from "@thi.ng/hdom/start";
+import { EventBus } from "@thi.ng/interceptors/event-bus";
+import { trace } from "@thi.ng/interceptors/interceptors";
+
+import { state, theme } from "./config";
+import { dropdown } from "./dropdown";
+import { fuzzyDropdown } from "./fuzzy";
+import { cancelableInput } from "./input";
+
+const bus = new EventBus(new Atom(state));
+bus.instrumentWith([trace]);
+
+const ctx = {
+ bus,
+ theme,
+ views: {
+ countries: bus.state.addView("countries"),
+ filter: bus.state.addView("countries.filter"),
+ }
+};
+
+const dd = dropdown("theme.dd");
+const input = cancelableInput("theme.input");
+
+start("app",
+ (ctx) => {
+ ctx.bus.processQueue();
+ return ["div", ctx.theme.root,
+ ["div", ctx.theme.column,
+ [fuzzyDropdown, {
+ state: ctx.views.countries,
+ filter: ctx.views.filter,
+ placeholder: "Start typing to fuzzy match",
+ hoverLabel: [["span", "Choose a country..."], ["i.fr.fas.fa-angle-down"]],
+ dropdown: dd,
+ input,
+ }]
+ ],
+ ];
+ },
+ ctx);
+
+// window["ctx"] = ctx;
diff --git a/examples/hdom-dropdown-fuzzy/src/input.ts b/examples/hdom-dropdown-fuzzy/src/input.ts
new file mode 100644
index 0000000000..847ca34f1f
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/src/input.ts
@@ -0,0 +1,63 @@
+import { Path } from "@thi.ng/api/api";
+import { IView } from "@thi.ng/atom/api";
+import { getIn } from "@thi.ng/paths";
+
+export interface InputArgs {
+ state: IView;
+ orig: IView;
+ attribs: any;
+ placeholder: string;
+ oninput: EventListener;
+ oncancel: EventListener;
+ onconfirm: EventListener;
+ onclear: EventListener;
+ onblur: EventListener;
+}
+
+export function cancelableInput(themeCtxPath: Path) {
+ let input;
+ return {
+ init: (el: HTMLElement) => (input = el.firstChild).focus(),
+ render: (ctx, args: InputArgs) =>
+ ["span.relative",
+ ["input",
+ {
+ ...getIn(ctx, themeCtxPath),
+ ...args.attribs,
+ type: "text",
+ oninput: args.oninput,
+ onblur: args.onblur,
+ onkeydown: (e: KeyboardEvent) => {
+ switch (e.key) {
+ case "Escape":
+ args.oncancel && args.oncancel(e);
+ (e.target).blur();
+ break;
+ case "Enter":
+ // case "Tab":
+ args.onconfirm && args.onconfirm(e);
+ (e.target).blur();
+ break;
+ default:
+ }
+ },
+ placeholder: args.placeholder,
+ value: args.state
+ },
+ ],
+ args.onclear ?
+ ["a",
+ {
+ href: "#",
+ onclick: (e) => {
+ e.stopPropagation();
+ input.focus();
+ args.onclear(e);
+ }
+ },
+ ["i.absolute.fas.fa-times-circle.gray.f7",
+ { style: { right: "0.5rem", top: "0.25rem" } }]] :
+ undefined
+ ]
+ };
+}
diff --git a/examples/hdom-dropdown-fuzzy/tsconfig.json b/examples/hdom-dropdown-fuzzy/tsconfig.json
new file mode 100644
index 0000000000..bd6481a5a6
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "."
+ },
+ "include": [
+ "./src/**/*.ts"
+ ]
+}
diff --git a/examples/hdom-dropdown-fuzzy/webpack.config.js b/examples/hdom-dropdown-fuzzy/webpack.config.js
new file mode 100644
index 0000000000..e2bf1e8d3a
--- /dev/null
+++ b/examples/hdom-dropdown-fuzzy/webpack.config.js
@@ -0,0 +1,18 @@
+module.exports = {
+ entry: "./src/index.ts",
+ output: {
+ path: __dirname,
+ filename: "bundle.js"
+ },
+ resolve: {
+ extensions: [".ts", ".js"]
+ },
+ module: {
+ rules: [
+ { test: /\.ts$/, use: "ts-loader" }
+ ]
+ },
+ devServer: {
+ contentBase: "."
+ }
+};
diff --git a/examples/rstream-dataflow/src/index.ts b/examples/rstream-dataflow/src/index.ts
index 42f7a0b216..07cce78ace 100644
--- a/examples/rstream-dataflow/src/index.ts
+++ b/examples/rstream-dataflow/src/index.ts
@@ -59,7 +59,7 @@ const graph = initGraph(db, {
mpos: {
fn: extract([1, "pos"]),
ins: { src: { stream: () => gestures } },
- out: "mpos"
+ outs: { "*": "mpos" }
},
// extracts last click position from gesture tuple
@@ -68,7 +68,7 @@ const graph = initGraph(db, {
clickpos: {
fn: extract([1, "click"]),
ins: { src: { stream: () => gestures } },
- out: "clickpos"
+ outs: { "*": "clickpos" }
},
// extracts & computes length of `delta` vector in gesture tuple
@@ -83,7 +83,7 @@ const graph = initGraph(db, {
}
)),
ins: { src: { stream: () => gestures } },
- out: "dist"
+ outs: { "*": "dist" }
},
// combines `clickpos`, `dist` and `color` streams to produce a
@@ -101,11 +101,11 @@ const graph = initGraph(db, {
undefined
)),
ins: {
- click: { stream: "clickpos" },
- radius: { stream: "radius" },
- color: { stream: "color" },
+ click: { stream: "/clickpos/node" },
+ radius: { stream: "/radius/node" },
+ color: { stream: "/color/node" },
},
- out: "circle"
+ outs: { "*": "circle" }
},
// produces a new random color for each new drag gesture (and
@@ -119,8 +119,8 @@ const graph = initGraph(db, {
dedupe(equiv),
map((x) => x && colors.next().value)
)),
- ins: { src: { stream: "clickpos" } },
- out: "color"
+ ins: { src: { stream: "/clickpos/node" } },
+ outs: { "*": "color" }
},
// transforms a `requestAnimationFrame` event stream (frame counter @ 60fps)
@@ -128,7 +128,7 @@ const graph = initGraph(db, {
sine: {
fn: node1(map((x: number) => 0.8 + 0.2 * Math.sin(x * 0.05))),
ins: { src: { stream: () => raf } },
- out: "sin"
+ outs: { "*": "sin" }
},
// multiplies `dist` and `sine` streams to produce an animated
@@ -136,10 +136,10 @@ const graph = initGraph(db, {
radius: {
fn: mul,
ins: {
- a: { stream: "sine" },
- b: { stream: "dist" }
+ a: { stream: "/sine/node" },
+ b: { stream: "/dist/node" }
},
- out: "radius"
+ outs: { "*": "radius" }
}
});
@@ -152,7 +152,7 @@ start("app", () =>
// since all @thi.ng/rstream subscriptions implement the
// @thi.ng/api/IDeref interface (like several other types, e.g.
// @thi.ng/atom's Atom, Cursor, View etc.)
- graph.circle
+ graph.circle.node
]);
// create a GraphViz DOT file of the entire dataflow graph
diff --git a/examples/rstream-grid/src/dataflow.ts b/examples/rstream-grid/src/dataflow.ts
index c48f792a23..67a395377f 100644
--- a/examples/rstream-grid/src/dataflow.ts
+++ b/examples/rstream-grid/src/dataflow.ts
@@ -32,22 +32,24 @@ export function initDataflow(bus: EventBus) {
rotation: {
fn: rotate,
ins: {
- shapes: { stream: "grid" },
+ shapes: { stream: "/grid/node" },
theta: { path: paths.THETA },
},
},
svg: {
fn: createSVG,
ins: {
- shapes: { stream: "rotation" },
+ shapes: { stream: "/rotation/node" },
cols: { path: paths.COLS },
rows: { path: paths.ROWS },
stroke: { path: paths.STROKE },
},
// dispatch SVG result doc as event
- out: (node) => node.subscribe({
- next: (svg) => bus.dispatch([ev.UPDATE_SVG, svg])
- })
+ outs: {
+ "*": (node) => node.subscribe({
+ next: (svg) => bus.dispatch([ev.UPDATE_SVG, svg])
+ })
+ }
}
});
return graph;
diff --git a/package.json b/package.json
index 1731618bbd..531a2faa09 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"webpack-dev-server": "^3.1.4"
},
"scripts": {
+ "bootstrap": "lerna bootstrap",
"build": "yarn install && lerna -v && lerna bootstrap && lerna run build --sort",
"cover": "lerna run cover",
"depgraph": "scripts/depgraph && git add assets/deps.png && git commit -m 'docs: update dep graph' && git push",
diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md
index d27c806af6..0b588ebc99 100644
--- a/packages/api/CHANGELOG.md
+++ b/packages/api/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.
+
+## [4.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@4.0.3...@thi.ng/api@4.0.4) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/api
+
+
+## [4.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@4.0.2...@thi.ng/api@4.0.3) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/api
+
## [4.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@4.0.1...@thi.ng/api@4.0.2) (2018-05-14)
diff --git a/packages/api/package.json b/packages/api/package.json
index ee4f6a8515..618face072 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/api",
- "version": "4.0.2",
+ "version": "4.0.4",
"description": "Common, generic types & interfaces for thi.ng projects",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/api",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,7 +28,7 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"compare",
diff --git a/packages/api/src/api.ts b/packages/api/src/api.ts
index 867ac23ddc..bd88b13385 100644
--- a/packages/api/src/api.ts
+++ b/packages/api/src/api.ts
@@ -95,8 +95,11 @@ export interface IBuffered {
*/
export interface ICompare {
/**
- * Compares this value with given value `x`.
- * Must follow same contract as `Comparator`.
+ * Compares this value with given value `x`. MUST follow same
+ * contract as `Comparator`. MUST return 0 if the type also
+ * implements `IEquiv` and `equiv` returns true for same `x`.
+ *
+ * Also see `IHash`.
*
* @param x
*/
@@ -159,6 +162,8 @@ export interface IEmpty {
/**
* Interface to provide enabled/disabled functionality. Also see
* `@IEnable` decorator mixin
+ *
+ * @param T type for enable/disable option arg
*/
export interface IEnable {
isEnabled(): boolean;
@@ -185,6 +190,9 @@ export interface IEquiv {
equiv(o: any): boolean;
}
+/**
+ * @param T value type
+ */
export interface IEqualsDelta {
/**
* Returns `true` if this value equals `o` with optional allowance
diff --git a/packages/associative/CHANGELOG.md b/packages/associative/CHANGELOG.md
index d6dc487c6e..27879e058d 100644
--- a/packages/associative/CHANGELOG.md
+++ b/packages/associative/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.5.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.5.7...@thi.ng/associative@0.5.8) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/associative
+
+
+## [0.5.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.5.6...@thi.ng/associative@0.5.7) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/associative
+
+
+## [0.5.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.5.5...@thi.ng/associative@0.5.6) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/associative
+
## [0.5.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.5.4...@thi.ng/associative@0.5.5) (2018-05-14)
diff --git a/packages/associative/README.md b/packages/associative/README.md
index a228908913..3c9a6e9e9b 100644
--- a/packages/associative/README.md
+++ b/packages/associative/README.md
@@ -142,7 +142,7 @@ interface, an extension of the native ES6 Set API.
### ArraySet
Simple array based `Set` implementation which by default uses
-[@thi.ng/api/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/api/src/equiv.ts)
+[@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv/src/index.ts)
for value equivalence checking.
### LLSet
@@ -161,8 +161,8 @@ canonical keys. By default uses `ArraySet` for this purpose.
Alternative implementation of the ES6 Map API using a Skip list as
backing store and support for configurable key equality and sorting
-semantics. Like with sets, uses @thi.ng/api/equiv & @thi.ng/api/compare
-by default.
+semantics. Like with sets, uses @thi.ng/equiv & @thi.ng/compare by
+default.
William Pugh's (creator of this data structure) description:
diff --git a/packages/associative/package.json b/packages/associative/package.json
index 9d9cdd31b8..aeb5d6ecdb 100644
--- a/packages/associative/package.json
+++ b/packages/associative/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/associative",
- "version": "0.5.5",
+ "version": "0.5.8",
"description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/associative",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,13 +28,13 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/compare": "^0.1.2",
- "@thi.ng/dcons": "^1.0.2",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/iterators": "^4.1.15"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/compare": "^0.1.4",
+ "@thi.ng/dcons": "^1.0.5",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/iterators": "^4.1.18"
},
"keywords": [
"data structures",
diff --git a/packages/atom/CHANGELOG.md b/packages/atom/CHANGELOG.md
index f8c37fcc5b..823f6e2fc3 100644
--- a/packages/atom/CHANGELOG.md
+++ b/packages/atom/CHANGELOG.md
@@ -3,6 +3,42 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.4.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.4.1...@thi.ng/atom@1.4.2) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/atom
+
+
+## [1.4.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.4.0...@thi.ng/atom@1.4.1) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/atom
+
+
+# [1.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.3.13...@thi.ng/atom@1.4.0) (2018-05-30)
+
+
+### Features
+
+* **atom:** add INotify impl for History ([9422598](https://github.com/thi-ng/umbrella/commit/9422598))
+* **atom:** provide prev/curr states to history event listeners ([7ac6227](https://github.com/thi-ng/umbrella/commit/7ac6227))
+
+
+
+
+
+## [1.3.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.3.12...@thi.ng/atom@1.3.13) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/atom
+
## [1.3.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.3.11...@thi.ng/atom@1.3.12) (2018-05-14)
diff --git a/packages/atom/README.md b/packages/atom/README.md
index 30eae4a003..552b25d978 100644
--- a/packages/atom/README.md
+++ b/packages/atom/README.md
@@ -227,7 +227,7 @@ value change (in contrast to normal watches, which execute with each
update, regardless of value change).
Related, the actual value change predicate can be customized. If not
-given, the default `@thi.ng/api/equiv` will be used.
+given, the default `@thi.ng/equiv` will be used.
```typescript
let x;
diff --git a/packages/atom/package.json b/packages/atom/package.json
index 459fb4ded1..82475b9ed7 100644
--- a/packages/atom/package.json
+++ b/packages/atom/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/atom",
- "version": "1.3.12",
+ "version": "1.4.2",
"description": "Mutable wrapper for immutable values",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/atom",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,11 +28,11 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/paths": "^1.3.8"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/paths": "^1.3.10"
},
"keywords": [
"cursor",
diff --git a/packages/atom/src/api.ts b/packages/atom/src/api.ts
index 8e52b14d82..377d5c1e63 100644
--- a/packages/atom/src/api.ts
+++ b/packages/atom/src/api.ts
@@ -50,7 +50,10 @@ export interface CursorOpts {
id?: string;
}
-export interface IHistory extends IAtom {
+export interface IHistory extends
+ IAtom,
+ api.INotify {
+
canUndo(): boolean;
canRedo(): boolean;
diff --git a/packages/atom/src/history.ts b/packages/atom/src/history.ts
index ad27234799..97a1b9a52e 100644
--- a/packages/atom/src/history.ts
+++ b/packages/atom/src/history.ts
@@ -1,4 +1,5 @@
-import { Predicate2, Watch } from "@thi.ng/api/api";
+import { Event, Predicate2, Watch } from "@thi.ng/api/api";
+import * as mixin from "@thi.ng/api/mixins/inotify";
import { equiv } from "@thi.ng/equiv";
import {
getIn,
@@ -21,11 +22,18 @@ import { View } from "./view";
* `IAtom` interface and so can be used directly in place and delegates
* to wrapped atom/cursor. Value changes are only recorded in history if
* `changed` predicate returns truthy value, or else by calling
- * `record()` directly.
+ * `record()` directly. This class too implements the @thi.ng/api
+ * `INotify` interface to support event listeners for `undo()`, `redo()`
+ * and `record()`.
*/
+@mixin.INotify
export class History implements
IHistory {
+ static readonly EVENT_UNDO = "undo";
+ static readonly EVENT_REDO = "redo";
+ static readonly EVENT_RECORD = "record";
+
state: IAtom;
maxLen: number;
changed: Predicate2;
@@ -67,11 +75,21 @@ export class History implements
* switch, first records the atom's current value into the future
* stack (to enable `redo()` feature). Returns `undefined` if
* there's no history.
+ *
+ * If undo was possible, the `History.EVENT_UNDO` event is emitted
+ * after the restoration with both the `prev` and `curr` (restored)
+ * states provided as event value (and object with these two keys).
+ * This allows for additional state handling to be executed, e.g.
+ * application of the "Command pattern". See `addListener()` for
+ * registering event listeners.
*/
undo() {
if (this.history.length) {
- this.future.push(this.state.deref());
- return this.state.reset(this.history.pop());
+ const prev = this.state.deref();
+ this.future.push(prev);
+ const curr = this.state.reset(this.history.pop());
+ this.notify({ id: History.EVENT_UNDO, value: { prev, curr } });
+ return curr;
}
}
@@ -81,11 +99,21 @@ export class History implements
* switch, first records the atom's current value into the history
* stack (to enable `undo()` feature). Returns `undefined` if
* there's no future (so sad!).
+ *
+ * If redo was possible, the `History.EVENT_REDO` event is emitted
+ * after the restoration with both the `prev` and `curr` (restored)
+ * states provided as event value (and object with these two keys).
+ * This allows for additional state handling to be executed, e.g.
+ * application of the "Command pattern". See `addListener()` for
+ * registering event listeners.
*/
redo() {
if (this.future.length) {
- this.history.push(this.state.deref());
- return this.state.reset(this.future.pop());
+ const prev = this.state.deref();
+ this.history.push(prev);
+ const curr = this.state.reset(this.future.pop());
+ this.notify({ id: History.EVENT_REDO, value: { prev, curr } });
+ return curr;
}
}
@@ -140,30 +168,34 @@ export class History implements
* manually managing snapshots, i.e. when applying multiple swaps on
* the wrapped atom directly, but not wanting to create an history
* entry for each change. **DO NOT call this explicitly if using
- * `History.reset()` / `History.swap()`**.
+ * `History.reset()` / `History.swap()` etc.**
*
* If no `state` is given, uses the wrapped atom's current state
- * value.
+ * value (user code SHOULD always call without arg).
+ *
+ * If recording succeeded, the `History.EVENT_RECORD` event is
+ * emitted with the recorded state provided as event value.
*
* @param state
*/
record(state?: T) {
const history = this.history;
const n = history.length;
- if (n >= this.maxLen) {
- history.shift();
- }
+ let ok = true;
// check for arg given and not if `state == null` we want to
// allow null/undefined as possible values
if (!arguments.length) {
state = this.state.deref();
- if (!n || this.changed(history[n - 1], state)) {
- history.push(state);
+ ok = (!n || this.changed(history[n - 1], state));
+ }
+ if (ok) {
+ if (n >= this.maxLen) {
+ history.shift();
}
- } else {
history.push(state);
+ this.notify({ id: History.EVENT_RECORD, value: state });
+ this.future.length = 0;
}
- this.future.length = 0;
}
/**
@@ -214,4 +246,15 @@ export class History implements
delete this.state;
return true;
}
+
+ addListener(id: string, fn: (e: Event) => void, scope?: any): boolean {
+ return false;
+ }
+
+ removeListener(id: string, fn: (e: Event) => void, scope?: any): boolean {
+ return false;
+ }
+
+ notify(event: Event): void {
+ }
}
diff --git a/packages/bench/CHANGELOG.md b/packages/bench/CHANGELOG.md
index 92f1536d9f..beceb0fa00 100644
--- a/packages/bench/CHANGELOG.md
+++ b/packages/bench/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.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/bench@0.1.2...@thi.ng/bench@0.1.3) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/bench
+
+
+## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/bench@0.1.1...@thi.ng/bench@0.1.2) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/bench
+
## [0.1.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/bench@0.1.0...@thi.ng/bench@0.1.1) (2018-05-13)
diff --git a/packages/bench/package.json b/packages/bench/package.json
index 5bb16a2a19..6de3c242ee 100644
--- a/packages/bench/package.json
+++ b/packages/bench/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/bench",
- "version": "0.1.1",
- "description": "TODO",
+ "version": "0.1.3",
+ "description": "Basic benchmarking helpers",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/bench",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
diff --git a/packages/bitstream/CHANGELOG.md b/packages/bitstream/CHANGELOG.md
index 4cf46f5115..dd7e09712e 100644
--- a/packages/bitstream/CHANGELOG.md
+++ b/packages/bitstream/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.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitstream@0.4.12...@thi.ng/bitstream@0.4.13) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/bitstream
+
## [0.4.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitstream@0.4.11...@thi.ng/bitstream@0.4.12) (2018-05-14)
diff --git a/packages/bitstream/package.json b/packages/bitstream/package.json
index 9903acc15d..3a5af6218d 100644
--- a/packages/bitstream/package.json
+++ b/packages/bitstream/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/bitstream",
- "version": "0.4.12",
+ "version": "0.4.13",
"description": "ES6 iterator based read/write bit streams & support for variable word widths",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/bitstream",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -16,7 +20,7 @@
"test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js"
},
"dependencies": {
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/errors": "^0.1.4"
},
"devDependencies": {
"@types/mocha": "^5.2.0",
diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md
index f3efb231b0..5dfcb11ab1 100644
--- a/packages/cache/CHANGELOG.md
+++ b/packages/cache/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.2.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.12...@thi.ng/cache@0.2.13) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/cache
+
+
+## [0.2.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.11...@thi.ng/cache@0.2.12) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/cache
+
+
+## [0.2.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.10...@thi.ng/cache@0.2.11) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/cache
+
## [0.2.10](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.9...@thi.ng/cache@0.2.10) (2018-05-14)
diff --git a/packages/cache/README.md b/packages/cache/README.md
index 9adc4c5464..8d71d93c9b 100644
--- a/packages/cache/README.md
+++ b/packages/cache/README.md
@@ -21,7 +21,7 @@ strategies available are:
- ES6 Map-like API (with minor differences)
- Supports any types for both keys & values
- Customizable cache limits (no. of items / actual size)
-- Customizable key equality checks (@thi.ng/api/equiv by default)
+- Customizable key equality checks (@thi.ng/equiv by default)
- Optional item release callbacks (to clean up resources when value is expunged)
## Installation
@@ -34,6 +34,7 @@ yarn add @thi.ng/cache
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api)
- [@thi.ng/dcons](https://github.com/thi-ng/umbrella/tree/master/packages/dcons)
+- [@thi.ng/equiv](https://github.com/thi-ng/umbrella/tree/master/packages/equiv)
- [@thi.ng/iterators](https://github.com/thi-ng/umbrella/tree/master/packages/iterators)
## Usage examples
diff --git a/packages/cache/package.json b/packages/cache/package.json
index ce9d5f9637..c39f4f6a89 100644
--- a/packages/cache/package.json
+++ b/packages/cache/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/cache",
- "version": "0.2.10",
+ "version": "0.2.13",
"description": "In-memory cache implementations with ES6 Map-like API and different eviction strategies",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/cache",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,9 +28,9 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/dcons": "^1.0.2",
- "@thi.ng/iterators": "^4.1.15"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/dcons": "^1.0.5",
+ "@thi.ng/iterators": "^4.1.18"
},
"keywords": [
"cache",
diff --git a/packages/checks/CHANGELOG.md b/packages/checks/CHANGELOG.md
index 00afe9f620..54d23f58f4 100644
--- a/packages/checks/CHANGELOG.md
+++ b/packages/checks/CHANGELOG.md
@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.5.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.5.4...@thi.ng/checks@1.5.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/checks
+
+
+## [1.5.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.5.3...@thi.ng/checks@1.5.4) (2018-06-18)
+
+
+### Bug Fixes
+
+* **checks:** isOdd() for negative values ([3589e15](https://github.com/thi-ng/umbrella/commit/3589e15))
+
+
+
+
## [1.5.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.5.2...@thi.ng/checks@1.5.3) (2018-05-13)
diff --git a/packages/checks/package.json b/packages/checks/package.json
index 64e68ac6e1..62c40bffd1 100644
--- a/packages/checks/package.json
+++ b/packages/checks/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/checks",
- "version": "1.5.3",
+ "version": "1.5.5",
"description": "Single-function sub-modules for type, feature & value checks",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/checks",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
diff --git a/packages/checks/src/is-odd.ts b/packages/checks/src/is-odd.ts
index a97a0e004c..46eb851ada 100644
--- a/packages/checks/src/is-odd.ts
+++ b/packages/checks/src/is-odd.ts
@@ -1,3 +1,3 @@
export function isOdd(x: number) {
- return (x % 2) === 1;
+ return (x % 2) !== 0;
}
diff --git a/packages/compare/CHANGELOG.md b/packages/compare/CHANGELOG.md
index 87c420bd7d..664386f43f 100644
--- a/packages/compare/CHANGELOG.md
+++ b/packages/compare/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.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/compare@0.1.3...@thi.ng/compare@0.1.4) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/compare
+
+
+## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/compare@0.1.2...@thi.ng/compare@0.1.3) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/compare
+
## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/compare@0.1.1...@thi.ng/compare@0.1.2) (2018-05-14)
diff --git a/packages/compare/README.md b/packages/compare/README.md
index 7e9cb85b20..65d92270bd 100644
--- a/packages/compare/README.md
+++ b/packages/compare/README.md
@@ -27,9 +27,10 @@ None
## Usage examples
```typescript
+import { ICompare } from "@thi.ng/api";
import { compare } from "@thi.ng/compare";
-class Foo {
+class Foo implements ICompare {
x: number;
diff --git a/packages/compare/package.json b/packages/compare/package.json
index 263039a556..2775241220 100644
--- a/packages/compare/package.json
+++ b/packages/compare/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/compare",
- "version": "0.1.2",
+ "version": "0.1.4",
"description": "Comparator with optional delegation for types implementing @thi.ng/api/ICompare interface",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/compare",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
diff --git a/packages/csp/CHANGELOG.md b/packages/csp/CHANGELOG.md
index 94994f36b8..460d8e1287 100644
--- a/packages/csp/CHANGELOG.md
+++ b/packages/csp/CHANGELOG.md
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.3.45](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.44...@thi.ng/csp@0.3.45) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/csp
+
+
+## [0.3.44](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.43...@thi.ng/csp@0.3.44) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/csp
+
+
+## [0.3.43](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.42...@thi.ng/csp@0.3.43) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/csp
+
+
+## [0.3.42](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.41...@thi.ng/csp@0.3.42) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/csp
+
## [0.3.41](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.40...@thi.ng/csp@0.3.41) (2018-05-14)
diff --git a/packages/csp/package.json b/packages/csp/package.json
index 9feb830e1b..36e0c11d82 100644
--- a/packages/csp/package.json
+++ b/packages/csp/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/csp",
- "version": "0.3.41",
+ "version": "0.3.45",
"description": "ES6 promise based CSP implementation",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/csp",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -28,11 +32,11 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/dcons": "^1.0.2",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/dcons": "^1.0.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"async",
diff --git a/packages/dcons/CHANGELOG.md b/packages/dcons/CHANGELOG.md
index e76bd0a6d0..e4997a4552 100644
--- a/packages/dcons/CHANGELOG.md
+++ b/packages/dcons/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.0.4...@thi.ng/dcons@1.0.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dcons
+
+
+## [1.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.0.3...@thi.ng/dcons@1.0.4) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dcons
+
+
+## [1.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.0.2...@thi.ng/dcons@1.0.3) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dcons
+
## [1.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@1.0.1...@thi.ng/dcons@1.0.2) (2018-05-14)
diff --git a/packages/dcons/package.json b/packages/dcons/package.json
index 1e06757fc2..c11ddcf3be 100644
--- a/packages/dcons/package.json
+++ b/packages/dcons/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/dcons",
- "version": "1.0.2",
+ "version": "1.0.5",
"description": "Comprehensive doubly linked list structure w/ iterator support",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/dcons",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,11 +28,11 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/compare": "^0.1.2",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/compare": "^0.1.4",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"datastructure",
@@ -36,6 +40,7 @@
"ES6",
"iterators",
"linkedlist",
+ "list",
"queue",
"stack",
"typescript"
diff --git a/packages/defmulti/CHANGELOG.md b/packages/defmulti/CHANGELOG.md
index 1637ff6cb4..58dd8076dd 100644
--- a/packages/defmulti/CHANGELOG.md
+++ b/packages/defmulti/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.3.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@0.3.4...@thi.ng/defmulti@0.3.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/defmulti
+
+
+## [0.3.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@0.3.3...@thi.ng/defmulti@0.3.4) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/defmulti
+
## [0.3.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@0.3.2...@thi.ng/defmulti@0.3.3) (2018-05-14)
diff --git a/packages/defmulti/package.json b/packages/defmulti/package.json
index 89b10132d5..fa1ffe5c95 100644
--- a/packages/defmulti/package.json
+++ b/packages/defmulti/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/defmulti",
- "version": "0.3.3",
+ "version": "0.3.5",
"description": "Dynamically extensible multiple dispatch via user supplied dispatch function.",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/defmulti",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,8 +28,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"ES6",
diff --git a/packages/dgraph/CHANGELOG.md b/packages/dgraph/CHANGELOG.md
index 8dc1487548..b189365a50 100644
--- a/packages/dgraph/CHANGELOG.md
+++ b/packages/dgraph/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.2.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.7...@thi.ng/dgraph@0.2.8) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dgraph
+
+
+## [0.2.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.6...@thi.ng/dgraph@0.2.7) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dgraph
+
+
+## [0.2.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.5...@thi.ng/dgraph@0.2.6) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dgraph
+
## [0.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.2.4...@thi.ng/dgraph@0.2.5) (2018-05-14)
diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json
index 1804649da9..2512297c86 100644
--- a/packages/dgraph/package.json
+++ b/packages/dgraph/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/dgraph",
- "version": "0.2.5",
+ "version": "0.2.8",
"description": "Type-agnostic directed acyclic graph (DAG) & graph operations",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/dgraph",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,11 +28,11 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/associative": "^0.5.5",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/iterators": "^4.1.15"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/associative": "^0.5.8",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/iterators": "^4.1.18"
},
"keywords": [
"data structure",
diff --git a/packages/diff/CHANGELOG.md b/packages/diff/CHANGELOG.md
index 8b9f85cca2..fad4861c8a 100644
--- a/packages/diff/CHANGELOG.md
+++ b/packages/diff/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.0.19](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.0.18...@thi.ng/diff@1.0.19) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/diff
+
+
+## [1.0.18](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.0.17...@thi.ng/diff@1.0.18) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/diff
+
+
+## [1.0.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.0.16...@thi.ng/diff@1.0.17) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/diff
+
## [1.0.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.0.15...@thi.ng/diff@1.0.16) (2018-05-14)
diff --git a/packages/diff/package.json b/packages/diff/package.json
index 9d8f8ae5bf..b562bb7e9a 100644
--- a/packages/diff/package.json
+++ b/packages/diff/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/diff",
- "version": "1.0.16",
+ "version": "1.0.19",
"description": "Array & object Diff",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/diff",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -22,8 +26,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/equiv": "^0.1.2"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/equiv": "^0.1.5"
},
"keywords": [
"array",
diff --git a/packages/dot/CHANGELOG.md b/packages/dot/CHANGELOG.md
index b644f2561e..b7f5194b75 100644
--- a/packages/dot/CHANGELOG.md
+++ b/packages/dot/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@0.1.7...@thi.ng/dot@0.1.8) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dot
+
+
+## [0.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@0.1.6...@thi.ng/dot@0.1.7) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dot
+
+
+## [0.1.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@0.1.5...@thi.ng/dot@0.1.6) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/dot
+
## [0.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@0.1.4...@thi.ng/dot@0.1.5) (2018-05-14)
diff --git a/packages/dot/package.json b/packages/dot/package.json
index e610c60e9d..2ffd61f490 100644
--- a/packages/dot/package.json
+++ b/packages/dot/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/dot",
- "version": "0.1.5",
- "description": "TODO",
+ "version": "0.1.8",
+ "description": "Graphviz DOM abstraction as vanilla JS objects & serialization to DOT format",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/dot",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,8 +28,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5"
},
"keywords": [
"ES6",
diff --git a/packages/equiv/CHANGELOG.md b/packages/equiv/CHANGELOG.md
index 3e9ee8a75b..eece6af9dd 100644
--- a/packages/equiv/CHANGELOG.md
+++ b/packages/equiv/CHANGELOG.md
@@ -3,6 +3,30 @@
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/equiv@0.1.4...@thi.ng/equiv@0.1.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/equiv
+
+
+## [0.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/equiv@0.1.3...@thi.ng/equiv@0.1.4) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/equiv
+
+
+## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/equiv@0.1.2...@thi.ng/equiv@0.1.3) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/equiv
+
## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/equiv@0.1.1...@thi.ng/equiv@0.1.2) (2018-05-14)
diff --git a/packages/equiv/README.md b/packages/equiv/README.md
index f6fb73c171..bca552c97f 100644
--- a/packages/equiv/README.md
+++ b/packages/equiv/README.md
@@ -40,6 +40,39 @@ equiv({a: {b: [1, 2]}}, {a: {b: [1, 2]}});
// true
```
+### Implement IEquiv interface
+
+This is useful & required for custom types to take part in `equiv`
+checks, by default only plain objects & array are traversed deeply.
+
+Furthemore by implementing this interface we can better control which
+internal values / criteria are required to establish equivalence. In
+this example we exclude the `meta` property and only check for same type
+& `children` equality.
+
+```ts
+import { IEquiv } from "@thi.ng/api";
+import { equiv } from "@thi.ng/equiv";
+
+class Node implements IEquiv {
+
+ meta: any;
+ children: any[];
+
+ constructor(children: any[], meta?) {
+ this.children = children;
+ this.meta = meta;
+ }
+
+ equiv(o: any) {
+ return o instanceof Node && equiv(this.children, o.children);
+ }
+}
+
+equiv(new Node([1,2,3], "foo"), new Node([1,2,3], "bar"));
+// true
+```
+
## Authors
- Karsten Schmidt
diff --git a/packages/equiv/package.json b/packages/equiv/package.json
index 740650491b..58e1148a41 100644
--- a/packages/equiv/package.json
+++ b/packages/equiv/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/equiv",
- "version": "0.1.2",
+ "version": "0.1.5",
"description": "Extensible deep equivalence checking for any data types",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/equiv",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,7 +28,7 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/checks": "^1.5.3"
+ "@thi.ng/checks": "^1.5.5"
},
"keywords": [
"deep",
diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md
index 4aecca8f2d..cddd89c9ea 100644
--- a/packages/errors/CHANGELOG.md
+++ b/packages/errors/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.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/errors@0.1.3...@thi.ng/errors@0.1.4) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/errors
+
## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/errors@0.1.2...@thi.ng/errors@0.1.3) (2018-05-14)
diff --git a/packages/errors/package.json b/packages/errors/package.json
index c58f22fc85..cd858f1431 100644
--- a/packages/errors/package.json
+++ b/packages/errors/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/errors",
- "version": "0.1.3",
+ "version": "0.1.4",
"description": "Custom error types and helper fns.",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/errors",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
diff --git a/packages/hdom-components/CHANGELOG.md b/packages/hdom-components/CHANGELOG.md
index fbf49ece49..6db3b12c04 100644
--- a/packages/hdom-components/CHANGELOG.md
+++ b/packages/hdom-components/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [2.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.1.7...@thi.ng/hdom-components@2.1.8) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom-components
+
+
+## [2.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.1.6...@thi.ng/hdom-components@2.1.7) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom-components
+
+
+## [2.1.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.1.5...@thi.ng/hdom-components@2.1.6) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom-components
+
## [2.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.1.4...@thi.ng/hdom-components@2.1.5) (2018-05-14)
diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json
index 53061833c4..ff485ef6a2 100644
--- a/packages/hdom-components/package.json
+++ b/packages/hdom-components/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/hdom-components",
- "version": "2.1.5",
+ "version": "2.1.8",
"description": "Raw, skinnable UI & SVG components for @thi.ng/hdom",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/hdom-components",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,9 +28,9 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/iterators": "^4.1.15",
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/iterators": "^4.1.18",
"@types/webgl2": "^0.0.3"
},
"keywords": [
diff --git a/packages/hdom/CHANGELOG.md b/packages/hdom/CHANGELOG.md
index 1d478a5b76..d64a23749d 100644
--- a/packages/hdom/CHANGELOG.md
+++ b/packages/hdom/CHANGELOG.md
@@ -3,6 +3,49 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [3.0.26](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.25...@thi.ng/hdom@3.0.26) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom
+
+
+## [3.0.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.24...@thi.ng/hdom@3.0.25) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom
+
+
+## [3.0.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.23...@thi.ng/hdom@3.0.24) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom
+
+
+## [3.0.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.22...@thi.ng/hdom@3.0.23) (2018-05-15)
+
+
+### Bug Fixes
+
+* **hdom:** delay init() lifecycle call to ensure children are available ([2482b16](https://github.com/thi-ng/umbrella/commit/2482b16))
+
+
+
+
+
+## [3.0.22](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.21...@thi.ng/hdom@3.0.22) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hdom
+
## [3.0.21](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.20...@thi.ng/hdom@3.0.21) (2018-05-14)
diff --git a/packages/hdom/package.json b/packages/hdom/package.json
index be900090ae..898ff4eef2 100644
--- a/packages/hdom/package.json
+++ b/packages/hdom/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/hdom",
- "version": "3.0.21",
+ "version": "3.0.26",
"description": "Lightweight vanilla ES6 UI component & virtual DOM system",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/hdom",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -16,7 +20,7 @@
"test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js"
},
"devDependencies": {
- "@thi.ng/atom": "^1.3.12",
+ "@thi.ng/atom": "^1.4.2",
"@types/mocha": "^5.2.0",
"@types/node": "^10.0.6",
"mocha": "^5.1.1",
@@ -25,12 +29,12 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/diff": "^1.0.16",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/hiccup": "^2.0.1",
- "@thi.ng/iterators": "^4.1.15"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/diff": "^1.0.19",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/hiccup": "^2.0.5",
+ "@thi.ng/iterators": "^4.1.18"
},
"keywords": [
"browser",
diff --git a/packages/hdom/src/diff.ts b/packages/hdom/src/diff.ts
index 496768f4fc..3e46a533d6 100644
--- a/packages/hdom/src/diff.ts
+++ b/packages/hdom/src/diff.ts
@@ -56,10 +56,6 @@ function _diffElement(parent: Element, prev: any, curr: any, child: number) {
if ((i = prev.__release) && i !== curr.__release) {
releaseDeep(prev);
}
- if ((i = curr.__init) && i != prev.__init) {
- // DEBUG && console.log("call __init", curr);
- i.apply(curr, [el, ...(curr.__args)]);
- }
if (edits[1][0] !== 0) {
diffAttributes(el, prev[1], curr[1]);
}
@@ -109,6 +105,10 @@ function _diffElement(parent: Element, prev: any, curr: any, child: number) {
}
}
}
+ if ((i = curr.__init) && i != prev.__init) {
+ // DEBUG && console.log("call __init", curr);
+ i.apply(curr, [el, ...(curr.__args)]);
+ }
}
function releaseDeep(tag: any) {
diff --git a/packages/hdom/test/index.ts b/packages/hdom/test/index.ts
index 1a440c5d67..55e630f16e 100644
--- a/packages/hdom/test/index.ts
+++ b/packages/hdom/test/index.ts
@@ -111,18 +111,21 @@ describe("hdom", () => {
);
it("life cycle", () => {
+ let src: any = { render: () => ["div"] };
let res: any = ["div", {}];
+ res.__this = src;
res.__init = res.__release = undefined;
res.__args = [null];
assert.deepEqual(
- normalizeTree([{ render: () => ["div"] }], null, [], false, false),
+ normalizeTree([src], null, [], false, false),
res
);
res = ["div", { key: "0" }];
+ res.__this = src;
res.__init = res.__release = undefined;
res.__args = [null];
assert.deepEqual(
- normalizeTree([{ render: () => ["div"] }], null, [0], true, false),
+ normalizeTree([src], null, [0], true, false),
res
);
});
diff --git a/packages/heaps/CHANGELOG.md b/packages/heaps/CHANGELOG.md
index 314f0a074b..8f0b924c04 100644
--- a/packages/heaps/CHANGELOG.md
+++ b/packages/heaps/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.2.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.2.12...@thi.ng/heaps@0.2.13) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/heaps
+
+
+## [0.2.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.2.11...@thi.ng/heaps@0.2.12) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/heaps
+
## [0.2.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.2.10...@thi.ng/heaps@0.2.11) (2018-05-14)
diff --git a/packages/heaps/package.json b/packages/heaps/package.json
index 23e5927cf7..65d0c50058 100644
--- a/packages/heaps/package.json
+++ b/packages/heaps/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/heaps",
- "version": "0.2.11",
+ "version": "0.2.13",
"description": "Generic binary heap & d-ary heap implementations with customizable ordering",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/heaps",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,8 +28,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/compare": "^0.1.2"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/compare": "^0.1.4"
},
"keywords": [
"data structure",
diff --git a/packages/hiccup-css/CHANGELOG.md b/packages/hiccup-css/CHANGELOG.md
index 0d43a8e53f..db432a47f9 100644
--- a/packages/hiccup-css/CHANGELOG.md
+++ b/packages/hiccup-css/CHANGELOG.md
@@ -3,6 +3,50 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.2.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.2.2...@thi.ng/hiccup-css@0.2.3) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-css
+
+
+## [0.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.2.1...@thi.ng/hiccup-css@0.2.2) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-css
+
+
+## [0.2.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.2.0...@thi.ng/hiccup-css@0.2.1) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-css
+
+
+# [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.1.24...@thi.ng/hiccup-css@0.2.0) (2018-06-08)
+
+
+### Features
+
+* **hiccup-css:** add class scoping support ([244bf21](https://github.com/thi-ng/umbrella/commit/244bf21))
+* **hiccup-css:** add injectStyleSheet() ([8d6e6c8](https://github.com/thi-ng/umbrella/commit/8d6e6c8))
+
+
+
+
+
+## [0.1.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.1.23...@thi.ng/hiccup-css@0.1.24) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-css
+
## [0.1.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.1.22...@thi.ng/hiccup-css@0.1.23) (2018-05-14)
diff --git a/packages/hiccup-css/README.md b/packages/hiccup-css/README.md
index 563bbd1d35..66a4a6fd67 100644
--- a/packages/hiccup-css/README.md
+++ b/packages/hiccup-css/README.md
@@ -18,10 +18,12 @@ structures, functions, iterators.
- Uses JS object to define selector properties
- Multiple objects per scope are combined automatically
- Supports nested selectors and computes their cartesian products
+- Optional CSS class scoping
+- DOM stylesheet injection
- Configurable auto-prefixed properties & vendor prefixes (disabled by
default)
- Automatically consumes embedded iterators
-- Supports embeded functions, either:
+- Supports embedded functions, either:
- to define entire selector branches/scopes
- to produce single selector items
- to produce property values
@@ -158,7 +160,7 @@ css.css(
}
```
-### Iterator support
+### Iterators & CSS class scoping
```typescript
import * as tx from "@thi.ng/transducers";
@@ -176,40 +178,41 @@ css.css(
tx.mapcat(tx.juxt(prop(".w", "width"), prop(".h", "height"))),
tx.range(25, 101, 25)
),
- { format: css.PRETTY }
+ // supply a scope ID (suffix) for all class names
+ { format: css.PRETTY, scope: "_xyz" }
);
```
```css
-.w25 {
+.w25_xyz {
width: 25%;
}
-.h25 {
+.h25_xyz {
height: 25%;
}
-.w50 {
+.w50_xyz {
width: 50%;
}
-.h50 {
+.h50_xyz {
height: 50%;
}
-.w75 {
+.w75_xyz {
width: 75%;
}
-.h75 {
+.h75_xyz {
height: 75%;
}
-.w100 {
+.w100_xyz {
width: 100%;
}
-.h100 {
+.h100_xyz {
height: 100%;
}
```
@@ -390,6 +393,18 @@ css.css(
}
```
+### DOM stylesheet injection
+
+CSS strings can be installed into the DOM `` element via `injectStyleSheet()`:
+
+```ts
+css.injectStyleSheet(
+ css.css([
+ "body", { background: "#000", color: "#fff" }
+ ])
+);
+```
+
### General function handling
**Functions are handled differently based on their position in the rule
diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json
index e68dda6c63..f2d4aa488e 100644
--- a/packages/hiccup-css/package.json
+++ b/packages/hiccup-css/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/hiccup-css",
- "version": "0.1.23",
+ "version": "0.2.3",
"description": "CSS from nested JS data structures",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-css",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,10 +28,10 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"clojure",
diff --git a/packages/hiccup-css/src/api.ts b/packages/hiccup-css/src/api.ts
index 44c3f92a87..c604a121a3 100644
--- a/packages/hiccup-css/src/api.ts
+++ b/packages/hiccup-css/src/api.ts
@@ -62,6 +62,10 @@ export interface CSSOpts {
* Current tree depth. Internal use only. Ignore.
*/
depth: number;
+ /**
+ * Optional scoping suffix for CSS classes
+ */
+ scope: string;
}
export const DEFAULT_VENDORS = [
diff --git a/packages/hiccup-css/src/impl.ts b/packages/hiccup-css/src/impl.ts
index 591ca499fe..02766d4398 100644
--- a/packages/hiccup-css/src/impl.ts
+++ b/packages/hiccup-css/src/impl.ts
@@ -4,6 +4,8 @@ import { isIterable } from "@thi.ng/checks/is-iterable";
import { isPlainObject } from "@thi.ng/checks/is-plain-object";
import { isString } from "@thi.ng/checks/is-string";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
+import { Transducer } from "@thi.ng/transducers/api";
+import { comp } from "@thi.ng/transducers/func/comp";
import { permutations } from "@thi.ng/transducers/iter/permutations";
import { repeat } from "@thi.ng/transducers/iter/repeat";
import { str } from "@thi.ng/transducers/rfn/str";
@@ -17,12 +19,14 @@ const EMPTY = new Set();
const NO_SPACES = ":[";
-// like tx.comp(), but avoiding import to save space
-const xfSel = ((a, b) => (x) => a(b(x)))(
+const xfSel = comp(
flatten(),
map((x: string) => NO_SPACES.indexOf(x.charAt(0)) >= 0 ? x : " " + x)
);
+const withScope = (xf: Transducer, scope: string) =>
+ comp(xf, map((x) => isString(x) && x.indexOf(" .") == 0 ? x + scope : x));
+
export function expand(acc: string[], parent: any[], rules: any[], opts: CSSOpts) {
const n = rules.length;
const sel: string[] = [];
@@ -34,7 +38,7 @@ export function expand(acc: string[], parent: any[], rules: any[], opts: CSSOpts
} else if (isIterable(r) && !isString(r)) {
expand(acc, makeSelector(parent, sel), [...r], opts);
} else if ((isFn = isFunction(r)) || opts.fns[r]) {
- if (i === 0) {
+ if (!parent.length) {
if (opts.fns[r]) {
opts.fns[r].apply(null, rules.slice(i + 1))(acc, opts);
return true;
@@ -64,16 +68,19 @@ export function expand(acc: string[], parent: any[], rules: any[], opts: CSSOpts
}
function makeSelector(parent: any[], curr: any[]) {
- return parent.length ? [...permutations(parent, curr)] : curr;
+ return parent.length ?
+ [...permutations(parent, curr)] :
+ curr;
}
function formatRule(parent: any[], sel: any[], curr: any, opts: CSSOpts) {
const f = opts.format;
const space = indent(opts);
+ const xf = opts.scope ? withScope(xfSel, opts.scope) : xfSel;
return [
space,
transduce(
- map((sel: any[]) => transduce(xfSel, str(), isArray(sel) ? sel : [sel]).trim()),
+ map((sel: any[]) => transduce(xf, str(), isArray(sel) ? sel : [sel]).trim()),
str(f.ruleSep),
makeSelector(parent, sel)),
f.declStart,
diff --git a/packages/hiccup-css/src/index.ts b/packages/hiccup-css/src/index.ts
index 67ffae1c6e..3468f7b9a1 100644
--- a/packages/hiccup-css/src/index.ts
+++ b/packages/hiccup-css/src/index.ts
@@ -4,6 +4,7 @@ export * from "./comment";
export * from "./conditional";
export * from "./css";
export * from "./import";
+export * from "./inject";
export * from "./keyframes";
export * from "./media";
export * from "./namespace";
diff --git a/packages/hiccup-css/src/inject.ts b/packages/hiccup-css/src/inject.ts
new file mode 100644
index 0000000000..b2cbdc4940
--- /dev/null
+++ b/packages/hiccup-css/src/inject.ts
@@ -0,0 +1,27 @@
+// https://davidwalsh.name/add-rules-stylesheets
+
+/**
+ * Injects given CSS string as global stylesheet in DOM head. If `first`
+ * is true, inserts it as first stylesheet, else (default) appends it.
+ *
+ * Returns created style DOM element.
+ *
+ * @param css
+ * @param first
+ */
+export const injectStyleSheet = (css: string, first = false) => {
+ const head = document.getElementsByTagName("head")[0];
+ const sheet = document.createElement("style");
+ sheet.setAttribute("type", "text/css");
+ if ((sheet).styleSheet !== undefined) {
+ (sheet).styleSheet.cssText = css;
+ } else {
+ sheet.textContent = css;
+ }
+ if (first) {
+ head.insertBefore(sheet, head.firstChild);
+ } else {
+ head.appendChild(sheet);
+ }
+ return sheet;
+};
diff --git a/packages/hiccup-svg/CHANGELOG.md b/packages/hiccup-svg/CHANGELOG.md
index 2d2181ace8..f3a5f6e1a9 100644
--- a/packages/hiccup-svg/CHANGELOG.md
+++ b/packages/hiccup-svg/CHANGELOG.md
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@1.0.4...@thi.ng/hiccup-svg@1.0.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-svg
+
+
+## [1.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@1.0.3...@thi.ng/hiccup-svg@1.0.4) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-svg
+
+
+## [1.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@1.0.2...@thi.ng/hiccup-svg@1.0.3) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-svg
+
+
+## [1.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@1.0.1...@thi.ng/hiccup-svg@1.0.2) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup-svg
+
## [1.0.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@1.0.0...@thi.ng/hiccup-svg@1.0.1) (2018-05-14)
diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json
index 0d63f020fd..36e355af77 100644
--- a/packages/hiccup-svg/package.json
+++ b/packages/hiccup-svg/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/hiccup-svg",
- "version": "1.0.1",
+ "version": "1.0.5",
"description": "SVG element functions for @thi.ng/hiccup & @thi.ng/hdom",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-svg",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,7 +28,7 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/hiccup": "^2.0.1"
+ "@thi.ng/hiccup": "^2.0.5"
},
"keywords": [
"components",
diff --git a/packages/hiccup/CHANGELOG.md b/packages/hiccup/CHANGELOG.md
index 369414746c..bb61d95af7 100644
--- a/packages/hiccup/CHANGELOG.md
+++ b/packages/hiccup/CHANGELOG.md
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [2.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.0.4...@thi.ng/hiccup@2.0.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup
+
+
+## [2.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.0.3...@thi.ng/hiccup@2.0.4) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup
+
+
+## [2.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.0.2...@thi.ng/hiccup@2.0.3) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup
+
+
+## [2.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.0.1...@thi.ng/hiccup@2.0.2) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/hiccup
+
## [2.0.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@2.0.0...@thi.ng/hiccup@2.0.1) (2018-05-14)
diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json
index 85fc6e3ff0..4ab7e21972 100644
--- a/packages/hiccup/package.json
+++ b/packages/hiccup/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/hiccup",
- "version": "2.0.1",
+ "version": "2.0.5",
"description": "HTML/SVG/XML serialization of nested data structures, iterables & closures",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/hiccup",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -16,7 +20,7 @@
"test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js"
},
"devDependencies": {
- "@thi.ng/atom": "^1.3.12",
+ "@thi.ng/atom": "^1.4.2",
"@types/mocha": "^5.2.0",
"@types/node": "^10.0.6",
"mocha": "^5.1.1",
@@ -25,8 +29,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"clojure",
diff --git a/packages/interceptors/CHANGELOG.md b/packages/interceptors/CHANGELOG.md
index 8779f00b28..99bf1a63ee 100644
--- a/packages/interceptors/CHANGELOG.md
+++ b/packages/interceptors/CHANGELOG.md
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.8.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.8.4...@thi.ng/interceptors@1.8.5) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/interceptors
+
+
+## [1.8.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.8.3...@thi.ng/interceptors@1.8.4) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/interceptors
+
+
+## [1.8.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.8.2...@thi.ng/interceptors@1.8.3) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/interceptors
+
+
+## [1.8.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.8.1...@thi.ng/interceptors@1.8.2) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/interceptors
+
## [1.8.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.8.0...@thi.ng/interceptors@1.8.1) (2018-05-14)
diff --git a/packages/interceptors/package.json b/packages/interceptors/package.json
index 8a6a4bc54c..b275e0adbc 100644
--- a/packages/interceptors/package.json
+++ b/packages/interceptors/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/interceptors",
- "version": "1.8.1",
+ "version": "1.8.5",
"description": "Interceptor based event bus, side effect & immutable state handling",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/interceptors",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,11 +28,11 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/atom": "^1.3.12",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/paths": "^1.3.8"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/atom": "^1.4.2",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/paths": "^1.3.10"
},
"keywords": [
"ES6",
diff --git a/packages/iterators/CHANGELOG.md b/packages/iterators/CHANGELOG.md
index 55f883e730..8b4c629542 100644
--- a/packages/iterators/CHANGELOG.md
+++ b/packages/iterators/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [4.1.18](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.17...@thi.ng/iterators@4.1.18) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/iterators
+
+
+## [4.1.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.16...@thi.ng/iterators@4.1.17) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/iterators
+
+
+## [4.1.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.15...@thi.ng/iterators@4.1.16) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/iterators
+
## [4.1.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.14...@thi.ng/iterators@4.1.15) (2018-05-14)
diff --git a/packages/iterators/package.json b/packages/iterators/package.json
index ff82da5366..4389886040 100644
--- a/packages/iterators/package.json
+++ b/packages/iterators/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/iterators",
- "version": "4.1.15",
+ "version": "4.1.18",
"description": "clojure.core inspired, composable ES6 iterators & generators",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/iterators",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,9 +28,9 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/dcons": "^1.0.2",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/dcons": "^1.0.5",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"clojure",
diff --git a/packages/paths/CHANGELOG.md b/packages/paths/CHANGELOG.md
index 944a3cdad0..ef99e390be 100644
--- a/packages/paths/CHANGELOG.md
+++ b/packages/paths/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.
+
+## [1.3.10](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.3.9...@thi.ng/paths@1.3.10) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/paths
+
+
+## [1.3.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.3.8...@thi.ng/paths@1.3.9) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/paths
+
## [1.3.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.3.7...@thi.ng/paths@1.3.8) (2018-05-14)
diff --git a/packages/paths/package.json b/packages/paths/package.json
index 2abc40430e..1974edc056 100644
--- a/packages/paths/package.json
+++ b/packages/paths/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/paths",
- "version": "1.3.8",
+ "version": "1.3.10",
"description": "immutable, optimized path-based object property / array accessors",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/paths",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,8 +28,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"accessors",
diff --git a/packages/pointfree-lang/CHANGELOG.md b/packages/pointfree-lang/CHANGELOG.md
index 84a4259479..68a37d1fac 100644
--- a/packages/pointfree-lang/CHANGELOG.md
+++ b/packages/pointfree-lang/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.2.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.14...@thi.ng/pointfree-lang@0.2.15) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/pointfree-lang
+
+
+## [0.2.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.13...@thi.ng/pointfree-lang@0.2.14) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/pointfree-lang
+
+
+## [0.2.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.12...@thi.ng/pointfree-lang@0.2.13) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/pointfree-lang
+
## [0.2.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.11...@thi.ng/pointfree-lang@0.2.12) (2018-05-14)
diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json
index e406e72db0..71482737d6 100644
--- a/packages/pointfree-lang/package.json
+++ b/packages/pointfree-lang/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/pointfree-lang",
- "version": "0.2.12",
+ "version": "0.2.15",
"description": "Forth style syntax layer/compiler for the @thi.ng/pointfree DSL",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/pointfree-lang",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -26,9 +30,9 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/pointfree": "^0.8.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/pointfree": "^0.8.4"
},
"keywords": [
"concatenative",
diff --git a/packages/pointfree/CHANGELOG.md b/packages/pointfree/CHANGELOG.md
index d4132a0f3a..424ca22d1d 100644
--- a/packages/pointfree/CHANGELOG.md
+++ b/packages/pointfree/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.8.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.8.3...@thi.ng/pointfree@0.8.4) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/pointfree
+
+
+## [0.8.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.8.2...@thi.ng/pointfree@0.8.3) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/pointfree
+
+
+## [0.8.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.8.1...@thi.ng/pointfree@0.8.2) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/pointfree
+
## [0.8.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.8.0...@thi.ng/pointfree@0.8.1) (2018-05-14)
diff --git a/packages/pointfree/package.json b/packages/pointfree/package.json
index a89e1af012..0dd7a77c04 100644
--- a/packages/pointfree/package.json
+++ b/packages/pointfree/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/pointfree",
- "version": "0.8.1",
+ "version": "0.8.4",
"description": "Pointfree functional composition / Forth style stack execution engine",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/pointfree",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,10 +28,10 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"composition",
diff --git a/packages/resolve-map/CHANGELOG.md b/packages/resolve-map/CHANGELOG.md
index a5176bc1a6..160d8fde2b 100644
--- a/packages/resolve-map/CHANGELOG.md
+++ b/packages/resolve-map/CHANGELOG.md
@@ -3,7 +3,52 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
-
+
+## [3.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@3.0.1...@thi.ng/resolve-map@3.0.2) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/resolve-map
+
+
+## [3.0.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@3.0.0...@thi.ng/resolve-map@3.0.1) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/resolve-map
+
+
+# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@2.0.6...@thi.ng/resolve-map@3.0.0) (2018-06-07)
+
+
+### Features
+
+* **resolve-map:** add cycle detection, fix edge cases ([e61c3b5](https://github.com/thi-ng/umbrella/commit/e61c3b5))
+* **resolve-map:** add ES6 destructuring shorthands for function vals ([57f1ed5](https://github.com/thi-ng/umbrella/commit/57f1ed5))
+
+
+### BREAKING CHANGES
+
+* **resolve-map:** `resolveMap()` renamed to `resolve()`, update docs
+
+
+
+
+
+## [2.0.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@2.0.5...@thi.ng/resolve-map@2.0.6) (2018-06-06)
+
+
+### Bug Fixes
+
+* **resolve-map:** add private _resolveDeep ([558f4f8](https://github.com/thi-ng/umbrella/commit/558f4f8))
+* **resolve-map:** also use _resolvePath for plain lookups, optimize ([48c796f](https://github.com/thi-ng/umbrella/commit/48c796f))
+
+
+
+
+
## [2.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@2.0.4...@thi.ng/resolve-map@2.0.5) (2018-05-14)
@@ -11,7 +56,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
**Note:** Version bump only for package @thi.ng/resolve-map
-
+
## [2.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@2.0.3...@thi.ng/resolve-map@2.0.4) (2018-05-14)
diff --git a/packages/resolve-map/README.md b/packages/resolve-map/README.md
index 27381be083..fae5816cd9 100644
--- a/packages/resolve-map/README.md
+++ b/packages/resolve-map/README.md
@@ -12,6 +12,8 @@ values. This is useful for expressing complex configurations with
derived values or computing interrelated values without having to
specify the order of computations.
+**TL;DR go check out [the examples](#usage-examples)**
+
It's common practice to use nested JS objects for configuration
purposes. Frequently some values in the object are copies or derivatives
of other values, which can lead to mistakes during refactoring and / or
@@ -25,47 +27,74 @@ supported.
## API
-### `resolveMap(obj)`
+### `resolve(obj)`
+
+Visits all key-value pairs or array items in depth-first order,
+expands any reference values, mutates the original object and returns
+it. Cyclic references are not allowed and will throw an error.
+However, refs pointing to other refs are recursively resolved (again,
+provided there are no cycles).
+Reference values are special strings representing lookup paths of
+other values in the object and are prefixed with `@` for relative
+refs or `@/` for absolute refs and both using `/` as path separator
+(Note: trailing slashes are NOT allowed!). Relative refs are resolved
+from the currently visited object and support "../" prefixes to
+access any parent levels. Absolute refs are always resolved from the
+root level (the original object passed to this function).
+
+```ts
+// `c` references sibling `d`
+// `d` references parent `a`
+resolve({a: 1, b: {c: "@d", d: "@/a"} })
+// { a: 1, b: { c: 1, d: 1 } }
+```
+
+Any function values are called using two possible conventions:
+
+1) If the user function uses ES6 object destructuring for its first
+ argument, the given object keys are resolved prior to calling the
+ function and the resolved values provided as first argument (object)
+ and a general `resolve` function as second argument.
+2) If no de-structure form is found in the function's arguments, the
+ function is only called with `resolve` as argument.
-Visits all key-value pairs in depth-first order for given object or
-array, expands any reference values, mutates the original object and
-returns it. Cyclic references are not allowed or checked for and if
-present will cause a stack overflow error. However, refs pointing to
-other refs are recursively resolved (again, provided there are no
-cycles).
+**Important:** Since ES6 var names can't contain special characters,
+destructured keys can ALWAYS only be looked up as siblings of the
+currently processed key.
-Reference values are special strings representing lookup paths of other
-values in the object and are prefixed with `@` for relative refs or
-`@/` for absolute refs and both using `/` as path separator (Note:
-trailing slashes are NOT allowed!). Relative refs are resolved from
-currently visited object and support "../" prefixes to access any parent
-levels. Absolute refs are always resolved from the root level (the
-original object passed to this function).
+The `resolve` function provided as arg to the user function accepts a
+path (**without `@` prefix**) to look up any other values in the root
+object.
```ts
-resolveMap({a: 1, b: {c: "@d", d: "@/a"} })
-// { a: 1, b: { c: 1, d: 1 } }
+// `c` uses ES6 destructuring form to look up `a` & `b` values
+// `d` uses provided resolve fn arg `$` to look up `c`
+resolve({a: 1, b: 2, c: ({a,b}) => a + b, d: ($) => $("c") })
+// { a: 1, b: 2, c: 3, d: 3 }
+
+// last item references item @ index = 2
+resolve([1,2, ($) => $("0") + $("1"), "@2"])
+// [1, 2, 3, 3]
```
-If a value is a function, it is called with a single arg `resolve`, a
-function which accepts a path (**without `@` prefix**) to look up other
-values. The return value of the user provided function is used as final
-value for that key. This mechanism can be used to compute derived values
-of other values stored anywhere in the root object. **Function values
-will always be called only once.** Therefore, in order to associate a
-function as value to a key, it needs to be wrapped with an additional
-function, as shown for the `e` key in the example below. Similarly, if
-an actual string value should happen to start with `@`, it needs to be
-wrapped in a function (see `f` key below).
+The return value of the user provided function is used as final value
+for that key in the object. This mechanism can be used to compute
+derived values of other values stored anywhere in the root object.
+**Function values will always be called only once.** Therefore, in order
+to associate a function as final value to a key, it MUST be wrapped with
+an additional function, as shown for the `e` key in the example below.
+Similarly, if an actual string value should happen to start with `@`, it
+needs to be wrapped in a function (see `f` key below).
```ts
// `a` is derived from 1st array element in `b.d`
// `b.c` is looked up from `b.d[0]`
// `b.d[1]` is derived from calling `e(2)`
// `e` is a wrapped function
-res = resolveMap({
- a: (resolve) => resolve("b/c") * 100,
- b: { c: "@d/0", d: [2, (resolve) => resolve("../../e")(2) ] },
+// `f` is wrapped to ignore `@` prefix
+res = resolve({
+ a: ($) => $("b/c") * 100,
+ b: { c: "@d/0", d: [2, ($) => $("../../e")(2) ] },
e: () => (x) => x * 10,
f: () => "@foo",
})
@@ -94,40 +123,34 @@ yarn add @thi.ng/resolve-map
In this example we construct a graph to compute a number of statistical
properties for some numeric input array. The graph is a plain object of
possibly dependent functions, which can be specified in any order. Each
-function accepts a "resolver" function as argument (`$`) to look up and
-execute other computations. Each computation is only executed once.
+function uses ES6 object destructuring to look up and execute other
+computations in the graph. Each computation is only executed once.
```ts
-import { resolveMap } from "@thi.ng/resolve-map";
+import { resolve } from "@thi.ng/resolve-map";
import * as tx from "@thi.ng/transducers";
-// define object of interrelated computations
-// the `$` arg passed to each fn is the resolver
-// the `src` key is still missing here and will be
-// provided later
+// define object of interrelated computations to be executed later
+// the `src` key used by most functions is still missing here and
+// will be injected later as well
const stats = {
// sequence average
- mean: ($) => tx.reduce(tx.mean(), $("src")),
+ mean: ({src}) => tx.reduce(tx.mean(), src),
// sequence range
- range: ($) => $("max") - $("min"),
+ range: ({min,max}) => max - min,
// computes sequence min val
- min: ($) => tx.reduce(tx.min(), $("src")),
+ min: ({src}) => tx.reduce(tx.min(), src),
// computes sequence max val
- max: ($) => tx.reduce(tx.max(), $("src")),
+ max: ({src}) => tx.reduce(tx.max(), src),
// sorted copy
- sorted: ($) => [...$("src")].sort((a, b) => a - b),
+ sorted: ({src}) => [...src].sort((a, b) => a - b),
// standard deviation
- sd: ($)=> {
- const src = $("src");
- const mean = $("mean");
- return Math.sqrt(
+ sd: ({src, mean})=>
+ Math.sqrt(
tx.transduce(tx.map((x) => Math.pow(x - mean, 2)), tx.add(), src) /
- (src.length - 1)
- );
- },
+ (src.length - 1)),
// compute 10th - 90th percentiles
- percentiles: ($) => {
- const sorted = $("sorted");
+ percentiles: ({sorted}) => {
return tx.transduce(
tx.map((x) => sorted[Math.floor(x / 100 * sorted.length)]),
tx.push(),
@@ -138,15 +161,15 @@ const stats = {
// inject some source data to analyze
-// Note: we wrap the data as function to avoid `resolveMap`
+// Note: we wrap the data as function to avoid `resolve`
// attempting to resolve each array item as well. this is
// purely for performance reasons and would also work without
// wrapping.
// Note 2: If the `stats` graph is meant to be re-usable in
// the future you MUST use the spread operator to create a
-// shallow copy, because `resolveMap` mutates the given object
-resolveMap({...stats, src: () => [ 1, 6, 7, 2, 4, 11, -3 ]})
+// shallow copy, because `resolve` mutates the given object
+resolve({...stats, src: () => [ 1, 6, 7, 2, 4, 11, -3 ]})
// {
// mean: 4,
// range: 14,
@@ -162,9 +185,9 @@ resolveMap({...stats, src: () => [ 1, 6, 7, 2, 4, 11, -3 ]})
### Theme configuration
```typescript
-import { resolveMap } from "@thi.ng/resolve-map";
+import { resolve } from "@thi.ng/resolve-map";
-resolveMap({
+resolve({
colors: {
bg: "white",
text: "black",
@@ -177,13 +200,13 @@ resolveMap({
bg: "@/colors/text",
label: "@/colors/bg",
// resolve with abs path inside fn
- fontsize: (resolve) => `${resolve("/main/fontsizes/0")}px`,
+ fontsize: ($) => `${$("/main/fontsizes/0")}px`,
},
buttonPrimary: {
bg: "@/colors/selected",
label: "@/button/label",
// resolve with relative path inside fn
- fontsize: (resolve) => `${resolve("../main/fontsizes/2")}px`,
+ fontsize: ($) => `${$("../main/fontsizes/2")}px`,
}
});
// {
diff --git a/packages/resolve-map/package.json b/packages/resolve-map/package.json
index 9c1c6e365b..b819cd5cac 100644
--- a/packages/resolve-map/package.json
+++ b/packages/resolve-map/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/resolve-map",
- "version": "2.0.5",
+ "version": "3.0.2",
"description": "DAG resolution of vanilla objects & arrays with internally linked values",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/resolve-map",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -22,9 +26,9 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/paths": "^1.3.8"
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/paths": "^1.3.10"
},
"keywords": [
"configuration",
diff --git a/packages/resolve-map/src/index.ts b/packages/resolve-map/src/index.ts
index cb5b4eadbb..72b81846d2 100644
--- a/packages/resolve-map/src/index.ts
+++ b/packages/resolve-map/src/index.ts
@@ -7,47 +7,80 @@ import { getIn, mutIn } from "@thi.ng/paths";
const SEMAPHORE = Symbol("SEMAPHORE");
+const RE_ARGS = /^(function\s+\w+)?\s*\(\{([\w\s,]+)\}/
+
+export type ResolveFn = (path: string) => any;
+
+export type LookupPath = PropertyKey[];
+
/**
- * Visits all key-value pairs in depth-first order for given object or
- * array, expands any reference values, mutates the original object and
- * returns it. Cyclic references are not allowed or checked for and if
- * present will cause a stack overflow error. However, refs pointing to
- * other refs are recursively resolved (again, provided there are no
- * cycles).
+ * Visits all key-value pairs or array items in depth-first order,
+ * expands any reference values, mutates the original object and returns
+ * it. Cyclic references are not allowed and will throw an error.
+ * However, refs pointing to other refs are recursively resolved (again,
+ * provided there are no cycles).
*
* Reference values are special strings representing lookup paths of
* other values in the object and are prefixed with `@` for relative
* refs or `@/` for absolute refs and both using `/` as path separator
* (Note: trailing slashes are NOT allowed!). Relative refs are resolved
- * from currently visited object and support "../" prefixes to access
- * any parent levels. Absolute refs are always resolved from the root
- * level (the original object passed to this function).
+ * from the currently visited object and support "../" prefixes to
+ * access any parent levels. Absolute refs are always resolved from the
+ * root level (the original object passed to this function).
*
* ```ts
- * resolveMap({a: 1, b: {c: "@d", d: "@/a"} })
+ * // `c` references sibling `d`
+ * // `d` references parent `a`
+ * resolve({a: 1, b: {c: "@d", d: "@/a"} })
* // { a: 1, b: { c: 1, d: 1 } }
* ```
*
- * If a value is a function, it is called with a single arg `resolve`, a
- * function which accepts a path (**without `@` prefix**) to look up
- * other values. The return value of the user provided function is used
- * as final value for that key. This mechanism can be used to compute
+ * Any function values are called using two possible conventions:
+ *
+ * 1) If the user function uses ES6 object destructuring for its first
+ * argument, the given object keys are resolved prior to calling the
+ * function and the resolved values provided as first argument
+ * (object) and a general `resolve` function as second argument.
+ * 2) If no de-structure form is found in the function's arguments, the
+ * function is only called with `resolve` as argument.
+ *
+ * **Important:** Since ES6 var names can't contain special characters,
+ * destructured keys can ALWAYS only be looked up as siblings of the
+ * currently processed key.
+ *
+ * The `resolve` function provided as arg to the user function accepts a
+ * path (**without `@` prefix**) to look up any other values in the root
+ * object.
+ *
+ * ```
+ * // `c` uses ES6 destructuring form to look up `a` & `b` values
+ * // `d` uses provided resolve fn arg `$` to look up `c`
+ * resolve({a: 1, b: 2, c: ({a,b}) => a + b, d: ($) => $("c") })
+ * // { a: 1, b: 2, c: 3, d: 3 }
+ *
+ * // last item references item @ index = 2
+ * resolve([1,2, ($) => $("0") + $("1"), "@2"])
+ * // [1, 2, 3, 3]
+ * ```
+ *
+ * The return value of the user provided function is used as final value
+ * for that key in the object. This mechanism can be used to compute
* derived values of other values stored anywhere in the root object.
* **Function values will always be called only once.** Therefore, in
- * order to associate a function as value to a key, it needs to be
+ * order to associate a function as final value to a key, it MUST be
* wrapped with an additional function, as shown for the `e` key in the
* example below. Similarly, if an actual string value should happen to
* start with `@`, it needs to be wrapped in a function (see `f` key
* below).
*
- * ```ts
+ * ```
* // `a` is derived from 1st array element in `b.d`
* // `b.c` is looked up from `b.d[0]`
* // `b.d[1]` is derived from calling `e(2)`
* // `e` is a wrapped function
- * res = resolveMap({
- * a: (resolve) => resolve("b/c") * 100,
- * b: { c: "@d/0", d: [2, (resolve) => resolve("../../e")(2) ] },
+ * res = resolve({
+ * a: ($) => $("b/c") * 100,
+ * b: { c: "@d/0", d: [2, ($) => $("../../e")(2) ] },
* e: () => (x) => x * 10,
* f: () => "@foo",
* })
@@ -57,72 +90,188 @@ const SEMAPHORE = Symbol("SEMAPHORE");
* // 20
* ```
*
- * `resolveMap` mutates the original object and returns it. User code
- * should NEVER provide any of the optional args (these are only used
- * for internal recursion purposes).
- *
- * @param obj
+ * @param root
*/
-export const resolveMap = (obj: any, root?: any, path: PropertyKey[] = [], resolved: any = {}) => {
+export const resolve = (root: any) => {
+ if (isPlainObject(root)) {
+ return resolveMap(root);
+ } else if (isArray(root)) {
+ return resolveArray(root);
+ }
+ return root;
+};
+
+const resolveMap = (obj: any, root?: any, path: LookupPath = [], resolved: any = {}, stack: string[] = []) => {
root = root || obj;
for (let k in obj) {
- _resolve(root, [...path, k], resolved);
+ _resolve(root, [...path, k], resolved, stack);
}
return obj;
-}
+};
+
+const resolveArray = (arr: any[], root?: any, path: LookupPath = [], resolved: any = {}, stack: string[] = []) => {
+ root = root || arr;
+ for (let k = 0, n = arr.length; k < n; k++) {
+ _resolve(root, [...path, k], resolved, stack);
+ }
+ return arr;
+};
/**
- * Like `resolveMap`, but for arrays.
+ * The actual recursive resolution mechanism. Takes root object, key
+ * path, helper object for marking visited keys and a stack of currently
+ * active lookups. The latter is used for cycle detection and `_resolve`
+ * will throw an error if a cycle has been detected.
*
- * @param arr
* @param root
* @param path
* @param resolved
+ * @param stack
*/
-const resolveArray = (arr: any[], root?: any, path: PropertyKey[] = [], resolved: any = {}) => {
- root = root || arr;
- for (let k = 0, n = arr.length; k < n; k++) {
- _resolve(root, [...path, k], resolved);
+const _resolve = (root: any, path: LookupPath, resolved: any, stack: string[]) => {
+ const pathID = path.join("/");
+ if (stack.indexOf(pathID) >= 0) {
+ illegalArgs(`cyclic references not allowed: ${pathID}`);
}
- return arr;
-}
-
-const _resolve = (root: any, path: PropertyKey[], resolved: any) => {
- let v = getIn(root, path), rv = SEMAPHORE;
- const pp = path.join("/");
- if (!resolved[pp]) {
- if (isString(v) && v.charAt(0) === "@") {
- rv = _resolve(root, absPath(path, v), resolved);
- } else if (isPlainObject(v)) {
- resolveMap(v, root, path, resolved);
+ // console.log(pp, resolved[pp], stack);
+ let v = getIn(root, path);
+ if (!resolved[pathID]) {
+ let res = SEMAPHORE;
+ stack.push(pathID);
+ if (isPlainObject(v)) {
+ resolveMap(v, root, path, resolved, stack);
} else if (isArray(v)) {
- resolveArray(v, root, path, resolved);
+ resolveArray(v, root, path, resolved, stack);
+ } else if (isString(v) && v.charAt(0) === "@") {
+ res = _resolve(root, absPath(path, v), resolved, stack);
} else if (isFunction(v)) {
- rv = v((p: string) => _resolve(root, absPath(path, p, 0), resolved));
+ res = resolveFunction(v, (p: string) => _resolve(root, absPath(path, p, 0), resolved, stack), pathID, resolved);
+ } else if (v === undefined) {
+ v = resolvePath(root, path, resolved, stack);
}
- if (rv !== SEMAPHORE) {
- mutIn(root, path, rv);
- v = rv;
+ if (res !== SEMAPHORE) {
+ mutIn(root, path, res);
+ v = res;
}
- resolved[pp] = true;
+ resolved[pathID] = true;
+ stack.pop();
}
return v;
-}
+};
-const absPath = (curr: PropertyKey[], q: string, idx = 1): PropertyKey[] => {
- if (q.charAt(idx) === "/") {
- return q.substr(idx + 1).split("/");
+/**
+ * Repeatedly calls `_resolve` by stepwise descending along given path
+ * and returns final value. This is to ensure full resolution of deeper
+ * values created by functions at intermediate tree levels.
+ *
+ * E.g. given:
+ *
+ * ```
+ * {a: () => ({b: {c: 1}}), d: "@/a/b/c" }
+ * =>
+ * { a: { b: { c: 1 } }, d: 1 }
+ * ```
+ *
+ * @param root
+ * @param path
+ * @param resolved
+ */
+const resolvePath = (root: any, path: LookupPath, resolved: any, stack: string[] = []) => {
+ // temporarily remove current path to avoid cycle detection
+ let pathID = stack.pop()
+ let v;
+ for (let i = 1, n = path.length; i <= n; i++) {
+ v = _resolve(root, path.slice(0, i), resolved, stack);
+ }
+ // restore
+ stack.push(pathID);
+ return v;
+};
+
+/**
+ * Resolution helper for function values. Checks if the user function
+ * uses ES6 object destructuring for its first argument and if so
+ * resolves the given keys before calling the function and provides
+ * their values as first arg. If no de-structure form is found, calls
+ * function only with `resolve` as argument.
+ *
+ * If the user function returns an array or plain object, all of its
+ * nested values are marked as resolved.
+ *
+ * See `resolve` comments for further details.
+ *
+ * @param fn
+ * @param resolve
+ * @param pathID current base path for marking
+ * @param resolved
+ */
+const resolveFunction = (fn: (x: any, r?: ResolveFn) => any, resolve: ResolveFn, pathID: string, resolved: any) => {
+ const match = RE_ARGS.exec(fn.toString());
+ let res;
+ if (match) {
+ const args = match[2]
+ .replace(/\s/g, "")
+ .split(/,/g)
+ .reduce((acc, k) => (acc[k] = resolve(k), acc), {});
+ res = fn(args, resolve);
+ } else {
+ res = fn(resolve);
+
+ }
+ markResolved(res, pathID, resolved);
+ return res;
+};
+
+const markResolved = (v: any, path: string, resolved: any) => {
+ resolved[path] = true;
+ if (isPlainObject(v)) {
+ markObjResolved(v, path, resolved);
+ }
+ else if (isArray(v)) {
+ markArrayResolved(v, path, resolved);
+ }
+};
+
+const markObjResolved = (obj: any, path: string, resolved: any) => {
+ let v, p;
+ for (let k in obj) {
+ v = obj[k];
+ p = path + "/" + k;
+ markResolved(v, p, resolved);
+ }
+};
+
+const markArrayResolved = (arr: any[], path: string, resolved: any) => {
+ let v, p;
+ for (let i = 0, n = arr.length; i < n; i++) {
+ v = arr[i];
+ p = path + "/" + i;
+ markResolved(v, p, resolved);
+ }
+};
+
+/**
+ * Takes the path for the current key and a lookup path string. Converts
+ * the possibly relative lookup path into its absolute form.
+ *
+ * @param curr
+ * @param path
+ * @param idx
+ */
+export const absPath = (curr: LookupPath, path: string, idx = 1): PropertyKey[] => {
+ if (path.charAt(idx) === "/") {
+ return path.substr(idx + 1).split("/");
}
curr = curr.slice(0, curr.length - 1);
- const sub = q.substr(idx).split("/");
+ const sub = path.substr(idx).split("/");
for (let i = 0, n = sub.length; i < n; i++) {
if (sub[i] === "..") {
- !curr.length && illegalArgs(`invalid lookup path`);
+ !curr.length && illegalArgs(`invalid lookup path: ${path}`);
curr.pop();
} else {
return curr.concat(sub.slice(i));
}
}
- !curr.length && illegalArgs(`invalid lookup path`);
+ !curr.length && illegalArgs(`invalid lookup path: ${path}`);
return curr;
-}
+};
diff --git a/packages/resolve-map/test/index.ts b/packages/resolve-map/test/index.ts
index ba4bcca815..7d12ee0324 100644
--- a/packages/resolve-map/test/index.ts
+++ b/packages/resolve-map/test/index.ts
@@ -1,57 +1,60 @@
+import * as tx from "@thi.ng/transducers";
import * as assert from "assert";
-import { resolveMap } from "../src/index";
+
+import { resolve } from "../src/index";
describe("resolve-map", () => {
it("simple", () => {
assert.deepEqual(
- resolveMap({ a: 1, b: "@a" }),
+ resolve({ a: 1, b: "@a" }),
{ a: 1, b: 1 }
);
});
it("linked refs", () => {
assert.deepEqual(
- resolveMap({ a: "@c", b: "@a", c: 1 }),
+ resolve({ a: "@c", b: "@a", c: 1 }),
{ a: 1, b: 1, c: 1 }
);
});
it("array refs", () => {
assert.deepEqual(
- resolveMap({ a: "@c/1", b: "@a", c: [1, 2] }),
+ resolve({ a: "@c/1", b: "@a", c: [1, 2] }),
{ a: 2, b: 2, c: [1, 2] }
);
});
it("abs vs rel refs", () => {
assert.deepEqual(
- resolveMap({ a1: { b: 1, c: "@b" }, a2: { b: 2, c: "@b" }, a3: { b: 3, c: "@/a1/b" } }),
+ resolve({ a1: { b: 1, c: "@b" }, a2: { b: 2, c: "@b" }, a3: { b: 3, c: "@/a1/b" } }),
{ a1: { b: 1, c: 1 }, a2: { b: 2, c: 2 }, a3: { b: 3, c: 1 } }
);
});
it("rel parent refs", () => {
assert.deepEqual(
- resolveMap({ a: { b: { c: "@../c/d", d: "@c", e: "@/c/d" }, c: { d: 1 } }, c: { d: 10 } }),
+ resolve({ a: { b: { c: "@../c/d", d: "@c", e: "@/c/d" }, c: { d: 1 } }, c: { d: 10 } }),
{ a: { b: { c: 1, d: 1, e: 10 }, c: { d: 1 } }, c: { d: 10 } }
);
})
it("cycles", () => {
- assert.throws(() => resolveMap({ a: "@a" }));
- assert.throws(() => resolveMap({ a: { b: "@b" } }));
- assert.throws(() => resolveMap({ a: { b: "@/a" } }));
- assert.throws(() => resolveMap({ a: { b: "@/a/b" } }));
- assert.throws(() => resolveMap({ a: "@b", b: "@a" }));
+ assert.throws(() => resolve({ a: "@a" }));
+ assert.throws(() => resolve({ a: { b: "@b" } }));
+ // console.log(resolve({ a: { b: "@/a" } }));
+ assert.throws(() => resolve({ a: { b: "@/a" } }));
+ assert.throws(() => resolve({ a: { b: "@/a/b" } }));
+ assert.throws(() => resolve({ a: "@b", b: "@a" }));
});
it("function refs", () => {
assert.deepEqual(
- resolveMap({ a: (x) => x("b/c") * 10, b: { c: "@d", d: "@/e" }, e: () => 1 }),
+ resolve({ a: (x) => x("b/c") * 10, b: { c: "@d", d: "@/e" }, e: () => 1 }),
{ a: 10, b: { c: 1, d: 1 }, e: 1 }
);
- const res = resolveMap({ a: (x) => x("b/c")() * 10, b: { c: "@d", d: "@/e" }, e: () => () => 1 });
+ const res = resolve({ a: (x) => x("b/c")() * 10, b: { c: "@d", d: "@/e" }, e: () => () => 1 });
assert.equal(res.a, 10);
assert.strictEqual(res.b.c, res.e);
assert.strictEqual(res.b.d, res.e);
@@ -61,9 +64,50 @@ describe("resolve-map", () => {
it("function resolves only once", () => {
let n = 0;
assert.deepEqual(
- resolveMap({ a: (x) => x("b/c"), b: { c: "@d", d: "@/e" }, e: () => (n++ , 1) }),
+ resolve({ a: (x) => x("b/c"), b: { c: "@d", d: "@/e" }, e: () => (n++ , 1) }),
{ a: 1, b: { c: 1, d: 1 }, e: 1 }
);
assert.equal(n, 1);
- })
+ });
+
+ it("destructure", () => {
+ const stats = {
+ // sequence average
+ mean: ({ src }) => tx.reduce(tx.mean(), src),
+ // sequence range
+ range: ({ min, max }) => max - min,
+ // computes sequence min val
+ min: ({ src }) => tx.reduce(tx.min(), src),
+ // computes sequence max val
+ max: ({ src }) => tx.reduce(tx.max(), src),
+ // sorted copy
+ sorted: ({ src }) => [...src].sort((a, b) => a - b),
+ // standard deviation
+ sd: ({ src, mean }) =>
+ Math.sqrt(
+ tx.transduce(tx.map((x: number) => Math.pow(x - mean, 2)), tx.add(), src) /
+ (src.length - 1)),
+ // compute 10th - 90th percentiles
+ percentiles: ({ sorted }) => {
+ return tx.transduce(
+ tx.map((x: number) => sorted[Math.floor(x / 100 * sorted.length)]),
+ tx.push(),
+ tx.range(10, 100, 5)
+ );
+ }
+ };
+ assert.deepEqual(
+ resolve({ ...stats, src: () => [1, 6, 7, 2, 4, 11, -3] }),
+ {
+ mean: 4,
+ range: 14,
+ min: -3,
+ max: 11,
+ sorted: [-3, 1, 2, 4, 6, 7, 11],
+ sd: 4.546060565661952,
+ percentiles: [-3, 1, 1, 1, 2, 2, 2, 4, 4, 4, 6, 6, 6, 7, 7, 7, 11, 11],
+ src: [1, 6, 7, 2, 4, 11, -3]
+ }
+ );
+ });
});
diff --git a/packages/rle-pack/CHANGELOG.md b/packages/rle-pack/CHANGELOG.md
index 6c3f62c1c2..05bcead5ec 100644
--- a/packages/rle-pack/CHANGELOG.md
+++ b/packages/rle-pack/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.22](https://github.com/thi-ng/umbrella/compare/@thi.ng/rle-pack@0.2.21...@thi.ng/rle-pack@0.2.22) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rle-pack
+
## [0.2.21](https://github.com/thi-ng/umbrella/compare/@thi.ng/rle-pack@0.2.20...@thi.ng/rle-pack@0.2.21) (2018-05-14)
diff --git a/packages/rle-pack/package.json b/packages/rle-pack/package.json
index 675483c4d3..9d4d4bd616 100644
--- a/packages/rle-pack/package.json
+++ b/packages/rle-pack/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rle-pack",
- "version": "0.2.21",
+ "version": "0.2.22",
"description": "Binary run-length encoding packer w/ flexible repeat bit widths",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rle-pack",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -25,7 +29,7 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/bitstream": "^0.4.12"
+ "@thi.ng/bitstream": "^0.4.13"
},
"keywords": [
"binary",
diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md
index 7326be2e2c..38dee7deb6 100644
--- a/packages/router/CHANGELOG.md
+++ b/packages/router/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.1.18](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.17...@thi.ng/router@0.1.18) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/router
+
+
+## [0.1.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.16...@thi.ng/router@0.1.17) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/router
+
+
+## [0.1.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.15...@thi.ng/router@0.1.16) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/router
+
## [0.1.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.14...@thi.ng/router@0.1.15) (2018-05-14)
diff --git a/packages/router/package.json b/packages/router/package.json
index c5b9983bab..10e98f14bc 100644
--- a/packages/router/package.json
+++ b/packages/router/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/router",
- "version": "0.1.15",
+ "version": "0.1.18",
"description": "Generic router for browser & non-browser based applications",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/router",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -23,10 +27,10 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4"
},
"keywords": [
"declarative",
diff --git a/packages/rstream-csp/CHANGELOG.md b/packages/rstream-csp/CHANGELOG.md
index e0c0209d16..b9c95246e3 100644
--- a/packages/rstream-csp/CHANGELOG.md
+++ b/packages/rstream-csp/CHANGELOG.md
@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.1.78](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.77...@thi.ng/rstream-csp@0.1.78) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-csp
+
+
+## [0.1.77](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.76...@thi.ng/rstream-csp@0.1.77) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-csp
+
+
+## [0.1.76](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.75...@thi.ng/rstream-csp@0.1.76) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-csp
+
+
+## [0.1.75](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.74...@thi.ng/rstream-csp@0.1.75) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-csp
+
+
+## [0.1.74](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.73...@thi.ng/rstream-csp@0.1.74) (2018-05-20)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-csp
+
+
+## [0.1.73](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.72...@thi.ng/rstream-csp@0.1.73) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-csp
+
## [0.1.72](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.71...@thi.ng/rstream-csp@0.1.72) (2018-05-14)
diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json
index f5cb46be6a..b1e6bbc0b1 100644
--- a/packages/rstream-csp/package.json
+++ b/packages/rstream-csp/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream-csp",
- "version": "0.1.72",
+ "version": "0.1.78",
"description": "@thi.ng/csp bridge module for @thi.ng/rstream",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream-csp",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,8 +28,8 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/csp": "^0.3.41",
- "@thi.ng/rstream": "^1.6.13"
+ "@thi.ng/csp": "^0.3.45",
+ "@thi.ng/rstream": "^1.8.0"
},
"keywords": [
"bridge",
diff --git a/packages/rstream-dot/CHANGELOG.md b/packages/rstream-dot/CHANGELOG.md
index 96909a4b6b..280414f472 100644
--- a/packages/rstream-dot/CHANGELOG.md
+++ b/packages/rstream-dot/CHANGELOG.md
@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.2.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.16...@thi.ng/rstream-dot@0.2.17) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-dot
+
+
+## [0.2.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.15...@thi.ng/rstream-dot@0.2.16) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-dot
+
+
+## [0.2.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.14...@thi.ng/rstream-dot@0.2.15) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-dot
+
+
+## [0.2.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.13...@thi.ng/rstream-dot@0.2.14) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-dot
+
+
+## [0.2.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.12...@thi.ng/rstream-dot@0.2.13) (2018-05-20)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-dot
+
+
+## [0.2.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.11...@thi.ng/rstream-dot@0.2.12) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-dot
+
## [0.2.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.10...@thi.ng/rstream-dot@0.2.11) (2018-05-14)
diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json
index 8252842c2c..6f97d99720 100644
--- a/packages/rstream-dot/package.json
+++ b/packages/rstream-dot/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream-dot",
- "version": "0.2.11",
+ "version": "0.2.17",
"description": "Graphviz DOT conversion of @thi.ng/rstream dataflow graph topologies",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream-dot",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,7 +28,7 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/rstream": "^1.6.13"
+ "@thi.ng/rstream": "^1.8.0"
},
"keywords": [
"conversion",
diff --git a/packages/rstream-gestures/CHANGELOG.md b/packages/rstream-gestures/CHANGELOG.md
index f4399bee44..e7e2db6ff8 100644
--- a/packages/rstream-gestures/CHANGELOG.md
+++ b/packages/rstream-gestures/CHANGELOG.md
@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.3.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.13...@thi.ng/rstream-gestures@0.3.14) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-gestures
+
+
+## [0.3.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.12...@thi.ng/rstream-gestures@0.3.13) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-gestures
+
+
+## [0.3.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.11...@thi.ng/rstream-gestures@0.3.12) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-gestures
+
+
+## [0.3.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.10...@thi.ng/rstream-gestures@0.3.11) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-gestures
+
+
+## [0.3.10](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.9...@thi.ng/rstream-gestures@0.3.10) (2018-05-20)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-gestures
+
+
+## [0.3.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.8...@thi.ng/rstream-gestures@0.3.9) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-gestures
+
## [0.3.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.3.7...@thi.ng/rstream-gestures@0.3.8) (2018-05-14)
diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json
index d3be430e9e..734843895d 100644
--- a/packages/rstream-gestures/package.json
+++ b/packages/rstream-gestures/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream-gestures",
- "version": "0.3.8",
+ "version": "0.3.14",
"description": "Unified mouse, mouse wheel & single-touch event stream abstraction",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream-gestures",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,9 +28,9 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/rstream": "^1.6.13",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/rstream": "^1.8.0",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"dataflow",
diff --git a/packages/rstream-graph/CHANGELOG.md b/packages/rstream-graph/CHANGELOG.md
index 806be879b4..28006105c3 100644
--- a/packages/rstream-graph/CHANGELOG.md
+++ b/packages/rstream-graph/CHANGELOG.md
@@ -3,6 +3,110 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+# [2.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.0.3...@thi.ng/rstream-graph@2.1.0) (2018-06-21)
+
+
+### Features
+
+* **rstream-graph:** add stop(), fix `const` inputs, update docs/readme ([d0b1e5c](https://github.com/thi-ng/umbrella/commit/d0b1e5c))
+
+
+
+
+
+## [2.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.0.2...@thi.ng/rstream-graph@2.0.3) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-graph
+
+
+## [2.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.0.1...@thi.ng/rstream-graph@2.0.2) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-graph
+
+
+## [2.0.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@2.0.0...@thi.ng/rstream-graph@2.0.1) (2018-06-07)
+
+
+### Bug Fixes
+
+* **rstream-graph:** rename `resolveMap` => `resolve` due to upstream changes ([0fc2305](https://github.com/thi-ng/umbrella/commit/0fc2305))
+
+
+
+
+
+# [2.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.1.2...@thi.ng/rstream-graph@2.0.0) (2018-06-06)
+
+
+### Features
+
+* **rstream-graph:** add full/optional support for multiple node outputs ([f2e0df2](https://github.com/thi-ng/umbrella/commit/f2e0df2))
+* **rstream-graph:** update NodeOutput, support multiple handlers ([be21c4c](https://github.com/thi-ng/umbrella/commit/be21c4c))
+
+
+### BREAKING CHANGES
+
+* **rstream-graph:** update NodeSpec format & graph initialization
+
+- add new types/interfaces
+- non-destructive initGraph() behavior
+- update & refactor nodeFromSpec()
+- update addNode/removeNode()
+- update tests & docs
+
+
+
+
+
+## [1.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.1.1...@thi.ng/rstream-graph@1.1.2) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-graph
+
+
+## [1.1.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.1.0...@thi.ng/rstream-graph@1.1.1) (2018-05-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-graph
+
+
+# [1.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.0.17...@thi.ng/rstream-graph@1.1.0) (2018-05-21)
+
+
+### Features
+
+* **rstream-graph:** update types, initGraph(), node1(), add tests ([0818498](https://github.com/thi-ng/umbrella/commit/0818498))
+
+
+
+
+
+## [1.0.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.0.16...@thi.ng/rstream-graph@1.0.17) (2018-05-20)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-graph
+
+
+## [1.0.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.0.15...@thi.ng/rstream-graph@1.0.16) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-graph
+
## [1.0.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.0.14...@thi.ng/rstream-graph@1.0.15) (2018-05-14)
diff --git a/packages/rstream-graph/README.md b/packages/rstream-graph/README.md
index 3595044cc9..7823a7c973 100644
--- a/packages/rstream-graph/README.md
+++ b/packages/rstream-graph/README.md
@@ -9,10 +9,17 @@ This project is part of the
Declarative, reactive dataflow graph construction using
[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/master/packages/rstream),
-[@thi.ng/atom](https://github.com/thi-ng/umbrella/tree/master/packages/atom) and [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers)
+[@thi.ng/atom](https://github.com/thi-ng/umbrella/tree/master/packages/atom)
+and
+[@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers)
primitives.
-Stream subscription types act as graph nodes and attached transducers as graph edges, transforming data for downstream consumers / nodes. Theoretically, allows cycles and is not restricted to DAG topologies, but care must be taken to avoid CPU hogging (user's responsibility).
+Stream subscription types act as graph nodes and attached transducers as
+graph edges, transforming data for downstream consumers / nodes.
+Theoretically, allows cycles and is not restricted to DAG topologies,
+but care must be taken to avoid CPU hogging if those cycles are causing
+synchronous computation loops (it the user's responsibility to avoid
+these).
## Installation
@@ -34,10 +41,10 @@ yarn add @thi.ng/rstream-graph
Small(ish), fully commented projects can be found in the `/examples` folder:
-* **Dataflow circles** -
- [Source](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-dataflow),
- [Live version](http://demo.thi.ng/umbrella/rstream-dataflow)
* **SVG grid gen** -
+ [Source](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-grid),
+ [Live version](http://demo.thi.ng/umbrella/rstream-grid)
+* **Dataflow circles** -
[Source](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-dataflow),
[Live version](http://demo.thi.ng/umbrella/rstream-dataflow)
@@ -67,7 +74,7 @@ const graph = rsg.initGraph(state, {
mul: {
fn: rsg.mul,
ins: {
- a: { stream: "add" },
+ a: { stream: "/add/node" },
b: { stream: () => rs.fromIterable([10, 20, 30]) }
},
}
@@ -87,7 +94,89 @@ setTimeout(() => state.resetIn("a", 10), 1000);
// result: 360
```
-Please documentation in the source code for further details.
+## Graph specification
+
+A dataflow graph spec is a plain object where keys are node names and
+their values are `NodeSpec`s, defining a node's inputs, outputs and the
+operation to be applied to produce one or more result streams.
+
+```ts
+interface NodeSpec {
+ fn: NodeFactory;
+ ins: IObjectOf;
+ outs?: IObjectOf;
+}
+```
+
+Specification for a single "node" in the dataflow graph. Nodes here are
+actually just wrappers of streams / subscriptions (or generally any form
+of
+[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/master/packages/rstream)
+`ISubscribable`), usually with an associated transducer to transform /
+combine the inputs and produce values for the node's result stream.
+
+The `fn` function is responsible to produce such a stream transformer
+construct and the library provides several general purpose helpers for
+that purpose. The keys used to specify inputs in the `ins` object are
+dictated by the actual node `fn` used. Most node functions with multiple
+inputs will be implemented as
+[`StreamSync`](https://github.com/thi-ng/umbrella/tree/master/packages/rstream/src/stream-sync.ts)
+instances and the input IDs are used to locally rename input streams
+within the `StreamSync` container. Alo see `initGraph` and
+`nodeFromSpec` (in
+[`/src/nodes.ts`](https://github.com/thi-ng/umbrella/tree/master/packages/rstream-graph/src/nodes.ts)
+for more details how these specs are compiled into stream constructs.
+
+Specification for a single input, which can be given in different ways:
+
+1) Create a stream of value changes at given path in state
+ [Atom](https://github.com/thi-ng/umbrella/e/master/packages/atom)
+ (passed to `initGraph`):
+
+```ts
+{ path: "nested.src.path" }
+{ path: ["nested", "src", "path"] }
+```
+
+2) Reference path to another node's output in the GraphSpec object. See
+ [@thi.ng/resolve-map](https://github.com/thi-ng/umbrella/tree/master/packages/resolve-map)
+ for details.
+
+```ts
+{ stream: "/node-id/node" } // main node output
+{ stream: "/node-id/outs/foo" } // specific output
+```
+
+3) Reference another node indirectly. The passed in `resolve` function
+ can be used to lookup other nodes, with the same logic as above. E.g.
+ the following spec looks up the main output of node "abc" and adds a
+ transformed subscription, which is then used as input for current
+ node.
+
+```ts
+{ stream: (resolve) =>
+ resolve("/abc/node").subscribe(map(x => x * 10)) }
+```
+
+4) Provide an external input stream:
+
+```ts
+{ stream: () => fromIterable([1,2,3], 500) }
+```
+
+5) Single value input stream:
+
+```ts
+{ const: 1 }
+{ const: () => 1 }
+```
+
+If the optional `xform` key is given, a subscription with the given
+transducer is added to the input and then used as input instead. This is
+allows for further pre-processing of inputs.
+
+Please see detailed documentation in the source code & test cases for
+further details.
## Authors
diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json
index dff0c1b1a4..db7129c991 100644
--- a/packages/rstream-graph/package.json
+++ b/packages/rstream-graph/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream-graph",
- "version": "1.0.15",
+ "version": "2.1.0",
"description": "Declarative dataflow graph construction for @thi.ng/rstream",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream-graph",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,13 +28,13 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/paths": "^1.3.8",
- "@thi.ng/resolve-map": "^2.0.5",
- "@thi.ng/rstream": "^1.6.13",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/paths": "^1.3.10",
+ "@thi.ng/resolve-map": "^3.0.2",
+ "@thi.ng/rstream": "^1.8.0",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"compute",
diff --git a/packages/rstream-graph/src/api.ts b/packages/rstream-graph/src/api.ts
index 6b5392d691..bda295f8ba 100644
--- a/packages/rstream-graph/src/api.ts
+++ b/packages/rstream-graph/src/api.ts
@@ -1,35 +1,56 @@
import { IObjectOf } from "@thi.ng/api/api";
+import { Path } from "@thi.ng/paths";
import { ISubscribable } from "@thi.ng/rstream/api";
import { Transducer } from "@thi.ng/transducers/api";
-export type NodeFactory = (src: IObjectOf>, id: string) => ISubscribable;
+/**
+ * A function which constructs and returns an `ISubscribable` using
+ * given object of inputs and node ID. See `node()` and `node1()`.
+ */
+export type NodeFactory = (src: NodeInputs, id: string) => ISubscribable;
+
+export type NodeInputs = IObjectOf>;
+export type NodeOutputs = IObjectOf>;
+export type Graph = IObjectOf;
+
+export interface Node {
+ ins: NodeInputs;
+ outs: NodeOutputs;
+ node: ISubscribable;
+}
/**
* A dataflow graph spec is simply an object where keys are node names
- * and their values are NodeSpec's, defining inputs and the operation to
- * be applied to produce a result stream.
+ * and their values are `NodeSpec`s, defining a node's inputs, outputs
+ * and the operation to be applied to produce one or more result
+ * streams.
*/
-export type GraphSpec = IObjectOf;
+export type GraphSpec = IObjectOf<
+ NodeSpec |
+ Node |
+ ((resolve: (path: string) => any) => Node)>;
/**
* Specification for a single "node" in the dataflow graph. Nodes here
- * are actually streams (or just generally any form of @thi.ng/rstream
- * subscription), usually with an associated transducer to transform /
- * combine the inputs and produce values for the node's result stream.
+ * are actually just wrappers of streams / subscriptions (or generally
+ * any form of thi.ng/rstream `ISubscribable`), usually with an
+ * associated transducer to transform / combine the inputs and produce
+ * values for the node's result stream.
*
- * The `fn` function is responsible to produce such a stream construct.
- * The keys used to specify inputs in the `ins` object are dictated by
- * the actual node `fn` used. Most node functions with multiple inputs
- * are implemented as `StreamSync` instances and the input IDs are used
- * to locally rename input streams within the `StreamSync` container.
+ * The `fn` function is responsible to produce such a stream transformer
+ * construct. The keys used to specify inputs in the `ins` object are
+ * dictated by the actual node `fn` used. Most node functions with
+ * multiple inputs will be implemented as `StreamSync` instances and the
+ * input IDs are used to locally rename input streams within the
+ * `StreamSync` container.
*
- * See `initGraph` and `nodeFromSpec` for more details (in
- * /src/nodes.ts)
+ * Alo see `initGraph` and `nodeFromSpec` (in /src/nodes.ts) for more
+ * details how these specs are compiled into stream constructs.
*/
export interface NodeSpec {
fn: NodeFactory;
- ins: IObjectOf;
- out?: NodeOutput;
+ ins: IObjectOf;
+ outs?: IObjectOf;
}
/**
@@ -41,21 +62,26 @@ export interface NodeSpec {
*
* ```
* { path: "nested.src.path" }
+ * { path: ["nested", "src", "path"] }
* ```
*
- * 2) Reference another node in the GraphSpec object:
+ * 2) Reference path to another node's output in the GraphSpec object.
+ * See `@thi.ng/resolve-map` for details.
*
* ```
- * { stream: "node-id" }
+ * { stream: "/node-id/node" } // main node output
+ * { stream: "/node-id/outs/foo" } // specific output
* ```
*
* 3) Reference another node indirectly. The passed in `resolve`
- * function can be used to lookup other nodes, e.g. the following
- * spec looks up node "src" and adds a transformed subscription,
- * which is then used as input for current node
+ * function can be used to lookup other nodes, with the same logic as
+ * above. E.g. the following spec looks up the main output of node
+ * "abc" and adds a transformed subscription, which is then used as
+ * input for current node.
*
* ```
- * { stream: (resolve) => resolve("src").subscribe(map(x => x * 10)) }
+ * { stream: (resolve) =>
+ * resolve("/abc/node").subscribe(map(x => x * 10)) }
* ```
*
* 4) Provide an external input stream:
@@ -68,17 +94,20 @@ export interface NodeSpec {
*
* ```
* { const: 1 }
+ * { const: () => 1 }
* ```
*
- * If the optional `xform` is given, a subscription with the transducer
- * is added to the input and then used as input instead.
+ * If the optional `xform` is given, a subscription with the given
+ * transducer is added to the input and then used as input instead.
*/
-export interface NodeInput {
+export interface NodeInputSpec {
id?: string;
- path?: string;
+ path?: Path;
stream?: string | ((resolve) => ISubscribable);
- const?: any;
+ const?: any | ((resolve) => any);
xform?: Transducer;
}
-export type NodeOutput = string | ((node: ISubscribable) => void);
+export type NodeOutputSpec = Path | NodeOutputFn;
+
+export type NodeOutputFn = (node: ISubscribable, id: PropertyKey) => ISubscribable;
diff --git a/packages/rstream-graph/src/graph.ts b/packages/rstream-graph/src/graph.ts
index 3e18841d41..c263043a02 100644
--- a/packages/rstream-graph/src/graph.ts
+++ b/packages/rstream-graph/src/graph.ts
@@ -1,89 +1,204 @@
import { IObjectOf } from "@thi.ng/api/api";
import { IAtom } from "@thi.ng/atom/api";
+import { isFunction } from "@thi.ng/checks/is-function";
+import { isPlainObject } from "@thi.ng/checks/is-plain-object";
import { isString } from "@thi.ng/checks/is-string";
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
-import { resolveMap } from "@thi.ng/resolve-map";
+import { getIn } from "@thi.ng/paths";
+import { absPath, resolve } from "@thi.ng/resolve-map";
import { ISubscribable } from "@thi.ng/rstream/api";
import { fromIterableSync } from "@thi.ng/rstream/from/iterable";
import { fromView } from "@thi.ng/rstream/from/view";
import { StreamSync, sync } from "@thi.ng/rstream/stream-sync";
-import { Subscription } from "@thi.ng/rstream/subscription";
import { Transducer } from "@thi.ng/transducers/api";
-import { NodeFactory, NodeSpec } from "./api";
+import {
+ Graph,
+ GraphSpec,
+ Node,
+ NodeFactory,
+ NodeInputs,
+ NodeInputSpec,
+ NodeOutputs,
+ NodeOutputSpec,
+ NodeSpec
+} from "./api";
/**
- * Dataflow graph initialization function. Takes an object of
- * NodeSpec's, calls `nodeFromSpec` for each and then recursively
- * resolves references via `@thi.ng/resolve-map/resolveMap`. Returns
- * updated graph object (mutates in-place, original specs are replaced
- * by stream constructs).
+ * Dataflow graph initialization function. Takes a state Atom (or `null`
+ * if not needed) and an object of `NodeSpec` values or functions
+ * returning `Node` objects. Calls `nodeFromSpec` for each spec and then
+ * recursively resolves references via thi.ng/resolve-map `resolve`.
+ * Returns new initialized graph object of `Node` objects and
+ * `@thi.ng/rstream` stream constructs. Does NOT mutate original
+ * `GraphSpec` object.
*
* @param state
- * @param nodes
+ * @param spec
*/
-export const initGraph = (state: IAtom, nodes: IObjectOf): IObjectOf> => {
- for (let id in nodes) {
- (nodes)[id] = nodeFromSpec(state, nodes[id], id);
+export const initGraph = (state: IAtom, spec: GraphSpec): Graph => {
+ const res: Graph = {}
+ for (let id in spec) {
+ const n = spec[id];
+ if (isNodeSpec(n)) {
+ res[id] = nodeFromSpec(state, spec[id], id);
+ } else {
+ res[id] = n;
+ }
}
- return resolveMap(nodes);
+ return resolve(res);
};
+const isNodeSpec = (x: any): x is NodeSpec =>
+ isPlainObject(x) && isFunction((x).fn);
+
/**
- * Transforms a single NodeSpec into a lookup function for `resolveMap`
+ * Transforms a single `NodeSpec` into a lookup function for `resolve`
* (which is called from `initGraph`). When that function is called,
* recursively resolves all specified input streams and calls this
- * spec's `fn` to produce a new stream from these inputs. If the spec
- * includes the optional `out` key, it also executes the provided
- * function, or if the value is a string, adds a subscription to this
- * node's result stream which then updates the provide state atom at the
- * path defined by `out`. Returns an ISubscribable.
+ * spec's `fn` to produce a new stream from these inputs.
+ *
+ * If the spec includes the optional `outs` keys, it also creates the
+ * subscriptions for each of the given output keys, which then can be
+ * used as inputs by other nodes. Each value in the `outs` subspec can
+ * be a function or state path (string/number/array, see thi.ng/paths).
+ * Functions are called with this node's constructed stream/subscribable
+ * and the output id and must return a new `ISubscribable`. For path
+ * values a subscription is added to this node's result stream which
+ * then updates the provided state atom at the path given.
+ *
+ * Non-function output specs subs assume the raw node output value is an
+ * object from which the different output keys are being extracted. The
+ * special `*` output key can be used to handle the entire node output
+ * value. This is useful/required for non-object node result values.
+ *
+ * ```
+ * out: {
+ * // fn output spec
+ * // creates new sub which uses `pick` transducer to
+ * // select key `a` from main node output (assumed to be object)
+ * a: (node, id) => node.subscribe({}, pick(id)),
+ *
+ * // yields sub of `b` key's values extracted from main output
+ * // and also stores them at given path in state atom
+ * b: "foo.b"
+ *
+ * // yields sub with same value as main node output and
+ * // stores vals in state atom at given path
+ * "*": "foo.main"
+ * }
+ * ```
*
* See `api.ts` for further details and possible spec variations.
*
+ * @param state
* @param spec
+ * @param id
*/
-const nodeFromSpec = (state: IAtom, spec: NodeSpec, id: string) => (resolve) => {
- const src: IObjectOf> = {};
- for (let id in spec.ins) {
+const nodeFromSpec = (state: IAtom, spec: NodeSpec, id: string) =>
+ (resolve) => {
+ const ins = prepareNodeInputs(spec.ins, state, resolve);
+ const node = spec.fn(ins, id);
+ const outs = prepareNodeOutputs(spec.outs, node, state, id);
+ return { ins, node, outs };
+ };
+
+const prepareNodeInputs = (ins: IObjectOf, state: IAtom, resolve: (x: string) => any) => {
+ const res: NodeInputs = {};
+ if (!ins) return res;
+ for (let id in ins) {
let s;
- const i = spec.ins[id];
+ const i = ins[id];
if (i.path) {
s = fromView(state, i.path);
- } else if (i.stream) {
- s = isString(i.stream) ?
- resolve(i.stream) :
- (i).stream(resolve);
- } else if (i.const) {
- s = fromIterableSync([i.const]);
- } else {
- illegalArgs(`invalid node spec`);
+ }
+ else if (i.stream) {
+ s = isString(i.stream) ? resolve(i.stream) : i.stream(resolve);
+ }
+ else if (i.const) {
+ s = fromIterableSync([isFunction(i.const) ? i.const(resolve) : i.const], false);
+ }
+ else {
+ illegalArgs(`invalid node input: ${id}`);
}
if (i.xform) {
s = s.subscribe(i.xform, id);
}
- src[id] = s;
+ res[id] = s;
}
- const node = spec.fn(src, id);
- if (spec.out) {
- if (isString(spec.out)) {
- ((path) => node.subscribe({ next: (x) => state.resetIn(path, x) }, `out-${id}`))(spec.out);
+ return res;
+}
+
+const prepareNodeOutputs = (outs: IObjectOf, node: ISubscribable, state: IAtom, nodeID: string) => {
+ const res: NodeOutputs = {};
+ if (!outs) return res;
+ for (let id in outs) {
+ const o = outs[id];
+ if (isFunction(o)) {
+ res[id] = o(node, id);
+ } else if (id == "*") {
+ res[id] = ((path) => node.subscribe({
+ next: (x) => state.resetIn(path, x)
+ }, `out-${nodeID}`))(o);
} else {
- spec.out(node);
+ res[id] = ((path, id) => node.subscribe({
+ next: (x) => state.resetIn(path, x[id])
+ }, `out-${nodeID}-${id}`))(o, id);
}
}
- return node;
+ return res;
};
-export const addNode = (graph: IObjectOf>, state: IAtom, id: string, spec: NodeSpec) =>
- graph[id] = nodeFromSpec(state, spec, id)((nodeID) => graph[nodeID]);
-
-export const removeNode = (graph: IObjectOf>, id: string) => {
+/**
+ * Compiles given `NodeSpec` and adds it to graph. Returns compiled
+ * `Node` object for the given spec. Throws error if the graph already
+ * contains a node with given `id`.
+ *
+ * @param graph
+ * @param state
+ * @param id
+ * @param spec
+ */
+export const addNode = (graph: Graph, state: IAtom, id: string, spec: NodeSpec): Node => {
if (graph[id]) {
- graph[id].unsubscribe();
+ illegalArgs(`graph already contains a node with ID: ${id}`);
+ }
+ return graph[id] = nodeFromSpec(state, spec, id)(
+ (path) => getIn(graph, absPath([id], path))
+ );
+}
+
+/**
+ * Calls `.unsubscribe()` on given node and all of its outputs, then
+ * removes it from graph. Returns `false` if no node exists for given
+ * `id`.
+ *
+ * @param graph
+ * @param id
+ */
+export const removeNode = (graph: Graph, id: string) => {
+ const node = graph[id];
+ if (node) {
+ node.node.unsubscribe();
+ for (let id in node.outs) {
+ node.outs[id].unsubscribe();
+ }
delete graph[id];
return true;
}
+ return false;
+};
+
+/**
+ * Calls `.unsubscribe()` on all nodes in the graph, causing all related
+ * streams & subscriptions to terminate.
+ *
+ * @param graph
+ */
+export const stop = (graph: Graph) => {
+ for (let id in graph) {
+ graph[id].node.unsubscribe();
+ }
};
/**
@@ -109,10 +224,12 @@ export const node = (xform: Transducer, any>, inputIDs?: string[]
* @param xform
* @param inputID
*/
-export const node1 = (xform: Transducer, inputID = "src"): NodeFactory =>
- (src: IObjectOf>, id: string): Subscription => {
+export const node1 = (xform?: Transducer, inputID = "src"): NodeFactory =>
+ (src: IObjectOf>, id: string): ISubscribable => {
ensureInputs(src, [inputID], id);
- return src[inputID].subscribe(xform, id);
+ return xform ?
+ src[inputID].subscribe(xform, id) :
+ src[inputID].subscribe(null, id);
};
/**
diff --git a/packages/rstream-graph/src/nodes/extract.ts b/packages/rstream-graph/src/nodes/extract.ts
index 4a36e0403a..1df94cfa92 100644
--- a/packages/rstream-graph/src/nodes/extract.ts
+++ b/packages/rstream-graph/src/nodes/extract.ts
@@ -8,6 +8,9 @@ import { node1 } from "../graph";
* Nested value extraction node. Higher order function.
*
* Inputs: 1
+ *
+ * @param path value lookup path
+ * @param inputID default: `src`
*/
export const extract = (path: Path, inputID?: string): NodeFactory =>
node1(map((x) => getIn(x, path)), inputID);
diff --git a/packages/rstream-graph/src/nodes/math.ts b/packages/rstream-graph/src/nodes/math.ts
index 9409c8ca62..ff7a1255fa 100644
--- a/packages/rstream-graph/src/nodes/math.ts
+++ b/packages/rstream-graph/src/nodes/math.ts
@@ -39,7 +39,7 @@ export const mul: NodeFactory = node(
/**
* Subtraction node.
*
- * Inputs: 2
+ * Inputs: `a`, `b`
*/
export const sub: NodeFactory =
node(map((ports: IObjectOf) => ports.a - ports.b), ["a", "b"]);
@@ -47,7 +47,7 @@ export const sub: NodeFactory =
/**
* Division node.
*
- * Inputs: 2
+ * Inputs: `a`, `b`
*/
export const div: NodeFactory =
node(map((ports: IObjectOf) => ports.a / ports.b), ["a", "b"]);
diff --git a/packages/rstream-graph/test/index.ts b/packages/rstream-graph/test/index.ts
index a9e7b95e00..461a548328 100644
--- a/packages/rstream-graph/test/index.ts
+++ b/packages/rstream-graph/test/index.ts
@@ -1,6 +1,75 @@
-// import * as assert from "assert";
-// import * as rsg from "../src/index";
+import { Atom } from "@thi.ng/atom";
+import * as rs from "@thi.ng/rstream";
+import { map } from "@thi.ng/transducers/xform/map";
+import * as assert from "assert";
+
+import * as rsg from "../src";
describe("rstream-graph", () => {
- it("tests pending");
+ it("basic", (done) => {
+ const acc = [];
+ const state = new Atom({ a: 1, b: 2 });
+ const graph = rsg.initGraph(state, {
+ foo: () => ({
+ node: rs.fromIterable([2]),
+ ins: {},
+ outs: {}
+ }),
+ bar: ($) => ({
+ node: $("/foo/node").transform(map((x: number) => x * 10)),
+ ins: {},
+ outs: {}
+ }),
+ add: {
+ fn: rsg.add,
+ ins: {
+ a: { path: "a" },
+ b: { path: "b" }
+ },
+ outs: {
+ alt: (n) => n.subscribe({}) // identical to main out, testing only
+ }
+ },
+ mul: {
+ fn: rsg.mul,
+ ins: {
+ a: { stream: "/add/outs/alt" },
+ b: { stream: () => rs.fromIterable([10, 20, 30]) },
+ c: { stream: "/bar/node" }
+ },
+ outs: {
+ baz: (n, id) => n.subscribe({ next: (x) => state.resetIn(["foo", id], x) })
+ }
+ },
+ res: {
+ ins: {
+ src: { stream: "/mul/node" }
+ },
+ fn: rsg.node1(map((x: number) => ({ x: x, x2: x * 2 }))),
+ outs: {
+ "*": "res"
+ }
+ },
+ res2: {
+ ins: {
+ src: { stream: "/res/node" }
+ },
+ fn: rsg.node1(),
+ outs: {
+ x: "res2.x",
+ }
+ }
+ });
+ graph.mul.node.subscribe({ next: (x) => acc.push(x) });
+ setTimeout(() => {
+ state.resetIn("a", 10);
+ console.log(graph);
+ assert.deepEqual(acc, [600, 1200, 1800, 7200]);
+ assert.deepEqual(
+ state.deref(),
+ { a: 10, b: 2, foo: { baz: 7200 }, res: { x: 7200, x2: 14400 }, res2: { x: 7200 } }
+ );
+ done();
+ }, 10);
+ });
});
diff --git a/packages/rstream-log/CHANGELOG.md b/packages/rstream-log/CHANGELOG.md
index 24db589f7f..1323c200db 100644
--- a/packages/rstream-log/CHANGELOG.md
+++ b/packages/rstream-log/CHANGELOG.md
@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [1.0.29](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.28...@thi.ng/rstream-log@1.0.29) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-log
+
+
+## [1.0.28](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.27...@thi.ng/rstream-log@1.0.28) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-log
+
+
+## [1.0.27](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.26...@thi.ng/rstream-log@1.0.27) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-log
+
+
+## [1.0.26](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.25...@thi.ng/rstream-log@1.0.26) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-log
+
+
+## [1.0.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.24...@thi.ng/rstream-log@1.0.25) (2018-05-20)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-log
+
+
+## [1.0.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.23...@thi.ng/rstream-log@1.0.24) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-log
+
## [1.0.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.22...@thi.ng/rstream-log@1.0.23) (2018-05-14)
diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json
index e11ab56255..9bb9fd48a1 100644
--- a/packages/rstream-log/package.json
+++ b/packages/rstream-log/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream-log",
- "version": "1.0.23",
+ "version": "1.0.29",
"description": "Structured, multilevel & hierarchical loggers based on @thi.ng/rstream",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream-log",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,11 +28,11 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/rstream": "^1.6.13",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/rstream": "^1.8.0",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"ES6",
diff --git a/packages/rstream-query/CHANGELOG.md b/packages/rstream-query/CHANGELOG.md
index 61958170cc..bbbf69808f 100644
--- a/packages/rstream-query/CHANGELOG.md
+++ b/packages/rstream-query/CHANGELOG.md
@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+## [0.3.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.15...@thi.ng/rstream-query@0.3.16) (2018-06-21)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-query
+
+
+## [0.3.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.14...@thi.ng/rstream-query@0.3.15) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-query
+
+
+## [0.3.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.13...@thi.ng/rstream-query@0.3.14) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-query
+
+
+## [0.3.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.12...@thi.ng/rstream-query@0.3.13) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-query
+
+
+## [0.3.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.11...@thi.ng/rstream-query@0.3.12) (2018-05-20)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-query
+
+
+## [0.3.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.10...@thi.ng/rstream-query@0.3.11) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream-query
+
## [0.3.10](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.9...@thi.ng/rstream-query@0.3.10) (2018-05-14)
diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json
index 82f80c6098..87e495caeb 100644
--- a/packages/rstream-query/package.json
+++ b/packages/rstream-query/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream-query",
- "version": "0.3.10",
+ "version": "0.3.16",
"description": "@thi.ng/rstream based triple store & reactive query engine",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream-query",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,14 +28,14 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/associative": "^0.5.5",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/equiv": "^0.1.2",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/rstream": "^1.6.13",
- "@thi.ng/rstream-dot": "^0.2.11",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/associative": "^0.5.8",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/equiv": "^0.1.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/rstream": "^1.8.0",
+ "@thi.ng/rstream-dot": "^0.2.17",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"dataflow",
diff --git a/packages/rstream/CHANGELOG.md b/packages/rstream/CHANGELOG.md
index 8c48692f5b..49df2db48b 100644
--- a/packages/rstream/CHANGELOG.md
+++ b/packages/rstream/CHANGELOG.md
@@ -3,6 +3,66 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+# [1.8.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.7.3...@thi.ng/rstream@1.8.0) (2018-06-21)
+
+
+### Features
+
+* **rstream:** option to avoid auto-closing `fromInterval()`, add docs ([cc5b736](https://github.com/thi-ng/umbrella/commit/cc5b736))
+
+
+
+
+
+## [1.7.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.7.2...@thi.ng/rstream@1.7.3) (2018-06-19)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream
+
+
+## [1.7.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.7.1...@thi.ng/rstream@1.7.2) (2018-06-18)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream
+
+
+## [1.7.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.7.0...@thi.ng/rstream@1.7.1) (2018-05-30)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream
+
+
+# [1.7.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.6.14...@thi.ng/rstream@1.7.0) (2018-05-20)
+
+
+### Bug Fixes
+
+* **rstream:** minor update PubSub topic fn return type ([cbc600e](https://github.com/thi-ng/umbrella/commit/cbc600e))
+
+
+### Features
+
+* **rstream:** re-implement bisect() using PubSub, update tests ([846aaf9](https://github.com/thi-ng/umbrella/commit/846aaf9))
+* **rstream:** update resolve(), update subscribe() overrides ([23fdd39](https://github.com/thi-ng/umbrella/commit/23fdd39))
+
+
+
+
+
+## [1.6.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.6.13...@thi.ng/rstream@1.6.14) (2018-05-14)
+
+
+
+
+**Note:** Version bump only for package @thi.ng/rstream
+
## [1.6.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.6.12...@thi.ng/rstream@1.6.13) (2018-05-14)
diff --git a/packages/rstream/package.json b/packages/rstream/package.json
index 009032e384..98754347b2 100644
--- a/packages/rstream/package.json
+++ b/packages/rstream/package.json
@@ -1,10 +1,14 @@
{
"name": "@thi.ng/rstream",
- "version": "1.6.13",
+ "version": "1.8.0",
"description": "Reactive multi-tap streams, dataflow & transformation pipeline constructs",
"main": "./index.js",
"typings": "./index.d.ts",
- "repository": "https://github.com/thi-ng/umbrella",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/thi-ng/umbrella.git"
+ },
+ "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/rstream",
"author": "Karsten Schmidt ",
"license": "Apache-2.0",
"scripts": {
@@ -24,13 +28,13 @@
"typescript": "^2.8.3"
},
"dependencies": {
- "@thi.ng/api": "^4.0.2",
- "@thi.ng/associative": "^0.5.5",
- "@thi.ng/atom": "^1.3.12",
- "@thi.ng/checks": "^1.5.3",
- "@thi.ng/errors": "^0.1.3",
- "@thi.ng/paths": "^1.3.8",
- "@thi.ng/transducers": "^1.10.1"
+ "@thi.ng/api": "^4.0.4",
+ "@thi.ng/associative": "^0.5.8",
+ "@thi.ng/atom": "^1.4.2",
+ "@thi.ng/checks": "^1.5.5",
+ "@thi.ng/errors": "^0.1.4",
+ "@thi.ng/paths": "^1.3.10",
+ "@thi.ng/transducers": "^1.11.1"
},
"keywords": [
"datastructure",
diff --git a/packages/rstream/src/api.ts b/packages/rstream/src/api.ts
index 1622cee818..ecde79300e 100644
--- a/packages/rstream/src/api.ts
+++ b/packages/rstream/src/api.ts
@@ -25,8 +25,10 @@ export interface ISubscribable extends
IDeref,
IID {
- subscribe(xform: Transducer, id?: string): Subscription;
subscribe(sub: Partial>, xform: Transducer, id?: string): Subscription;
+ // subscribe, C>(sub: S): S;
+ subscribe(sub: Subscription): Subscription;
+ subscribe(xform: Transducer, id?: string): Subscription;
subscribe(sub: Partial>, id?: string): Subscription;
unsubscribe(sub?: Partial>): boolean;
getState(): State;
diff --git a/packages/rstream/src/from/interval.ts b/packages/rstream/src/from/interval.ts
index 381e35f5ec..f1dc1106f3 100644
--- a/packages/rstream/src/from/interval.ts
+++ b/packages/rstream/src/from/interval.ts
@@ -1,5 +1,14 @@
import { Stream } from "../stream";
+/**
+ * Returns a new `Stream` which emits a monotonically increasing counter
+ * value at given `delay` interval, up to an optionally defined max
+ * value (default: ∞), after which the stream is closed. The stream only
+ * starts when the first subscriber becomes available.
+ *
+ * @param delay
+ * @param count
+ */
export function fromInterval(delay: number, count = Number.POSITIVE_INFINITY) {
return new Stream((stream) => {
let i = 0;
diff --git a/packages/rstream/src/from/iterable.ts b/packages/rstream/src/from/iterable.ts
index 2126bdedbf..ea839f13a6 100644
--- a/packages/rstream/src/from/iterable.ts
+++ b/packages/rstream/src/from/iterable.ts
@@ -1,6 +1,18 @@
import { Stream } from "../stream";
-export function fromIterable(src: Iterable, delay = 0) {
+/**
+ * Creates a new `Stream` of given iterable which asynchronously calls
+ * `.next()` for each item of the iterable when the first (and in this
+ * case the only one) subscriber becomes available. The values are
+ * processed via `setInterval()` using the given `delay` value (default:
+ * 0). Once the iterable is exhausted (if finite), then calls `.done()`
+ * by default, but can be avoided by passing `false` as last argument.
+ *
+ * @param src
+ * @param delay
+ * @param close
+ */
+export function fromIterable(src: Iterable, delay = 0, close = true) {
return new Stream(
(stream) => {
const iter = src[Symbol.iterator]();
@@ -8,7 +20,7 @@ export function fromIterable(src: Iterable, delay = 0) {
let val: IteratorResult;
if ((val = iter.next()).done) {
clearInterval(id);
- stream.done();
+ close && stream.done();
} else {
stream.next(val.value);
}
@@ -19,13 +31,23 @@ export function fromIterable(src: Iterable, delay = 0) {
);
}
-export function fromIterableSync(src: Iterable) {
+/**
+ * Creates a new `Stream` of given iterable which synchronously calls
+ * `.next()` for each item of the iterable when the first (and in this
+ * case the only one) subscriber becomes available. Once the iterable is
+ * exhausted (MUST be finite!), then calls `.done()` by default, but can
+ * be avoided by passing `false` as last argument.
+ *
+ * @param src
+ * @param close
+ */
+export function fromIterableSync(src: Iterable, close = true) {
return new Stream(
(stream) => {
for (let s of src) {
stream.next(s);
}
- stream.done();
+ close && stream.done();
return null;
},
`iterable-${Stream.NEXT_ID++}`
diff --git a/packages/rstream/src/pubsub.ts b/packages/rstream/src/pubsub.ts
index 62b0ff888d..e0df7022ef 100644
--- a/packages/rstream/src/pubsub.ts
+++ b/packages/rstream/src/pubsub.ts
@@ -51,7 +51,7 @@ export interface PubSubOpts {
*/
export class PubSub extends Subscription {
- topicfn: (x: B) => PropertyKey;
+ topicfn: (x: B) => any;
topics: EquivMap>;
constructor(opts?: PubSubOpts) {
@@ -81,8 +81,10 @@ export class PubSub extends Subscription {
return null;
}
- subscribeTopic(topicID: any, sub: Partial>, id?: string): Subscription;
subscribeTopic(topicID: any, tx: Transducer, id?: string): Subscription;
+ // subscribeTopic, C>(topicID: any, sub: S): S;
+ subscribeTopic(topicID: any, sub: Subscription): Subscription;
+ subscribeTopic(topicID: any, sub: Partial>, id?: string): Subscription;
subscribeTopic(topicID: any, sub: any, id?: string): Subscription {
let t = this.topics.get(topicID);
if (!t) {
@@ -108,7 +110,6 @@ export class PubSub extends Subscription {
return super.unsubscribe();
}
unsupported();
- return false;
}
done() {
diff --git a/packages/rstream/src/stream.ts b/packages/rstream/src/stream.ts
index 25fe200173..56fc04ff8b 100644
--- a/packages/rstream/src/stream.ts
+++ b/packages/rstream/src/stream.ts
@@ -46,9 +46,11 @@ export class Stream extends Subscription
this.src = src;
}
- subscribe(sub: Partial>, id?: string): Subscription
+ subscribe(sub: Partial>, xform: Transducer, id?: string): Subscription;
+ // subscribe, C>(sub: S): S;
+ subscribe(sub: Subscription): Subscription;
subscribe(xform: Transducer, id?: string): Subscription;
- subscribe(sub: Partial>, xform: Transducer, id?: string): Subscription
+ subscribe(sub: Partial>, id?: string): Subscription;
subscribe(...args: any[]) {
const wrapped = super.subscribe.apply(this, args);
if (this.subs.size === 1) {
diff --git a/packages/rstream/src/subs/bisect.ts b/packages/rstream/src/subs/bisect.ts
index ce788445ec..4a6ac6e058 100644
--- a/packages/rstream/src/subs/bisect.ts
+++ b/packages/rstream/src/subs/bisect.ts
@@ -1,17 +1,41 @@
import { Predicate } from "@thi.ng/api/api";
import { ISubscriber } from "../api";
-import { Subscription } from "../subscription";
+import { PubSub } from "../pubsub";
-export function bisect(pred: Predicate, a?: ISubscriber, b?: ISubscriber) {
- return new Subscription({
- next(x) {
- const sub = pred(x) ? a : b;
- sub.next && sub.next(x);
- },
- done() {
- a.done && a.done();
- b.done && b.done();
- }
- });
+/**
+ * Returns a new `PubSub` instance using given predicate `pred` as
+ * boolean topic function and `a` & `b` as subscribers for truthy (`a`)
+ * and falsey `b` values.
+ *
+ * ```
+ * rs.fromIterable([1,2,3,4]).subscribe(
+ * rs.bisect(
+ * (x) => !(x & 1),
+ * { next: (x) => console.log("even", x) },
+ * { next: (x) => console.log("odd", x) }
+ * )
+ * );
+ * ```
+ *
+ * If `a` or `b` need to be subscribed to directly, then `a` / `b` MUST
+ * be converted into a `Subscription` instance (if not already) and a
+ * reference kept prior to calling `bisect()`.
+ *
+ * ```
+ * const even = new rs.Subscription({next: (x) => console.log("even", x) });
+ * const odd = new rs.Subscription({next: (x) => console.log("odd", x) });
+ *
+ * rs.fromIterable([1,2,3,4]).subscribe(rs.bisect((x) => !(x & 1), even, odd));
+ * ```
+ *
+ * @param pred
+ * @param a
+ * @param b
+ */
+export function bisect(pred: Predicate, a?: ISubscriber, b?: ISubscriber): PubSub {
+ const sub = new PubSub({ topic: pred });
+ sub.subscribeTopic(true, a);
+ sub.subscribeTopic(false, b);
+ return sub;
}
diff --git a/packages/rstream/src/subs/resolve.ts b/packages/rstream/src/subs/resolve.ts
index 4d32653420..dec967adc2 100644
--- a/packages/rstream/src/subs/resolve.ts
+++ b/packages/rstream/src/subs/resolve.ts
@@ -1,12 +1,19 @@
+import { IID } from "@thi.ng/api/api";
import { DEBUG, State } from "../api";
import { Subscription } from "../subscription";
+export interface ResolverOpts extends IID {
+ fail: (e: any) => void;
+}
+
export class Resolver extends Subscription, T> {
protected outstanding = 0;
+ protected fail: (e: any) => void;
- constructor(id?: string) {
- super(null, null, null, id || `resolve-${Subscription.NEXT_ID++}`);
+ constructor(opts: Partial = {}) {
+ super(null, null, null, opts.id || `resolve-${Subscription.NEXT_ID++}`);
+ this.fail = opts.fail;
}
next(x: Promise) {
@@ -22,7 +29,7 @@ export class Resolver extends Subscription, T> {
DEBUG && console.log(`resolved value in ${State[this.state]} state (${x})`);
}
},
- (e) => this.error(e)
+ (e) => (this.fail || this.error)(e)
);
}
@@ -33,6 +40,6 @@ export class Resolver extends Subscription, T> {
}
}
-export function resolve(id?: string) {
- return new Resolver(id);
-}
\ No newline at end of file
+export function resolve(opts?: Partial) {
+ return new Resolver(opts);
+}
diff --git a/packages/rstream/src/subscription.ts b/packages/rstream/src/subscription.ts
index 93359b86a4..e8669fa882 100644
--- a/packages/rstream/src/subscription.ts
+++ b/packages/rstream/src/subscription.ts
@@ -57,9 +57,11 @@ export class Subscription implements
* Creates new child subscription with given subscriber and/or
* transducer and optional subscription ID.
*/
- subscribe(sub: Partial>, id?: string): Subscription
+ subscribe(sub: Partial>, xform: Transducer, id?: string): Subscription;
+ // subscribe, C>(sub: S): S;
+ subscribe(sub: Subscription): Subscription;
subscribe(xform: Transducer, id?: string): Subscription;
- subscribe(sub: Partial>, xform: Transducer, id?: string): Subscription