vivisector
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -9,2 +9,4 @@ "use strict"; | ||
function ObservableArray(items) { | ||
var _this = this; | ||
var _self = this, | ||
@@ -73,2 +75,23 @@ _handlers = { | ||
}); | ||
Object.defineProperty(_self, "findIndexAllDeep", { | ||
configurable: false, | ||
enumerable: false, | ||
writable: false, | ||
value: function value(_value2) { | ||
var indices = []; | ||
_this.some(function walk(path) { | ||
return function (item, i) { | ||
if (item === _value2) { | ||
indices.push(path.concat(i)); | ||
} | ||
; | ||
return Array.isArray(item) && item.some(walk(path.concat(i))); | ||
}; | ||
}([])); | ||
return indices; | ||
} | ||
}); | ||
defineAddEventListener(_self, _handlers); | ||
@@ -75,0 +98,0 @@ defineRemoveEventListener(_self, _handlers); |
@@ -18,3 +18,3 @@ "use strict"; | ||
function mutateCoreValue(coreObject, coreValue) { | ||
var mutateCoreValue = function mutateCoreValue(coreObject, coreValue) { | ||
var value = coreObject[0].valueOf(); | ||
@@ -27,3 +27,3 @@ coreObject[0] = String(coreValue); | ||
}; | ||
} | ||
}; | ||
@@ -50,4 +50,4 @@ Object.defineProperty(_self, "value", { | ||
writable: false, | ||
value: function value(arg) { | ||
if (!(typeof arg === "string")) { | ||
value: function value(candidate) { | ||
if (!(typeof candidate === "string")) { | ||
throw new Error("Error: Invalid type."); | ||
@@ -58,3 +58,3 @@ } | ||
type: "mutated" | ||
}, mutateCoreValue(_self, arg)), _self, _handlers); | ||
}, mutateCoreValue(_self, candidate)), _self, _handlers); | ||
return _self; | ||
@@ -61,0 +61,0 @@ } |
"use strict"; | ||
var debounce = function debounce(fn, ms) { | ||
var timeout; | ||
return function (args) { | ||
clearTimeout(timeout); | ||
timeout = setTimeout(function () { | ||
return fn(args); | ||
}, ms); | ||
}; | ||
}; | ||
var computeNamedFunction = function computeNamedFunction(fn, name) { | ||
Object.defineProperty(fn, "name", { | ||
value: name, | ||
configurable: true | ||
}); | ||
return fn; | ||
}; | ||
var defineAddEventListener = function defineAddEventListener(context, handlers) { | ||
@@ -8,3 +26,3 @@ Object.defineProperty(context, "addEventListener", { | ||
writable: false, | ||
value: function value(eventName, handler) { | ||
value: function value(eventName, handler, ms) { | ||
eventName = ("" + eventName).toLowerCase(); | ||
@@ -20,2 +38,8 @@ | ||
if (ms) { | ||
var machinedProperty = handler.name; | ||
handler = debounce(handler, ms); | ||
handler = computeNamedFunction(handler, machinedProperty); | ||
} | ||
handlers[eventName].push(handler); | ||
@@ -47,3 +71,3 @@ return context; | ||
while (--handlerSetLen >= 0) { | ||
if (handlerSet[handlerSetLen] === handler) { | ||
if (handlerSet[handlerSetLen] === handler || handlerSet[handlerSetLen].name === handler.name) { | ||
handlerSet.splice(handlerSetLen, 1); | ||
@@ -67,3 +91,5 @@ } | ||
defineRemoveEventListener: defineRemoveEventListener, | ||
raiseEvent: raiseEvent | ||
raiseEvent: raiseEvent, | ||
debounce: debounce, | ||
computeNamedFunction: computeNamedFunction | ||
}; |
{ | ||
"name": "vivisector", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "node.js library for creating observable datatypes", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
300
README.md
@@ -58,98 +58,177 @@ ![Vivisector Logo](https://github.com/MatthewZito/vivisector-js/blob/master/documentation/vx.png) | ||
## <a name="docs"></a> Documentation | ||
- [Types](#types) | ||
- [Arrays](#arr) | ||
- [Objects](#obj) | ||
- [Strings](#str) | ||
- [Ubiquitous Properties](#all) | ||
### Vivisector Types | ||
#### ObservableArray (*extends Array*) | ||
### <a name="types"></a> Vivisector Types | ||
<hr> | ||
#### <a name="arr"></a> <u>ObservableArray (*extends Array*)</u> | ||
*an Array-like Object* | ||
**Unique Methods and Props** | ||
- **findIndexAll** Returns an Array of all indices that contain a match to given argument. | ||
**Example:** | ||
``` | ||
const albums = Vx("Array", ["Tago Mago", "Monster Movie", "Ege Bamyasi"]); | ||
``` | ||
``` | ||
const users = Vx("Array", ["hello", "world", "world", "hello", "world"]); | ||
console.log(users.findIndexAll("hello")); | ||
// [0, 3] | ||
``` | ||
#### Unique Methods and Props | ||
**Event Types** | ||
- **itemadded** A new item has been added to the Array. Callbacks will receive an Object consisting of | ||
- **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 | ||
#### findIndexAll | ||
Returns an Array of all indices that contain a match to given argument. Does not evaluate nested items. | ||
**Fires on:** *push, unshift, splice* | ||
**Example:** | ||
``` | ||
const users = Vx("Array", ["hello", "world", "world", "hello", "world"]); | ||
console.log(users.findIndexAll("hello")); | ||
// [0, 3] | ||
``` | ||
- **itemset** An item in the Array has moved. Callbacks will receive an Object consisting of | ||
- **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 | ||
#### findIndexAllDeep | ||
Returns an Array of all indices that contain a match to given argument. Walks entire Array tree and evaluates nested items. | ||
**Fires on:** *unshift, using index accessors to set Array items* | ||
**Example:** | ||
``` | ||
const users = Vx("Array", ["hello",["hello"], "world", ["world", "hello"], ["world", ["world",["hello"]]]]); | ||
console.log(users.findIndexAllDeep("hello")); | ||
// [ [ 0 ], [ 1, 0 ], [ 3, 1 ], [ 4, 1, 1, 0 ] ] | ||
``` | ||
**Note:** Shuffling the Array or using methods like `unshift` will fire `itemset` for *each* index change | ||
#### Event Types | ||
- **itemremoved** An item has been removed from the Array. Callbacks will receive an Object consisting of | ||
- **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 | ||
#### 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* | ||
**Fires on:** *pop, shift, 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* | ||
<br> | ||
**Note:** Shuffling the Array or using methods like `unshift` will fire `itemset` for *each* index change | ||
- **mutated** The Array value has been reassigned. Callbacks will receive an Object consisting of | ||
- **type** String "mutated", denoting the event-type that was triggered | ||
- **item** the new Array value, | ||
- **index** "all", String - all indices will have been affected | ||
#### 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* | ||
**Fires on:** *Using the value accessor to mutate the Array value* | ||
#### 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* | ||
<hr> | ||
#### ObservableString (*extends String*) | ||
#### <a name="obj"></a> <u>ObservableObject (*extends Proxy*)</u> | ||
*an extended Object Proxy* | ||
**Example:** | ||
``` | ||
const target = { | ||
name: "La Monte Young", | ||
genre: "Minimalism" | ||
}; | ||
const music = Vx("Object", 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 | | ||
<hr> | ||
#### <a name="str"></a> <u>ObservableString (*extends String*)</u> | ||
*a mutable, String-like Object* | ||
**Unique Methods and Props** | ||
- **reassign** Mutates String value, chainable (returns `this`). | ||
**Example:** | ||
``` | ||
const hash = Vx("String", "UmVhZE1vcmVZdWtpb01pc2hpbWEK"); | ||
``` | ||
``` | ||
let str = Vx("String", "Hello, world"); | ||
str.reassign("Hello, moon").addEventListener(... | ||
#### Unique Methods and Props | ||
console.log(str); | ||
// Hello, moon | ||
``` | ||
#### reassign | ||
Mutates String value, chainable (returns `this`). | ||
- **length** Returns String value length; non-configurable. | ||
**Example:** | ||
``` | ||
const str = Vx("String", "Hello, world"); | ||
str.reassign("Hello, moon").addEventListener(... | ||
**Event Types** | ||
- **mutated** The String value has been reassigned. Callbacks will receive an Object consisting of | ||
- **type** String "mutated", denoting the event-type that was triggered | ||
- **value** the previous String value, | ||
- **mutant** the reassigned String value | ||
console.log(str); | ||
// Hello, moon | ||
``` | ||
#### ObservableObject (*extends Proxy*) | ||
*an extended Object Proxy* | ||
#### length | ||
Returns String value length; non-configurable. | ||
**Event Types** | ||
- **itemget** An Object property value has been accessed. Callbacks will receive an Object consisting of | ||
- **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 | ||
- **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 | ||
- **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 | ||
#### Event Types | ||
### Vivisector Ubiquitous Methods and Props | ||
- **value** A non-enumerable accessor for getting and/or setting the core value of a given *Observable* | ||
#### 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 | | ||
<hr> | ||
#### <a name="all"></a> <u>Ubiquitous Methods and Props</u> | ||
#### value | ||
A non-enumerable accessor for getting and/or setting the core value of a given *Observable* | ||
**Example:** | ||
``` | ||
const users = Vx("Array", ["Alice", "Bob"]); | ||
console.log(users.value); | ||
// ["Alice", "Bob"] | ||
users.value = ["Alexei", "Quinn"] | ||
users.value = ["Alexei", "Quinn"]; | ||
console.log(users.value); | ||
@@ -159,32 +238,71 @@ // ["Alexei", "Quinn"] | ||
*Get/Set on types `String`, `Array`* | ||
*Get on types `Object`* | ||
**Note**: *Get/Set on types `String`, `Array`*; *Get on types `Object`* | ||
- **identifier** A unique identifier assigned to all *Observables*. Namespace confined to the Nodejs runtime's `global`, or 'module context'. Currently a paused feature. | ||
- **type** The type identifier of a given *Observable*, *e.g. "Array", "Object", "String"* | ||
- **addEventListener** Bind a callback to fire whenever a given event-type has been triggered. | ||
#### identifier | ||
A unique identifier assigned to all *Observables*. Namespace confined to the Nodejs runtime's `global`, or 'module context'. Currently a paused feature. | ||
``` | ||
const logMsg = function(event) { | ||
// every time an item is added to the array, fire this callback | ||
console.log(`Added ${event.item} at index ${event.index}.`); | ||
}); | ||
let users = Vx("Array", ["Alice","Bob"]).addEventListener("itemadded", logMsg); | ||
#### type | ||
The type identifier of a given *Observable*, *e.g. "Array", "Object", "String"* | ||
users.push("Charlie"); | ||
// "Added Charlie at index 2." | ||
``` | ||
#### addEventListener | ||
Bind a callback to fire whenever a given event-type has been triggered. | ||
<br> | ||
See also: [debounce](#debounce) option. | ||
- **removeEventListener** Remove an existing callback from the respective event-type to which it has been registered. | ||
**Example:** | ||
``` | ||
const logMsg = function(event) { | ||
// every time an item is added to the array, fire this callback | ||
console.log(`Added ${event.item} at index ${event.index}.`); | ||
}); | ||
``` | ||
const logMsg = function(event) { | ||
// every time an item is added to the array, fire this callback | ||
console.log(`Added ${event.item} at index ${event.index}.`); | ||
}); | ||
let users = Vx("Array", ["Alice","Bob"]).addEventListener("itemadded", logMsg).removeEventListener("itemadded", logMsg); | ||
const users = Vx("Array", ["Alice","Bob"]).addEventListener("itemadded", logMsg); | ||
users.push("Charlie"); | ||
// "Added Charlie at index 2." | ||
``` | ||
users.push("Charlie"); | ||
// no log - handler was removed ^ | ||
``` | ||
#### removeEventListener | ||
Remove an existing callback from the respective event-type to which it has been registered. | ||
<br> | ||
See also: [debounce](#debounce) option. | ||
**Example:** | ||
``` | ||
const logMsg = function(event) { | ||
console.log(`Added ${event.item} at index ${event.index}.`); | ||
}); | ||
const users = Vx("Array", ["Alice","Bob"]) | ||
.addEventListener("itemadded", logMsg) | ||
.removeEventListener("itemadded", logMsg); | ||
users.push("Charlie"); | ||
// no log - handler was removed ^ | ||
``` | ||
#### <a name="debounce"></a> debounce (option) | ||
Optionally enforce a debounce on a given event-listener; handler calls will be throttled for a duration of *n* milliseconds. | ||
To provide the Vx constructor 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 = Vx("Array", ["Alice","Bob"]).addEventListener("itemadded", logMsg, 2000); | ||
users.push("Charlie"); | ||
// two seconds later..."Added Charlie at index 2." | ||
// Vx will find and remove the debounced `logMsg`; no debounce directive needed here | ||
users.removeEventListener("itemadded", logMsg); | ||
users.push("RMS"); | ||
// no log - debounced handler was removed ^ | ||
``` | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36601
560
307