@lazarv/react-server 0.0.0-experimental-43e79e6-20230928

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/bin/cli.mjs +93 -0
  4. package/bin/commands/build.mjs +19 -0
  5. package/bin/commands/dev.mjs +23 -0
  6. package/bin/commands/start.mjs +16 -0
  7. package/bin/loader.mjs +38 -0
  8. package/client/ActionState.mjs +16 -0
  9. package/client/ClientOnly.jsx +14 -0
  10. package/client/ClientProvider.jsx +243 -0
  11. package/client/ErrorBoundary.jsx +45 -0
  12. package/client/FlightContext.mjs +3 -0
  13. package/client/Link.jsx +59 -0
  14. package/client/Params.mjs +15 -0
  15. package/client/ReactServerComponent.jsx +77 -0
  16. package/client/Refresh.jsx +52 -0
  17. package/client/components.mjs +28 -0
  18. package/client/context.mjs +6 -0
  19. package/client/entry.client.jsx +146 -0
  20. package/client/index.jsx +6 -0
  21. package/client/navigation.jsx +4 -0
  22. package/config/context.mjs +37 -0
  23. package/config/index.mjs +114 -0
  24. package/lib/build/action.mjs +57 -0
  25. package/lib/build/banner.mjs +13 -0
  26. package/lib/build/chunks.mjs +26 -0
  27. package/lib/build/client.mjs +114 -0
  28. package/lib/build/custom-logger.mjs +13 -0
  29. package/lib/build/dependencies.mjs +54 -0
  30. package/lib/build/resolve.mjs +101 -0
  31. package/lib/build/server.mjs +142 -0
  32. package/lib/build/static.mjs +89 -0
  33. package/lib/dev/action.mjs +63 -0
  34. package/lib/dev/create-logger.mjs +52 -0
  35. package/lib/dev/create-server.mjs +208 -0
  36. package/lib/dev/modules.mjs +20 -0
  37. package/lib/dev/ssr-handler.mjs +135 -0
  38. package/lib/handlers/error.mjs +153 -0
  39. package/lib/handlers/not-found.mjs +5 -0
  40. package/lib/handlers/redirect.mjs +1 -0
  41. package/lib/handlers/rewrite.mjs +1 -0
  42. package/lib/handlers/static.mjs +120 -0
  43. package/lib/handlers/trailing-slash.mjs +12 -0
  44. package/lib/plugins/react-server.mjs +73 -0
  45. package/lib/plugins/use-client.mjs +135 -0
  46. package/lib/plugins/use-server.mjs +175 -0
  47. package/lib/start/action.mjs +110 -0
  48. package/lib/start/create-server.mjs +111 -0
  49. package/lib/start/manifest.mjs +104 -0
  50. package/lib/start/ssr-handler.mjs +134 -0
  51. package/lib/sys.mjs +49 -0
  52. package/lib/utils/merge.mjs +31 -0
  53. package/lib/utils/server-address.mjs +14 -0
  54. package/memory-cache/index.mjs +125 -0
  55. package/package.json +81 -0
  56. package/react-server.d.ts +209 -0
  57. package/server/ErrorBoundary.jsx +14 -0
  58. package/server/RemoteComponent.jsx +210 -0
  59. package/server/Route.jsx +108 -0
  60. package/server/actions.mjs +72 -0
  61. package/server/cache.mjs +19 -0
  62. package/server/client-component.mjs +62 -0
  63. package/server/context.mjs +32 -0
  64. package/server/cookies.mjs +14 -0
  65. package/server/entry.server.jsx +972 -0
  66. package/server/error-boundary.jsx +2 -0
  67. package/server/http-headers.mjs +8 -0
  68. package/server/http-status.mjs +6 -0
  69. package/server/index.mjs +14 -0
  70. package/server/logger.mjs +15 -0
  71. package/server/module-loader.mjs +20 -0
  72. package/server/redirects.mjs +45 -0
  73. package/server/remote-component.jsx +2 -0
  74. package/server/request.mjs +37 -0
  75. package/server/revalidate.mjs +22 -0
  76. package/server/rewrites.mjs +0 -0
  77. package/server/router.jsx +6 -0
  78. package/server/runtime.mjs +32 -0
  79. package/server/symbols.mjs +24 -0
