Skip to content

Commit

Permalink
docs: improve towards organic concept v1.0.0
Browse files Browse the repository at this point in the history
+ removed reactions definitions - es6 and beyond render them absolete
+ consolidate guidelines/best practices into docs per topic
+ shrink Plasma's interface definition
+ add Plasma's interface detailed explanation about feedback support and hints towards its implementations
  • Loading branch information
outbounder committed Jan 12, 2016
1 parent 283e78e commit 7f26a4c
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 274 deletions.
133 changes: 128 additions & 5 deletions README.md
@@ -1,12 +1,135 @@
[node-organic](http://node-organic.com)
============
# [node-organic](http://node-organic.com)

# Organic v1.0.0

[Organic Computing](en.wikipedia.org/wiki/Organic_computing) inspired implementation based on nodejs.

This document represents a draft outline of the fundamental principles, understandings and concepts in engineering `node-organic` as package library named `organic` published in http://npmjs.org.

The library represents abstract form of the implementation bundled with concept documentation.
Further [modules/libraries/packages](http://node-organic.com/#/modules) inheriting `organic` core classes provide actual implementation and the ability to extend, improve and adapt furthermore the concept and its outcome.

## [Chemical](./Chemical.md)

Chemical **is raw data structure**.

Every chemical has a type and in its nature is a plain object filled with properties (primitive values and/or references to other objects).

One chemical has this generalized structure

{
type: String,
// ... other custom properties
}

## [DNA](./DNA.md)

DNA is **configuration**.

It is the collected internal knowledge of the entire cell application - its relations, abilities, build phases, functionalities and modes. DNA information can be acquired from various sources and can be transmited across various mediums if needed because it is a Chemical (raw data structure)

var dnaStructure = {
"OrganelleName": {
"source": "path/to/organelle_implementation"
},
"branchName": {
"OrganelleName2": "path/to/implementation"
}
}

var dna = new DNA(dnaStructure)
console.log(dna.OrganelleName.source) // "path/to/organelle_implementation"

## [Plasma](./Plasma.md)

Plasma is **EventBus/EventDispatcher/PubSub pattern**.

It is the fluid/environment which contains different kinds and copies of Organelles and/or Chemicals. The plasma also has main purpose in transmitting Chemicals between Organelles and within the Cell itself.

var plasma = new Plasma()
plasma.on(chemicalPattern, chemicalReactionFn)
plasma.emit(chemical)

Implementations:

* [organic-plasma](https://github.com/outbounder/organic-plasma)

## [Organelles](./Organel.md)

Organelle is **Controller/Command/Strategy pattern**.

These are the building blocks of organic application. Organelles are simple class implementations having the following form:

var Organelle = function(plasma, dna) {
this.plasma = plasma
plasma.on(dna.reactOn, self.reactionToChemical)
}

Organelle.prototype.reactionToChemical = function(c) {
// -- reaction logic
}

## [Nucleus](./Nucleus.md)

Nucles is **DependencyInjector/Factory pattern**.

Nucleus is an `Organelle`. It however has reactions vital for a 'living' Cells - ability to process DNA and execute reactions involved in constructing Organelles.

var nucleus = new Nucleus(plasma, dna)

// add ability to construct organelles on demand via "build" typed chemical.
plasma.on({type: "build"}, function(c){ nucleus.build(c) })

// build some organelles from dna
plasma.emit({type: "build", branch: dna.organelles})

## [Cell](./docs/Cell.md)

Cell is **Application**.

It is usually a single constructor logic which brings up Plasma and Nucleus. The Cell also can provide support to "build" organelles using `build` chemicals.

// dna/organelles.json
{
"plasma": {
"organelle": {
"source": "path/relative/to/cwd"
}
}
}

// cell.js
var Cell = function Cell(dna){
this.plasma = new Plasma()
var nucleus = new Nucleus(this.plasma, dna)
this.plasma.on("build", nucleus.build, nucleus)
}

// main.js
var loadDNA = require('organic-dna-loader')
loadDNA(function(err, dna){

// instantiate
var instance = new Cell(dna)

// trigger building
instance.plasma.emit({type: "build", branch: "organelles.plasma"})
})


Cells can be in different kinds - command line, web services, desktop apps.
Cells themselfs can form up and organize into a Systems.
Different kinds of systems can build up even more complex structures interconnecting with each other like Organisms...

-----
Note that the proposed concept and its respective implementations **doesn't simulate the actual nature order and processes**.
The concept follows closely nature's patterns where applicable to software development discipline.


Organic development in node.js

* [documentation](https://github.com/VarnaLab/node-organic/blob/master/docs)
* [organic-presentation-101](http://outbounder.github.io/organic-presentation-101/#/)
* [organic development (an article at net.tutsplus.com)](http://net.tutsplus.com/tutorials/javascript-ajax/organic-development/)
* [simple app which uses Organic](https://github.com/tutsplus/organic-development)
* [organic ecosystem](http://wisdom.camplight.net/wisdom/51194d8ca672da1148000007/ecosystem)

* [trello board](https://trello.com/board/node-organic/50659ffd3a3664af033e2024)
* [trello board](https://trello.com/board/node-organic/50659ffd3a3664af033e2024)
22 changes: 22 additions & 0 deletions docs/Cell.md
@@ -0,0 +1,22 @@
# Cell

## Cell abstract

var Cell = function Cell(){
this.plasma = new Plasma()
}

module.exports.prototype.build = function(dna){
var nucleus = new Nucleus(this.plasma, dna)
this.plasma.on("build", nucleus.build, nucleus)
this.plasma.emit({type: "build", branch: "organelles"})
}

module.exports.prototype.kill = function(){
this.plasma.emit({type: "kill"})
}

## Best practices

* Do not store reference of DNA object within the cell because access to DNA should be provided only to trusted instances like Nucleus based implementations.
* Provide `build` and `kill` methods with their respective implementations so that a cell instance can be managed and tested.
12 changes: 3 additions & 9 deletions docs/Chemical.md
@@ -1,15 +1,9 @@
# Chemical

One chemical has this generalized structure
One chemical is just an Object structure:

{
type: String,
// ...
reference: Object,
// ...
property: Value
// ...
function: Function(also an Object or Class)
// ... properties
}

## abstract Chemical
Expand All @@ -22,4 +16,4 @@ Every property of data object if present will be copied over the Chemical object
property: "value"
})

console.log(c.property) // "value"
console.log(c.property) // "value"
6 changes: 3 additions & 3 deletions docs/DNA.md
Expand Up @@ -10,14 +10,14 @@ It is the collected internal knowledge of the entire cell application - its rela
"OrganelleName2": "path/to/implementation"
}
}

var dna = new DNA(dnaStructure)
console.log(dna.OrganelleName.source) // "path/to/organelle_implementation"

## abstract DNA

### construction function DNA(data)

Should implement [Chemical's constructor function logic](./Chemical.md) at least.
Should implement [Chemical's constructor function logic](./Chemical.md).

> Every property of data object if present will be copied over the DNA object.
> Every property of data object if present will be copied over the DNA object.
14 changes: 4 additions & 10 deletions docs/Nucleus.md
@@ -1,6 +1,6 @@
# Nucleus

Nucleus is an Organelle. It however has reactions vital for a living Cell - ability to read DNA and execute reactions involved in constructing Organelles.
Nucleus is an Organelle. It however has reactions vital for a 'living' Cell - ability to read DNA and construct Organelles.

// construct Nucleus giving its own dna branch for configuration.
var plasma = new Plasma()
Expand All @@ -12,14 +12,9 @@ Nucleus is an Organelle. It however has reactions vital for a living Cell - abil
"OrganelleName2": "path/to/implementation"
}
})

var nucleus = new Nucleus(plasma, dna)

// add ability to construct organelles on demand via "build" typed chemical.
plasma.on("build", nucleus.build, nucleus)

// build some organelles from dna
plasma.emit({type: "build", branch: "organelles"})
var nucleus = new Nucleus(plasma, dna)
nucleus.build({type: "build", branch: "organelles"})

## abstract Nucleus

Expand All @@ -32,9 +27,8 @@ Should implement construction and build logic for Nucleus Organelle.
* `plasma` is expected to implement [Plasma](./Plasma.md)
* `dna` is expected to implement [DNA](./DNA.md)

### function build(chemical [, callback])
### function build(chemical)

Should implement logic for building Organelles using combined information from `chemical` argument and provided `dna` structure upon construction.

* `chemical` is expected to implement [Chemical](./Chemical.md)
* `callback` is expected to implement [ReactionFn callback form](./Reactions.md#reactionfn-callback)
12 changes: 7 additions & 5 deletions docs/Organel.md
Expand Up @@ -9,7 +9,7 @@ These are the building blocks of organic application, they in general are clonab

Organelle.prototype.reactionToChemical = function(c, next) {
// -- reaction logic
// -- submits new chemical in plasma via this.plasma.emit(...)
// -- submits new chemical in plasma via this.plasma.emit(...)
// -- calls next()
}

Expand All @@ -22,9 +22,11 @@ Should implement construction and building logic of Organelle.
* `plasma` is expected to implement [Plasma](./Plasma.md)
* `dna` is expected to implement [DNA](./DNA.md)

### function dispose(chemical, callback)

A [Reaction](./Reactions.md#reactionfn) function. Should implement if required destruction and disposal logic of Organelle instance.
## Best practices

* `chemical` is expected to implement [Chemical](./Chemical.md)
* `callback` is expected to implement [reactionFn callback form](./Reactions.md#reactionfn-callback) form of `function(err, result)`
* attach organelle's reaction functions to its prototype, this way inheriting of organelles and overriding reactions can be achieved.
* store references to plasma and dna so that reaction functions can use them accordingly when needed.
* dispose resources acquired during the lifetime of the Organelle
* unregister any previously registered reactions during dispose process
* do not hard code chemical patterns and their relation to reactions. Instead use the information provided by the dna structure to build the mappings.
81 changes: 63 additions & 18 deletions docs/Plasma.md
@@ -1,43 +1,88 @@
# Plasma

This is a Class(OOP) implementation with support of decorations/extensions/plugins. The plasma also has main purpose in transmitting Chemicals between Organelles and within the Cell itself.
The plasma has main purpose in transmitting Chemicals between Organelles and within the Cell itself.

var plasma = new Plasma()
plasma.on("ChemicalName", reactionFn)
plasma.off("ChemicalName", reactionFn)
plasma.once("ChemicalName", reactionFn)

// ... any kind of plasma interaction can be achieved via applied on instance level decorations
plasma.onAll("ChemicalName1", "ChemicalName2", reactionFn)
plasma.on(chemicalPattern, reactionFn)
plasma.off(chemicalPattern, reactionFn)
plasma.once(chemicalPattern, reactionFn)
plasma.emit(chemical)

## abstract Plasma

### constructor function Plasma()

Should implement construction and building logic of Plasma instance.

### function on(chemicalPattern, reactionFn [, context])
### function on(chemicalPattern, reactionFn)

Should implement logic for registering reaction functions capable to handle chemicals by given pattern.

* `chemicalPattern` is a value used to link emitted chemicals to their respective reaction functions. Current implementations assume chemicalPatterns as of having String, Object and/or Prototype values.
* `reactionFn` is expected to have the form of [Reaction function](./Reacitons.md#reactionfn)
* `context` argument is optional and is indicator that the `reactionFn` should be invoked with other than its own context.
* `chemicalPattern` - pattern for matching chemical(s)
* `reactionFn` - reaction function upon matched chemical(s)

### function off(chemicalPattern, reactionFn)

Should implement logic for unregistering reaction functions previously registered with respective chemicalPattern.

* `chemicalPattern` is expected to have the same value when `reactionFn` has been registered.
* `reactionFn` is expected to be the same `reactionFn` which has been previously registered.

### function once(chemicalPattern, reactionFn [, context])
### function once(chemicalPattern, reactionFn)

Should implement the same logic as `function on(...)` with the important difference that `reactionFn` function should be invoked only once and then unregistered.

### function emit(chemical [, callback])
### function emit(chemical)

Should implement logic for trasmitting and delivering chemicals to registered reaction functions based on their respective patterns.
Should implement logic for trasmitting and delivering chemical(s) to registered reaction functions matched by their respective patterns.

* `chemical` is expected to implement [Chemical](./Chemical.md).
* `callback` is optional and is expected to implement [reactionFn's callback form](./Reactions.md#reactionfn-callback).

#### action <-> feedback

Nature's pattern for feedback and results delivery for organelles is based on emitting back a different chemical eg (over-simplified):

```
// worker organelle
plasma.on(doWorkPattern, function (doWorkChemical) {
// do work with chemical
plasma.emit(doWorkResultsChemical)
})
// cell
// register worker organelle results feedback
plasma.on(doWorkResultsChemical, function (resultsChemical) {
})
// engage action on worker organelle
plasma.emit(doWorkChemical)
```

However with increase in algorithmic complexity of implementations such can be shortened to be developer-friendly to its abstract form in code implementations:

##### via callbacks

```
// worker organelle
plasma.on(doWorkPattern, function (doWorkChemical, doneCallback) {
// do work with chemical
doneCallback(null, doWorkResults)
})
// cell
// engage action on worker organelle
plasma.emit(doWorkChemical, function (err, results) {
})
```

##### via promises

```
// worker organelle
plasma.on(doWorkPattern, function (doWorkChemical) {
// do work with chemical
return doWorkResultsPromise
})
// cell
// engage action on worker organelle
var doWorkResultsPromise = plasma.emit(doWorkChemical)
```

0 comments on commit 7f26a4c

Please sign in to comment.