@rsc-kit/core 0.9.0 → 0.11.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 (50) hide show
  1. package/dist/action.d.ts +21 -0
  2. package/dist/action.js +67 -36
  3. package/dist/action.js.map +1 -1
  4. package/dist/apiPrerender.d.ts +33 -0
  5. package/dist/apiPrerender.js +200 -0
  6. package/dist/apiPrerender.js.map +1 -0
  7. package/dist/appAssets.d.ts +30 -0
  8. package/dist/appAssets.js +90 -0
  9. package/dist/appAssets.js.map +1 -0
  10. package/dist/buildReport.d.ts +43 -0
  11. package/dist/buildReport.js +40 -0
  12. package/dist/buildReport.js.map +1 -0
  13. package/dist/host.d.ts +12 -0
  14. package/dist/host.js +148 -2
  15. package/dist/host.js.map +1 -1
  16. package/dist/js/RouteErrorBoundary.d.ts +36 -0
  17. package/dist/js/RouteErrorBoundary.js +43 -0
  18. package/dist/js/RouteErrorBoundary.js.map +1 -0
  19. package/dist/js/queryClient.js +21 -1
  20. package/dist/js/queryClient.js.map +1 -1
  21. package/dist/manifest.d.ts +33 -0
  22. package/dist/manifest.js.map +1 -1
  23. package/dist/notFound.d.ts +24 -0
  24. package/dist/notFound.js +107 -0
  25. package/dist/notFound.js.map +1 -0
  26. package/dist/prerender.d.ts +48 -4
  27. package/dist/prerender.js +79 -9
  28. package/dist/prerender.js.map +1 -1
  29. package/dist/query.d.ts +23 -0
  30. package/dist/query.js +45 -3
  31. package/dist/query.js.map +1 -1
  32. package/dist/redirect.d.ts +8 -0
  33. package/dist/redirect.js +11 -1
  34. package/dist/redirect.js.map +1 -1
  35. package/dist/request.d.ts +27 -0
  36. package/dist/request.js +50 -6
  37. package/dist/request.js.map +1 -1
  38. package/dist/routeSchema.d.ts +115 -0
  39. package/dist/routeSchema.js +182 -0
  40. package/dist/routeSchema.js.map +1 -0
  41. package/dist/routing.d.ts +20 -1
  42. package/dist/routing.js +30 -7
  43. package/dist/routing.js.map +1 -1
  44. package/dist/vite.d.ts +34 -1
  45. package/dist/vite.js +837 -33
  46. package/dist/vite.js.map +1 -1
  47. package/dist/webManifest.d.ts +54 -0
  48. package/dist/webManifest.js +81 -0
  49. package/dist/webManifest.js.map +1 -0
  50. package/package.json +17 -1
