Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hook-up

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hook-up

Create your own hook api with 2-dimensional hooks - better than events or simple hooks

  • 0.2.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
11
increased by22.22%
Maintainers
1
Weekly downloads
 
Created
Source

hook-up

Speed, functionality, simplicity - choose two.

This fundamental tradeoff in programming is as true as always. We are just better at hiding complexity - regular severe security flaws are a reminder of what we already hid away.

The only way we can improve this tradeoff is clever program design.

Over the last few years of programming I produced two very helpful guidelines

  • aim for declarative programming
  • separate by functionality

Aim for declarative programming

Make your programs work with configuration files - the most common type of declarative programming. They can be easily read, merged, diffed and shared.

Common settings of different projects can be easily extracted and maintained in one place.

I created read-conf as a powerful configuration reader with watching and plugin functionality.

Separation by functionality

Separation by functionality greatly improves extendability and understandability - thus maintainability.

You probably experienced the need for a major refactoring or even a complete rewrite at least once. And you will remember the large impact this had on your project - This happens when functionality isn't separated properly.

I'm using two design pattern for different types of programms:

  • user interface: mixins (used in cerijs)

Each functionality is encapsulated in one mixin. A user interface component and each mixin can depend on other mixins. You need one main merging algorithm to resolve the dependency tree and merge all functionality into your ui-component.

  • processing programs: plugins and actions (used in leajs or snapy)

Think of an action as an 2d array of callbacks where a state can progress through. Each callback only interacts with the current (action and/or program) state.

# cb2 and cb3 will be called simultaneously but only after cb1 is finished
# there is empty space where plugins could hook in more cbs
{actionState, programState} -> [cb1, , , , [cb2, cb3], , ,] -> {actionState}

A plugin can hook in in those actions on any position.

This package is an action builder working in node and in browser (in combination with e.g. webpack)

Install

npm install --save hook-up

Usage

hookUp = require("hook-up")

program = {
  config: {}
}

// hookUp(obj:Object, options:Object)
hookUp(program,{
  actions: {
    {"": "run"},
    {"cache": ["get", "set"]}
  },
  catch: {
    "cache.get": (e) => { console.error(e) } 
  }
})

// hookIn([position:Number], cb:Function)
// position defaults to program.position.during
// (see below)
program.run.hookIn((state,{config}) => {
  // config equals program.config
  // it is recommend to test the state if you depend on it
  // as you have no idea what the previous cbs did
  if (// is in correct state) {
    // doSomething with state
  } 
  // you don't need to return anything, each cb will be
  // called with the current action and program state
  // if you return a promise or the cb is async
  // the next cb will only get called afterwards
})
result = await program.run({})

// remove all cbs
program.run.reset()

// program.position
// with a default spread of 8
// contains the predefined positions:
// {init: 0,before: 8, during: 16, after: 24, end: 32}
program.run.hookIn(program.position.init, (state) => {
  // init state somehow
})

For the separation by functionality design pattern each functionality needs to be a separate plugin (not necessarily a separate package). These plugins need access to the actions of your program.

Options
Nametypedefaultdescription
actionsString or Array or Object-name of the actions - maximum 1 depth
catchObject-lookup object to apply default catch functions to actions
spreadNumber8distance between the predefined positions
positionObject-lookup object to use as predefined positions
PromiseObjectnative PromisePromise lib to use
namesObject-see below

you can change the default names:

// available: "hookIn", "reset", "position", "call"
hookUp(program = {},{
  actions: "run",
  names:{
    hookIn: "", // only one of hookIn or call can be empty
    reset: "clear",
    position: "pos",
    call: "call"
  }
})

program.run(program.pos.init,(state)=>{
  // do something
})
result = await program.run.call({})
program.run.clear()

License

Copyright (c) 2017 Paul Pflugradt Licensed under the MIT license.

FAQs

Package last updated on 19 Feb 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc