@hyrious/utils

Common JS/TS utils by hyrious


Keywords
utils
License
MIT
Install
npm install @hyrious/utils@0.0.6

Documentation

@hyrious/utils

Utility functions I often use.

Contents

Most of the utils are quite simple, I'd suggest you to read the source code directly. Some interesting parts will be documented here.

observable(sample?)

Create a emitter that on() returns a disposer.
let emitter = observable({ a: 1, b: "" });
let dispose = emitter.on("a", (a) => console.log(a));
emitter.emit("a", 2); // logs: 2
dispose();

To use it in typescript:

let emitter = observable<{ a: number; b: string }>();

writable(initial?)

Create a reactive value (an instance of Val) that can be subscribed.
let count$ = writable(0);
count$.subscribe(console.log); // logs: 0
count$.set(1);                 // logs: 1
count$.value;                  // 1

To create a readonly value (i.e. no set()), you just type-cast it to Readable.

let count$ = writable(0);
let readonlyCount$: Readable<number> = count$;

This is super useful for using in UI frameworks.

import { useSyncExternalStore } from "use-sync-external-store/shim";
const foo$ = writable(0);
const subscribeFoo = foo$.subscribe.bind(foo$);
function App() {
  const foo = useSyncExternalStore(subscribeFoo, () => foo$.value);
  return <button onClick={() => foo$.set(foo$.value + 1)}>{foo}</button>;
}

Feature, not bug:

let foo$ = writable(-0);
foo$.set(+0); // won't trigger listeners because -0 === +0, same as NaN === NaN
let obj = [];
foo$.set(obj); // triggers listener(obj)
foo$.set(obj); // triggers listener(obj) again, because the object may be modified

let bar$ = writable();
bar$.subscribe(console.log); // no log, because bar$ is not ready
bar$.set(1); // logs: 1
bar$.set(undefined); // logs: undefined

batch(render)

Batch multiple calls to one to happen in next micro task.
const schedule = batch(render);
times(10, () => schedule()); // run 10 times synchronously
await tick();
expect(render).toBeCalledTimes(1); // only render once

Coding Style

1. Make sure to only export pure variables.
export let a = 1;           // pure
export let a = 1 << 1;      // maybe not pure (need constant folding)
export let a = {}; a.b = 1; // not pure
export function f() {}      // pure
2. Correctly export isomorphic modules.
"exports": {
   "./module": {
      "node": "./module-node.js",
      "default": "./module.js" // bundlers will be happy to see this
   }
}
  1. No fool-proofing checks, use typescript to call attention.

License

MIT @ hyrious