raktajs 0.1.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/README.md +90 -0
- package/dist/auto-import/generator.d.ts +4 -0
- package/dist/auto-import/generator.d.ts.map +1 -0
- package/dist/auto-import/index.d.ts +5 -0
- package/dist/auto-import/index.d.ts.map +1 -0
- package/dist/auto-import/index.js +153 -0
- package/dist/auto-import/index.js.map +11 -0
- package/dist/auto-import/scanner.d.ts +9 -0
- package/dist/auto-import/scanner.d.ts.map +1 -0
- package/dist/auto-import/types.d.ts +20 -0
- package/dist/auto-import/types.d.ts.map +1 -0
- package/dist/cli/build.d.ts +2 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/dev.d.ts +2 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/imports.d.ts +2 -0
- package/dist/cli/imports.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/make.d.ts +4 -0
- package/dist/cli/make.d.ts.map +1 -0
- package/dist/cli/rakta.d.ts +3 -0
- package/dist/cli/rakta.d.ts.map +1 -0
- package/dist/cli/rakta.js +1511 -0
- package/dist/cli/rakta.js.map +33 -0
- package/dist/cli/routes.d.ts +2 -0
- package/dist/cli/routes.d.ts.map +1 -0
- package/dist/cli/rpcTypes.d.ts +2 -0
- package/dist/cli/rpcTypes.d.ts.map +1 -0
- package/dist/cli/seo.d.ts +2 -0
- package/dist/cli/seo.d.ts.map +1 -0
- package/dist/cli/start.d.ts +2 -0
- package/dist/cli/start.d.ts.map +1 -0
- package/dist/components/Click.d.ts +11 -0
- package/dist/components/Click.d.ts.map +1 -0
- package/dist/components/Picture.d.ts +22 -0
- package/dist/components/Picture.d.ts.map +1 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +1383 -0
- package/dist/components/index.js.map +15 -0
- package/dist/config/defineConfig.d.ts +64 -0
- package/dist/config/defineConfig.d.ts.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +104 -0
- package/dist/config/index.js.map +11 -0
- package/dist/config/loadConfig.d.ts +4 -0
- package/dist/config/loadConfig.d.ts.map +1 -0
- package/dist/forge/build.d.ts +7 -0
- package/dist/forge/build.d.ts.map +1 -0
- package/dist/forge/devServer.d.ts +7 -0
- package/dist/forge/devServer.d.ts.map +1 -0
- package/dist/forge/index.d.ts +6 -0
- package/dist/forge/index.d.ts.map +1 -0
- package/dist/forge/index.js +579 -0
- package/dist/forge/index.js.map +17 -0
- package/dist/forge/inspect.d.ts +9 -0
- package/dist/forge/inspect.d.ts.map +1 -0
- package/dist/forge/types.d.ts +55 -0
- package/dist/forge/types.d.ts.map +1 -0
- package/dist/http/errors.d.ts +17 -0
- package/dist/http/errors.d.ts.map +1 -0
- package/dist/http/index.d.ts +4 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +154 -0
- package/dist/http/index.js.map +11 -0
- package/dist/http/panturaFetch.d.ts +33 -0
- package/dist/http/panturaFetch.d.ts.map +1 -0
- package/dist/http/types.d.ts +24 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3872 -0
- package/dist/index.js.map +50 -0
- package/dist/pwa/cache.d.ts +6 -0
- package/dist/pwa/cache.d.ts.map +1 -0
- package/dist/pwa/index.d.ts +5 -0
- package/dist/pwa/index.d.ts.map +1 -0
- package/dist/pwa/index.js +136 -0
- package/dist/pwa/index.js.map +12 -0
- package/dist/pwa/manifest.d.ts +11 -0
- package/dist/pwa/manifest.d.ts.map +1 -0
- package/dist/pwa/serviceWorker.d.ts +11 -0
- package/dist/pwa/serviceWorker.d.ts.map +1 -0
- package/dist/pwa/types.d.ts +45 -0
- package/dist/pwa/types.d.ts.map +1 -0
- package/dist/render/index.d.ts +5 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +183 -0
- package/dist/render/index.js.map +11 -0
- package/dist/render/modes.d.ts +13 -0
- package/dist/render/modes.d.ts.map +1 -0
- package/dist/render/renderer.d.ts +15 -0
- package/dist/render/renderer.d.ts.map +1 -0
- package/dist/render/types.d.ts +72 -0
- package/dist/render/types.d.ts.map +1 -0
- package/dist/router/index.d.ts +5 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +228 -0
- package/dist/router/index.js.map +12 -0
- package/dist/router/manifest.d.ts +6 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/matcher.d.ts +5 -0
- package/dist/router/matcher.d.ts.map +1 -0
- package/dist/router/scanner.d.ts +6 -0
- package/dist/router/scanner.d.ts.map +1 -0
- package/dist/router/types.d.ts +45 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/rpc/client.d.ts +24 -0
- package/dist/rpc/client.d.ts.map +1 -0
- package/dist/rpc/index.d.ts +6 -0
- package/dist/rpc/index.d.ts.map +1 -0
- package/dist/rpc/index.js +179 -0
- package/dist/rpc/index.js.map +13 -0
- package/dist/rpc/procedure.d.ts +28 -0
- package/dist/rpc/procedure.d.ts.map +1 -0
- package/dist/rpc/router.d.ts +12 -0
- package/dist/rpc/router.d.ts.map +1 -0
- package/dist/rpc/types.d.ts +48 -0
- package/dist/rpc/types.d.ts.map +1 -0
- package/dist/schema/array.d.ts +15 -0
- package/dist/schema/array.d.ts.map +1 -0
- package/dist/schema/boolean.d.ts +7 -0
- package/dist/schema/boolean.d.ts.map +1 -0
- package/dist/schema/errors.d.ts +21 -0
- package/dist/schema/errors.d.ts.map +1 -0
- package/dist/schema/index.d.ts +11 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +393 -0
- package/dist/schema/index.js.map +16 -0
- package/dist/schema/number.d.ts +17 -0
- package/dist/schema/number.d.ts.map +1 -0
- package/dist/schema/object.d.ts +19 -0
- package/dist/schema/object.d.ts.map +1 -0
- package/dist/schema/string.d.ts +18 -0
- package/dist/schema/string.d.ts.map +1 -0
- package/dist/schema/types.d.ts +27 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/seo/head.d.ts +8 -0
- package/dist/seo/head.d.ts.map +1 -0
- package/dist/seo/index.d.ts +9 -0
- package/dist/seo/index.d.ts.map +1 -0
- package/dist/seo/index.js +1578 -0
- package/dist/seo/index.js.map +17 -0
- package/dist/seo/metadata.d.ts +106 -0
- package/dist/seo/metadata.d.ts.map +1 -0
- package/dist/seo/robots.d.ts +14 -0
- package/dist/seo/robots.d.ts.map +1 -0
- package/dist/seo/sitemap.d.ts +27 -0
- package/dist/seo/sitemap.d.ts.map +1 -0
- package/dist/store/createStore.d.ts +18 -0
- package/dist/store/createStore.d.ts.map +1 -0
- package/dist/store/index.d.ts +3 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +925 -0
- package/dist/store/index.js.map +12 -0
- package/dist/store/types.d.ts +14 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/tide/adapter.d.ts +8 -0
- package/dist/tide/adapter.d.ts.map +1 -0
- package/dist/tide/index.d.ts +4 -0
- package/dist/tide/index.d.ts.map +1 -0
- package/dist/tide/index.js +477 -0
- package/dist/tide/index.js.map +16 -0
- package/dist/tide/runtime.d.ts +8 -0
- package/dist/tide/runtime.d.ts.map +1 -0
- package/dist/tide/types.d.ts +40 -0
- package/dist/tide/types.d.ts.map +1 -0
- package/package.json +128 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CacheStrategyOptions } from "./types";
|
|
2
|
+
/** Builds a versioned cache name, e.g. "rakta-shrimp-harbor-v1". */
|
|
3
|
+
export declare function buildCacheName(cacheName: string, cacheVersion: string): string;
|
|
4
|
+
/** Returns the list of URLs that should be precached, including the offline fallback. */
|
|
5
|
+
export declare function resolvePrecacheList(options: CacheStrategyOptions): string[];
|
|
6
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/pwa/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,oEAAoE;AACpE,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GAClB,MAAM,CAKR;AAED,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAK3E"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { buildCacheName, resolvePrecacheList } from "./cache";
|
|
2
|
+
export { createManifestHandler, generateManifest, generateManifestJson, } from "./manifest";
|
|
3
|
+
export { generateServiceWorkerSource } from "./serviceWorker";
|
|
4
|
+
export type { CacheStrategyOptions, ManifestDisplayMode, ManifestIcon, ManifestOptions, ServiceWorkerOptions, WebAppManifest, WebAppManifestIcon, } from "./types";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pwa/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACN,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D,YAAY,EACX,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,kBAAkB,GAClB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/pwa/cache.ts
|
|
3
|
+
function buildCacheName(cacheName, cacheVersion) {
|
|
4
|
+
const sanitizedName = cacheName.trim().toLowerCase().replace(/\s+/g, "-");
|
|
5
|
+
const sanitizedVersion = cacheVersion.trim().toLowerCase();
|
|
6
|
+
return `${sanitizedName}-${sanitizedVersion}`;
|
|
7
|
+
}
|
|
8
|
+
function resolvePrecacheList(options) {
|
|
9
|
+
const uniqueUrls = new Set(options.precacheUrls);
|
|
10
|
+
uniqueUrls.add(options.offlineFallbackUrl);
|
|
11
|
+
return Array.from(uniqueUrls);
|
|
12
|
+
}
|
|
13
|
+
// src/pwa/manifest.ts
|
|
14
|
+
function generateManifest(options) {
|
|
15
|
+
const manifestObject = {
|
|
16
|
+
name: options.name,
|
|
17
|
+
short_name: options.shortName,
|
|
18
|
+
start_url: options.startUrl ?? "/",
|
|
19
|
+
scope: options.scope ?? "/",
|
|
20
|
+
display: options.display ?? "standalone",
|
|
21
|
+
background_color: options.backgroundColor ?? "#050505",
|
|
22
|
+
theme_color: options.themeColor ?? "#dc2626",
|
|
23
|
+
icons: options.icons.map((icon) => {
|
|
24
|
+
const manifestIcon = {
|
|
25
|
+
src: icon.src,
|
|
26
|
+
sizes: icon.sizes,
|
|
27
|
+
type: icon.type
|
|
28
|
+
};
|
|
29
|
+
if (icon.purpose !== undefined) {
|
|
30
|
+
return {
|
|
31
|
+
...manifestIcon,
|
|
32
|
+
purpose: icon.purpose
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return manifestIcon;
|
|
36
|
+
})
|
|
37
|
+
};
|
|
38
|
+
if (options.description !== undefined) {
|
|
39
|
+
return {
|
|
40
|
+
...manifestObject,
|
|
41
|
+
description: options.description
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return manifestObject;
|
|
45
|
+
}
|
|
46
|
+
function generateManifestJson(options) {
|
|
47
|
+
return JSON.stringify(generateManifest(options), undefined, 2);
|
|
48
|
+
}
|
|
49
|
+
function createManifestHandler(options) {
|
|
50
|
+
return () => {
|
|
51
|
+
const manifestJson = generateManifestJson(options);
|
|
52
|
+
return new Response(manifestJson, {
|
|
53
|
+
status: 200,
|
|
54
|
+
headers: {
|
|
55
|
+
"Content-Type": "application/manifest+json; charset=utf-8",
|
|
56
|
+
"Cache-Control": "public, max-age=3600"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// src/pwa/serviceWorker.ts
|
|
62
|
+
function toJsStringArray(values) {
|
|
63
|
+
return `[${values.map((value) => JSON.stringify(value)).join(", ")}]`;
|
|
64
|
+
}
|
|
65
|
+
function generateServiceWorkerSource(options) {
|
|
66
|
+
const cacheName = buildCacheName(options.cacheName, options.cacheVersion);
|
|
67
|
+
const precacheList = resolvePrecacheList(options);
|
|
68
|
+
const offlineFallbackUrl = options.offlineFallbackUrl;
|
|
69
|
+
return `// Generated by Rakta.js ShrimpHarbor - do not edit manually.
|
|
70
|
+
// Re-run "bun rakta pwa:generate" to regenerate this file.
|
|
71
|
+
|
|
72
|
+
const CACHE_NAME = ${JSON.stringify(cacheName)};
|
|
73
|
+
const OFFLINE_FALLBACK_URL = ${JSON.stringify(offlineFallbackUrl)};
|
|
74
|
+
const PRECACHE_URLS = ${toJsStringArray(precacheList)};
|
|
75
|
+
|
|
76
|
+
self.addEventListener("install", (installEvent) => {
|
|
77
|
+
installEvent.waitUntil(
|
|
78
|
+
caches.open(CACHE_NAME).then((cache) => cache.addAll(PRECACHE_URLS)),
|
|
79
|
+
);
|
|
80
|
+
self.skipWaiting();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
self.addEventListener("activate", (activateEvent) => {
|
|
84
|
+
activateEvent.waitUntil(
|
|
85
|
+
caches.keys().then((cacheKeys) =>
|
|
86
|
+
Promise.all(
|
|
87
|
+
cacheKeys
|
|
88
|
+
.filter((cacheKey) => cacheKey !== CACHE_NAME)
|
|
89
|
+
.map((staleCacheKey) => caches.delete(staleCacheKey)),
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
);
|
|
93
|
+
self.clients.claim();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
self.addEventListener("fetch", (fetchEvent) => {
|
|
97
|
+
if (fetchEvent.request.method !== "GET") {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fetchEvent.respondWith(
|
|
102
|
+
caches.match(fetchEvent.request).then((cachedResponse) => {
|
|
103
|
+
if (cachedResponse) {
|
|
104
|
+
return cachedResponse;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return fetch(fetchEvent.request)
|
|
108
|
+
.then((networkResponse) => {
|
|
109
|
+
const responseClone = networkResponse.clone();
|
|
110
|
+
caches
|
|
111
|
+
.open(CACHE_NAME)
|
|
112
|
+
.then((cache) => cache.put(fetchEvent.request, responseClone));
|
|
113
|
+
return networkResponse;
|
|
114
|
+
})
|
|
115
|
+
.catch(() => {
|
|
116
|
+
if (fetchEvent.request.mode === "navigate") {
|
|
117
|
+
return caches.match(OFFLINE_FALLBACK_URL);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return caches.match(fetchEvent.request);
|
|
121
|
+
});
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
resolvePrecacheList,
|
|
129
|
+
generateServiceWorkerSource,
|
|
130
|
+
generateManifestJson,
|
|
131
|
+
generateManifest,
|
|
132
|
+
createManifestHandler,
|
|
133
|
+
buildCacheName
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
//# debugId=A887C53731F3975E64756E2164756E21
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["..\\..\\src\\pwa\\cache.ts", "..\\..\\src\\pwa\\manifest.ts", "..\\..\\src\\pwa\\serviceWorker.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { CacheStrategyOptions } from \"./types\";\n\n/** Builds a versioned cache name, e.g. \"rakta-shrimp-harbor-v1\". */\nexport function buildCacheName(\n\tcacheName: string,\n\tcacheVersion: string,\n): string {\n\tconst sanitizedName = cacheName.trim().toLowerCase().replace(/\\s+/g, \"-\");\n\tconst sanitizedVersion = cacheVersion.trim().toLowerCase();\n\n\treturn `${sanitizedName}-${sanitizedVersion}`;\n}\n\n/** Returns the list of URLs that should be precached, including the offline fallback. */\nexport function resolvePrecacheList(options: CacheStrategyOptions): string[] {\n\tconst uniqueUrls = new Set<string>(options.precacheUrls);\n\tuniqueUrls.add(options.offlineFallbackUrl);\n\n\treturn Array.from(uniqueUrls);\n}\n",
|
|
6
|
+
"import type { ManifestOptions, WebAppManifest } from \"./types\";\n\n/**\n * ShrimpHarbor — generates a web app manifest object for PWA installability.\n * Serialize with JSON.stringify and serve as /manifest.webmanifest.\n */\nexport function generateManifest(options: ManifestOptions): WebAppManifest {\n\tconst manifestObject: WebAppManifest = {\n\t\tname: options.name,\n\t\tshort_name: options.shortName,\n\t\tstart_url: options.startUrl ?? \"/\",\n\t\tscope: options.scope ?? \"/\",\n\t\tdisplay: options.display ?? \"standalone\",\n\t\tbackground_color: options.backgroundColor ?? \"#050505\",\n\t\ttheme_color: options.themeColor ?? \"#dc2626\",\n\t\ticons: options.icons.map((icon) => {\n\t\t\tconst manifestIcon = {\n\t\t\t\tsrc: icon.src,\n\t\t\t\tsizes: icon.sizes,\n\t\t\t\ttype: icon.type,\n\t\t\t};\n\n\t\t\tif (icon.purpose !== undefined) {\n\t\t\t\treturn {\n\t\t\t\t\t...manifestIcon,\n\t\t\t\t\tpurpose: icon.purpose,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn manifestIcon;\n\t\t}),\n\t};\n\n\tif (options.description !== undefined) {\n\t\treturn {\n\t\t\t...manifestObject,\n\t\t\tdescription: options.description,\n\t\t};\n\t}\n\n\treturn manifestObject;\n}\n\n/** Serializes the manifest to a JSON string ready to write to disk or serve. */\nexport function generateManifestJson(options: ManifestOptions): string {\n\treturn JSON.stringify(generateManifest(options), undefined, 2);\n}\n\n/** Creates a Bun/Tide-compatible request handler that serves the manifest. */\nexport function createManifestHandler(\n\toptions: ManifestOptions,\n): () => Response {\n\treturn () => {\n\t\tconst manifestJson = generateManifestJson(options);\n\n\t\treturn new Response(manifestJson, {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/manifest+json; charset=utf-8\",\n\t\t\t\t\"Cache-Control\": \"public, max-age=3600\",\n\t\t\t},\n\t\t});\n\t};\n}\n",
|
|
7
|
+
"import { buildCacheName, resolvePrecacheList } from \"./cache\";\nimport type { ServiceWorkerOptions } from \"./types\";\n\nfunction toJsStringArray(values: readonly string[]): string {\n\treturn `[${values.map((value) => JSON.stringify(value)).join(\", \")}]`;\n}\n\n/**\n * ShrimpHarbor — generates the source text of a service worker file\n * implementing a cache-first strategy with an offline fallback page.\n *\n * Write the returned string to public/sw.js in the generated app.\n * This function only produces text; it does not touch the filesystem\n * or any browser-only APIs, so it is safe to call at build time.\n */\nexport function generateServiceWorkerSource(\n\toptions: ServiceWorkerOptions,\n): string {\n\tconst cacheName = buildCacheName(options.cacheName, options.cacheVersion);\n\tconst precacheList = resolvePrecacheList(options);\n\tconst offlineFallbackUrl = options.offlineFallbackUrl;\n\n\treturn `// Generated by Rakta.js ShrimpHarbor - do not edit manually.\n// Re-run \"bun rakta pwa:generate\" to regenerate this file.\n\nconst CACHE_NAME = ${JSON.stringify(cacheName)};\nconst OFFLINE_FALLBACK_URL = ${JSON.stringify(offlineFallbackUrl)};\nconst PRECACHE_URLS = ${toJsStringArray(precacheList)};\n\nself.addEventListener(\"install\", (installEvent) => {\n installEvent.waitUntil(\n caches.open(CACHE_NAME).then((cache) => cache.addAll(PRECACHE_URLS)),\n );\n self.skipWaiting();\n});\n\nself.addEventListener(\"activate\", (activateEvent) => {\n activateEvent.waitUntil(\n caches.keys().then((cacheKeys) =>\n Promise.all(\n cacheKeys\n .filter((cacheKey) => cacheKey !== CACHE_NAME)\n .map((staleCacheKey) => caches.delete(staleCacheKey)),\n ),\n ),\n );\n self.clients.claim();\n});\n\nself.addEventListener(\"fetch\", (fetchEvent) => {\n if (fetchEvent.request.method !== \"GET\") {\n return;\n }\n\n fetchEvent.respondWith(\n caches.match(fetchEvent.request).then((cachedResponse) => {\n if (cachedResponse) {\n return cachedResponse;\n }\n\n return fetch(fetchEvent.request)\n .then((networkResponse) => {\n const responseClone = networkResponse.clone();\n caches\n .open(CACHE_NAME)\n .then((cache) => cache.put(fetchEvent.request, responseClone));\n return networkResponse;\n })\n .catch(() => {\n if (fetchEvent.request.mode === \"navigate\") {\n return caches.match(OFFLINE_FALLBACK_URL);\n }\n\n return caches.match(fetchEvent.request);\n });\n }),\n );\n});\n`;\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";;AAGO,SAAS,cAAc,CAC7B,WACA,cACS;AAAA,EACT,MAAM,gBAAgB,UAAU,KAAK,EAAE,YAAY,EAAE,QAAQ,QAAQ,GAAG;AAAA,EACxE,MAAM,mBAAmB,aAAa,KAAK,EAAE,YAAY;AAAA,EAEzD,OAAO,GAAG,iBAAiB;AAAA;AAIrB,SAAS,mBAAmB,CAAC,SAAyC;AAAA,EAC5E,MAAM,aAAa,IAAI,IAAY,QAAQ,YAAY;AAAA,EACvD,WAAW,IAAI,QAAQ,kBAAkB;AAAA,EAEzC,OAAO,MAAM,KAAK,UAAU;AAAA;;ACZtB,SAAS,gBAAgB,CAAC,SAA0C;AAAA,EAC1E,MAAM,iBAAiC;AAAA,IACtC,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,WAAW,QAAQ,YAAY;AAAA,IAC/B,OAAO,QAAQ,SAAS;AAAA,IACxB,SAAS,QAAQ,WAAW;AAAA,IAC5B,kBAAkB,QAAQ,mBAAmB;AAAA,IAC7C,aAAa,QAAQ,cAAc;AAAA,IACnC,OAAO,QAAQ,MAAM,IAAI,CAAC,SAAS;AAAA,MAClC,MAAM,eAAe;AAAA,QACpB,KAAK,KAAK;AAAA,QACV,OAAO,KAAK;AAAA,QACZ,MAAM,KAAK;AAAA,MACZ;AAAA,MAEA,IAAI,KAAK,YAAY,WAAW;AAAA,QAC/B,OAAO;AAAA,aACH;AAAA,UACH,SAAS,KAAK;AAAA,QACf;AAAA,MACD;AAAA,MAEA,OAAO;AAAA,KACP;AAAA,EACF;AAAA,EAEA,IAAI,QAAQ,gBAAgB,WAAW;AAAA,IACtC,OAAO;AAAA,SACH;AAAA,MACH,aAAa,QAAQ;AAAA,IACtB;AAAA,EACD;AAAA,EAEA,OAAO;AAAA;AAID,SAAS,oBAAoB,CAAC,SAAkC;AAAA,EACtE,OAAO,KAAK,UAAU,iBAAiB,OAAO,GAAG,WAAW,CAAC;AAAA;AAIvD,SAAS,qBAAqB,CACpC,SACiB;AAAA,EACjB,OAAO,MAAM;AAAA,IACZ,MAAM,eAAe,qBAAqB,OAAO;AAAA,IAEjD,OAAO,IAAI,SAAS,cAAc;AAAA,MACjC,QAAQ;AAAA,MACR,SAAS;AAAA,QACR,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,MAClB;AAAA,IACD,CAAC;AAAA;AAAA;;AC1DH,SAAS,eAAe,CAAC,QAAmC;AAAA,EAC3D,OAAO,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,IAAI;AAAA;AAW3D,SAAS,2BAA2B,CAC1C,SACS;AAAA,EACT,MAAM,YAAY,eAAe,QAAQ,WAAW,QAAQ,YAAY;AAAA,EACxE,MAAM,eAAe,oBAAoB,OAAO;AAAA,EAChD,MAAM,qBAAqB,QAAQ;AAAA,EAEnC,OAAO;AAAA;AAAA;AAAA,qBAGa,KAAK,UAAU,SAAS;AAAA,+BACd,KAAK,UAAU,kBAAkB;AAAA,wBACxC,gBAAgB,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
10
|
+
"debugId": "A887C53731F3975E64756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ManifestOptions, WebAppManifest } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* ShrimpHarbor — generates a web app manifest object for PWA installability.
|
|
4
|
+
* Serialize with JSON.stringify and serve as /manifest.webmanifest.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateManifest(options: ManifestOptions): WebAppManifest;
|
|
7
|
+
/** Serializes the manifest to a JSON string ready to write to disk or serve. */
|
|
8
|
+
export declare function generateManifestJson(options: ManifestOptions): string;
|
|
9
|
+
/** Creates a Bun/Tide-compatible request handler that serves the manifest. */
|
|
10
|
+
export declare function createManifestHandler(options: ManifestOptions): () => Response;
|
|
11
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/pwa/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAmCzE;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAErE;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,eAAe,GACtB,MAAM,QAAQ,CAYhB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ServiceWorkerOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* ShrimpHarbor — generates the source text of a service worker file
|
|
4
|
+
* implementing a cache-first strategy with an offline fallback page.
|
|
5
|
+
*
|
|
6
|
+
* Write the returned string to public/sw.js in the generated app.
|
|
7
|
+
* This function only produces text; it does not touch the filesystem
|
|
8
|
+
* or any browser-only APIs, so it is safe to call at build time.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateServiceWorkerSource(options: ServiceWorkerOptions): string;
|
|
11
|
+
//# sourceMappingURL=serviceWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceWorker.d.ts","sourceRoot":"","sources":["../../src/pwa/serviceWorker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAMpD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,oBAAoB,GAC3B,MAAM,CA8DR"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface ManifestIcon {
|
|
2
|
+
readonly src: string;
|
|
3
|
+
readonly sizes: string;
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly purpose?: "any" | "maskable" | "monochrome";
|
|
6
|
+
}
|
|
7
|
+
export type ManifestDisplayMode = "standalone" | "fullscreen" | "minimal-ui" | "browser";
|
|
8
|
+
export interface ManifestOptions {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly shortName: string;
|
|
11
|
+
readonly description?: string;
|
|
12
|
+
readonly startUrl?: string;
|
|
13
|
+
readonly scope?: string;
|
|
14
|
+
readonly display?: ManifestDisplayMode;
|
|
15
|
+
readonly backgroundColor?: string;
|
|
16
|
+
readonly themeColor?: string;
|
|
17
|
+
readonly icons: ManifestIcon[];
|
|
18
|
+
}
|
|
19
|
+
export interface WebAppManifestIcon {
|
|
20
|
+
src: string;
|
|
21
|
+
sizes: string;
|
|
22
|
+
type: string;
|
|
23
|
+
purpose?: "any" | "maskable" | "monochrome";
|
|
24
|
+
}
|
|
25
|
+
export interface WebAppManifest {
|
|
26
|
+
name: string;
|
|
27
|
+
short_name: string;
|
|
28
|
+
start_url: string;
|
|
29
|
+
scope: string;
|
|
30
|
+
display: ManifestDisplayMode;
|
|
31
|
+
background_color: string;
|
|
32
|
+
theme_color: string;
|
|
33
|
+
icons: WebAppManifestIcon[];
|
|
34
|
+
description?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface CacheStrategyOptions {
|
|
37
|
+
readonly cacheName: string;
|
|
38
|
+
readonly cacheVersion: string;
|
|
39
|
+
readonly precacheUrls: string[];
|
|
40
|
+
readonly offlineFallbackUrl: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ServiceWorkerOptions extends CacheStrategyOptions {
|
|
43
|
+
readonly runtimeCachePatterns?: string[];
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pwa/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,YAAY,CAAC;CACrD;AAED,MAAM,MAAM,mBAAmB,GAC5B,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,SAAS,CAAC;AAEb,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,YAAY,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,mBAAmB,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IACjE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACzC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { getModeDescriptor, isBuildTimeMode, isRoadmapMode, RENDER_MODE_DESCRIPTORS, requiresServer, resolveRouteMode, } from "./modes";
|
|
2
|
+
export type { RendererOptions } from "./renderer";
|
|
3
|
+
export { render, renderNotFound, renderServerError, } from "./renderer";
|
|
4
|
+
export type { HybridRouteEntry, RenderConfig, RenderContext, RenderFailure, RenderMode, RenderModeDescriptor, RenderResult, RenderSource, RenderSuccess, ResolvedRouteMode, RouteRenderMap, StaticEntry, } from "./types";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,cAAc,EACd,gBAAgB,GAChB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EACN,MAAM,EACN,cAAc,EACd,iBAAiB,GACjB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACX,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,WAAW,GACX,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/render/modes.ts
|
|
3
|
+
var RENDER_MODE_DESCRIPTORS = {
|
|
4
|
+
csr: {
|
|
5
|
+
mode: "csr",
|
|
6
|
+
label: "Client-Side Rendering",
|
|
7
|
+
shortLabel: "CSR",
|
|
8
|
+
description: "React renders entirely in the browser. The server sends a minimal HTML shell with a JS bundle. No server required at runtime.",
|
|
9
|
+
serverRequired: false,
|
|
10
|
+
buildTimeGenerated: false,
|
|
11
|
+
clientHydration: true,
|
|
12
|
+
roadmap: false
|
|
13
|
+
},
|
|
14
|
+
ssr: {
|
|
15
|
+
mode: "ssr",
|
|
16
|
+
label: "Server-Side Rendering",
|
|
17
|
+
shortLabel: "SSR",
|
|
18
|
+
description: "React renders to HTML on the server per request. The client receives full HTML and then hydrates. Requires a running Node/Bun server.",
|
|
19
|
+
serverRequired: true,
|
|
20
|
+
buildTimeGenerated: false,
|
|
21
|
+
clientHydration: true,
|
|
22
|
+
roadmap: true
|
|
23
|
+
},
|
|
24
|
+
ssg: {
|
|
25
|
+
mode: "ssg",
|
|
26
|
+
label: "Static Site Generation",
|
|
27
|
+
shortLabel: "SSG",
|
|
28
|
+
description: "Pages are fully rendered at build time. Output is static HTML files. No server required at runtime.",
|
|
29
|
+
serverRequired: false,
|
|
30
|
+
buildTimeGenerated: true,
|
|
31
|
+
clientHydration: false,
|
|
32
|
+
roadmap: true
|
|
33
|
+
},
|
|
34
|
+
csg: {
|
|
35
|
+
mode: "csg",
|
|
36
|
+
label: "Client-Side Generation",
|
|
37
|
+
shortLabel: "CSG",
|
|
38
|
+
description: "A static shell is generated at build time, data is fetched and rendered on the client. Combines SSG speed with dynamic data.",
|
|
39
|
+
serverRequired: false,
|
|
40
|
+
buildTimeGenerated: true,
|
|
41
|
+
clientHydration: true,
|
|
42
|
+
roadmap: true
|
|
43
|
+
},
|
|
44
|
+
spa: {
|
|
45
|
+
mode: "spa",
|
|
46
|
+
label: "Single Page Application",
|
|
47
|
+
shortLabel: "SPA",
|
|
48
|
+
description: "A single HTML entry point is served for all routes. React handles all routing client-side. Equivalent to a standard Vite SPA.",
|
|
49
|
+
serverRequired: false,
|
|
50
|
+
buildTimeGenerated: false,
|
|
51
|
+
clientHydration: true,
|
|
52
|
+
roadmap: false
|
|
53
|
+
},
|
|
54
|
+
hybrid: {
|
|
55
|
+
mode: "hybrid",
|
|
56
|
+
label: "Hybrid Rendering",
|
|
57
|
+
shortLabel: "Hybrid",
|
|
58
|
+
description: "Different routes use different render modes. Configured via the `render.routes` map in rakta.config.ts. The top-level mode is the fallback.",
|
|
59
|
+
serverRequired: false,
|
|
60
|
+
buildTimeGenerated: false,
|
|
61
|
+
clientHydration: true,
|
|
62
|
+
roadmap: false
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
function pathMatchesPattern(pathname, pattern) {
|
|
66
|
+
if (pattern === pathname)
|
|
67
|
+
return true;
|
|
68
|
+
const patternParts = pattern.split("/");
|
|
69
|
+
const pathParts = pathname.split("/");
|
|
70
|
+
if (patternParts.length !== pathParts.length)
|
|
71
|
+
return false;
|
|
72
|
+
for (let i = 0;i < patternParts.length; i++) {
|
|
73
|
+
const pp = patternParts[i];
|
|
74
|
+
const path = pathParts[i];
|
|
75
|
+
if (pp === undefined || path === undefined)
|
|
76
|
+
return false;
|
|
77
|
+
if (pp.startsWith(":"))
|
|
78
|
+
continue;
|
|
79
|
+
if (pp !== path)
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function resolveRouteMode(pathname, config) {
|
|
85
|
+
const patterns = Object.keys(config.routes).sort((a, b) => b.length - a.length);
|
|
86
|
+
for (const pattern of patterns) {
|
|
87
|
+
const overrideMode = config.routes[pattern];
|
|
88
|
+
if (overrideMode !== undefined && pathMatchesPattern(pathname, pattern)) {
|
|
89
|
+
return {
|
|
90
|
+
routePath: pathname,
|
|
91
|
+
mode: overrideMode,
|
|
92
|
+
source: "route-override"
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
routePath: pathname,
|
|
98
|
+
mode: config.defaultMode,
|
|
99
|
+
source: "default"
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function getModeDescriptor(mode) {
|
|
103
|
+
return RENDER_MODE_DESCRIPTORS[mode];
|
|
104
|
+
}
|
|
105
|
+
function isRoadmapMode(mode) {
|
|
106
|
+
return RENDER_MODE_DESCRIPTORS[mode].roadmap;
|
|
107
|
+
}
|
|
108
|
+
function requiresServer(mode) {
|
|
109
|
+
return RENDER_MODE_DESCRIPTORS[mode].serverRequired;
|
|
110
|
+
}
|
|
111
|
+
function isBuildTimeMode(mode) {
|
|
112
|
+
return RENDER_MODE_DESCRIPTORS[mode].buildTimeGenerated;
|
|
113
|
+
}
|
|
114
|
+
// src/render/renderer.ts
|
|
115
|
+
function buildHtmlShell(options) {
|
|
116
|
+
return `
|
|
117
|
+
<!DOCTYPE html>
|
|
118
|
+
<html lang="${options.lang}">
|
|
119
|
+
<head>
|
|
120
|
+
<meta charset="UTF-8" />
|
|
121
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
122
|
+
<title>
|
|
123
|
+
${options.appName}
|
|
124
|
+
</title>
|
|
125
|
+
<link rel="stylesheet" href="${options.cssPath}" />
|
|
126
|
+
</head>
|
|
127
|
+
<body>
|
|
128
|
+
<div id="rakta-root"></div>
|
|
129
|
+
<script type="module" src="${options.scriptPath}"></script>
|
|
130
|
+
</body>
|
|
131
|
+
</html>`;
|
|
132
|
+
}
|
|
133
|
+
function makeSuccess(html, mode, renderMs, httpStatus = 200, fromCache = false) {
|
|
134
|
+
return {
|
|
135
|
+
kind: "success",
|
|
136
|
+
html,
|
|
137
|
+
mode,
|
|
138
|
+
httpStatus,
|
|
139
|
+
responseHeaders: { "Content-Type": "text/html; charset=utf-8" },
|
|
140
|
+
fromCache,
|
|
141
|
+
renderMs
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function makeFailure(reason, mode, httpStatus = 500) {
|
|
145
|
+
return { kind: "failure", reason, mode, httpStatus };
|
|
146
|
+
}
|
|
147
|
+
async function render(context, options) {
|
|
148
|
+
const startMs = Date.now();
|
|
149
|
+
if (isRoadmapMode(context.mode)) {
|
|
150
|
+
console.warn(`[Rakta.js] Render mode "${context.mode}" is a roadmap feature (v0.2.0). ` + `Falling back to CSR for: ${context.routePath}`);
|
|
151
|
+
return makeSuccess(buildHtmlShell(options), "csr", Date.now() - startMs);
|
|
152
|
+
}
|
|
153
|
+
switch (context.mode) {
|
|
154
|
+
case "csr":
|
|
155
|
+
case "spa":
|
|
156
|
+
return makeSuccess(buildHtmlShell(options), context.mode, Date.now() - startMs);
|
|
157
|
+
case "hybrid":
|
|
158
|
+
return makeSuccess(buildHtmlShell(options), "csr", Date.now() - startMs);
|
|
159
|
+
case "ssr":
|
|
160
|
+
case "ssg":
|
|
161
|
+
case "csg":
|
|
162
|
+
return makeFailure(`Render mode "${context.mode}" is not yet implemented.`, context.mode, 501);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function renderNotFound(options) {
|
|
166
|
+
return makeSuccess(buildHtmlShell(options), "csr", 0, 404);
|
|
167
|
+
}
|
|
168
|
+
function renderServerError(reason, mode) {
|
|
169
|
+
return makeFailure(reason, mode, 500);
|
|
170
|
+
}
|
|
171
|
+
export {
|
|
172
|
+
resolveRouteMode,
|
|
173
|
+
requiresServer,
|
|
174
|
+
renderServerError,
|
|
175
|
+
renderNotFound,
|
|
176
|
+
render,
|
|
177
|
+
isRoadmapMode,
|
|
178
|
+
isBuildTimeMode,
|
|
179
|
+
getModeDescriptor,
|
|
180
|
+
RENDER_MODE_DESCRIPTORS
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
//# debugId=CC5E8D5EC6EA00C564756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["..\\..\\src\\render\\modes.ts", "..\\..\\src\\render\\renderer.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n\tRenderConfig,\n\tRenderMode,\n\tRenderModeDescriptor,\n\tResolvedRouteMode,\n} from \"./types\";\n\nexport const RENDER_MODE_DESCRIPTORS: Readonly<\n\tRecord<RenderMode, RenderModeDescriptor>\n> = {\n\tcsr: {\n\t\tmode: \"csr\",\n\t\tlabel: \"Client-Side Rendering\",\n\t\tshortLabel: \"CSR\",\n\t\tdescription:\n\t\t\t\"React renders entirely in the browser. The server sends a minimal HTML shell with a JS bundle. No server required at runtime.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: false,\n\t},\n\tssr: {\n\t\tmode: \"ssr\",\n\t\tlabel: \"Server-Side Rendering\",\n\t\tshortLabel: \"SSR\",\n\t\tdescription:\n\t\t\t\"React renders to HTML on the server per request. The client receives full HTML and then hydrates. Requires a running Node/Bun server.\",\n\t\tserverRequired: true,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: true, // Roadmap: v0.2.0\n\t},\n\tssg: {\n\t\tmode: \"ssg\",\n\t\tlabel: \"Static Site Generation\",\n\t\tshortLabel: \"SSG\",\n\t\tdescription:\n\t\t\t\"Pages are fully rendered at build time. Output is static HTML files. No server required at runtime.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: true,\n\t\tclientHydration: false,\n\t\troadmap: true, // Roadmap: v0.2.0\n\t},\n\tcsg: {\n\t\tmode: \"csg\",\n\t\tlabel: \"Client-Side Generation\",\n\t\tshortLabel: \"CSG\",\n\t\tdescription:\n\t\t\t\"A static shell is generated at build time, data is fetched and rendered on the client. Combines SSG speed with dynamic data.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: true,\n\t\tclientHydration: true,\n\t\troadmap: true, // Roadmap: v0.2.0\n\t},\n\tspa: {\n\t\tmode: \"spa\",\n\t\tlabel: \"Single Page Application\",\n\t\tshortLabel: \"SPA\",\n\t\tdescription:\n\t\t\t\"A single HTML entry point is served for all routes. React handles all routing client-side. Equivalent to a standard Vite SPA.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: false,\n\t},\n\thybrid: {\n\t\tmode: \"hybrid\",\n\t\tlabel: \"Hybrid Rendering\",\n\t\tshortLabel: \"Hybrid\",\n\t\tdescription:\n\t\t\t\"Different routes use different render modes. Configured via the `render.routes` map in rakta.config.ts. The top-level mode is the fallback.\",\n\t\tserverRequired: false,\n\t\tbuildTimeGenerated: false,\n\t\tclientHydration: true,\n\t\troadmap: false,\n\t},\n};\n\n/**\n * Returns true if the pathname matches a given route pattern.\n * Supports exact paths and simple :param segments (e.g. /blog/:slug).\n */\nfunction pathMatchesPattern(pathname: string, pattern: string): boolean {\n\tif (pattern === pathname) return true;\n\n\tconst patternParts = pattern.split(\"/\");\n\tconst pathParts = pathname.split(\"/\");\n\n\tif (patternParts.length !== pathParts.length) return false;\n\n\tfor (let i = 0; i < patternParts.length; i++) {\n\t\tconst pp = patternParts[i];\n\t\tconst path = pathParts[i];\n\t\tif (pp === undefined || path === undefined) return false;\n\t\tif (pp.startsWith(\":\")) continue; // dynamic segment — always matches\n\t\tif (pp !== path) return false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Resolves the render mode for the given pathname using the provided config.\n * Route-specific overrides take priority. The most specific (longest) matching\n * pattern wins. Falls back to `config.defaultMode`.\n */\nexport function resolveRouteMode(\n\tpathname: string,\n\tconfig: RenderConfig,\n): ResolvedRouteMode {\n\tconst patterns = Object.keys(config.routes).sort(\n\t\t(a, b) => b.length - a.length, // longest pattern first (most specific)\n\t);\n\n\tfor (const pattern of patterns) {\n\t\tconst overrideMode = config.routes[pattern];\n\t\tif (overrideMode !== undefined && pathMatchesPattern(pathname, pattern)) {\n\t\t\treturn {\n\t\t\t\troutePath: pathname,\n\t\t\t\tmode: overrideMode,\n\t\t\t\tsource: \"route-override\",\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\troutePath: pathname,\n\t\tmode: config.defaultMode,\n\t\tsource: \"default\",\n\t};\n}\n\nexport function getModeDescriptor(mode: RenderMode): RenderModeDescriptor {\n\treturn RENDER_MODE_DESCRIPTORS[mode];\n}\n\nexport function isRoadmapMode(mode: RenderMode): boolean {\n\treturn RENDER_MODE_DESCRIPTORS[mode].roadmap;\n}\n\nexport function requiresServer(mode: RenderMode): boolean {\n\treturn RENDER_MODE_DESCRIPTORS[mode].serverRequired;\n}\n\nexport function isBuildTimeMode(mode: RenderMode): boolean {\n\treturn RENDER_MODE_DESCRIPTORS[mode].buildTimeGenerated;\n}\n",
|
|
6
|
+
"import { isRoadmapMode } from \"./modes\";\nimport type {\n\tRenderContext,\n\tRenderFailure,\n\tRenderMode,\n\tRenderResult,\n\tRenderSuccess,\n} from \"./types\";\n\nexport interface RendererOptions {\n\treadonly appName: string;\n\treadonly scriptPath: string;\n\treadonly cssPath: string;\n\treadonly lang: string;\n}\n\nfunction buildHtmlShell(options: RendererOptions): string {\n\treturn `\n <!DOCTYPE html>\n <html lang=\"${options.lang}\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>\n ${options.appName}\n </title>\n <link rel=\"stylesheet\" href=\"${options.cssPath}\" />\n </head>\n <body>\n <div id=\"rakta-root\"></div>\n <script type=\"module\" src=\"${options.scriptPath}\"></script>\n </body>\n </html>`;\n}\n\nfunction makeSuccess(\n\thtml: string,\n\tmode: RenderMode,\n\trenderMs: number,\n\thttpStatus: number = 200,\n\tfromCache: boolean = false,\n): RenderSuccess {\n\treturn {\n\t\tkind: \"success\",\n\t\thtml,\n\t\tmode,\n\t\thttpStatus,\n\t\tresponseHeaders: { \"Content-Type\": \"text/html; charset=utf-8\" },\n\t\tfromCache,\n\t\trenderMs,\n\t};\n}\n\nfunction makeFailure(\n\treason: string,\n\tmode: RenderMode,\n\thttpStatus: number = 500,\n): RenderFailure {\n\treturn { kind: \"failure\", reason, mode, httpStatus };\n}\n\n/**\n * Render a page using the resolved mode from the context.\n * Roadmap modes (ssr, ssg, csg) fall back to a CSR shell in v0.1.0.\n */\nexport async function render(\n\tcontext: RenderContext,\n\toptions: RendererOptions,\n): Promise<RenderResult> {\n\tconst startMs = Date.now();\n\n\t// Roadmap modes: fall back to CSR shell with a warning\n\tif (isRoadmapMode(context.mode)) {\n\t\tconsole.warn(\n\t\t\t`[Rakta.js] Render mode \"${context.mode}\" is a roadmap feature (v0.2.0). ` +\n\t\t\t\t`Falling back to CSR for: ${context.routePath}`,\n\t\t);\n\t\treturn makeSuccess(buildHtmlShell(options), \"csr\", Date.now() - startMs);\n\t}\n\n\tswitch (context.mode) {\n\t\tcase \"csr\":\n\t\tcase \"spa\":\n\t\t\treturn makeSuccess(\n\t\t\t\tbuildHtmlShell(options),\n\t\t\t\tcontext.mode,\n\t\t\t\tDate.now() - startMs,\n\t\t\t);\n\n\t\tcase \"hybrid\":\n\t\t\t// Hybrid resolution happens upstream in Tide. If it reaches the renderer\n\t\t\t// as hybrid, the route had no specific override - fall back to CSR.\n\t\t\treturn makeSuccess(buildHtmlShell(options), \"csr\", Date.now() - startMs);\n\n\t\tcase \"ssr\":\n\t\tcase \"ssg\":\n\t\tcase \"csg\":\n\t\t\t// These are already caught by isRoadmapMode above, but TypeScript\n\t\t\t// requires an exhaustive switch for the RenderMode union.\n\t\t\treturn makeFailure(\n\t\t\t\t`Render mode \"${context.mode}\" is not yet implemented.`,\n\t\t\t\tcontext.mode,\n\t\t\t\t501,\n\t\t\t);\n\t}\n}\n\nexport function renderNotFound(options: RendererOptions): RenderSuccess {\n\treturn makeSuccess(buildHtmlShell(options), \"csr\", 0, 404);\n}\n\nexport function renderServerError(\n\treason: string,\n\tmode: RenderMode,\n): RenderFailure {\n\treturn makeFailure(reason, mode, 500);\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "CC5E8D5EC6EA00C564756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RenderConfig, RenderMode, RenderModeDescriptor, ResolvedRouteMode } from "./types";
|
|
2
|
+
export declare const RENDER_MODE_DESCRIPTORS: Readonly<Record<RenderMode, RenderModeDescriptor>>;
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the render mode for the given pathname using the provided config.
|
|
5
|
+
* Route-specific overrides take priority. The most specific (longest) matching
|
|
6
|
+
* pattern wins. Falls back to `config.defaultMode`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveRouteMode(pathname: string, config: RenderConfig): ResolvedRouteMode;
|
|
9
|
+
export declare function getModeDescriptor(mode: RenderMode): RenderModeDescriptor;
|
|
10
|
+
export declare function isRoadmapMode(mode: RenderMode): boolean;
|
|
11
|
+
export declare function requiresServer(mode: RenderMode): boolean;
|
|
12
|
+
export declare function isBuildTimeMode(mode: RenderMode): boolean;
|
|
13
|
+
//# sourceMappingURL=modes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../../src/render/modes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAC7C,MAAM,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAoExC,CAAC;AAyBF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GAClB,iBAAiB,CAqBnB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,oBAAoB,CAExE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAEvD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAExD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAEzD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { RenderContext, RenderFailure, RenderMode, RenderResult, RenderSuccess } from "./types";
|
|
2
|
+
export interface RendererOptions {
|
|
3
|
+
readonly appName: string;
|
|
4
|
+
readonly scriptPath: string;
|
|
5
|
+
readonly cssPath: string;
|
|
6
|
+
readonly lang: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Render a page using the resolved mode from the context.
|
|
10
|
+
* Roadmap modes (ssr, ssg, csg) fall back to a CSR shell in v0.1.0.
|
|
11
|
+
*/
|
|
12
|
+
export declare function render(context: RenderContext, options: RendererOptions): Promise<RenderResult>;
|
|
13
|
+
export declare function renderNotFound(options: RendererOptions): RenderSuccess;
|
|
14
|
+
export declare function renderServerError(reason: string, mode: RenderMode): RenderFailure;
|
|
15
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/render/renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,aAAa,EACb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AA+CD;;;GAGG;AACH,wBAAsB,MAAM,CAC3B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,YAAY,CAAC,CAqCvB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,aAAa,CAEtE;AAED,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,GACd,aAAa,CAEf"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** All supported rendering modes in Rakta.js. */
|
|
2
|
+
export type RenderMode = "csr" | "ssr" | "ssg" | "csg" | "spa" | "hybrid";
|
|
3
|
+
/** Where the mode decision came from. */
|
|
4
|
+
export type RenderSource = "route-override" | "default";
|
|
5
|
+
/** Per-route render mode map. Keys are URL patterns, values are modes. */
|
|
6
|
+
export interface RouteRenderMap {
|
|
7
|
+
readonly [routePattern: string]: RenderMode;
|
|
8
|
+
}
|
|
9
|
+
/** Render configuration block inside rakta.config.ts. */
|
|
10
|
+
export interface RenderConfig {
|
|
11
|
+
readonly defaultMode: RenderMode;
|
|
12
|
+
readonly routes: RouteRenderMap;
|
|
13
|
+
}
|
|
14
|
+
/** Result of resolving the render mode for a specific pathname. */
|
|
15
|
+
export interface ResolvedRouteMode {
|
|
16
|
+
readonly routePath: string;
|
|
17
|
+
readonly mode: RenderMode;
|
|
18
|
+
readonly source: RenderSource;
|
|
19
|
+
}
|
|
20
|
+
/** Static descriptor for a render mode. */
|
|
21
|
+
export interface RenderModeDescriptor {
|
|
22
|
+
readonly mode: RenderMode;
|
|
23
|
+
readonly label: string;
|
|
24
|
+
readonly shortLabel: string;
|
|
25
|
+
readonly description: string;
|
|
26
|
+
readonly serverRequired: boolean;
|
|
27
|
+
readonly buildTimeGenerated: boolean;
|
|
28
|
+
readonly clientHydration: boolean;
|
|
29
|
+
/** True if this mode is planned but not yet implemented. */
|
|
30
|
+
readonly roadmap: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** Execution context passed to every renderer call. */
|
|
33
|
+
export interface RenderContext {
|
|
34
|
+
readonly routePath: string;
|
|
35
|
+
readonly mode: RenderMode;
|
|
36
|
+
readonly params: Readonly<Record<string, string>>;
|
|
37
|
+
readonly searchParams: Readonly<Record<string, string>>;
|
|
38
|
+
readonly requestHeaders: Readonly<Record<string, string>>;
|
|
39
|
+
readonly timestampMs: number;
|
|
40
|
+
}
|
|
41
|
+
/** Successful render outcome. */
|
|
42
|
+
export interface RenderSuccess {
|
|
43
|
+
readonly kind: "success";
|
|
44
|
+
readonly html: string;
|
|
45
|
+
readonly mode: RenderMode;
|
|
46
|
+
readonly httpStatus: number;
|
|
47
|
+
readonly responseHeaders: Record<string, string>;
|
|
48
|
+
readonly fromCache: boolean;
|
|
49
|
+
readonly renderMs: number;
|
|
50
|
+
}
|
|
51
|
+
/** Failed render outcome. */
|
|
52
|
+
export interface RenderFailure {
|
|
53
|
+
readonly kind: "failure";
|
|
54
|
+
readonly reason: string;
|
|
55
|
+
readonly mode: RenderMode;
|
|
56
|
+
readonly httpStatus: number;
|
|
57
|
+
}
|
|
58
|
+
export type RenderResult = RenderSuccess | RenderFailure;
|
|
59
|
+
/** A pre-generated static page entry (SSG / CSG). */
|
|
60
|
+
export interface StaticEntry {
|
|
61
|
+
readonly routePath: string;
|
|
62
|
+
readonly html: string;
|
|
63
|
+
readonly generatedAt: string;
|
|
64
|
+
readonly mode: "ssg" | "csg";
|
|
65
|
+
readonly sizeBytes: number;
|
|
66
|
+
}
|
|
67
|
+
/** Per-route mode assignment used inside a hybrid config. */
|
|
68
|
+
export interface HybridRouteEntry {
|
|
69
|
+
readonly pattern: string;
|
|
70
|
+
readonly mode: Exclude<RenderMode, "hybrid">;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/render/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { generateManifest, printManifest, readManifest, writeManifest, } from "./manifest.js";
|
|
2
|
+
export { findLayoutsForPathname, findSpecialRoute, matchRoute, } from "./matcher.js";
|
|
3
|
+
export { scanRoutes } from "./scanner.js";
|
|
4
|
+
export type { ApiMethod, ApiRouteHandler, ApiRouteModule, GenerateMetadataFn, LayoutProps, MatchedRoute, PageProps, RouteContext, RouteKind, RouteManifest, RouteManifestEntry, RouteSegment, } from "./types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,YAAY,EACX,SAAS,EACT,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,YAAY,GACZ,MAAM,YAAY,CAAC"}
|