Skip to content

Commit

Permalink
Merge pull request #21 from eta-dev/path-caching
Browse files Browse the repository at this point in the history
  • Loading branch information
nebrelbug authored Sep 16, 2020
2 parents e551376 + 70bb7e5 commit 88a65e0
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 78 deletions.
5 changes: 4 additions & 1 deletion deno_dist/compile-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import type { AstObject } from "./parse.ts";
* ```
*/

export default function compileToString(str: string, config: EtaConfig) {
export default function compileToString(
str: string,
config: EtaConfig,
): string {
var buffer: Array<AstObject> = Parse(str, config);

var res = "var tR=''" +
Expand Down
97 changes: 61 additions & 36 deletions deno_dist/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,75 @@ import type { Cacher } from "./storage.ts";
type trimConfig = "nl" | "slurp" | false;

export interface EtaConfig {
/** Name of the data object. Default `it` */
varName: string;
/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig];
/** Remove all safe-to-remove whitespace */
rmWhitespace: boolean;
/** Whether or not to automatically XML-escape interpolations. Default true */
autoEscape: boolean;
/** Delimiters: by default `['<%', '%>']` */
tags: [string, string];

/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig];

/** Compile to async function */
async: boolean;

/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean;

/** XML-escaping function */
e: (str: string) => string;

/** Parsing options */
parse: {
/** Which prefix to use for evaluation. Default `""` */
exec: string;

/** Which prefix to use for interpolation. Default `"="` */
interpolate: string;

/** Which prefix to use for raw interpolation. Default `"~"` */
raw: string;
/** Which prefix to use for evaluation. Default `""` */
exec: string;
};
/** XML-escaping function */
e: (str: string) => string;

/** Array of plugins */
plugins: Array<{ processFnString?: Function; processAST?: Function }>;
/** Compile to async function */
async: boolean;

/** Remove all safe-to-remove whitespace */
rmWhitespace: boolean;

/** Delimiters: by default `['<%', '%>']` */
tags: [string, string];

/** Holds template cache */
templates: Cacher<TemplateFunction>;
/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean;
/** Directories that contain templates */
views?: string | Array<string>;
/** Where should absolute paths begin? Default '/' */
root?: string;

/** Name of the data object. Default `it` */
varName: string;

/** Absolute path to template file */
filename?: string;
/** Name of template file */
name?: string;
/** Whether or not to cache templates if `name` or `filename` is passed */
"view cache"?: boolean;
/** Make data available on the global object instead of varName */
useWith?: boolean;

/** Holds cache of resolved filepaths. Set to `false` to disable */
filepathCache?: Record<string, string> | false;

/** Function to include templates by name */
include?: Function;

/** Function to include templates by filepath */
includeFile?: Function;

/** Name of template */
name?: string;

/** Where should absolute paths begin? Default '/' */
root?: string;

/** Make data available on the global object instead of varName */
useWith?: boolean;

/** Whether or not to cache templates if `name` or `filename` is passed: duplicate of `cache` */
"view cache"?: boolean;

/** Directory or directories that contain templates */
views?: string | Array<string>;

[index: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
}

Expand Down Expand Up @@ -85,23 +110,23 @@ function includeHelper(

/** Eta's base (global) configuration */
var config: EtaConfig = {
varName: "it",
autoTrim: [false, "nl"],
rmWhitespace: false,
async: false,
autoEscape: true,
tags: ["<%", "%>"],
autoTrim: [false, "nl"],
cache: false,
e: XMLEscape,
include: includeHelper,
parse: {
exec: "",
interpolate: "=",
raw: "~",
exec: "",
},
async: false,
templates: templates,
cache: false,
plugins: [],
rmWhitespace: false,
tags: ["<%", "%>"],
templates: templates,
useWith: false,
e: XMLEscape,
include: includeHelper,
varName: "it",
};

/**
Expand Down
25 changes: 25 additions & 0 deletions deno_dist/file-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ function getPath(path: string, options: EtaConfig) {
var views = options.views;
var searchedPaths: Array<string> = [];

// If these four values are the same,
// getPath() will return the same result every time.
// We can cache the result to avoid expensive
// file operations.
var pathOptions = JSON.stringify({
filename: options.filename, // filename of the template which called includeFile()
path: path,
root: options.root,
views: options.views,
});

if (
options.cache && options.filepathCache && options.filepathCache[pathOptions]
) {
// Use the cached filepath
return options.filepathCache[pathOptions];
}

/** Add a filepath to the list of paths we've checked for a template */
function addPathToSearched(pathSearched: string) {
if (!searchedPaths.includes(pathSearched)) {
Expand Down Expand Up @@ -160,6 +178,13 @@ function getPath(path: string, options: EtaConfig) {
);
}
}

// If caching and filepathCache are enabled,
// cache the input & output of this function.
if (options.cache && options.filepathCache) {
options.filepathCache[pathOptions] = includePath;
}

return includePath;
}

Expand Down
1 change: 1 addition & 0 deletions deno_dist/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { includeFileHelper } from "./file-helpers.ts";
import { config } from "./config.ts";

config.includeFile = includeFileHelper;
config.filepathCache = {};

export {
loadFile,
Expand Down
2 changes: 1 addition & 1 deletion deno_dist/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Cacher<T> {
define(key: string, val: T) {
this.cache[key] = val;
}
get(key: string) {
get(key: string): T {
// string | array.
// TODO: allow array of keys to look down
// TODO: create plugin to allow referencing helpers, filters with dot notation
Expand Down
2 changes: 1 addition & 1 deletion src/compile-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { AstObject } from './parse'
* ```
*/

