![Vivisector Logo](https://github.com/MatthewZito/vivisector-js/blob/master/documentation/%60vivisect%60.png)
Vivisector.js | Create event-driven datatypes
![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
Table of Contents
Introduction
Vivisector is a light-weight JavaScript library for reactive programming. Vivisector's Observable types broadcast unique events correlated to specific types of mutations and accessors. As such, one can bind methods to variables and render them event-bound.
Vivisector is flexible, compact, and straightforward; it affords you fine-grained control by allowing you to decide when and what happens when a variable changes.
Features
- lightweight, reactive programming with no setup or boilerplate
- Observe prototype methods on Arrays, Objects, Strings
- instantly link/unlink actions to a variable's state
- bind unlimited callbacks to specific types of state-mutation events e.g.
itemadded
, itemremoved
- custom, chainable methods maintain stable execution context i.e. method-chaining without the need to explicitly pipe
this
- helper accessors on all Observables to simplify evaluation
- no need to use
new
keyword, no configuration; Vivisector
types work out-of-the-box - absolutely zero dependencies
Installation and Usage
Install via NPM with npm i vivisector
.
Import Vivisector's caller alias vivisect
:
const { vivisect } = require("vivisector");
Create a new Observable - in this example, of type Array
- and register a handler to fire when any new elements are added:
const logAdditions = ({item, index}) => console.log(`Added ${item} at index ${index}.`);
const users = vivisect(["Alice", "Bob"]);
users.addEventListener("itemadded", logAdditions);
users.push("Charlie");
Have a look at these usage guides for a full overview:
Documentation
Vivisector Types
Arrays
Example:
const albums = vivisect(["Tago Mago", "Monster Movie", "Ege Bamyasi"]);
Unique Methods and Props
findIndexAll
Returns an Array of all indices that contain a match to given argument. Does not evaluate nested items.
Example:
const users = vivisect(["hello", "world", "world", "hello", "world"]);
console.log(users.findIndexAll("hello"));
findIndexAllDeep
Returns an Array of all indices that contain a match to given argument. Walks entire Array tree and evaluates nested items.
Example:
const users = vivisect(["hello",["hello"], "world", ["world", "hello"], ["world", ["world",["hello"]]]]);
console.log(users.findIndexAllDeep("hello"));
Event Types
itemadded
A new item has been added to the Array. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "itemadded", denoting the event-type that was triggered |
item | the new item, now added to the Array |
index | the index at which the item was added |
Fires on: push, unshift, splice
itemset
An item in the Array has moved. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "itemset", denoting the event-type that was triggered |
item | the item set in the Array |
index | the index to which the item was allocated |
Fires on: unshift, using index accessors to set Array items
Note: Shuffling the Array or using methods like unshift
will fire itemset
for each index change
itemremoved
An item has been removed from the Array. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "itemremoved", denoting the event-type that was triggered |
item | the item removed from the Array |
index | the index at which the item was removed |
Fires on: pop, shift, splice
mutated
The Array value has been reassigned. Callbacks will receive an Object consisting of :
Property | Value |
---|
type | String "mutated", denoting the event-type that was triggered |
item | the new Array value |
index | String "all", denoting all indices will have been affected |
Fires on: Using the value accessor to mutate the Array value
Objects
Example:
const target = {
name: "La Monte Young",
genre: "Minimalism"
};
const music = vivisect(target);
Event Types
itemget
An Object property value has been accessed. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "itemget", denoting the event-type that was triggered |
prop | The name or Symbol of the property being accessed |
target | The target object |
value | The specific value being accessed |
itemset
An Object property value has been set. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "itemset", denoting the event-type that was triggered |
prop | The name or Symbol of the property being set |
target | The target object |
value | The new value that has been set on prop |
itemdeleted
An Object property value has been deleted. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "itemdeleted", denoting the event-type that was triggered |
prop | The name or Symbol of the property being deleted |
target | The stringified target object |
value | A Boolean value indicating deletion success |
Strings
Example:
const hash = vivisect("UmVhZE1vcmVZdWtpb01pc2hpbWEK");
Unique Methods and Props
reassign
Mutates String value, chainable (returns this
).
Example:
const str = vivisect("Hello, world");
str.reassign("Hello, moon").addEventListener(...
console.log(str);
length
Returns String value length; non-configurable.
Event Types
mutated
The String value has been reassigned. Callbacks will receive an Object consisting of:
Property | Value |
---|
type | String "mutated", denoting the event-type that was triggered |
value | the previous String value |
mutant | the reassigned String value |
Ubiquitous Methods and Props
Purity
The vivisect
handler copies by value, not by reference. Observables do not modify the original Objects passed to them upon instantiation.
value
A non-enumerable accessor for getting and/or setting the core value of a given Observable
Example:
const users = vivisect(["Alice", "Bob"]);
console.log(users.value);
users.value = ["Alexei", "Quinn"];
console.log(users.value);
Note: Get/Set on types String
, Array
; Get on types Object
addEventListener
Bind a callback to fire whenever a given event-type has been triggered.
See also: debounce option.
Example:
const logMsg = function (event) {
console.log(`Added ${event.item} at index ${event.index}.`);
});
const users = vivisect(["Alice","Bob"]).addEventListener("itemadded", logMsg);
users.push("Charlie");
removeEventListener
Remove an existing callback from the respective event-type to which it has been registered.
See also: debounce option.
Example:
const logMsg = function (event) {
console.log(`Added ${event.item} at index ${event.index}.`);
});
const users = vivisect(["Alice","Bob"])
.addEventListener("itemadded", logMsg)
.removeEventListener("itemadded", logMsg);
users.push("Charlie");
debounce (option)
Optionally enforce a debounce on a given event-listener; handler calls will be throttled for a duration of n milliseconds.
To vivisect
with a debounce directive, one need only specify a third and optional argument when calling addEventListener
- a Number denoting milliseconds to which the debounce timeout will be set.
To unregister a debounced handler via removeEventListener
, simply pass the handler name as usual.
Example:
const logMsg = function (event) {
console.log(`Added ${event.item} at index ${event.index}.`);
});
const users = vivisect(["Alice","Bob"]).addEventListener("itemadded", logMsg, 2000);
users.push("Charlie");
users.removeEventListener("itemadded", logMsg);
users.push("RMS");