@pablozaiden/webapp 0.4.0 → 0.4.1

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.
@@ -48,7 +48,21 @@ const app = createWebAppServer({
48
48
  await app.runFromCli();
49
49
  ```
50
50
 
51
- The `pwa` option is optional; by default the framework derives install metadata from `appName`, serves `/manifest.webmanifest`, and injects the manifest/icon/mobile head tags into the shell HTML. Configure `icons`, `appleTouchIcon`, `startUrl`, and `scope` when your app ships specific install assets.
51
+ The `pwa` option is optional; by default the framework derives install metadata from `appName` and serves `/manifest.webmanifest`. Configure `icons`, `appleTouchIcon`, `startUrl`, and `scope` when your app serves the manifest dynamically through the framework.
52
+
53
+ For the recommended Bun `HTMLBundle` shape (`import webIndex from "./index.html"`), keep the install metadata static and relative to `index.html` so Bun can bundle and rewrite those assets:
54
+
55
+ ```html
56
+ <link rel="manifest" href="./site.webmanifest" />
57
+ <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
58
+ <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
59
+ <meta name="mobile-web-app-capable" content="yes" />
60
+ <meta name="apple-mobile-web-app-capable" content="yes" />
61
+ <meta name="apple-mobile-web-app-title" content="MyApp" />
62
+ <meta name="theme-color" content="#111827" />
63
+ ```
64
+
65
+ Place `site.webmanifest`, icons, and apple-touch icons next to `index.html`, and reference manifest icons with relative paths such as `"./web-app-manifest-192x192.png"`. A single SVG favicon is enough for lightweight examples; production apps should include PNG manifest icons and an Apple touch icon like Clanky. For string, `Blob`, or `Response` HTML indexes, the framework injects equivalent tags automatically.
52
66
 
53
67
  Apps should stay one app and one binary. Use subcommands for different modes:
54
68
 
package/docs/server.md CHANGED
@@ -96,7 +96,7 @@ Built-in endpoints include:
96
96
 
97
97
  ## PWA metadata
98
98
 
99
- `createWebAppServer` provides shell-level PWA metadata so apps do not need to duplicate manifest and icon tags in every `index.html`. PWA support is enabled by default with `appName`-derived manifest values, `/manifest.webmanifest`, `/` start/scope, `standalone` display, and conventional icon paths (`/web-app-manifest-192x192.png`, `/web-app-manifest-512x512.png`, and `/apple-touch-icon.png`).
99
+ `createWebAppServer` provides shell-level PWA metadata. PWA support is enabled by default with `appName`-derived manifest values, `/manifest.webmanifest`, `/` start/scope, `standalone` display, and conventional icon paths (`/web-app-manifest-192x192.png`, `/web-app-manifest-512x512.png`, and `/apple-touch-icon.png`).
100
100
 
101
101
  ```ts
102
102
  createWebAppServer({
@@ -118,7 +118,9 @@ createWebAppServer({
118
118
  });
119
119
  ```
120
120
 
121
- The framework serves the manifest with `application/manifest+json; charset=utf-8` and injects the installability tags into HTML shell responses:
121
+ The framework serves the manifest with `application/manifest+json; charset=utf-8`.
122
+
123
+ For string, `Blob`, or `Response` HTML indexes, the framework also injects the installability tags into HTML shell responses:
122
124
 
123
125
  ```html
124
126
  <link rel="manifest" href="/manifest.webmanifest" />
@@ -130,6 +132,37 @@ The framework serves the manifest with `application/manifest+json; charset=utf-8
130
132
  <meta name="theme-color" content="#111827" />
131
133
  ```
132
134
 
135
+ For Bun `HTMLBundle` indexes imported from `index.html`, Bun must serve the HTML and generated assets directly so module rewriting and transpilation keep working. In that mode the framework still serves `/manifest.webmanifest`, but it does not mutate the HTML response. Follow the Clanky-style static asset pattern instead: place `site.webmanifest`, favicons, and apple-touch icons next to `index.html`, then reference them with relative paths so Bun can bundle and rewrite them:
136
+
137
+ ```html
138
+ <link rel="manifest" href="./site.webmanifest" />
139
+ <link rel="icon" href="./favicon.ico" sizes="any" />
140
+ <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
141
+ <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
142
+ <meta name="mobile-web-app-capable" content="yes" />
143
+ <meta name="apple-mobile-web-app-capable" content="yes" />
144
+ <meta name="apple-mobile-web-app-title" content="MyApp" />
145
+ <meta name="theme-color" content="#111827" />
146
+ ```
147
+
148
+ Use relative icon paths inside `site.webmanifest` as well:
149
+
150
+ ```json
151
+ {
152
+ "name": "My App",
153
+ "short_name": "MyApp",
154
+ "start_url": "./",
155
+ "scope": "./",
156
+ "display": "standalone",
157
+ "background_color": "#ffffff",
158
+ "theme_color": "#111827",
159
+ "icons": [
160
+ { "src": "./web-app-manifest-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
161
+ { "src": "./web-app-manifest-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
162
+ ]
163
+ }
164
+ ```
165
+
133
166
  Icon files still need to exist in the app bundle or public routes; the framework advertises and serves metadata, but it does not generate image assets. Set `pwa: { enabled: false }` to opt out. Apps that already serve `/manifest.webmanifest` through `publicRoutes` can keep that override; explicit public routes take precedence over the generated manifest.
134
167
 
135
168
  ## Public/static routes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pablozaiden/webapp",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Opinionated Bun + React webapp framework for single-server apps",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1105,6 +1105,8 @@ export function createWebAppServer<TEvent = unknown>(input: WebAppServerConfig<T
1105
1105
  const dynamicHandler = (req: Request, server: Server<WebAppWebSocketData>) => handleRequest(req, server);
1106
1106
  const publicRouteHandlers = Object.fromEntries(Object.keys(publicRoutes).map((path) => [path, dynamicHandler]));
1107
1107
  const pwaRouteHandlers = pwa && !hasOwnPublicRoute(publicRoutes, pwa.manifestPath) ? { [pwa.manifestPath]: dynamicHandler } : {};
1108
+ const indexCanRespond = canRespondWithIndex(input.index);
1109
+ const indexIsHtmlBundle = isHtmlBundleIndex(input.index);
1108
1110
  const server = Bun.serve<WebAppWebSocketData>({
1109
1111
  hostname: config.host,
1110
1112
  port: config.port,
@@ -1113,9 +1115,9 @@ export function createWebAppServer<TEvent = unknown>(input: WebAppServerConfig<T
1113
1115
  ...pwaRouteHandlers,
1114
1116
  "/api/*": dynamicHandler,
1115
1117
  "/.well-known/*": dynamicHandler,
1116
- "/device": deviceAuthEnabled && !canRespondWithIndex(input.index) ? input.index as never : dynamicHandler,
1117
- "/setup": passkeysEnabled && !canRespondWithIndex(input.index) ? input.index as never : dynamicHandler,
1118
- "/*": canRespondWithIndex(input.index) ? dynamicHandler : input.index as never,
1118
+ "/device": deviceAuthEnabled && (!indexCanRespond || indexIsHtmlBundle) ? input.index as never : dynamicHandler,
1119
+ "/setup": passkeysEnabled && (!indexCanRespond || indexIsHtmlBundle) ? input.index as never : dynamicHandler,
1120
+ "/*": indexCanRespond && !indexIsHtmlBundle ? dynamicHandler : input.index as never,
1119
1121
  },
1120
1122
  websocket: {
1121
1123
  open(socket) {