Skip to content

Commit

Permalink
refactor: cleanup and upgrade to new project style
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Jul 21, 2019
1 parent 6ec2bd7 commit 6c0c405
Show file tree
Hide file tree
Showing 31 changed files with 432 additions and 354 deletions.
39 changes: 36 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"homepage": "https://github.com/poppinss/edge#readme",
"devDependencies": {
"@adonisjs/mrm-preset": "^2.0.3",
"@poppinss/dev-utils": "^1.0.0",
"@types/node": "^12.6.8",
"commitizen": "^4.0.3",
"cz-conventional-changelog": "^3.0.2",
Expand Down Expand Up @@ -61,9 +62,10 @@
]
},
"dependencies": {
"@poppinss/utils": "^1.0.3",
"debug": "^4.1.1",
"edge-error": "^1.0.2",
"edge-parser": "^2.0.5",
"edge-parser": "^2.0.6",
"he": "^1.2.0",
"import-fresh": "^3.1.0",
"lodash": "^4.17.15",
Expand All @@ -84,5 +86,14 @@
"pre-commit": "doctoc README.md --title='## Table of contents' && git add README.md",
"commit-msg": "node ./node_modules/@adonisjs/mrm-preset/validateCommit/conventional/validate.js"
}
}
},
"directories": {
"example": "examples",
"test": "test"
},
"keywords": [
"template",
"mustache",
"edge"
]
}
49 changes: 49 additions & 0 deletions src/CacheManager/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @module edge
*/

/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { LoaderTemplate } from '../Contracts'

/**
* In memory cache manager to parsed pre-compiled templates
*/
export class CacheManager {
private _cacheStore: Map<string, LoaderTemplate> = new Map()

constructor (private _enabled: boolean) {
}

/**
* Returns the template and the presenter class from the
* cache. If caching is disabled, then it will
* return undefined.
*/
public get (templatePath: string): undefined | LoaderTemplate {
if (!this._enabled) {
return
}

return this._cacheStore.get(templatePath)
}

/**
* Set's the template path and the payload to the cache. If
* cache is disabled, then this function returns in noop.
*/
public set (templatePath: string, payload: LoaderTemplate) {
if (!this._enabled) {
return
}

this._cacheStore.set(templatePath, payload)
}
}
99 changes: 44 additions & 55 deletions src/Compiler/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module main
* @module edge
*/

/*
Expand All @@ -11,13 +11,12 @@
* file that was distributed with this source code.
*/

import { Token } from 'edge-lexer'
import { Parser } from 'edge-parser'
import { Token } from 'edge-lexer/build'
import { LoaderContract, CompilerContract, Tags, LoaderTemplate } from '../Contracts'
import { mergeSections, isBlock } from '../utils'
import * as Debug from 'debug'

const debug = Debug('edge:loader')
import { LoaderContract, Tags, LoaderTemplate } from '../Contracts'
import { mergeSections, isBlock } from '../utils'
import { CacheManager } from '../CacheManager'

