All files / languages/triplate triplate-compile-cache.ts

100% Statements 12/12
100% Branches 4/4
100% Functions 1/1
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                                                                                16x             14x 14x 14x   14x 1x     13x 13x   13x   13x   2x   2x        
import * as vscode from 'vscode';
import { compile } from 'triplate';
 
/**
 * The compiled result of a triplate template, as produced by `compile`.
 */
type CompiledTemplate = ReturnType<typeof compile>;
 
/**
 * A cache for compiled triplate templates, keyed by document URI and version, 
 * to avoid redundant compilation in providers that repeatedly compile the same document
 * (hover, code lens) while the document is unchanged.
 *
 * A template that fails to compile (syntax error) is not cached — {@link get}
 * returns `null` and clears any stale entry, so the next edit re-compiles.
 */
interface CacheEntry {
	/**
	 * The document version for which `compiled` was produced. Used to determine cache
	 * validity without needing to re-compile.
	 */
	version: number;
 
	/**
	 * The compiled template for the document version given by `version`. Should only be
	 * used if the cache entry is valid (i.e. `version` matches the document's current
	 * version), otherwise may be stale.
	 */
	compiled: CompiledTemplate;
}
 
/**
 * Caches the `compile()` result of a triplate template per document, keyed by
 * `document.version`, so providers that compile the same document repeatedly
 * (hover, code lens) avoid redundant work while the document is unchanged.
 *
 * A template that fails to compile (syntax error) is not cached — {@link get}
 * returns `null` and clears any stale entry, so the next edit re-compiles.
 */
export class TriplateCompileCache {
	private readonly _cache = new Map<string, CacheEntry>();
 
	/**
	 * Returns the compiled template for `document`, or `null` if it currently fails
	 * to compile. Reuses the cached result when the document version is unchanged.
	 */
	get(document: vscode.TextDocument): CompiledTemplate | null {
		const key = document.uri.toString();
		const version = document.version;
		const cached = this._cache.get(key);
 
		if (cached && cached.version === version) {
			return cached.compiled;
		}
 
		try {
			const compiled = compile(document.getText());
 
			this._cache.set(key, { version, compiled });
 
			return compiled;
		} catch {
			this._cache.delete(key);
 
			return null;
		}
	}
}