Skip to content

Commit 2420555

Browse files
committed
BREAKING: Make ESM only
1 parent fa43845 commit 2420555

File tree

9 files changed

+87
-133
lines changed

9 files changed

+87
-133
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"extends": "@voxpelli",
2+
"extends": "@voxpelli/eslint-config/esm",
33
"root": true
44
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Renders a [`htm`](https://www.npmjs.com/package/htm) tagged template asyncly int
44

55
[![npm version](https://img.shields.io/npm/v/async-htm-to-string.svg?style=flat)](https://www.npmjs.com/package/async-htm-to-string)
66
[![npm downloads](https://img.shields.io/npm/dm/async-htm-to-string.svg?style=flat)](https://www.npmjs.com/package/async-htm-to-string)
7-
[![Module type: CJS+ESM](https://img.shields.io/badge/module%20type-cjs%2Besm-brightgreen)](https://github.com/voxpelli/badges-cjs-esm)
7+
[![Module type: ESM](https://img.shields.io/badge/module%20type-esm-brightgreen)](https://github.com/voxpelli/badges-cjs-esm)
88
[![Types in JS](https://img.shields.io/badge/types_in_js-yes-brightgreen)](https://github.com/voxpelli/types-in-js)
99
[![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/voxpelli/eslint-config)
1010
[![Follow @voxpelli@mastodon.social](https://img.shields.io/mastodon/follow/109247025527949675?domain=https%3A%2F%2Fmastodon.social&style=social)](https://mastodon.social/@voxpelli)
@@ -18,7 +18,7 @@ npm install async-htm-to-string
1818
```
1919

2020
```javascript
21-
const { html, renderToString } = require('async-htm-to-string');
21+
import { html, renderToString } from 'async-htm-to-string';
2222

2323
const customTag = ({ prefix }, children) => html`<div>${prefix}-${children}</div>`;
2424
const dynamicContent = 'bar';

index.js

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
// @ts-check
2-
3-
'use strict';
4-
5-
const htm = require('htm'); // linemod-replace-with: import htm from 'htm';
6-
7-
const escape = require('stringify-entities'); // linemod-replace-with: import escape from 'stringify-entities';
1+
import htm from 'htm';
2+
import { stringifyEntities } from 'stringify-entities';
83

94
// *** REACT BORROWED ***
105
const ATTRIBUTE_NAME_START_CHAR =
@@ -129,7 +124,7 @@ const omittedCloseTags = {
129124
* @param {ElementProps} props
130125
* @returns {Generator<string>}
131126
*/
132-
const _renderProps = function * (props) {
127+
function * _renderProps (props) {
133128
// *** REACT BORROWED https://github.com/facebook/react/blob/779a472b0901b2d28e382f3850b2ad09a555b014/packages/react-dom/src/server/DOMMarkupOperations.js#L48-L72 ***
134129
for (const propKey in props) {
135130
if (!Object.prototype.hasOwnProperty.call(props, propKey)) {
@@ -151,7 +146,7 @@ const _renderProps = function * (props) {
151146
} else if (propValue === '') {
152147
yield ` ${propKey}=""`;
153148
} else if (typeof propValue === 'string') {
154-
yield ` ${propKey}="${escape(propValue, { useNamedReferences: true })}"`;
149+
yield ` ${propKey}="${stringifyEntities(propValue, { escapeOnly: true, useNamedReferences: true })}"`;
155150
} else if (typeof propValue === 'number') {
156151
yield ` ${propKey}="${propValue}"`;
157152
} else {
@@ -160,15 +155,15 @@ const _renderProps = function * (props) {
160155
}
161156
}
162157
// *** END REACT BORROWED ***
163-
};
158+
}
164159

165160
/**
166161
* @yields {string}
167162
* @template {ElementProps} Props
168163
* @param {StringRenderableElement<Props>} item
169164
* @returns {AsyncIterableIterator<string>}
170165
*/
171-
const _renderStringItem = async function * (item) {
166+
async function * _renderStringItem (item) {
172167
const { children, props, type } = item;
173168

174169
const tag = type.toLowerCase();
@@ -186,15 +181,15 @@ const _renderStringItem = async function * (item) {
186181
yield * _render(children);
187182
yield `</${tag}>`;
188183
}
189-
};
184+
}
190185

191186
/**
192187
* @yields {string}
193188
* @template {ElementProps} Props
194189
* @param {BasicRenderableElement<Props>} item
195190
* @returns {AsyncIterableIterator<string>}
196191
*/
197-
const _renderElement = async function * (item) {
192+
async function * _renderElement (item) {
198193
const { children, props, skipStringEscape, type } = item;
199194

200195
if (type === undefined) {
@@ -215,29 +210,29 @@ const _renderElement = async function * (item) {
215210
} else {
216211
throw new TypeError(`Invalid element type: ${typeof type}`);
217212
}
218-
};
213+
}
219214

220215
/**
221216
* @yields {string}
222217
* @param {IterableIteratorMaybeAsync<RenderableElement>} iterator
223218
* @returns {AsyncIterableIterator<string>}
224219
*/
225-
const _renderIterable = async function * (iterator) {
220+
async function * _renderIterable (iterator) {
226221
for await (const item of iterator) {
227222
yield * _render(item);
228223
}
229-
};
224+
}
230225

231226
/**
232227
* @yields {string}
233228
* @param {RenderableElement|IterableIteratorMaybeAsync<RenderableElement>} item
234229
* @returns {AsyncIterableIterator<string>}
235230
*/
236-
const _render = async function * (item) {
231+
async function * _render (item) {
237232
if (item === undefined || item === null) {
238233
yield '';
239234
} else if (typeof item === 'string') {
240-
yield escape(item, { useNamedReferences: true });
235+
yield stringifyEntities(item, { escapeOnly: true, useNamedReferences: true });
241236
} else if (typeof item === 'number') {
242237
yield item + '';
243238
} else {
@@ -249,14 +244,14 @@ const _render = async function * (item) {
249244
throw new TypeError(`Invalid render item type: ${typeof item}`);
250245
}
251246
}
252-
};
247+
}
253248

254249
/**
255250
* @yields {string}
256251
* @param {HtmlMethodResult} item
257252
* @returns {AsyncIterableIterator<string>}
258253
*/
259-
const render = async function * (item) { // linemod-prefix-with: export
254+
export async function * render (item) {
260255
if (item === undefined) throw new TypeError('Expected an argument');
261256
if (!item) throw new TypeError(`Expected a non-falsy argument, got: ${item}`);
262257
if (Array.isArray(item)) {
@@ -268,25 +263,27 @@ const render = async function * (item) { // linemod-prefix-with: export
268263
} else {
269264
throw new TypeError(`Expected a string or an object, got: ${typeof item}`);
270265
}
271-
};
266+
}
272267

273268
/**
274269
* @param {IterableIteratorMaybeAsync<string>} generator
275270
* @returns {Promise<string>}
276271
*/
277-
const generatorToString = async (generator) => { // linemod-prefix-with: export
272+
export async function generatorToString (generator) {
278273
let result = '';
279274
for await (const item of generator) {
280275
result += item;
281276
}
282277
return result;
283-
};
278+
}
284279

285280
/**
286281
* @param {HtmlMethodResult} item
287282
* @returns {Promise<string>}
288283
*/
289-
const renderToString = async (item) => generatorToString(render(item)); // linemod-prefix-with: export
284+
export async function renderToString (item) {
285+
return generatorToString(render(item));
286+
}
290287

291288
/**
292289
* @template {ElementProps} T
@@ -295,9 +292,9 @@ const renderToString = async (item) => generatorToString(render(item)); // linem
295292
* @param {...RenderableElement} children
296293
* @returns {BasicRenderableElement<T>}
297294
*/
298-
const h = (type, props, ...children) => { // linemod-prefix-with: export
295+
export function h (type, props, ...children) {
299296
return { type, props: props || {}, children };
300-
};
297+
}
301298

302299
/** @type {(strings: TemplateStringsArray, ...values: Array<ElementPropsValue|ElementProps|RenderableElementFunction<any>|RenderableElement|RenderableElement[]>) => unknown} */
303300
const _internalHtml =
@@ -308,7 +305,7 @@ const _internalHtml =
308305
* @param {unknown} result
309306
* @returns {BasicRenderableElement<ElementProps>|string}
310307
*/
311-
const _checkHtmlResult = (result) => {
308+
function _checkHtmlResult (result) {
312309
if (typeof result === 'number') {
313310
return result + '';
314311
} else if (!result) {
@@ -332,14 +329,14 @@ const _checkHtmlResult = (result) => {
332329
} else {
333330
throw new TypeError(`Resolved to invalid value type: ${typeof result}`);
334331
}
335-
};
332+
}
336333

337334
/**
338335
* @param {TemplateStringsArray} strings
339336
* @param {...ElementPropsValue|ElementProps|RenderableElementFunction<any>|RenderableElement|RenderableElement[]} values
340337
* @returns {HtmlMethodResult}
341338
*/
342-
const html = (strings, ...values) => { // linemod-prefix-with: export
339+
export function html (strings, ...values) {
343340
const result = _internalHtml(strings, ...values);
344341

345342
if (!Array.isArray(result)) return _checkHtmlResult(result);
@@ -348,24 +345,15 @@ const html = (strings, ...values) => { // linemod-prefix-with: export
348345
const unknownArray = result;
349346

350347
return unknownArray.map(item => _checkHtmlResult(item));
351-
};
348+
}
352349

353350
/**
354351
* @param {TemplateStringsArray|string} strings
355352
* @param {...(string|number)} values
356353
* @returns {BasicRenderableElement<{}>}
357354
*/
358-
const rawHtml = (strings, ...values) => { // linemod-prefix-with: export
355+
export function rawHtml (strings, ...values) {
359356
/** @type {RenderableElementFunction<{}>} */
360357
const type = () => typeof strings === 'string' ? strings : String.raw(strings, ...values);
361358
return { type, props: {}, children: [], skipStringEscape: true };
362-
};
363-
364-
module.exports = { // linemod-remove
365-
generatorToString, // linemod-remove
366-
html, // linemod-remove
367-
h, // linemod-remove
368-
rawHtml, // linemod-remove
369-
render, // linemod-remove
370-
renderToString, // linemod-remove
371-
}; // linemod-remove
359+
}

index.test-d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
RenderableElement,
1515
RenderableElementFunction,
1616
BasicRenderableElement
17-
} from '.';
17+
} from './index.js';
1818

1919
type ExtendableRenderableElementFunction<Props extends ElementProps = ElementProps> = (props: Props, children: RenderableElement[]) => HtmlMethodResult;
2020

package.json

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,9 @@
99
"type": "git",
1010
"url": "git://github.com/voxpelli/async-htm-to-string.git"
1111
},
12-
"main": "index.js",
13-
"module": "index.mjs",
12+
"type": "module",
13+
"exports": "./index.js",
1414
"types": "index.d.ts",
15-
"exports": {
16-
"require": "./index.js",
17-
"import": "./index.mjs"
18-
},
1915
"engines": {
2016
"node": ">=16.0.0"
2117
},
@@ -40,9 +36,7 @@
4036
],
4137
"scripts": {
4238
"build:0": "run-s clean",
43-
"build:1:declaration": "tsc -p declaration.tsconfig.json",
44-
"build:1:commonjs": "linemod -e mjs index.js",
45-
"build:1": "run-p build:1:*",
39+
"build:1": "tsc -p declaration.tsconfig.json",
4640
"build": "run-s build:*",
4741
"check:0": "run-s clean",
4842
"check:1:dependency-check": "dependency-check *.js 'test/**/*.js' --no-dev -i type-fest",
@@ -52,7 +46,7 @@
5246
"check:1:tsc": "tsc",
5347
"check:1:type-coverage": "type-coverage --detail --strict --at-least 99 --ignore-files 'test/*'",
5448
"check:1": "run-p -c --aggregate-output check:1:*",
55-
"check:2": "run-s build:1:declaration",
49+
"check:2": "run-s build:1",
5650
"check:3": "tsd",
5751
"check": "run-s check:*",
5852
"clean:declarations": "rm -rf $(find . -maxdepth 2 -type f -name '*.d.ts*')",
@@ -69,7 +63,7 @@
6963
},
7064
"dependencies": {
7165
"htm": "^3.0.4",
72-
"stringify-entities": "^3.1.0"
66+
"stringify-entities": "^4.0.3"
7367
},
7468
"devDependencies": {
7569
"@skypack/package-check": "^0.2.2",
@@ -100,7 +94,6 @@
10094
"ghat": "^0.14.0",
10195
"husky": "^8.0.3",
10296
"installed-check": "^7.0.0",
103-
"linemod": "^0.3.0",
10497
"mocha": "^10.2.0",
10598
"nodemon": "^2.0.22",
10699
"npm-run-all2": "^6.0.5",

test/fixtures.js

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
'use strict';
1+
/** @type {import('../index.js').HtmlMethodResult} */
2+
export const ELEMENT_FIXTURE = Object.freeze({ type: 'div', props: {}, children: [] });
23

3-
/** @type {import('..').HtmlMethodResult} */
4-
const ELEMENT_FIXTURE = Object.freeze({ type: 'div', props: {}, children: [] });
5-
6-
/** @type {import('..').HtmlMethodResult} */
7-
const ELEMENT_ARRAY_CHILD_FIXTURE = Object.freeze({
4+
/** @type {import('../index.js').HtmlMethodResult} */
5+
export const ELEMENT_ARRAY_CHILD_FIXTURE = Object.freeze({
86
type: 'ul',
97
props: {},
108
children: [
@@ -13,28 +11,21 @@ const ELEMENT_ARRAY_CHILD_FIXTURE = Object.freeze({
1311
],
1412
});
1513

16-
const ELEMENT_FIXTURE_INVALID_TYPE = Object.freeze({ type: true, props: {}, children: [] });
14+
export const ELEMENT_FIXTURE_INVALID_TYPE = Object.freeze({ type: true, props: {}, children: [] });
1715

18-
const PrototypeIncludingClass = function () {
16+
function PrototypeIncludingClass () {
1917
this.a = 1;
2018
this.b = 2;
21-
};
19+
}
2220

2321
// add properties in f function's prototype
2422
PrototypeIncludingClass.prototype.b = 3;
2523
PrototypeIncludingClass.prototype.c = 4;
2624

27-
/** @type {import('..').HtmlMethodResult} */
25+
/** @type {import('../index.js').HtmlMethodResult} */
2826
// @ts-ignore
29-
const ELEMENT_FIXTURE_WITH_COMPLEX_PROPS = Object.freeze({
27+
export const ELEMENT_FIXTURE_WITH_COMPLEX_PROPS = Object.freeze({
3028
type: 'div',
3129
props: new PrototypeIncludingClass(),
3230
children: [],
3331
});
34-
35-
module.exports = {
36-
ELEMENT_FIXTURE,
37-
ELEMENT_ARRAY_CHILD_FIXTURE,
38-
ELEMENT_FIXTURE_INVALID_TYPE,
39-
ELEMENT_FIXTURE_WITH_COMPLEX_PROPS,
40-
};

0 commit comments

Comments
 (0)