@fastify/react 1.1.5 → 1.1.6-rc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastify/react",
3
- "version": "1.1.5",
3
+ "version": "1.1.6-rc.0",
4
4
  "description": "The official @fastify/vite renderer for React",
5
5
  "keywords": [
6
6
  "fastify",
@@ -67,9 +67,8 @@
67
67
  "acorn": "^8.14.1",
68
68
  "acorn-strip-function": "^1.2.0",
69
69
  "acorn-walk": "^8.3.4",
70
- "devalue": "^5.6.1",
70
+ "devalue": "^5.6.2",
71
71
  "history": "latest",
72
- "html-rewriter-wasm": "^0.4.1",
73
72
  "minipass": "latest",
74
73
  "mlly": "^1.7.4",
75
74
  "react": "^19.2.3",
@@ -77,7 +76,7 @@
77
76
  "react-router": "^7.12.0",
78
77
  "valtio": "latest",
79
78
  "youch": "^3.3.4",
80
- "@fastify/vite": "^8.4.0"
79
+ "@fastify/vite": "^9.0.0-rc.0"
81
80
  },
82
81
  "scripts": {}
83
82
  }
package/plugin/index.js CHANGED
@@ -1,5 +1,3 @@
1
- import { readFileSync, existsSync } from 'node:fs'
2
- import { join } from 'node:path'
3
1
  import viteFastify from '@fastify/vite/plugin'
