@ossy/app 3.15.0 → 3.17.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.task.js CHANGED
@@ -409,7 +409,11 @@ export async function build (cliArgs = []) {
409
409
  external: (id) => {
410
410
  if (id.startsWith('node:') || NODE_BUILTINS.has(id)) return true
411
411
  if (id === 'sharp' || id.startsWith('@img/sharp-')) return true
412
- // Singleton packages — must not be bundled into entry chunks
412
+ // Singleton packages — must not be bundled into entry chunks.
413
+ // Exception: `@ossy/platform/storage-keys` is a pure browser-safe helper
414
+ // imported by client resource UI; leaving it external breaks hydration
415
+ // (bare specifier with no import map).
416
+ if (id === '@ossy/platform/storage-keys') return false
413
417
  if (id === '@ossy/platform' || id.startsWith('@ossy/platform/')) return true
414
418
  if (id === '@ossy/event-store' || id.startsWith('@ossy/event-store/')) return true
415
419
  if (id === '@ossy/observability' || id.startsWith('@ossy/observability/')) return true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/app",
3
- "version": "3.15.0",
3
+ "version": "3.17.0",
4
4
  "description": "",
5
5
  "source": "./src/index.js",
6
6
  "main": "./src/index.js",
@@ -50,21 +50,21 @@
50
50
  "@babel/preset-react": "^7.26.3",
51
51
  "@babel/register": "^7.25.9",
52
52
  "@ossy/authentication": "^3.11.1",
53
- "@ossy/design-system": "^3.15.0",
53
+ "@ossy/design-system": "^3.17.0",
54
54
  "@ossy/locale": "^3.4.0",
55
- "@ossy/manifest": "^3.15.0",
56
- "@ossy/package-catalog": "^3.15.0",
55
+ "@ossy/manifest": "^3.17.0",
56
+ "@ossy/package-catalog": "^3.17.0",
57
57
  "@ossy/pages": "^3.0.9",
58
- "@ossy/platform": "^3.15.0",
59
- "@ossy/resources": "^3.15.0",
58
+ "@ossy/platform": "^3.17.0",
59
+ "@ossy/resources": "^3.17.0",
60
60
  "@ossy/router": "^3.0.9",
61
- "@ossy/router-react": "^3.15.0",
62
- "@ossy/schema": "^3.15.0",
63
- "@ossy/sdk": "^3.12.0",
61
+ "@ossy/router-react": "^3.17.0",
62
+ "@ossy/schema": "^3.17.0",
63
+ "@ossy/sdk": "^3.17.0",
64
64
  "@ossy/sdk-react": "^3.12.0",
65
65
  "@ossy/themes": "^3.8.0",
66
- "@ossy/users": "^3.15.0",
67
- "@ossy/workspaces": "^3.15.0",
66
+ "@ossy/users": "^3.17.0",
67
+ "@ossy/workspaces": "^3.17.0",
68
68
  "@rollup/plugin-alias": "^6.0.0",
69
69
  "@rollup/plugin-babel": "^7.1.0",
70
70
  "@rollup/plugin-commonjs": "^29.0.0",
@@ -98,5 +98,5 @@
98
98
  "README.md",
99
99
  "tsconfig.json"
100
100
  ],
101
- "gitHead": "23517232ddc4f2c64ca0062faa3cad84ceaa34a7"
101
+ "gitHead": "91ff7dffe9b0bddcb823daee67213d2008eb64e9"
102
102
  }
@@ -54,5 +54,13 @@ export function defaultAppSettings() {
54
54
  * need live cross-tab cache updates (see @ossy/sdk-react README).
55
55
  */
56
56
  enablePushInvalidation: false,
57
+ /**
58
+ * SSR-only device hint (`Sec-CH-UA-Mobile` client hint / UA sniff —
59
+ * see `@ossy/platform`'s `detectMobileDevice`). Seeds
60
+ * `useCompactShellLayout`'s `getServerSnapshot` so mobile requests
61
+ * don't flash the desktop sidenav before hydration resolves the
62
+ * real `matchMedia` value (#871).
63
+ */
64
+ isMobileDevice: false,
57
65
  }
58
66
  }
@@ -1,5 +1,6 @@
1
- import { useSyncExternalStore } from 'react'
1
+ import { useCallback, useSyncExternalStore } from 'react'
2
2
  import { COMPACT_SHELL_MEDIA_QUERY } from './shellChrome.js'
3
+ import { useApp } from './AppContext.js'
3
4
 
4
5
  export { COMPACT_SHELL_MEDIA_QUERY }
5
6
 
@@ -15,10 +16,20 @@ function getSnapshot () {
15
16
  return window.matchMedia(COMPACT_SHELL_MEDIA_QUERY).matches
16
17
  }
17
18
 
18
- function getServerSnapshot () {
19
- return false
20
- }
21
-
19
+ /**
20
+ * Resolves whether the app shell should render compact (mobile) chrome.
21
+ *
22
+ * `getServerSnapshot` is seeded from `AppContext.isMobileDevice` — a
23
+ * server-computed guess based on the `Sec-CH-UA-Mobile` client hint /
24
+ * User-Agent (see `@ossy/platform`'s `detectMobileDevice`) — instead of
25
+ * hardcoding `false`. Without this, SSR always assumed desktop, so mobile
26
+ * requests rendered the full desktop sidenav and snapped closed on
27
+ * hydration (#871). The client still re-resolves the real value via
28
+ * `matchMedia` once mounted; a wrong guess only causes one corrective
29
+ * re-render instead of a guaranteed flash on every mobile page load.
30
+ */
22
31
  export function useCompactShellLayout () {
32
+ const { isMobileDevice } = useApp()
33
+ const getServerSnapshot = useCallback(() => isMobileDevice === true, [isMobileDevice])
23
34
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)
24
35
  }
@@ -33,10 +33,11 @@ export default function DefaultHeader ({
33
33
  {...rest}
34
34
  far={(
35
35
  <View
36
- layout="row"
36
+ layout="row-wrap"
37
37
  style={{
38
- flexShrink: 0,
38
+ minWidth: 0,
39
39
  alignItems: 'center',
40
+ justifyContent: 'flex-end',
40
41
  gap: compact ? 'var(--space-xs)' : 'var(--space-s)',
41
42
  }}
42
43
  >