npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mona-dish

v0.50.0-beta.8

Published

TypeScript/Javascript set of functional pattern inspired helpers, which will ease your programming live

Readme

Mona-dish

A set of functional programming "inspired" helpers

What is it?

This project is a set of small helpers which utilize mostly monad and monad like patterns to cut down on code for essential tasks.

For now, it is only a small set of Helpers consisting of following items:

  • Monad ... an implementation of a Monad
  • Optional ... a class which is derived from Javas optional but also encapsulates elvis operator like accessors to cut down on code
  • ValueEmbedder ... if you ever need something like optional but want to write the value as well this might be what you are looking for
  • Promise ... a promise shim implementation for older browsers (newer ones have Promised baked in), will be deprecated soon, there are better options
  • CancellablePromise ... a promise with cancel functionality
  • Configuration ... an Optional utilizing wrapper over json configurations which allow both read and write access and elvis like access to the data stored in the config
  • Streams ... a typescript based implementation of early and lazily evaluating streams
  • DomQuery ... a jquery like functional query and dom manipulation engine based on querySelectorAll, also support streams and shadow dom trees
  • XmlQuery ... a jquery like XML document query selection and manipulation engine ... also supports streams
  • Messaging ... a messaging bus which can break page isolation levels to allow communication between iframes/popups/shadow dom/dom, exposed via mona-dish/messaging
  • RxJS ... RxJS bindings for the optional messaging module

Breaking change: messaging moved to an explicit entry point

The default mona-dish package entry now exposes the core API only and does not load the RxJS-backed messaging module.

Projects using messaging must import it from mona-dish/messaging:

import {Broker, BroadcastChannelBroker, Message} from "mona-dish/messaging";

rxjs remains a consumer-provided external dependency. Install/provide it in applications which use mona-dish/messaging.

Implementation languages

Everything is implemented in typescript and can be used straight from the source directories "src/main/typescript".

However, also javascript transpilations for various packaging systems and ecmascript levels are in place as well hosted under "dist".

If you want a cleaner cut between your own typescript sources, and the mona-dish sources there is a d.ts file also, hosted under "dist".

building

For building the project you need following

  • npm
  • webpack

once this is done you can build it by calling ./init.sh one time to install all the needed build dependencies, after that calling /build.sh rebuilds the entire project.

You also can run mocha based unit tests on the project by calling ./test.sh

(note this is for unixoid systems, windows command files will be added soon, in the meanwhile simply check the command sequences in the sh files for building and testing)

Usage

Optional

The enhanced documentation for optional can be found here:

For a non sideffect free implementation, you can use:

ValueEmbedder

Optional is a purely readonly construct, now for sideffect free-ness, having only readonly operations is fine. However, in iterative systems we often deal with states. To get the conciseness of Optional also for writeable states there is a class available which is inherited from optional and hence shares the same functionality.

Configuration

Promise and CancellablePromise

Promise is just a lightweight shim of the Promise API including finally. Cancellable promise adds on top of that by allowing to cancel (aka never hit the then/cancel phase)

Stream

The idea is to have streams like java does for arrays. (forEach, filter etc...)

Details

The streams are heavily influenced by the java streams. Currently, two type of streams are implemented

  • Early streams (Streams)

The default (working already) a simple implementation of early evaluating streams

  • Lazy Streams (LazyStreams) Lazily evaluating streams, aka elements are processed at the latest possible stage, this is the default in Java. The advantage of those is you basically can process endless data without any impact on ram. Hence there is a set of Data Providers implemented and a general DataProvider interface available.

Usage

beforeEach(function () {
        this.probe = [1, 2, 3, 4, 5];
});

it("must have a correct first last lazy", function () {
    let stream = LazyStream.of<number>(...this.probe);

    let first = LazyStream.of<number>(...this.probe).filter((data) => data != 5).onElem((data) => {
        data;
    }).first().value;
    let last = Stream.of<number>(...this.probe).filter((data) => data != 5).onElem((data) => {
        data;
    }).last().value;
    expect(first).to.eq(1);
    expect(last).to.eq(4);
});

Or in conjunction with DomQuery

let searchRoot = DomQuery.querySelectorAll("input[type='hidden']")
let formWindowId: Optional<string> = searchRoot
                    .stream
                    .map<string>(getValue)
                    .reduce(doubleCheck, INIT); 

let otherStream = LazyStream.ofDataSource(searchRoot);

See StreamTest.spec.ts in the "test sources" directory for additional examples

DomQuery

A JQuery like interface for standard dom queries, also supports Streams and Shadow doms. Further Info can be found here

