ghtml 3.0.5 → 3.0.7

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ta**ghtml** lets you replace your template engine with fast JavaScript by leveraging the power of tagged templates.
4
4
 
5
- Works in the browser. No runtime dependencies. [~30x faster than React. ~10x faster than common-tags.](#benchmarks)
5
+ Works in the browser. No runtime dependencies. [Faster than React & Co. ~3x faster than EJS and ~13x faster than common-tags.](#benchmarks)
6
6
 
7
7
  ![ghtml.gif](./ghtml.gif)
8
8
 
@@ -181,7 +181,11 @@ console.log(logo);
181
181
 
182
182
  ## Benchmarks
183
183
 
184
- Latest results [from Kita](https://github.com/kitajs/html/tree/cb7950c68489ff70dd0b0c130c9b70046c1543ea/benchmarks):
184
+ Latest results from [Platformatic's SSR Showdown](https://blog.platformatic.dev/ssr-performance-showdown) (fastify-html is ghtml):
185
+
186
+ ![ghtml-perf.png](./ghtml-perf.png)
187
+
188
+ Latest results from [KitaJS HTML](https://github.com/kitajs/html/tree/cb7950c68489ff70dd0b0c130c9b70046c1543ea/benchmarks):
185
189
 
186
190
  ```sh
187
191
  benchmark time (avg) (min … max) p75 p99 p999
package/bin/src/utils.js CHANGED
@@ -74,7 +74,7 @@ const updateFilePathsWithHashes = async (
74
74
  }
75
75
  };
76
76
 
77
- const generateHashesAndReplace = async ({
77
+ export const generateHashesAndReplace = async ({
78
78
  roots,
79
79
  refs,
80
80
  prefix,
@@ -124,5 +124,3 @@ const generateHashesAndReplace = async ({
124
124
  skipPatterns,
125
125
  );
126
126
  };
127
-
128
- export { generateHashesAndReplace };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Replace your template engine with fast JavaScript by leveraging the power of tagged templates.",
4
4
  "author": "Gürgün Dayıoğlu",
5
5
  "license": "MIT",
6
- "version": "3.0.5",
6
+ "version": "3.0.7",
7
7
  "type": "module",
8
8
  "bin": "./bin/src/index.js",
9
9
  "main": "./src/index.js",
package/src/html.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export function html({ raw: literals }: TemplateStringsArray, ...expressions: any[]): string;
2
- export function htmlGenerator({ raw: literals }: TemplateStringsArray, ...expressions: any[]): Generator<string, void, void>;
3
- export function htmlAsyncGenerator({ raw: literals }: TemplateStringsArray, ...expressions: any[]): AsyncGenerator<string, void, void>;
1
+ export function html(literals: TemplateStringsArray, ...expressions: any[]): string;
2
+ export function htmlGenerator(literals: TemplateStringsArray, ...expressions: any[]): Generator<string, void, void>;
3
+ export function htmlAsyncGenerator(literals: TemplateStringsArray, ...expressions: any[]): AsyncGenerator<string, void, void>;
package/src/html.js CHANGED
@@ -1,57 +1,50 @@
1
1
  const escapeRegExp = /["&'<=>]/g;
2
2
 
3
3
  const escapeFunction = (string) => {
4
- if (!string || !escapeRegExp.test(string)) {
5
- return string;
6
- }
7
-
8
4
  let escaped = "";
9
5
  let start = 0;
10
6
 
11
- do {
7
+ while (escapeRegExp.test(string)) {
12
8
  const i = escapeRegExp.lastIndex - 1;
13
9
 
14
10
  switch (string.charCodeAt(i)) {
15
11
  case 34: // "
16
12
  escaped += string.slice(start, i) + "&#34;";
17
- start = escapeRegExp.lastIndex;
18
- continue;
13
+ break;
19
14
  case 38: // &
20
15
  escaped += string.slice(start, i) + "&#38;";
21
- start = escapeRegExp.lastIndex;
22
- continue;
16
+ break;
23
17
  case 39: // '
24
18
  escaped += string.slice(start, i) + "&#39;";
25
- start = escapeRegExp.lastIndex;
26
- continue;
19
+ break;
27
20
  case 60: // <
28
21
  escaped += string.slice(start, i) + "&#60;";
29
- start = escapeRegExp.lastIndex;
30
- continue;
22
+ break;
31
23
  case 61: // =
32
24
  escaped += string.slice(start, i) + "&#61;";
33
- start = escapeRegExp.lastIndex;
34
- continue;
25
+ break;
35
26
  case 62: // >
36
27
  escaped += string.slice(start, i) + "&#62;";
37
- start = escapeRegExp.lastIndex;
38
- continue;
28
+ break;
39
29
  }
40
- } while (escapeRegExp.test(string));
30
+
31
+ start = escapeRegExp.lastIndex;
32
+ }
41
33
 
42
34
  return escaped + string.slice(start);
43
35
  };
44
36
 
45
37
  /**
38
+ * The `html` function is designed to tag template literals and automatically escape their expressions.
46
39
  * @param {TemplateStringsArray} literals Tagged template literals.
47
40
  * @param {...any} expressions Expressions to interpolate.
48
41
  * @returns {string} The processed HTML string.
49
42
  */
50
- export const html = ({ raw: literals }, ...expressions) => {
43
+ export const html = (literals, ...expressions) => {
51
44
  let accumulator = "";
52
45
 
53
46
  for (let i = 0; i !== expressions.length; ++i) {
54
- let literal = literals[i];
47
+ let literal = literals.raw[i];
55
48
  let string =
56
49
  typeof expressions[i] === "string"
57
50
  ? expressions[i]
@@ -64,25 +57,26 @@ export const html = ({ raw: literals }, ...expressions) => {
64
57
  if (literal && literal.charCodeAt(literal.length - 1) === 33) {
65
58
  literal = literal.slice(0, -1);
66
59
  } else {
67
- string = escapeFunction(string);
60
+ string &&= escapeFunction(string);
68
61
  }
69
62
 
70
63
  accumulator += literal + string;
71
64
  }
72
65
 
73
- return accumulator + literals[expressions.length];
66
+ return accumulator + literals.raw[expressions.length];
74
67
  };
75
68
 
76
69
  /**
70
+ * The `htmlGenerator` function acts as the generator version of the `html` function.
77
71
  * @param {TemplateStringsArray} literals Tagged template literals.
78
72
  * @param {...any} expressions Expressions to interpolate.
79
73
  * @yields Processed HTML strings.
80
74
  * @returns {Generator<string, void, void>} The HTML generator.
81
75
  */
82
- export const htmlGenerator = function* ({ raw: literals }, ...expressions) {
76
+ export const htmlGenerator = function* (literals, ...expressions) {
83
77
  for (let i = 0; i !== expressions.length; ++i) {
84
78
  let expression = expressions[i];
85
- let literal = literals[i];
79
+ let literal = literals.raw[i];
86
80
  let string;
87
81
 
88
82
  if (typeof expression === "string") {
@@ -122,11 +116,11 @@ export const htmlGenerator = function* ({ raw: literals }, ...expressions) {
122
116
  string = `${expression}`;
123
117
  }
124
118
 
125
- if (!isRaw) {
126
- string = escapeFunction(string);
127
- }
128
-
129
119
  if (string) {
120
+ if (!isRaw) {
121
+ string = escapeFunction(string);
122
+ }
123
+
130
124
  yield string;
131
125
  }
132
126
  }
@@ -137,11 +131,11 @@ export const htmlGenerator = function* ({ raw: literals }, ...expressions) {
137
131
  string = `${expression}`;
138
132
  }
139
133
 
140
- if (!isRaw) {
141
- string = escapeFunction(string);
142
- }
143
-
144
134
  if (string) {
135
+ if (!isRaw) {
136
+ string = escapeFunction(string);
137
+ }
138
+
145
139
  yield string;
146
140
  }
147
141
  }
@@ -155,7 +149,7 @@ export const htmlGenerator = function* ({ raw: literals }, ...expressions) {
155
149
  if (literal && literal.charCodeAt(literal.length - 1) === 33) {
156
150
  literal = literal.slice(0, -1);
157
151
  } else {
158
- string = escapeFunction(string);
152
+ string &&= escapeFunction(string);
159
153
  }
160
154
 
161
155
  if (literal || string) {
@@ -163,24 +157,22 @@ export const htmlGenerator = function* ({ raw: literals }, ...expressions) {
163
157
  }
164
158
  }
165
159
 
166
- if (literals[expressions.length]) {
167
- yield literals[expressions.length];
160
+ if (literals.raw[expressions.length]) {
161
+ yield literals.raw[expressions.length];
168
162
  }
169
163
  };
170
164
 
171
165
  /**
166
+ * This version of HTML generator should be preferred for asynchronous and streaming use cases.
172
167
  * @param {TemplateStringsArray} literals Tagged template literals.
173
168
  * @param {...any} expressions Expressions to interpolate.
174
169
  * @yields Processed HTML strings.
175
170
  * @returns {AsyncGenerator<string, void, void>} The HTML generator.
176
171
  */
177
- export const htmlAsyncGenerator = async function* (
178
- { raw: literals },
179
- ...expressions
180
- ) {
172
+ export const htmlAsyncGenerator = async function* (literals, ...expressions) {
181
173
  for (let i = 0; i !== expressions.length; ++i) {
182
174
  let expression = await expressions[i];
183
- let literal = literals[i];
175
+ let literal = literals.raw[i];
184
176
  let string;
185
177
 
186
178
  if (typeof expression === "string") {
@@ -223,11 +215,11 @@ export const htmlAsyncGenerator = async function* (
223
215
  string = `${expression}`;
224
216
  }
225
217
 
226
- if (!isRaw) {
227
- string = escapeFunction(string);
228
- }
229
-
230
218
  if (string) {
219
+ if (!isRaw) {
220
+ string = escapeFunction(string);
221
+ }
222
+
231
223
  yield string;
232
224
  }
233
225
  }
@@ -238,11 +230,11 @@ export const htmlAsyncGenerator = async function* (
238
230
  string = `${expression}`;
239
231
  }
240
232
 
241
- if (!isRaw) {
242
- string = escapeFunction(string);
243
- }
244
-
245
233
  if (string) {
234
+ if (!isRaw) {
235
+ string = escapeFunction(string);
236
+ }
237
+
246
238
  yield string;
247
239
  }
248
240
  }
@@ -256,7 +248,7 @@ export const htmlAsyncGenerator = async function* (
256
248
  if (literal && literal.charCodeAt(literal.length - 1) === 33) {
257
249
  literal = literal.slice(0, -1);
258
250
  } else {
259
- string = escapeFunction(string);
251
+ string &&= escapeFunction(string);
260
252
  }
261
253
 
262
254
  if (literal || string) {
@@ -264,7 +256,7 @@ export const htmlAsyncGenerator = async function* (
264
256
  }
265
257
  }
266
258
 
267
- if (literals[expressions.length]) {
268
- yield literals[expressions.length];
259
+ if (literals.raw[expressions.length]) {
260
+ yield literals.raw[expressions.length];
269
261
  }
270
262
  };