@ossy/app 1.4.1 → 1.6.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.
@@ -0,0 +1,35 @@
1
+ import React, { cloneElement } from 'react'
2
+ import { prerenderToNodeStream } from 'react-dom/static'
3
+
4
+ /** Strips non-JSON content (e.g. React elements on `pages`) for the bootstrap script. */
5
+ export function appConfigForBootstrap (appConfig) {
6
+ if (!appConfig || typeof appConfig !== 'object') return appConfig
7
+ const pages = Array.isArray(appConfig.pages)
8
+ ? appConfig.pages.map(({ id, path }) => ({ id, path }))
9
+ : appConfig.pages
10
+ return { ...appConfig, pages }
11
+ }
12
+
13
+ export const BuildPage = {
14
+ async handle ({ route, appConfig, isDevReloadEnabled }) {
15
+ const rootElement = cloneElement(route.element, appConfig)
16
+ const devReloadScript = isDevReloadEnabled
17
+ ? `(function(){try{var es=new EventSource('/__ossy_reload');es.addEventListener('reload',function(){location.reload();});}catch(e){}})();`
18
+ : ``
19
+
20
+ const hydrateUrl = `/static/hydrate-${route.id}.js`
21
+ const { prelude } = await prerenderToNodeStream(rootElement, {
22
+ bootstrapScriptContent: `window.__INITIAL_APP_CONFIG__ = ${JSON.stringify(appConfigForBootstrap(appConfig))};${devReloadScript}`,
23
+ bootstrapModules: [hydrateUrl],
24
+ })
25
+
26
+ return new Promise((resolve, reject) => {
27
+ let data = ''
28
+ prelude.on('data', (chunk) => {
29
+ data += chunk
30
+ })
31
+ prelude.on('end', () => resolve(data))
32
+ prelude.on('error', reject)
33
+ })
34
+ },
35
+ }
package/cli/server.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import path from 'path';
2
2
  import url from 'url'
3
- import React, { cloneElement } from 'react';
4
3
  import express from 'express'
5
4
  import morgan from 'morgan'
6
5
  import { Router as OssyRouter } from '@ossy/router'
7
- import { prerenderToNodeStream } from 'react-dom/static'
8
6
  import { ProxyInternal } from './proxy-internal.js'
9
7
  import cookieParser from 'cookie-parser'
8
+ import { BuildPage } from './render-page.task.js'
10
9
 
11
10
  import pages from './.ossy/pages.bundle.js'
12
11
  import ApiRoutes from './.ossy/api.bundle.js'
@@ -112,36 +111,54 @@ const Router = OssyRouter.of({
112
111
  pages: [...apiRouteList, ...pageList]
113
112
  })
114
113
 
115
- app.all('*all', (req, res) => {
116
- const pathname = req.originalUrl
117
-
118
- const route = Router.getPageByUrl(pathname)
119
-
120
- if (route && typeof route.handle === 'function') {
121
- console.log(`[@ossy/app][server] Handling API route: ${pathname}`)
122
- route.handle(req, res)
123
- return
124
- }
125
-
114
+ function resolveAppConfig ({ req, buildTimeConfig, activeRouteId }) {
126
115
  const userAppSettings = req.userAppSettings || {}
127
-
128
- const appConfig = {
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 {
129
127
  ...buildTimeConfig,
130
128
  url: req.originalUrl,
131
129
  theme: userAppSettings.theme || buildTimeConfig.theme || 'light',
132
130
  isAuthenticated: req.isAuthenticated || false,
133
131
  workspaceId: userAppSettings.workspaceId || buildTimeConfig.workspaceId,
134
132
  apiUrl: buildTimeConfig.apiUrl,
133
+ pages,
135
134
  /** Primary app shell sidebar: icon rail when true (persisted in `x-ossy-user-settings`). */
136
135
  sidebarPrimaryCollapsed: userAppSettings.sidebarPrimaryCollapsed === true,
137
136
  }
137
+ }
138
+
139
+ app.all('*all', (req, res) => {
140
+ const pathname = req.originalUrl
141
+
142
+ const route = Router.getPageByUrl(pathname)
143
+
144
+ if (route && typeof route.handle === 'function') {
145
+ console.log(`[@ossy/app][server] Handling API route: ${pathname}`)
146
+ route.handle(req, res)
147
+ return
148
+ }
138
149
 
139
150
  if (!route?.element) {
140
151
  res.status(404).send('Not found')
141
152
  return
142
153
  }
143
154
 
144
- prerenderHtmlDocument(cloneElement(route.element, appConfig), appConfig, route.id)
155
+ const appConfig = resolveAppConfig({
156
+ req,
157
+ buildTimeConfig,
158
+ activeRouteId: route.id,
159
+ })
160
+
161
+ BuildPage.handle({ route, appConfig, isDevReloadEnabled })
145
162
  .then(html => { res.send(html) })
146
163
  .catch(err => { res.send(err) })
147
164
 
@@ -149,28 +166,4 @@ app.all('*all', (req, res) => {
149
166
 
150
167
  app.listen(port, () => {
151
168
  console.log(`[@ossy/app][server] Running on http://localhost:${port}`);
152
- });
153
-
154
- async function prerenderHtmlDocument (rootElement, config, pageId) {
155
-
156
- const devReloadScript = isDevReloadEnabled
157
- ? `(function(){try{var es=new EventSource('/__ossy_reload');es.addEventListener('reload',function(){location.reload();});}catch(e){}})();`
158
- : ``
159
-
160
- const hydrateUrl = `/static/hydrate-${pageId}.js`
161
-
162
- const { prelude } = await prerenderToNodeStream(rootElement, {
163
- bootstrapScriptContent: `window.__INITIAL_APP_CONFIG__ = ${JSON.stringify(config)};${devReloadScript}`,
164
- bootstrapModules: [hydrateUrl]
165
- });
166
-
167
- return new Promise((resolve, reject) => {
168
- let data = '';
169
- prelude.on('data', chunk => {
170
- data += chunk;
171
- });
172
- prelude.on('end', () => resolve(data));
173
- prelude.on('error', reject);
174
- });
175
-
176
- }
169
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/app",
3
- "version": "1.4.1",
3
+ "version": "1.6.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.4.1",
31
- "@ossy/design-system": "^1.4.1",
32
- "@ossy/pages": "^1.4.1",
33
- "@ossy/router": "^1.4.1",
34
- "@ossy/router-react": "^1.4.1",
35
- "@ossy/sdk": "^1.4.1",
36
- "@ossy/sdk-react": "^1.4.1",
37
- "@ossy/themes": "^1.4.1",
30
+ "@ossy/connected-components": "^1.6.0",
31
+ "@ossy/design-system": "^1.6.0",
32
+ "@ossy/pages": "^1.6.0",
33
+ "@ossy/router": "^1.6.0",
34
+ "@ossy/router-react": "^1.6.0",
35
+ "@ossy/sdk": "^1.6.0",
36
+ "@ossy/sdk-react": "^1.6.0",
37
+ "@ossy/themes": "^1.6.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": "ffccd09f5b13bddbf48e2b88ebb8b9d1e02c43f1"
70
+ "gitHead": "a1c29650f72ec23bd397d3c9e1c42387461acf8e"
71
71
  }