@@ -0,0 +1,54 @@
1
+ /** What `rscKit({ manifest })` takes. */
2
+ export interface WebManifestOptions {
3
+ /** The app's name, as an install prompt shows it. */
4
+ name: string;
5
+ /** The short name a home screen uses when there is no room for the full one. */
6
+ shortName?: string;
7
+ description?: string;
8
+ /**
9
+ * The icons a browser may install.
10
+ *
11
+ * Paths relative to the client output — a file in `public/` is served at its
12
+ * own name, so `icon-192.png` is usually right. Sizes and types are read from
13
+ * the filename rather than declared twice.
14
+ *
15
+ * A browser will not offer to install an app with no icon of at least 192px,
16
+ * so the build says so rather than writing a manifest that quietly does
17
+ * nothing.
18
+ */
19
+ icons?: string[];
20
+ /** Where an installed launch lands. Defaults to `/`. */
21
+ startUrl?: string;
22
+ /** Defaults to `standalone`, which is the one that looks like an app. */
23
+ display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
24
+ /** The colour a browser paints its chrome. Also emitted as a meta tag. */
25
+ themeColor?: string;
26
+ /** The colour behind the app while it is starting. */
27
+ backgroundColor?: string;
28
+ /** Anything else the spec allows, passed through untouched. */
29
+ other?: Record<string, unknown>;
30
+ }
31
+ /** Where the manifest is written and linked from. */
32
+ export declare const MANIFEST_PATH = "/manifest.webmanifest";
33
+ /**
34
+ * The size a filename claims, or null.
35
+ *
36
+ * `icon-192.png` and `icon-192x192.png` both read as 192. Declaring it in the
37
+ * options as well would be the same number written twice, and the one that
38
+ * drifts is the one nobody looks at.
39
+ */
40
+ export declare function sizeOf(file: string): number | null;
41
+ /** The manifest's JSON, ready to write. */
42
+ export declare function webManifest(options: WebManifestOptions): string;
43
+ /**
44
+ * Whether these options produce something a browser would actually install.
45
+ *
46
+ * Returned as a sentence rather than thrown: a manifest with no icon is still
47
+ * a valid manifest and still sets the theme colour, so refusing the build over
48
+ * it would be refusing something that works. But an author who wrote
49
+ * `manifest: {...}` meant "installable", and silence here is how they find out
50
+ * months later that it never was.
51
+ */
52
+ export declare function manifestWarning(options: WebManifestOptions): string | null;
53
+ /** The type a src/app/manifest.ts file satisfies. */
54
+ export type WebManifest = WebManifestOptions;
@@ -0,0 +1,81 @@
1
+ // The file that makes an app installable.
2
+ //
3
+ // A service worker makes an app work offline; this is what makes a browser
4
+ // offer to put it on a home screen. They are separate decisions and separate
5
+ // options, because an app can want either without the other — a site that
6
+ // should survive a dead network is not necessarily one anybody wants as an
7
+ // icon, and vice versa.
8
+ //
9
+ // Everything here is the web app manifest spec rather than an invention of
10
+ // this package, so the names are its names and anything it accepts that is not
11
+ // spelled out below can be passed through `other`.
12
+ /** Where the manifest is written and linked from. */
13
+ export const MANIFEST_PATH = '/manifest.webmanifest';
14
+ /**
15
+ * The size a filename claims, or null.
16
+ *
17
+ * `icon-192.png` and `icon-192x192.png` both read as 192. Declaring it in the
18
+ * options as well would be the same number written twice, and the one that
19
+ * drifts is the one nobody looks at.
20
+ */
21
+ export function sizeOf(file) {
22
+ const match = /(\d{2,4})(?:x\d{2,4})?\.(?:png|webp|jpg|jpeg|svg)$/i.exec(file);
23
+ return match ? Number(match[1]) : null;
24
+ }
25
+ function typeOf(file) {
26
+ const extension = file.slice(file.lastIndexOf('.') + 1).toLowerCase();
27
+ return extension === 'svg'
28
+ ? 'image/svg+xml'
29
+ : extension === 'jpg' || extension === 'jpeg'
30
+ ? 'image/jpeg'
31
+ : `image/${extension}`;
32
+ }
33
+ /** The manifest's JSON, ready to write. */
34
+ export function webManifest(options) {
35
+ const icons = (options.icons ?? []).map((file) => {
36
+ const size = sizeOf(file);
37
+ return {
38
+ src: file.startsWith('/') ? file : `/${file}`,
39
+ type: typeOf(file),
40
+ ...(size ? { sizes: `${size}x${size}` } : {}),
41
+ // Maskable as well as any: without it Android crops a square icon into a
42
+ // circle and takes the corners off whatever is in them.
43
+ purpose: 'any maskable',
44
+ };
45
+ });
46
+ return (JSON.stringify({
47
+ name: options.name,
48
+ short_name: options.shortName ?? options.name,
49
+ ...(options.description ? { description: options.description } : {}),
50
+ start_url: options.startUrl ?? '/',
51
+ display: options.display ?? 'standalone',
52
+ ...(options.themeColor ? { theme_color: options.themeColor } : {}),
53
+ ...(options.backgroundColor ? { background_color: options.backgroundColor } : {}),
54
+ ...(icons.length ? { icons } : {}),
55
+ ...(options.other ?? {}),
56
+ }, null, 2) + '\n');
57
+ }
58
+ /**
59
+ * Whether these options produce something a browser would actually install.
60
+ *
61
+ * Returned as a sentence rather than thrown: a manifest with no icon is still
62
+ * a valid manifest and still sets the theme colour, so refusing the build over
63
+ * it would be refusing something that works. But an author who wrote
64
+ * `manifest: {...}` meant "installable", and silence here is how they find out
65
+ * months later that it never was.
66
+ */
67
+ export function manifestWarning(options) {
68
+ const icons = options.icons ?? [];
69
+ if (icons.length === 0) {
70
+ return 'manifest: no icons, so no browser will offer to install this. Add a 192px and a 512px png.';
71
+ }
72
+ const largest = icons.reduce((best, file) => Math.max(best, sizeOf(file) ?? 0), 0);
73
+ if (largest < 192) {
74
+ return 'manifest: no icon of 192px or more, which is the smallest a browser will install. Sizes are read from the filename, so name it like icon-192.png.';
75
+ }
76
+ if (largest < 512) {
77
+ return 'manifest: no 512px icon, so a splash screen will be upscaled from a smaller one.';
78
+ }
79
+ return null;
80
+ }
81
+ //# sourceMappingURL=webManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webManifest.js","sourceRoot":"","sources":["../src/webManifest.ts"],"names":[],"mappings":"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","sourcesContent":["// The file that makes an app installable.\n//\n// A service worker makes an app work offline; this is what makes a browser\n// offer to put it on a home screen. They are separate decisions and separate\n// options, because an app can want either without the other — a site that\n// should survive a dead network is not necessarily one anybody wants as an\n// icon, and vice versa.\n//\n// Everything here is the web app manifest spec rather than an invention of\n// this package, so the names are its names and anything it accepts that is not\n// spelled out below can be passed through `other`.\n\n/** What `rscKit({ manifest })` takes. */\nexport interface WebManifestOptions {\n /** The app's name, as an install prompt shows it. */\n name: string\n /** The short name a home screen uses when there is no room for the full one. */\n shortName?: string\n description?: string\n /**\n * The icons a browser may install.\n *\n * Paths relative to the client output — a file in `public/` is served at its\n * own name, so `icon-192.png` is usually right. Sizes and types are read from\n * the filename rather than declared twice.\n *\n * A browser will not offer to install an app with no icon of at least 192px,\n * so the build says so rather than writing a manifest that quietly does\n * nothing.\n */\n icons?: string[]\n /** Where an installed launch lands. Defaults to `/`. */\n startUrl?: string\n /** Defaults to `standalone`, which is the one that looks like an app. */\n display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser'\n /** The colour a browser paints its chrome. Also emitted as a meta tag. */\n themeColor?: string\n /** The colour behind the app while it is starting. */\n backgroundColor?: string\n /** Anything else the spec allows, passed through untouched. */\n other?: Record<string, unknown>\n}\n\n/** Where the manifest is written and linked from. */\nexport const MANIFEST_PATH = '/manifest.webmanifest'\n\n/**\n * The size a filename claims, or null.\n *\n * `icon-192.png` and `icon-192x192.png` both read as 192. Declaring it in the\n * options as well would be the same number written twice, and the one that\n * drifts is the one nobody looks at.\n */\nexport function sizeOf(file: string): number | null {\n const match = /(\\d{2,4})(?:x\\d{2,4})?\\.(?:png|webp|jpg|jpeg|svg)$/i.exec(file)\n\n return match ? Number(match[1]) : null\n}\n\nfunction typeOf(file: string): string {\n const extension = file.slice(file.lastIndexOf('.') + 1).toLowerCase()\n\n return extension === 'svg'\n ? 'image/svg+xml'\n : extension === 'jpg' || extension === 'jpeg'\n ? 'image/jpeg'\n : `image/${extension}`\n}\n\n/** The manifest's JSON, ready to write. */\nexport function webManifest(options: WebManifestOptions): string {\n const icons = (options.icons ?? []).map((file) => {\n const size = sizeOf(file)\n\n return {\n src: file.startsWith('/') ? file : `/${file}`,\n type: typeOf(file),\n ...(size ? { sizes: `${size}x${size}` } : {}),\n // Maskable as well as any: without it Android crops a square icon into a\n // circle and takes the corners off whatever is in them.\n purpose: 'any maskable',\n }\n })\n\n return (\n JSON.stringify(\n {\n name: options.name,\n short_name: options.shortName ?? options.name,\n ...(options.description ? { description: options.description } : {}),\n start_url: options.startUrl ?? '/',\n display: options.display ?? 'standalone',\n ...(options.themeColor ? { theme_color: options.themeColor } : {}),\n ...(options.backgroundColor ? { background_color: options.backgroundColor } : {}),\n ...(icons.length ? { icons } : {}),\n ...(options.other ?? {}),\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\n/**\n * Whether these options produce something a browser would actually install.\n *\n * Returned as a sentence rather than thrown: a manifest with no icon is still\n * a valid manifest and still sets the theme colour, so refusing the build over\n * it would be refusing something that works. But an author who wrote\n * `manifest: {...}` meant \"installable\", and silence here is how they find out\n * months later that it never was.\n */\nexport function manifestWarning(options: WebManifestOptions): string | null {\n const icons = options.icons ?? []\n\n if (icons.length === 0) {\n return 'manifest: no icons, so no browser will offer to install this. Add a 192px and a 512px png.'\n }\n\n const largest = icons.reduce((best, file) => Math.max(best, sizeOf(file) ?? 0), 0)\n\n if (largest < 192) {\n return 'manifest: no icon of 192px or more, which is the smallest a browser will install. Sizes are read from the filename, so name it like icon-192.png.'\n }\n\n if (largest < 512) {\n return 'manifest: no 512px icon, so a splash screen will be upscaled from a smaller one.'\n }\n\n return null\n}\n\n/** The type a src/app/manifest.ts file satisfies. */\nexport type WebManifest = WebManifestOptions\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsc-kit/core",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "React Server Components on any JavaScript server: a Vite plugin that discovers the route tree, and a host adapter that serves it.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,6 +25,10 @@
25
25
  "types": "./dist/runtime.d.ts",
26
26
  "default": "./dist/runtime.js"
27
27
  },
28
+ "./RouteErrorBoundary": {
29
+ "types": "./dist/js/RouteErrorBoundary.d.ts",
30
+ "default": "./dist/js/RouteErrorBoundary.js"
31
+ },
28
32
  "./metadata": {
29
33
  "types": "./dist/metadata.d.ts",
30
34
  "default": "./dist/metadata.js"
@@ -160,6 +164,18 @@
160
164
  "./action": {
161
165
  "types": "./dist/action.d.ts",
162
166
  "default": "./dist/action.js"
167
+ },
168
+ "./not-found": {
169
+ "types": "./dist/notFound.d.ts",
170
+ "default": "./dist/notFound.js"
171
+ },
172
+ "./route-schema": {
173
+ "types": "./dist/routeSchema.d.ts",
174
+ "default": "./dist/routeSchema.js"
175
+ },
176
+ "./manifest-file": {
177
+ "types": "./dist/webManifest.d.ts",
178
+ "default": "./dist/webManifest.js"
163
179
  }
164
180
  },
165
181
  "peerDependencies": {