diff --git a/assets/deps.png b/assets/deps.png index 262ed61ea1..49167257a4 100644 Binary files a/assets/deps.png and b/assets/deps.png differ diff --git a/examples/README.md b/examples/README.md index 5473fbece5..36644f3e44 100644 --- a/examples/README.md +++ b/examples/README.md @@ -18,7 +18,8 @@ If you want to [contribute](../CONTRIBUTING.md) an example, please get in touch | 10 | [pointfree-svg](./pointfree-svg) | generate SVG using pointfree DSL | hiccup, hdom-components, pointfree-lang | intermediate | | 11 | [router-basics](./router-basics) | complete mini SPA | atom, hdom, interceptors, router | advanced | | 12 | [rstream-dataflow](./rstream-dataflow) | dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate | -| 13 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic | -| 13 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate | -| 14 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate | -| 15 | [webgl](./webgl) | Canvas component handling | hdom, hdom-components | basic | +| 13 | [rstream-grid](./rstream-grid) | dataflow graph svg gen | atom, hdom, hiccup-svg, interceptors, rstream-graph, transducers | advanced | +| 14 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic | +| 15 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate | +| 16 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate | +| 17 | [webgl](./webgl) | Canvas component handling | hdom, hdom-components | basic | diff --git a/examples/rstream-grid/README.md b/examples/rstream-grid/README.md new file mode 100644 index 0000000000..6468ec8eee --- /dev/null +++ b/examples/rstream-grid/README.md @@ -0,0 +1,49 @@ +# rstream-grid + +## About + +[Live demo](http://demo.thi.ng/umbrella/rstream-grid/) + +Interactive SVG grid pattern creator with undo, local file download and +implemented as rstream dataflow graph, combined with interceptor event & +side effect handling. + +- [@thi.ng/atom](https://github.com/thi-ng/umbrella/tree/master/packages/atom) +- [@thi.ng/interceptors](https://github.com/thi-ng/umbrella/tree/master/packages/interceptors) +- [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/master/packages/hdom) +- [@thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/master/packages/hiccup-svg) +- [@thi.ng/rstream-graph](https://github.com/thi-ng/umbrella/tree/master/packages/rstream-graph) +- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers) + +## Building + +This example is based on the +[create-hdom-app](https://github.com/thi-ng/create-hdom-app) project +template. + +### Development + +``` +git clone https://github.com/thi-ng/umbrella/ +cd umbrella/examples/rstream-grid +yarn install +yarn start +``` + +Installs all dependencies, runs `webpack-dev-server` and opens the app +in your browser. + +### Production + +``` +yarn build +``` + +Builds a minified version of the app and places it in `/public` +directory. + +## Authors + +- Karsten Schmidt + +© 2018 \ No newline at end of file diff --git a/examples/rstream-grid/index.html b/examples/rstream-grid/index.html new file mode 100644 index 0000000000..cf6fed151f --- /dev/null +++ b/examples/rstream-grid/index.html @@ -0,0 +1,125 @@ + + + + + + + + svg-grid + + + + + + +
+ + + + \ No newline at end of file diff --git a/examples/rstream-grid/package.json b/examples/rstream-grid/package.json new file mode 100644 index 0000000000..8eaf075684 --- /dev/null +++ b/examples/rstream-grid/package.json @@ -0,0 +1,28 @@ +{ + "name": "rstream-grid", + "version": "0.0.1", + "description": "TODO", + "repository": "https://github.com/[your-gh-username]/rs-undo", + "author": "TODO", + "license": "MIT", + "scripts": { + "build": "webpack --mode production --display-reasons --display-modules", + "start": "webpack-dev-server --open --mode development --devtool inline-source-map" + }, + "dependencies": { + "@thi.ng/atom": "latest", + "@thi.ng/hdom": "latest", + "@thi.ng/hiccup-svg": "latest", + "@thi.ng/interceptors": "latest", + "@thi.ng/rstream-graph": "latest", + "@thi.ng/transducers": "latest" + }, + "devDependencies": { + "@types/node": "^9.6.2", + "typescript": "^2.8.1", + "ts-loader": "^4.2.0", + "webpack": "^4.5.0", + "webpack-cli": "^2.0.14", + "webpack-dev-server": "^3.1.3" + } +} \ No newline at end of file diff --git a/examples/rstream-grid/src/api.ts b/examples/rstream-grid/src/api.ts new file mode 100644 index 0000000000..6f788867c0 --- /dev/null +++ b/examples/rstream-grid/src/api.ts @@ -0,0 +1,67 @@ +import { IObjectOf } from "@thi.ng/api/api"; +import { IView, ViewTransform } from "@thi.ng/atom/api"; +import { EffectDef, EventDef } from "@thi.ng/interceptors/api"; +import { EventBus } from "@thi.ng/interceptors/event-bus"; + +/** + * Function signature for main app components. + * I.e. components representing different app states linked to router. + */ +export type AppComponent = (ctx: AppContext, ...args: any[]) => any; + +/** + * Derived view configurations. + */ +export type ViewSpec = string | [string, ViewTransform]; + +/** + * Structure of the overall application config object. + * See `src/config.ts`. + */ +export interface AppConfig { + rootComponent: AppComponent; + domRoot: string | Element; + effects: IObjectOf; + events: IObjectOf; + initialState: any; + ui: UIAttribs; + views: Partial>; +} + +/** + * Base structure of derived views exposed by the base app. + * Add more declarations here as needed. + */ +export interface AppViews extends Record> { + svg: IView; + cols: IView; + rows: IView; + theta: IView; + stroke: IView; +} + +/** + * Helper interface to pre-declare keys of shared UI attributes for + * components and so enable autocomplete & type safety. + * + * See `AppConfig` above and its use in `src/config.ts` and various + * component functions. + */ +export interface UIAttribs { + button: any; + buttongroup: any; + footer: any; + link: any; + root: any; + slider: { root: any, range: any, label: any, number: any }; + sidebar: any; +} + +/** + * Structure of the context object passed to all component functions + */ +export interface AppContext { + bus: EventBus; + views: AppViews; + ui: UIAttribs; +} diff --git a/examples/rstream-grid/src/app.ts b/examples/rstream-grid/src/app.ts new file mode 100644 index 0000000000..b042e6d88e --- /dev/null +++ b/examples/rstream-grid/src/app.ts @@ -0,0 +1,118 @@ +import { IObjectOf } from "@thi.ng/api/api"; +import { Atom } from "@thi.ng/atom/atom"; +import { Cursor } from "@thi.ng/atom/cursor"; +import { History } from "@thi.ng/atom/history"; +import { isArray } from "@thi.ng/checks/is-array"; +import { start } from "@thi.ng/hdom/start"; +import { EventBus } from "@thi.ng/interceptors/event-bus"; + +import { + AppConfig, + AppContext, + AppViews, + ViewSpec +} from "./api"; +import { initDataflow } from "./dataflow"; +import * as ev from "./events"; +import { PARAM_BASE } from "./paths"; + +/** + * The app does not much more than: + * + * - initialize state, undo history, event bus, dataflow graph + * - attach derived views + * - start hdom render & event bus loop + */ +export class App { + + config: AppConfig; + ctx: AppContext; + state: Atom; + history: History; + + constructor(config: AppConfig) { + this.config = config; + this.state = new Atom(config.initialState || {}); + // note: the undo history only records the `PARAM_BASE` branch + // in the app state atom. this is so we don't include the generated + // SVG in the history and therefore save a lot of RAM + // furthermore, the param changes trigger updates in the dataflow graph + // (see `init()` method below) and will regenerate the SVG anyway + this.history = new History(new Cursor(this.state, PARAM_BASE), 1000); + // define context object passed to all UI component functions + this.ctx = { + bus: new EventBus(this.state, config.events, config.effects), + views: {}, + ui: config.ui, + }; + // initialize derived views + this.addViews(this.config.views); + } + + /** + * Initializes given derived view specs and attaches them to app + * state atom. + * + * @param specs + */ + addViews(specs: IObjectOf) { + const views = this.ctx.views; + for (let id in specs) { + const spec = specs[id]; + if (isArray(spec)) { + views[id] = this.state.addView(spec[0], spec[1]); + } else { + views[id] = this.state.addView(spec); + } + } + } + + /** + * Calls `init()` and kicks off hdom render loop, including batched + * event processing and fast fail check if DOM updates are necessary + * (assumes ALL state is held in the app state atom). So if there + * weren't any events causing a state change since last frame, + * re-rendering is skipped without even attempting to diff DOM + * tree). + */ + start() { + this.init(); + // assume main root component is a higher order function + // call it here to pre-initialize + const root = this.config.rootComponent(this.ctx); + let firstFrame = true; + start( + this.config.domRoot, + () => { + if (this.ctx.bus.processQueue({ history: this.history }) || firstFrame) { + firstFrame = false; + return root(); + } + }, + this.ctx + ); + } + + /** + * User initialization hook. + * Automatically called from `start()` + */ + init() { + // initialize dataflow graph + initDataflow(this.ctx.bus); + + // initialize key event handlers for undo/redo + document.addEventListener("keypress", (e) => { + if (e.ctrlKey) { + if (e.key === "z") { + this.ctx.bus.dispatch([ev.UNDO]); + } else if (e.key === "y") { + this.ctx.bus.dispatch([ev.REDO]); + } + } + }); + + // record snapshot of initial state + this.history.record(); + } +} diff --git a/examples/rstream-grid/src/components/button-group.ts b/examples/rstream-grid/src/components/button-group.ts new file mode 100644 index 0000000000..acc7cab85a --- /dev/null +++ b/examples/rstream-grid/src/components/button-group.ts @@ -0,0 +1,5 @@ +import { AppContext } from "../api"; +import { button } from "./button"; + +export const buttonGroup = (ctx: AppContext, ...buttons) => + ["section", ctx.ui.buttongroup, buttons.map((bt) => [button, ...bt])]; diff --git a/examples/rstream-grid/src/components/button.ts b/examples/rstream-grid/src/components/button.ts new file mode 100644 index 0000000000..73518110e4 --- /dev/null +++ b/examples/rstream-grid/src/components/button.ts @@ -0,0 +1,5 @@ +import { AppContext } from "../api"; +import { eventLink } from "./event-link"; + +export const button = (ctx: AppContext, event: Event, label: string) => + [eventLink, ctx.ui.button, event, label]; diff --git a/examples/rstream-grid/src/components/event-link.ts b/examples/rstream-grid/src/components/event-link.ts new file mode 100644 index 0000000000..ddc4c8bb7a --- /dev/null +++ b/examples/rstream-grid/src/components/event-link.ts @@ -0,0 +1,23 @@ +import { Event } from "@thi.ng/interceptors/api"; + +import { AppContext } from "../api"; + +/** + * Customizable hyperlink component emitting given event on event bus + * when clicked. + * + * @param ctx + * @param event event tuple of `[event-id, payload]` + * @param attribs element attribs + * @param body link body + */ +export const eventLink = (ctx: AppContext, attribs: any, event: Event, body: any) => + ["a", + { + ...attribs, + onclick: (e) => { + e.preventDefault(); + ctx.bus.dispatch(event); + } + }, + body]; diff --git a/examples/rstream-grid/src/components/link.ts b/examples/rstream-grid/src/components/link.ts new file mode 100644 index 0000000000..dd2890452c --- /dev/null +++ b/examples/rstream-grid/src/components/link.ts @@ -0,0 +1,4 @@ +import { AppContext } from "../api"; + +export const link = (ctx: AppContext, href, ...body) => + ["a", { ...ctx.ui.link, href }, ...body]; diff --git a/examples/rstream-grid/src/components/main.ts b/examples/rstream-grid/src/components/main.ts new file mode 100644 index 0000000000..8474453a0e --- /dev/null +++ b/examples/rstream-grid/src/components/main.ts @@ -0,0 +1,9 @@ +import { AppContext } from "../api"; +import { sidebar } from "./sidebar"; + +import { SLIDERS } from "../sliders"; + +export const main = (ctx: AppContext) => { + const bar = sidebar(ctx, ...SLIDERS); + return () => ["div", ctx.ui.root, bar, ctx.views.svg]; +}; diff --git a/examples/rstream-grid/src/components/sidebar.ts b/examples/rstream-grid/src/components/sidebar.ts new file mode 100644 index 0000000000..9256747aed --- /dev/null +++ b/examples/rstream-grid/src/components/sidebar.ts @@ -0,0 +1,30 @@ +import { AppContext } from "../api"; +import * as ev from "../events"; + +import { buttonGroup } from "./button-group"; +import { link } from "./link"; +import { slider, SliderOpts } from "./slider"; + +export const sidebar = (ctx: AppContext, ...specs: SliderOpts[]) => { + const sliders = specs.map((s) => slider(ctx, s)); + return ["div", ctx.ui.sidebar.root, + ["h3", ctx.ui.sidebar.title, "@thi.ng/rstream grid"], + ...sliders, + [buttonGroup, + [[ev.UNDO], "undo"], + [[ev.REDO], "redo"]], + [buttonGroup, + [[ev.SAVE_SVG], "download svg"]], + [buttonGroup, + [[ev.SAVE_ANIM], "download anim"]], + ["div", + "Undo / Redo can also be triggered via ", + ["code", "Ctrl+Z"], " / ", ["code", "Ctrl+Y"], + ". The last 1000 edits are stored."], + ["div", ctx.ui.footer, + [link, "https://github.com/thi-ng/umbrella/tree/master/examples/rstream-grid", "Source"], + ["br"], + "Made with ", + [link, "https://github.com/thi-ng/umbrella/", "@thi.ng/umbrella"]] + ]; +}; diff --git a/examples/rstream-grid/src/components/slider.ts b/examples/rstream-grid/src/components/slider.ts new file mode 100644 index 0000000000..9aa50cd633 --- /dev/null +++ b/examples/rstream-grid/src/components/slider.ts @@ -0,0 +1,50 @@ +import { AppContext } from "../api"; + +export interface SliderOpts { + event: PropertyKey; + view: PropertyKey; + label: string; + min?: number; + max?: number; + step?: number; +} + +/** + * Higher-order slider component using both an HTML5 range and number + * control connected to the same derived view of an app state value. + * Changes as dispatched via event configured via `opts` object. + * + * Because it's an higher order component, it CANNOT be used in an + * inline manner in the parent component and must be initialized + * separately. + * + * See `main.ts` for usage. + * + * @param ctx + * @param opts + */ +export const slider = (ctx: AppContext, opts: SliderOpts) => { + opts = Object.assign({ + oninput: (e) => ctx.bus.dispatch([opts.event, parseFloat(e.target.value)]), + min: 0, + max: 100, + step: 1, + }, opts); + const ui = ctx.ui.slider; + return () => + ["section", ui.root, + ["input", + { + ...ui.range, + ...opts, + type: "range", + value: ctx.views[opts.view].deref(), + }], + ["div", ui.label, opts.label, + ["input", { + ...ui.number, + ...opts, + type: "number", + value: ctx.views[opts.view].deref(), + }]]]; +}; diff --git a/examples/rstream-grid/src/config.ts b/examples/rstream-grid/src/config.ts new file mode 100644 index 0000000000..5b08bd848b --- /dev/null +++ b/examples/rstream-grid/src/config.ts @@ -0,0 +1,118 @@ +import { serialize } from "@thi.ng/hiccup/serialize"; +import { snapshot, valueSetter } from "@thi.ng/interceptors/interceptors"; +import { getIn } from "@thi.ng/paths"; +import { fromIterable } from "@thi.ng/rstream/from/iterable"; +import { range } from "@thi.ng/transducers/iter/range"; + +import { AppConfig } from "./api"; +import { main } from "./components/main"; +import { download } from "./download"; +import * as fx from "./effects"; +import * as ev from "./events"; +import * as paths from "./paths"; +import { SLIDERS } from "./sliders"; + +const FG_COL = "light-silver"; +const LINK_COL = "white"; + +// main App configuration +export const CONFIG: AppConfig = { + + // event handlers events are queued and batch processed in app's RAF + // render loop event handlers can be single functions, interceptor + // objects with `pre`/`post` keys or arrays of either. + + // the event handlers' only task is to transform the event into a + // number of side effects. event handlers should be pure functions + // and only side effect functions execute any "real" work. + + // Docs here: + // https://github.com/thi-ng/umbrella/blob/master/packages/interceptors/src/event-bus.ts#L14 + events: { + // generate slider event handlers. each uses the `snapshot()` + // interceptor to record a snapshot of the current app state + // before applying new slider value + ...SLIDERS.reduce( + (events, spec) => + (events[spec.event] = [ + snapshot(), + valueSetter(spec.path) + ], events), + {}), + [ev.UPDATE_SVG]: [valueSetter(paths.SVG)], + [ev.SAVE_SVG]: (state) => ({ [fx.SAVE_SVG]: getIn(state, paths.SVG) }), + [ev.SAVE_ANIM]: () => ({ [fx.SAVE_ANIM]: true }) + }, + + // custom side effects + effects: { + // prepares given hiccup format SVG doc with bounds + // then uses @thi.ng/hiccup to serialize to XML syntax + // finally triggers download to local disk + [fx.SAVE_SVG]: (src) => { + src = src.slice(); + src[1] = { ...src[1], width: 1000, height: 1000 }; + download(`grid-${Date.now()}.svg`, serialize(src)); + }, + // triggers download of 18 svg files (each delayed by 1sec), + // each with a different rotation in the 0-90 degrees interval + [fx.SAVE_ANIM]: (_, bus) => + fromIterable(range(0, 90, 5), 1000) + .subscribe({ + next: (x) => { + bus.dispatch([ev.SET_THETA, x]); + bus.dispatchLater([ev.SAVE_SVG]); + } + }) + }, + + rootComponent: main, + + // DOM root element (or ID) + domRoot: "app", + + // initial app state + initialState: { + [paths.PARAM_BASE]: { + cols: 5, + rows: 5, + theta: 35, + stroke: 0.3, + } + }, + + // derived view declarations + // each key specifies the name of the view and each value is + // a state path or `[path, transformer]` tuple + + // docs here: + // https://github.com/thi-ng/umbrella/tree/master/packages/atom#derived-views + views: { + cols: paths.COLS, + rows: paths.ROWS, + stroke: paths.STROKE, + theta: paths.THETA, + svg: paths.SVG, + }, + + // component CSS class config using http://tachyons.io/ + // these attribs are being passed to all component functions + // as part of the AppContext object + ui: { + button: { class: `pointer bg-${FG_COL} hover-bg-${LINK_COL} bg-animate black pa2 mr1 w-100 ttu b tracked-tight` }, + buttongroup: { class: "flex mb1" }, + footer: { class: "absolute bottom-1" }, + link: { class: `pointer link dim ${LINK_COL} b` }, + root: { class: "vw-100 vh-100 flex" }, + sidebar: { + root: { class: `bg-near-black pa2 pt3 w5 f7 ${FG_COL}` }, + title: { class: `mt0 ${FG_COL}` }, + }, + slider: { + root: { class: `mb3 ttu b tracked-tight ${FG_COL}` }, + range: { class: "w-100" }, + label: { class: "pl2" }, + number: { class: `fr w3 tr ttu bn bg-transparent ${FG_COL}` }, + }, + } +}; diff --git a/examples/rstream-grid/src/dataflow.ts b/examples/rstream-grid/src/dataflow.ts new file mode 100644 index 0000000000..ca47c6df4f --- /dev/null +++ b/examples/rstream-grid/src/dataflow.ts @@ -0,0 +1,99 @@ +import { svgdoc } from "@thi.ng/hiccup-svg/doc"; +import { group } from "@thi.ng/hiccup-svg/group"; +import { rect } from "@thi.ng/hiccup-svg/rect"; +import { EventBus } from "@thi.ng/interceptors/event-bus"; +import { initGraph, node } from "@thi.ng/rstream-graph/graph"; +import { range2d } from "@thi.ng/transducers/iter/range2d"; +import { iterator } from "@thi.ng/transducers/iterator"; +import { map } from "@thi.ng/transducers/xform/map"; + +import * as ev from "./events"; +import * as paths from "./paths"; + +/** + * Initializes data flow graph for generating SVG grid. Some of the + * nodes are using subscriptions to value changes in certain + * paths/locations in the app state atom. The final node (`svg`) in the + * graph triggers the `UPDATE_SVG` event each time a new value has been + * produced. In turn, this event will update the app state and so + * trigger a DOM update to display the new result. + * + * @param bus + */ +export function initDataflow(bus: EventBus) { + const graph = initGraph(bus.state, { + grid: { + fn: grid, + ins: { + cols: { path: paths.COLS }, + rows: { path: paths.ROWS }, + }, + }, + rotation: { + fn: rotate, + ins: { + shapes: { stream: "grid" }, + theta: { path: paths.THETA }, + }, + }, + svg: { + fn: createSVG, + ins: { + shapes: { stream: "rotation" }, + 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]) + }) + } + }); + return graph; +}; + +/** + * Implementation for grid generator node. + */ +const grid = node(map( + ({ cols, rows }) => + [...iterator( + map(([x, y]) => ["rect", { x, y, width: 1, height: 1 }]), + range2d(cols, rows) + )])); + +/** + * Implementation for rotate node. Injects SVG `transform` attribute in + * all received shapes. + */ +const rotate = node(map( + ({ shapes, theta }) => + [...iterator( + map((s) => (s[1].transform = `rotate(${theta} ${s[1].x + 0.5} ${s[1].y + 0.5})`, s)), + shapes)] +)); + +/** + * Implementation for svg dataflow node. Wraps received shapes as + * complete svg document in hiccup format. + */ +const createSVG = node(map( + ({ shapes, cols, rows, stroke }) => + svgdoc( + { + class: "w-100 h-100", + preserveAspectRatio: "xMidYMid", + viewBox: `-1 -1 ${cols + 2} ${rows + 2}` + }, + rect([-1, -1], cols + 2, rows + 2, { fill: "black" }), + group( + { + stroke: "white", + fill: "none", + "stroke-width": stroke, + }, + ...shapes + ) + ) +)); diff --git a/examples/rstream-grid/src/download.ts b/examples/rstream-grid/src/download.ts new file mode 100644 index 0000000000..07169e5e89 --- /dev/null +++ b/examples/rstream-grid/src/download.ts @@ -0,0 +1,24 @@ +/** + * Helper function to trigger download of given `src` string as local + * file with filename `name` and mime `type`. Wraps `src` as blob and + * creates an object URL for download. By default, the URL auto-expires + * after 10 seconds to free up memory. + * + * @param name + * @param src + * @param type + * @param expire + */ +export function download(name: string, src: string, type = "image/svg", expire = 10000) { + const blob = new Blob([src], { type }); + const uri = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.download = name; + a.href = uri; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + if (uri.indexOf("blob:") === 0) { + setTimeout(() => URL.revokeObjectURL(uri), expire); + } +} diff --git a/examples/rstream-grid/src/effects.ts b/examples/rstream-grid/src/effects.ts new file mode 100644 index 0000000000..32593dd7d2 --- /dev/null +++ b/examples/rstream-grid/src/effects.ts @@ -0,0 +1,7 @@ +// best practice tip: define event & effect names as consts or enums +// and avoid hardcoded strings for more safety and easier refactoring +// also see pre-defined event handlers & interceptors in @thi.ng/atom: +// https://github.com/thi-ng/umbrella/blob/master/packages/interceptors/src/api.ts#L14 + +export const SAVE_SVG = "save-svg"; +export const SAVE_ANIM = "save-anim"; diff --git a/examples/rstream-grid/src/events.ts b/examples/rstream-grid/src/events.ts new file mode 100644 index 0000000000..3868641694 --- /dev/null +++ b/examples/rstream-grid/src/events.ts @@ -0,0 +1,16 @@ +import { EV_UNDO, EV_REDO } from "@thi.ng/interceptors/api"; + +// best practice tip: define event & effect names as consts or enums +// and avoid hardcoded strings for more safety and easier refactoring +// also see pre-defined event handlers & interceptors in @thi.ng/atom: +// https://github.com/thi-ng/umbrella/blob/master/packages/interceptors/src/api.ts#L14 + +export const UNDO = EV_UNDO; +export const REDO = EV_REDO; +export const UPDATE_SVG = "update-svg"; +export const SAVE_SVG = "save-svg"; +export const SAVE_ANIM = "save-anim"; +export const SET_COLS = "set-cols"; +export const SET_ROWS = "set-rows"; +export const SET_STROKE = "set-stroke"; +export const SET_THETA = "set-theta"; diff --git a/examples/rstream-grid/src/index.ts b/examples/rstream-grid/src/index.ts new file mode 100644 index 0000000000..8ebcb7ec8c --- /dev/null +++ b/examples/rstream-grid/src/index.ts @@ -0,0 +1,10 @@ +import { App } from "./app"; +import { CONFIG } from "./config"; + +// export app to global var in dev mode +// (for interaction via browser dev tools) +if (process.env.NODE_ENV === "development") { + (window["APP"] = new App(CONFIG)).start(); +} else { + new App(CONFIG).start(); +} diff --git a/examples/rstream-grid/src/paths.ts b/examples/rstream-grid/src/paths.ts new file mode 100644 index 0000000000..b28b1c9fb6 --- /dev/null +++ b/examples/rstream-grid/src/paths.ts @@ -0,0 +1,9 @@ +// single source of truth definitions for parameter paths in central +// app state atom + +export const PARAM_BASE = "params"; +export const COLS = `${PARAM_BASE}.cols`; +export const ROWS = `${PARAM_BASE}.rows`; +export const THETA = `${PARAM_BASE}.theta`; +export const STROKE = `${PARAM_BASE}.stroke`; +export const SVG = "svg"; diff --git a/examples/rstream-grid/src/sliders.ts b/examples/rstream-grid/src/sliders.ts new file mode 100644 index 0000000000..2b7c426d80 --- /dev/null +++ b/examples/rstream-grid/src/sliders.ts @@ -0,0 +1,13 @@ +import * as ev from "./events"; +import * as paths from "./paths"; + +/** + * Slider definitions used to generate UI components and their + * respective event handlers. + */ +export const SLIDERS = [ + { event: ev.SET_COLS, path: paths.COLS, view: "cols", label: "cols", min: 1, max: 16 }, + { event: ev.SET_ROWS, path: paths.ROWS, view: "rows", label: "rows", min: 1, max: 16 }, + { event: ev.SET_THETA, path: paths.THETA, view: "theta", label: "rotate", min: 0, max: 360 }, + { event: ev.SET_STROKE, path: paths.STROKE, view: "stroke", label: "stroke weight", min: 0.01, max: 0.5, step: 0.01 }, +]; diff --git a/examples/rstream-grid/tsconfig.json b/examples/rstream-grid/tsconfig.json new file mode 100644 index 0000000000..acab3b01c9 --- /dev/null +++ b/examples/rstream-grid/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES6", + "outDir": "build", + "experimentalDecorators": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "sourceMap": true, + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": [ + "./**/node_modules" + ] +} \ No newline at end of file diff --git a/examples/rstream-grid/webpack.config.js b/examples/rstream-grid/webpack.config.js new file mode 100644 index 0000000000..e2bf1e8d3a --- /dev/null +++ b/examples/rstream-grid/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/todo-list/src/index.ts b/examples/todo-list/src/index.ts index c73db64bde..7b5767714e 100644 --- a/examples/todo-list/src/index.ts +++ b/examples/todo-list/src/index.ts @@ -1,14 +1,3 @@ -/* - * Obligatory Todo list demo (in < 50 LOC excl. comments) - * Total filesize: 18KB minified - * - * Other packages used: - * - @thi.ng/atom for state handling - * - @thi.ng/transducers for task list processing - * - * @author Karsten Schmidt - */ - import { IObjectOf } from "@thi.ng/api/api"; import { Atom, Cursor, History } from "@thi.ng/atom"; import { start } from "@thi.ng/hdom/start"; @@ -28,6 +17,11 @@ const db = new Atom({ tasks: {}, nextID: 0 }); const tasks = new History>(new Cursor(db, "tasks"), 100); // cursor for direct access to `nextID` const nextID = new Cursor(db, "nextID"); +// create derived view of tasks transformed into components +const items = db.addView( + "tasks", + (tasks) => [...iterator(map(([id, t]) => taskItem(id, t)), pairs(tasks))] +); // state updaters // each applies its updates via the history atom wrapper @@ -37,43 +31,47 @@ const toggleTask = (id) => tasks.swap((tasks) => updateIn(tasks, [id, "done"], d const updateTask = (id, body) => tasks.swap((tasks) => setIn(tasks, [id, "body"], body)); // single task component -// the text field uses lifecycle hooks to set keyboard focus for new tasks -const taskItem = (id, task: Task) => - ["div", +const taskItem = (id, task: Task) => { + const checkAttribs = { + type: "checkbox", + checked: task.done, + onclick: () => toggleTask(id), + }; + const textAttribs = { + type: "text", + placeholder: "todo...", + value: task.body, + onkeydown: (e) => e.key === "Enter" && e.target.blur(), + onblur: (e) => updateTask(id, (e.target).value) + }; + return ["div", { class: "task" + (task.done ? " done" : "") }, - ["input", - { - type: "checkbox", - checked: task.done, - onclick: () => toggleTask(id), - }], - [{ - init: (el) => !el.value && el.focus(), - render: () => - ["input", - { - type: "text", - placeholder: "todo...", - value: task.body, - onkeydown: (e) => e.key === "Enter" && e.target.blur(), - onblur: (e) => updateTask(id, (e.target).value) - }] - }]]; + ["input", checkAttribs], + ["input", textAttribs]] +}; // complete task list // uses transducer to transform all tasks using above component function const taskList = () => { - const tasks = db.deref().tasks; - return Object.keys(tasks).length ? - ["div#tasks", ...iterator(map(([id, t]) => taskItem(id, t)), pairs(tasks))] : + const _items = items.deref(); + return _items.length ? + ["div#tasks", _items] : ["div", "nothing todo, get busy..."]; }; -const toolbar = () => - ["div#toolbar", - ["button", { onclick: () => addNewTask() }, "+ Add"], - ["button", { onclick: () => tasks.undo(), disabled: !tasks.canUndo() }, "Undo"], - ["button", { onclick: () => tasks.redo(), disabled: !tasks.canRedo() }, "Redo"]]; +const button = (onclick, body) => + (_, disabled) => ["button", { onclick, disabled }, body]; + +const toolbar = () => { + const btAdd = button(() => addNewTask(), "+ Add"); + const btUndo = button(() => tasks.undo(), "Undo"); + const btRedo = button(() => tasks.redo(), "Redo"); + return () => + ["div#toolbar", + [btAdd], + [btUndo, !tasks.canUndo()], + [btRedo, !tasks.canRedo()]]; +}; // static header component (simple array) const header = @@ -81,5 +79,9 @@ const header = ["small", "made with \u2764 ", ["a", { href: "https://github.com/thi-ng/umbrella/tree/master/packages/hdom" }, "@thi.ng/hdom"]]]; +const app = () => { + return ["div", header, toolbar(), taskList] +}; + // kick off UI w/ root component function -start("app", () => ["div", header, toolbar, taskList]); +start("app", app()); diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index defd6bd200..fc2958d2e2 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [2.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@2.3.0...@thi.ng/api@2.3.1) (2018-04-29) + + +### Performance Improvements + +* **api:** major speedup equivObject(), update equivSet() ([7fdf172](https://github.com/thi-ng/umbrella/commit/7fdf172)) + + + + # [2.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@2.2.0...@thi.ng/api@2.3.0) (2018-04-26) diff --git a/packages/api/package.json b/packages/api/package.json index 2c84f0cf60..8e3961f500 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/api", - "version": "2.3.0", + "version": "2.3.1", "description": "Common, generic types & interfaces for thi.ng projects", "main": "./index.js", "typings": "./index.d.ts", @@ -24,7 +24,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/checks": "^1.5.0" + "@thi.ng/checks": "^1.5.1" }, "keywords": [ "compare", diff --git a/packages/api/src/equiv.ts b/packages/api/src/equiv.ts index 3f1f07981c..d1f31abdd4 100644 --- a/packages/api/src/equiv.ts +++ b/packages/api/src/equiv.ts @@ -32,8 +32,11 @@ export function equiv(a, b): boolean { if (isArrayLike(a) && isArrayLike(b)) { return equivArrayLike(a, b); } - if ((isSet(a) && isSet(b)) || (isMap(a) && isMap(b))) { - return equivSetLike(a, b); + if (isSet(a) && isSet(b)) { + return equivSet(a, b); + } + if (isMap(a) && isMap(b)) { + return equivMap(a, b); } if (isDate(a) && isDate(b)) { return a.getTime() === b.getTime(); @@ -53,22 +56,24 @@ function equivArrayLike(a: ArrayLike, b: ArrayLike) { return l < 0; } -function equivSetLike(a: Set, b: Set) { +function equivSet(a: Set, b: Set) { + if (a.size !== b.size) return false; + return equiv([...a.keys()].sort(), [...b.keys()].sort()); +} + +function equivMap(a: Map, b: Map) { if (a.size !== b.size) return false; return equiv([...a].sort(), [...b].sort()); } function equivObject(a, b) { - const keys = new Set(Object.keys(a).concat(Object.keys(b))); - for (let k of keys) { - if (a.hasOwnProperty(k)) { - if (b.hasOwnProperty(k)) { - if (equiv(a[k], b[k])) { - continue; - } - } + const ka = Object.keys(a); + if (ka.length !== Object.keys(b).length) return false; + for (let i = ka.length, k; --i >= 0;) { + k = ka[i]; + if (!b.hasOwnProperty(k) || !equiv(a[k], b[k])) { + return false; } - return false; } return true; } diff --git a/packages/associative/CHANGELOG.md b/packages/associative/CHANGELOG.md index 9e2bf83e6b..1972097b6f 100644 --- a/packages/associative/CHANGELOG.md +++ b/packages/associative/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.4.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.4.5...@thi.ng/associative@0.4.6) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/associative + ## [0.4.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@0.4.4...@thi.ng/associative@0.4.5) (2018-04-26) diff --git a/packages/associative/package.json b/packages/associative/package.json index dd9541d466..7f25322332 100644 --- a/packages/associative/package.json +++ b/packages/associative/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/associative", - "version": "0.4.5", + "version": "0.4.6", "description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations", "main": "./index.js", "typings": "./index.d.ts", @@ -24,9 +24,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/dcons": "^0.3.2", - "@thi.ng/iterators": "^4.1.8" + "@thi.ng/api": "^2.3.1", + "@thi.ng/dcons": "^0.3.3", + "@thi.ng/iterators": "^4.1.9" }, "keywords": [ "data structures", diff --git a/packages/atom/CHANGELOG.md b/packages/atom/CHANGELOG.md index f5bd2ced14..8130bd9728 100644 --- a/packages/atom/CHANGELOG.md +++ b/packages/atom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.3.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.3.5...@thi.ng/atom@1.3.6) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/atom + ## [1.3.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@1.3.4...@thi.ng/atom@1.3.5) (2018-04-26) diff --git a/packages/atom/package.json b/packages/atom/package.json index 30ca7aef46..166ce89a2c 100644 --- a/packages/atom/package.json +++ b/packages/atom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/atom", - "version": "1.3.5", + "version": "1.3.6", "description": "Mutable wrapper for immutable values", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/paths": "^1.3.2" + "@thi.ng/api": "^2.3.1", + "@thi.ng/paths": "^1.3.3" }, "keywords": [ "cursor", diff --git a/packages/bitstream/CHANGELOG.md b/packages/bitstream/CHANGELOG.md index 955c2e5b26..5f2dd3beb5 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.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitstream@0.4.6...@thi.ng/bitstream@0.4.7) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/bitstream + ## [0.4.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitstream@0.4.5...@thi.ng/bitstream@0.4.6) (2018-04-26) diff --git a/packages/bitstream/package.json b/packages/bitstream/package.json index 5e0ac091b9..e4e7b80b23 100644 --- a/packages/bitstream/package.json +++ b/packages/bitstream/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/bitstream", - "version": "0.4.6", + "version": "0.4.7", "description": "ES6 iterator based read/write bit streams & support for variable word widths", "main": "./index.js", "typings": "./index.d.ts", @@ -16,7 +16,7 @@ "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "devDependencies": { "@types/mocha": "^5.0.0", diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md index b52cc0d379..5b83bd1405 100644 --- a/packages/cache/CHANGELOG.md +++ b/packages/cache/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.3...@thi.ng/cache@0.2.4) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/cache + ## [0.2.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@0.2.2...@thi.ng/cache@0.2.3) (2018-04-26) diff --git a/packages/cache/package.json b/packages/cache/package.json index f0c023b003..ed32b53559 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/cache", - "version": "0.2.3", + "version": "0.2.4", "description": "In-memory cache implementations with ES6 Map-like API and different eviction strategies", "main": "./index.js", "typings": "./index.d.ts", @@ -24,9 +24,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/dcons": "^0.3.2", - "@thi.ng/iterators": "^4.1.8" + "@thi.ng/api": "^2.3.1", + "@thi.ng/dcons": "^0.3.3", + "@thi.ng/iterators": "^4.1.9" }, "keywords": [ "cache", diff --git a/packages/checks/CHANGELOG.md b/packages/checks/CHANGELOG.md index 1264f81fb3..505c5eef0f 100644 --- a/packages/checks/CHANGELOG.md +++ b/packages/checks/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.5.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.5.0...@thi.ng/checks@1.5.1) (2018-04-29) + + +### Bug Fixes + +* **checks:** exclude functions in isArrayLike() ([ac60404](https://github.com/thi-ng/umbrella/commit/ac60404)) +* **checks:** return type isMap() ([76920f7](https://github.com/thi-ng/umbrella/commit/76920f7)) + + + + # [1.5.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@1.4.0...@thi.ng/checks@1.5.0) (2018-04-26) diff --git a/packages/checks/package.json b/packages/checks/package.json index 5a3d892923..c1de4c39b3 100644 --- a/packages/checks/package.json +++ b/packages/checks/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/checks", - "version": "1.5.0", + "version": "1.5.1", "description": "Single-function sub-modules for type, feature & value checks", "main": "./index.js", "typings": "./index.d.ts", diff --git a/packages/checks/src/is-arraylike.ts b/packages/checks/src/is-arraylike.ts index a770a5b345..7824d8f9dc 100644 --- a/packages/checks/src/is-arraylike.ts +++ b/packages/checks/src/is-arraylike.ts @@ -1,3 +1,3 @@ export function isArrayLike(x: any): x is ArrayLike { - return Array.isArray(x) || (x != null && x.length !== undefined); + return (x != null && typeof x !== "function" && x.length !== undefined); } diff --git a/packages/checks/src/is-map.ts b/packages/checks/src/is-map.ts index cf8bb3ed2f..d895c5decc 100644 --- a/packages/checks/src/is-map.ts +++ b/packages/checks/src/is-map.ts @@ -1,3 +1,3 @@ -export function isMap(x: any): x is Set { +export function isMap(x: any): x is Map { return x instanceof Map; } diff --git a/packages/checks/test/index.ts b/packages/checks/test/index.ts index 98fb3b7059..a735b68aa5 100644 --- a/packages/checks/test/index.ts +++ b/packages/checks/test/index.ts @@ -62,6 +62,7 @@ describe("checks", function () { assert(!isArrayLike(0), "zero"); assert(!isArrayLike(null), "null"); assert(!isArrayLike(undefined), "null"); + assert(!isArrayLike((x, y) => x + y), "null"); }); it("isObject", () => { diff --git a/packages/csp/CHANGELOG.md b/packages/csp/CHANGELOG.md index 158f248c61..75ba56a087 100644 --- a/packages/csp/CHANGELOG.md +++ b/packages/csp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.3.32](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.31...@thi.ng/csp@0.3.32) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/csp + ## [0.3.31](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@0.3.30...@thi.ng/csp@0.3.31) (2018-04-26) diff --git a/packages/csp/package.json b/packages/csp/package.json index 0f4a599937..a7b6c72d30 100644 --- a/packages/csp/package.json +++ b/packages/csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/csp", - "version": "0.3.31", + "version": "0.3.32", "description": "ES6 promise based CSP implementation", "main": "./index.js", "typings": "./index.d.ts", @@ -28,8 +28,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/dcons": "^0.3.2", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/dcons": "^0.3.3", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "async", diff --git a/packages/dcons/CHANGELOG.md b/packages/dcons/CHANGELOG.md index 4ef560d035..ea2e37d2e7 100644 --- a/packages/dcons/CHANGELOG.md +++ b/packages/dcons/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.3.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@0.3.2...@thi.ng/dcons@0.3.3) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/dcons + ## [0.3.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@0.3.1...@thi.ng/dcons@0.3.2) (2018-04-26) diff --git a/packages/dcons/package.json b/packages/dcons/package.json index 5ef78ede7e..842777fc58 100644 --- a/packages/dcons/package.json +++ b/packages/dcons/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dcons", - "version": "0.3.2", + "version": "0.3.3", "description": "Comprehensive doubly linked list structure w/ iterator support", "main": "./index.js", "typings": "./index.d.ts", @@ -24,7 +24,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "keywords": [ "datastructure", diff --git a/packages/dgraph/CHANGELOG.md b/packages/dgraph/CHANGELOG.md index 50a4a4554e..dfdfd61b84 100644 --- a/packages/dgraph/CHANGELOG.md +++ b/packages/dgraph/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.1.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.1.8...@thi.ng/dgraph@0.1.9) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/dgraph + ## [0.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@0.1.7...@thi.ng/dgraph@0.1.8) (2018-04-26) diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json index bc97469e39..044da28f32 100644 --- a/packages/dgraph/package.json +++ b/packages/dgraph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dgraph", - "version": "0.1.8", + "version": "0.1.9", "description": "Type-agnostic directed acyclic graph (DAG) & graph operations", "main": "./index.js", "typings": "./index.d.ts", @@ -24,9 +24,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/associative": "^0.4.5", - "@thi.ng/iterators": "^4.1.8" + "@thi.ng/api": "^2.3.1", + "@thi.ng/associative": "^0.4.6", + "@thi.ng/iterators": "^4.1.9" }, "keywords": [ "data structure", diff --git a/packages/diff/CHANGELOG.md b/packages/diff/CHANGELOG.md index bc9789af11..86a4ea2510 100644 --- a/packages/diff/CHANGELOG.md +++ b/packages/diff/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.0.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.0.8...@thi.ng/diff@1.0.9) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/diff + ## [1.0.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@1.0.7...@thi.ng/diff@1.0.8) (2018-04-26) diff --git a/packages/diff/package.json b/packages/diff/package.json index ea1118d149..ce7ac613f7 100644 --- a/packages/diff/package.json +++ b/packages/diff/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/diff", - "version": "1.0.8", + "version": "1.0.9", "description": "Array & object Diff", "main": "./index.js", "typings": "./index.d.ts", @@ -22,7 +22,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "keywords": [ "array", diff --git a/packages/hdom-components/CHANGELOG.md b/packages/hdom-components/CHANGELOG.md index 24debd9671..e50f71880e 100644 --- a/packages/hdom-components/CHANGELOG.md +++ b/packages/hdom-components/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [2.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.0.2...@thi.ng/hdom-components@2.0.3) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/hdom-components + ## [2.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@2.0.1...@thi.ng/hdom-components@2.0.2) (2018-04-26) diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index 86b2e36e53..6e111164bb 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-components", - "version": "2.0.2", + "version": "2.0.3", "description": "Raw, skinnable UI & SVG components for @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -24,7 +24,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/checks": "^1.5.0", + "@thi.ng/checks": "^1.5.1", "@types/webgl2": "^0.0.3" }, "keywords": [ diff --git a/packages/hdom/CHANGELOG.md b/packages/hdom/CHANGELOG.md index 7b773295bb..f823c92a70 100644 --- a/packages/hdom/CHANGELOG.md +++ b/packages/hdom/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [3.0.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.11...@thi.ng/hdom@3.0.12) (2018-04-29) + + +### Performance Improvements + +* **hdom:** update event handling in diffAttributes() ([31ec3af](https://github.com/thi-ng/umbrella/commit/31ec3af)) + + + + ## [3.0.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@3.0.10...@thi.ng/hdom@3.0.11) (2018-04-26) diff --git a/packages/hdom/package.json b/packages/hdom/package.json index d8b0a84401..322ca77707 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom", - "version": "3.0.11", + "version": "3.0.12", "description": "Lightweight vanilla ES6 UI component & virtual DOM system", "main": "./index.js", "typings": "./index.d.ts", @@ -16,7 +16,7 @@ "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { - "@thi.ng/atom": "^1.3.5", + "@thi.ng/atom": "^1.3.6", "@types/mocha": "^5.0.0", "@types/node": "^9.6.1", "mocha": "^5.0.5", @@ -25,10 +25,10 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/diff": "^1.0.8", - "@thi.ng/hiccup": "^1.3.11", - "@thi.ng/iterators": "^4.1.8" + "@thi.ng/api": "^2.3.1", + "@thi.ng/diff": "^1.0.9", + "@thi.ng/hiccup": "^1.3.12", + "@thi.ng/iterators": "^4.1.9" }, "keywords": [ "browser", diff --git a/packages/hdom/src/diff.ts b/packages/hdom/src/diff.ts index 06385f4852..a0b0f96ee9 100644 --- a/packages/hdom/src/diff.ts +++ b/packages/hdom/src/diff.ts @@ -9,8 +9,6 @@ import { setAttrib } from "./dom"; -// import { DEBUG } from "./api"; - const isArray = isa.isArray; const isString = iss.isString; const diffArray = diff.diffArray; @@ -47,7 +45,7 @@ function _diffElement(parent: Element, prev: any, curr: any, child: number) { const edits = delta.linear; const el = parent.children[child]; let i, j, k, eq, e, status, idx, val; - if (edits[0][0] !== 0 || (i = prev[1]).key !== (j = curr[1]).key || hasChangedEvents(i, j)) { + if (edits[0][0] !== 0 || (i = prev[1]).key !== (j = curr[1]).key) { // DEBUG && console.log("replace:", prev, curr); releaseDeep(prev); removeChild(parent, child); @@ -119,30 +117,25 @@ function releaseDeep(tag: any) { (tag).__release.apply(tag, (tag).__args); delete (tag).__release; } - for (let i = tag.length - 1; i >= 2; i--) { + for (let i = tag.length; --i >= 2;) { releaseDeep(tag[i]); } } } -function hasChangedEvents(prev: any, curr: any) { - for (let k in curr) { - if (k.indexOf("on") === 0 && prev[k] !== curr[k]) { - return true; - } - } - return false; -} - function diffAttributes(el: Element, prev: any, curr: any) { let i, e, edits; const delta = diffObject(prev, curr); - removeAttribs(el, delta.dels); - for (edits = delta.edits, i = edits.length - 1; i >= 0; i--) { + removeAttribs(el, delta.dels, prev); + for (edits = delta.edits, i = edits.length; --i >= 0;) { e = edits[i]; - setAttrib(el, e[0], e[1], curr); + const a = e[0]; + if (a.indexOf("on") === 0) { + el.removeEventListener(a.substr(2), prev[a]); + } + setAttrib(el, a, e[1], curr); } - for (edits = delta.adds, i = edits.length - 1; i >= 0; i--) { + for (edits = delta.adds, i = edits.length; --i >= 0;) { e = edits[i]; setAttrib(el, e, curr[e], curr); } @@ -151,7 +144,7 @@ function diffAttributes(el: Element, prev: any, curr: any) { function extractEquivElements(edits: diff.DiffLogEntry[]) { let k, v, e, ek; const equiv = {}; - for (let i = edits.length - 1; i >= 0; i--) { + for (let i = edits.length; --i >= 0;) { e = edits[i]; v = e[2]; if (isArray(v) && (k = v[1].key) !== undefined) { diff --git a/packages/hdom/src/dom.ts b/packages/hdom/src/dom.ts index d36f142dd3..3ccc7ef464 100644 --- a/packages/hdom/src/dom.ts +++ b/packages/hdom/src/dom.ts @@ -161,9 +161,14 @@ export function updateValueAttrib(el: HTMLInputElement, v: any) { } } -export function removeAttribs(el: Element, attribs: string[]) { - for (let i = attribs.length - 1; i >= 0; i--) { - el.removeAttribute(attribs[i]); +export function removeAttribs(el: Element, attribs: string[], prev: any) { + for (let i = attribs.length; --i >= 0;) { + const a = attribs[i]; + if (a.indexOf("on") === 0) { + el.removeEventListener(a.substr(2), prev[a]); + } else { + el.removeAttribute(a); + } } } diff --git a/packages/heaps/CHANGELOG.md b/packages/heaps/CHANGELOG.md index bb39a565df..12ab8bf6e7 100644 --- a/packages/heaps/CHANGELOG.md +++ b/packages/heaps/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.2.4...@thi.ng/heaps@0.2.5) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/heaps + ## [0.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@0.2.3...@thi.ng/heaps@0.2.4) (2018-04-26) diff --git a/packages/heaps/package.json b/packages/heaps/package.json index e9e56574de..daa89bec47 100644 --- a/packages/heaps/package.json +++ b/packages/heaps/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/heaps", - "version": "0.2.4", + "version": "0.2.5", "description": "Generic binary heap & d-ary heap implementations with customizable ordering", "main": "./index.js", "typings": "./index.d.ts", @@ -24,7 +24,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "keywords": [ "data structure", diff --git a/packages/hiccup-css/CHANGELOG.md b/packages/hiccup-css/CHANGELOG.md index 843aeb44fe..57cb4d6ec8 100644 --- a/packages/hiccup-css/CHANGELOG.md +++ b/packages/hiccup-css/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.1.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.1.13...@thi.ng/hiccup-css@0.1.14) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/hiccup-css + ## [0.1.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@0.1.12...@thi.ng/hiccup-css@0.1.13) (2018-04-26) diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json index 6b935822df..3f1da5a219 100644 --- a/packages/hiccup-css/package.json +++ b/packages/hiccup-css/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-css", - "version": "0.1.13", + "version": "0.1.14", "description": "CSS from nested JS data structures", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "clojure", diff --git a/packages/hiccup-svg/CHANGELOG.md b/packages/hiccup-svg/CHANGELOG.md index f22aa28e64..cd3420db0f 100644 --- a/packages/hiccup-svg/CHANGELOG.md +++ b/packages/hiccup-svg/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.2.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@0.2.8...@thi.ng/hiccup-svg@0.2.9) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/hiccup-svg + ## [0.2.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@0.2.7...@thi.ng/hiccup-svg@0.2.8) (2018-04-26) diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index a574fadad8..2ada6bc793 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-svg", - "version": "0.2.8", + "version": "0.2.9", "description": "SVG element functions for @thi.ng/hiccup & @thi.ng/hdom", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/hiccup": "^1.3.11" + "@thi.ng/api": "^2.3.1", + "@thi.ng/hiccup": "^1.3.12" }, "keywords": [ "components", diff --git a/packages/hiccup/CHANGELOG.md b/packages/hiccup/CHANGELOG.md index 66217d7a8d..3bb3a2724a 100644 --- a/packages/hiccup/CHANGELOG.md +++ b/packages/hiccup/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.3.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@1.3.11...@thi.ng/hiccup@1.3.12) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/hiccup + ## [1.3.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@1.3.10...@thi.ng/hiccup@1.3.11) (2018-04-26) diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json index 27b8744ea1..28900bc83f 100644 --- a/packages/hiccup/package.json +++ b/packages/hiccup/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup", - "version": "1.3.11", + "version": "1.3.12", "description": "HTML/SVG/XML serialization of nested data structures, iterables & closures", "main": "./index.js", "typings": "./index.d.ts", @@ -16,7 +16,7 @@ "test": "rm -rf build && tsc -p test && nyc mocha build/test/*.js" }, "devDependencies": { - "@thi.ng/atom": "^1.3.5", + "@thi.ng/atom": "^1.3.6", "@types/mocha": "^5.0.0", "@types/node": "^9.6.1", "mocha": "^5.0.5", @@ -25,8 +25,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/checks": "^1.5.0" + "@thi.ng/api": "^2.3.1", + "@thi.ng/checks": "^1.5.1" }, "keywords": [ "clojure", diff --git a/packages/interceptors/CHANGELOG.md b/packages/interceptors/CHANGELOG.md index 86e350a3e4..de7eb2c0b1 100644 --- a/packages/interceptors/CHANGELOG.md +++ b/packages/interceptors/CHANGELOG.md @@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.6.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.6.1...@thi.ng/interceptors@1.6.2) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/interceptors + + +## [1.6.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.6.0...@thi.ng/interceptors@1.6.1) (2018-04-28) + + +### Bug Fixes + +* **interceptors:** multiple sidefx value assignment ([c4d8851](https://github.com/thi-ng/umbrella/commit/c4d8851)) + + + + + +# [1.6.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.5.3...@thi.ng/interceptors@1.6.0) (2018-04-27) + + +### Features + +* **interceptors:** add dispatchLater() ([f4a095a](https://github.com/thi-ng/umbrella/commit/f4a095a)) + + + + ## [1.5.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@1.5.2...@thi.ng/interceptors@1.5.3) (2018-04-26) diff --git a/packages/interceptors/README.md b/packages/interceptors/README.md index 35303110fe..5c4ac18d2e 100644 --- a/packages/interceptors/README.md +++ b/packages/interceptors/README.md @@ -35,7 +35,10 @@ Introductory: Advanced: +- [/examples/rstream-dataflow](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-dataflow) | [live demo](http://demo.thi.ng/umbrella/rstream-dataflow) +- [/examples/rstream-grid](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-grid) | [live demo](http://demo.thi.ng/umbrella/rstream-grid) - [/examples/router-basics](https://github.com/thi-ng/umbrella/tree/master/examples/router-basics) | [live demo](http://demo.thi.ng/umbrella/router-basics) +- [/examples/svg-waveform](https://github.com/thi-ng/umbrella/tree/master/examples/svg-waveform) | [live demo](http://demo.thi.ng/umbrella/svg-waveform) - [create-hdom-app](https://github.com/thi-ng/create-hdom-app) Yarn project generator. Uses: @thi.ng/atom + hdom + interceptors + router diff --git a/packages/interceptors/package.json b/packages/interceptors/package.json index c0c0f1210f..a43327c052 100644 --- a/packages/interceptors/package.json +++ b/packages/interceptors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/interceptors", - "version": "1.5.3", + "version": "1.6.2", "description": "Interceptor based event bus, side effect & immutable state handling", "main": "./index.js", "typings": "./index.d.ts", @@ -24,9 +24,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/atom": "^1.3.5", - "@thi.ng/paths": "^1.3.2" + "@thi.ng/api": "^2.3.1", + "@thi.ng/atom": "^1.3.6", + "@thi.ng/paths": "^1.3.3" }, "keywords": [ "ES6", diff --git a/packages/interceptors/src/api.ts b/packages/interceptors/src/api.ts index 1e1eb62c06..69eb3191a0 100644 --- a/packages/interceptors/src/api.ts +++ b/packages/interceptors/src/api.ts @@ -48,6 +48,7 @@ export interface IDispatch { readonly state: ReadonlyAtom; dispatch(event: Event); dispatchNow(event: Event); + dispatchLater(event: Event, delay?: number); } export interface Interceptor { diff --git a/packages/interceptors/src/event-bus.ts b/packages/interceptors/src/event-bus.ts index d8faee5a6d..28b5f2a2bf 100644 --- a/packages/interceptors/src/event-bus.ts +++ b/packages/interceptors/src/event-bus.ts @@ -324,6 +324,17 @@ export class StatelessEventBus implements (this.currQueue || this.eventQueue).push(e); } + /** + * Dispatches given event after `delay` milliseconds + * (by default 17). + * + * @param e + * @param delay + */ + dispatchLater(e: api.Event, delay = 17) { + setTimeout(() => this.dispatch(e), delay); + } + /** * Triggers processing of current event queue and returns `true` if * any events have been processed. @@ -489,16 +500,13 @@ export class StatelessEventBus implements this.dispatchNow(v); } } else { - if (ctx[k]) { - if (isArray(v[0])) { - for (let e of v) { - e !== undefined && ctx[k].push(e); - } - } else { - ctx[k].push(v) + ctx[k] || (ctx[k] = []); + if (isArray(v[0])) { + for (let e of v) { + e !== undefined && ctx[k].push(e); } } else { - ctx[k] = [v]; + ctx[k].push(v) } } } diff --git a/packages/iterators/CHANGELOG.md b/packages/iterators/CHANGELOG.md index 017bc1ef22..19f30826e0 100644 --- a/packages/iterators/CHANGELOG.md +++ b/packages/iterators/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [4.1.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.8...@thi.ng/iterators@4.1.9) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/iterators + ## [4.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@4.1.7...@thi.ng/iterators@4.1.8) (2018-04-26) diff --git a/packages/iterators/package.json b/packages/iterators/package.json index ec5d640245..63d035b5df 100644 --- a/packages/iterators/package.json +++ b/packages/iterators/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iterators", - "version": "4.1.8", + "version": "4.1.9", "description": "clojure.core inspired, composable ES6 iterators & generators", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/dcons": "^0.3.2" + "@thi.ng/api": "^2.3.1", + "@thi.ng/dcons": "^0.3.3" }, "keywords": [ "clojure", diff --git a/packages/paths/CHANGELOG.md b/packages/paths/CHANGELOG.md index 4977d9d2a5..9dc894103f 100644 --- a/packages/paths/CHANGELOG.md +++ b/packages/paths/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.3.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.3.2...@thi.ng/paths@1.3.3) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/paths + ## [1.3.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@1.3.1...@thi.ng/paths@1.3.2) (2018-04-26) diff --git a/packages/paths/package.json b/packages/paths/package.json index be5e2002fe..b30772f1dd 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/paths", - "version": "1.3.2", + "version": "1.3.3", "description": "immutable, optimized path-based object property / array accessors", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/checks": "^1.5.0" + "@thi.ng/api": "^2.3.1", + "@thi.ng/checks": "^1.5.1" }, "keywords": [ "accessors", diff --git a/packages/pointfree-lang/CHANGELOG.md b/packages/pointfree-lang/CHANGELOG.md index ccd4d427db..fa9a2a3ab9 100644 --- a/packages/pointfree-lang/CHANGELOG.md +++ b/packages/pointfree-lang/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.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.5...@thi.ng/pointfree-lang@0.2.6) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/pointfree-lang + ## [0.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@0.2.4...@thi.ng/pointfree-lang@0.2.5) (2018-04-26) diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json index 2b39a16e9e..91fa458da6 100644 --- a/packages/pointfree-lang/package.json +++ b/packages/pointfree-lang/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pointfree-lang", - "version": "0.2.5", + "version": "0.2.6", "description": "Forth style syntax layer/compiler for the @thi.ng/pointfree DSL", "main": "./index.js", "typings": "./index.d.ts", @@ -26,8 +26,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/pointfree": "^0.7.5" + "@thi.ng/api": "^2.3.1", + "@thi.ng/pointfree": "^0.7.6" }, "keywords": [ "concatenative", diff --git a/packages/pointfree/CHANGELOG.md b/packages/pointfree/CHANGELOG.md index d660174f1a..5a0f87ccc8 100644 --- a/packages/pointfree/CHANGELOG.md +++ b/packages/pointfree/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.7.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.7.5...@thi.ng/pointfree@0.7.6) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/pointfree + ## [0.7.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@0.7.4...@thi.ng/pointfree@0.7.5) (2018-04-26) diff --git a/packages/pointfree/package.json b/packages/pointfree/package.json index 26aa1bf6a6..efa909dc2b 100644 --- a/packages/pointfree/package.json +++ b/packages/pointfree/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pointfree", - "version": "0.7.5", + "version": "0.7.6", "description": "Pointfree functional composition / Forth style stack execution engine", "main": "./index.js", "typings": "./index.d.ts", @@ -24,7 +24,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "keywords": [ "composition", diff --git a/packages/resolve-map/CHANGELOG.md b/packages/resolve-map/CHANGELOG.md index 217e7c1c75..71183dde64 100644 --- a/packages/resolve-map/CHANGELOG.md +++ b/packages/resolve-map/CHANGELOG.md @@ -3,7 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - + +## [1.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@1.0.3...@thi.ng/resolve-map@1.0.4) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/resolve-map + + ## [1.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@1.0.2...@thi.ng/resolve-map@1.0.3) (2018-04-26) @@ -11,7 +19,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @thi.ng/resolve-map - + ## [1.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@1.0.1...@thi.ng/resolve-map@1.0.2) (2018-04-19) diff --git a/packages/resolve-map/package.json b/packages/resolve-map/package.json index 06bddff40a..b52050fe5f 100644 --- a/packages/resolve-map/package.json +++ b/packages/resolve-map/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/resolve-map", - "version": "1.0.3", + "version": "1.0.4", "description": "DAG resolution of vanilla objects & arrays with internally linked values", "main": "./index.js", "typings": "./index.d.ts", @@ -22,9 +22,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/checks": "^1.5.0", - "@thi.ng/paths": "^1.3.2" + "@thi.ng/api": "^2.3.1", + "@thi.ng/checks": "^1.5.1", + "@thi.ng/paths": "^1.3.3" }, "keywords": [ "configuration", diff --git a/packages/rle-pack/CHANGELOG.md b/packages/rle-pack/CHANGELOG.md index 811e452638..5ff929f352 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.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/rle-pack@0.2.15...@thi.ng/rle-pack@0.2.16) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rle-pack + ## [0.2.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/rle-pack@0.2.14...@thi.ng/rle-pack@0.2.15) (2018-04-26) diff --git a/packages/rle-pack/package.json b/packages/rle-pack/package.json index 3437420997..e67fdee3bb 100644 --- a/packages/rle-pack/package.json +++ b/packages/rle-pack/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rle-pack", - "version": "0.2.15", + "version": "0.2.16", "description": "Binary run-length encoding packer w/ flexible repeat bit widths", "main": "./index.js", "typings": "./index.d.ts", @@ -25,7 +25,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/bitstream": "^0.4.6" + "@thi.ng/bitstream": "^0.4.7" }, "keywords": [ "binary", diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md index 377501326c..e40e8a438b 100644 --- a/packages/router/CHANGELOG.md +++ b/packages/router/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.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.8...@thi.ng/router@0.1.9) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/router + ## [0.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@0.1.7...@thi.ng/router@0.1.8) (2018-04-26) diff --git a/packages/router/package.json b/packages/router/package.json index 15e1618e24..9acf48a4ce 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/router", - "version": "0.1.8", + "version": "0.1.9", "description": "Generic router for browser & non-browser based applications", "main": "./index.js", "typings": "./index.d.ts", @@ -23,7 +23,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "keywords": [ "declarative", diff --git a/packages/rstream-csp/CHANGELOG.md b/packages/rstream-csp/CHANGELOG.md index 3a04598047..2a3e05ea9e 100644 --- a/packages/rstream-csp/CHANGELOG.md +++ b/packages/rstream-csp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.1.63](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.62...@thi.ng/rstream-csp@0.1.63) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream-csp + ## [0.1.62](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@0.1.61...@thi.ng/rstream-csp@0.1.62) (2018-04-26) diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json index 4664b23ba7..7442fec6ca 100644 --- a/packages/rstream-csp/package.json +++ b/packages/rstream-csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-csp", - "version": "0.1.62", + "version": "0.1.63", "description": "@thi.ng/csp bridge module for @thi.ng/rstream", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/csp": "^0.3.31", - "@thi.ng/rstream": "^1.6.3" + "@thi.ng/csp": "^0.3.32", + "@thi.ng/rstream": "^1.6.4" }, "keywords": [ "bridge", diff --git a/packages/rstream-dot/CHANGELOG.md b/packages/rstream-dot/CHANGELOG.md index e7e6d21879..135b7e8ef3 100644 --- a/packages/rstream-dot/CHANGELOG.md +++ b/packages/rstream-dot/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.1...@thi.ng/rstream-dot@0.2.2) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream-dot + ## [0.2.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@0.2.0...@thi.ng/rstream-dot@0.2.1) (2018-04-26) diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json index 076fee2a70..05e377669d 100644 --- a/packages/rstream-dot/package.json +++ b/packages/rstream-dot/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-dot", - "version": "0.2.1", + "version": "0.2.2", "description": "Graphviz DOT conversion of @thi.ng/rstream dataflow graph topologies", "main": "./index.js", "typings": "./index.d.ts", @@ -24,9 +24,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/rstream": "^1.6.3", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/rstream": "^1.6.4", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "conversion", diff --git a/packages/rstream-gestures/CHANGELOG.md b/packages/rstream-gestures/CHANGELOG.md index e6fabdb134..6c2a837d1c 100644 --- a/packages/rstream-gestures/CHANGELOG.md +++ b/packages/rstream-gestures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.2.4...@thi.ng/rstream-gestures@0.2.5) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream-gestures + ## [0.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@0.2.3...@thi.ng/rstream-gestures@0.2.4) (2018-04-26) diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json index 3b16ebd6aa..1655b82842 100644 --- a/packages/rstream-gestures/package.json +++ b/packages/rstream-gestures/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-gestures", - "version": "0.2.4", + "version": "0.2.5", "description": "Unified mouse, mouse wheel & single-touch event stream abstraction", "main": "./index.js", "typings": "./index.d.ts", @@ -24,9 +24,9 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/rstream": "^1.6.3", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/rstream": "^1.6.4", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "dataflow", diff --git a/packages/rstream-graph/CHANGELOG.md b/packages/rstream-graph/CHANGELOG.md index 440b891503..b3977cdcdb 100644 --- a/packages/rstream-graph/CHANGELOG.md +++ b/packages/rstream-graph/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.0.4...@thi.ng/rstream-graph@1.0.5) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream-graph + ## [1.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@1.0.3...@thi.ng/rstream-graph@1.0.4) (2018-04-26) diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json index 2420ce7bed..4682ffe3a3 100644 --- a/packages/rstream-graph/package.json +++ b/packages/rstream-graph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-graph", - "version": "1.0.4", + "version": "1.0.5", "description": "Declarative dataflow graph construction for @thi.ng/rstream", "main": "./index.js", "typings": "./index.d.ts", @@ -24,11 +24,11 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/paths": "^1.3.2", - "@thi.ng/resolve-map": "^1.0.3", - "@thi.ng/rstream": "^1.6.3", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/paths": "^1.3.3", + "@thi.ng/resolve-map": "^1.0.4", + "@thi.ng/rstream": "^1.6.4", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "compute", diff --git a/packages/rstream-log/CHANGELOG.md b/packages/rstream-log/CHANGELOG.md index 6d20e3aac3..1643359ac6 100644 --- a/packages/rstream-log/CHANGELOG.md +++ b/packages/rstream-log/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.0.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.13...@thi.ng/rstream-log@1.0.14) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream-log + ## [1.0.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@1.0.12...@thi.ng/rstream-log@1.0.13) (2018-04-26) diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json index 69e2314d63..64d922c6a2 100644 --- a/packages/rstream-log/package.json +++ b/packages/rstream-log/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-log", - "version": "1.0.13", + "version": "1.0.14", "description": "Structured, multilevel & hierarchical loggers based on @thi.ng/rstream", "main": "./index.js", "typings": "./index.d.ts", @@ -24,8 +24,8 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/rstream": "^1.6.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/rstream": "^1.6.4" }, "keywords": [ "ES6", diff --git a/packages/rstream-query/CHANGELOG.md b/packages/rstream-query/CHANGELOG.md index 6ebdd537e2..4bba4f0a09 100644 --- a/packages/rstream-query/CHANGELOG.md +++ b/packages/rstream-query/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. + +## [0.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.3.0...@thi.ng/rstream-query@0.3.1) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream-query + + +# [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.2.2...@thi.ng/rstream-query@0.3.0) (2018-04-27) + + +### Features + +* **rstream-query:** add obj->triple converter, update readme & example ([6f95bcb](https://github.com/thi-ng/umbrella/commit/6f95bcb)) + + + + ## [0.2.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@0.2.1...@thi.ng/rstream-query@0.2.2) (2018-04-26) diff --git a/packages/rstream-query/README.md b/packages/rstream-query/README.md index 9dd2bb72ec..98e558c1c4 100644 --- a/packages/rstream-query/README.md +++ b/packages/rstream-query/README.md @@ -53,30 +53,47 @@ yarn add @thi.ng/rstream-query ## Usage examples ```typescript +import { TripleStore, asTriples } from "@thi.ng/rstream-query"; import { trace } from "@thi.ng/rstream"; -import { TripleStore } from "../src"; // create store with initial set of triples / facts const store = new TripleStore([ ["london", "type", "city"], ["london", "part-of", "uk"], ["portland", "type", "city"], - ["portland", "part-of", "oregon"], - ["portland", "part-of", "usa"], + ["portland", "partOf", "oregon"], + ["portland", "partOf", "usa"], ["oregon", "type", "state"], ["usa", "type", "country"], ["uk", "type", "country"], ]); +// alternatively, convert an object into a sequence of triples +const store = new TripleStore(asTriples({ + london: { + type: "city", + partOf: "uk" + }, + portland: { + type: "city", + partOf: ["oregon", "usa"] + }, + oregon: { type: "state" }, + uk: { type: "country" }, + usa: { type: "country" }, +}); + // compile the below query spec into a dataflow graph // pattern items prefixed w/ "?" are query variables // this query matches the following relationships // using all currently known triples in the store +// when matching triples are added or removed, the query +// result updates automatically... -// currently only "where" and "path" sub-queries are possible +// currently only "where" and bounded "path" sub-queries are possible // in the near future, more query types will be supported -// (e.g. optional relationships, filters etc.) +// (e.g. optional relationships, pre/post filters etc.) store.addQueryFromSpec({ q: [ { @@ -85,7 +102,7 @@ store.addQueryFromSpec({ // match any subject of type "city" ["?city", "type", "city"], // match each ?city var's "part-of" relationships (if any) - ["?city", "part-of", "?country"], + ["?city", "partOf", "?country"], // matched ?country var must have type = "country" ["?country", "type", "country"] ] @@ -100,7 +117,8 @@ store.addQueryFromSpec({ }, // another post-processing step, only keeps "answer" var in results select: ["answer"] -}).subscribe(trace("results")) +}) +.subscribe(trace("results")) // results Set { // { answer: 'london is located in uk' }, // { answer: 'portland is located in usa' } } @@ -109,7 +127,7 @@ store.addQueryFromSpec({ const addCity = (name, country) => store.into([ [name, "type", "city"], - [name, "part-of", country], + [name, "partOf", country], [country, "type", "country"], ]); diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json index 5eac9ccbc1..4e7f45e36d 100644 --- a/packages/rstream-query/package.json +++ b/packages/rstream-query/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-query", - "version": "0.2.2", + "version": "0.3.1", "description": "@thi.ng/rstream based triple store & reactive query engine", "main": "./index.js", "typings": "./index.d.ts", @@ -24,11 +24,11 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/associative": "^0.4.5", - "@thi.ng/rstream": "^1.6.3", - "@thi.ng/rstream-dot": "^0.2.1", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/associative": "^0.4.6", + "@thi.ng/rstream": "^1.6.4", + "@thi.ng/rstream-dot": "^0.2.2", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "dataflow", diff --git a/packages/rstream-query/src/convert.ts b/packages/rstream-query/src/convert.ts new file mode 100644 index 0000000000..49ea82d9fb --- /dev/null +++ b/packages/rstream-query/src/convert.ts @@ -0,0 +1,86 @@ +import { isArray } from "@thi.ng/checks/is-array"; +import { isPlainObject } from "@thi.ng/checks/is-plain-object"; +import { concat } from "@thi.ng/transducers/iter/concat"; +import { pairs } from "@thi.ng/transducers/iter/pairs"; +import { iterator } from "@thi.ng/transducers/iterator"; +import { mapcat } from "@thi.ng/transducers/xform/mapcat"; + +let NEXT_ID = 0; + +const mapBNode = (s: any, p: any, o: any) => { + const id = `__b${NEXT_ID++}__`; + return concat([[s, p, id]], asTriples(o, id)); +}; + +const mapSubject = (subject: any) => + ([p, o]) => { + if (isArray(o)) { + return iterator( + mapcat((o) => + isPlainObject(o) ? + mapBNode(subject, p, o) : + [[subject, p, o]]), + o); + } else if (isPlainObject(o)) { + return mapBNode(subject, p, o); + } + return [[subject, p, o]]; + }; + +/** + * Converts given object into an iterable of triples, with the following + * conversion rules: + * + * - Toplevel object keys are used as subjects and MUST each have a + * plain object as value, where its keys are used as predicates and + * values as objects (in the SPO sense). + * - Plain objects in SPO object position are translated into unique IDs + * in order to allow the nested map to become a subject itself. In RDF + * terms, this is equivalent to BNodes. + * - Arrays in SPO object position cause multiple triples with same + * subject & predicate to be emitted. If any of the items in the array + * is a plain object, it will be treated as BNode and transformed as + * described in the previous rule + * + * ``` + * src = { + * "@thi.ng/rstream-query": { + * type: "project", + * author: "toxi", + * tag: ["ES6", "TypeScript", "graph"] + * }, + * toxi: { + * type: "person", + * hasAccount: [ + * {type: "twitter", id: "toxi"}, + * {type: "github", id: "postspectacular"} + * ] + * } + * }; + * + * [...asTriples(src)] + * // [ [ '@thi.ng/rstream-query', 'type', 'project' ], + * // [ '@thi.ng/rstream-query', 'author', 'toxi' ], + * // [ '@thi.ng/rstream-query', 'tag', 'ES6' ], + * // [ '@thi.ng/rstream-query', 'tag', 'TypeScript' ], + * // [ '@thi.ng/rstream-query', 'tag', 'graph' ], + * // [ 'toxi', 'type', 'person' ], + * // [ 'toxi', 'hasAccount', '__b0__' ], + * // [ '__b0__', 'type', 'twitter' ], + * // [ '__b0__', 'id', 'toxi' ], + * // [ 'toxi', 'hasAccount', '__b1__' ], + * // [ '__b1__', 'type', 'github' ], + * // [ '__b1__', 'id', 'postspectacular' ] ] + * ``` + * + * @param obj + * @param subject internal use only, do not specify! + */ +export const asTriples = (obj: any, subject?: any) => + iterator( + mapcat( + subject === undefined ? + ([s, v]: any) => iterator(mapcat(mapSubject(s)), pairs(v)) : + mapSubject(subject) + ), + pairs(obj)); diff --git a/packages/rstream-query/src/index.ts b/packages/rstream-query/src/index.ts index cde4f0f325..fed8901627 100644 --- a/packages/rstream-query/src/index.ts +++ b/packages/rstream-query/src/index.ts @@ -1,4 +1,5 @@ export * from "./api"; +export * from "./convert"; export * from "./pattern"; export * from "./qvar"; export * from "./store"; diff --git a/packages/rstream-query/src/store.ts b/packages/rstream-query/src/store.ts index 26c9dbbed1..4337dc2ea4 100644 --- a/packages/rstream-query/src/store.ts +++ b/packages/rstream-query/src/store.ts @@ -219,7 +219,7 @@ export class TripleStore implements } } return emitTriples ? - results.subscribe(asTriples(this)) : + results.subscribe(resultTriples(this)) : results; } @@ -432,7 +432,7 @@ const indexSel = (key: any): Transducer => ); }; -const asTriples = (graph: TripleStore) => +const resultTriples = (graph: TripleStore) => map>( (ids) => { const res = new Set(); diff --git a/packages/rstream-query/test/example.ts b/packages/rstream-query/test/example.ts index 9a28886371..7cf18581d1 100644 --- a/packages/rstream-query/test/example.ts +++ b/packages/rstream-query/test/example.ts @@ -1,7 +1,7 @@ import { trace } from "@thi.ng/rstream"; -import { TripleStore } from "../src"; +import * as q from "../src"; -const store = new TripleStore([ +const store = new q.TripleStore([ ["london", "type", "city"], ["london", "part-of", "uk"], ["portland", "type", "city"], @@ -12,6 +12,21 @@ const store = new TripleStore([ ["uk", "type", "country"], ]); +// alternatively, convert an object into a sequence of triples +// const store = new q.TripleStore(q.asTriples({ +// london: { +// type: "city", +// partOf: "uk" +// }, +// portland: { +// type: "city", +// partOf: ["oregon", "usa"] +// }, +// oregon: { type: "state" }, +// uk: { type: "country" }, +// usa: { type: "country" }, +// })); + // compile the below query spec into a dataflow graph // pattern items prefixed w/ "?" are query variables @@ -28,7 +43,7 @@ store.addQueryFromSpec({ // first match any subject of type "city" ["?city", "type", "city"], // then a city's "part-of" relationships (if any) - ["?city", "part-of", "?country"], + ["?city", "partOf", "?country"], // the matched ?country must have type = "country" ["?country", "type", "country"] ] @@ -52,7 +67,7 @@ store.addQueryFromSpec({ const addCity = (name, country) => store.into([ [name, "type", "city"], - [name, "part-of", country], + [name, "partOf", country], [country, "type", "country"], ]); diff --git a/packages/rstream/CHANGELOG.md b/packages/rstream/CHANGELOG.md index 5f6efcfc99..fe29baffa3 100644 --- a/packages/rstream/CHANGELOG.md +++ b/packages/rstream/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.6.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.6.3...@thi.ng/rstream@1.6.4) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/rstream + ## [1.6.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@1.6.2...@thi.ng/rstream@1.6.3) (2018-04-26) diff --git a/packages/rstream/package.json b/packages/rstream/package.json index ee7ff4f4fa..a92dd1cf12 100644 --- a/packages/rstream/package.json +++ b/packages/rstream/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream", - "version": "1.6.3", + "version": "1.6.4", "description": "Reactive multi-tap streams, dataflow & transformation pipeline constructs", "main": "./index.js", "typings": "./index.d.ts", @@ -24,10 +24,10 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0", - "@thi.ng/associative": "^0.4.5", - "@thi.ng/atom": "^1.3.5", - "@thi.ng/transducers": "^1.8.3" + "@thi.ng/api": "^2.3.1", + "@thi.ng/associative": "^0.4.6", + "@thi.ng/atom": "^1.3.6", + "@thi.ng/transducers": "^1.8.4" }, "keywords": [ "datastructure", diff --git a/packages/transducers/CHANGELOG.md b/packages/transducers/CHANGELOG.md index 9598093e57..58e6ae4278 100644 --- a/packages/transducers/CHANGELOG.md +++ b/packages/transducers/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.8.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@1.8.3...@thi.ng/transducers@1.8.4) (2018-04-29) + + + + +**Note:** Version bump only for package @thi.ng/transducers + ## [1.8.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@1.8.2...@thi.ng/transducers@1.8.3) (2018-04-26) diff --git a/packages/transducers/package.json b/packages/transducers/package.json index 0200cd5f46..4acb3b9d98 100644 --- a/packages/transducers/package.json +++ b/packages/transducers/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers", - "version": "1.8.3", + "version": "1.8.4", "description": "Lightweight transducer implementations for ES6 / TypeScript", "main": "./index.js", "typings": "./index.d.ts", @@ -24,7 +24,7 @@ "typescript": "^2.8.1" }, "dependencies": { - "@thi.ng/api": "^2.3.0" + "@thi.ng/api": "^2.3.1" }, "keywords": [ "ES6",