* add components * example: componentize header * fix choo SSR * example: componentize footer * example: fix footer * update component cache asserts * componentize todos * reorder example dir * fix example tests * fix dep check test * Add garbage collection of unused components * Apply args when calling identity * update to new component preview * update nanocomponent * fix cache err name * remove static methods from example * restore app.emit() function * public API tests * offset component cache iteration by 2 * whitelist contents of component folder (#643) * allow lru number arg * fix lint typo
42 lines
1.4 KiB
JavaScript
42 lines
1.4 KiB
JavaScript
var assert = require('assert')
|
|
var LRU = require('nanolru')
|
|
|
|
module.exports = ChooComponentCache
|
|
|
|
function ChooComponentCache (state, emit, lru) {
|
|
assert.ok(this instanceof ChooComponentCache, 'ChooComponentCache should be created with `new`')
|
|
|
|
assert.equal(typeof state, 'object', 'ChooComponentCache: state should be type object')
|
|
assert.equal(typeof emit, 'function', 'ChooComponentCache: emit should be type function')
|
|
|
|
if (typeof lru === 'number') this.cache = new LRU(lru)
|
|
else this.cache = lru || new LRU(100)
|
|
this.state = state
|
|
this.emit = emit
|
|
}
|
|
|
|
// Get & create component instances.
|
|
ChooComponentCache.prototype.render = function (Component, id) {
|
|
assert.equal(typeof Component, 'function', 'ChooComponentCache.render: Component should be type function')
|
|
assert.ok(typeof id === 'string' || typeof id === 'number', 'ChooComponentCache.render: id should be type string or type number')
|
|
|
|
var el = this.cache.get(id)
|
|
if (!el) {
|
|
var args = []
|
|
for (var i = 2, len = arguments.length; i < len; i++) {
|
|
args.push(arguments[i])
|
|
}
|
|
args.unshift(Component, id, this.state, this.emit)
|
|
el = newCall.apply(newCall, args)
|
|
this.cache.set(id, el)
|
|
}
|
|
|
|
return el
|
|
}
|
|
|
|
// Because you can't call `new` and `.apply()` at the same time. This is a mad
|
|
// hack, but hey it works so we gonna go for it. Whoop.
|
|
function newCall (Cls) {
|
|
return new (Cls.bind.apply(Cls, arguments)) // eslint-disable-line
|
|
}
|