speedy-entities 1.1.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Savva Mikhalevski
3
+ Copyright (c) 2023 Savva Mikhalevski
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,103 +1,79 @@
1
- # speedy-entities [![build](https://github.com/smikhalevski/speedy-entities/actions/workflows/master.yml/badge.svg?branch=master&event=push)](https://github.com/smikhalevski/speedy-entities/actions/workflows/master.yml)
1
+ # speedy-entities 🏎💨 [![build](https://github.com/smikhalevski/speedy-entities/actions/workflows/master.yml/badge.svg?branch=master&event=push)](https://github.com/smikhalevski/speedy-entities/actions/workflows/master.yml)
2
2
 
3
- [The fastest](#performance) XML/HTML entity decoder that supports customizable named character references.
3
+ [The fastest](#performance) XML/HTML entity encoder/decoder in
4
+ [23 kB gzipped](https://bundlephobia.com/package/speedy-entities).
4
5
 
5
6
  ```shell
6
7
  npm install --save-prod speedy-entities
7
8
  ```
8
9
 
9
- # Usage
10
+ # Decode
10
11
 
11
- ⚠️ [API documentation is available here.](https://smikhalevski.github.io/speedy-entities/)
12
-
13
- ## Preconfigured decoders
14
-
15
- There are two preconfigured decoders: `decodeXml` and `decodeHtml`.
12
+ There are two preconfigured decoders: `decodeXML` and `decodeHTML`.
16
13
 
17
14
  ```ts
18
- import {decodeXml, decodeHtml} from 'speedy-entities';
19
-
20
- decodeXml('ab<'); // → "ab&lt"
21
- decodeHtml('&ltfoo&AElig'); // → "<foo\u00c6"
22
- ```
23
-
24
- By default, `decodeHtml` supports only legacy HTML entities. This allowed to reduce the bundle size to just
25
- [2.3 kB gzipped](https://bundlephobia.com/package/speedy-entities).
26
-
27
- <details>
28
- <summary>The list of legacy HTML entities</summary>
29
- <p>
15
+ import { decodeXML, decodeHTML } from 'speedy-entities';
30
16
 
31
- > `aacute` `Aacute` `acirc` `Acirc` `acute` `aelig` `AElig` `agrave` `Agrave` `amp` `AMP` `aring` `Aring` `atilde`
32
- > `Atilde` `auml` `Auml` `brvbar` `ccedil` `Ccedil` `cedil` `cent` `copy` `COPY` `curren` `deg` `divide` `eacute`
33
- > `Eacute` `ecirc` `Ecirc` `egrave` `Egrave` `eth` `ETH` `euml` `Euml` `frac12` `frac14` `frac34` `gt` `GT` `iacute`
34
- > `Iacute` `icirc` `Icirc` `iexcl` `igrave` `Igrave` `iquest` `iuml` `Iuml` `laquo` `lt` `LT` `macr` `micro` `middot`
35
- > `nbsp` `not` `ntilde` `Ntilde` `oacute` `Oacute` `ocirc` `Ocirc` `ograve` `Ograve` `ordf` `ordm` `oslash` `Oslash`
36
- > `otilde` `Otilde` `ouml` `Ouml` `para` `plusmn` `pound` `quot` `QUOT` `raquo` `reg` `REG` `sect` `shy` `sup1` `sup2`
37
- > `sup3` `szlig` `thorn` `THORN` `times` `uacute` `Uacute` `ucirc` `Ucirc` `ugrave` `Ugrave` `uml` `uuml` `Uuml`
38
- > `yacute` `Yacute` `yen` `yuml`
17
+ decodeXML('&#X61;&#98;&lt');
18
+ // ⮕ 'ab&lt'
39
19
 
40
- </p>
41
- </details>
20
+ decodeHTML('&ltfoo&AElig');
21
+ // ⮕ '<foo\u00c6'
42
22
 
43
- To decode [all HTML entities](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references)
44
- import from `speedy-entities/lib/full`. The size of this bundle is 12.5 kB gzipped.
45
-
46
- ```ts
47
- import {decodeXml, decodeHtml} from 'speedy-entities/lib/full';
48
-
49
- decodeXml('&#X61;&#98;&lt;'); // → "ab&lt"
50
- decodeHtml('&NotNestedGreaterGreater;&CounterClockwiseContourIntegral;');
51
- // → "\u2aa2\u0338\u2233"
23
+ decodeHTML('&NotNestedGreaterGreater;&CounterClockwiseContourIntegral;');
24
+ // ⮕ '\u2aa2\u0338\u2233'
52
25
  ```
53
26
 
54
- You can manually add entities that `decodeXml` and `decodeHtml` would recognize:
27
+ ## Custom decoder
28
+
29
+ You can create a decoder that decodes custom named entities:
55
30
 
56
31
  ```ts
57
- import {decodeXml, decodeHtml, xmlEntityManager, htmlEntityManager} from 'speedy-entities';
32
+ import { arrayTrieEncode, trieCreate, trieSet } from '@smikhalevski/trie';
33
+ import { createEntityDecoder } from 'speedy-entities';
58
34
 
59
- xmlEntityManager.set('foo', 'okay');
60
- decodeXml('&foo;'); // → "okay"
35
+ // Create a trie that would hold entities
36
+ const trie = trieCreate<string>();
61
37
 
62
- htmlEntityManager.set('bar', 'nope');
63
- decodeHtml('&bar;'); // → "nope"
64
- ```
38
+ // Register named entities
39
+ trieSet('foo;', 'okay');
40
+ trieSet('qux;', 'yeah');
65
41
 
66
- ## Custom decoders
42
+ // Encode a trie
43
+ const entitiesTrie = arrayTrieEncode(trie);
67
44
 
68
- You can create a custom decoder that would recognize custom entities.
45
+ // Create a decoder
46
+ const decode = createEntityDecoder({
47
+ entitiesTrie,
48
+ numericReferenceSemicolonRequired: true,
49
+ });
69
50
 
70
- ```ts
71
- import {createEntityDecoder, createEntityManager} from 'speedy-entities';
51
+ // Decode entities
52
+ decode('&foo;');
53
+ // ⮕ 'okay'
72
54
 
73
- // Create an entity manager
74
- const entityManager = createEntityManager();
55
+ decode('&foo');
56
+ // ⮕ '&foo'
75
57
 
76
- // Register a new entity
77
- entityManager.set('foo', 'okay');
58
+ // Decode numeric character references
59
+ decode('&#X61;&#x62;&#x63;');
60
+ // ⮕ 'abc'
61
+ ```
78
62
 
79
- // Register a new legacy entity
80
- entityManager.set('bar', 'nope', true);
63
+ # Encode
81
64
 
82
- // Register a batch of entities
83
- entityManager.set({
84
- foo: 'okay',
85
- qux: 'yeah',
86
- });
65
+ `encodeXML` encodes non-ASCII characters as named XML entities or as numeric references.
87
66
 
88
- // Create a decoder
89
- const decode = createEntityDecoder(entityManager);
67
+ `escapeXML` escapes only `"&'<>` characters.
90
68
 
91
- // Decode non-legacy entities
92
- decode('&foo'); // → "&foo"
93
- decode('&foo;'); // → "okay"
69
+ ```ts
70
+ import { encodeXML, escapeXML } from 'speedy-entities';
94
71
 
95
- // Decode legacy entities
96
- decode('&bar'); // → "nope"
97
- decode('&bar;'); // → "nope"
72
+ encodeXML('&😘❤️');
73
+ // ⮕ '&amp;&#x1f618;&#x2764;&#xfe0f;'
98
74
 
99
- // Decode numeric character references
100
- decode('&#X61;&#x62;&#x63;'); // → "abc"
75
+ escapeXML('&😘❤️');
76
+ // ⮕ '&amp;😘❤'
101
77
  ```
102
78
 
103
79
  # Performance
@@ -106,13 +82,10 @@ Clone this repo and use `npm ci && npm run perf` to run the performance testsuit
106
82
 
107
83
  Results are in millions of operations per second. The higher number is better.
108
84
 
109
- | | speedy-entities <br/>`decodeXml` | [fb55/entities](https://github.com/fb55/entities) <br/>`decodeXML` | speedy-entities <br/>`decodeHtml` | [fb55/entities](https://github.com/fb55/entities) <br/>`decodeHTML` |
110
- | ----------------------------- | ---: | ---: | ---: | ---: |
111
- | `"&#X61;&#x62;&#x63;"` | 2.36 | 1.25 | 2.29 | 0.88 |
112
- | `"&#X61&#x62&#x63"` | 4.61 | 3.00 | 2.39 | 0.72 |
113
- | `"&#97;&#98;&#99;"` | 2.24 | 0.71 | 2.25 | 0.92 |
114
- | `"&#97&#98&#99"` | 5.09 | 3.07 | 2.21 | 0.88 |
115
- | `"&amp;&lt;&gt;"` | 3.98 | 1.28 | 3.34 | 1.06 |
116
- | `"&amp&lt&gt"` | 4.08 | 3.10 | 3.46 | 1.02 |
117
- | `"&NotNestedGreaterGreater;"` | 6.47 | 1.84 | 3.80 | 1.64 |
118
- | `"&NotNestedGreaterGreater"` | 6.44 | 2.74 | 4.00 | 2.41 |
85
+ ### Decode
86
+
87
+ ![Decode HTML performance chart](./images/perf-decode-html.svg)
88
+
89
+ ### Encode
90
+
91
+ ![Encode XML performance chart](./images/perf-encode-xml.svg)
package/lib/index.d.ts CHANGED
@@ -1,4 +1,42 @@
1
- export * from './createEntityDecoder';
2
- export * from './createEntityManager';
3
- export * from './decodeHtml';
4
- export * from './decodeXml';
1
+ import { ArrayTrie } from '@smikhalevski/trie';
2
+
3
+ /**
4
+ * The options recognized by {@linkcode createEntityDecoder}.
5
+ */
6
+ interface EntityDecoderOptions {
7
+ /**
8
+ * The trie of [character entity references](https://www.w3.org/TR/html4/charset.html#h-5.3.2).
9
+ */
10
+ entitiesTrie?: ArrayTrie<string>;
11
+ /**
12
+ * If `true` then [numeric character references](https://www.w3.org/TR/html4/charset.html#h-5.3.1) must be terminated
13
+ * with a semicolon to be decoded. Otherwise, numeric character references are recognized even if they aren't
14
+ * terminated with a semicolon.
15
+ *
16
+ * @default false
17
+ */
18
+ numericReferenceSemicolonRequired?: boolean;
19
+ }
20
+ /**
21
+ * Creates an entity decoder that rewrites numeric and named entities found in input to their respective values.
22
+ *
23
+ * @param options The decoder options.
24
+ * @returns A function that decodes entities in the string.
25
+ */
26
+ declare function createEntityDecoder(options?: EntityDecoderOptions): (input: string) => string;
27
+
28
+ /**
29
+ * Decodes all known HTML entities and numeric character references in the input.
30
+ */
31
+ declare const decodeHTML: (input: string) => string;
32
+
33
+ /**
34
+ * Decodes XML entities and numeric character references in the input.
35
+ */
36
+ declare const decodeXML: (input: string) => string;
37
+
38
+ declare function encodeXML(input: string): string;
39
+
40
+ declare function escapeXML(input: string): string;
41
+
42
+ export { EntityDecoderOptions, createEntityDecoder, decodeHTML, decodeXML, encodeXML, escapeXML };