├── .eslintrc.json
├── .gitignore
├── .travis.yml
├── CNAME
├── CONTRIBUTING.md
├── GENESIS.md
├── LICENSE
├── README.md
├── VIRUS.md
├── cell.js
├── examples
└── virtual_dom.js
├── index.html
├── package.json
├── phd.config.js
├── test
├── Gene.js
├── Genotype.js
├── God.js
├── Membrane.js
├── Nucleus.js
├── Phenotype.js
├── integration.js
└── spy.js
├── travis
└── test.sh
└── website
├── components
└── mailchimp
│ └── form.html
├── demos
├── bitcoin.js
├── twitter.css
└── twitter.js
└── style.css
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint:recommended",
3 | "parserOptions": {
4 | "ecmaVersion": 5
5 | },
6 | "env": {
7 | "es6": true,
8 | "node": true,
9 | "browser": true
10 | },
11 | "rules": {
12 | "no-await-in-loop": "warn",
13 | "no-compare-neg-zero": "error",
14 | "no-extra-parens": ["warn", "all", {
15 | "nestedBinaryExpressions": false
16 | }],
17 | "no-template-curly-in-string": "error",
18 | "no-unsafe-negation": "error",
19 | "valid-jsdoc": ["error", {
20 | "requireReturn": false,
21 | "requireReturnDescription": false,
22 | "prefer": {
23 | "return": "returns",
24 | "arg": "param"
25 | },
26 | "preferType": {
27 | "String": "string",
28 | "Number": "number",
29 | "Boolean": "boolean",
30 | "Symbol": "symbol",
31 | "object": "Object",
32 | "function": "Function",
33 | "array": "Array",
34 | "date": "Date",
35 | "error": "Error",
36 | "null": "void"
37 | }
38 | }],
39 |
40 | "accessor-pairs": "warn",
41 | "array-callback-return": "error",
42 | "complexity": "warn",
43 | "curly": ["error", "multi-line", "consistent"],
44 | "dot-location": ["error", "property"],
45 | "dot-notation": "error",
46 | "eqeqeq": "error",
47 | "no-empty-function": "error",
48 | "no-floating-decimal": "error",
49 | "no-implied-eval": "error",
50 | "no-invalid-this": "error",
51 | "no-lone-blocks": "error",
52 | "no-multi-spaces": "error",
53 | "no-new-func": "error",
54 | "no-new-wrappers": "error",
55 | "no-new": "error",
56 | "no-octal-escape": "error",
57 | "no-return-assign": "error",
58 | "no-return-await": "error",
59 | "no-self-compare": "error",
60 | "no-sequences": "error",
61 | "no-throw-literal": "error",
62 | "no-unmodified-loop-condition": "error",
63 | "no-unused-expressions": "error",
64 | "no-useless-call": "error",
65 | "no-useless-concat": "error",
66 | "no-useless-escape": "error",
67 | "no-useless-return": "error",
68 | "no-void": "error",
69 | "no-warning-comments": "warn",
70 | "prefer-promise-reject-errors": "error",
71 | "require-await": "warn",
72 | "wrap-iife": "error",
73 | "yoda": "error",
74 |
75 | "no-label-var": "error",
76 | "no-undef-init": "error",
77 |
78 | "callback-return": "error",
79 | "handle-callback-err": "error",
80 |
81 | "array-bracket-spacing": "error",
82 | "block-spacing": "error",
83 | "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
84 | "comma-dangle": ["error", "always-multiline"],
85 | "comma-spacing": "error",
86 | "comma-style": "error",
87 | "computed-property-spacing": "error",
88 | "eol-last": "error",
89 | "func-name-matching": "error",
90 | "indent": ["error", 2, { "SwitchCase": 1 }],
91 | "key-spacing": "error",
92 | "keyword-spacing": ["error"],
93 | "max-depth": "error",
94 | "max-nested-callbacks": ["error", { "max": 4 }],
95 | "max-statements-per-line": ["error", { "max": 2 }],
96 | "new-cap": "off",
97 | "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 3 }],
98 | "no-array-constructor": "error",
99 | "no-mixed-operators": "error",
100 | "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
101 | "no-new-object": "error",
102 | "no-spaced-func": "error",
103 | "no-trailing-spaces": "error",
104 | "no-unneeded-ternary": "error",
105 | "no-whitespace-before-property": "error",
106 | "nonblock-statement-body-position": "error",
107 | "object-curly-spacing": ["error", "always"],
108 | "operator-assignment": "error",
109 | "operator-linebreak": ["error", "after"],
110 | "padded-blocks": ["error", "never"],
111 | "quote-props": ["error", "as-needed"],
112 | "quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": false }],
113 | "semi-spacing": "error",
114 | "semi": "error",
115 | "space-before-blocks": "error",
116 | "space-before-function-paren": ["error", "never"],
117 | "space-in-parens": "error",
118 | "space-unary-ops": "error",
119 | "template-tag-spacing": "error",
120 | "unicode-bom": "error"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | **/.DS_Store
4 | coverage
5 | .nyc_output
6 | index.html
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | cache:
5 | directories:
6 | - node_modules
7 | install: npm install
8 | jobs:
9 | include:
10 | - stage: test
11 | script: bash ./travis/test.sh
12 | dist: trusty
13 | sudo: false
14 | after_success: npm run coverage
15 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | www.celljs.org
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributions Welcome
2 |
3 | Feel free to make suggestions and share improvements on the [issues](https://github.com/intercellular/cell/issues/new).
4 |
5 | # Cell Architecture
6 |
7 | For a quick overview of how Cell works internally, please refer to the [Genesis](./GENESIS.md) document, where it explains every module in detail.
8 |
9 | # Tests Required!
10 |
11 | Because Cell creates HTML elements that are completely self-driving, it can be tricky at times to debug when something goes wrong.
12 |
13 | That's why it is necessary to write as many tests as possible, in order to make sure one fix or improvement doesn't result in unexpected trouble elsewhere.
14 |
15 | So when you do make a contribution, please write a test verifing that:
16 |
17 | 1. Your code does what you say it does.
18 | 2. Your code doesn't break any of the existing tests.
19 |
20 | You can check out all the existing tests under the [/test](./test) folder.
21 |
--------------------------------------------------------------------------------
/GENESIS.md:
--------------------------------------------------------------------------------
1 | # Genesis
2 |
3 | ## 1. God
4 |
5 | 1. In the beginning God creates a [Membrane](#2-membrane). Now the cell has a "shell" (an empty html node) that can be filled.
6 | 2. And God builds a [Genotype](#3-genotype). Genotype stores all the data a cell needs to construct itself.
7 | 3. And God builds a [Nucleus](#5-nucleus). Nucleus is the central processing unit of a cell. It handles the cell cycle, synchronization, app execution, and other core functions.
8 | 4. And God builds a [Phenotype](#6-phenotype). Phenotype is the actual manifestation of the cell's genotype as an HTML element.
9 | 5. Finally God's job has finished. From here on, God doesn't get in the way and let each cell take care of its own destiny. Each cell starts its own life cycle based on their membrane, genotype, nucleus, and phenotype.
10 |
11 |
12 |
13 | ## 2. Membrane
14 |
15 | Membrane is the "shell" of a cell. The membrane unit determines whether the cell will be created from scratch or if it will be injected into an existing element on the DOM.
16 |
17 | - `inject()` - Injects a cell into an existing element. You can inject cells into `head`, `body`, or any element with an `id`.
18 | - `create()` - Creates membrane from scratch and appends it to body. In most cases you will just create everything from scratch instead of injecting into an existing DOM.
19 | - `build()` - A wrapper around inject() and create(). Depending on the gene info, it decides whether to inject or create. (Inject in case the `$type` is either `body` or `head`, or if there exists an element on the DOM tree that matches one of the gene ids. Otherwise create and append to body).
20 |
21 |
22 | ## 3. Genotype
23 |
24 | Genotype stores an entire blueprint of a cell. Then, it's used to generate the phenotype (an actual HTML element)
25 |
26 | - `set` - stores a single key/value pair under genotype
27 | - `update` - updates genotype for a single key
28 | - `build` - builds an entire genotype for a node
29 |
30 |
31 |
32 | ## 4. Gene
33 |
34 | Gene is a utility unit that deals with comparing and deduplicating gene data
35 |
36 | - `freeze` - freezes a gene for comparison
37 | - `LCS` - longest common subsequence algorithm
38 | - `diff` - compares two genotypes and comes up with a diff
39 |
40 |
41 |
42 | ## 5. Nucleus
43 |
44 | Nucleus handles the actual cell cycle. Nucleus functions as the interface between the outside world/the programmer and the cell's Genotype and Phenotype.
45 |
46 | - `tick()` - A polyfill method for `requestAnimationFrame`, which is used throughout the cell cycle. Makes sure all the view updates are carried out in a single animation frame.
47 | - `set()` - Instead of directly setting attributes on an element, we use the nucleus structure as a pseudo proxy. This function makes sure that all the attributes defined on the genotype object gets monitored for change, so we can trigger `$update()` whenever there's an update
48 | - `build()` - The root method for building out the nucleus of an element.
49 | - `bind()` - binds the functions so we can run post-processing logic after each function is run, as well as trigger `$update()` when there's an update.
50 | - `queue()` - queues up all the attributes that may have been udpated, so we can check later and make an update all at once when the call stack becomes empty.
51 |
52 |
53 |
54 | ## 6. Phenotype
55 |
56 | A cell's Genotype manifests itself into Phenotype--an actual HTML element.
57 |
58 | - `build()` - builds phenotype for a node from genotype. Internally, callse the `update()` for each gene
59 | - `update()` - updates phenotype for a single gene
60 | - `$type()` - updates the `$type` of a phenotype
61 | - `$components()` - updates the `$components` of a phenotype
62 | - `$init()` - automatically called after `Phenotype.build()`
63 | - `$update()` - automatically called when there's a data update on this cell.
64 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 gliechtenstein
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |