@alxia/react-router 0.8.1 → 0.9.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.
Files changed (56) hide show
  1. package/README.md +107 -8
  2. package/dist/chunks/index-zqa30gr7.js +139 -0
  3. package/dist/chunks/index-zqa30gr7.js.map +12 -0
  4. package/dist/pwa/index.d.ts +14 -0
  5. package/dist/pwa/index.d.ts.map +1 -0
  6. package/dist/pwa/index.js +165 -0
  7. package/dist/pwa/index.js.map +14 -0
  8. package/dist/pwa/model/caching.d.ts +46 -0
  9. package/dist/pwa/model/caching.d.ts.map +1 -0
  10. package/dist/pwa/model/clear-app-caches.d.ts +9 -0
  11. package/dist/pwa/model/clear-app-caches.d.ts.map +1 -0
  12. package/dist/pwa/model/manifest.d.ts +80 -0
  13. package/dist/pwa/model/manifest.d.ts.map +1 -0
  14. package/dist/pwa/model/precache-list.d.ts +40 -0
  15. package/dist/pwa/model/precache-list.d.ts.map +1 -0
  16. package/dist/pwa/model/registration.d.ts +39 -0
  17. package/dist/pwa/model/registration.d.ts.map +1 -0
  18. package/dist/pwa/model/start-service-worker.d.ts +24 -0
  19. package/dist/pwa/model/start-service-worker.d.ts.map +1 -0
  20. package/dist/pwa/model/storable.d.ts +8 -0
  21. package/dist/pwa/model/storable.d.ts.map +1 -0
  22. package/dist/pwa/model/update-notice.d.ts +38 -0
  23. package/dist/pwa/model/update-notice.d.ts.map +1 -0
  24. package/dist/pwa/model/worker-contract.d.ts +61 -0
  25. package/dist/pwa/model/worker-contract.d.ts.map +1 -0
  26. package/dist/pwa/react/index.d.ts +9 -0
  27. package/dist/pwa/react/index.d.ts.map +1 -0
  28. package/dist/pwa/react/index.js +75 -0
  29. package/dist/pwa/react/index.js.map +13 -0
  30. package/dist/pwa/react/use-online.d.ts +6 -0
  31. package/dist/pwa/react/use-online.d.ts.map +1 -0
  32. package/dist/pwa/react/use-service-worker.d.ts +33 -0
  33. package/dist/pwa/react/use-service-worker.d.ts.map +1 -0
  34. package/dist/pwa/react/use-update-notice.d.ts +14 -0
  35. package/dist/pwa/react/use-update-notice.d.ts.map +1 -0
  36. package/dist/pwa/server/index.d.ts +7 -0
  37. package/dist/pwa/server/index.d.ts.map +1 -0
  38. package/dist/pwa/server/index.js +18 -0
  39. package/dist/pwa/server/index.js.map +10 -0
  40. package/dist/pwa/server/no-cache.d.ts +22 -0
  41. package/dist/pwa/server/no-cache.d.ts.map +1 -0
  42. package/docs/README.md +12 -3
  43. package/docs/guide/beside-the-pages.md +178 -0
  44. package/docs/guide/csp-nonce.md +100 -0
  45. package/docs/guide/customising-the-server.md +292 -0
  46. package/docs/guide/deploying.md +99 -0
  47. package/docs/guide/getting-started.md +112 -0
  48. package/docs/guide/how-it-works.md +262 -0
  49. package/docs/guide/openapi.md +51 -0
  50. package/docs/guide/pwa.md +475 -0
  51. package/docs/guide/testing.md +42 -0
  52. package/docs/guide/typing-the-loaders.md +311 -0
  53. package/docs/guide.md +27 -1391
  54. package/docs/roadmap.md +25 -1
  55. package/docs/troubleshooting.md +194 -8
  56. package/package.json +26 -4
package/docs/roadmap.md CHANGED
@@ -11,10 +11,17 @@ Nothing in progress.
11
11
 
12
12
  ## Next
13
13
 
14
- Nothing scheduled yet.
14
+ - **The service worker and its build.** A worker of Workbox strategies over
15
+ `cachingFor` and `isStorable`, and the build that writes it, reading
16
+ `precacheList` and possibly run by `/vite`'s `alxia()`, with the `workbox-*`
17
+ packages as optional peers. Until it ships, the worker and its build stay
18
+ the app's.
15
19
 
16
20
  ## Later
17
21
 
