dyn-template
Advanced tools
Comparing version 0.0.1 to 1.0.0
@@ -6,3 +6,5 @@ import dts from 'bun-plugin-dts' | ||
outdir: "./dist", | ||
plugins: [dts()], | ||
plugins: [dts({ | ||
output: { noBanner: true }, | ||
})], | ||
minify: true, | ||
@@ -9,0 +11,0 @@ target: "browser", |
@@ -1,12 +0,10 @@ | ||
// Generated by dts-bundle-generator v9.5.1 | ||
export interface DynTemplate<F extends (...args: any) => any = () => any> { | ||
first: string; | ||
fns: readonly F[]; | ||
strs: readonly string[]; | ||
first: string | ||
fns: readonly F[] | ||
strs: readonly string[] | ||
} | ||
export declare function dynTemplate<F extends (...args: any) => any>(strs: TemplateStringsArray, ...exps: any[]): DynTemplate<F>; | ||
export declare function closure<F extends (...args: any) => any>(template: DynTemplate<F>): () => string; | ||
export declare function dyn(strs: TemplateStringsArray, ...exps: any[]): () => string; | ||
export declare function dynTemplate<F extends (...args: any) => any>(strs: TemplateStringsArray, ...exps: any[]): DynTemplate<F> | ||
export declare function closure<F extends (...args: any) => any>(template: DynTemplate<F>): () => string | ||
export declare function dyn(strs: TemplateStringsArray, ...exps: any[]): () => string | ||
export {}; | ||
export { } |
{ | ||
"name": "dyn-template", | ||
"version": "0.0.1", | ||
"version": "1.0.0", | ||
"author": "Wzh <wzh@uvwee.com>", | ||
"repository": "github:wzh19960613/dyn-template-js", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/wzh19960613/dyn-template-js.git" | ||
}, | ||
"main": "dist/index.js", | ||
"module": "dist/index.js", | ||
"devDependencies": { | ||
"@types/bun": "^1.1.11", | ||
"@types/bun": "^1.1.12", | ||
"bun-plugin-dts": "^0.3.0" | ||
@@ -11,0 +14,0 @@ }, |
# dyn-template | ||
Dynamic Template string. It is all the same with Template Literal String in Javascript besides | ||
instead of returning a string, it returns a function whose return value is a string. | ||
English | [中文](README_CN.md) | ||
Dynamic template strings. It works similarly to JavaScript's [template literals](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals), with two key differences: | ||
- While template literals return a string directly, dynamic templates return a function that returns a string when called | ||
- If an expression in the dynamic template is a function, that function will be executed each time the dynamic template is called | ||
## Installation | ||
@@ -22,3 +26,3 @@ | ||
// Maybe | ||
// Possible output: | ||
// | ||
@@ -32,5 +36,4 @@ // 1. 0.7632479109972825 | ||
If the expression in template is a function, the function will be executed every time when the | ||
dynamic template is executed. On the other hand, if the expression is not a function, it will be | ||
calculated only once when the dynamic template is created. | ||
If an expression in the dynamic template is a function, it will be executed each time the dynamic template is called. | ||
On the other hand, if an expression is not a function, it will only be evaluated once when creating the dynamic template. | ||
@@ -40,14 +43,83 @@ ```javascript | ||
const template = dyn`Compiled at ${Date.now()}, Running at ${Date.now}` | ||
const template = dyn`Compile time: ${Date.now()}, Runtime: ${Date.now}` | ||
for (let n = 0; n < 1000; ++n) console.log(template()) | ||
// Maybe | ||
// Possible output: | ||
// | ||
// Compiled at 1729781340083, Running at 1729781340083 | ||
// Compile time: 1729781340083, Runtime: 1729781340083 | ||
// ... | ||
// Compiled at 1729781340083, Running at 1729781340084 | ||
// Compile time: 1729781340083, Runtime: 1729781340084 | ||
// ... | ||
// Compiled at 1729781340083, Running at 1729781340085 | ||
// Compile time: 1729781340083, Runtime: 1729781340085 | ||
// ... | ||
``` | ||
## Advanced Usage | ||
```javascript | ||
import { dynTemplate, closure } from 'dyn-template' | ||
const fn1 = () => new Date() | ||
const fn2 = Math.random | ||
const template = dynTemplate`str1 ${fn1} str2 ${'non-function expression'} str3 ${fn2} str4` | ||
console.log(template) | ||
// { | ||
// first: 'str1 ', | ||
// fns: [ [Function: fn1], [Function: fn2] ], | ||
// strs: [ ' str2 non-function expression str3 ', ' str4' ] | ||
// } | ||
const fn = closure(template) // Convert template to function | ||
console.log(fn()) | ||
// Possible output: str1 2024-10-27T15:51:51.000Z str2 non-function expression str3 0.763247910 str4 | ||
``` | ||
The object returned by `dynTemplate` contains three properties: | ||
- `first`: The first text block in the template | ||
- `fns`: All functions in the template | ||
- `strs`: Other text blocks in the template. If there are non-function expressions, they will be evaluated and concatenated into the text blocks | ||
The `fns` and `strs` arrays are frozen, so they are immutable, but their elements can be modified. | ||
The `closure` function converts the above object into a function. Its implementation is as follows: | ||
```javascript | ||
function closure(template) { | ||
const { first, fns, strs } = template | ||
return function () { return fns.reduce((r, p, i) => r + p() + strs[i], first) } | ||
} | ||
``` | ||
So the following two approaches are equivalent: | ||
```javascript | ||
import { dynTemplate, closure, dyn } from 'dyn-template' | ||
const t1 = closure(dynTemplate`...`) | ||
const t2 = dyn`...` | ||
``` | ||
When you need to further process the template content, you can first use `dynTemplate` to generate a template object, process it further, and then use `closure` to convert it into a function. | ||
When you need to modify the closure process, you can first use `dynTemplate` to generate a template object, then rewrite a function similar to `closure`: | ||
```javascript | ||
function compile(template) { | ||
const { first, fns, strs } = template | ||
return function (time) { | ||
// Both fns in the template and the closure fn should accept a number or Date parameter | ||
const t = time instanceof Date ? time : new Date(time) | ||
return fns.reduce((r, p, i) => r + p(t) + strs[i], first) | ||
// Added a parameter to the call of `p` | ||
} | ||
} | ||
const template = compile(dynTemplate`Today is ${t => t.getMonth() + 1}/${t => t.getDate()}`) | ||
console.log(template(Date.now())) // Possible output: Today is 10/27 | ||
``` | ||
This allows you to customize the closure calling process to implement more complex functionality. [clock-reader](https://www.npmjs.com/package/clock-reader) is implemented using a similar approach. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
25999
10
81
1
123
0