DomQuery ... a jquery like functional query and dom manipulation engine based on querySelectorAll, also support streams and shadow dom trees

XmlQuery

similar to DomQuery but atm without a full query engine behind it, the reason for that is, that the browsers do not have a universal query engine, yet. Also, I tried to avoid third party dependencies. You, also, will get many other benefits similar to DomQuery by using XmlQuery

Messaging

A messaging bus ... for documentation follow this link:

Messaging is not exported by the default mona-dish package entry anymore. Use:

import {Broker, BroadcastChannelBroker, Message} from "mona-dish/messaging";

Extended Documentation

I am going to provide extended documentation on the various aspects of mona-dish in following subpages

Examples

Various usage examples can be found in the tests:

Changelog

(Starting with version 0.18)

...

Version 0.18

Adding Extended Array, to provide shim like functionality without shims (adds several functions to the standard array older browsers do not support, but does not hook itself in like a shim)

Version 0.19

  • New messaging submodule
  • Improved documentation
  • DomQuery: Shadow Dom support

Version 0.19.1 - 0.19.22

  • ongoing works in the messaging area (not fully finalized)
  • minor api change, channel now parameter in broker.broadcast instead of part of the message.
  • setting the code baseline of the compiled code to es5
  • Messaging will be finalized in version 0.20.x
  • Minor compiler issues fixed in the "typings" area which could cause typescript warnings
  • Bidirectional messaging which allows answer/response patterns
  • Re-enabling IE11 compatibility
  • basing the messaging on top of the broadcast channel as universal base, the messaging is basically a broadcast channel++ with additional functionality

Version 0.20.++

  • Rxjs connectivity, rxjs is a more popular framework than mona-dish but both have a heavy functional overlap. It makes sense to open mona-dish for rjxs in both directions to be able to combine both frameworks easily

  • RXJS forward connectivity enabled via iterable implementation! you can basically now use streams as iterables

  • 20.3 Adding basic rxjs support for streams

  • 20.4-20.5 Adding rxjs connectivity apis for the messages, brokerchannels now can be exported as Subjects

  • 0.20.7 Adding encryption extension points to the messaging api

  • 0.20.8 extension refinements tests for the extensions documentation updates

Version 0.21.++

  • 0.21.0 adding a mutation observer

Version 0.22 ++

  • Api change, the Promise has been removed from the index.js and resides in its own PromiseShim.js file. The reason was UMD builds did not check for an existing Promise before installing it. It made sense to decouple it anyway, literally all modern browsers do not need it anymore. CancellablePromise is still enabled.
  • Added convenience methods for easier access to value (via val) and innerHTML,
  • mutation observer fixes
  • improved nonce handling
  • improved rxjs connectivity
  • documentation updates
  • changing default package type from commonjs to umd, to improve ide handling
  • adding a sticky eval to DomQuery to keep the evaled elements in the head
  • adding a sticky eval handling to run scripts as well

Version 0.23+

  • (minor version change due to an api change which has been reverted)
  • fixing the script loading, loading order now in a series of scripts is in sync with mixed src and embedded scripts (no api change)

Version 0.24 ++

  • Optional typed and semi typed configs which allow fixed keys and subtrees of keys which are not predefined

Version 0.25 ++

  • Fixing of bugs in the stream area
  • API change for the lookAhead (might break old code using it)
  • Added Config Collector similar to Assoc Array Collectors

This is from now on a development branch, to finally split between unstable and stable

0.25.20

Breaking change:

To get reduced coupling between modules (I want to make the usage of Config optional) DomQuery does not use Config anymore but relies on standard associative arrays:

  • before: encodeFormElement(toMerge: Config): Config;
  • new: encodeFormElement(toMerge: {[key: string]: any}): {[key: string]: any};

Config now is not a dependency of DomQuery anymore!

A new module AssocArray provides helper functions to provide a similar functionality as Config

0.25.26

Another minor breaking change.

0.25.26 reorganizes the internal data structure of config to allow easier access and a direct mapping of associative arrays and arrays. (Allows for easier debugging internal data structures and a small speed bump) due to this change following construct is not possible anymore

let conf = new Config({}); conf.assign("[5]","[6]","key").value = "new value";

This goes hand in hand with the newly introduced low level associative array api you have to change the code accordingly let conf = new Config([]); conf.assign("[5]","[6]","key").value = "new value";

So always when an array is referenced from root, the root element must be an array otherwise an exception is thrown (the same goes for existing subelemements)