export default function compileToString(str: string, config: EtaConfig) {
export default function compileToString(str: string, config: EtaConfig): string {
var buffer: Array<AstObject> = Parse(str, config)

var res =
Expand Down
99 changes: 62 additions & 37 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,75 @@ import type { Cacher } from './storage'
type trimConfig = 'nl' | 'slurp' | false

export interface EtaConfig {
/** Name of the data object. Default `it` */
varName: string
/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig]
/** Remove all safe-to-remove whitespace */
rmWhitespace: boolean
/** Whether or not to automatically XML-escape interpolations. Default true */
autoEscape: boolean
/** Delimiters: by default `['<%', '%>']` */
tags: [string, string]

/** Configure automatic whitespace trimming. Default `[false, 'nl']` */
autoTrim: trimConfig | [trimConfig, trimConfig]

/** Compile to async function */
async: boolean

/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean

/** XML-escaping function */
e: (str: string) => string

/** Parsing options */
parse: {
/** Which prefix to use for evaluation. Default `""` */
exec: string

/** Which prefix to use for interpolation. Default `"="` */
interpolate: string

/** Which prefix to use for raw interpolation. Default `"~"` */
raw: string
/** Which prefix to use for evaluation. Default `""` */
exec: string
}
/** XML-escaping function */
e: (str: string) => string

/** Array of plugins */
plugins: Array<{ processFnString?: Function; processAST?: Function }>
/** Compile to async function */
async: boolean

/** Remove all safe-to-remove whitespace */
rmWhitespace: boolean

/** Delimiters: by default `['<%', '%>']` */
tags: [string, string]

/** Holds template cache */
templates: Cacher<TemplateFunction>
/** Whether or not to cache templates if `name` or `filename` is passed */
cache: boolean
/** Directories that contain templates */
views?: string | Array<string>
/** Where should absolute paths begin? Default '/' */
root?: string

/** Name of the data object. Default `it` */
varName: string

/** Absolute path to template file */
filename?: string
/** Name of template file */
name?: string
/** Whether or not to cache templates if `name` or `filename` is passed */
'view cache'?: boolean
/** Make data available on the global object instead of varName */
useWith?: boolean

/** Holds cache of resolved filepaths. Set to `false` to disable */
filepathCache?: Record<string, string> | false

/** Function to include templates by name */
include?: Function

/** Function to include templates by filepath */
includeFile?: Function

/** Name of template */
name?: string

/** Where should absolute paths begin? Default '/' */
root?: string

/** Make data available on the global object instead of varName */
useWith?: boolean

/** Whether or not to cache templates if `name` or `filename` is passed: duplicate of `cache` */
'view cache'?: boolean

/** Directory or directories that contain templates */
views?: string | Array<string>

[index: string]: any // eslint-disable-line @typescript-eslint/no-explicit-any
}

Expand Down Expand Up @@ -81,23 +106,23 @@ function includeHelper(this: EtaConfig, templateNameOrPath: string, data: object

/** Eta's base (global) configuration */
var config: EtaConfig = {
varName: 'it',
autoTrim: [false, 'nl'],
rmWhitespace: false,
async: false,
autoEscape: true,
tags: ['<%', '%>'],
autoTrim: [false, 'nl'],
cache: false,
e: XMLEscape,
include: includeHelper,
parse: {
exec: '',
interpolate: '=',
raw: '~',
exec: ''
raw: '~'
},
async: false,
templates: templates,
cache: false,
plugins: [],
rmWhitespace: false,
tags: ['<%', '%>'],
templates: templates,
useWith: false,
e: XMLEscape,
include: includeHelper
varName: 'it'
}

/**
Expand Down
23 changes: 23 additions & 0 deletions src/file-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ function getPath(path: string, options: EtaConfig) {
var views = options.views
var searchedPaths: Array<string> = []

// If these four values are the same,
// getPath() will return the same result every time.
// We can cache the result to avoid expensive
// file operations.
var pathOptions = JSON.stringify({
filename: options.filename, // filename of the template which called includeFile()
path: path,
root: options.root,
views: options.views
})

if (options.cache && options.filepathCache && options.filepathCache[pathOptions]) {
// Use the cached filepath
return options.filepathCache[pathOptions]
}

/** Add a filepath to the list of paths we've checked for a template */
function addPathToSearched(pathSearched: string) {
if (!searchedPaths.includes(pathSearched)) {
Expand Down Expand Up @@ -146,6 +162,13 @@ function getPath(path: string, options: EtaConfig) {
throw EtaErr('Could not find the template "' + path + '". Paths tried: ' + searchedPaths)
}
}

// If caching and filepathCache are enabled,
// cache the input & output of this function.
if (options.cache && options.filepathCache) {
options.filepathCache[pathOptions] = includePath
}

return includePath
}

Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { includeFileHelper } from './file-helpers'
import { config } from './config'

config.includeFile = includeFileHelper
config.filepathCache = {}

export { loadFile, renderFile, renderFile as __express } from './file-handlers'

Expand Down
Loading

0 comments on commit 88a65e0

Please sign in to comment.