@thi.ng/defmulti
Advanced tools
Comparing version 1.2.26 to 1.3.0
@@ -1,2 +0,2 @@ | ||
import type { Fn, Fn2, Fn3, Fn4, Fn5, Fn6, Fn7, Fn8, FnAny, IObjectOf } from "@thi.ng/api"; | ||
import type { Fn, Fn2, Fn3, Fn4, Fn5, Fn6, Fn7, Fn8, FnAny, IObjectOf, Pair } from "@thi.ng/api"; | ||
export declare type DispatchFn = FnAny<PropertyKey>; | ||
@@ -101,2 +101,9 @@ export declare type DispatchFn1<A> = Fn<A, PropertyKey>; | ||
ancestors(id: PropertyKey): Set<PropertyKey>; | ||
/** | ||
* Returns iterator of all known dispatch values and their dependencies in | ||
* the hierarchy of dispatch values. Each dependency is encoded as `[value, | ||
* parent-value?]`. If `parent-value` is undefined, the dispatch value has | ||
* no parent. | ||
*/ | ||
dependencies(): IterableIterator<Pair<PropertyKey, PropertyKey | undefined>>; | ||
} | ||
@@ -103,0 +110,0 @@ export interface MultiFn<T> extends Implementation<T>, MultiFnBase<Implementation<T>> { |
@@ -6,2 +6,13 @@ # Change Log | ||
# [1.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@1.2.26...@thi.ng/defmulti@1.3.0) (2020-11-24) | ||
### Features | ||
* **defmulti:** add .dependencies(), add tests ([d15a159](https://github.com/thi-ng/umbrella/commit/d15a1594750ac171b1ab93da18d908f1ca6c3897)) | ||
## [1.2.26](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@1.2.25...@thi.ng/defmulti@1.2.26) (2020-09-22) | ||
@@ -8,0 +19,0 @@ |
@@ -57,2 +57,11 @@ import { unsupported } from "@thi.ng/errors"; | ||
fn.ancestors = (id) => new Set(findAncestors([], rels, id)); | ||
fn.dependencies = function* () { | ||
for (let a in rels) { | ||
for (let b of rels[a]) | ||
yield [a, b]; | ||
} | ||
for (let id in impls) { | ||
!rels[id] && (yield [id, undefined]); | ||
} | ||
}; | ||
return fn; | ||
@@ -59,0 +68,0 @@ } |
@@ -66,2 +66,11 @@ 'use strict'; | ||
fn.ancestors = (id) => new Set(findAncestors([], rels, id)); | ||
fn.dependencies = function* () { | ||
for (let a in rels) { | ||
for (let b of rels[a]) | ||
yield [a, b]; | ||
} | ||
for (let id in impls) { | ||
!rels[id] && (yield [id, undefined]); | ||
} | ||
}; | ||
return fn; | ||
@@ -68,0 +77,0 @@ } |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/api"),require("@thi.ng/errors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/api","@thi.ng/errors"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.defmulti={}),e.thi.ng.api,e.thi.ng.errors)}(this,(function(e,t,n){"use strict";const i=Symbol();e.LOGGER=t.NULL_LOGGER;function r(t,r){const f={},d=r?s(r):{},a=(...e)=>{const r=t(...e),l=f[r]||o(f,d,r)||f[i];return l?l(...e):n.unsupported(`missing implementation for: "${r.toString()}"`)};return a.add=(t,n)=>(f[t]&&e.LOGGER.warn(`overwriting '${t.toString()}' impl`),f[t]=n,!0),a.addAll=e=>{let t=!0;for(let n in e)t=a.add(n,e[n])&&t;return t},a.remove=e=>!!f[e]&&(delete f[e],!0),a.callable=(...e)=>{const n=t(...e);return!!(f[n]||o(f,d,n)||f[i])},a.isa=(e,t)=>{let n=d[e];!n&&(d[e]=n=new Set),n.add(t)},a.impls=()=>{const e=new Set(Object.keys(f));for(let t in d)o(f,d,t)&&e.add(t);return f[i]&&e.add(i),e},a.rels=()=>d,a.parents=e=>d[e],a.ancestors=e=>new Set(l([],d,e)),a}const o=(e,t,n)=>{const i=t[n];if(i)for(let n of i){let i=e[n]||o(e,t,n);if(i)return i}},l=(e,t,n)=>{const i=t[n];if(i)for(let n of i)e.push(n),l(e,t,n);return e},s=e=>{const t={};for(let n in e){const i=e[n];t[n]=i instanceof Set?i:new Set(i)}return t};e.DEFAULT=i,e.defmulti=r,e.defmultiN=(e,t)=>{const o=r((...e)=>e.length);o.add(i,t||((...e)=>n.illegalArity(e.length)));for(let t in e)o.add(t,e[t]);return o},e.implementations=(e,t,...i)=>{if(1&i.length&&n.illegalArgs("expected an even number of implementation items"),t)for(let n in t)for(let i of t[n])i.isa(e,n);for(let t=0;t<i.length;t+=2)i[t].add(e,i[t+1])},e.setLogger=t=>e.LOGGER=t,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/api"),require("@thi.ng/errors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/api","@thi.ng/errors"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.defmulti={}),e.thi.ng.api,e.thi.ng.errors)}(this,(function(e,t,n){"use strict";const i=Symbol();e.LOGGER=t.NULL_LOGGER;function r(t,r){const s={},d=r?f(r):{},a=(...e)=>{const r=t(...e),l=s[r]||o(s,d,r)||s[i];return l?l(...e):n.unsupported(`missing implementation for: "${r.toString()}"`)};return a.add=(t,n)=>(s[t]&&e.LOGGER.warn(`overwriting '${t.toString()}' impl`),s[t]=n,!0),a.addAll=e=>{let t=!0;for(let n in e)t=a.add(n,e[n])&&t;return t},a.remove=e=>!!s[e]&&(delete s[e],!0),a.callable=(...e)=>{const n=t(...e);return!!(s[n]||o(s,d,n)||s[i])},a.isa=(e,t)=>{let n=d[e];!n&&(d[e]=n=new Set),n.add(t)},a.impls=()=>{const e=new Set(Object.keys(s));for(let t in d)o(s,d,t)&&e.add(t);return s[i]&&e.add(i),e},a.rels=()=>d,a.parents=e=>d[e],a.ancestors=e=>new Set(l([],d,e)),a.dependencies=function*(){for(let e in d)for(let t of d[e])yield[e,t];for(let e in s)!d[e]&&(yield[e,void 0])},a}const o=(e,t,n)=>{const i=t[n];if(i)for(let n of i){let i=e[n]||o(e,t,n);if(i)return i}},l=(e,t,n)=>{const i=t[n];if(i)for(let n of i)e.push(n),l(e,t,n);return e},f=e=>{const t={};for(let n in e){const i=e[n];t[n]=i instanceof Set?i:new Set(i)}return t};e.DEFAULT=i,e.defmulti=r,e.defmultiN=(e,t)=>{const o=r(((...e)=>e.length));o.add(i,t||((...e)=>n.illegalArity(e.length)));for(let t in e)o.add(t,e[t]);return o},e.implementations=(e,t,...i)=>{if(1&i.length&&n.illegalArgs("expected an even number of implementation items"),t)for(let n in t)for(let i of t[n])i.isa(e,n);for(let t=0;t<i.length;t+=2)i[t].add(e,i[t+1])},e.setLogger=t=>e.LOGGER=t,Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "@thi.ng/defmulti", | ||
"version": "1.2.26", | ||
"version": "1.3.0", | ||
"description": "Dynamic, extensible multiple dispatch via user supplied dispatch function.", | ||
@@ -42,14 +42,14 @@ "module": "./index.js", | ||
"@istanbuljs/nyc-config-typescript": "^1.0.1", | ||
"@microsoft/api-extractor": "^7.9.11", | ||
"@microsoft/api-extractor": "^7.12.0", | ||
"@types/mocha": "^8.0.3", | ||
"@types/node": "^14.6.1", | ||
"mocha": "^8.1.2", | ||
"mocha": "^8.2.1", | ||
"nyc": "^15.1.0", | ||
"ts-node": "^9.0.0", | ||
"typedoc": "^0.18.0", | ||
"typescript": "^4.0.2" | ||
"typedoc": "^0.19.2", | ||
"typescript": "^4.1.2" | ||
}, | ||
"dependencies": { | ||
"@thi.ng/api": "^6.13.1", | ||
"@thi.ng/errors": "^1.2.22" | ||
"@thi.ng/api": "^6.13.2", | ||
"@thi.ng/errors": "^1.2.23" | ||
}, | ||
@@ -62,3 +62,4 @@ "files": [ | ||
"keywords": [ | ||
"arity", | ||
"agent", | ||
"clojure", | ||
"functional", | ||
@@ -78,3 +79,3 @@ "hierarchy", | ||
}, | ||
"gitHead": "130dff672b56f789205177c2243169d33d479948" | ||
"gitHead": "3a89bdfa4c58983d5e005b3e9fb056b0351198fe" | ||
} |
@@ -25,2 +25,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
- [True multiple arg dispatch](#true-multiple-arg-dispatch) | ||
- [Dispatch value graph visualization](#dispatch-value-graph-visualization) | ||
- [Authors](#authors) | ||
@@ -57,3 +58,3 @@ - [License](#license) | ||
Package sizes (gzipped, pre-treeshake): ESM: 750 bytes / CJS: 811 bytes / UMD: 885 bytes | ||
Package sizes (gzipped, pre-treeshake): ESM: 801 bytes / CJS: 863 bytes / UMD: 939 bytes | ||
@@ -111,2 +112,3 @@ ## Dependencies | ||
- `.ancestors(id)` - transitive parents of dispatch value `id` | ||
- `.dependencies()` - returns iterator of all dispatch value relationship pairs | ||
@@ -333,2 +335,42 @@ #### Dispatch value hierarchies | ||
#### Dispatch value graph visualization | ||
To facilitate better introspection of dynamically constructed/added `defmulti()` | ||
implementations (with possibly deep hierarchies of dispatch values), we can | ||
utilize the `.dependencies()` method to extract all dispatch value relationships | ||
and use these to build [dependency | ||
graph](https://github.com/thi-ng/umbrella/tree/develop/packages/dgraph), which | ||
then can also be visualized. | ||
```ts | ||
import { defDGraph } from "@thi.ng/dgraph"; | ||
import { toDot } from "@thi.ng/dgraph-dot"; | ||
const fn = defmulti((x) => x); | ||
// dummy impls | ||
fn.add("a", () => {}); | ||
fn.add("d", () => {}); | ||
// dispatch value relationships | ||
fn.isa("b", "a"); | ||
fn.isa("c", "b"); | ||
fn.isa("e", "d"); | ||
// build dependency graph and export as Graphviz DOT format | ||
console.log(toDot(defDGraph(fn.dependencies()), { id: (id) => id })); | ||
// digraph g { | ||
// "b"[label="b"]; | ||
// "c"[label="c"]; | ||
// "e"[label="e"]; | ||
// "a"[label="a"]; | ||
// "d"[label="d"]; | ||
// "b" -> "a"; | ||
// "c" -> "b"; | ||
// "e" -> "d"; | ||
// } | ||
``` | ||
![Graphviz output](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/defmulti/readme.dot.svg) | ||
## Authors | ||
@@ -335,0 +377,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
69048
660
379
Updated@thi.ng/api@^6.13.2
Updated@thi.ng/errors@^1.2.23