(the same goes implicity for associative arrays in the other direction, arrays cannot have key references anymore with assignments)

Version 0.26 ++

  • Fixing of bugs in the stream area
  • API change for the lookAhead (might break old code using it)
  • Added Config Collector similar to Assoc Array Collectors

This is from now on a stable branch (and all even numbered ones will be, with every odd branch there will be a higher even numbered one release to avoid accidental downloads)

Version 0.28++

Important API chnage

  • Decoupling of Stream and DomQuery

In order to reduce the possible include size, there now is a stronger decoupling between streams and DomQuery. You now can use DomQuery without linking the Streams. In order to do so, the API has slightly changed. DomQuery.streams now is gone To generate a Stream of a DomQuery object you can use Stream.ofDomQuery and LazyStream.ofDomQuery

The reason was that Streams have a significant code overhead and with ES2019 the native api has somewhat reached the status of good enough with the inclusion of map. (internally we provide a non, bleeding shim for that functionality)

If you include Streams the backwards compatibility is restored

  • Decoupling of DomQuery and Config

Additional api change, in order do decouple DomQuery and Config encodeSubmittableFields now returns an associative array instead of a Config. You can convert it back to an associative array simply by using

new Config(dq.encodeSubmittableFields())

Other changes 0.28++

  • Es2019 Array as non-intrusive Es2019 array shim (providing filter and flapMap to browsers which do not support it)

  • New helper module providing functions similar to what config does to plain associative arrays

  • Internal Config data structure reorganisation on top of the new AssocArray helper module it now uses plain associative arrays as internal data structure to make debugging easier

  • added nonce ValueHolder to DomQuery (console.log(element.nonce.value) and element.nonce.value = "nonceValue"), or element.nonce.isPresent()

  • Fixing shallow copy in AssocArray

Version 0.40.0

Update to typescript 6.0 in preparation for typescript 7

Version 0.40.0-beta.3

Breaking change:

Messaging moved out of the default mona-dish package entry and is now exposed via mona-dish/messaging. This keeps the default package entry free of the RxJS-backed messaging layer. Applications using messaging must import from mona-dish/messaging and provide rxjs themselves.

Build and test changes:

  • Removed the runtime build/test dependency on ts-node; TypeScript config files and tests now run through tsx.

  • Webpack keeps using webpack.config.ts, but bundle builds now run with full ts-loader type checking.

  • npm run build runs verify first, then docs, declarations, bundles, dist copy, and dist smoke tests.

  • Added npm run smoke to verify generated dist module formats.

  • Added manual npm run package:test to pack the package isolatedly and verify core usage without RxJS plus messaging usage with explicitly provided RxJS.

  • Fixed Beta 2 - beta 3

    - Beta 2 and older
       - Webpack runtime: aliased mona-dish → src/main/typescript/index_core.ts (TS source, compiled by ts-loader) — same as now
       - TypeScript type-checking: package had no useful native types entry, so modules.d.ts declared an ambient module "mona-dish" override and the tsconfig paths redirected to the shim, which re-exported from dist/typescript/index_core.ts (TS source alongside .d.ts files in the same dir)
    - Beta 3 (new):
        - Webpack runtime: same — src/main/typescript/index_core.ts via the alias, nothing changed
        - TypeScript type-checking: beta 3 added a proper "types": "./dist/types/index_core.d.ts" condition to the package.json exports map, so TypeScript resolves it natively 

Version 0.50.0-beta.8

Performance (deep selector lookups):

  • _querySelectorAll now pushes each NodeList straight into a single target array via pushChunked instead of nodes = nodes.concat(objToArray(res)), eliminating the per-root objToArray copy and the concat reallocation (two redundant full copies of large result sets, e.g. the querySelectorAll("*") shadow scan in querySelectorAllDeep).
  • querySelectorAllDeep collects shadow hosts in a single pass (new private helper _collectShadowRoots) instead of querySelectorAll("*").shadowRoot, which materialized a DomQuery wrapping every element and then re-walked it through the shadowRoot getter. The cost stays O(number of elements) — there is no selector for "has a shadow root" — but the throwaway all-elements DomQuery and the second traversal are gone. Behaviour is unchanged, covered by a new nested-shadow-root regression test.
  • childNodes now pushChunkeds each root's child list into one target array instead of childNodeArr = childNodeArr.concat(objToArray(item.childNodes)) per root, removing the per-root copy and the O(roots × children) accumulator reallocation.
  • byTagName (includeRoot branch) appends the matching roots via pushChunked instead of reduce((acc, item) => acc.concat([item])), which reallocated the accumulator on every match (O(matches²)). Both are covered by new multi-root regression tests.