22
+ - **A check of an offline page's policy.** The offline page declares its
23
+ Content-Security-Policy in a `<meta>`; a check would read the page and
24
+ confirm that each inline script and style is allowed by its hash.
18
25
  - **`context.alxia` typed under `Route.LoaderArgs`.** Once react-router's
19
26
  `./internal` types and its main entry share one `RouterContextProvider`
20
27
  declaration, the generated route types see the shorthand too; today
@@ -48,6 +55,23 @@ Nothing scheduled yet.
48
55
 
49
56
  ## Shipped
50
57
 
58
+ ### 0.9.0
59
+
60
+ - **`@alxia/react-router/pwa`.** The code with no UI an installable app
61
+ shares, importing nothing: the service worker's contract and cache names
62
+ (`defineWorkerContract`), which requests the worker caches and which
63
+ responses it may store (`cachingFor`, `isStorable`), the precache list read
64
+ from the build, registering the worker and the update notice's store, the
65
+ web app manifest with its language in `?lang=`, and `clearAppCaches` for
66
+ sign-out. Every app-specific name is an option, so two apps never share a
67
+ default ([guide](guide/pwa.md)).
68
+ - **`@alxia/react-router/pwa/react`.** `useOnline`, `useServiceWorker({
69
+ enabled })` and `useUpdateNotice`, with the page's one `updateNotice`;
70
+ `react` is an optional peer.
71
+ - **`@alxia/react-router/pwa/server`.** `noCache` serves the worker's
72
+ script revalidated on every update check, with the worker's own policy
73
+ (`revalidated` and `WORKER_POLICY` beneath it).
74
+
51
75
  ### 0.8.0
52
76
 
53
77
  - **`withAlxia(fn)`.** A loader, an action or a middleware given `alxia`,