/**
* Compiler compiles the template to a function, which can be invoked at a later
Expand All @@ -26,43 +25,17 @@ const debug = Debug('edge:loader')
* Compiler uses [edge-parser](https://npm.im/edge-parser) under the hood and also
* handles the layouts.
*
* When caching is set to `true`, the compiled templates will be cached to improve performance.
* When caching is set to `true`, the compiled templates will be cached in-memory
* to improve performance.
*/
export class Compiler implements CompilerContract {
private cacheStore: Map<string, LoaderTemplate> = new Map()
export class Compiler {
private _cacheManager = new CacheManager(this._cache)

constructor (
private loader: LoaderContract,
private tags: Tags,
private cache: boolean = true,
) {
}

/**
* Returns the template and the presenter class from the
* cache. If caching is disabled, then it will
* return undefined.
*/
private _getFromCache (templatePath: string): undefined | LoaderTemplate {
if (!this.cache) {
return
}

return this.cacheStore.get(templatePath)
}

/**
* Set's the template path and the payload to the cache. If
* cache is disabled, then it will never be set.
*/
private _setInCache (templatePath: string, payload: LoaderTemplate) {
if (!this.cache) {
return
}

debug('adding to cache %s', templatePath)
this.cacheStore.set(templatePath, payload)
}
private _loader: LoaderContract,
private _tags: Tags,
private _cache: boolean = true,
) {}

/**
* Generates an array of lexer tokens from the template string. Further tokens
Expand All @@ -74,9 +47,11 @@ export class Compiler implements CompilerContract {

const firstToken = templateTokens[0]

/**
* The `layout` is inbuilt feature from core, where we merge the layout
* and parent template sections together
*/
if (isBlock(firstToken, 'layout')) {
debug('detected layout %s', firstToken.properties.jsArg)

const layoutTokens = this.generateTokens(firstToken.properties.jsArg.replace(/'/g, ''))
templateTokens = mergeSections(layoutTokens, templateTokens)
}
Expand All @@ -85,24 +60,25 @@ export class Compiler implements CompilerContract {
}

/**
* Converts the template content to an [array of lexer tokens](https://github.com/poppinss/edge-lexer#nodes). If
* Converts the template content to an [array of lexer tokens](https://github.com/edge-js/edge-lexer#nodes). If
* layouts detected, their sections will be merged together.
*
* ```
* compiler.generateTokens('<template-path>')
* ```
*/
public generateTokens (templatePath: string): Token[] {
const parser = new Parser(this.tags, { filename: templatePath })
const { template } = this.loader.resolve(templatePath, false)
const { template } = this._loader.resolve(templatePath, false)

const parser = new Parser(this._tags, { filename: templatePath })
return this._templateContentToTokens(template, parser)
}

/**
* Compiles the template contents to a function string, which can be invoked
* later.
*
* When `inline` is set to true, the compiled output will not have it's own scope and
* When `inline` is set to true, the compiled output **will not have it's own scope** and
* neither an attempt to load the presenter is made. The `inline` is mainly used for partials.
*
* ```js
Expand All @@ -120,41 +96,54 @@ export class Compiler implements CompilerContract {
* ```
*/
public compile (templatePath: string, inline: boolean): LoaderTemplate {
templatePath = this.loader.makePath(templatePath)
const absPath = this._loader.makePath(templatePath)

/**
* If template is in the cache, then return it without
* further processing
*/
const cachedResponse = this._getFromCache(templatePath)
const cachedResponse = this._cacheManager.get(absPath)
if (cachedResponse) {
return cachedResponse
}

/**
* Get a new instance of the parser
* Do not load presenter in inline mode
*/
const loadPresenter = !inline

/**
* Inline templates are not wrapped inside a function
* call. They share the parent template scope
*/
const wrapAsFunction = !inline

/**
* Get a new instance of the parser. We use the `templatePath` as the filename
* instead of the `absPath`, since `templatePath` are relative and readable.
*/
const parser = new Parser(this.tags, { filename: templatePath })
const parser = new Parser(this._tags, { filename: templatePath })

/**
* Resolve the base template from loader
* Resolve the template and Presenter using the given loader
*/
const { template, Presenter } = this.loader.resolve(templatePath, !inline)
const { template, Presenter } = this._loader.resolve(absPath, loadPresenter)

/**
* Convert template to AST. So that we can merge the layout tokens
* Convert template to AST. The AST will have the layout actions merged (if layout)
* is used.
*/
const templateTokens = this._templateContentToTokens(template, parser)

/**
* Finally process the ast
*/
const payload = {
template: parser.processTokens(templateTokens, !inline),
template: parser.processTokens(templateTokens, wrapAsFunction),
Presenter,
}

this._setInCache(templatePath, payload)
this._cacheManager.set(absPath, payload)
return payload
}
}
10 changes: 4 additions & 6 deletions src/Context/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @module main
* @module edge
*/

/*
Expand All @@ -11,10 +11,9 @@
* file that was distributed with this source code.
*/

import { Macroable } from 'macroable'
import * as he from 'he'
import { set } from 'lodash'
import { PresenterContract } from '../Contracts'
import { Macroable } from 'macroable'

/**
* Context is used at runtime to resolve values for a given
Expand All @@ -25,7 +24,6 @@ import { PresenterContract } from '../Contracts'
*/
export class Context extends Macroable {
protected static _macros = {}

protected static _getters = {}

/**
Expand All @@ -36,7 +34,7 @@ export class Context extends Macroable {
*/
private frames: any[] = []

constructor (public presenter: PresenterContract, public sharedState: object) {
constructor (public presenter: any, public sharedState: any) {
super()
}

Expand Down Expand Up @@ -64,7 +62,7 @@ export class Context extends Macroable {

/**
* Set key/value pair on the frame object. The value will only be available until
* the `removeFrame` is called.
* the `removeFrame` is not called.
*
* ```js
* ctx.setOnFrame('username', 'virk')
Expand Down
Loading

0 comments on commit 6c0c405

Please sign in to comment.