Version 0.50.0-beta.6

Bug fix (caret restore on non-text inputs):

  • Fixed Uncaught InvalidStateError: Failed to execute 'setSelectionRange' on 'HTMLInputElement' thrown by DomQuery.setCaretPosition when a checkbox or radio button is re-rendered (e.g. via a JSF/Faces Ajax partial update that focuses the re-rendered control). setSelectionRange exists on every HTMLInputElement but the DOM spec mandates it throw for input types without text selection (checkbox, radio, button, file, …); the prior existence-only guard was therefore insufficient. The call is now wrapped so the error is swallowed while the preceding focus() still applies (silent fail as documented). Regression introduced together with the caret-restore refocus logic.

Version 0.50.0-beta.5

Bug fix (browser argument-stack limit on large arrays):

  • Fixed RangeError: Maximum call stack size exceeded when collections beyond the engine argument-stack limit (~65k elements in Chromium, varies per engine) flow through the library. All internal call-position spreads of unbounded arrays (fn(...data), new Cls(...data), push(...data), Element.prepend(...data)) were replaced by chunk-safe copies (chunk size 30000, see MAX_ARG_LENGTH).
  • New chunk-safe entry points for large data: Es2019ArrayFrom(arrayLike), pushChunked(target, source), Stream.ofArr(array), LazyStream.ofArr(array), ArrayStreamDataSource.ofArray(array). The variadic forms (Stream.of(...arr) etc.) remain unchanged but are inherently subject to the engine argument limit when the caller spreads — use the ofArr-style factories for large arrays.
  • DomQuery now accepts plain element arrays directly (new DomQuery(elementArray)) and flattens them chunk-safely (the constructor signature always advertised this).
  • DomQuery.prepend / prependTo prepend in reverse chunk order — same resulting element order as before, still a single native prepend call below the chunk size.
  • Fixed DomQuery.offsetTop returning NaN (long-standing missing spread in the reduction).
  • Added the regression suite LargeArrayChunkingTest.spec.ts: 200k-element runs over all chunking primitives with full order/completeness verification, 70k-element DomQuery construction, 35k chunk-boundary prepend order check.

Version 0.50.0-beta.4

Cleanup:

  • DomQuery.getCaretPosition: removed the legacy IE document.selection / TextRange fallback branch and rewrote the method as a clean-room selectionStart-only implementation. Caret read-out works on IE9+ and all modern browsers; IE8 and older (which never supported selectionStart) are no longer handled.

Version 0.50.0-beta.3

Bug fix:

  • DomQuery.outerHTML / caret handling: fixed a regression where a partial update of an unrelated component reset the caret of a different, still-focused input field to position 0. The caret is now only saved/restored when the focused element is actually part of the subtree being replaced.
  • DomQuery.getCaretPosition: prefer the modern selectionStart property when available, falling back to the legacy IE document.selection range only when it is not. This makes caret read-out reliable across partial-update cycles (e.g. the Tobago <tc:in> typing scenario).
  • Added regression tests covering caret survival across partial updates and in-subtree restore.

Version 0.50.0-beta.2

Bug fixes and test coverage improvements:

  • Lang.objAssign fallback path: fixed spec non-compliance — now copies enumerable Symbol-keyed own properties via Object.getOwnPropertySymbols + propertyIsEnumerable, matching ES2015 Object.assign behaviour
  • DomQuery.fromMarkup: fixed tfoot branch (was using wrong table index); unified thead/tbody/tfoot into a single branch; added th cell handling (previously fell through to default)
  • DomQuery.setCaretPosition: fixed typo setSelectiongRangesetSelectionRange (caret positioning was silently doing nothing)
  • DomQuery.firstElem / lastElem: fixed guard condition > 1> 0 (single-element DomQuery was skipped); fixed lastElem passing wrong index to callback
  • DomQuery.elements / deepElements: removed invalid checkbox CSS selector (dead weight — checkboxes are already matched by input)
  • DomQuery legacy waitUntilDom fallback: moved timeout/interval declarations before assignment for clarity
  • Style.getClass() / Style.fromNullable(): fixed both returning/creating ElementAttribute instead of Style
  • ElementAttribute.set value(): removed duplicate setAttribute call after loop
  • Added test coverage for: objAssign (12 tests), fromMarkup all branches (14 tests), setCaretPosition (3 tests), firstElem/lastElem (6 tests), Style.fromNullable/getClass (3 tests), waitUntilDom fast-path + tightened assertions