@ossy/app 1.11.5 → 1.11.6

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
@@ -21,11 +21,9 @@ export const metadata = { path: { en: '/about', sv: '/om' } }
21
21
  export default () => <h1>About</h1>
22
22
  ```
23
23
 
24
- For a single-file setup, use `src/pages.jsx` (legacy).
24
+ During `dev` / `build`, the tooling writes **JSON manifests** under **`build/.ossy/`**: **`pages.generated.json`** (after compile: route ids, paths, `sourceFile`, merged `metadata`, and **`module`** — a `page-modules/<id>.mjs` path used for lazy `import()` in the browser and on SSR), **`pages.bundle.json`** (compiled module index), plus the same pattern for API and tasks. Small **`*.runtime.mjs`** loaders (copied from `@ossy/app`) load the app shell; **`pages.runtime.mjs`** exports the route table from **`pages.generated.json`** only. The server exposes compiled page modules at **`/__ossy/page-modules/`** for same-origin dynamic imports.
25
25
 
26
- During `dev` / `build`, the tooling writes **JSON manifests** under **`build/.ossy/`**: **`pages.generated.json`** (route ids, default paths, and `sourceFile` paths), **`pages.bundle.json`** (compiled `page-modules/<id>.mjs` paths), plus the same pattern for API and tasks (`*.generated.json` / `*.bundle.json`). Small **`*.runtime.mjs`** loaders (copied from `@ossy/app`) dynamically `import()` those compiled modules at runtime.
27
-
28
- **Client JS (per-page):** For each `*.page.jsx`, the build emits **`build/.ossy/hydrate-<pageId>.jsx`** → **`public/static/hydrate-<pageId>.js`**. The HTML for a request only loads the hydrate script for the **current** route (full document navigation), so other pages’ components are not part of that entry. React and shared dependencies still go into hashed shared chunks. The inline config (`window.__INITIAL_APP_CONFIG__`) no longer includes the full `pages` list—only request-time fields (theme, `apiUrl`, etc.).
26
+ **Client JS (per-page):** For each `*.page.jsx`, the build emits **`build/.ossy/hydrate-<pageId>.jsx`** **`public/static/<pageId>.js`**. The HTML for a request only loads the hydrate script for the **current** route (full document navigation), so other pages’ components are not part of that entry. React and shared dependencies still go into hashed shared chunks. The inline config (`window.__INITIAL_APP_CONFIG__`) no longer includes the full `pages` list—only request-time fields (theme, `apiUrl`, etc.).
29
27
 
30
28
  Add `src/config.js` for workspace and theme:
31
29
 
package/cli/build.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import path from 'path';
2
2
  import url from 'url';
3
3
  import fs from 'fs';
4
+ import { pathToFileURL } from 'node:url'
4
5
  import { rollup } from 'rollup';
5
6
  import babel from '@rollup/plugin-babel';
6
7
  import { nodeResolve as resolveDependencies } from '@rollup/plugin-node-resolve'
@@ -67,6 +68,9 @@ export const OSSY_API_RUNTIME_BASENAME = 'api.runtime.mjs'
67
68
  export const OSSY_TASKS_RUNTIME_BASENAME = 'tasks.runtime.mjs'
68
69
 
69
70
  export const OSSY_PAGE_MODULES_DIRNAME = 'page-modules'
71
+
72
+ /** Express serves compiled page modules here for browser `import()`. Must match `server.js`. */
73
+ export const OSSY_PAGE_MODULE_WEB_PREFIX = '/__ossy/page-modules'
70
74
  /** Tiny Rollup inputs that re-export `metadata` so per-page server bundles keep i18n paths. */
71
75
  export const OSSY_PAGE_SERVER_ENTRIES_DIRNAME = 'page-server-entries'
72
76
  export const OSSY_API_MODULES_DIRNAME = 'api-modules'
@@ -385,7 +389,8 @@ export async function compilePageServerModules ({
385
389
  for (const f of pageFiles) {
386
390
  const pageId = clientHydrateIdForPage(f, srcDir)
387
391
  const safeId = String(pageId).replace(/[^a-zA-Z0-9_-]+/g, '-') || 'page'
388
- const outName = `${safeId}.mjs`
392
+ const relPath = pageServerModuleRelPath(f, srcDir)
393
+ const outName = path.posix.basename(relPath)
389
394
  const outFile = path.join(modsDir, outName)
390
395
  const stubPath = path.join(entriesDir, `${safeId}.mjs`)
391
396
  writePageServerRollupEntry({ pageAbsPath: f, stubPath })
@@ -398,7 +403,7 @@ export async function compilePageServerModules ({
398
403
  })
399
404
  bundlePages.push({
400
405
  id: pageId,
401
- module: `${OSSY_PAGE_MODULES_DIRNAME}/${outName}`,
406
+ module: relPath,
402
407
  })
403
408
  }
404
409
  return bundlePages
@@ -448,6 +453,50 @@ export async function compileTaskServerModules ({ taskFiles, ossyDir, nodeEnv, o
448
453
  return modules
449
454
  }
450
455
 
456
+ /**
457
+ * Merges compiled `metadata` + `module` into `pages.generated.json` (same order as `pageBundleList`).
458
+ * Enables lazy `import()` in the browser and Node without putting `Component` on the route object.
459
+ */
460
+ export async function enrichPagesGeneratedManifest ({
461
+ ossyDir,
462
+ pagesGeneratedPath,
463
+ pageBundleList,
464
+ }) {
465
+ if (!pageBundleList?.length || !fs.existsSync(pagesGeneratedPath)) return
466
+ const raw = JSON.parse(fs.readFileSync(pagesGeneratedPath, 'utf8'))
467
+ const basePages = raw?.pages
468
+ if (!Array.isArray(basePages) || basePages.length !== pageBundleList.length) {
469
+ throw new Error(
470
+ '[@ossy/app] pages.generated.json page count must match compiled page modules (re-run build).'
471
+ )
472
+ }
473
+ const pages = []
474
+ for (let i = 0; i < basePages.length; i++) {
475
+ const abs = path.join(ossyDir, pageBundleList[i].module)
476
+ const mod = await import(pathToFileURL(abs).href)
477
+ const meta = mod?.metadata && typeof mod.metadata === 'object' ? mod.metadata : {}
478
+ const derived = { id: basePages[i].id, path: basePages[i].path }
479
+ const merged = {
480
+ ...derived,
481
+ ...meta,
482
+ sourceFile: basePages[i].sourceFile,
483
+ module: pageBundleList[i].module,
484
+ }
485
+ try {
486
+ JSON.stringify(merged)
487
+ } catch {
488
+ pages.push({
489
+ ...derived,
490
+ sourceFile: basePages[i].sourceFile,
491
+ module: pageBundleList[i].module,
492
+ })
493
+ continue
494
+ }
495
+ pages.push(merged)
496
+ }
497
+ writeOssyJson(pagesGeneratedPath, { version: raw.version ?? 1, pages })
498
+ }
499
+
451
500
  /**
452
501
  * Writes `pages.bundle.json`, `api.bundle.json`, `tasks.bundle.json` by Rollup-compiling each source module.
453
502
  */
@@ -477,6 +526,11 @@ export async function compileOssyNodeArtifacts ({
477
526
  version: 1,
478
527
  modules: taskModuleList,
479
528
  })
529
+ await enrichPagesGeneratedManifest({
530
+ ossyDir,
531
+ pagesGeneratedPath: path.join(ossyDir, OSSY_GEN_PAGES_BASENAME),
532
+ pageBundleList,
533
+ })
480
534
  }
481
535
 
482
536
  export function filePathToRoute(filePath, srcDir) {
@@ -489,7 +543,7 @@ export function filePathToRoute(filePath, srcDir) {
489
543
  }
490
544
 
491
545
  /**
492
- * Basename for `/static/hydrate-<id>.js` must match `route.id` after `metadata` is merged in `toPage`
546
+ * Basename for `/static/<id>.js` (per-page client bundle) must match `route.id` after `metadata` is merged in `toPage`
493
547
  * (`{ ...derived, ...metadata }`). Uses a light `metadata` scan when possible.
494
548
  */
495
549
  export function clientHydrateIdForPage (pageAbsPath, srcDir) {
@@ -507,6 +561,13 @@ export function clientHydrateIdForPage (pageAbsPath, srcDir) {
507
561
  return idMatch ? idMatch[1] : derived.id
508
562
  }
509
563
 
564
+ /** Posix path relative to `build/.ossy/` for the compiled server/browser page module. */
565
+ export function pageServerModuleRelPath (pageAbsPath, srcDir) {
566
+ const pageId = clientHydrateIdForPage(pageAbsPath, srcDir)
567
+ const safeId = String(pageId).replace(/[^a-zA-Z0-9_-]+/g, '-') || 'page'
568
+ return `${OSSY_PAGE_MODULES_DIRNAME}/${safeId}.mjs`
569
+ }
570
+
510
571
  export function pageSourceExportsMetadata (pageAbsPath) {
511
572
  try {
512
573
  const src = fs.readFileSync(pageAbsPath, 'utf8')
@@ -539,37 +600,35 @@ export function writePageServerRollupEntry ({ pageAbsPath, stubPath }) {
539
600
  }
540
601
 
541
602
  /**
542
- * One client entry per page: imports only that page module and hydrates the document.
543
- * Keeps the same `toPage` shape as `pages.runtime.mjs` + manifests so SSR and client trees match.
603
+ * One client entry per page: `import()` the compiled page module URL, then hydrates the document.
544
604
  */
545
605
  export function generatePageHydrateModule ({ pageAbsPath, stubAbsPath, srcDir }) {
546
- const rel = relToGeneratedImport(stubAbsPath, pageAbsPath)
547
- const { id, path: routePath } = filePathToRoute(pageAbsPath, srcDir)
548
- const pathLiteral = JSON.stringify(routePath)
549
- const idLiteral = JSON.stringify(id)
606
+ void stubAbsPath
607
+ const outName = path.posix.basename(pageServerModuleRelPath(pageAbsPath, srcDir))
608
+ const pageImportUrl = `${OSSY_PAGE_MODULE_WEB_PREFIX}/${outName}`
609
+ const pageImportLiteral = JSON.stringify(pageImportUrl)
550
610
  return [
551
611
  '// Generated by @ossy/app — do not edit',
552
612
  '',
553
- "import React, { cloneElement } from 'react'",
613
+ "import React, { createElement } from 'react'",
554
614
  "import 'react-dom'",
555
615
  "import { hydrateRoot } from 'react-dom/client'",
556
- `import * as _page from './${rel}'`,
557
616
  '',
558
- 'function toPage(mod, derived) {',
559
- ' const meta = mod?.metadata || {}',
560
- ' const def = mod?.default',
561
- ' if (typeof def === \'function\') {',
562
- ' return { ...derived, ...meta, element: React.createElement(def) }',
617
+ 'async function main () {',
618
+ ' const initialConfig = window.__INITIAL_APP_CONFIG__ || {}',
619
+ ` const _page = await import(${pageImportLiteral})`,
620
+ ' const Page = _page?.default',
621
+ ' if (typeof Page !== \'function\') {',
622
+ ' throw new Error(`[@ossy/app] Page must export default as a function component`)',
563
623
  ' }',
564
- ' return { ...derived, ...meta, ...(def || {}) }',
624
+ ' const rootTree = createElement(Page, initialConfig)',
625
+ ' hydrateRoot(document, rootTree)',
565
626
  '}',
566
627
  '',
567
- `const _route = toPage(_page, { id: ${idLiteral}, path: ${pathLiteral} })`,
568
- 'const initialConfig = window.__INITIAL_APP_CONFIG__ || {}',
569
- 'const rootTree = _route?.element',
570
- ' ? cloneElement(_route.element, initialConfig)',
571
- " : React.createElement('p', null, 'Not found')",
572
- 'hydrateRoot(document, rootTree)',
628
+ 'main().catch((err) => {',
629
+ ' console.error(err)',
630
+ " document.body.innerHTML = '<p style=\\'font-family:sans-serif;padding:1rem\\'>Hydration failed.</p>'",
631
+ '})',
573
632
  '',
574
633
  ].join('\n')
575
634
  }
@@ -646,33 +705,30 @@ export function parsePagesFromManifestJson (manifestPath) {
646
705
  const data = JSON.parse(raw)
647
706
  const pages = data?.pages
648
707
  if (!Array.isArray(pages)) return []
649
- return pages.map((p) => ({ id: p.id, path: p.path }))
708
+ return pages.map((p) => ({
709
+ id: p.id,
710
+ path: p.path,
711
+ ...(typeof p.module === 'string' ? { module: p.module } : {}),
712
+ }))
650
713
  } catch {
651
714
  return []
652
715
  }
653
716
  }
654
717
 
655
- export function parsePagesFromSource(filePath) {
718
+ /**
719
+ * Best-effort scan of a source file for `{ id, path }` literals (e.g. `*.api.js` default export).
720
+ * Used only for the build dashboard API list — **not** for page discovery (`*.page.jsx` only).
721
+ */
722
+ export function parseIdPathPairsFromFile (filePath) {
656
723
  try {
657
724
  const content = fs.readFileSync(filePath, 'utf8')
658
725
  const items = []
659
- // Match { id: 'x', path: '/y' } or { id: "x", path: "/y" }
660
726
  const idPathPattern = /\{\s*id\s*:\s*['"]([^'"]*)['"]\s*,\s*path\s*:\s*['"]([^'"]*)['"]/g
661
- // Match { path: '/y', element: ... } (path-first)
662
- const pathElementPattern = /\{\s*path\s*:\s*['"]([^'"]*)['"]\s*,\s*element\s*:/g
663
- // Match { path: { en: '/x', sv: '/y' }, ... }
664
727
  const pathObjPattern = /\{\s*path\s*:\s*\{\s*([^}]+)\}/g
665
728
  let m
666
729
  while ((m = idPathPattern.exec(content)) !== null) {
667
730
  items.push({ id: m[1], path: m[2] })
668
731
  }
669
- if (items.length === 0) {
670
- while ((m = pathElementPattern.exec(content)) !== null) {
671
- const p = m[1]
672
- const id = p === '/' ? 'home' : p.replace(/^\//, '').replace(/\/$/, '').replace(/\//g, '-') || 'page'
673
- items.push({ id, path: p })
674
- }
675
- }
676
732
  if (items.length === 0) {
677
733
  while ((m = pathObjPattern.exec(content)) !== null) {
678
734
  const pathStr = m[1].replace(/\s/g, '').replace(/:/g, ': ')
@@ -707,7 +763,7 @@ export function getBuildOverviewSnapshot ({
707
763
 
708
764
  const apiRoutes = []
709
765
  for (const f of apiOverviewFiles) {
710
- if (fs.existsSync(f)) apiRoutes.push(...parsePagesFromSource(f))
766
+ if (fs.existsSync(f)) apiRoutes.push(...parseIdPathPairsFromFile(f))
711
767
  }
712
768
 
713
769
  return { configRel, pages, apiRoutes }
package/cli/dev.js CHANGED
@@ -132,7 +132,7 @@ export const dev = async (cliArgs) => {
132
132
  entryFileNames ({ name }) {
133
133
  if (name.startsWith('hydrate__')) {
134
134
  const pageId = name.slice('hydrate__'.length)
135
- return `static/hydrate-${pageId}.js`
135
+ return `static/${pageId}.js`
136
136
  }
137
137
  return 'static/[name].js'
138
138
  },
@@ -1,7 +1,6 @@
1
1
  import fs from 'node:fs'
2
2
  import path from 'node:path'
3
- import { fileURLToPath, pathToFileURL } from 'node:url'
4
- import React from 'react'
3
+ import { fileURLToPath } from 'node:url'
5
4
 
6
5
  const __ossyDir = path.dirname(fileURLToPath(import.meta.url))
7
6
 
@@ -9,31 +8,7 @@ function readJson (name) {
9
8
  return JSON.parse(fs.readFileSync(path.join(__ossyDir, name), 'utf8'))
10
9
  }
11
10
 
12
- function toPage (mod, derived) {
13
- const meta = mod?.metadata || {}
14
- const def = mod?.default
15
- if (typeof def === 'function') {
16
- return { ...derived, ...meta, element: React.createElement(def) }
17
- }
18
- return { ...derived, ...meta, ...(def || {}) }
19
- }
20
-
21
- const { pages: metaPages } = readJson('pages.generated.json')
22
- const { pages: bundlePages } = readJson('pages.bundle.json')
23
-
24
- if (metaPages.length !== bundlePages.length) {
25
- throw new Error(
26
- '[@ossy/app][pages.runtime] pages.generated.json and pages.bundle.json must list the same number of pages'
27
- )
28
- }
29
-
30
- const out = []
31
- for (let i = 0; i < metaPages.length; i++) {
32
- const derived = { id: metaPages[i].id, path: metaPages[i].path }
33
- const rel = bundlePages[i].module
34
- const abs = path.resolve(__ossyDir, rel)
35
- const mod = await import(pathToFileURL(abs).href)
36
- out.push(toPage(mod, derived))
37
- }
11
+ /** Route list from `pages.generated.json` (includes `module` for lazy `import()` after build). */
12
+ const { pages } = readJson('pages.generated.json')
38
13
 
39
- export default out
14
+ export default Array.isArray(pages) ? pages : []
@@ -55,7 +55,7 @@ async function bundleOneHydratePage ({
55
55
  const n = chunkInfo.name
56
56
  if (n.startsWith('hydrate__')) {
57
57
  const pageId = n.slice('hydrate__'.length)
58
- return `static/hydrate-${pageId}.js`
58
+ return `static/${pageId}.js`
59
59
  }
60
60
  return 'static/[name].js'
61
61
  },
@@ -157,7 +157,7 @@ async function prerenderPagesParallel ({
157
157
 
158
158
  const routesToRender = []
159
159
  for (const route of pageList) {
160
- if (!route?.element) continue
160
+ if (typeof route?.module !== 'string' || !route.module) continue
161
161
  if (!pathIsPrerenderable(route.path)) {
162
162
  reporter?.skipPrerender?.(
163
163
  route.id,
@@ -1,8 +1,29 @@
1
- import React, { cloneElement } from 'react'
1
+ import path from 'node:path'
2
+ import { fileURLToPath, pathToFileURL } from 'node:url'
3
+ import React, { createElement } from 'react'
2
4
  import { prerenderToNodeStream } from 'react-dom/static'
3
5
 
6
+ const __ossyDir = path.dirname(fileURLToPath(import.meta.url))
7
+
8
+ async function loadPageDefaultExport (route) {
9
+ if (typeof route?.module !== 'string' || !route.module) {
10
+ throw new Error(
11
+ `[@ossy/app][BuildPage] Route "${route?.id ?? '?'}" has no compiled module path (re-run build so pages.generated.json includes "module").`
12
+ )
13
+ }
14
+ const abs = path.join(__ossyDir, route.module)
15
+ const mod = await import(pathToFileURL(abs).href)
16
+ const def = mod?.default
17
+ if (typeof def !== 'function') {
18
+ throw new Error(
19
+ `[@ossy/app][BuildPage] Page "${route?.id}" must export default as a function component (got ${typeof def}).`
20
+ )
21
+ }
22
+ return def
23
+ }
24
+
4
25
  /**
5
- * App shell config for SSR / prerender (mirrors client: theme, pages metadata, active route element).
26
+ * App shell config for SSR / prerender (mirrors client: theme, pages metadata, props for the active page).
6
27
  */
7
28
  export function buildPrerenderAppConfig ({
8
29
  buildTimeConfig,
@@ -11,10 +32,11 @@ export function buildPrerenderAppConfig ({
11
32
  urlPath,
12
33
  isAuthenticated = false,
13
34
  }) {
14
- /** Never attach `element` here it cannot round-trip through `JSON.stringify` in the hydrate bootstrap. */
35
+ /** `module` is the lazy import path segment (see `OSSY_PAGE_MODULE_WEB_PREFIX` in the server). */
15
36
  const pages = pageList.map((page) => ({
16
37
  id: page?.id,
17
38
  path: page?.path,
39
+ ...(typeof page?.module === 'string' ? { module: page.module } : {}),
18
40
  }))
19
41
  return {
20
42
  ...buildTimeConfig,
@@ -28,11 +50,15 @@ export function buildPrerenderAppConfig ({
28
50
  }
29
51
  }
30
52
 
31
- /** Strips non-JSON content (e.g. React elements on `pages`) for the bootstrap script. */
53
+ /** Strips non-JSON content for the bootstrap script; keeps serializable route fields including `module`. */
32
54
  export function appConfigForBootstrap (appConfig) {
33
55
  if (!appConfig || typeof appConfig !== 'object') return appConfig
34
56
  const pages = Array.isArray(appConfig.pages)
35
- ? appConfig.pages.map(({ id, path }) => ({ id, path }))
57
+ ? appConfig.pages.map(({ id, path, module }) => ({
58
+ id,
59
+ path,
60
+ ...(typeof module === 'string' ? { module } : {}),
61
+ }))
36
62
  : appConfig.pages
37
63
  return { ...appConfig, pages }
38
64
  }
@@ -65,12 +91,13 @@ export function buildHydrationAppConfig (appConfig) {
65
91
  export const BuildPage = {
66
92
  async handle ({ route, appConfig, isDevReloadEnabled }) {
67
93
  const hydrationConfig = buildHydrationAppConfig(appConfig)
68
- const rootElement = cloneElement(route.element, hydrationConfig)
94
+ const Page = await loadPageDefaultExport(route)
95
+ const rootElement = createElement(Page, hydrationConfig)
69
96
  const devReloadScript = isDevReloadEnabled
70
97
  ? `(function(){try{var es=new EventSource('/__ossy_reload');es.addEventListener('reload',function(){location.reload();});}catch(e){}})();`
71
98
  : ``
72
99
 
73
- const hydrateUrl = `/static/hydrate-${route.id}.js`
100
+ const hydrateUrl = `/static/${route.id}.js`
74
101
  const { prelude } = await prerenderToNodeStream(rootElement, {
75
102
  bootstrapScriptContent: `window.__INITIAL_APP_CONFIG__ = ${JSON.stringify(hydrationConfig)};${devReloadScript}`,
76
103
  bootstrapModules: [hydrateUrl],
package/cli/server.js CHANGED
@@ -38,6 +38,7 @@ const app = express();
38
38
 
39
39
  const currentDir = path.dirname(url.fileURLToPath(import.meta.url))
40
40
  const ROOT_PATH = path.resolve(currentDir, 'public')
41
+ const OSSY_PAGE_MODULES_STATIC = path.resolve(currentDir, '.ossy', 'page-modules')
41
42
 
42
43
  const isDevReloadEnabled = process.env.OSSY_DEV_RELOAD === '1'
43
44
  const reloadClients = new Set()
@@ -121,6 +122,10 @@ const middleware = [
121
122
  ProxyInternal(),
122
123
  ]
123
124
 
125
+ const pageModuleRouter = express.Router()
126
+ pageModuleRouter.use(express.static(OSSY_PAGE_MODULES_STATIC))
127
+ app.use('/__ossy/page-modules', pageModuleRouter)
128
+
124
129
  app.use(middleware)
125
130
 
126
131
  const apiRouter = OssyRouter.of({
@@ -155,7 +160,7 @@ app.all('*all', async (req, res) => {
155
160
  }
156
161
 
157
162
  const pageRoute = pageRouter.getPageByUrl(requestUrl)
158
- if (pageRoute?.element) {
163
+ if (pageRoute?.module) {
159
164
  const appConfig = buildPrerenderAppConfig({
160
165
  buildTimeConfig,
161
166
  pageList: sitePageList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/app",
3
- "version": "1.11.5",
3
+ "version": "1.11.6",
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.11.5",
31
- "@ossy/design-system": "^1.11.5",
32
- "@ossy/pages": "^1.11.5",
33
- "@ossy/router": "^1.11.5",
34
- "@ossy/router-react": "^1.11.5",
35
- "@ossy/sdk": "^1.11.5",
36
- "@ossy/sdk-react": "^1.11.5",
37
- "@ossy/themes": "^1.11.5",
30
+ "@ossy/connected-components": "^1.11.6",
31
+ "@ossy/design-system": "^1.11.6",
32
+ "@ossy/pages": "^1.11.6",
33
+ "@ossy/router": "^1.11.6",
34
+ "@ossy/router-react": "^1.11.6",
35
+ "@ossy/sdk": "^1.11.6",
36
+ "@ossy/sdk-react": "^1.11.6",
37
+ "@ossy/themes": "^1.11.6",
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": "9dcb9e0e0a09c23690f1a8e009fa79e2961fe6d6"
70
+ "gitHead": "f9bbe1dbd426b6ee5d07021428b900c570952ea4"
71
71
  }