xanix 1.0.0 → 1.0.3
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/dist/BaseDocument.d.ts +1 -1
- package/dist/BaseDocument.js +3 -3
- package/dist/bin/bundler/buildCache.js +6 -23
- package/dist/bin/bundler/plugins/XanixReactRefresh.js +33 -33
- package/dist/bin/bundler/plugins/XanixResolveCacheDeps/index.js +5 -0
- package/dist/bin/bundler/plugins/XanixTsconfigAlias.d.ts +2 -0
- package/dist/bin/bundler/plugins/{xanixTsconfigAlias.js → XanixTsconfigAlias.js} +3 -5
- package/dist/bin/bundler/plugins/plugins.js +6 -0
- package/dist/bin/bundler/watchClient.js +7 -1
- package/dist/bin/cli/build.js +3 -1
- package/dist/bin/cli/dev.js +3 -0
- package/dist/bin/cli/start copy.d.ts +2 -0
- package/dist/bin/cli/start copy.js +34 -0
- package/dist/bin/index.js +0 -0
- package/dist/client/client-runtime.d.ts +10 -0
- package/dist/client/client-runtime.js +98 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +2 -2
- package/dist/client/navigation.d.ts +3 -4
- package/dist/client/navigation.js +23 -10
- package/dist/client/runtime.d.ts +1 -1
- package/dist/components/Document/context.d.ts +4 -10
- package/dist/components/Document/context.js +6 -5
- package/dist/components/Document/index.d.ts +6 -5
- package/dist/components/Document/index.js +3 -7
- package/dist/components/Head.js +1 -1
- package/dist/document/Body.js +1 -2
- package/dist/document/Document.js +1 -2
- package/dist/document/DocumentContext.d.ts +1 -0
- package/dist/document/Head.js +4 -3
- package/dist/document/index.d.ts +1 -1
- package/dist/document/index.js +1 -1
- package/dist/document/useDocument.d.ts +1 -1
- package/dist/hooks/useCookie.d.ts +2 -0
- package/dist/hooks/useCookie.js +13 -0
- package/dist/hooks/useData.js +1 -3
- package/dist/hooks/useRequest copy.d.ts +2 -0
- package/dist/hooks/useRequest copy.js +8 -0
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -4
- package/dist/navigation/navigate.js +6 -6
- package/dist/navigation/useLocation.js +1 -1
- package/dist/router/index.d.ts +3 -1
- package/dist/router/index.js +3 -1
- package/dist/router/useParams.d.ts +1 -9
- package/dist/router/useParams.js +3 -48
- package/dist/router/usePathname.d.ts +1 -0
- package/dist/router/usePathname.js +8 -0
- package/dist/router/useSearchParams.js +2 -8
- package/dist/runtime/createServer.d.ts +12 -0
- package/dist/runtime/createServer.js +40 -0
- package/dist/runtime/index.d.ts +12 -0
- package/dist/runtime/index.js +40 -0
- package/dist/runtime/readManifest.d.ts +14 -0
- package/dist/runtime/readManifest.js +8 -0
- package/dist/runtime/xanixPage.d.ts +9 -0
- package/dist/runtime/xanixPage.js +62 -0
- package/dist/server/createServer.d.ts +12 -0
- package/dist/server/createServer.js +40 -0
- package/dist/server/page.js +2 -0
- package/dist/server/runtime copy.d.ts +12 -0
- package/dist/server/runtime copy.js +40 -0
- package/dist/server/runtime.d.ts +12 -0
- package/dist/server/runtime.js +40 -0
- package/dist/server/xanixPage.d.ts +9 -0
- package/dist/server/xanixPage.js +62 -0
- package/dist/utils/index.d.ts +0 -9
- package/dist/utils/index.js +1 -27
- package/dist/xanix.js +12 -12
- package/package.json +73 -73
- package/{src/xanix-env.d.ts → xanix-env.d.ts} +79 -79
- package/dist/Document.d.ts +0 -7
- package/dist/Document.js +0 -7
- package/dist/bin/bundler/plugins/XanixWatchChange copy.d.ts +0 -10
- package/dist/bin/bundler/plugins/XanixWatchChange copy.js +0 -30
- package/dist/bin/bundler/plugins/XanixWatchChange.d.ts +0 -9
- package/dist/bin/bundler/plugins/XanixWatchChange.js +0 -27
- package/dist/bin/bundler/plugins/XanixWatchChangeClient.d.ts +0 -7
- package/dist/bin/bundler/plugins/XanixWatchChangeClient.js +0 -15
- package/dist/bin/bundler/plugins/pathResolver.d.ts +0 -5
- package/dist/bin/bundler/plugins/pathResolver.js +0 -57
- package/dist/bin/bundler/plugins/xanixServerData.d.ts +0 -6
- package/dist/bin/bundler/plugins/xanixServerData.js +0 -224
- package/dist/bin/bundler/plugins/xanixTsconfigAlias.d.ts +0 -6
- package/dist/client/components/Body.d.ts +0 -5
- package/dist/client/components/Body.js +0 -10
- package/dist/client/components/Document/context.d.ts +0 -3
- package/dist/client/components/Document/context.js +0 -14
- package/dist/client/components/Document/index.d.ts +0 -8
- package/dist/client/components/Document/index.js +0 -6
- package/dist/client/components/Head copy.d.ts +0 -5
- package/dist/client/components/Head copy.js +0 -8
- package/dist/client/components/Head.d.ts +0 -5
- package/dist/client/components/Head.js +0 -10
- package/dist/client/components/Link.d.ts +0 -6
- package/dist/client/components/Link.js +0 -10
- package/dist/client/refresh.d.ts +0 -7
- package/dist/client/refresh.js +0 -15
- package/dist/components/Document/Document.d.ts +0 -16
- package/dist/components/Document/Document.js +0 -15
- package/dist/components/DocumentContext/DocumentContext.d.ts +0 -15
- package/dist/components/DocumentContext/DocumentContext.js +0 -18
- package/dist/components/DocumentContext/context.d.ts +0 -11
- package/dist/components/DocumentContext/context.js +0 -14
- package/dist/components/DocumentContext/index.d.ts +0 -15
- package/dist/components/DocumentContext/index.js +0 -18
- package/dist/components/DocumentProvider.d.ts +0 -13
- package/dist/components/DocumentProvider.js +0 -7
- package/dist/document/Document/Document.d.ts +0 -7
- package/dist/document/Document/Document.js +0 -10
- package/dist/document/Document/context.d.ts +0 -17
- package/dist/document/Document/context.js +0 -13
- package/dist/document/Document/index.d.ts +0 -7
- package/dist/document/Document/index.js +0 -10
- package/dist/document/context.d.ts +0 -17
- package/dist/document/context.js +0 -13
- package/dist/loader.d.ts +0 -11
- package/dist/loader.js +0 -16
- package/dist/router/useSearchParams .d.ts +0 -9
- package/dist/router/useSearchParams .js +0 -50
package/dist/index.d.ts
CHANGED
|
@@ -14,10 +14,5 @@ import useHeaders from "./hooks/useHeaders.js";
|
|
|
14
14
|
import useCookies from "./hooks/useCookies.js";
|
|
15
15
|
import useData from "./hooks/useData.js";
|
|
16
16
|
import { navigate, back, forward, preload, onNavigateStart, onNavigateEnd, reload } from "./navigate.js";
|
|
17
|
-
export declare const isClient: boolean;
|
|
18
|
-
export declare const isServer: boolean;
|
|
19
|
-
export declare const isDevelopment: boolean;
|
|
20
|
-
export declare const isProduction: boolean;
|
|
21
17
|
export { Link, Document, Head, Body, Script, useDocument, useLocation, useParams, usePathname, useSearchParams, usePage, useRequest, useHeaders, useCookies, useData, navigate, back, forward, preload, onNavigateStart, onNavigateEnd, reload, };
|
|
22
|
-
export type * from "./types";
|
|
23
18
|
export type { DocumentProps };
|
package/dist/index.js
CHANGED
|
@@ -16,10 +16,6 @@ import useCookies from "./hooks/useCookies.js";
|
|
|
16
16
|
import useData from "./hooks/useData.js";
|
|
17
17
|
// navigate
|
|
18
18
|
import { navigate, back, forward, preload, onNavigateStart, onNavigateEnd, reload, } from "./navigate.js";
|
|
19
|
-
export const isClient = __XANIX_CLIENT__;
|
|
20
|
-
export const isServer = __XANIX_SERVER__;
|
|
21
|
-
export const isDevelopment = __XANIX_DEV__;
|
|
22
|
-
export const isProduction = __XANIX_PROD__;
|
|
23
19
|
export { Link, Document, Head, Body, Script,
|
|
24
20
|
// hooks
|
|
25
21
|
useDocument, useLocation, useParams, usePathname, useSearchParams, usePage, useRequest, useHeaders, useCookies, useData,
|
|
@@ -20,12 +20,12 @@ export const reload = (hard = false) => {
|
|
|
20
20
|
window.dispatchEvent(new CustomEvent("xanix:reload"));
|
|
21
21
|
};
|
|
22
22
|
export const onNavigateStart = (callback) => {
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
if (__XANIX_CLIENT__) {
|
|
24
|
+
window.addEventListener("xanix:navigate:start", callback);
|
|
25
|
+
}
|
|
26
26
|
};
|
|
27
27
|
export const onNavigateEnd = (callback) => {
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
if (__XANIX_CLIENT__) {
|
|
29
|
+
window.addEventListener("xanix:navigate:end", callback);
|
|
30
|
+
}
|
|
31
31
|
};
|
package/dist/router/index.d.ts
CHANGED
package/dist/router/index.js
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export declare const useParams: () =>
|
|
2
|
-
get: (key: string) => string | null;
|
|
3
|
-
set: (key: string, value: string) => void;
|
|
4
|
-
sets: (entries: Record<string, string>) => void;
|
|
5
|
-
delete: (key: string) => void;
|
|
6
|
-
deletes: (keys: string[]) => void;
|
|
7
|
-
clear: () => void;
|
|
8
|
-
has: (key: string) => boolean;
|
|
9
|
-
};
|
|
1
|
+
export declare const useParams: () => any;
|
package/dist/router/useParams.js
CHANGED
|
@@ -1,50 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
3
|
-
const getParams = () => {
|
|
4
|
-
return new URLSearchParams(window.location.search);
|
|
5
|
-
};
|
|
1
|
+
import useDocument from "../hooks/useDocument.js";
|
|
6
2
|
export const useParams = () => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const onNavigate = () => setParams(getParams());
|
|
10
|
-
window.addEventListener("xanix:navigate:end", onNavigate);
|
|
11
|
-
return () => {
|
|
12
|
-
window.removeEventListener("xanix:navigate:end", onNavigate);
|
|
13
|
-
};
|
|
14
|
-
}, []);
|
|
15
|
-
return {
|
|
16
|
-
get: (key) => params.get(key),
|
|
17
|
-
set: (key, value) => {
|
|
18
|
-
const newParams = new URLSearchParams(params.toString());
|
|
19
|
-
newParams.set(key, value);
|
|
20
|
-
navigate(window.location.pathname + "?" + newParams.toString());
|
|
21
|
-
},
|
|
22
|
-
sets: (entries) => {
|
|
23
|
-
const newParams = new URLSearchParams(params.toString());
|
|
24
|
-
for (const [key, value] of Object.entries(entries)) {
|
|
25
|
-
newParams.set(key, value);
|
|
26
|
-
}
|
|
27
|
-
navigate(window.location.pathname + "?" + newParams.toString());
|
|
28
|
-
},
|
|
29
|
-
delete: (key) => {
|
|
30
|
-
const newParams = new URLSearchParams(params.toString());
|
|
31
|
-
newParams.delete(key);
|
|
32
|
-
setParams(newParams);
|
|
33
|
-
navigate(window.location.pathname + "?" + newParams.toString());
|
|
34
|
-
},
|
|
35
|
-
deletes: (keys) => {
|
|
36
|
-
const newParams = new URLSearchParams(params.toString());
|
|
37
|
-
for (const key of keys) {
|
|
38
|
-
newParams.delete(key);
|
|
39
|
-
}
|
|
40
|
-
setParams(newParams);
|
|
41
|
-
navigate(window.location.pathname + "?" + newParams.toString());
|
|
42
|
-
},
|
|
43
|
-
clear: () => {
|
|
44
|
-
const newParams = new URLSearchParams();
|
|
45
|
-
setParams(newParams);
|
|
46
|
-
navigate(window.location.pathname + "?" + newParams.toString());
|
|
47
|
-
},
|
|
48
|
-
has: (key) => params.has(key),
|
|
49
|
-
};
|
|
3
|
+
const { params } = useDocument();
|
|
4
|
+
return params;
|
|
50
5
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const usePathname: () => any;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { navigate } from "../navigation/navigate.js";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
-
import useDocument from "../
|
|
3
|
+
import useDocument from "../hooks/useDocument.js";
|
|
4
4
|
const getParams = () => {
|
|
5
5
|
return new URLSearchParams(window.location.search);
|
|
6
6
|
};
|
|
@@ -12,13 +12,7 @@ const buildUrl = (params) => {
|
|
|
12
12
|
};
|
|
13
13
|
export const useSearchParams = () => {
|
|
14
14
|
const { request } = useDocument();
|
|
15
|
-
let _params;
|
|
16
|
-
if (request) {
|
|
17
|
-
_params = new URLSearchParams(request.url.split("?")[1] || "");
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
_params = getParams();
|
|
21
|
-
}
|
|
15
|
+
let _params = new URLSearchParams(__XANIX_SERVER__ ? request.url.split("?")[1] || "" : window.location.search);
|
|
22
16
|
const [params, setParams] = useState(_params);
|
|
23
17
|
useEffect(() => {
|
|
24
18
|
const onNavigate = () => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export interface XanixProps {
|
|
3
|
+
clientId: string;
|
|
4
|
+
req: any;
|
|
5
|
+
res: any;
|
|
6
|
+
component: React.ReactElement;
|
|
7
|
+
}
|
|
8
|
+
type Options = {
|
|
9
|
+
mode: "watch" | "start";
|
|
10
|
+
};
|
|
11
|
+
export declare function createXanixServer({ mode }: Options): express.Express;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export function createXanixServer({ mode }) {
|
|
3
|
+
const app = express();
|
|
4
|
+
if (mode === "watch") {
|
|
5
|
+
app.use("/.xanix/client", express.static(".xanix/client"));
|
|
6
|
+
app.use("/assets", express.static(".xanix/assets"));
|
|
7
|
+
app.use("/.xanix/cache", express.static(".xanix/cache"));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
app.use("/.xanix/client", express.static(".xanix/client", {
|
|
11
|
+
maxAge: "1y",
|
|
12
|
+
immutable: true,
|
|
13
|
+
etag: true,
|
|
14
|
+
}));
|
|
15
|
+
app.use("/assets", express.static(".xanix/assets", {
|
|
16
|
+
maxAge: "1y",
|
|
17
|
+
immutable: true,
|
|
18
|
+
etag: true,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
app.use((req, res, next) => {
|
|
22
|
+
let data = {
|
|
23
|
+
title: null,
|
|
24
|
+
meta: [],
|
|
25
|
+
};
|
|
26
|
+
if (!req.page) {
|
|
27
|
+
req.page = {
|
|
28
|
+
setTitle(title) {
|
|
29
|
+
data.title = title;
|
|
30
|
+
},
|
|
31
|
+
setMeta(name, content) {
|
|
32
|
+
data.meta.push({ name, content });
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
req.XanixPageData = data;
|
|
36
|
+
}
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
return app;
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export interface XanixProps {
|
|
3
|
+
clientId: string;
|
|
4
|
+
req: any;
|
|
5
|
+
res: any;
|
|
6
|
+
component: React.ReactElement;
|
|
7
|
+
}
|
|
8
|
+
type Options = {
|
|
9
|
+
mode: "watch" | "start";
|
|
10
|
+
};
|
|
11
|
+
export declare function createXanixServer({ mode }: Options): express.Express;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export function createXanixServer({ mode }) {
|
|
3
|
+
const app = express();
|
|
4
|
+
if (mode === "watch") {
|
|
5
|
+
app.use("/.xanix/client", express.static(".xanix/client"));
|
|
6
|
+
app.use("/assets", express.static(".xanix/assets"));
|
|
7
|
+
app.use("/.xanix/cache", express.static(".xanix/cache"));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
app.use("/.xanix/client", express.static(".xanix/client", {
|
|
11
|
+
maxAge: "1y",
|
|
12
|
+
immutable: true,
|
|
13
|
+
etag: true,
|
|
14
|
+
}));
|
|
15
|
+
app.use("/assets", express.static(".xanix/assets", {
|
|
16
|
+
maxAge: "1y",
|
|
17
|
+
immutable: true,
|
|
18
|
+
etag: true,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
app.use((req, res, next) => {
|
|
22
|
+
let data = {
|
|
23
|
+
title: null,
|
|
24
|
+
meta: [],
|
|
25
|
+
};
|
|
26
|
+
if (!req.page) {
|
|
27
|
+
req.page = {
|
|
28
|
+
setTitle(title) {
|
|
29
|
+
data.title = title;
|
|
30
|
+
},
|
|
31
|
+
setMeta(name, content) {
|
|
32
|
+
data.meta.push({ name, content });
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
req.XanixPageData = data;
|
|
36
|
+
}
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
return app;
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface XanixManifestEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
file: string;
|
|
5
|
+
path: string;
|
|
6
|
+
build: string;
|
|
7
|
+
export: string;
|
|
8
|
+
}
|
|
9
|
+
interface XanixManifest {
|
|
10
|
+
version: number;
|
|
11
|
+
entries: XanixManifestEntry[];
|
|
12
|
+
}
|
|
13
|
+
declare function readManifest(): Promise<XanixManifest>;
|
|
14
|
+
export default readManifest;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
async function readManifest() {
|
|
4
|
+
const manifestPath = path.resolve(process.cwd(), ".xanix", "client-manifest.json");
|
|
5
|
+
const source = await fs.readFile(manifestPath, "utf8");
|
|
6
|
+
return JSON.parse(source);
|
|
7
|
+
}
|
|
8
|
+
export default readManifest;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface XanixPageProps {
|
|
2
|
+
pageId: string;
|
|
3
|
+
req: any;
|
|
4
|
+
res: any;
|
|
5
|
+
Component: (props: Record<string, any>) => React.ReactElement;
|
|
6
|
+
props: Record<string, any>;
|
|
7
|
+
}
|
|
8
|
+
export default function xanix_page({ pageId, req, res, Component, props, }: XanixPageProps): Promise<string | undefined>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
3
|
+
import readManifest from "./readManifest.js";
|
|
4
|
+
import { PassThrough } from "node:stream";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
function renderPage(element) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
let html = "";
|
|
10
|
+
const stream = new PassThrough();
|
|
11
|
+
stream.on("data", (chunk) => {
|
|
12
|
+
html += chunk.toString();
|
|
13
|
+
});
|
|
14
|
+
stream.on("end", () => {
|
|
15
|
+
resolve(html);
|
|
16
|
+
});
|
|
17
|
+
stream.on("error", reject);
|
|
18
|
+
const { pipe } = renderToPipeableStream(element, {
|
|
19
|
+
onAllReady() {
|
|
20
|
+
pipe(stream);
|
|
21
|
+
},
|
|
22
|
+
onError(error) {
|
|
23
|
+
console.error("SSR error:", error);
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export default async function xanix_page({ pageId, req, res, Component, props, }) {
|
|
29
|
+
const manifest = await readManifest();
|
|
30
|
+
const { title, meta } = req.XanixPageData;
|
|
31
|
+
const entry = manifest.entries.find((item) => item.id === pageId);
|
|
32
|
+
const method = req.method.toUpperCase();
|
|
33
|
+
if (method !== "GET") {
|
|
34
|
+
res.status(405).send("Method Not Allowed");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (!entry) {
|
|
38
|
+
throw new Error(`Xanix client entry "${pageId}" was not found in the manifest.`);
|
|
39
|
+
}
|
|
40
|
+
if ("x-navigation" in req.headers) {
|
|
41
|
+
res.setHeader("Content-Type", "application/json");
|
|
42
|
+
return JSON.stringify({
|
|
43
|
+
pageId,
|
|
44
|
+
props,
|
|
45
|
+
title: title ?? entry.name.replaceAll("-", " "),
|
|
46
|
+
meta,
|
|
47
|
+
params: req.params,
|
|
48
|
+
request: null,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const Document = (await import(pathToFileURL(path.join(process.cwd(), ".xanix", "xanix-document.js"))
|
|
52
|
+
.href)).default;
|
|
53
|
+
const html = await renderPage(_jsx(Document, { document: {
|
|
54
|
+
pageId,
|
|
55
|
+
props,
|
|
56
|
+
title: title ?? entry.name.replaceAll("-", " "),
|
|
57
|
+
meta,
|
|
58
|
+
params: req.params,
|
|
59
|
+
request: req,
|
|
60
|
+
}, children: _jsx(Component, { ...props }) }));
|
|
61
|
+
return `<!DOCTYPE html>${html}`;
|
|
62
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export interface XanixProps {
|
|
3
|
+
clientId: string;
|
|
4
|
+
req: any;
|
|
5
|
+
res: any;
|
|
6
|
+
component: React.ReactElement;
|
|
7
|
+
}
|
|
8
|
+
type Options = {
|
|
9
|
+
mode: "watch" | "start";
|
|
10
|
+
};
|
|
11
|
+
export declare function createXanixServer({ mode }: Options): express.Express;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export function createXanixServer({ mode }) {
|
|
3
|
+
const app = express();
|
|
4
|
+
if (mode === "watch") {
|
|
5
|
+
app.use("/.xanix/client", express.static(".xanix/client"));
|
|
6
|
+
app.use("/assets", express.static(".xanix/assets"));
|
|
7
|
+
app.use("/.xanix/cache", express.static(".xanix/cache"));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
app.use("/.xanix/client", express.static(".xanix/client", {
|
|
11
|
+
maxAge: "1y",
|
|
12
|
+
immutable: true,
|
|
13
|
+
etag: true,
|
|
14
|
+
}));
|
|
15
|
+
app.use("/assets", express.static(".xanix/assets", {
|
|
16
|
+
maxAge: "1y",
|
|
17
|
+
immutable: true,
|
|
18
|
+
etag: true,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
app.use((req, res, next) => {
|
|
22
|
+
let data = {
|
|
23
|
+
title: null,
|
|
24
|
+
meta: [],
|
|
25
|
+
};
|
|
26
|
+
if (!req.page) {
|
|
27
|
+
req.page = {
|
|
28
|
+
setTitle(title) {
|
|
29
|
+
data.title = title;
|
|
30
|
+
},
|
|
31
|
+
setMeta(name, content) {
|
|
32
|
+
data.meta.push({ name, content });
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
req.XanixPageData = data;
|
|
36
|
+
}
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
return app;
|
|
40
|
+
}
|
package/dist/server/page.js
CHANGED
|
@@ -44,6 +44,7 @@ export default async function xanix_page({ pageId, req, res, Component, props, }
|
|
|
44
44
|
props,
|
|
45
45
|
title: title ?? entry.name.replaceAll("-", " "),
|
|
46
46
|
meta,
|
|
47
|
+
params: req.params,
|
|
47
48
|
request: null,
|
|
48
49
|
});
|
|
49
50
|
}
|
|
@@ -54,6 +55,7 @@ export default async function xanix_page({ pageId, req, res, Component, props, }
|
|
|
54
55
|
props,
|
|
55
56
|
title: title ?? entry.name.replaceAll("-", " "),
|
|
56
57
|
meta,
|
|
58
|
+
params: req.params,
|
|
57
59
|
request: req,
|
|
58
60
|
}, children: _jsx(Component, { ...props }) }));
|
|
59
61
|
return `<!DOCTYPE html>${html}`;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export interface XanixProps {
|
|
3
|
+
clientId: string;
|
|
4
|
+
req: any;
|
|
5
|
+
res: any;
|
|
6
|
+
component: React.ReactElement;
|
|
7
|
+
}
|
|
8
|
+
type Options = {
|
|
9
|
+
mode: "watch" | "start";
|
|
10
|
+
};
|
|
11
|
+
export declare function createXanixServer({ mode }: Options): express.Express;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export function createXanixServer({ mode }) {
|
|
3
|
+
const app = express();
|
|
4
|
+
if (mode === "watch") {
|
|
5
|
+
app.use("/.xanix/client", express.static(".xanix/client"));
|
|
6
|
+
app.use("/assets", express.static(".xanix/assets"));
|
|
7
|
+
app.use("/.xanix/cache", express.static(".xanix/cache"));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
app.use("/.xanix/client", express.static(".xanix/client", {
|
|
11
|
+
maxAge: "1y",
|
|
12
|
+
immutable: true,
|
|
13
|
+
etag: true,
|
|
14
|
+
}));
|
|
15
|
+
app.use("/assets", express.static(".xanix/assets", {
|
|
16
|
+
maxAge: "1y",
|
|
17
|
+
immutable: true,
|
|
18
|
+
etag: true,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
app.use((req, res, next) => {
|
|
22
|
+
let data = {
|
|
23
|
+
title: null,
|
|
24
|
+
meta: [],
|
|
25
|
+
};
|
|
26
|
+
if (!req.page) {
|
|
27
|
+
req.page = {
|
|
28
|
+
setTitle(title) {
|
|
29
|
+
data.title = title;
|
|
30
|
+
},
|
|
31
|
+
setMeta(name, content) {
|
|
32
|
+
data.meta.push({ name, content });
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
req.XanixPageData = data;
|
|
36
|
+
}
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
return app;
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export interface XanixProps {
|
|
3
|
+
clientId: string;
|
|
4
|
+
req: any;
|
|
5
|
+
res: any;
|
|
6
|
+
component: React.ReactElement;
|
|
7
|
+
}
|
|
8
|
+
type Options = {
|
|
9
|
+
mode: "watch" | "start";
|
|
10
|
+
};
|
|
11
|
+
export declare function createXanixServer({ mode }: Options): express.Express;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
export function createXanixServer({ mode }) {
|
|
3
|
+
const app = express();
|
|
4
|
+
if (mode === "watch") {
|
|
5
|
+
app.use("/.xanix/client", express.static(".xanix/client"));
|
|
6
|
+
app.use("/assets", express.static(".xanix/assets"));
|
|
7
|
+
app.use("/.xanix/cache", express.static(".xanix/cache"));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
app.use("/.xanix/client", express.static(".xanix/client", {
|
|
11
|
+
maxAge: "1y",
|
|
12
|
+
immutable: true,
|
|
13
|
+
etag: true,
|
|
14
|
+
}));
|
|
15
|
+
app.use("/assets", express.static(".xanix/assets", {
|
|
16
|
+
maxAge: "1y",
|
|
17
|
+
immutable: true,
|
|
18
|
+
etag: true,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
app.use((req, res, next) => {
|
|
22
|
+
let data = {
|
|
23
|
+
title: null,
|
|
24
|
+
meta: [],
|
|
25
|
+
};
|
|
26
|
+
if (!req.page) {
|
|
27
|
+
req.page = {
|
|
28
|
+
setTitle(title) {
|
|
29
|
+
data.title = title;
|
|
30
|
+
},
|
|
31
|
+
setMeta(name, content) {
|
|
32
|
+
data.meta.push({ name, content });
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
req.XanixPageData = data;
|
|
36
|
+
}
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
return app;
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface XanixPageProps {
|
|
2
|
+
pageId: string;
|
|
3
|
+
req: any;
|
|
4
|
+
res: any;
|
|
5
|
+
Component: (props: Record<string, any>) => React.ReactElement;
|
|
6
|
+
props: Record<string, any>;
|
|
7
|
+
}
|
|
8
|
+
export default function xanix_page({ pageId, req, res, Component, props, }: XanixPageProps): Promise<string | undefined>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
3
|
+
import readManifest from "./readManifest.js";
|
|
4
|
+
import { PassThrough } from "node:stream";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
function renderPage(element) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
let html = "";
|
|
10
|
+
const stream = new PassThrough();
|
|
11
|
+
stream.on("data", (chunk) => {
|
|
12
|
+
html += chunk.toString();
|
|
13
|
+
});
|
|
14
|
+
stream.on("end", () => {
|
|
15
|
+
resolve(html);
|
|
16
|
+
});
|
|
17
|
+
stream.on("error", reject);
|
|
18
|
+
const { pipe } = renderToPipeableStream(element, {
|
|
19
|
+
onAllReady() {
|
|
20
|
+
pipe(stream);
|
|
21
|
+
},
|
|
22
|
+
onError(error) {
|
|
23
|
+
console.error("SSR error:", error);
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export default async function xanix_page({ pageId, req, res, Component, props, }) {
|
|
29
|
+
const manifest = await readManifest();
|
|
30
|
+
const { title, meta } = req.XanixPageData;
|
|
31
|
+
const entry = manifest.entries.find((item) => item.id === pageId);
|
|
32
|
+
const method = req.method.toUpperCase();
|
|
33
|
+
if (method !== "GET") {
|
|
34
|
+
res.status(405).send("Method Not Allowed");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (!entry) {
|
|
38
|
+
throw new Error(`Xanix client entry "${pageId}" was not found in the manifest.`);
|
|
39
|
+
}
|
|
40
|
+
if ("x-navigation" in req.headers) {
|
|
41
|
+
res.setHeader("Content-Type", "application/json");
|
|
42
|
+
return JSON.stringify({
|
|
43
|
+
pageId,
|
|
44
|
+
props,
|
|
45
|
+
title: title ?? entry.name.replaceAll("-", " "),
|
|
46
|
+
meta,
|
|
47
|
+
params: req.params,
|
|
48
|
+
request: null,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const Document = (await import(pathToFileURL(path.join(process.cwd(), ".xanix", "xanix-document.js"))
|
|
52
|
+
.href)).default;
|
|
53
|
+
const html = await renderPage(_jsx(Document, { document: {
|
|
54
|
+
pageId,
|
|
55
|
+
props,
|
|
56
|
+
title: title ?? entry.name.replaceAll("-", " "),
|
|
57
|
+
meta,
|
|
58
|
+
params: req.params,
|
|
59
|
+
request: req,
|
|
60
|
+
}, children: _jsx(Component, { ...props }) }));
|
|
61
|
+
return `<!DOCTYPE html>${html}`;
|
|
62
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
2
|
-
export declare const getGlobal: () => any;
|
|
3
|
-
export declare const getGlobalXanix: () => Record<string, any>;
|
|
4
|
-
export type DocumentData = {
|
|
5
|
-
head: ReactNode;
|
|
6
|
-
body: ReactNode;
|
|
7
|
-
};
|
|
8
|
-
export declare const getDocumentData: () => DocumentData;
|
|
9
|
-
export declare const getDocumentFile: () => Promise<string>;
|