@popeindustries/lit-html-server
Advanced tools
Comparing version 0.13.0 to 0.14.0
@@ -10,9 +10,9 @@ 'use strict'; | ||
* so this is a no-op. | ||
* @param {*} expression | ||
* @param {function} valueFn | ||
* @param {*} value | ||
* @param {function} fn | ||
* @returns {function} | ||
*/ | ||
guard: directive((expression, valueFn) => (part) => { | ||
part.setValue(valueFn()); | ||
guard: directive((value, fn) => (part) => { | ||
part.setValue(fn()); | ||
}) | ||
}; |
module.exports = { | ||
...require('./classMap.js'), | ||
...require('./class-map.js'), | ||
...require('./guard.js'), | ||
...require('./if-defined.js'), | ||
...require('./repeat.js'), | ||
...require('./styleMap.js'), | ||
...require('./style-map.js'), | ||
...require('./unsafe-html.js'), | ||
...require('./until.js'), | ||
...require('./when.js') | ||
...require('./until.js') | ||
}; |
'use strict'; | ||
const { directive } = require('../lib/directive.js'); | ||
const { isPrimitive } = require('../lib/is.js'); | ||
module.exports = { | ||
/** | ||
* Render 'defaultContent'. | ||
* Not possible to render more than once in a server context, | ||
* so this is a no-op. | ||
* @param {Promise<*>} promise | ||
* @param {*} defaultContent | ||
* Renders one of a series of values, including Promises, in priority order. | ||
* Not possible to render more than once in a server context, so primitive | ||
* sync values are prioritised over async, unless there are no more pending | ||
* values, in which case the last value is always rendered regardless. | ||
* @param {...} args | ||
* @returns {function} | ||
*/ | ||
until: directive((promise, defaultContent) => (part) => { | ||
part.setValue(defaultContent); | ||
until: directive((...args) => (part) => { | ||
for (let i = 0, n = args.length; i < n; i++) { | ||
const value = args[i]; | ||
// Render sync values immediately, | ||
// or last value (async included) if no more values pending | ||
if (isPrimitive(value) || i === n - 1) { | ||
part.setValue(value); | ||
return; | ||
} | ||
} | ||
}) | ||
}; |
{ | ||
"name": "@popeindustries/lit-html-server", | ||
"version": "0.13.0", | ||
"version": "0.14.0", | ||
"description": "Render lit-html templates on the server", | ||
@@ -24,13 +24,17 @@ "keywords": [ | ||
"devDependencies": { | ||
"autocannon": "^3.1.0", | ||
"autocannon": "^3.2.0", | ||
"babel-eslint": "^10.0.1", | ||
"chai": "^4.2.0", | ||
"eslint": "^5.8.0", | ||
"eslint-config-prettier": "^3.1.0", | ||
"eslint": "^5.9.0", | ||
"eslint-config-prettier": "^3.3.0", | ||
"eslint-plugin-prettier": "^3.0.0", | ||
"husky": "^1.1.3", | ||
"lint-staged": "^8.0.4", | ||
"lit-html": "^0.13.0", | ||
"husky": "^1.2.0", | ||
"lint-staged": "^8.1.0", | ||
"lit-html": "^0.14.0", | ||
"mocha": "^5.2.0", | ||
"prettier": "^1.15.1" | ||
"normalize-html-whitespace": "^0.2.0", | ||
"prettier": "^1.15.3", | ||
"rollup": "^0.67.4", | ||
"rollup-plugin-commonjs": "^9.2.0", | ||
"rollup-plugin-node-resolve": "^3.4.0" | ||
}, | ||
@@ -41,2 +45,3 @@ "engines": { | ||
"scripts": { | ||
"build": "rollup --config rollup.config.js", | ||
"format": "prettier --write './{directives,lib,test}/**/*.{js,json}'", | ||
@@ -46,4 +51,5 @@ "lint": "eslint './{directives,lib,test}/**/*.js'", | ||
"precommit": "lint-staged", | ||
"prepublishOnly": "npm run build", | ||
"test": "NODE_ENV=test mocha \"test/*-test.js\" --reporter spec --bail --timeout 2000" | ||
} | ||
} |
210
README.md
@@ -22,14 +22,18 @@ [](https://npmjs.org/package/@popeindustries/lit-html-server) | ||
const { html } = require('@popeindustries/lit-html-server'); | ||
const { classMap } = require('@popeindustries/lit-html-server/directives/class-map.js'); | ||
const { until } = require('@popeindustries/lit-html-server/directives/until.js'); | ||
function layout(data) { | ||
return html`<!DOCTYPE html> | ||
return html` | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>${data.title}</title> | ||
</head> | ||
<body> | ||
${body(data.api)} | ||
</body> | ||
</html>`; | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<title>${data.title}</title> | ||
</head> | ||
<body> | ||
${until(body(data.api))} | ||
</body> | ||
</html> | ||
`; | ||
} | ||
@@ -41,5 +45,7 @@ | ||
return html`<h1>${data.title}</h1> | ||
<x-widget ?enabled=${data.hasWidget}></x-widget> | ||
<p class="${data.invertedText ? 'negative' : ''}">${data.text}</p>`; | ||
return html` | ||
<h1>${data.title}</h1> | ||
<x-widget ?enabled="${data.hasWidget}"></x-widget> | ||
<p class="${classMap({ 'negative': data.invertedText }">${data.text}</p> | ||
`; | ||
} | ||
@@ -65,3 +71,5 @@ ``` | ||
const name = 'Bob'; | ||
html`<h1>Hello ${name}!</h1>`; | ||
html` | ||
<h1>Hello ${name}!</h1> | ||
`; | ||
``` | ||
@@ -73,5 +81,5 @@ | ||
const { unsafeHTML } = require('@popeindustries/lit-html-server/directives/unsafe-html.js'); | ||
html`<div> | ||
${unsafeHTML('<span>dangerous!</span>')} | ||
</div>`; | ||
html` | ||
<div> ${unsafeHTML('<span>dangerous!</span>')} </div> | ||
`; | ||
``` | ||
@@ -84,3 +92,7 @@ | ||
```js | ||
render(html`<h1>Hello ${name}!</h1>`).pipe(response); | ||
render( | ||
html` | ||
<h1>Hello ${name}!</h1> | ||
` | ||
).pipe(response); | ||
``` | ||
@@ -93,3 +105,7 @@ | ||
```js | ||
const markup = await renderToString(html`<h1>Hello ${name}!</h1>`); | ||
const markup = await renderToString( | ||
html` | ||
<h1>Hello ${name}!</h1> | ||
` | ||
); | ||
``` | ||
@@ -134,3 +150,5 @@ | ||
```js | ||
html`<h1>Hello ${name}</h1>`; | ||
html` | ||
<h1>Hello ${name}</h1> | ||
`; | ||
//=> <h1>Hello Bob</h1> | ||
@@ -142,3 +160,5 @@ ``` | ||
```js | ||
html`<div id=${id}></div>`; | ||
html` | ||
<div id="${id}"></div> | ||
`; | ||
//=> <div id="main"></div> | ||
@@ -150,3 +170,5 @@ ``` | ||
```js | ||
html`<input type="checkbox" ?checked=${checked}>`; | ||
html` | ||
<input type="checkbox" ?checked="${checked}" /> | ||
`; | ||
//=> <input type="checkbox" checked> if truthy | ||
@@ -159,3 +181,5 @@ //=> <input type="checkbox" > if falsey | ||
```js | ||
html`<input .value=${value}>`; | ||
html` | ||
<input .value="${value}" /> | ||
`; | ||
//=> <input > | ||
@@ -168,3 +192,5 @@ ``` | ||
const fn = (e) => console.log('clicked'); | ||
html`<button @click=${fn}>Click Me</button>`; | ||
html` | ||
<button @click="${fn}">Click Me</button> | ||
`; | ||
//=> <button >Click Me</button> | ||
@@ -184,6 +210,7 @@ ``` | ||
```js | ||
const header = html`<h1>Header</h1>`; | ||
const header = html` | ||
<h1>Header</h1> | ||
`; | ||
const page = html` | ||
${header} | ||
<p>This is some text</p> | ||
${header} <p>This is some text</p> | ||
`; | ||
@@ -196,4 +223,17 @@ ``` | ||
const items = [1, 2, 3]; | ||
html`<ul>${items.map((item) => html`<li>${item}</li>`)}</ul>`; | ||
html`<p>total = ${new Set(items)}</p>`; | ||
html` | ||
<ul> | ||
${ | ||
items.map( | ||
(item) => | ||
html` | ||
<li>${item}</li> | ||
` | ||
) | ||
} | ||
</ul> | ||
`; | ||
html` | ||
<p>total = ${new Set(items)}</p> | ||
`; | ||
``` | ||
@@ -205,5 +245,9 @@ | ||
const promise = fetch('sample.txt').then((r) => r.text()); | ||
html`<p>The response is ${promise}.</p>`; | ||
html` | ||
<p>The response is ${promise}.</p> | ||
`; | ||
``` | ||
> note that **lit-html** no longer supports Promise values, and **lit-html-server** will therefore log a warning. Use the `until` directive instead. | ||
### Directives | ||
@@ -213,9 +257,20 @@ | ||
- `guard(expression, valueFn)`: no-op since re-rendering does not apply (renders result of `valueFn`) | ||
- `guard(value, fn)`: no-op since re-rendering does not apply (renders result of `fn`) | ||
```js | ||
const guard = require('@popeindustries/lit-html-server/directives/guard.js'); | ||
html`<div> | ||
${guard(items, () => items.map((item) => html`${item}`))} | ||
</div>`; | ||
html` | ||
<div> | ||
${ | ||
guard(items, () => | ||
items.map( | ||
(item) => | ||
html` | ||
${item} | ||
` | ||
) | ||
) | ||
} | ||
</div> | ||
`; | ||
``` | ||
@@ -227,44 +282,93 @@ | ||
const ifDefined = require('@popeindustries/lit-html-server/directives/if-defined.js'); | ||
html`<div class=${ifDefined(className)}></div>`; | ||
html` | ||
<div class="${ifDefined(className)}"></div> | ||
`; | ||
``` | ||
- `repeat(items, keyfn, template))`: no-op since re-rendering does not apply (maps `items` over `template`) | ||
- `repeat(items, keyfnOrTemplate, template))`: no-op since re-rendering does not apply (maps `items` over `template`) | ||
```js | ||
const repeat = require('@popeindustries/lit-html-server/directives/repeat.js'); | ||
html`<ul> | ||
${repeat(items, (i) => i.id, (i, index) => html`<li>${index}: ${i.name}</li>`)} | ||
</ul>`; | ||
html` | ||
<ul> | ||
${ | ||
repeat( | ||
items, | ||
(i) => i.id, | ||
(i, index) => | ||
html` | ||
<li>${index}: ${i.name}</li> | ||
` | ||
) | ||
} | ||
</ul> | ||
`; | ||
``` | ||
- `until(promise, defaultContent)`: no-op since only one render pass (renders `defaultContent`) | ||
- `until(...args)`: renders one of a series of values, including Promises, in priority order. Since it's not possible to render more than once in a server context, primitive sync values are prioritised over async Promises, unless there are no more pending values, in which case the last value is rendered regardless | ||
```js | ||
const until = require('@popeindustries/lit-html-server/directives/until.js'); | ||
html`<p> | ||
${until(fetch('content.txt').then((r) => r.text()), html`<span>Loading...</span>`)} | ||
</p>`; | ||
html` | ||
<p> | ||
${ | ||
until( | ||
fetch('content.json').then((r) => r.json()), | ||
html` | ||
<span>Loading...</span> | ||
` | ||
) | ||
} | ||
</p> | ||
`; | ||
// => renders <p><span>Loading...</span></p> | ||
html` | ||
<p> | ||
${ | ||
until( | ||
fetch('content.json').then((r) => r.json()), | ||
isBrowser | ||
? html` | ||
<span>Loading...</span> | ||
` | ||
: undefined | ||
) | ||
} | ||
</p> | ||
`; | ||
// => renders fetch result | ||
``` | ||
- `when(condition, trueTemplate, falseTemplate)`: switches between two templates based on the given condition (does not cache templates) | ||
- `classMap(classInfo)`: applies css classes to the `class` attribute. 'classInfo' keys are added as class names if values are truthy | ||
```js | ||
const when = require('@popeindustries/lit-html-server/directives/when.js'); | ||
html`<p> | ||
${when(checked, () => html`Checkmark is checked`, () => html`Checkmark is not checked`)} | ||
</p>`; | ||
const classMap = require('@popeindustries/lit-html-server/directives/class-map.js'); | ||
html` | ||
<div class="${classMap({ red: true })}"></div> | ||
`; | ||
``` | ||
- `classMap(classInfo)`: applies css classes to the `class` attribute. 'classInfo' keys are added as class names if values are truthy | ||
- `styleMap(styleInfo)`: applies css properties to the `style` attribute. 'styleInfo' keys and values are added as style properties | ||
```js | ||
const classMap = require('@popeindustries/lit-html-server/directives/classMap.js'); | ||
html`<div class=${classMap({ red: true })}></div>`; | ||
const styleMap = require('@popeindustries/lit-html-server/directives/style-map.js'); | ||
html` | ||
<div style="${styleMap({ color: 'red' })}"></div> | ||
`; | ||
``` | ||
- `styleMap(styleInfo)`: applies css properties to the `style` attribute. 'styleInfo' keys and values are added as style properties | ||
- `cache(value)`: Enables fast switching between multiple templates by caching previous results. Since it's generally not desireable to cache between requests, this is a no-op | ||
```js | ||
const styleMap = require('@popeindustries/lit-html-server/directives/styleMap.js'); | ||
html`<div style=${styleMap({ color: 'red' })}></div>`; | ||
const cache = require('@popeindustries/lit-html-server/directives/cache.js'); | ||
cache( | ||
loggedIn | ||
? html` | ||
You are logged in | ||
` | ||
: html` | ||
Please log in | ||
` | ||
); | ||
``` | ||
@@ -271,0 +375,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
258469
2696
363
15
14
2
1