Giter Site home page Giter Site logo

augmentor's Introduction

augmentor

Build Status Coverage Status Greenkeeper badge WebReflection status

Extensible, general purpose, React like hooks for the masses.

Code Pen playground.

Include via:

  • CDN as global utility, via https://unpkg.com/augmentor
  • CJS via const {default: augmentor, useState} = require('augmentor')
  • ESM via import augmentor, {useState} from 'augmentor'
  • ESM CDN via import augmentor, {useState} from 'https://unpkg.com/augmentor?module'

Available Hooks

All hooks behave as close as possible to their React counter part, with a notable difference for useEffect.

A DOM oriented useEffect

If you'd like to have DOM nodes connect/disconnect hooks, similarly to how React mount and unmount work, consider using dom-augmentor or keep reading to understand how to write your own.

example

You can test this example directly on Code Pen.

import augmentor, {useState} from 'augmentor';

// augment any function once
const a = augmentor(test);
a();

// ... or many times ...
const [b, c] = [test, test].map(augmentor);
b();
c();

function test() {

  const [count, setCount] = useState(0);

  // log current count value
  console.log(count);

  // will invoke this augmented function each second
  setTimeout(() => setCount(count + 1), 1000);
}

What's different in useEffect

With React components, when you pass an empty array to useEffect the effects, and their cleanup, would run only on component mounted or unmounted.

However, being augmentor a general purpose utility, there is no notion of any component, so that an empty array will result into an effect that will run once, but it'll never clean up unless explicitly forced through the augmented function .reset() method.

import augmentor, {useEffect} from 'augmentor';

const effected = augmentor(() => {
  useEffect(
    () => {
      const i = setInterval(console.log, 1000, Math.random());
      return () => clearInterval(i);
    },
    []
  );
});

// will start showing the random number every second
effected();

// will cleanup the effect in 5 seconds
setTimeout(effected.reset, 5000);

This behavior might be OK in some well orchestrated case, but it's quite unpractical in the real world.

To help developers define whenever effects should run, or cleanup, instead of passing an empty array one can pass a callback which will be executed right after the augmented function is invoked, receiving effect callback, and the augmented function returned value.

In this case, the augmentor will invoke such callback once, and never again, for the whole augmented lifecycle (unless forced via explicit .reset()), so that it's safe to setup an effect behavior within the provided effects handler.

import augmentor, {useEffect} from 'augmentor';

const effected = augmentor(() => {
  useEffect(
    () => {
      const i = setInterval(console.log, 1000, Math.random());
      return () => clearInterval(i);
    },
    lifecycleHandler
  );
  // returning some value
  return 5000;
});

// will start showing the random number every second
// and it will automatically clean up after 5 seconds
effected(); // returns 5000

function lifecycleHandler(callback, result) {
  const cleanUp = callback();
  // returned value used to clear the timer after 5 seconds
  setTimeout(cleanUp, result);
}

You can see this mechanism in practice applied through the neverland library, where passing an empty array will implicitly result into observing nodes through the DOM.

About useImperativeMethods

This hook is strictly React oriented and have no meaning in current augmentor world.

Create your own hook

Beside using any of the already implemented hooks to create your own would work just fine, you could also take advantage of internals used to create other hooks.

The augmentor core provides indeed utilities to make your own hook, for your own library, and export these like any other.

Following a useUpdate example based on these internals.

import {setup, stacked, unstacked, uid} from 'augmentor/esm/core.js';

// create a unique identifier for this hook
const id = uid();

// add to each runner setup a new stack for this hook
setup.push(stacked(id));

// export the updater
export const useUpdate = value => {
  const {i, stack, update, unknown} = unstacked(id);
  // if unknown, add this this hook stack any value
  // this could be also the update function itself
  // which will re-invoke the callback any time it's used
  if (unknown)
    stack.push(update);
  // return the current stack position at index `i`
  return stack[i];
};

Now import the code in your project, and see every time an updater is invoked the whole callback is re-executed.

import augmentor from 'augmentor';
import { useUpdate } from './use-update.js';

const zero = augmentor(increment);

zero({value: 0});

function increment(ref) {
  // used to invoke again the augmented function
  const update = useUpdate();
  setTimeout(update, 1000);

 // log and increment the reference value
  console.log(ref.value++);
}

You can test both files, as CJS version, through the example folder.

augmentor's People

Contributors

greenkeeper[bot] avatar webreflection avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.