├── .gitignore ├── .travis.yml ├── LICENSE ├── index.js ├── lib └── cache.js ├── package-lock.json ├── package.json ├── readme.md └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | .npmignore 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | node_js: 2 | - "4" 3 | - "5" 4 | - "6" 5 | - "7" 6 | sudo: false 7 | language: node_js 8 | script: "npm run test" 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jon Gacnik 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 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var x = require('xtend') 2 | var assert = require('nanoassert') 3 | 4 | var components = {} 5 | var _cache = null 6 | 7 | module.exports = box 8 | 9 | function box (name, key) { 10 | assert.ok(typeof name === 'string' || typeof name === 'number', 'component-box: name should be type string or number') 11 | assert.ok(components[name], 'component-box: no component handler found for [' + name + ']') 12 | 13 | if (!_cache) _cache = require('./lib/cache')() 14 | 15 | if (key && _cache.get(name + '-' + key)) { 16 | return _cache.get(name + '-' + key) 17 | } else if (key) { 18 | var value = components[name]() 19 | _cache.set(name + '-' + key, value) 20 | return value 21 | } else if (key === false) { 22 | return components[name]() 23 | } else if (name && _cache.get(name)) { 24 | return _cache.get(name) 25 | } else { 26 | var value = components[name]() 27 | _cache.set(name, value) 28 | return value 29 | } 30 | } 31 | 32 | box.use = function (newcomponents) { 33 | assert.equal(typeof newcomponents, 'object', 'component-box.use: components should be type object') 34 | Object.keys(newcomponents).forEach(function (key) { 35 | assert.equal(typeof newcomponents[key], 'function', 'component-box.use: component handler should be type function for [' + key + ']') 36 | }) 37 | 38 | components = x(components, newcomponents) 39 | } 40 | 41 | box.cache = function(cache) { 42 | assert.equal(typeof cache.get, 'function', 'component-box.cache: cache should have get property of type function') 43 | assert.equal(typeof cache.set, 'function', 'component-box.cache: cache should have set property of type function') 44 | assert.equal(typeof cache.remove, 'function', 'component-box.cache: cache should have remove property of type function') 45 | _cache = cache 46 | } 47 | 48 | box.delete = function (key) { 49 | assert.ok(typeof key === 'string' || typeof key === 'number', 'component-box.delete: key should be type string or number') 50 | assert.ok(_cache, 'component-box.delete: cache has not been set or initialized') 51 | 52 | _cache.remove(key) 53 | } 54 | 55 | box._inspect = function () { 56 | return x({}, { 57 | _cache: _cache, 58 | components: components 59 | }) 60 | } 61 | -------------------------------------------------------------------------------- /lib/cache.js: -------------------------------------------------------------------------------- 1 | module.exports = Cache 2 | 3 | function Cache() { 4 | if (!(this instanceof Cache)) return new Cache() 5 | this._cache = {} 6 | } 7 | 8 | Cache.prototype.get = function (key) { 9 | return this._cache[key] 10 | } 11 | 12 | Cache.prototype.set = function (key, value) { 13 | this._cache[key] = value 14 | } 15 | 16 | Cache.prototype.remove = function (key) { 17 | delete this._cache[key] 18 | } 19 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component-box", 3 | "version": "0.2.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "balanced-match": { 8 | "version": "1.0.0", 9 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 10 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 11 | "dev": true 12 | }, 13 | "brace-expansion": { 14 | "version": "1.1.8", 15 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 16 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 17 | "dev": true, 18 | "requires": { 19 | "balanced-match": "1.0.0", 20 | "concat-map": "0.0.1" 21 | } 22 | }, 23 | "concat-map": { 24 | "version": "0.0.1", 25 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 26 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 27 | "dev": true 28 | }, 29 | "deep-equal": { 30 | "version": "1.0.1", 31 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", 32 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", 33 | "dev": true 34 | }, 35 | "define-properties": { 36 | "version": "1.1.2", 37 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", 38 | "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", 39 | "dev": true, 40 | "requires": { 41 | "foreach": "2.0.5", 42 | "object-keys": "1.0.11" 43 | } 44 | }, 45 | "defined": { 46 | "version": "1.0.0", 47 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", 48 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", 49 | "dev": true 50 | }, 51 | "es-abstract": { 52 | "version": "1.8.2", 53 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.8.2.tgz", 54 | "integrity": "sha512-dvhwFL3yjQxNNsOWx6exMlaDrRHCRGMQlnx5lsXDCZ/J7G/frgIIl94zhZSp/galVAYp7VzPi1OrAHta89/yGQ==", 55 | "dev": true, 56 | "requires": { 57 | "es-to-primitive": "1.1.1", 58 | "function-bind": "1.1.1", 59 | "has": "1.0.1", 60 | "is-callable": "1.1.3", 61 | "is-regex": "1.0.4" 62 | } 63 | }, 64 | "es-to-primitive": { 65 | "version": "1.1.1", 66 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", 67 | "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", 68 | "dev": true, 69 | "requires": { 70 | "is-callable": "1.1.3", 71 | "is-date-object": "1.0.1", 72 | "is-symbol": "1.0.1" 73 | } 74 | }, 75 | "for-each": { 76 | "version": "0.3.2", 77 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", 78 | "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", 79 | "dev": true, 80 | "requires": { 81 | "is-function": "1.0.1" 82 | } 83 | }, 84 | "foreach": { 85 | "version": "2.0.5", 86 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 87 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", 88 | "dev": true 89 | }, 90 | "fs.realpath": { 91 | "version": "1.0.0", 92 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 93 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 94 | "dev": true 95 | }, 96 | "function-bind": { 97 | "version": "1.1.1", 98 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 99 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 100 | "dev": true 101 | }, 102 | "glob": { 103 | "version": "7.1.2", 104 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 105 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 106 | "dev": true, 107 | "requires": { 108 | "fs.realpath": "1.0.0", 109 | "inflight": "1.0.6", 110 | "inherits": "2.0.3", 111 | "minimatch": "3.0.4", 112 | "once": "1.4.0", 113 | "path-is-absolute": "1.0.1" 114 | } 115 | }, 116 | "has": { 117 | "version": "1.0.1", 118 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", 119 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", 120 | "dev": true, 121 | "requires": { 122 | "function-bind": "1.1.1" 123 | } 124 | }, 125 | "inflight": { 126 | "version": "1.0.6", 127 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 128 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 129 | "dev": true, 130 | "requires": { 131 | "once": "1.4.0", 132 | "wrappy": "1.0.2" 133 | } 134 | }, 135 | "inherits": { 136 | "version": "2.0.3", 137 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 138 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 139 | "dev": true 140 | }, 141 | "is-callable": { 142 | "version": "1.1.3", 143 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", 144 | "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", 145 | "dev": true 146 | }, 147 | "is-date-object": { 148 | "version": "1.0.1", 149 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 150 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", 151 | "dev": true 152 | }, 153 | "is-function": { 154 | "version": "1.0.1", 155 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", 156 | "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", 157 | "dev": true 158 | }, 159 | "is-regex": { 160 | "version": "1.0.4", 161 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 162 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 163 | "dev": true, 164 | "requires": { 165 | "has": "1.0.1" 166 | } 167 | }, 168 | "is-symbol": { 169 | "version": "1.0.1", 170 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", 171 | "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", 172 | "dev": true 173 | }, 174 | "minimatch": { 175 | "version": "3.0.4", 176 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 177 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 178 | "dev": true, 179 | "requires": { 180 | "brace-expansion": "1.1.8" 181 | } 182 | }, 183 | "minimist": { 184 | "version": "1.2.0", 185 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 186 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", 187 | "dev": true 188 | }, 189 | "nanoassert": { 190 | "version": "1.1.0", 191 | "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", 192 | "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40=" 193 | }, 194 | "object-inspect": { 195 | "version": "1.3.0", 196 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", 197 | "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==", 198 | "dev": true 199 | }, 200 | "object-keys": { 201 | "version": "1.0.11", 202 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", 203 | "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", 204 | "dev": true 205 | }, 206 | "once": { 207 | "version": "1.4.0", 208 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 209 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 210 | "dev": true, 211 | "requires": { 212 | "wrappy": "1.0.2" 213 | } 214 | }, 215 | "path-is-absolute": { 216 | "version": "1.0.1", 217 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 218 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 219 | "dev": true 220 | }, 221 | "path-parse": { 222 | "version": "1.0.5", 223 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 224 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 225 | "dev": true 226 | }, 227 | "resolve": { 228 | "version": "1.4.0", 229 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 230 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 231 | "dev": true, 232 | "requires": { 233 | "path-parse": "1.0.5" 234 | } 235 | }, 236 | "resumer": { 237 | "version": "0.0.0", 238 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", 239 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", 240 | "dev": true, 241 | "requires": { 242 | "through": "2.3.8" 243 | } 244 | }, 245 | "string.prototype.trim": { 246 | "version": "1.1.2", 247 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", 248 | "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", 249 | "dev": true, 250 | "requires": { 251 | "define-properties": "1.1.2", 252 | "es-abstract": "1.8.2", 253 | "function-bind": "1.1.1" 254 | } 255 | }, 256 | "tape": { 257 | "version": "4.8.0", 258 | "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", 259 | "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", 260 | "dev": true, 261 | "requires": { 262 | "deep-equal": "1.0.1", 263 | "defined": "1.0.0", 264 | "for-each": "0.3.2", 265 | "function-bind": "1.1.1", 266 | "glob": "7.1.2", 267 | "has": "1.0.1", 268 | "inherits": "2.0.3", 269 | "minimist": "1.2.0", 270 | "object-inspect": "1.3.0", 271 | "resolve": "1.4.0", 272 | "resumer": "0.0.0", 273 | "string.prototype.trim": "1.1.2", 274 | "through": "2.3.8" 275 | } 276 | }, 277 | "through": { 278 | "version": "2.3.8", 279 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 280 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 281 | "dev": true 282 | }, 283 | "wrappy": { 284 | "version": "1.0.2", 285 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 286 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 287 | "dev": true 288 | }, 289 | "xtend": { 290 | "version": "4.0.1", 291 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 292 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 293 | } 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component-box", 3 | "version": "0.2.0", 4 | "description": "A little component cacher", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js" 8 | }, 9 | "keywords": [ 10 | "component" 11 | ], 12 | "author": "Jon Gacnik (http://jongacnik.com)", 13 | "license": "MIT", 14 | "dependencies": { 15 | "nanoassert": "^1.1.0", 16 | "xtend": "^4.0.1" 17 | }, 18 | "devDependencies": { 19 | "tape": "^4.8.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

component-box 📦

2 | 3 |
4 | 5 | Stability 6 | 7 | 8 | NPM version 9 | 10 | 11 | Build Status 13 | 14 |
15 | 16 |
17 | 18 | A little component cacher for things like [nanocomponent](https://github.com/choojs/nanocomponent) 19 | 20 | ## Usage 21 | 22 | ```js 23 | var Nanocomponent = require('nanocomponent') 24 | var html = require('bel') 25 | var c = require('component-box') 26 | 27 | // component 28 | class MyComponent extends Nanocomponent { 29 | createElement (text) { 30 | return html`
${text}
` 31 | } 32 | } 33 | 34 | // function which returns component instance 35 | function createMyComponent () { 36 | return new MyComponent() 37 | } 38 | 39 | c.use({ 40 | mycomponent: createMyComponent 41 | }) 42 | 43 | // return and render new `mycomponent` 44 | c('mycomponent').render() 45 | ``` 46 | 47 | Meanwhile in another file... 48 | 49 | ```js 50 | var c = require('component-box') 51 | 52 | // return and render cached `mycomponent` 53 | c('mycomponent').render() 54 | ``` 55 | 56 | ## API 57 | 58 | ### `component = c(name, key)` 59 | 60 | Return a component. `key` is optional. Works as follows: 61 | 62 | ```js 63 | // return new `mycomponent` and cache as `mycomponent` 64 | c('mycomponent') 65 | 66 | // return cached `mycomponent` 67 | c('mycomponent') 68 | 69 | // return new `mycomponent` and cache as `boop` 70 | c('mycomponent', 'boop') 71 | 72 | // return cached `mycomponent` with key `boop` 73 | c('mycomponent', 'boop') 74 | 75 | // always return new `mycomponent` (never cache) 76 | c('mycomponent', false) 77 | ``` 78 | 79 | ### `c.use([components])` 80 | 81 | Add components to the store. Object values expect Functions which return a component. 82 | 83 | ```js 84 | var c = require('component-box') 85 | 86 | c.use({ 87 | beep: beepComponent, 88 | boop: boopComponent 89 | }) 90 | 91 | c('beep').render() 92 | c('boop').render() 93 | ``` 94 | 95 | These are shared throughout your app, so in another file you don't need to re-`.use`: 96 | 97 | ```js 98 | var c = require('component-box') 99 | 100 | c('beep').render() 101 | c('boop').render() 102 | ``` 103 | 104 | ### `c.delete(key)` 105 | 106 | Remove component from the cache 107 | 108 | ```js 109 | // return new `mycomponent` and cache as `mycomponent` 110 | c('mycomponent') 111 | 112 | // remove `mycomponent` from cache 113 | c.delete('mycomponent') 114 | 115 | // return new `mycomponent` and cache as `mycomponent` 116 | c('mycomponent') 117 | ``` 118 | 119 | ### `c.cache(cache)` 120 | 121 | Use a custom cache implementation. Expects an object with `.get`, `.set`, and `.remove` methods. 122 | 123 | ```js 124 | var c = require('component-box') 125 | 126 | c.cache(require('lru')(2)) // only cache 2 instances, using lru eviction 127 | 128 | c.use({ 129 | post: postComponent 130 | }) 131 | 132 | c('post', 'slug1').render() 133 | c('post', 'slug2').render() 134 | c('post', 'slug3').render() // evict 'post-slug1' and return new 'post-slug3' instance 135 | ``` 136 | 137 | ## Alternative Pattern 138 | 139 | You could also choose to only return the `.render` method from nanocomponent, allowing for a slightly more concise syntax: 140 | 141 | ```js 142 | // function which creates component instance and returns render method 143 | function createMyComponent () { 144 | var component = new MyComponent() 145 | return function () { 146 | return component.render(...arguments) 147 | } 148 | } 149 | ``` 150 | 151 | ```js 152 | // directly calls nanocomponent .render 153 | c('mycomponent')() 154 | ``` 155 | 156 | ## Real World 157 | 158 | This module is useful when you are creating components on the fly. References to components are saved for you based on `keys`, that way on app re-renders it will re-use your components so things like `load` and etc are not wonky. 159 | 160 | In this example we are using post slugs as component keys: 161 | 162 | ```js 163 | var html = require('bel') 164 | var c = require('component-box') 165 | 166 | c.use({ 167 | post: require('my-post-component') 168 | }) 169 | 170 | var postsData = [ 171 | { title: 'Beep', slug: 'beep' }, 172 | { title: 'Boop', slug: 'boop' }, 173 | { title: 'Blap', slug: 'blap' } 174 | ] 175 | 176 | function view () { 177 | var posts = postsData.map(function (post) { 178 | return c('post', post.slug).render(post) 179 | }) 180 | 181 | return html`
${posts}
` 182 | } 183 | 184 | ``` 185 | 186 | ## More Examples 187 | 188 | ### [fun-component](https://github.com/tornqvist/fun-component) 189 | 190 | ```js 191 | var component = require('fun-component') 192 | var html = require('bel') 193 | var c = require('component-box') 194 | 195 | // function which returns a component 196 | function mycomponent () { 197 | return component(function (props) { 198 | return html`
Hello!
` 199 | }) 200 | } 201 | 202 | c.use({ 203 | mycomponent: mycomponent 204 | }) 205 | 206 | // return new `mycomponent` 207 | c('mycomponent')() 208 | ``` 209 | 210 | ## See Also 211 | 212 | - [choojs/nanocomponent](https://github.com/choojs/nanocomponent) 213 | - [tornqvist/fun-component](https://github.com/tornqvist/fun-component) 214 | 215 | ## License 216 | 217 | [MIT](https://tldrlegal.com/license/mit-license) 218 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | var c = require('.') 3 | 4 | test('c.use()', function (t) { 5 | c.use({ 6 | component: () => prop => console.log(prop) 7 | }) 8 | 9 | var box = c._inspect() 10 | 11 | t.ok('component' in box.components, '`component` passed into box') 12 | t.end() 13 | }) 14 | 15 | test('c(\'component\')', function (t) { 16 | c('component') 17 | 18 | var box = c._inspect() 19 | 20 | t.ok(box._cache.get('component'), '`component` created and cached as `component`') 21 | t.end() 22 | }) 23 | 24 | test('c(\'component\', \'custom\')', function (t) { 25 | c('component', 'custom') 26 | 27 | var box = c._inspect() 28 | 29 | t.ok(box._cache.get('component-custom'), '`component` created and cached as `custom`') 30 | t.end() 31 | }) 32 | 33 | test('c.delete(\'component\')', function (t) { 34 | c.delete('component') 35 | 36 | var box = c._inspect() 37 | 38 | t.notOk(box._cache.get('component'), '`component` uncached') 39 | t.end() 40 | }) 41 | 42 | test('c(\'component\', false)', function (t) { 43 | c('component', false) 44 | 45 | var box = c._inspect() 46 | 47 | t.notOk(box._cache.get('component'), '`component` created and not cached') 48 | t.end() 49 | }) 50 | --------------------------------------------------------------------------------