raktajs 0.1.2 → 0.1.4
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 +104 -70
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/rakta.js +355 -92
- package/dist/cli/rakta.js.map +11 -10
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/forge/build.d.ts.map +1 -1
- package/dist/forge/clientEntry.d.ts +9 -0
- package/dist/forge/clientEntry.d.ts.map +1 -0
- package/dist/forge/devServer.d.ts +1 -1
- package/dist/forge/devServer.d.ts.map +1 -1
- package/dist/forge/index.js +275 -22
- package/dist/forge/index.js.map +7 -6
- package/dist/forge/types.d.ts +4 -0
- package/dist/forge/types.d.ts.map +1 -1
- package/dist/index.js +283 -28
- package/dist/index.js.map +8 -7
- package/dist/render/index.js +7 -4
- package/dist/render/index.js.map +3 -3
- package/dist/render/renderer.d.ts +3 -0
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/tide/adapter.d.ts.map +1 -1
- package/dist/tide/index.js +10 -5
- package/dist/tide/index.js.map +4 -4
- package/dist/tide/types.d.ts +2 -0
- package/dist/tide/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/forge/types.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import type { SeoConfig } from "../config/defineConfig.js";
|
|
1
2
|
import type { RenderConfig, RenderMode } from "../render/types.js";
|
|
2
3
|
import type { RouteManifest } from "../router/types.js";
|
|
3
4
|
export interface ForgeDevServerOptions {
|
|
5
|
+
readonly projectRoot: string;
|
|
4
6
|
readonly port: number;
|
|
5
7
|
readonly host: string;
|
|
6
8
|
readonly appDir: string;
|
|
7
9
|
readonly publicDir: string;
|
|
8
10
|
readonly appName: string;
|
|
11
|
+
readonly seo: SeoConfig;
|
|
9
12
|
readonly renderConfig: RenderConfig;
|
|
10
13
|
}
|
|
11
14
|
export interface ForgeBuildOptions {
|
|
15
|
+
readonly projectRoot: string;
|
|
12
16
|
readonly entryPoint: string;
|
|
13
17
|
readonly outDir: string;
|
|
14
18
|
readonly appDir: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/forge/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1E,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACxD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;CAC1B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/forge/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1E,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACxD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;CAC1B"}
|
package/dist/index.js
CHANGED
|
@@ -1615,8 +1615,8 @@ function mergeConfig(baseConfig, overrideConfig) {
|
|
|
1615
1615
|
};
|
|
1616
1616
|
}
|
|
1617
1617
|
// src/forge/build.ts
|
|
1618
|
-
import { mkdirSync as
|
|
1619
|
-
import { join as
|
|
1618
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
|
|
1619
|
+
import { join as join6, resolve as resolve2 } from "path";
|
|
1620
1620
|
|
|
1621
1621
|
// src/router/manifest.ts
|
|
1622
1622
|
import { existsSync as existsSync4, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -1776,14 +1776,219 @@ function printManifest(manifest) {
|
|
|
1776
1776
|
`);
|
|
1777
1777
|
}
|
|
1778
1778
|
|
|
1779
|
+
// src/forge/clientEntry.ts
|
|
1780
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
1781
|
+
import { dirname, join as join5, relative as relative3 } from "path";
|
|
1782
|
+
function toModuleSpecifier(fromFile, targetFile) {
|
|
1783
|
+
const relativePath = relative3(dirname(fromFile), targetFile).replace(/\\/g, "/");
|
|
1784
|
+
if (relativePath.startsWith(".")) {
|
|
1785
|
+
return relativePath;
|
|
1786
|
+
}
|
|
1787
|
+
return `./${relativePath}`;
|
|
1788
|
+
}
|
|
1789
|
+
function toCssImportSpecifier(entryPath, projectRoot) {
|
|
1790
|
+
const candidates = [
|
|
1791
|
+
join5(projectRoot, "styles", "globals.css"),
|
|
1792
|
+
join5(projectRoot, "styles", "globals.scss"),
|
|
1793
|
+
join5(projectRoot, "styles", "globals.sass")
|
|
1794
|
+
];
|
|
1795
|
+
const stylePath = candidates.find((candidate) => existsSync5(candidate));
|
|
1796
|
+
if (!stylePath) {
|
|
1797
|
+
return null;
|
|
1798
|
+
}
|
|
1799
|
+
return toModuleSpecifier(entryPath, stylePath);
|
|
1800
|
+
}
|
|
1801
|
+
function getPageRoutes(manifest) {
|
|
1802
|
+
return manifest.routes.filter((route) => route.kind === "page");
|
|
1803
|
+
}
|
|
1804
|
+
function buildRouteImports(entryPath, appDir, pageRoutes) {
|
|
1805
|
+
const routeEntries = pageRoutes.map((route) => {
|
|
1806
|
+
const pagePath = join5(appDir, route.filePath);
|
|
1807
|
+
return ` ${JSON.stringify(route.urlPattern)}: () => import("${toModuleSpecifier(entryPath, pagePath)}"),`;
|
|
1808
|
+
}).join(`
|
|
1809
|
+
`);
|
|
1810
|
+
return `const routeModules = {
|
|
1811
|
+
${routeEntries}
|
|
1812
|
+
} as const;`;
|
|
1813
|
+
}
|
|
1814
|
+
function buildRouteTable(pageRoutes) {
|
|
1815
|
+
const routeEntries = pageRoutes.map((route) => ` ${JSON.stringify(route.urlPattern)}: routeModules[${JSON.stringify(route.urlPattern)}],`).join(`
|
|
1816
|
+
`);
|
|
1817
|
+
return `const routes = {
|
|
1818
|
+
${routeEntries}
|
|
1819
|
+
} as const;`;
|
|
1820
|
+
}
|
|
1821
|
+
function findExistingModule(basePathWithoutExtension) {
|
|
1822
|
+
const candidates = [".tsx", ".ts", ".jsx", ".js"].map((extension) => `${basePathWithoutExtension}${extension}`);
|
|
1823
|
+
return candidates.find((candidate) => existsSync5(candidate));
|
|
1824
|
+
}
|
|
1825
|
+
function buildStarterGlobalLoaders(entryPath, appDir) {
|
|
1826
|
+
const mascotPath = findExistingModule(join5(appDir, "components", "raktaShrimpMascot"));
|
|
1827
|
+
const gamePath = findExistingModule(join5(appDir, "components", "shrimpRunGame"));
|
|
1828
|
+
const loaders = [];
|
|
1829
|
+
if (mascotPath !== undefined) {
|
|
1830
|
+
loaders.push(` const mascotModule = await import("${toModuleSpecifier(entryPath, mascotPath)}");
|
|
1831
|
+
(globalThis as typeof globalThis & Record<string, unknown>).RaktaShrimpMascot = mascotModule.default;`);
|
|
1832
|
+
}
|
|
1833
|
+
if (gamePath !== undefined) {
|
|
1834
|
+
loaders.push(` const gameModule = await import("${toModuleSpecifier(entryPath, gamePath)}");
|
|
1835
|
+
(globalThis as typeof globalThis & Record<string, unknown>).ShrimpRunGame = gameModule.default;`);
|
|
1836
|
+
}
|
|
1837
|
+
if (loaders.length === 0) {
|
|
1838
|
+
return `async function loadRaktaGlobals(): Promise<void> {
|
|
1839
|
+
return;
|
|
1840
|
+
}`;
|
|
1841
|
+
}
|
|
1842
|
+
return `async function loadRaktaGlobals(): Promise<void> {
|
|
1843
|
+
${loaders.join(`
|
|
1844
|
+
|
|
1845
|
+
`)}
|
|
1846
|
+
}`;
|
|
1847
|
+
}
|
|
1848
|
+
function buildClientEntrySource(options, entryPath) {
|
|
1849
|
+
const pageRoutes = getPageRoutes(options.manifest);
|
|
1850
|
+
const routeModules = buildRouteImports(entryPath, options.appDir, pageRoutes);
|
|
1851
|
+
const routeTable = buildRouteTable(pageRoutes);
|
|
1852
|
+
const cssImportSpecifier = toCssImportSpecifier(entryPath, options.projectRoot);
|
|
1853
|
+
const cssImport = cssImportSpecifier !== null ? `import "${cssImportSpecifier}";
|
|
1854
|
+
` : "";
|
|
1855
|
+
const starterGlobalLoaders = buildStarterGlobalLoaders(entryPath, options.appDir);
|
|
1856
|
+
return `import React, { useEffect, useState } from "react";
|
|
1857
|
+
import { createRoot } from "react-dom/client";
|
|
1858
|
+
import * as ReactHooks from "react";
|
|
1859
|
+
${cssImport}
|
|
1860
|
+
(globalThis as typeof globalThis & Record<string, unknown>).useCallback = ReactHooks.useCallback;
|
|
1861
|
+
(globalThis as typeof globalThis & Record<string, unknown>).useEffect = ReactHooks.useEffect;
|
|
1862
|
+
(globalThis as typeof globalThis & Record<string, unknown>).useRef = ReactHooks.useRef;
|
|
1863
|
+
(globalThis as typeof globalThis & Record<string, unknown>).useState = ReactHooks.useState;
|
|
1864
|
+
|
|
1865
|
+
${starterGlobalLoaders}
|
|
1866
|
+
|
|
1867
|
+
await loadRaktaGlobals();
|
|
1868
|
+
|
|
1869
|
+
${routeModules}
|
|
1870
|
+
|
|
1871
|
+
${routeTable}
|
|
1872
|
+
|
|
1873
|
+
type RoutePath = keyof typeof routes;
|
|
1874
|
+
type PageModule = { default: React.ComponentType };
|
|
1875
|
+
|
|
1876
|
+
function normalizePathname(pathname: string): string {
|
|
1877
|
+
if (pathname.length > 1 && pathname.endsWith("/")) {
|
|
1878
|
+
return pathname.slice(0, -1);
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
return pathname;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
function resolveRouteLoader(pathname: string): () => Promise<PageModule> {
|
|
1885
|
+
const normalizedPathname = normalizePathname(pathname) as RoutePath;
|
|
1886
|
+
|
|
1887
|
+
return routes[normalizedPathname] ?? routes["/"];
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
function navigate(to: string): void {
|
|
1891
|
+
window.history.pushState({ source: "rakta-click", to }, "", to);
|
|
1892
|
+
window.dispatchEvent(new PopStateEvent("popstate", { state: { to } }));
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
function App(): React.ReactElement {
|
|
1896
|
+
const [pathname, setPathname] = useState(() => window.location.pathname);
|
|
1897
|
+
const [Page, setPage] = useState<React.ComponentType | null>(null);
|
|
1898
|
+
|
|
1899
|
+
useEffect(() => {
|
|
1900
|
+
function handlePopState(): void {
|
|
1901
|
+
setPathname(window.location.pathname);
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
function handleClick(event: MouseEvent): void {
|
|
1905
|
+
const target = event.target;
|
|
1906
|
+
|
|
1907
|
+
if (!(target instanceof Element)) {
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
const clickElement = target.closest("click");
|
|
1912
|
+
|
|
1913
|
+
if (!clickElement) {
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
const to = clickElement.getAttribute("to");
|
|
1918
|
+
|
|
1919
|
+
if (!to || to.startsWith("http://") || to.startsWith("https://")) {
|
|
1920
|
+
return;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
event.preventDefault();
|
|
1924
|
+
navigate(to);
|
|
1925
|
+
setPathname(window.location.pathname);
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
window.addEventListener("popstate", handlePopState);
|
|
1929
|
+
document.addEventListener("click", handleClick);
|
|
1930
|
+
|
|
1931
|
+
return () => {
|
|
1932
|
+
window.removeEventListener("popstate", handlePopState);
|
|
1933
|
+
document.removeEventListener("click", handleClick);
|
|
1934
|
+
};
|
|
1935
|
+
}, []);
|
|
1936
|
+
|
|
1937
|
+
useEffect(() => {
|
|
1938
|
+
let isCurrent = true;
|
|
1939
|
+
|
|
1940
|
+
resolveRouteLoader(pathname)().then((pageModule) => {
|
|
1941
|
+
if (isCurrent) {
|
|
1942
|
+
setPage(() => pageModule.default);
|
|
1943
|
+
}
|
|
1944
|
+
});
|
|
1945
|
+
|
|
1946
|
+
return () => {
|
|
1947
|
+
isCurrent = false;
|
|
1948
|
+
};
|
|
1949
|
+
}, [pathname]);
|
|
1950
|
+
|
|
1951
|
+
if (!Page) {
|
|
1952
|
+
return React.createElement("main", {
|
|
1953
|
+
style: {
|
|
1954
|
+
minHeight: "100vh",
|
|
1955
|
+
display: "grid",
|
|
1956
|
+
placeItems: "center",
|
|
1957
|
+
background: "#050505",
|
|
1958
|
+
color: "#f8fafc",
|
|
1959
|
+
fontFamily: "ui-sans-serif, system-ui, sans-serif",
|
|
1960
|
+
},
|
|
1961
|
+
}, "Loading Rakta.js...");
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
return React.createElement(Page);
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
const rootElement = document.getElementById("rakta-root");
|
|
1968
|
+
|
|
1969
|
+
if (!rootElement) {
|
|
1970
|
+
throw new Error("Rakta.js root element #rakta-root was not found.");
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
createRoot(rootElement).render(React.createElement(App));
|
|
1974
|
+
`;
|
|
1975
|
+
}
|
|
1976
|
+
function writeClientEntry(options) {
|
|
1977
|
+
mkdirSync2(options.workDir, { recursive: true });
|
|
1978
|
+
const entryPath = join5(options.workDir, "client-entry.tsx");
|
|
1979
|
+
const entrySource = buildClientEntrySource(options, entryPath);
|
|
1980
|
+
writeFileSync3(entryPath, entrySource, "utf-8");
|
|
1981
|
+
return entryPath;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1779
1984
|
// src/forge/build.ts
|
|
1780
1985
|
async function buildProject(options) {
|
|
1781
1986
|
const startMs = Date.now();
|
|
1782
1987
|
const artifacts = [];
|
|
1783
1988
|
const errors = [];
|
|
1784
|
-
|
|
1989
|
+
mkdirSync3(resolve2(options.outDir), { recursive: true });
|
|
1785
1990
|
const manifest = generateManifest(options.appDir);
|
|
1786
|
-
const manifestPath =
|
|
1991
|
+
const manifestPath = join6(options.outDir, "route-manifest.json");
|
|
1787
1992
|
writeManifest(manifest, manifestPath);
|
|
1788
1993
|
const manifestContent = JSON.stringify(manifest);
|
|
1789
1994
|
artifacts.push({
|
|
@@ -1791,15 +1996,21 @@ async function buildProject(options) {
|
|
|
1791
1996
|
sizeBytes: new TextEncoder().encode(manifestContent).byteLength,
|
|
1792
1997
|
kind: "manifest"
|
|
1793
1998
|
});
|
|
1999
|
+
const entryPoint = existsSync6(options.entryPoint) ? options.entryPoint : writeClientEntry({
|
|
2000
|
+
projectRoot: options.projectRoot,
|
|
2001
|
+
appDir: options.appDir,
|
|
2002
|
+
workDir: join6(options.projectRoot, ".rakta"),
|
|
2003
|
+
manifest
|
|
2004
|
+
});
|
|
1794
2005
|
const buildResult = await Bun.build({
|
|
1795
|
-
entrypoints: [
|
|
2006
|
+
entrypoints: [entryPoint],
|
|
1796
2007
|
outdir: options.outDir,
|
|
1797
2008
|
target: options.target,
|
|
1798
2009
|
minify: options.minify,
|
|
1799
2010
|
sourcemap: options.sourcemap ? "external" : "none",
|
|
1800
2011
|
splitting: options.splitting,
|
|
1801
2012
|
naming: {
|
|
1802
|
-
entry: "
|
|
2013
|
+
entry: "app.[ext]",
|
|
1803
2014
|
chunk: "chunks/[name]-[hash].[ext]",
|
|
1804
2015
|
asset: "assets/[name]-[hash].[ext]"
|
|
1805
2016
|
}
|
|
@@ -1832,8 +2043,8 @@ async function buildProject(options) {
|
|
|
1832
2043
|
};
|
|
1833
2044
|
}
|
|
1834
2045
|
// src/forge/devServer.ts
|
|
1835
|
-
import { existsSync as
|
|
1836
|
-
import { join as
|
|
2046
|
+
import { existsSync as existsSync7, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
|
|
2047
|
+
import { join as join7 } from "path";
|
|
1837
2048
|
|
|
1838
2049
|
// src/render/modes.ts
|
|
1839
2050
|
var RENDER_MODE_DESCRIPTORS = {
|
|
@@ -1950,15 +2161,18 @@ function isBuildTimeMode(mode) {
|
|
|
1950
2161
|
|
|
1951
2162
|
// src/render/renderer.ts
|
|
1952
2163
|
function buildHtmlShell(options) {
|
|
2164
|
+
const title = options.title ?? options.appName;
|
|
2165
|
+
const faviconPath = options.faviconPath ?? "/favicon.ico";
|
|
2166
|
+
const descriptionMeta = options.description !== undefined ? `<meta name="description" content="${options.description}" />` : "";
|
|
1953
2167
|
return `
|
|
1954
2168
|
<!DOCTYPE html>
|
|
1955
2169
|
<html lang="${options.lang}">
|
|
1956
2170
|
<head>
|
|
1957
2171
|
<meta charset="UTF-8" />
|
|
1958
2172
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
1959
|
-
<title>
|
|
1960
|
-
|
|
1961
|
-
|
|
2173
|
+
<title>${title}</title>
|
|
2174
|
+
${descriptionMeta}
|
|
2175
|
+
<link rel="icon" href="${faviconPath}" sizes="any" />
|
|
1962
2176
|
<link rel="stylesheet" href="${options.cssPath}" />
|
|
1963
2177
|
</head>
|
|
1964
2178
|
<body>
|
|
@@ -2091,18 +2305,55 @@ function resolveDevPort(port) {
|
|
|
2091
2305
|
return port > 0 ? port : DEFAULT_DEV_PORT;
|
|
2092
2306
|
}
|
|
2093
2307
|
function isReadableFile(filePath) {
|
|
2094
|
-
return
|
|
2308
|
+
return existsSync7(filePath) && statSync2(filePath).isFile();
|
|
2309
|
+
}
|
|
2310
|
+
async function buildDevClientBundle(options, manifest) {
|
|
2311
|
+
const workDir = join7(options.projectRoot, ".rakta");
|
|
2312
|
+
const clientOutDir = join7(workDir, "dev");
|
|
2313
|
+
const clientEntry = writeClientEntry({
|
|
2314
|
+
projectRoot: options.projectRoot,
|
|
2315
|
+
appDir: options.appDir,
|
|
2316
|
+
workDir,
|
|
2317
|
+
manifest
|
|
2318
|
+
});
|
|
2319
|
+
const buildResult = await Bun.build({
|
|
2320
|
+
entrypoints: [clientEntry],
|
|
2321
|
+
outdir: clientOutDir,
|
|
2322
|
+
target: "browser",
|
|
2323
|
+
sourcemap: "external",
|
|
2324
|
+
naming: {
|
|
2325
|
+
entry: "app.[ext]",
|
|
2326
|
+
chunk: "chunks/[name]-[hash].[ext]",
|
|
2327
|
+
asset: "assets/[name]-[hash].[ext]"
|
|
2328
|
+
}
|
|
2329
|
+
});
|
|
2330
|
+
if (!buildResult.success) {
|
|
2331
|
+
const buildErrors = buildResult.logs.map((buildLog) => buildLog.message).join(`
|
|
2332
|
+
`);
|
|
2333
|
+
throw new Error(`Failed to build Rakta.js client bundle.
|
|
2334
|
+
${buildErrors}`);
|
|
2335
|
+
}
|
|
2336
|
+
return clientOutDir;
|
|
2095
2337
|
}
|
|
2096
|
-
function startDevServer(options) {
|
|
2338
|
+
async function startDevServer(options) {
|
|
2097
2339
|
const manifest = generateManifest(options.appDir);
|
|
2098
2340
|
const resolvedPort = resolveDevPort(options.port);
|
|
2341
|
+
const clientOutDir = await buildDevClientBundle(options, manifest);
|
|
2099
2342
|
const server = Bun.serve({
|
|
2100
2343
|
port: resolvedPort,
|
|
2101
2344
|
hostname: options.host,
|
|
2102
2345
|
async fetch(request) {
|
|
2103
2346
|
const url = new URL(request.url);
|
|
2104
2347
|
const { pathname } = url;
|
|
2105
|
-
|
|
2348
|
+
if (clientOutDir.length > 0) {
|
|
2349
|
+
const clientBundlePath = join7(clientOutDir, pathname);
|
|
2350
|
+
if (isReadableFile(clientBundlePath)) {
|
|
2351
|
+
return new Response(readFileSync2(clientBundlePath), {
|
|
2352
|
+
headers: { "Content-Type": resolveMime(clientBundlePath) }
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
const publicPath = join7(options.publicDir, pathname);
|
|
2106
2357
|
if (isReadableFile(publicPath)) {
|
|
2107
2358
|
return new Response(readFileSync2(publicPath), {
|
|
2108
2359
|
headers: { "Content-Type": resolveMime(pathname) }
|
|
@@ -2110,7 +2361,7 @@ function startDevServer(options) {
|
|
|
2110
2361
|
}
|
|
2111
2362
|
const apiMatch = matchRoute(pathname, manifest.routes.filter((route) => route.kind === "api"));
|
|
2112
2363
|
if (apiMatch) {
|
|
2113
|
-
const modulePath =
|
|
2364
|
+
const modulePath = join7(options.appDir, apiMatch.entry.filePath);
|
|
2114
2365
|
const routeModule = await import(modulePath);
|
|
2115
2366
|
const method = request.method.toUpperCase();
|
|
2116
2367
|
const handler = routeModule[method];
|
|
@@ -2137,8 +2388,10 @@ function startDevServer(options) {
|
|
|
2137
2388
|
timestampMs: Date.now()
|
|
2138
2389
|
}, {
|
|
2139
2390
|
appName: options.appName,
|
|
2391
|
+
title: options.seo.defaultTitle,
|
|
2392
|
+
description: options.seo.defaultDescription,
|
|
2140
2393
|
scriptPath: "/app.js",
|
|
2141
|
-
cssPath: "/
|
|
2394
|
+
cssPath: "/app.css",
|
|
2142
2395
|
lang: "en"
|
|
2143
2396
|
});
|
|
2144
2397
|
if (result.kind === "failure") {
|
|
@@ -2159,8 +2412,8 @@ function startDevServer(options) {
|
|
|
2159
2412
|
};
|
|
2160
2413
|
}
|
|
2161
2414
|
// src/forge/inspect.ts
|
|
2162
|
-
import { existsSync as
|
|
2163
|
-
import { join as
|
|
2415
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
|
|
2416
|
+
import { join as join8 } from "path";
|
|
2164
2417
|
function detectArtifactKind(filename) {
|
|
2165
2418
|
if (filename === "route-manifest.json")
|
|
2166
2419
|
return "manifest";
|
|
@@ -2178,13 +2431,13 @@ function formatBytes(bytes) {
|
|
|
2178
2431
|
return `${(bytes / 1048576).toFixed(2)} MB`;
|
|
2179
2432
|
}
|
|
2180
2433
|
function scanDirectory2(dirPath) {
|
|
2181
|
-
if (!
|
|
2434
|
+
if (!existsSync8(dirPath))
|
|
2182
2435
|
return [];
|
|
2183
2436
|
const collected = [];
|
|
2184
2437
|
function walk(current) {
|
|
2185
2438
|
const entries = readdirSync3(current, { withFileTypes: true });
|
|
2186
2439
|
for (const entry of entries) {
|
|
2187
|
-
const full =
|
|
2440
|
+
const full = join8(current, entry.name);
|
|
2188
2441
|
if (entry.isDirectory()) {
|
|
2189
2442
|
walk(full);
|
|
2190
2443
|
} else if (entry.isFile()) {
|
|
@@ -2201,7 +2454,7 @@ function scanDirectory2(dirPath) {
|
|
|
2201
2454
|
}
|
|
2202
2455
|
function inspectBuild(options) {
|
|
2203
2456
|
const artifacts = scanDirectory2(options.outDir);
|
|
2204
|
-
const manifestPath =
|
|
2457
|
+
const manifestPath = join8(options.outDir, "route-manifest.json");
|
|
2205
2458
|
const manifest = readManifest(manifestPath);
|
|
2206
2459
|
const emptyManifest = {
|
|
2207
2460
|
version: "1",
|
|
@@ -3605,8 +3858,8 @@ function createRaktaStore(creator) {
|
|
|
3605
3858
|
return Object.assign(useStore, storeApi);
|
|
3606
3859
|
}
|
|
3607
3860
|
// src/tide/adapter.ts
|
|
3608
|
-
import { existsSync as
|
|
3609
|
-
import { join as
|
|
3861
|
+
import { existsSync as existsSync9, readFileSync as readFileSync3, statSync as statSync4 } from "fs";
|
|
3862
|
+
import { join as join9 } from "path";
|
|
3610
3863
|
|
|
3611
3864
|
// src/tide/runtime.ts
|
|
3612
3865
|
function createRuntimeContext(request, url, params, resolvedMode) {
|
|
@@ -3678,7 +3931,7 @@ function normalizeStaticPath(pathname) {
|
|
|
3678
3931
|
return "index.html";
|
|
3679
3932
|
}
|
|
3680
3933
|
function isReadableFile2(filePath) {
|
|
3681
|
-
return
|
|
3934
|
+
return existsSync9(filePath) && statSync4(filePath).isFile();
|
|
3682
3935
|
}
|
|
3683
3936
|
function isApiRouteExports(value) {
|
|
3684
3937
|
if (typeof value !== "object" || value === null) {
|
|
@@ -3719,7 +3972,7 @@ function createBunAdapter(adapterConfig, renderConfig) {
|
|
|
3719
3972
|
const { pathname } = url;
|
|
3720
3973
|
const staticPathname = normalizeStaticPath(pathname);
|
|
3721
3974
|
for (const searchDirectory of searchDirectories) {
|
|
3722
|
-
const filePath =
|
|
3975
|
+
const filePath = join9(searchDirectory, staticPathname);
|
|
3723
3976
|
if (isReadableFile2(filePath)) {
|
|
3724
3977
|
return new Response(readFileSync3(filePath), {
|
|
3725
3978
|
headers: {
|
|
@@ -3732,7 +3985,7 @@ function createBunAdapter(adapterConfig, renderConfig) {
|
|
|
3732
3985
|
const apiRoutes = manifest.routes.filter((route) => route.kind === "api");
|
|
3733
3986
|
const apiMatch = matchRoute(pathname, apiRoutes);
|
|
3734
3987
|
if (apiMatch) {
|
|
3735
|
-
const modulePath =
|
|
3988
|
+
const modulePath = join9(adapterConfig.appDir, apiMatch.entry.filePath);
|
|
3736
3989
|
const routeModule = await import(modulePath);
|
|
3737
3990
|
if (!isApiRouteExports(routeModule)) {
|
|
3738
3991
|
return new Response("Invalid API route module", {
|
|
@@ -3758,8 +4011,10 @@ function createBunAdapter(adapterConfig, renderConfig) {
|
|
|
3758
4011
|
timestampMs: runtimeContext.timestampMs
|
|
3759
4012
|
}, {
|
|
3760
4013
|
appName: adapterConfig.appName,
|
|
4014
|
+
title: adapterConfig.seo.defaultTitle,
|
|
4015
|
+
description: adapterConfig.seo.defaultDescription,
|
|
3761
4016
|
scriptPath: "/app.js",
|
|
3762
|
-
cssPath: "/
|
|
4017
|
+
cssPath: "/app.css",
|
|
3763
4018
|
lang: "en"
|
|
3764
4019
|
});
|
|
3765
4020
|
if (renderResult.kind === "failure") {
|
|
@@ -3875,4 +4130,4 @@ export {
|
|
|
3875
4130
|
ArrayType
|
|
3876
4131
|
};
|
|
3877
4132
|
|
|
3878
|
-
//# debugId=
|
|
4133
|
+
//# debugId=2891A5FC74296A2364756E2164756E21
|