diff --git a/package.json b/package.json index 0ad5e62..e0a762b 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "klaw": "^1.3.1", "lodash": "^4.17.4", "node-exceptions": "^2.0.0", + "require-uncached": "^1.0.3", "upcast": "^1.0.4" } } diff --git a/src/Edge/index.js b/src/Edge/index.js index 2430927..c9f2242 100644 --- a/src/Edge/index.js +++ b/src/Edge/index.js @@ -26,6 +26,9 @@ class Edge { this._tags = {} this._globals = require('../Globals') this._loader = new Loader() + this._options = { + cache: false + } this._boot() } @@ -54,7 +57,9 @@ class Edge { * @private */ _getTemplate () { - return new Template(this._tags, this._globals, this._loader) + return new Template(this._tags, { + cache: this._options.cache + }, this._globals, this._loader) } /** @@ -100,6 +105,19 @@ class Edge { tag.run(Context) } + /** + * Configure edge by passing object of options. + * + * @method configure + * + * @param {Object} options + * + * @return {void} + */ + configure (options) { + this._options = _.merge(this._options, options) + } + /** * Register a new global. * diff --git a/src/Loader/index.js b/src/Loader/index.js index d6a7f79..2c69521 100644 --- a/src/Loader/index.js +++ b/src/Loader/index.js @@ -11,6 +11,7 @@ const fs = require('fs') const path = require('path') +const requireUncached = require('require-uncached') const CE = require('../Exceptions') /** @@ -147,7 +148,7 @@ class Loader { * * @return {String} */ - loadPresenter (presenter) { + loadPresenter (presenter, clearCache = false) { /** * Presenters path has not been registered and trying * to load a presenter. @@ -157,7 +158,8 @@ class Loader { } try { - return require(path.join(this.presentersPath, presenter)) + const presenterPath = path.join(this.presentersPath, presenter) + return clearCache ? requireUncached(presenterPath) : require(presenterPath) } catch (error) { if (error.code === 'MODULE_NOT_FOUND') { throw CE.RuntimeException.missingPresenter(presenter, this.presentersPath) diff --git a/src/Template/index.js b/src/Template/index.js index a59497c..329a015 100644 --- a/src/Template/index.js +++ b/src/Template/index.js @@ -38,12 +38,13 @@ const cache = require('../Cache') * @constructor */ class Template { - constructor (tags, globals = {}, loader = null) { + constructor (tags, options, globals = {}, loader = null) { this._tags = tags this._globals = globals this._loader = loader this._viewName = 'raw string' this._runTimeViews = [] + this._options = options this._locals = {} this._presenter = null @@ -111,7 +112,7 @@ class Template { * @private */ _makeContext (data) { - const Presenter = this._presenter ? this._loader.loadPresenter(this._presenter) : BasePresenter + const Presenter = this._presenter ? this._loader.loadPresenter(this._presenter, !this._options.cache) : BasePresenter const presenter = new Presenter(data, this._locals) /** * We should always make the context with the original view @@ -126,6 +127,8 @@ class Template { * @method _addRunTimeView * * @param {String} view + * + * @private */ _addRunTimeView (view) { this._runTimeViews.push(view) @@ -138,11 +141,52 @@ class Template { * @method _removeRunTimeView * * @return {void} + * + * @private */ _removeRunTimeView () { this._runTimeViews.pop() } + /** + * Return the view from cache if cachining is + * turned on. + * + * @method _getFromCache + * + * @param {String} view + * + * @return {String|Null} + * + * @private + */ + _getFromCache (view) { + if (!this._options.cache) { + return null + } + return cache.get(view) + } + + /** + * Save view to cache when caching is turned on + * + * @method _saveToCache + * + * @param {String} view + * @param {String} output + * + * @return {void} + * + * @private + */ + _saveToCache (view, output) { + if (!this._options.cache) { + return + } + cache.add(view, output) + debug('adding view %s to cache', view) + } + /** * Compile a view by loading it from the disk and * cache the view when caching is set to true. @@ -155,7 +199,7 @@ class Template { * @return {String} */ _compileView (view, asFunction = true) { - const preCompiledView = cache.get(view) + const preCompiledView = this._getFromCache(view) /** * Return the precompiled view from the cache if @@ -170,13 +214,7 @@ class Template { try { const compiledView = compiler.compile(view) - - /** - * Adding view to cache - */ - cache.add(view, compiledView) - debug('adding view %s to cache', view) - + this._saveToCache(view, compiledView) return compiledView } catch (error) { throw this._prepareStack(view, error) @@ -378,7 +416,7 @@ class Template { return result }, {}) - const template = new Template(this._tags, this._globals, this._loader) + const template = new Template(this._tags, this._options, this._globals, this._loader) template.presenter(presenter) template._makeContext(data) return template diff --git a/test/unit/tags/component.spec.js b/test/unit/tags/component.spec.js index 1e3af01..61cb620 100644 --- a/test/unit/tags/component.spec.js +++ b/test/unit/tags/component.spec.js @@ -25,7 +25,7 @@ test.group('Tags | Component ', (group) => { }) test('parse a simple component without any slots', (assert) => { - const template = new Template(this.tags, {}, loader) + const template = new Template(this.tags, {}, {}, loader) const statement = dedent` @component('components.alert')