@@ -38,6 +38,10 @@ a loader, a message React Router or the browser prints, or an error from
38
38
  - [`error: lockfile had changes, but lockfile is frozen`](#error-lockfile-had-changes-but-lockfile-is-frozen)
39
39
  - [`EACCES: permission denied, open '/app/…'`](#eacces-permission-denied-open-app)
40
40
  - [`error: Cannot find package '…' from '/app/build/server/index.js'`](#error-cannot-find-package--from-appbuildserverindexjs)
41
+ - [`TypeError: defineWorkerContract(): cachePrefix must be a non-empty name, …`](#typeerror-defineworkercontract-cacheprefix-must-be-a-non-empty-name-)
42
+ - [`TypeError: defineWorkerContract(): cacheVersion must be a non-empty name without '-', …`](#typeerror-defineworkercontract-cacheversion-must-be-a-non-empty-name-without---)
43
+ - [`parseBrowserManifest(): not React Router's browser manifest …`](#parsebrowsermanifest-not-react-routers-browser-manifest-)
44
+ - [`error: Cannot find package 'react' from '…/@alxia/react-router/dist/pwa/react/index.js'`](#error-cannot-find-package-react-from-alxiareact-routerdistpwareactindexjs)
41
45
 
42
46
  **Types**
43
47
 
@@ -63,6 +67,13 @@ a loader, a message React Router or the browser prints, or an error from
63
67
  - [A `publish` under `react-router dev` misses the sockets opened before an edit](#a-publish-under-react-router-dev-misses-the-sockets-opened-before-an-edit)
64
68
  - [The build has a package's Node variant, not its `bun` one](#the-build-has-a-packages-node-variant-not-its-bun-one)
65
69
  - [`request.url` in a loader is `http://` and the internal host behind a proxy](#requesturl-in-a-loader-is-http-and-the-internal-host-behind-a-proxy)
70
+ - [An unhashed file under `public/assets/` is cached for a year](#an-unhashed-file-under-publicassets-is-cached-for-a-year)
71
+ - [A cache the contract did not make is swept](#a-cache-the-contract-did-not-make-is-swept)
72
+ - [The update notice never shows](#the-update-notice-never-shows)
73
+ - [The worker registers under `react-router dev`](#the-worker-registers-under-react-router-dev)
74
+ - [An update waits an hour](#an-update-waits-an-hour)
75
+ - [The worker cannot fetch another origin](#the-worker-cannot-fetch-another-origin)
76
+ - [The manifest is in the wrong language](#the-manifest-is-in-the-wrong-language)
66
77
 
67
78
  ## Thrown or printed
68
79
 
@@ -133,7 +144,7 @@ key: one copy is the fix for both.
133
144
  sets.
134
145
 
135
146
  **Fix:** add `alxia()` to `vite.config.ts`, as in the
136
- [setup](guide.md#setup). With a server of your own in a monorepo, tell
147
+ [setup](guide/getting-started.md). With a server of your own in a monorepo, tell
137
148
  Vite to leave the package external:
138
149
 
139
150
  ```ts
@@ -210,7 +221,7 @@ reactRouter(app, { build, getLoadContext: ({ user }, context) => context.set(use
210
221
  **Fix:** serve the app with the plugin, `alxia()` in `vite.config.ts`: the
211
222
  server is then built with the routes, and `app/context.ts` is one module
212
223
  for both, in dev and in the build. See
213
- [the app's own context keys](guide.md#the-apps-own-context-keys).
224
+ [the app's own context keys](guide/typing-the-loaders.md#the-apps-own-context-keys).
214
225
 
215
226
  Without the plugin, read alxia's context with `alxiaOf`: its key,
216
227
  `alxiaContext`, lives in this package under `node_modules`, which Vite
@@ -245,7 +256,7 @@ export default server;
245
256
  ```
246
257
 
247
258
  An alxia app of your own, with `reactRouter()` on it, is served without the
248
- plugin: see [a server of your own](guide.md#a-server-of-your-own-without-the-plugin).
259
+ plugin: see [a server of your own](guide/customising-the-server.md#a-server-of-your-own-without-the-plugin).
249
260
 
250
261
  ### `alxia-react-router: the entry … does not exist. …`
251
262
 
@@ -465,7 +476,7 @@ export default createServer({
465
476
 
466
477
  or `contentSecurityPolicy: false`. Better than `'unsafe-inline'`: a nonce
467
478
  per request, with `nonce: true` and `nonceOf(loadContext)` in
468
- `entry.server.tsx` ([guide](guide.md#a-csp-nonce)).
479
+ `entry.server.tsx` ([guide](guide/csp-nonce.md#a-csp-nonce)).
469
480
 
470
481
  ### `alxia-react-router: … already exists, and reveal leaves it as it is. Run alxia-react-router reveal --force to overwrite it.`
471
482
 
@@ -651,7 +662,7 @@ bun add -d typescript@^6
651
662
  and uses it outside its `loader` and `action`, in the component or at the
652
663
  module's top level. React Router keeps that code in the client build, for
653
664
  the browser, which has no such module. The server build leaves Bun's
654
- modules external ([Built for Bun](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide.md#built-for-bun));
665
+ modules external ([Built for Bun](https://github.com/softistx/alxia/blob/develop/packages/react-router/docs/guide/how-it-works.md#built-for-bun));
655
666
  the client build cannot.
656
667
 
657
668
  **Fix:** use them only in the server's code: in `loader` and `action`, or
@@ -735,7 +746,7 @@ The image runs `bun --no-install`: without the flag, Bun finds no
735
746
  whatever version npm has, instead of failing.
736
747
 
737
748
  **Why:** under `react-router build` the plugin bundles every package into
738
- `build/server/index.js` ([Self-contained](guide.md#self-contained)), so
749
+ `build/server/index.js` ([Self-contained](guide/how-it-works.md#self-contained)), so
739
750
  the image needs no `node_modules`. What stays outside the file must be
740
751
  installed beside it.
741
752
 
@@ -770,6 +781,75 @@ addon built for glibc alone then stops it with
770
781
  put the final stage back on `oven/bun:1`
771
782
  ([`@alxia/create`'s troubleshooting](https://github.com/softistx/alxia/blob/develop/packages/create/docs/troubleshooting.md#error--is-linked-against-glibc-dt_needed-libmso6-but-this-bun-build-uses-musl)).
772
783
 
784
+ ### `TypeError: defineWorkerContract(): cachePrefix must be a non-empty name, …`
785
+
786
+ The full message is `defineWorkerContract(): cachePrefix must be a non-empty
787
+ name, such as 'my-app'; got ''.`, or `… must not end with '-', which the
788
+ contract adds; got 'my-app-'. Use 'my-app'.`
789
+
790
+ **Why:** every cache name is `<prefix>-<kind>-<version>`, and the worker
791
+ deletes the caches shaped `<prefix>-<kind>-<version>`. An empty prefix would own
792
+ every cache of the origin, and a trailing dash would be doubled.
793
+
794
+ **Fix:** pass the app's own name, without the dash:
795
+
796
+ ```ts
797
+ import { defineWorkerContract } from '@alxia/react-router/pwa';
798
+
799
+ export const workerContract = defineWorkerContract({ cachePrefix: 'my-app' });
800
+ ```
801
+
802
+ ### `TypeError: defineWorkerContract(): cacheVersion must be a non-empty name without '-', …`
803
+
804
+ The full message is `defineWorkerContract(): cacheVersion must be a
805
+ non-empty name without '-', such as 'v2'; got 'v1-beta'.`
806
+
807
+ **Why:** every cache name is `<prefix>-<kind>-<version>`, and the contract
808
+ tells a version from the rest of the name by its dashes. A version with a `-`
809
+ (or an empty one) would make the name ambiguous.
810
+
811
+ **Fix:** use a name with no dash, such as `'v2'` or `'2026'`:
812
+
813
+ ```ts
814
+ import { defineWorkerContract } from '@alxia/react-router/pwa';
815
+
816
+ export const workerContract = defineWorkerContract({
817
+ cachePrefix: 'my-app',
818
+ cacheVersion: 'v2',
819
+ });
820
+ ```
821
+
822
+ ### `parseBrowserManifest(): not React Router's browser manifest …`
823
+
824
+ The full message ends with `(build/client/assets/manifest-*.js).`
825
+
826
+ **Why:** the source holds no `{ … }` object. The build script read another
827
+ file, an empty one, or the build has not run.
828
+
829
+ **Fix:** run `react-router build` first, then read the file named
830
+ `manifest-<hash>.js` in `build/client/assets`, not the server's manifest:
831
+
832
+ ```ts
833
+ import { readdirSync, readFileSync } from 'node:fs';
834
+ import { parseBrowserManifest } from '@alxia/react-router/pwa';
835
+
836
+ const assets = 'build/client/assets';
837
+ const file = readdirSync(assets).find((name) => /^manifest-.*\.js$/.test(name));
838
+ if (!file) throw new Error('Run react-router build first.');
839
+ export const manifest = parseBrowserManifest(readFileSync(`${assets}/${file}`, 'utf8'));
840
+ ```
841
+
842
+ ### `error: Cannot find package 'react' from '…/@alxia/react-router/dist/pwa/react/index.js'`
843
+
844
+ **Why:** `@alxia/react-router/pwa/react` imports `react`, an optional peer of
845
+ the package, so nothing installs it for you. An app with no `react` does not
846
+ need the subpath; a build script or the worker importing it by mistake meets
847
+ this message too.
848
+
849
+ **Fix:** add `react` where the page is built (`bun add react`), and import
850
+ `/pwa/react` from the page alone. The worker and a build script import
851
+ `@alxia/react-router/pwa`, which imports nothing.
852
+
773
853
  ## Types
774
854
 
775
855
  ### `Property 'alxia' does not exist on type 'Readonly<RouterContextProvider>'`
@@ -989,7 +1069,7 @@ following Content Security Policy directive: "script-src 'self'
989
1069
  attribute.
990
1070
 
991
1071
  **Fix:** reveal the entry and pass `nonceOf(loadContext)` to both
992
- ([guide](guide.md#a-csp-nonce)). A script of your own reads the nonce
1072
+ ([guide](guide/csp-nonce.md#a-csp-nonce)). A script of your own reads the nonce
993
1073
  through a loader, where `nonceOf(context)` works as well:
994
1074
 
995
1075
  ```tsx
@@ -1119,7 +1199,7 @@ plugin relays the app's sockets to. So `ctx.server` is that side server: its
1119
1199
  and its `requestIP` and `timeout` know nothing of a request Vite took, so
1120
1200
  the default `ctx.ip` is `undefined`. A `page()` (Bun's HTML bundle) is not
1121
1201
  served: Vite answers the HTML
1122
- ([The server](guide.md#the-server-server)).
1202
+ ([The server](guide/typing-the-loaders.md#the-server-server)).
1123
1203
 
1124
1204
  **Fix:** read `ctx.server` as optional, which also covers `app.request` in
1125
1205
  a test, and take nothing from its `url` or `requestIP` in dev:
@@ -1188,3 +1268,109 @@ export default createServer({ proxy: trustProxy({ trusted: ['10.0.0.0/8'] }) });
1188
1268
 
1189
1269
  React Router then gets its request at `originalUrl(ctx)`
1190
1270
  ([Behind a proxy](https://github.com/softistx/alxia/blob/develop/packages/core/docs/guide/serving.md#behind-a-proxy-proxy)).
1271
+
1272
+ ### An unhashed file under `public/assets/` is cached for a year
1273
+
1274
+ A file you put in `public/assets/` (a sprite, an icon) changes on a deploy,
1275
+ and visitors keep the old one.
1276
+
1277
+ **Why:** Vite copies `public/` into `build/client/`, and the client's files
1278
+ under `build/client/assets/` are served `public, max-age=31536000,
1279
+ immutable`, hashed or not. The worker's `cachingFor` agrees by default:
1280
+ everything under `/assets/` is `immutable`, cache-first.
1281
+
1282
+ **Fix:** keep unhashed files out of `assets/`: `public/icons/` is served for
1283
+ an hour and is `static` for the worker. If they must stay there, give
1284
+ `cachingFor` an `immutable` option that leaves their folder out, so the worker
1285
+ revalidates them ([the option](guide/pwa.md#what-the-worker-caches)),
1286
+ and expect the HTTP cache to hold them for a year until the file's name
1287
+ changes.
1288
+
1289
+ ### A cache the contract did not make is swept
1290
+
1291
+ Signing out, or a new worker activating, deletes a cache the app made itself.
1292
+
1293
+ **Why:** a contract owns every cache named exactly
1294
+ `<prefix>-<kind>-<version>`, kind being lowercase letters and digits and
1295
+ version having no `-`. That includes a kind the app retired (`my-app-pages-v0` is swept once
1296
+ it is not current). It is also why `app` and `app-admin` can share an origin:
1297
+ `app-admin-assets-v1` has one segment too many to be `app`'s. Contracts never
1298
+ take each other's caches; only a cache made by other code, such as
1299
+ `my-app-runtime-v1`, matches the shape and is swept.
1300
+
1301
+ **Fix:** name your own caches outside the shape. A name is outside it when it
1302
+ has more than `<kind>-<version>` after `<prefix>-`, with the prefix `my-app`:
1303
+ `my-app-runtime-v1-x`. A kind with an uppercase letter, `_` or `.`
1304
+ (`my-app-Runtime-v1`, `my-app-run_time-v1`), or a different prefix, is outside
1305
+ too.
1306
+
1307
+ ### The update notice never shows
1308
+
1309
+ A new version is deployed and the page offers no "Reload".
1310
+
1311
+ **Why:** the notice is offered only when a worker finished installing while
1312
+ an older one controls the page. A first install controls nothing, so it
1313
+ offers nothing; the next visit, with the first worker in control, does. And
1314
+ nothing is registered at all where the app does not call
1315
+ `registerServiceWorker` (for example while `useServiceWorker({ enabled })`
1316
+ is given `false`, as `import.meta.env.PROD` is under `react-router dev`). A
1317
+ tab that chose "Later" stays quiet until the next session.
1318
+
1319
+ **Fix:** build, serve and load the page twice, then deploy a change and load
1320
+ it again. In the console, `navigator.serviceWorker.controller` must not be
1321
+ `null` and `(await navigator.serviceWorker.getRegistration()).waiting` must
1322
+ hold the new worker.
1323
+
1324
+ ### The worker registers under `react-router dev`
1325
+
1326
+ The dev server serves stale code after an edit, or a page keeps an old
1327
+ version of itself, and `navigator.serviceWorker.controller` is not `null`.
1328
+
1329
+ **Why:** `useServiceWorker` registers whenever `enabled` is `true`, and the
1330
+ package does not know the mode: it never reads `import.meta.env`. A worker
1331
+ under a dev server caches the code you are editing.
1332
+
1333
+ **Fix:** pass the mode from the app, `useServiceWorker({ enabled:
1334
+ import.meta.env.PROD })` ([the hook](guide/pwa.md#in-react)). Then unregister
1335
+ the worker the dev server already took (DevTools, Application, Service
1336
+ Workers, Unregister) and clear its site data.
1337
+
1338
+ ### An update waits an hour
1339
+
1340
+ A new worker is deployed and tabs still run the old one for up to an hour.
1341
+
1342
+ **Why:** the worker's script was served with the client's hour of
1343
+ `Cache-Control`, so the browser's update check found the cached script.
1344
+ Either `noCache` is not declared, or it is declared in `configure`, which
1345
+ runs after the client's files: they answer first and the middleware never
1346
+ sees the request.
1347
+
1348
+ **Fix:** declare it in `beforeAll`
1349
+ ([serving the worker's script](guide/pwa.md#serving-the-workers-script)), and
1350
+ check with `curl -I https://your.app/service-worker.js` that `cache-control` is
1351
+ `no-cache`.
1352
+
1353
+ ### The worker cannot fetch another origin
1354
+
1355
+ The console reports `Refused to connect to 'https://api.example.com/…' because it violates the following Content Security Policy directive: "connect-src 'self'"` from the worker.
1356
+
1357
+ **Why:** `noCache` gives the worker's script `WORKER_POLICY`,
1358
+ `default-src 'none'; connect-src 'self'`: the worker fetches this site only.
1359
+
1360
+ **Fix:** if the worker really must reach another origin, serve the script
1361
+ with a wider policy through `revalidated(response, policy)` in a middleware of
1362
+ your own ([serving the worker's script](guide/pwa.md#serving-the-workers-script)),
1363
+ rather than loosening the pages' policy.
1364
+
1365
+ ### The manifest is in the wrong language
1366
+
1367
+ The installed app's name and description are in the default language,
1368
+ whatever the user chose.
1369
+
1370
+ **Why:** the browser fetches the manifest without cookies, so the `language`
1371
+ cookie never reaches the server. Only the link's query does.
1372
+
1373
+ **Fix:** link `manifestHref(language)` (`/manifest.webmanifest?lang=fr`), and
1374
+ read it with `manifestLanguage(url, supported, fallback)`; the fallback is a
1375
+ supported language the app resolves from the request's `Accept-Language`, not
1376
+ from the cookie ([the manifest route](guide/pwa.md#the-web-app-manifest-and-why-the-language-travels-in-lang)).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@alxia/react-router",
3
- "version": "0.8.1",
4
- "description": "alxia as the server of a React Router framework app: server rendering behind the app's hooks, loaders reading its typed context, the client's assets served",
3
+ "version": "0.9.0",
4
+ "description": "alxia as the server of a React Router framework app: server rendering behind the app's hooks, loaders reading its typed context, the client's assets served; the code with no UI an installable app shares (`/pwa`), its hooks (`/pwa/react`) and `noCache` for the worker's script (`/pwa/server`)",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -27,6 +27,21 @@
27
27
  "import": "./dist/vite/index.js",
28
28
  "default": "./dist/vite/index.js"
29
29
  },
30
+ "./pwa": {
31
+ "types": "./dist/pwa/index.d.ts",
32
+ "import": "./dist/pwa/index.js",
33
+ "default": "./dist/pwa/index.js"
34
+ },
35
+ "./pwa/react": {
36
+ "types": "./dist/pwa/react/index.d.ts",
37
+ "import": "./dist/pwa/react/index.js",
38
+ "default": "./dist/pwa/react/index.js"
39
+ },
40
+ "./pwa/server": {
41
+ "types": "./dist/pwa/server/index.d.ts",
42
+ "import": "./dist/pwa/server/index.js",
43
+ "default": "./dist/pwa/server/index.js"
44
+ },
30
45
  "./package.json": "./package.json"
31
46
  },
32
47
  "repository": {
@@ -47,12 +62,15 @@
47
62
  "entrypoints": [
48
63
  "src/index.ts",
49
64
  "src/vite/index.ts",
65
+ "src/pwa/index.ts",
66
+ "src/pwa/react/index.ts",
67
+ "src/pwa/server/index.ts",
50
68
  "src/cli/index.ts"
51
69
  ]
52
70
  },
53
71
  "devDependencies": {
54
72
  "@alxia/compress": "^0.3.10",
55
- "@alxia/core": "^0.15.0",
73
+ "@alxia/core": "^0.15.1",
56
74
  "@alxia/openapi": "^0.6.10",
57
75
  "@react-router/dev": "^8.5.0",
58
76
  "@types/bun": "^1.4.2",
@@ -65,12 +83,16 @@
65
83
  "vite": "^7.0.0"
66
84
  },
67
85
  "peerDependencies": {
68
- "@alxia/core": "^0.15.0",
86
+ "@alxia/core": "^0.15.1",
87
+ "react": "^19.0.0",
69
88
  "react-router": "^8.0.0",
70
89
  "typescript": "^6.0.3 || ^7.0.0",
71
90
  "vite": "^7.0.0 || ^8.0.0"
72
91
  },
73
92
  "peerDependenciesMeta": {
93
+ "react": {
94
+ "optional": true
95
+ },
74
96
  "vite": {
75
97
  "optional": true
76
98
  }