@@ -0,0 +1,13 @@
1
+ import { createLogger } from "vite";
2
+
3
+ const logger = createLogger();
4
+
5
+ const loggerInfo = logger.info;
6
+ logger.info = (msg) => {
7
+ if (msg.includes("vite v")) {
8
+ return;
9
+ }
10
+ loggerInfo(msg);
11
+ };
12
+
13
+ export default logger;
@@ -0,0 +1,54 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ import * as sys from "../sys.mjs";
4
+
5
+ const __require = createRequire(import.meta.url);
6
+ const cwd = sys.cwd();
7
+
8
+ const react = __require.resolve("react");
9
+ const reactJsxRuntime = __require.resolve("react/jsx-runtime");
10
+ const reactJsxDevRuntime = __require.resolve("react/jsx-dev-runtime");
11
+ const reactDom = __require.resolve("react-dom");
12
+ const reactDomClient = __require.resolve("react-dom/client");
13
+ const reactDomServerEdge = __require.resolve("react-dom/server.edge");
14
+ const reactServerDomWebpackClientBrowser = __require.resolve(
15
+ "react-server-dom-webpack/client.browser"
16
+ );
17
+ const reactServerDomWebpackClientEdge = __require.resolve(
18
+ "react-server-dom-webpack/client.edge"
19
+ );
20
+ const reactServerDomWebpackServerEdge = __require.resolve(
21
+ "react-server-dom-webpack/server.edge"
22
+ );
23
+ const reactErrorBoundary = __require.resolve("react-error-boundary");
24
+ const scheduler = __require.resolve("scheduler");
25
+ const reactServerClient = __require.resolve("@lazarv/react-server/client", {
26
+ paths: [cwd],
27
+ });
28
+ const reactServerNavigation = __require.resolve(
29
+ "@lazarv/react-server/navigation"
30
+ );
31
+ const reactServerClientContext = __require.resolve(
32
+ "@lazarv/react-server/client/context.mjs"
33
+ );
34
+ const reactServerClientComponents = __require.resolve(
35
+ "@lazarv/react-server/client/components.mjs"
36
+ );
37
+
38
+ export {
39
+ react,
40
+ reactJsxRuntime,
41
+ reactJsxDevRuntime,
42
+ reactDom,
43
+ reactDomClient,
44
+ reactDomServerEdge,
45
+ reactServerDomWebpackClientBrowser,
46
+ reactServerDomWebpackClientEdge,
47
+ reactServerDomWebpackServerEdge,
48
+ reactErrorBoundary,
49
+ scheduler,
50
+ reactServerClient,
51
+ reactServerClientContext,
52
+ reactServerClientComponents,
53
+ reactServerNavigation,
54
+ };
@@ -0,0 +1,101 @@
1
+ import * as dependencies from "./dependencies.mjs";
2
+
3
+ export const serverAlias = (dev) => [
4
+ { find: /^react$/, replacement: dependencies.react },
5
+ {
6
+ find: /^react\/jsx-runtime$/,
7
+ replacement: dev
8
+ ? dependencies.reactJsxDevRuntime
9
+ : dependencies.reactJsxRuntime,
10
+ },
11
+ // {
12
+ // find: /^react\/jsx-dev-runtime$/,
13
+ // replacement: dependencies.reactJsxDevRuntime,
14
+ // },
15
+ { find: /^react-dom$/, replacement: dependencies.reactDom },
16
+ { find: /^react-dom\/client$/, replacement: dependencies.reactDomClient },
17
+ {
18
+ find: /^react-dom\/server.edge$/,
19
+ replacement: dependencies.reactDomServerEdge,
20
+ },
21
+ {
22
+ find: /^react-server-dom-webpack\/client.browser$/,
23
+ replacement: dependencies.reactServerDomWebpackClientBrowser,
24
+ },
25
+ {
26
+ find: /^react-server-dom-webpack\/client.edge$/,
27
+ replacement: dependencies.reactServerDomWebpackClientEdge,
28
+ },
29
+ {
30
+ find: /^react-server-dom-webpack\/server.edge$/,
31
+ replacement: dependencies.reactServerDomWebpackServerEdge,
32
+ },
33
+ {
34
+ find: /^react-error-boundary$/,
35
+ replacement: dependencies.reactErrorBoundary,
36
+ },
37
+ {
38
+ find: /^scheduler$/,
39
+ replacement: dependencies.scheduler,
40
+ },
41
+ // {
42
+ // find: /^@lazarv\/react-server\/client$/,
43
+ // replacement: dependencies.reactServerClient,
44
+ // },
45
+ // {
46
+ // find: /^@lazarv\/react-server\/client\/context\.mjs$/,
47
+ // replacement: dependencies.reactServerClientContext,
48
+ // },
49
+ // {
50
+ // find: /^@lazarv\/react-server\/client\/components\.mjs$/,
51
+ // replacement: dependencies.reactServerClientComponents,
52
+ // },
53
+ // {
54
+ // find: /^@lazarv\/react-server\/navigation$/,
55
+ // replacement: dependencies.reactServerNavigation,
56
+ // },
57
+ ];
58
+
59
+ export const clientAlias = (dev) => [
60
+ { find: /^react$/, replacement: dependencies.react },
61
+ {
62
+ find: /^react\/jsx-runtime$/,
63
+ replacement: dev
64
+ ? dependencies.reactJsxDevRuntime
65
+ : dependencies.reactJsxRuntime,
66
+ },
67
+ // {
68
+ // find: /^react\/jsx-dev-runtime$/,
69
+ // replacement: dependencies.reactJsxDevRuntime,
70
+ // },
71
+ { find: /^react-dom$/, replacement: dependencies.reactDom },
72
+ { find: /^react-dom\/client$/, replacement: dependencies.reactDomClient },
73
+ {
74
+ find: /^react-server-dom-webpack\/client.browser$/,
75
+ replacement: dependencies.reactServerDomWebpackClientBrowser,
76
+ },
77
+ {
78
+ find: /^react-error-boundary$/,
79
+ replacement: dependencies.reactErrorBoundary,
80
+ },
81
+ {
82
+ find: /^scheduler$/,
83
+ replacement: dependencies.scheduler,
84
+ },
85
+ // {
86
+ // find: /^@lazarv\/react-server\/client$/,
87
+ // replacement: dependencies.reactServerClient,
88
+ // },
89
+ // {
90
+ // find: /^@lazarv\/react-server\/navigation$/,
91
+ // replacement: dependencies.reactServerNavigation,
92
+ // },
93
+ // {
94
+ // find: /^@lazarv\/react-server\/client\/context\.mjs$/,
95
+ // replacement: dependencies.reactServerClientContext,
96
+ // },
97
+ // {
98
+ // find: /^@lazarv\/react-server\/client\/components\.mjs$/,
99
+ // replacement: dependencies.reactServerClientComponents,
100
+ // },
101
+ ];
@@ -0,0 +1,142 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ import replace from "@rollup/plugin-replace";
4
+ import viteReact from "@vitejs/plugin-react";
5
+ import { build as viteBuild } from "vite";
6
+
7
+ import { forRoot } from "../../config/index.mjs";
8
+ import merge from "../../lib/utils/merge.mjs";
9
+ import packageJson from "../../package.json" assert { type: "json" };
10
+ import viteReactServer from "../plugins/react-server.mjs";
11
+ import rollupUseClient from "../plugins/use-client.mjs";
12
+ import rollupUseServer from "../plugins/use-server.mjs";
13
+ import * as sys from "../sys.mjs";
14
+ import banner from "./banner.mjs";
15
+ import { serverChunks } from "./chunks.mjs";
16
+ import customLogger from "./custom-logger.mjs";
17
+ import { serverAlias } from "./resolve.mjs";
18
+
19
+ const __require = createRequire(import.meta.url);
20
+ const cwd = sys.cwd();
21
+
22
+ export default async function serverBuild(root, options) {
23
+ banner("server", options.dev);
24
+ const config = forRoot();
25
+ const buildConfig = {
26
+ root: __require.resolve(`${packageJson.name}`),
27
+ resolve: {
28
+ alias: [...serverAlias(options.dev), ...(config.resolve?.alias ?? [])],
29
+ },
30
+ customLogger,
31
+ build: {
32
+ ...config.build,
33
+ target: "esnext",
34
+ outDir: ".react-server",
35
+ emptyOutDir: false,
36
+ minify: options.minify,
37
+ manifest: "server/manifest.json",
38
+ ssr: true,
39
+ ssrEmitAssets: true,
40
+ sourcemap: options.sourcemap,
41
+ rollupOptions: {
42
+ ...config.build?.rollupOptions,
43
+ preserveEntrySignatures: "allow-extension",
44
+ output: {
45
+ dir: ".react-server",
46
+ format: "esm",
47
+ entryFileNames: "[name].mjs",
48
+ chunkFileNames: "server/@lazarv/react-server/[name].[hash].mjs",
49
+ manualChunks: (id) => {
50
+ if (serverChunks["react"].includes(id)) return "react";
51
+ if (id.includes("@lazarv/react-server") && id.endsWith(".mjs")) {
52
+ return "react-server";
53
+ }
54
+ },
55
+ },
56
+ input: {
57
+ "server/entry": __require.resolve(
58
+ "@lazarv/react-server/server/entry.server.jsx",
59
+ { paths: [cwd] }
60
+ ),
61
+ "server/index": __require.resolve(
62
+ root ?? "@lazarv/react-server-router",
63
+ { paths: [cwd] }
64
+ ),
65
+ "server/@lazarv/react-server/client/ClientOnly": __require.resolve(
66
+ "@lazarv/react-server/client/ClientOnly.jsx",
67
+ { paths: [cwd] }
68
+ ),
69
+ "server/@lazarv/react-server/client/ErrorBoundary": __require.resolve(
70
+ "@lazarv/react-server/client/ErrorBoundary.jsx",
71
+ { paths: [cwd] }
72
+ ),
73
+ "server/@lazarv/react-server/client/Link": __require.resolve(
74
+ "@lazarv/react-server/client/Link.jsx",
75
+ { paths: [cwd] }
76
+ ),
77
+ "server/@lazarv/react-server/client/Refresh": __require.resolve(
78
+ "@lazarv/react-server/client/Refresh.jsx",
79
+ { paths: [cwd] }
80
+ ),
81
+ "server/@lazarv/react-server/client/ReactServerComponent":
82
+ __require.resolve(
83
+ "@lazarv/react-server/client/ReactServerComponent.jsx",
84
+ { paths: [cwd] }
85
+ ),
86
+ },
87
+ external: [
88
+ /manifest\.json/,
89
+ /^bun:/,
90
+ ...(config.build?.rollupOptions?.external ?? []),
91
+ ],
92
+ plugins: [
93
+ replace({
94
+ preventAssignment: true,
95
+ "process.env.NODE_ENV": JSON.stringify(
96
+ options.dev ? "development" : "production"
97
+ ),
98
+ }),
99
+ rollupUseClient("server"),
100
+ rollupUseServer(),
101
+ ...(config.build?.rollupOptions?.plugins ?? []),
102
+ ],
103
+ },
104
+ },
105
+ plugins: [
106
+ viteReactServer("server"),
107
+ ...(!root || root === "@lazarv/react-server-router"
108
+ ? [
109
+ (async () =>
110
+ (
111
+ await import(
112
+ __require.resolve("@lazarv/react-server-router/plugin", {
113
+ paths: [cwd],
114
+ })
115
+ )
116
+ ).default())(),
117
+ ]
118
+ : []),
119
+ viteReact(),
120
+ ...(config.plugins ?? []),
121
+ ],
122
+ css: {
123
+ ...config.css,
124
+ postcss: cwd,
125
+ },
126
+ };
127
+
128
+ let viteConfig = buildConfig;
129
+
130
+ if (typeof config.build?.server?.config === "function")
131
+ viteConfig = config.build?.server?.config(buildConfig);
132
+
133
+ if (typeof config.build?.server?.config === "object")
134
+ viteConfig = merge(buildConfig, config.build?.server?.config);
135
+
136
+ if (typeof config.vite === "function") viteConfig = config.vite(viteConfig);
137
+
138
+ if (typeof config.vite === "object")
139
+ viteConfig = merge(viteConfig, config.vite);
140
+
141
+ return viteBuild(viteConfig);
142
+ }
@@ -0,0 +1,89 @@
1
+ import { createWriteStream } from "node:fs";
2
+ import { mkdir, stat, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { Readable } from "node:stream";
5
+ import { pipeline } from "node:stream/promises";
6
+ import { createBrotliCompress, createGzip } from "node:zlib";
7
+
8
+ import { filesize } from "filesize";
9
+ import colors from "picocolors";
10
+
11
+ import { forRoot } from "../../config/index.mjs";
12
+ import { getContext } from "../../server/context.mjs";
13
+ import { init$ as runtime_init$, runtime$ } from "../../server/runtime.mjs";
14
+ import { CONFIG_CONTEXT } from "../../server/symbols.mjs";
15
+ import ssrHandler from "../start/ssr-handler.mjs";
16
+ import { cwd } from "../sys.mjs";
17
+ import banner from "./banner.mjs";
18
+
19
+ const size = (bytes) => {
20
+ const s = filesize(bytes);
21
+ return " ".repeat(Math.max(0, 8 - s.length)) + s;
22
+ };
23
+
24
+ export default async function staticSiteGenerator(root, options) {
25
+ banner("static", options.dev);
26
+ const config = getContext(CONFIG_CONTEXT);
27
+
28
+ await runtime_init$(async () => {
29
+ runtime$(CONFIG_CONTEXT, config);
30
+
31
+ const configRoot = forRoot();
32
+
33
+ if (configRoot?.export) {
34
+ const paths =
35
+ typeof configRoot.export === "function"
36
+ ? await configRoot.export()
37
+ : configRoot.export;
38
+
39
+ const render = await ssrHandler();
40
+ await Promise.all(
41
+ paths.map(async ({ path }) => {
42
+ const stream = await render({
43
+ request: {
44
+ url: `http${config.server?.https ? "s" : ""}://${
45
+ config.host ?? "localhost"
46
+ }:${config.port ?? 3000}${path}`,
47
+ headers: new Headers({
48
+ accept: "text/html",
49
+ }),
50
+ },
51
+ });
52
+ const html = await stream.text();
53
+ await mkdir(join(cwd(), ".react-server/dist", path), {
54
+ recursive: true,
55
+ });
56
+ const basename = `${path.replace(/^\/+/g, "")}/index.html`;
57
+ const filename = join(cwd(), ".react-server/dist", basename);
58
+ const gzip = createGzip();
59
+ const brotli = createBrotliCompress();
60
+ const gzipWriteStream = createWriteStream(`${filename}.gz`);
61
+ const brotliWriteStream = createWriteStream(`${filename}.br`);
62
+ await Promise.all([
63
+ pipeline(Readable.from(html), gzip, gzipWriteStream),
64
+ pipeline(Readable.from(html), brotli, brotliWriteStream),
65
+ writeFile(filename, html, "utf8"),
66
+ ]);
67
+ const [htmlStat, gzipStat, brotliStat] = await Promise.all([
68
+ stat(filename),
69
+ stat(`${filename}.gz`),
70
+ stat(`${filename}.br`),
71
+ ]);
72
+ console.log(
73
+ `${colors.dim(".react-server/dist/")}${colors.green(
74
+ path.length < 30
75
+ ? `${path.replace(/^\/+/g, "")}${colors.cyan("/index.html")}`
76
+ : `${path.replace(/^\/+/g, "").slice(0, 27)}...`
77
+ )}${`${" ".repeat(Math.max(0, 30 - path.length))}${colors.gray(
78
+ colors.bold(size(htmlStat.size))
79
+ )} ${colors.dim(
80
+ `│ gzip: ${size(gzipStat.size)} │ brotli: ${size(
81
+ brotliStat.size
82
+ )}`
83
+ )}`}`
84
+ );
85
+ })
86
+ );
87
+ }
88
+ });
89
+ }
@@ -0,0 +1,63 @@
1
+ import open from "open";
2
+ import colors from "picocolors";
3
+
4
+ import { loadConfig } from "../../config/index.mjs";
5
+ import { logger } from "../../server/logger.mjs";
6
+ import { init$ as runtime_init$, runtime$ } from "../../server/runtime.mjs";
7
+ import {
8
+ CONFIG_CONTEXT,
9
+ CONFIG_ROOT,
10
+ SERVER_CONTEXT,
11
+ } from "../../server/symbols.mjs";
12
+ import getServerAddresses from "../utils/server-address.mjs";
13
+ import createServer from "./create-server.mjs";
14
+
15
+ export default async function dev(root, options) {
16
+ try {
17
+ const config = await loadConfig();
18
+ const configRoot = config[CONFIG_ROOT];
19
+
20
+ await runtime_init$(async () => {
21
+ runtime$(CONFIG_CONTEXT, config);
22
+
23
+ const server = await createServer(root, options);
24
+
25
+ const port = options.port ?? configRoot.port;
26
+ const host = options.host ?? configRoot.host;
27
+ const listenerHost = host === true ? undefined : host;
28
+
29
+ const listener = server.listen(port, listenerHost);
30
+ runtime$(SERVER_CONTEXT, listener);
31
+ listener
32
+ .on("listening", () => {
33
+ getServerAddresses(listener).forEach((address) => {
34
+ logger.info(
35
+ colors.gray(
36
+ `${colors.green("listening")} on http${
37
+ options.https ?? configRoot.server?.https ? "s" : ""
38
+ }://${address.address}:${listener.address().port}`
39
+ )
40
+ );
41
+ if (options.open ?? configRoot.server?.open) {
42
+ open(
43
+ `http${
44
+ options.https ?? configRoot.server?.https ? "s" : ""
45
+ }://${host}:${port}`
46
+ );
47
+ }
48
+ });
49
+ })
50
+ .on("error", (e) => {
51
+ console.error(colors.red(e.stack));
52
+ if (e.code === "EADDRINUSE") {
53
+ setTimeout(() => {
54
+ server.ws.listen();
55
+ server.listen(port, listenerHost);
56
+ }, 1000);
57
+ }
58
+ });
59
+ });
60
+ } catch (e) {
61
+ console.error(colors.red(e.stack));
62
+ }
63
+ }
@@ -0,0 +1,52 @@
1
+ import colors from "picocolors";
2
+ import { createLogger as createViteLogger } from "vite";
3
+
4
+ export default function createLogger() {
5
+ const logger = createViteLogger();
6
+ return {
7
+ ...logger,
8
+ ...["info", "warn", "warnOnce"].reduce((newLogger, command) => {
9
+ newLogger[command] = (...args) => {
10
+ const [msg] = args;
11
+ logger[command](
12
+ typeof msg !== "string"
13
+ ? args
14
+ .map((it) => {
15
+ if (typeof it !== "object") return colors.gray(`${it}`);
16
+ try {
17
+ return colors.cyan(JSON.stringify(it));
18
+ } catch (e) {
19
+ return colors.red(
20
+ `${it} ${e.message.replace(/\n/g, "")}`.replace(
21
+ /\s\s+/g,
22
+ " "
23
+ )
24
+ );
25
+ }
26
+ })
27
+ .join(" ")
28
+ : msg,
29
+ { timestamp: true }
30
+ );
31
+ };
32
+ return newLogger;
33
+ }, {}),
34
+ error(e) {
35
+ let msg = e?.stack;
36
+ if (!msg) {
37
+ try {
38
+ if (typeof e !== "string") {
39
+ msg = JSON.stringify(e);
40
+ } else {
41
+ msg = e;
42
+ }
43
+ } catch (e) {
44
+ msg = e.message || e;
45
+ }
46
+ }
47
+ logger.error(colors.red(msg), {
48
+ timestamp: true,
49
+ });
50
+ },
51
+ };
52
+ }