@wix/origami-site-express 0.1.2 → 0.1.4

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
@@ -18,3 +18,5 @@ through Vite; set `HOST=0.0.0.0` to reach it from another machine or a container
18
18
  - In dev each request imports the core through Vite's module runner, so a linked core reloads on edit
19
19
  without a restart. An installed core loads once.
20
20
  - HMR runs on the site's own port (`server.ws.server`).
21
+ - The page's essential Wix custom embeds (`resolution.embeds`) go at the end of `<head>`, first in `<body>` and
22
+ last in `<body>`; in dev after `vite.transformIndexHtml`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/origami-site-express",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Run an exported Wix origami site on Node with Express and Vite.",
5
5
  "type": "module",
6
6
  "files": [
@@ -65,5 +65,5 @@
65
65
  ]
66
66
  }
67
67
  },
68
- "falconPackageHash": "3470a27832e07e4b9235a2df50d0c09302d980f76639e8987884ee39"
68
+ "falconPackageHash": "c747f0aab95a2845e2ad63b387beb5dde7b4e28c62baceff7b05fc63"
69
69
  }
@@ -12,7 +12,7 @@ async function spawnBin(command, root, env) {
12
12
  const { spawn } = await import('node:child_process')
13
13
  const child = spawn(process.execPath, [binPath(root), command], {
14
14
  cwd: root, stdio: ['ignore', 'pipe', 'pipe'],
15
- env: { ...process.env, ...env, ...(command === 'start' ? { NODE_ENV: 'production' } : {}) },
15
+ env: { ...process.env, ...env, ...(command === 'dev' ? {} : { NODE_ENV: 'production' }) },
16
16
  })
17
17
  let output = ''
18
18
  child.stdout.on('data', chunk => { output += chunk })
package/src/server/dev.js CHANGED
@@ -4,7 +4,7 @@ import { createServer as createViteServer, isRunnableDevEnvironment, loadEnv } f
4
4
  import react from '@vitejs/plugin-react'
5
5
  import { coreEntry, importCoreBuild, importCoreNode, importCoreServer } from './core.js'
6
6
  import { catchAll } from './bridge.js'
7
- import { pageHtml } from './shell.js'
7
+ import { pageHtml, plantEmbeds } from './shell.js'
8
8
  import { host, port, siteOptions } from './env.js'
9
9
  import { serve } from './lifecycle.js'
10
10
  import { createCurrentSite } from './currentSite.js'
@@ -12,7 +12,7 @@ import { createCurrentSite } from './currentSite.js'
12
12
  /** `origami-site-express dev`: Vite in middleware mode, Express, and the core in dev mode, all live.
13
13
  * @param {{ root: string }} options */
14
14
  export async function dev({ root }) {
15
- const env = loadEnv('development', root, ['VITE_', 'ORIGAMI_'])
15
+ const env = loadEnv('development', root, ['VITE_', 'ORIGAMI_', 'PORT', 'HOST'])
16
16
  const { errorResponse, serializePageData } = await importCoreServer(root)
17
17
  const { origamiVitePlugins } = await importCoreBuild(root)
18
18
  const node = await importCoreNode(root)
@@ -41,11 +41,11 @@ export async function dev({ root }) {
41
41
  app.use(vite.middlewares)
42
42
  app.use(catchAll({
43
43
  mode: 'dev', errorResponse, node, getSite: currentSite,
44
- renderPage: (resolution, request) => vite.transformIndexHtml(new URL(request.url).pathname, pageHtml(resolution, {
44
+ renderPage: async (resolution, request) => plantEmbeds(await vite.transformIndexHtml(new URL(request.url).pathname, pageHtml(resolution, {
45
45
  serializePageData,
46
46
  body: '<script type="module" src="/src/site/_generated/client.jsx"></script>',
47
- })),
47
+ })), resolution.embeds),
48
48
  }))
49
49
  httpServer.on('request', app)
50
- await serve(httpServer, { port: port(), host: host('dev'), onClose: async () => { await vite.close(); await site()?.close() } })
50
+ await serve(httpServer, { port: port(env), host: host('dev', env), onClose: async () => { await vite.close(); await site()?.close() } })
51
51
  }
package/src/server/env.js CHANGED
@@ -7,9 +7,10 @@ export function siteOptions(env) {
7
7
  }
8
8
  }
9
9
 
10
- export const port = () => Number(process.env.PORT ?? 3000)
10
+ /** An empty PORT= means the default, not a random port. @param {Record<string, string | undefined>} [env] */
11
+ export const port = (env = process.env) => Number(env.PORT || 3000)
11
12
 
12
13
  /** Dev serves the site's source through Vite, so it stays on this machine unless HOST says otherwise.
13
14
  * 127.0.0.1, not localhost: on macOS localhost binds only ::1. Start listens on every interface so the deployed site is reachable.
14
- * @param {'dev' | 'prod'} mode */
15
- export const host = mode => process.env.HOST || (mode === 'dev' ? '127.0.0.1' : undefined)
15
+ * @param {'dev' | 'prod'} mode @param {Record<string, string | undefined>} [env] */
16
+ export const host = (mode, env = process.env) => env.HOST || (mode === 'dev' ? '127.0.0.1' : undefined)
@@ -4,7 +4,7 @@ import { join } from 'node:path'
4
4
  import express from 'express'
5
5
  import { importCoreNode, importCoreServer } from './core.js'
6
6
  import { catchAll } from './bridge.js'
7
- import { pageHtml } from './shell.js'
7
+ import { pageHtml, plantEmbeds } from './shell.js'
8
8
  import { readManifest } from './manifest.js'
9
9
  import { port, siteOptions } from './env.js'
10
10
  import { serve } from './lifecycle.js'
@@ -26,7 +26,7 @@ export async function start({ root }) {
26
26
  app.use(express.static(join(root, 'dist/client'), { index: false, redirect: false }))
27
27
  app.use(catchAll({
28
28
  mode: 'prod', errorResponse, node, getSite: async () => site,
29
- renderPage: async resolution => pageHtml(resolution, { serializePageData, ...assetsFor(resolution.page) }),
29
+ renderPage: async resolution => plantEmbeds(pageHtml(resolution, { serializePageData, ...assetsFor(resolution.page) }), resolution.embeds),
30
30
  }))
31
31
  await serve(createServer(app), { port: port(), onClose: () => site.close() })
32
32
  }
@@ -21,3 +21,16 @@ export function pageHtml({ page, data }, { serializePageData, head = '', body })
21
21
  </body>
22
22
  </html>`
23
23
  }
24
+
25
+ /** Plants the page's Wix embeds at the end of <head>, the start of <body> and the end of <body>. Positions are
26
+ * found in the shell before anything is inserted, so embed HTML can never move the next slot. In dev this runs
27
+ * after vite.transformIndexHtml, so Vite never rewrites an embed's inline scripts.
28
+ * @param {string} html @param {import('@wix/origami-site/types').PageEmbeds | undefined} embeds */
29
+ export function plantEmbeds(html, embeds) {
30
+ if (!embeds || (!embeds.head && !embeds.bodyStart && !embeds.bodyEnd)) return html
31
+ const headEnd = html.indexOf('</head>')
32
+ const bodyStart = html.indexOf('>', html.indexOf('<body')) + 1
33
+ const bodyEnd = html.lastIndexOf('</body>')
34
+ return html.slice(0, headEnd) + `${embeds.head}\n ` + html.slice(headEnd, bodyStart) + `\n${embeds.bodyStart}` +
35
+ html.slice(bodyStart, bodyEnd) + `${embeds.bodyEnd}\n ` + html.slice(bodyEnd)
36
+ }