@ossy/app 1.4.0 → 1.5.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 CHANGED
@@ -159,8 +159,8 @@ export function createOssyAppBundlePlugins ({ nodeEnv }) {
159
159
  }),
160
160
  json(),
161
161
  nodeExternals({
162
- deps: true,
163
- devDeps: false,
162
+ deps: false,
163
+ devDeps: true,
164
164
  peerDeps: true,
165
165
  packagePath: path.join(process.cwd(), 'package.json'),
166
166
  }),
@@ -185,8 +185,8 @@ export function createOssyClientRollupPlugins ({ nodeEnv, copyPublicFrom, buildP
185
185
  }),
186
186
  json(),
187
187
  nodeExternals({
188
- deps: true,
189
- devDeps: false,
188
+ deps: false,
189
+ devDeps: true,
190
190
  peerDeps: true,
191
191
  packagePath: path.join(process.cwd(), 'package.json'),
192
192
  }),
@@ -407,21 +407,18 @@ export function clientHydrateIdForPage (pageAbsPath, srcDir) {
407
407
  * One client entry per page: imports only that page module and hydrates the document.
408
408
  * Keeps the same `toPage` shape as `generatePagesModule` so SSR and client trees match.
409
409
  */
410
- export function generatePageHydrateModule ({ pageAbsPath, stubAbsPath, srcDir, pagesGeneratedPath }) {
410
+ export function generatePageHydrateModule ({ pageAbsPath, stubAbsPath, srcDir }) {
411
411
  const rel = relToGeneratedImport(stubAbsPath, pageAbsPath)
412
- const pagesRel = relToGeneratedImport(stubAbsPath, pagesGeneratedPath)
413
412
  const { id, path: routePath } = filePathToRoute(pageAbsPath, srcDir)
414
413
  const pathLiteral = JSON.stringify(routePath)
415
414
  const idLiteral = JSON.stringify(id)
416
415
  return [
417
416
  '// Generated by @ossy/app — do not edit',
418
417
  '',
419
- "import React, { cloneElement, createElement } from 'react'",
418
+ "import React, { cloneElement } from 'react'",
420
419
  "import 'react-dom'",
421
420
  "import { hydrateRoot } from 'react-dom/client'",
422
- "import { App } from '@ossy/connected-components'",
423
421
  `import * as _page from './${rel}'`,
424
- `import pageRoutes from './${pagesRel}'`,
425
422
  '',
426
423
  'function toPage(mod, derived) {',
427
424
  ' const meta = mod?.metadata || {}',
@@ -434,17 +431,9 @@ export function generatePageHydrateModule ({ pageAbsPath, stubAbsPath, srcDir, p
434
431
  '',
435
432
  `const _route = toPage(_page, { id: ${idLiteral}, path: ${pathLiteral} })`,
436
433
  'const initialConfig = window.__INITIAL_APP_CONFIG__ || {}',
437
- 'const pagesForApp = pageRoutes.map((p) =>',
438
- ' p.id === _route.id',
439
- ' ? { ...p, element: cloneElement(p.element, initialConfig) }',
440
- ' : p',
441
- ')',
442
- 'const rootTree = createElement(App, {',
443
- ' ...initialConfig,',
444
- ' url: window.location.href,',
445
- ' pages: pagesForApp,',
446
- ' includeDocumentShell: false,',
447
- '})',
434
+ 'const rootTree = _route?.element',
435
+ ' ? cloneElement(_route.element, initialConfig)',
436
+ " : React.createElement('p', null, 'Not found')",
448
437
  'hydrateRoot(document, rootTree)',
449
438
  '',
450
439
  ].join('\n')
@@ -452,7 +441,6 @@ export function generatePageHydrateModule ({ pageAbsPath, stubAbsPath, srcDir, p
452
441
 
453
442
  /** Writes `hydrate-<id>.jsx` for each page; removes stale `hydrate-*` outputs in `ossyDir` first. */
454
443
  export function writePageHydrateStubs (pageFiles, srcDir, ossyDir) {
455
- const pagesGeneratedPath = path.join(ossyDir, OSSY_GEN_PAGES_BASENAME)
456
444
  if (!fs.existsSync(ossyDir)) fs.mkdirSync(ossyDir, { recursive: true })
457
445
  for (const ent of fs.readdirSync(ossyDir, { withFileTypes: true })) {
458
446
  const full = path.join(ossyDir, ent.name)
@@ -479,12 +467,7 @@ export function writePageHydrateStubs (pageFiles, srcDir, ossyDir) {
479
467
  fs.mkdirSync(path.dirname(stubPath), { recursive: true })
480
468
  fs.writeFileSync(
481
469
  stubPath,
482
- generatePageHydrateModule({
483
- pageAbsPath: f,
484
- stubAbsPath: stubPath,
485
- srcDir,
486
- pagesGeneratedPath,
487
- })
470
+ generatePageHydrateModule({ pageAbsPath: f, stubAbsPath: stubPath, srcDir })
488
471
  )
489
472
  }
490
473
  }
@@ -0,0 +1,26 @@
1
+ import React, { cloneElement } from 'react'
2
+ import { prerenderToNodeStream } from 'react-dom/static'
3
+
4
+ export const BuildPage = {
5
+ async handle ({ route, appConfig, isDevReloadEnabled }) {
6
+ const rootElement = cloneElement(route.element, appConfig)
7
+ const devReloadScript = isDevReloadEnabled
8
+ ? `(function(){try{var es=new EventSource('/__ossy_reload');es.addEventListener('reload',function(){location.reload();});}catch(e){}})();`
9
+ : ``
10
+
11
+ const hydrateUrl = `/static/hydrate-${route.id}.js`
12
+ const { prelude } = await prerenderToNodeStream(rootElement, {
13
+ bootstrapScriptContent: `window.__INITIAL_APP_CONFIG__ = ${JSON.stringify(appConfig)};${devReloadScript}`,
14
+ bootstrapModules: [hydrateUrl],
15
+ })
16
+
17
+ return new Promise((resolve, reject) => {
18
+ let data = ''
19
+ prelude.on('data', (chunk) => {
20
+ data += chunk
21
+ })
22
+ prelude.on('end', () => resolve(data))
23
+ prelude.on('error', reject)
24
+ })
25
+ },
26
+ }
package/cli/server.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import path from 'path';
2
2
  import url from 'url'
3
- import React, { cloneElement, createElement } 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 { App } from '@ossy/connected-components'
8
- import { prerenderToNodeStream } from 'react-dom/static'
9
6
  import { ProxyInternal } from './proxy-internal.js'
10
7
  import cookieParser from 'cookie-parser'
8
+ import { BuildPage } from './render-page.task.js'
11
9
 
12
10
  import pages from './.ossy/pages.bundle.js'
13
11
  import ApiRoutes from './.ossy/api.bundle.js'
@@ -113,6 +111,25 @@ const Router = OssyRouter.of({
113
111
  pages: [...apiRouteList, ...pageList]
114
112
  })
115
113
 
114
+ function resolveAppConfig ({ req, buildTimeConfig }) {
115
+ const userAppSettings = req.userAppSettings || {}
116
+ const pages = pageList.map((page) => ({
117
+ id: page?.id,
118
+ path: page?.path,
119
+ }))
120
+ return {
121
+ ...buildTimeConfig,
122
+ url: req.originalUrl,
123
+ theme: userAppSettings.theme || buildTimeConfig.theme || 'light',
124
+ isAuthenticated: req.isAuthenticated || false,
125
+ workspaceId: userAppSettings.workspaceId || buildTimeConfig.workspaceId,
126
+ apiUrl: buildTimeConfig.apiUrl,
127
+ pages,
128
+ /** Primary app shell sidebar: icon rail when true (persisted in `x-ossy-user-settings`). */
129
+ sidebarPrimaryCollapsed: userAppSettings.sidebarPrimaryCollapsed === true,
130
+ }
131
+ }
132
+
116
133
  app.all('*all', (req, res) => {
117
134
  const pathname = req.originalUrl
118
135
 
@@ -124,36 +141,14 @@ app.all('*all', (req, res) => {
124
141
  return
125
142
  }
126
143
 
127
- const userAppSettings = req.userAppSettings || {}
128
-
129
- const appConfig = {
130
- ...buildTimeConfig,
131
- url: req.originalUrl,
132
- theme: userAppSettings.theme || buildTimeConfig.theme || 'light',
133
- isAuthenticated: req.isAuthenticated || false,
134
- workspaceId: userAppSettings.workspaceId || buildTimeConfig.workspaceId,
135
- apiUrl: buildTimeConfig.apiUrl,
136
- /** Primary app shell sidebar: icon rail when true (persisted in `x-ossy-user-settings`). */
137
- sidebarPrimaryCollapsed: userAppSettings.sidebarPrimaryCollapsed === true,
138
- }
144
+ const appConfig = resolveAppConfig({ req, buildTimeConfig })
139
145
 
140
146
  if (!route?.element) {
141
147
  res.status(404).send('Not found')
142
148
  return
143
149
  }
144
150
 
145
- const pagesForApp = pageList.map((p) =>
146
- p.id === route.id
147
- ? { ...p, element: cloneElement(p.element, appConfig) }
148
- : p
149
- )
150
- const rootElement = createElement(App, {
151
- ...appConfig,
152
- pages: pagesForApp,
153
- includeDocumentShell: false,
154
- })
155
-
156
- prerenderHtmlDocument(rootElement, appConfig, route.id)
151
+ BuildPage.handle({ route, appConfig, isDevReloadEnabled })
157
152
  .then(html => { res.send(html) })
158
153
  .catch(err => { res.send(err) })
159
154
 
@@ -161,28 +156,4 @@ app.all('*all', (req, res) => {
161
156
 
162
157
  app.listen(port, () => {
163
158
  console.log(`[@ossy/app][server] Running on http://localhost:${port}`);
164
- });
165
-
166
- async function prerenderHtmlDocument (rootElement, config, pageId) {
167
-
168
- const devReloadScript = isDevReloadEnabled
169
- ? `(function(){try{var es=new EventSource('/__ossy_reload');es.addEventListener('reload',function(){location.reload();});}catch(e){}})();`
170
- : ``
171
-
172
- const hydrateUrl = `/static/hydrate-${pageId}.js`
173
-
174
- const { prelude } = await prerenderToNodeStream(rootElement, {
175
- bootstrapScriptContent: `window.__INITIAL_APP_CONFIG__ = ${JSON.stringify(config)};${devReloadScript}`,
176
- bootstrapModules: [hydrateUrl]
177
- });
178
-
179
- return new Promise((resolve, reject) => {
180
- let data = '';
181
- prelude.on('data', chunk => {
182
- data += chunk;
183
- });
184
- prelude.on('end', () => resolve(data));
185
- prelude.on('error', reject);
186
- });
187
-
188
- }
159
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/app",
3
- "version": "1.4.0",
3
+ "version": "1.5.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.0",
31
- "@ossy/design-system": "^1.4.0",
32
- "@ossy/pages": "^1.4.0",
33
- "@ossy/router": "^1.4.0",
34
- "@ossy/router-react": "^1.4.0",
35
- "@ossy/sdk": "^1.4.0",
36
- "@ossy/sdk-react": "^1.4.0",
37
- "@ossy/themes": "^1.4.0",
30
+ "@ossy/connected-components": "^1.5.0",
31
+ "@ossy/design-system": "^1.5.0",
32
+ "@ossy/pages": "^1.5.0",
33
+ "@ossy/router": "^1.5.0",
34
+ "@ossy/router-react": "^1.5.0",
35
+ "@ossy/sdk": "^1.5.0",
36
+ "@ossy/sdk-react": "^1.5.0",
37
+ "@ossy/themes": "^1.5.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": "69e80ed4e43a04263df106e0f504c6d2fb55e0fb"
70
+ "gitHead": "b1a36350ae22ae6776163952e3bf03b2a6cb6498"
71
71
  }