@fastify/react 1.0.1 → 1.0.2

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
@@ -3,7 +3,7 @@
3
3
  "main": "index.js",
4
4
  "name": "@fastify/react",
5
5
  "description": "The official @fastify/vite renderer for React",
6
- "version": "1.0.1",
6
+ "version": "1.0.2",
7
7
  "files": [
8
8
  "plugin/index.js",
9
9
  "plugin/parsers.js",
@@ -51,7 +51,7 @@
51
51
  "unihead": "latest",
52
52
  "valtio": "latest",
53
53
  "youch": "^3.3.4",
54
- "@fastify/vite": "^8.0.2"
54
+ "@fastify/vite": "^8.0.5"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@biomejs/biome": "^1.9.2"
package/plugin/index.js CHANGED
@@ -12,7 +12,7 @@ import { closeBundle } from './preload.js'
12
12
  import { parseStateKeys } from './parsers.js'
13
13
  import { generateStores } from './stores.js'
14
14
 
15
- export default function viteFastifyVue () {
15
+ export default function viteFastifyReactPlugin () {
16
16
  const context = {
17
17
  root: null,
18
18
  }
@@ -23,12 +23,21 @@ export default function viteFastifyVue () {
23
23
  config,
24
24
  configResolved: configResolved.bind(context),
25
25
  resolveId: resolveId.bind(context),
26
+ configEnvironment (name, config, { mode }) {
27
+ if (mode === 'production') {
28
+ config.build.minify = true
29
+ config.build.sourcemap = false
30
+ }
31
+ if (name === 'ssr') {
32
+ config.build.manifest = false
33
+ }
34
+ },
26
35
  async load (id) {
27
- if (id.includes('?server') && !context.resolvedConfig.build.ssr) {
36
+ if (id.includes('?server') && !this.environment.config.build?.ssr) {
28
37
  const source = loadSource(id)
29
38
  return createPlaceholderExports(source)
30
39
  }
31
- if (id.includes('?client') && context.resolvedConfig.build.ssr) {
40
+ if (id.includes('?client') && this.environment.config.build?.ssr) {
32
41
  const source = loadSource(id)
33
42
  return createPlaceholderExports(source)
34
43
  }
@@ -51,7 +60,9 @@ export default function viteFastifyVue () {
51
60
  order: 'post',
52
61
  handler: transformIndexHtml.bind(context)
53
62
  },
54
- closeBundle: closeBundle.bind(context),
63
+ closeBundle () {
64
+ closeBundle.call(this, context.resolvedBundle)
65
+ },
55
66
  }]
56
67
  }
57
68
 
package/plugin/preload.js CHANGED
@@ -1,46 +1,52 @@
1
- import { writeFileSync, mkdirSync, existsSync } from 'node:fs'
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
2
2
  import { join, parse as parsePath } from 'node:path'
3
3
  import { HTMLRewriter } from 'html-rewriter-wasm'
4
4
 
5
- const imageFile = /\.((png)|(jpg)|(svg)|(webp)|(gif))$/
5
+ const imageFileRE = /\.((png)|(jpg)|(svg)|(webp)|(gif))$/
6
6
 
7
- export async function closeBundle() {
8
- if (!this.resolvedConfig.build.ssr) {
9
- const distDir = join(this.root, this.resolvedConfig.build.outDir)
10
- const pages = Object.fromEntries(
11
- Object.entries(this.resolvedBundle ?? {})
12
- .filter(([id, meta]) => {
13
- if (meta.facadeModuleId?.includes('/pages/')) {
14
- meta.htmlPath = meta.facadeModuleId.replace(/.*pages\/(.*)\.jsx$/, 'html/$1.html')
15
- return true
16
- }
17
- })
18
- )
19
- for (const page of Object.values(pages)) {
20
- const jsImports = page.imports
21
- const cssImports = page.viteMetadata.importedCss
22
- const images = page.moduleIds.filter(_ => imageFile.test(_))
23
- let imagePreloads = '\n'
24
- for (let image of images) {
25
- image = image.slice(this.root.length + 1)
26
- imagePreloads += ` <link rel="preload" as="image" href="${this.resolvedConfig.base}${image}">\n`
27
- }
28
- let cssPreloads = ''
29
- for (const css of cssImports) {
30
- cssPreloads += ` <link rel="preload" as="style" href="${this.resolvedConfig.base}${css}">\n`
31
- }
32
- let jsPreloads = ''
33
- for (const js of jsImports) {
34
- jsPreloads += ` <link rel="modulepreload" href="${this.resolvedConfig.base}${js}">\n`
35
- }
36
- const pageHtml = await appendHead(
37
- this.indexHtml,
38
- imagePreloads,
39
- cssPreloads,
40
- jsPreloads
41
- )
42
- writeHtml(page, pageHtml, distDir)
7
+ export async function closeBundle(resolvedBundle) {
8
+ if (this.environment.name !== 'client') {
9
+ return
10
+ }
11
+ const { assetsInlineLimit } = this.environment.config.build
12
+ const { root, base } = this.environment.config
13
+ const distDir = join(root, this.environment.config.build.outDir)
14
+ const indexHtml = readFileSync(join(distDir, 'index.html'), 'utf8')
15
+ const pages = Object.fromEntries(
16
+ Object.entries(resolvedBundle ?? {})
17
+ .filter(([id, meta]) => {
18
+ if (meta.facadeModuleId?.includes('/pages/')) {
19
+ meta.htmlPath = meta.facadeModuleId.replace(/.*pages\/(.*)\.jsx$/, 'html/$1.html')
20
+ return true
21
+ }
22
+ })
23
+ )
24
+ for (const page of Object.values(pages)) {
25
+ const jsImports = page.imports
26
+ const cssImports = page.viteMetadata.importedCss
27
+ const images = page.moduleIds.filter((img) => {
28
+ return (page.modules[img].originalLength > assetsInlineLimit) && imageFileRE.test(img)
29
+ })
30
+ let imagePreloads = '\n'
31
+ for (let image of images) {
32
+ image = image.slice(root.length + 1)
33
+ imagePreloads += ` <link rel="preload" as="image" crossorigin href="${base}${image}">\n`
34
+ }
35
+ let cssPreloads = ''
36
+ for (const css of cssImports) {
37
+ cssPreloads += ` <link rel="preload" as="style" crossorigin href="${base}${css}">\n`
43
38
  }
39
+ let jsPreloads = ''
40
+ for (const js of jsImports) {
41
+ jsPreloads += ` <link rel="modulepreload" crossorigin href="${base}${js}">\n`
42
+ }
43
+ const pageHtml = await appendHead(
44
+ indexHtml,
45
+ imagePreloads,
46
+ cssPreloads,
47
+ jsPreloads
48
+ )
49
+ writeHtml(page, pageHtml, distDir)
44
50
  }
45
51
  }
46
52
 
package/plugin/stores.js CHANGED
@@ -11,7 +11,7 @@ function storeGetter (proxy, prop) {
11
11
  return proxy.context.state[proxy.key]
12
12
  }
13
13
  let method
14
- if (method = proxy.context.actions[proxy.key][prop]) {
14
+ if (method = proxy.context.actions?.[proxy.key]?.[prop]) {
15
15
  if (!proxy.wrappers[prop]) {
16
16
  proxy.wrappers[prop] = (...args) => {
17
17
  return method(proxy.context.state, ...args)
package/plugin/virtual.js CHANGED
@@ -23,6 +23,11 @@ const virtualModules = [
23
23
  export const prefix = /^\/?\$app\//
24
24
 
25
25
  export async function resolveId (id) {
26
+ // Paths are prefixed with .. on Windows by the glob import
27
+ if (process.platform === 'win32' && /^\.\.\/[C-Z]:/.test(id)) {
28
+ return id.substring(3)
29
+ }
30
+
26
31
  if (prefix.test(id)) {
27
32
  const [, virtual] = id.split(prefix)
28
33
  if (virtual) {
package/routing.js CHANGED
@@ -120,12 +120,13 @@ export async function createRoute ({ client, errorHandler, route }, scope, confi
120
120
  // Replace wildcard routes with Fastify compatible syntax
121
121
  const routePath = route.path.replace(/:[^+]+\+/, '*')
122
122
 
123
+ unshiftHook(route, 'onRequest', onRequest)
124
+ unshiftHook(route, 'preHandler', preHandler)
125
+
123
126
  scope.route({
124
127
  url: routePath,
125
128
  method: route.method ?? ['GET', 'POST', 'PUT', 'DELETE'],
126
129
  errorHandler,
127
- onRequest,
128
- preHandler,
129
130
  handler,
130
131
  ...route,
131
132
  })
@@ -140,3 +141,16 @@ export async function createRoute ({ client, errorHandler, route }, scope, confi
140
141
  })
141
142
  }
142
143
  }
144
+
145
+ function unshiftHook (route, hookName, hook) {
146
+ if (!route[hookName]) {
147
+ route[hookName] = []
148
+ }
149
+ if (!Array.isArray(hook)) {
150
+ hook = [hook]
151
+ }
152
+ if (!Array.isArray(route[hookName])) {
153
+ route[hookName] = [route[hookName]]
154
+ }
155
+ route[hookName] = [...route[hookName], ...hook]
156
+ }
package/server.js CHANGED
@@ -117,6 +117,19 @@ function getRouteModuleExports (routeModule) {
117
117
  streaming: routeModule.streaming,
118
118
  clientOnly: routeModule.clientOnly,
119
119
  serverOnly: routeModule.serverOnly,
120
+ // Server configure function
121
+ configure: routeModule.configure,
122
+ // Route-level Fastify hooks
123
+ onRequest: routeModule.onRequest ?? undefined,
124
+ preParsing: routeModule.preParsing ?? undefined,
125
+ preValidation: routeModule.preValidation ?? undefined,
126
+ preHandler: routeModule.preHandler ?? undefined,
127
+ preSerialization: routeModule.preSerialization ?? undefined,
128
+ onError: routeModule.onError ?? undefined,
129
+ onSend: routeModule.onSend ?? undefined,
130
+ onResponse: routeModule.onResponse ?? undefined,
131
+ onTimeout: routeModule.onTimeout ?? undefined,
132
+ onRequestAbort: routeModule.onRequestAbort ?? undefined,
120
133
  }
121
134
  }
122
135