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

@debonet/es6pacts

v3.0.0

Published

Releasable/cancellable and Reporting Promises for Javascript ES6

Downloads

83

Readme

es6pacts

Releasable, reporting Promises for JavaScript ES6.

TL;DR

  • A Pact is a Promise that can be released from its obligation (release, resolve, reject, fulfill) and that delivers progress reports to independent observers (.progress).
  • One line of composition: fclassReleasable( Task ). Release semantics come from @debonet/es6pledges; reporting semantics come from @debonet/es6tasks.
  • The constructor takes a single executor argument, ( fResolve, fReject, fReport ) => xPolicy. The executor's RETURN VALUE is the release policy; the v2 second constructor argument is removed.
  • Progress reports stop when the pact settles. This is a library guarantee (post-settle suppression), not executor discipline.

Example

const Pact = require( "@debonet/es6pacts" );

function fpactDelay( dtm, dtmTick = 100 ){
	return new Pact(( fResolve, fReject, fReport ) => {
		let dtmElapsed = 0;
		const interval = setInterval(() => {
			dtmElapsed += dtmTick;
			fReport( dtmElapsed );
			if ( dtmElapsed >= dtm ){
				clearInterval( interval );
				fResolve( dtm );
			}
		}, dtmTick );
		return () => clearInterval( interval );
	});
}

Hold the SOURCE pact and release it; cancellation flows downstream as ordinary settlement:

const pactDelay = fpactDelay( 10000 );

pactDelay
	.progress(( dtmElapsed ) => console.log( "progress:", dtmElapsed ))
	.then(( x ) => console.log( "result:", x ));

setTimeout(() => { pactDelay.resolve( "faster" ); }, 250 );

Output:

progress: 100
progress: 200
result: faster
  • The release at 250ms lands mid-gap between the 200ms and 300ms ticks, so the output is stable.
  • The cleanup is the executor's return value: return () => clearInterval( interval );. It clears the interval, and post-settle suppression guarantees no report after settlement.
  • The usage releases the source pact, not a chain tail. Releasing a derived pact settles only that pact and skips its own handler (see Chains).

Same example, three libraries: remove the fReport executor parameter and the fReport( dtmElapsed ); line and this is fpledgeDelay (@debonet/es6pledges — releasable, no reporting). Remove instead the return () => clearInterval( interval ); line and this is ftaskDelay (@debonet/es6tasks — reporting, not releasable). All other lines are identical across the three libraries. Pact is the union, exactly as fclassReleasable( Task ) is the union of the two libraries.

Chain Windowing

Using the same fpactDelay, attachment position selects what a .progress observer sees:

const pactFirst = fpactDelay( 10000 );

const pactDone = pactFirst
	.progress(( dtm ) => console.log( "first stage:", dtm ))
	.then(( x ) => fpactDelay( 300 ))
	.progress(( dtm ) => console.log( "whole chain:", dtm ));

setTimeout(() => pactFirst.resolve( "faster" ), 350 );

pactDone.then(( x ) => console.log( "result:", x ));

Output:

first stage: 100
whole chain: 100
first stage: 200
whole chain: 200
first stage: 300
whole chain: 300
whole chain: 100
whole chain: 200
whole chain: 300
result: 300

What the example shows:

  • The .progress attached BEFORE the .then observes only pactFirst's stage.
  • The .progress attached AFTER the .then observes the forwarded parent stream plus the stream of the pact the handler returns.
  • The release arrives mid-chain: pactFirst.resolve( "faster" ) settles the first stage, its reports stop (post-settle suppression), and the early value flows downstream as ordinary settlement.

The Executor

new Pact( fxExecutor ) takes ONE argument. Task supplies fReport as the executor's third parameter, so the full signature is ( fResolve, fReject, fReport ) => xPolicy. The return value xPolicy is the release policy:

  • A function ( xReason ) => ... — the release handler. It closes over fResolve, fReject, fReport, and the executor's locals (the useEffect-cleanup idiom).
  • An Error instance — unconditional refusal: every release() rejects with it.
  • undefined or anything else — releasable with no cleanup.

Release

pact.release( xReason ) runs a consent pipeline: the policy may clean up and consent, or refuse. On consent the pact settles by type dispatch on xReason:

  • PactResolve → resolves with its cause
  • PactReject → rejects with its cause
  • any other Error → rejects with it
  • anything else → resolves with it

Pact.PactResolve and Pact.PactReject are statics on the class.

The release() return contract:

  • FULFILLS with a settlement record { sStatus, x } after the pact settles, ordered after handlers registered before the call.
  • REJECTS only on refusal (the release handler threw or rejected) while the pact was still pending. A refused pact stays pending, keeps all handlers, and keeps reporting.

Settlement is a report that the obligation ended; nothing settles the pact without the release handler's consent. No forced settlement exists.

Settle Verbs

  • pact.resolve( x )pact.release( new PactResolve( x ))
  • pact.reject( e )pact.release( new PactReject( e ))
  • pact.fulfill( x ) — alias of resolve( x )

All refusable, same pipeline. The instance resolve / reject are distinct from the inherited statics Pact.resolve / Pact.reject, which construct already-settled pacts.

releaseOn

pact.releaseOn( signal ) requests a release when the AbortSignal fires, with signal.reason as xReason; it returns this. A bare abort() produces an AbortError, which rejects by dispatch; abort( xValue ) resolves with the value. This is a refusable request, not an unconditional deadline.

Chains

Cancel a pipeline at its SOURCE: release the base pact you hold, and cancellation flows downstream as ordinary settlement. Releasing a derived pact never affects an ancestor; it settles the derived pact (and at most one owned child: an in-flight pact returned by its own stage handler).

Reporting

  • pact.progress( f ) registers an independent observer and returns this (chainable).
  • Every observer receives the SAME raw value passed to fReport, in attachment order. Observer return values are ignored.
  • Delivery is queued on a microtask. There is no replay buffer: attach late, miss earlier reports.
  • Once the pact settles, further reports are dropped by the library.
  • Derived pacts forward their parent's report stream, plus the stream of any pact a handler returns. Attachment position selects the observation window (see Chain Windowing).
  • Combinators (Pact.all, any, race, allSettled) re-emit member reports as { task : n, report : x } and suppress them once the combined pact settles. Releasing a combined pact settles the combined pact only; members are not owned and keep running.

Interlocking Guarantees

  • A released pact is a settled pact, so its reports stop — suppression is central, in the library.
  • A refused release leaves the pact pending, so reports keep flowing during and after the refusal.

Full Semantics

This module adds no behavior of its own; the complete contracts live upstream:

  • @debonet/es6pledges specs/v3-core.md — constructor, executor, policy, pipeline, dispatch, wrappers, release contract, verbs, releaseOn.
  • @debonet/es6pledges specs/v3-chains-combinators.md — chain and combinator release.
  • @debonet/es6tasks specs/v3-reporting.md — observer model, microtask delivery, post-settle suppression, windowing, combinator report format.

See Also

  • @debonet/es6pledges
  • @debonet/es6tasks