4
2
  import {
5
3
  prefix,
@@ -9,8 +7,6 @@ import {
9
7
  createPlaceholderExports,
10
8
  } from './virtual.js'
11
9
  import { closeBundle } from './preload.js'
12
- import { parseStateKeys } from './parsers.js'
13
- import { generateStores } from './stores.js'
14
10
 
15
11
  export default function viteFastifyReactPlugin({ ts } = {}) {
16
12
  const context = {
@@ -1,7 +1,7 @@
1
1
  import test from 'node:test'
2
2
  import assert from 'node:assert'
3
3
 
4
- test('parseStateKeys', (t) => {
4
+ test('parseStateKeys', () => {
5
5
  const a = `export function state () {
6
6
  return {
7
7
  user: {
package/plugin/preload.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
2
2
  import { join, isAbsolute, parse as parsePath } from 'node:path'
3
- import { HTMLRewriter } from 'html-rewriter-wasm'
4
3
 
5
4
  const imageFileRE = /\.((png)|(jpg)|(svg)|(webp)|(gif))$/
6
5
 
@@ -18,7 +17,7 @@ export async function closeBundle(resolvedBundle) {
18
17
  }
19
18
  const indexHtml = readFileSync(join(distDir, 'index.html'), 'utf8')
20
19
  const pages = Object.fromEntries(
21
- Object.entries(resolvedBundle ?? {}).filter(([id, meta]) => {
20
+ Object.entries(resolvedBundle ?? {}).filter(([, meta]) => {
22
21
  if (meta.facadeModuleId?.includes('/pages/')) {
23
22
  meta.htmlPath = meta.facadeModuleId.replace(/.*pages\/(.*)\.(j|t)sx$/, 'html/$1.html')
24
23
  return true
@@ -44,30 +43,14 @@ export async function closeBundle(resolvedBundle) {
44
43
  for (const js of jsImports) {
45
44
  jsPreloads += ` <link rel="modulepreload" crossorigin href="${base}${js}">\n`
46
45
  }
47
- const pageHtml = await appendHead(indexHtml, imagePreloads, cssPreloads, jsPreloads)
46
+ const pageHtml = appendHead(indexHtml, imagePreloads, cssPreloads, jsPreloads)
48
47
  writeHtml(page, pageHtml, distDir)
49
48
  }
50
49
  }
51
50
 
52
- async function appendHead(html, ...tags) {
53
- const encoder = new TextEncoder()
54
- const decoder = new TextDecoder()
55
- let output = ''
56
- const rewriter = new HTMLRewriter((outputChunk) => {
57
- output += decoder.decode(outputChunk)
58
- })
59
- rewriter.on('head', {
60
- element(element) {
61
- element.prepend(tags.join('\n '), { html: true })
62
- },
63
- })
64
- try {
65
- await rewriter.write(encoder.encode(html))
66
- await rewriter.end()
67
- return output
68
- } finally {
69
- rewriter.free()
70
- }
51
+ function appendHead(html, ...tags) {
52
+ const content = tags.join('\n ')
53
+ return html.replace(/<head([^>]*)>/i, `<head$1>\n ${content}`)
71
54
  }
72
55
 
73
56
  function writeHtml(page, pageHtml, distDir) {
package/rendering.js CHANGED
@@ -75,7 +75,7 @@ async function createResponse(req, routes) {
75
75
  export async function createHtmlFunction(source, _, config) {
76
76
  // Creates `universal` and `serverOnly` sets of
77
77
  // HTML `beforeElement` and `afterElement` templates
78
- const templates = await createHtmlTemplates(source, config)
78
+ const templates = createHtmlTemplates(source, config)
79
79
 
80
80
  // Registered as reply.html()
81
81
  return async function () {
package/routing.js CHANGED
@@ -106,6 +106,7 @@ export async function createRoute({ client, errorHandler, route }, scope, config
106
106
  } else {
107
107
  const { id } = route
108
108
  const htmlPath = id.replace('pages/', 'html/').replace(/\.(j|t)sx$/, '.html')
109
+ // TODO: Switch to config.viteConfig once deprecated config.vite alias is removed.
109
110
  let distDir = config.vite.build.outDir
110
111
  if (!isAbsolute(config.vite.build.outDir)) {
111
112
  distDir = join(config.vite.root, distDir)
package/templating.js CHANGED
@@ -1,51 +1,28 @@
1
1
  import { createHtmlTemplateFunction } from '@fastify/vite/utils'
2
- import { HTMLRewriter } from 'html-rewriter-wasm'
3
2
 
4
- export async function createHtmlTemplates(source, config) {
3
+ const moduleScriptPattern = /<script\s[^>]*\btype\s*=\s*["']module["'][^>]*>[\s\S]*?<\/script>/gi
4
+
5
+ export function createHtmlTemplates(source, config) {
5
6
  const el = '<!-- element -->'
6
7
 
7
8
  const universal = source.split(el)
8
- const serverOnlyRaw = await removeClientModule(source, config)
9
+ const serverOnlyRaw = removeClientModule(source, config)
9
10
  const serverOnly = serverOnlyRaw.split(el)
10
11
 
11
12
  return {
12
13
  // Templates for client-only and universal rendering
13
14
  universal: {
14
- beforeElement: await createHtmlTemplateFunction(universal[0]),
15
- afterElement: await createHtmlTemplateFunction(universal[1]),
15
+ beforeElement: createHtmlTemplateFunction(universal[0]),
16
+ afterElement: createHtmlTemplateFunction(universal[1]),
16
17
  },
17
18
  // Templates for server-only rendering
18
19
  serverOnly: {
19
- beforeElement: await createHtmlTemplateFunction(serverOnly[0]),
20
- afterElement: await createHtmlTemplateFunction(serverOnly[1]),
20
+ beforeElement: createHtmlTemplateFunction(serverOnly[0]),
21
+ afterElement: createHtmlTemplateFunction(serverOnly[1]),
21
22
  },
22
23
  }
23
24
  }
24
25
 
25
- async function removeClientModule(html, config) {
26
- const decoder = new TextDecoder()
27
-
28
- let output = ''
29
- const rewriter = new HTMLRewriter((outputChunk) => {
30
- output += decoder.decode(outputChunk)
31
- })
32
-
33
- rewriter.on('script', {
34
- element(element) {
35
- for (const [attr, value] of element.attributes) {
36
- if (attr === 'type' && value === 'module') {
37
- element.replace('')
38
- }
39
- }
40
- },
41
- })
42
-
43
- try {
44
- const encoder = new TextEncoder()
45
- await rewriter.write(encoder.encode(html))
46
- await rewriter.end()
47
- return output
48
- } finally {
49
- rewriter.free()
50
- }
26
+ function removeClientModule(html) {
27
+ return html.replace(moduleScriptPattern, '')
51
28
  }