@ossy/app 1.8.0 → 1.10.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/cli/build.js +19 -38
- package/cli/dev.js +15 -4
- package/cli/prerender-react.task.js +270 -0
- package/cli/server.js +3 -48
- package/package.json +10 -10
package/cli/build.js
CHANGED
|
@@ -11,6 +11,7 @@ import nodeExternals from 'rollup-plugin-node-externals'
|
|
|
11
11
|
import copy from 'rollup-plugin-copy';
|
|
12
12
|
import replace from '@rollup/plugin-replace';
|
|
13
13
|
import arg from 'arg'
|
|
14
|
+
import prerenderReactTask from './prerender-react.task.js'
|
|
14
15
|
|
|
15
16
|
export const PAGE_FILE_PATTERN = /\.page\.(jsx?|tsx?)$/
|
|
16
17
|
export const API_FILE_PATTERN = /\.api\.(mjs|cjs|js)$/
|
|
@@ -23,7 +24,7 @@ export const OSSY_RESOURCE_TEMPLATES_OUT = '.ossy-system-templates.generated.js'
|
|
|
23
24
|
/** Rollup output paths for JS served to the browser (see `entryFileNames` / `chunkFileNames`). */
|
|
24
25
|
const BROWSER_STATIC_PREFIX = 'public/static/'
|
|
25
26
|
|
|
26
|
-
function minifyBrowserStaticChunks () {
|
|
27
|
+
export function minifyBrowserStaticChunks () {
|
|
27
28
|
return {
|
|
28
29
|
name: 'minify-browser-static-chunks',
|
|
29
30
|
async renderChunk (code, chunk, outputOptions) {
|
|
@@ -55,11 +56,10 @@ export const OSSY_GEN_PAGES_BASENAME = 'pages.generated.jsx'
|
|
|
55
56
|
export const OSSY_GEN_API_BASENAME = 'api.generated.js'
|
|
56
57
|
export const OSSY_GEN_TASKS_BASENAME = 'tasks.generated.js'
|
|
57
58
|
|
|
58
|
-
/** Bundled
|
|
59
|
-
export const
|
|
59
|
+
/** Bundled pages + React for build-time prerender only (not loaded by `server.js`). */
|
|
60
|
+
export const OSSY_PAGES_PRERENDER_BUNDLE = 'pages.prerender.bundle.js'
|
|
60
61
|
export const OSSY_API_SERVER_BUNDLE = 'api.bundle.js'
|
|
61
62
|
export const OSSY_TASKS_SERVER_BUNDLE = 'tasks.bundle.js'
|
|
62
|
-
export const OSSY_CONFIG_RUNTIME_BASENAME = 'config.runtime.js'
|
|
63
63
|
export const OSSY_MIDDLEWARE_RUNTIME_BASENAME = 'middleware.runtime.js'
|
|
64
64
|
|
|
65
65
|
/** Per-page client entries: `hydrate-<pageId>.jsx` under `.ossy/` */
|
|
@@ -223,16 +223,10 @@ export async function bundleOssyNodeEntry ({ inputPath, outputFile, nodeEnv }) {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
/**
|
|
226
|
-
* Re-exports
|
|
227
|
-
* relative imports (copying those files into `build/` would break them).
|
|
226
|
+
* Re-exports middleware via `file:` URL so `src/middleware.js` can keep relative imports.
|
|
228
227
|
*/
|
|
229
|
-
export function writeAppRuntimeShims ({
|
|
230
|
-
const cfgHref = url.pathToFileURL(path.resolve(configSourcePath)).href
|
|
228
|
+
export function writeAppRuntimeShims ({ middlewareSourcePath, ossyDir }) {
|
|
231
229
|
const mwHref = url.pathToFileURL(path.resolve(middlewareSourcePath)).href
|
|
232
|
-
fs.writeFileSync(
|
|
233
|
-
path.join(ossyDir, OSSY_CONFIG_RUNTIME_BASENAME),
|
|
234
|
-
`// Generated by @ossy/app — do not edit\nexport { default } from '${cfgHref}'\n`
|
|
235
|
-
)
|
|
236
230
|
fs.writeFileSync(
|
|
237
231
|
path.join(ossyDir, OSSY_MIDDLEWARE_RUNTIME_BASENAME),
|
|
238
232
|
`// Generated by @ossy/app — do not edit\nexport { default } from '${mwHref}'\n`
|
|
@@ -241,7 +235,7 @@ export function writeAppRuntimeShims ({ configSourcePath, middlewareSourcePath,
|
|
|
241
235
|
|
|
242
236
|
/**
|
|
243
237
|
* Copies framework runtime into `build/`: server, worker entry, proxy.
|
|
244
|
-
*
|
|
238
|
+
* Middleware loads via `./.ossy/middleware.runtime.js`.
|
|
245
239
|
*/
|
|
246
240
|
export function copyOssyAppRuntime ({ scriptDir, buildPath }) {
|
|
247
241
|
for (const name of ['server.js', 'proxy-internal.js']) {
|
|
@@ -656,7 +650,7 @@ export const build = async (cliArgs) => {
|
|
|
656
650
|
? configPath
|
|
657
651
|
: path.resolve(scriptDir, 'default-config.js')
|
|
658
652
|
|
|
659
|
-
const pagesBundlePath = path.join(ossyDir,
|
|
653
|
+
const pagesBundlePath = path.join(ossyDir, OSSY_PAGES_PRERENDER_BUNDLE)
|
|
660
654
|
const apiBundlePath = path.join(ossyDir, OSSY_API_SERVER_BUNDLE)
|
|
661
655
|
const tasksBundlePath = path.join(ossyDir, OSSY_TASKS_SERVER_BUNDLE)
|
|
662
656
|
|
|
@@ -678,37 +672,24 @@ export const build = async (cliArgs) => {
|
|
|
678
672
|
})
|
|
679
673
|
|
|
680
674
|
writeAppRuntimeShims({
|
|
681
|
-
configSourcePath,
|
|
682
675
|
middlewareSourcePath,
|
|
683
676
|
ossyDir,
|
|
684
677
|
})
|
|
685
678
|
copyOssyAppRuntime({ scriptDir, buildPath })
|
|
686
679
|
|
|
687
|
-
const clientPlugins = createOssyClientRollupPlugins({
|
|
688
|
-
nodeEnv: 'production',
|
|
689
|
-
copyPublicFrom: publicDir,
|
|
690
|
-
buildPath,
|
|
691
|
-
})
|
|
692
|
-
|
|
693
680
|
if (Object.keys(clientHydrateInput).length > 0) {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
return 'public/static/[name].js'
|
|
707
|
-
},
|
|
708
|
-
chunkFileNames: 'public/static/[name]-[hash].js',
|
|
709
|
-
plugins: [minifyBrowserStaticChunks()],
|
|
681
|
+
await prerenderReactTask.handler({
|
|
682
|
+
op: 'runProduction',
|
|
683
|
+
clientHydrateInput,
|
|
684
|
+
pageFilesLength: pageFiles.length,
|
|
685
|
+
copyPublicFrom: publicDir,
|
|
686
|
+
buildPath,
|
|
687
|
+
nodeEnv: 'production',
|
|
688
|
+
pagesBundlePath,
|
|
689
|
+
configSourcePath,
|
|
690
|
+
createClientRollupPlugins: createOssyClientRollupPlugins,
|
|
691
|
+
minifyBrowserStaticChunks,
|
|
710
692
|
})
|
|
711
|
-
await clientBundle.close()
|
|
712
693
|
}
|
|
713
694
|
|
|
714
695
|
console.log('[@ossy/app][build] Finished');
|
package/cli/dev.js
CHANGED
|
@@ -21,13 +21,14 @@ import {
|
|
|
21
21
|
OSSY_GEN_PAGES_BASENAME,
|
|
22
22
|
OSSY_GEN_API_BASENAME,
|
|
23
23
|
OSSY_GEN_TASKS_BASENAME,
|
|
24
|
-
|
|
24
|
+
OSSY_PAGES_PRERENDER_BUNDLE,
|
|
25
25
|
OSSY_API_SERVER_BUNDLE,
|
|
26
26
|
OSSY_TASKS_SERVER_BUNDLE,
|
|
27
27
|
writeResourceTemplatesBarrelIfPresent,
|
|
28
28
|
resourceTemplatesDir,
|
|
29
29
|
OSSY_RESOURCE_TEMPLATES_OUT,
|
|
30
30
|
} from './build.js';
|
|
31
|
+
import prerenderReactTask from './prerender-react.task.js'
|
|
31
32
|
import { watch } from 'rollup';
|
|
32
33
|
import arg from 'arg'
|
|
33
34
|
import { spawn } from 'node:child_process'
|
|
@@ -89,7 +90,7 @@ export const dev = async (cliArgs) => {
|
|
|
89
90
|
? configPath
|
|
90
91
|
: path.resolve(scriptDir, 'default-config.js')
|
|
91
92
|
|
|
92
|
-
const pagesBundlePath = path.join(ossyDir,
|
|
93
|
+
const pagesBundlePath = path.join(ossyDir, OSSY_PAGES_PRERENDER_BUNDLE)
|
|
93
94
|
const apiBundlePath = path.join(ossyDir, OSSY_API_SERVER_BUNDLE)
|
|
94
95
|
const tasksBundlePath = path.join(ossyDir, OSSY_TASKS_SERVER_BUNDLE)
|
|
95
96
|
const tasksGeneratedPath = path.join(ossyDir, OSSY_GEN_TASKS_BASENAME)
|
|
@@ -111,7 +112,6 @@ export const dev = async (cliArgs) => {
|
|
|
111
112
|
nodeEnv: 'development',
|
|
112
113
|
})
|
|
113
114
|
writeAppRuntimeShims({
|
|
114
|
-
configSourcePath,
|
|
115
115
|
middlewareSourcePath,
|
|
116
116
|
ossyDir,
|
|
117
117
|
})
|
|
@@ -235,11 +235,22 @@ export const dev = async (cliArgs) => {
|
|
|
235
235
|
}
|
|
236
236
|
if (event.code === 'END') {
|
|
237
237
|
writeAppRuntimeShims({
|
|
238
|
-
configSourcePath,
|
|
239
238
|
middlewareSourcePath,
|
|
240
239
|
ossyDir,
|
|
241
240
|
})
|
|
242
241
|
copyOssyAppRuntime({ scriptDir, buildPath })
|
|
242
|
+
if (pageFiles.length > 0) {
|
|
243
|
+
try {
|
|
244
|
+
await prerenderReactTask.handler({
|
|
245
|
+
op: 'prerenderPagesParallel',
|
|
246
|
+
pagesBundlePath,
|
|
247
|
+
configSourcePath,
|
|
248
|
+
publicDir: path.join(buildPath, 'public'),
|
|
249
|
+
})
|
|
250
|
+
} catch (err) {
|
|
251
|
+
console.error('[@ossy/app][dev] Prerender failed', err)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
243
254
|
scheduleRestart()
|
|
244
255
|
}
|
|
245
256
|
})
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import url from 'url'
|
|
3
|
+
import fs from 'fs'
|
|
4
|
+
import { rollup } from 'rollup'
|
|
5
|
+
import { BuildPage } from './render-page.task.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Maps an app route path to the file path express.static will serve for that URL
|
|
9
|
+
* (`/` → `public/index.html`, `/a/b` → `public/a/b/index.html`).
|
|
10
|
+
*/
|
|
11
|
+
export function staticHtmlPathForRoute (routePath, publicDir) {
|
|
12
|
+
const p = typeof routePath === 'string' ? routePath : '/'
|
|
13
|
+
if (p === '/' || p === '') {
|
|
14
|
+
return path.join(publicDir, 'index.html')
|
|
15
|
+
}
|
|
16
|
+
const segments = p.replace(/^\//, '').split('/').filter(Boolean)
|
|
17
|
+
return path.join(publicDir, ...segments, 'index.html')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function pathIsPrerenderable (routePath) {
|
|
21
|
+
if (typeof routePath !== 'string') return false
|
|
22
|
+
if (!routePath.startsWith('/') || routePath.includes(':')) return false
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Mirrors server-era app shell config with static defaults (no cookies / session). */
|
|
27
|
+
export function buildPrerenderAppConfig ({
|
|
28
|
+
buildTimeConfig,
|
|
29
|
+
pageList,
|
|
30
|
+
activeRouteId,
|
|
31
|
+
urlPath,
|
|
32
|
+
}) {
|
|
33
|
+
const pages = pageList.map((page) => {
|
|
34
|
+
const entry = {
|
|
35
|
+
id: page?.id,
|
|
36
|
+
path: page?.path,
|
|
37
|
+
}
|
|
38
|
+
if (activeRouteId != null && page?.id === activeRouteId) {
|
|
39
|
+
entry.element = page?.element
|
|
40
|
+
}
|
|
41
|
+
return entry
|
|
42
|
+
})
|
|
43
|
+
return {
|
|
44
|
+
...buildTimeConfig,
|
|
45
|
+
url: urlPath,
|
|
46
|
+
theme: buildTimeConfig.theme || 'light',
|
|
47
|
+
isAuthenticated: false,
|
|
48
|
+
workspaceId: buildTimeConfig.workspaceId,
|
|
49
|
+
apiUrl: buildTimeConfig.apiUrl,
|
|
50
|
+
pages,
|
|
51
|
+
sidebarPrimaryCollapsed: false,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function copyPublicToBuild ({ copyPublicFrom, buildPath }) {
|
|
56
|
+
if (!copyPublicFrom || !fs.existsSync(copyPublicFrom)) return
|
|
57
|
+
const dest = path.join(buildPath, 'public')
|
|
58
|
+
fs.mkdirSync(dest, { recursive: true })
|
|
59
|
+
fs.cpSync(copyPublicFrom, dest, { recursive: true })
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function countSettledFailures (results) {
|
|
63
|
+
return results.filter((r) => r.status === 'rejected').length
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function bundleOneHydratePage ({
|
|
67
|
+
entryName,
|
|
68
|
+
stubPath,
|
|
69
|
+
buildPath,
|
|
70
|
+
plugins,
|
|
71
|
+
minifyPlugin,
|
|
72
|
+
}) {
|
|
73
|
+
const bundle = await rollup({
|
|
74
|
+
input: { [entryName]: stubPath },
|
|
75
|
+
plugins,
|
|
76
|
+
})
|
|
77
|
+
try {
|
|
78
|
+
await bundle.write({
|
|
79
|
+
dir: buildPath,
|
|
80
|
+
format: 'esm',
|
|
81
|
+
inlineDynamicImports: true,
|
|
82
|
+
entryFileNames (chunkInfo) {
|
|
83
|
+
const n = chunkInfo.name
|
|
84
|
+
if (n.startsWith('hydrate__')) {
|
|
85
|
+
const pageId = n.slice('hydrate__'.length)
|
|
86
|
+
return `public/static/hydrate-${pageId}.js`
|
|
87
|
+
}
|
|
88
|
+
return 'public/static/[name].js'
|
|
89
|
+
},
|
|
90
|
+
chunkFileNames: 'public/static/[name]-[hash].js',
|
|
91
|
+
plugins: minifyPlugin ? [minifyPlugin] : [],
|
|
92
|
+
})
|
|
93
|
+
} finally {
|
|
94
|
+
await bundle.close()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function bundleHydratePagesParallel ({
|
|
99
|
+
clientHydrateInput,
|
|
100
|
+
buildPath,
|
|
101
|
+
copyPublicFrom,
|
|
102
|
+
nodeEnv,
|
|
103
|
+
buildPathForPlugins,
|
|
104
|
+
createClientRollupPlugins,
|
|
105
|
+
minifyBrowserStaticChunks,
|
|
106
|
+
}) {
|
|
107
|
+
copyPublicToBuild({ copyPublicFrom, buildPath })
|
|
108
|
+
fs.mkdirSync(path.join(buildPath, 'public', 'static'), { recursive: true })
|
|
109
|
+
|
|
110
|
+
const entries = Object.entries(clientHydrateInput)
|
|
111
|
+
|
|
112
|
+
const results = await Promise.allSettled(
|
|
113
|
+
entries.map(([entryName, stubPath]) => {
|
|
114
|
+
const plugins = createClientRollupPlugins({
|
|
115
|
+
nodeEnv,
|
|
116
|
+
copyPublicFrom: undefined,
|
|
117
|
+
buildPath: buildPathForPlugins,
|
|
118
|
+
})
|
|
119
|
+
return bundleOneHydratePage({
|
|
120
|
+
entryName,
|
|
121
|
+
stubPath,
|
|
122
|
+
buildPath,
|
|
123
|
+
plugins,
|
|
124
|
+
minifyPlugin: minifyBrowserStaticChunks(),
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
const failures = countSettledFailures(results)
|
|
130
|
+
results.forEach((r, i) => {
|
|
131
|
+
if (r.status === 'rejected') {
|
|
132
|
+
const [entryName] = entries[i]
|
|
133
|
+
console.error(`[@ossy/app][client-bundle] ${entryName} failed:`, r.reason)
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
return { results, failures }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function prerenderOnePage ({
|
|
141
|
+
route,
|
|
142
|
+
buildTimeConfig,
|
|
143
|
+
pageList,
|
|
144
|
+
publicDir,
|
|
145
|
+
}) {
|
|
146
|
+
const appConfig = buildPrerenderAppConfig({
|
|
147
|
+
buildTimeConfig,
|
|
148
|
+
pageList,
|
|
149
|
+
activeRouteId: route.id,
|
|
150
|
+
urlPath: route.path,
|
|
151
|
+
})
|
|
152
|
+
const html = await BuildPage.handle({
|
|
153
|
+
route,
|
|
154
|
+
appConfig,
|
|
155
|
+
isDevReloadEnabled: false,
|
|
156
|
+
})
|
|
157
|
+
const outPath = staticHtmlPathForRoute(route.path, publicDir)
|
|
158
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true })
|
|
159
|
+
fs.writeFileSync(outPath, html, 'utf8')
|
|
160
|
+
console.log(
|
|
161
|
+
`[@ossy/app][prerender] ${route.path} → ${path.relative(process.cwd(), outPath)}`
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function prerenderPagesParallel ({
|
|
166
|
+
pagesBundlePath,
|
|
167
|
+
configSourcePath,
|
|
168
|
+
publicDir,
|
|
169
|
+
}) {
|
|
170
|
+
const cfgHref = url.pathToFileURL(path.resolve(configSourcePath)).href
|
|
171
|
+
const pagesHref = url.pathToFileURL(path.resolve(pagesBundlePath)).href
|
|
172
|
+
|
|
173
|
+
const configModule = await import(cfgHref)
|
|
174
|
+
const pagesModule = await import(pagesHref)
|
|
175
|
+
|
|
176
|
+
const buildTimeConfig = configModule?.default ?? configModule ?? {}
|
|
177
|
+
const pageList = pagesModule?.default ?? []
|
|
178
|
+
|
|
179
|
+
const routesToRender = []
|
|
180
|
+
for (const route of pageList) {
|
|
181
|
+
if (!route?.element) continue
|
|
182
|
+
if (!pathIsPrerenderable(route.path)) {
|
|
183
|
+
console.warn(
|
|
184
|
+
`[@ossy/app][prerender] Skipping "${route.id}" (path not prerenderable: ${JSON.stringify(route.path)})`
|
|
185
|
+
)
|
|
186
|
+
continue
|
|
187
|
+
}
|
|
188
|
+
routesToRender.push(route)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const results = await Promise.allSettled(
|
|
192
|
+
routesToRender.map((route) =>
|
|
193
|
+
prerenderOnePage({
|
|
194
|
+
route,
|
|
195
|
+
buildTimeConfig,
|
|
196
|
+
pageList,
|
|
197
|
+
publicDir,
|
|
198
|
+
})
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
const failures = countSettledFailures(results)
|
|
202
|
+
results.forEach((r, i) => {
|
|
203
|
+
if (r.status === 'rejected') {
|
|
204
|
+
const route = routesToRender[i]
|
|
205
|
+
console.error(
|
|
206
|
+
`[@ossy/app][prerender] "${route?.id}" (${route?.path}) failed:`,
|
|
207
|
+
r.reason
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
return { results, failures }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function runProduction ({
|
|
216
|
+
clientHydrateInput,
|
|
217
|
+
pageFilesLength,
|
|
218
|
+
copyPublicFrom,
|
|
219
|
+
buildPath,
|
|
220
|
+
nodeEnv,
|
|
221
|
+
pagesBundlePath,
|
|
222
|
+
configSourcePath,
|
|
223
|
+
createClientRollupPlugins,
|
|
224
|
+
minifyBrowserStaticChunks,
|
|
225
|
+
}) {
|
|
226
|
+
if (pageFilesLength === 0 || Object.keys(clientHydrateInput).length === 0) {
|
|
227
|
+
return { bundleFailures: 0, prerenderFailures: 0 }
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const { failures: bundleFailures } = await bundleHydratePagesParallel({
|
|
231
|
+
clientHydrateInput,
|
|
232
|
+
buildPath,
|
|
233
|
+
copyPublicFrom,
|
|
234
|
+
nodeEnv,
|
|
235
|
+
buildPathForPlugins: buildPath,
|
|
236
|
+
createClientRollupPlugins,
|
|
237
|
+
minifyBrowserStaticChunks,
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
const { failures: prerenderFailures } = await prerenderPagesParallel({
|
|
241
|
+
pagesBundlePath,
|
|
242
|
+
configSourcePath,
|
|
243
|
+
publicDir: path.join(buildPath, 'public'),
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
if (bundleFailures + prerenderFailures > 0) {
|
|
247
|
+
console.warn(
|
|
248
|
+
`[@ossy/app][build] Finished with ${bundleFailures} client bundle error(s) and ${prerenderFailures} prerender error(s)`
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return { bundleFailures, prerenderFailures }
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export default {
|
|
256
|
+
type: '@ossy/app/prerender-react',
|
|
257
|
+
/** `input.op`: `runProduction` | `prerenderPagesParallel` (see callers in `build.js` / `dev.js`). */
|
|
258
|
+
async handler (input) {
|
|
259
|
+
const op = input?.op
|
|
260
|
+
if (op === 'runProduction') {
|
|
261
|
+
return runProduction(input)
|
|
262
|
+
}
|
|
263
|
+
if (op === 'prerenderPagesParallel') {
|
|
264
|
+
return prerenderPagesParallel(input)
|
|
265
|
+
}
|
|
266
|
+
throw new Error(
|
|
267
|
+
`[@ossy/app][prerender-react] Unknown op: ${String(op)} (expected runProduction | prerenderPagesParallel)`
|
|
268
|
+
)
|
|
269
|
+
},
|
|
270
|
+
}
|
package/cli/server.js
CHANGED
|
@@ -5,18 +5,12 @@ import morgan from 'morgan'
|
|
|
5
5
|
import { Router as OssyRouter } from '@ossy/router'
|
|
6
6
|
import { ProxyInternal } from './proxy-internal.js'
|
|
7
7
|
import cookieParser from 'cookie-parser'
|
|
8
|
-
import { BuildPage } from './render-page.task.js'
|
|
9
8
|
|
|
10
|
-
import pages from './.ossy/pages.bundle.js'
|
|
11
9
|
import ApiRoutes from './.ossy/api.bundle.js'
|
|
12
10
|
import Middleware from './.ossy/middleware.runtime.js'
|
|
13
|
-
import configModule from './.ossy/config.runtime.js'
|
|
14
|
-
|
|
15
|
-
const buildTimeConfig = configModule?.default ?? configModule ?? {}
|
|
16
11
|
|
|
17
12
|
/** API bundle default may be an empty array. */
|
|
18
13
|
const apiRouteList = ApiRoutes ?? []
|
|
19
|
-
const pageList = pages ?? []
|
|
20
14
|
|
|
21
15
|
const app = express();
|
|
22
16
|
|
|
@@ -108,34 +102,9 @@ const middleware = [
|
|
|
108
102
|
app.use(middleware)
|
|
109
103
|
|
|
110
104
|
const Router = OssyRouter.of({
|
|
111
|
-
pages:
|
|
105
|
+
pages: apiRouteList,
|
|
112
106
|
})
|
|
113
107
|
|
|
114
|
-
function resolveAppConfig ({ req, buildTimeConfig, activeRouteId }) {
|
|
115
|
-
const userAppSettings = req.userAppSettings || {}
|
|
116
|
-
const pages = pageList.map((page) => {
|
|
117
|
-
const entry = {
|
|
118
|
-
id: page?.id,
|
|
119
|
-
path: page?.path,
|
|
120
|
-
}
|
|
121
|
-
if (activeRouteId != null && page?.id === activeRouteId) {
|
|
122
|
-
entry.element = page?.element
|
|
123
|
-
}
|
|
124
|
-
return entry
|
|
125
|
-
})
|
|
126
|
-
return {
|
|
127
|
-
...buildTimeConfig,
|
|
128
|
-
url: req.originalUrl,
|
|
129
|
-
theme: userAppSettings.theme || buildTimeConfig.theme || 'light',
|
|
130
|
-
isAuthenticated: req.isAuthenticated || false,
|
|
131
|
-
workspaceId: userAppSettings.workspaceId || buildTimeConfig.workspaceId,
|
|
132
|
-
apiUrl: buildTimeConfig.apiUrl,
|
|
133
|
-
pages,
|
|
134
|
-
/** Primary app shell sidebar: icon rail when true (persisted in `x-ossy-user-settings`). */
|
|
135
|
-
sidebarPrimaryCollapsed: userAppSettings.sidebarPrimaryCollapsed === true,
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
108
|
app.all('*all', (req, res) => {
|
|
140
109
|
const pathname = req.originalUrl
|
|
141
110
|
|
|
@@ -147,23 +116,9 @@ app.all('*all', (req, res) => {
|
|
|
147
116
|
return
|
|
148
117
|
}
|
|
149
118
|
|
|
150
|
-
|
|
151
|
-
res.status(404).send('Not found')
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const appConfig = resolveAppConfig({
|
|
156
|
-
req,
|
|
157
|
-
buildTimeConfig,
|
|
158
|
-
activeRouteId: route.id,
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
BuildPage.handle({ route, appConfig, isDevReloadEnabled })
|
|
162
|
-
.then(html => { res.send(html) })
|
|
163
|
-
.catch(err => { res.send(err) })
|
|
164
|
-
|
|
119
|
+
res.status(404).send('Not found')
|
|
165
120
|
})
|
|
166
121
|
|
|
167
122
|
app.listen(port, () => {
|
|
168
123
|
console.log(`[@ossy/app][server] Running on http://localhost:${port}`);
|
|
169
|
-
});
|
|
124
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"source": "./src/index.js",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"@babel/eslint-parser": "^7.15.8",
|
|
28
28
|
"@babel/preset-react": "^7.26.3",
|
|
29
29
|
"@babel/register": "^7.25.9",
|
|
30
|
-
"@ossy/connected-components": "^1.
|
|
31
|
-
"@ossy/design-system": "^1.
|
|
32
|
-
"@ossy/pages": "^1.
|
|
33
|
-
"@ossy/router": "^1.
|
|
34
|
-
"@ossy/router-react": "^1.
|
|
35
|
-
"@ossy/sdk": "^1.
|
|
36
|
-
"@ossy/sdk-react": "^1.
|
|
37
|
-
"@ossy/themes": "^1.
|
|
30
|
+
"@ossy/connected-components": "^1.10.0",
|
|
31
|
+
"@ossy/design-system": "^1.10.0",
|
|
32
|
+
"@ossy/pages": "^1.10.0",
|
|
33
|
+
"@ossy/router": "^1.10.0",
|
|
34
|
+
"@ossy/router-react": "^1.10.0",
|
|
35
|
+
"@ossy/sdk": "^1.10.0",
|
|
36
|
+
"@ossy/sdk-react": "^1.10.0",
|
|
37
|
+
"@ossy/themes": "^1.10.0",
|
|
38
38
|
"@rollup/plugin-alias": "^6.0.0",
|
|
39
39
|
"@rollup/plugin-babel": "6.1.0",
|
|
40
40
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"README.md",
|
|
68
68
|
"tsconfig.json"
|
|
69
69
|
],
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "bd9dfaf87661392562fbe2cdfd3ca6d645147f24"
|
|
71
71
|
}
|