JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2568
  • Score
    100M100P100Q115157F
  • License MIT

A tiny library to encapsulate side effects in a compact, reusable and testable style.

Package Exports

  • side-effect-manager
  • side-effect-manager/dist/side-effect-manager.cjs.js
  • side-effect-manager/dist/side-effect-manager.es.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (side-effect-manager) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

side-effect-manager

Build Status npm-version Coverage Status

Commitizen friendly Conventional Commits code style: prettier

A tiny library to encapsulate side effects in a compact, reusable and testable style.

Install

npm add side-effect-manager

Why

Conventionally we write side effects like this:

class MyClass {
  constructor() {
    this.handleResize = () => {
      console.log("resize");
    };
    window.addEventListener("resize", this.handleResize);
  }

  destroy() {
    // cleanup side effects
    window.removeEventListener("resize", this.handleResize);
  }
}

This code style is scattered and hard-to-follow. The side effect handler has to be exposed to this which leaves us many unwanted and uncompressible properties.

With side-effect-manager we may write the same logic like this instead:

import { SideEffectManager } from "side-effect-manager";

class MyClass {
  constructor() {
    this.sideEffect = new SideEffectManager();

    this.sideEffect.add(() => {
      const handleResize = () => {
        console.log("resize");
      };
      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    });

    // or simply like this
    this.sideEffect.addEventListener(window, "resize", () => {
      console.log("resize");
    });
  }

  destroy() {
    this.sideEffect.flushAll();
  }
}

Not only the code is more compact and readable, variables can now be compressed as they are not properties.

Usage

Add a side effect:

sideEffect.add(() => {
  const subscription = observable$.subscribe(value => {
    console.log(value);
  });
  return () => subscription.unsubscribe();
});

There are also sugars for addEventListener, setTimeout and setInterval.

sideEffect.setTimeout(() => {
  console.log("timeout");
}, 2000);

Adding a side effect returns a disposerID which can be used to remove or flush a side effect.

const disposerID = sideEffect.addEventListener(window, "resize", () => {
  console.log("resize");
});

// Remove the side effect without running the disposer callback
sideEffect.remove(disposerID);

// Remove the side effect then run the disposer callback
sideEffect.flush(disposerID);

A disposerID can also be set deliberately. Side effects with the same ID will be flushed before adding a new one.

function debounce(handler, timeout) {
  sideEffect.setTimeout(handler, timeout, "my-timeout");
}