@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.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/bin/cli.mjs +93 -0
- package/bin/commands/build.mjs +19 -0
- package/bin/commands/dev.mjs +23 -0
- package/bin/commands/start.mjs +16 -0
- package/bin/loader.mjs +38 -0
- package/client/ActionState.mjs +16 -0
- package/client/ClientOnly.jsx +14 -0
- package/client/ClientProvider.jsx +243 -0
- package/client/ErrorBoundary.jsx +45 -0
- package/client/FlightContext.mjs +3 -0
- package/client/Link.jsx +59 -0
- package/client/Params.mjs +15 -0
- package/client/ReactServerComponent.jsx +77 -0
- package/client/Refresh.jsx +52 -0
- package/client/components.mjs +28 -0
- package/client/context.mjs +6 -0
- package/client/entry.client.jsx +146 -0
- package/client/index.jsx +6 -0
- package/client/navigation.jsx +4 -0
- package/config/context.mjs +37 -0
- package/config/index.mjs +114 -0
- package/lib/build/action.mjs +57 -0
- package/lib/build/banner.mjs +13 -0
- package/lib/build/chunks.mjs +26 -0
- package/lib/build/client.mjs +114 -0
- package/lib/build/custom-logger.mjs +13 -0
- package/lib/build/dependencies.mjs +54 -0
- package/lib/build/resolve.mjs +101 -0
- package/lib/build/server.mjs +142 -0
- package/lib/build/static.mjs +89 -0
- package/lib/dev/action.mjs +63 -0
- package/lib/dev/create-logger.mjs +52 -0
- package/lib/dev/create-server.mjs +208 -0
- package/lib/dev/modules.mjs +20 -0
- package/lib/dev/ssr-handler.mjs +135 -0
- package/lib/handlers/error.mjs +153 -0
- package/lib/handlers/not-found.mjs +5 -0
- package/lib/handlers/redirect.mjs +1 -0
- package/lib/handlers/rewrite.mjs +1 -0
- package/lib/handlers/static.mjs +120 -0
- package/lib/handlers/trailing-slash.mjs +12 -0
- package/lib/plugins/react-server.mjs +73 -0
- package/lib/plugins/use-client.mjs +135 -0
- package/lib/plugins/use-server.mjs +175 -0
- package/lib/start/action.mjs +110 -0
- package/lib/start/create-server.mjs +111 -0
- package/lib/start/manifest.mjs +104 -0
- package/lib/start/ssr-handler.mjs +134 -0
- package/lib/sys.mjs +49 -0
- package/lib/utils/merge.mjs +31 -0
- package/lib/utils/server-address.mjs +14 -0
- package/memory-cache/index.mjs +125 -0
- package/package.json +81 -0
- package/react-server.d.ts +209 -0
- package/server/ErrorBoundary.jsx +14 -0
- package/server/RemoteComponent.jsx +210 -0
- package/server/Route.jsx +108 -0
- package/server/actions.mjs +72 -0
- package/server/cache.mjs +19 -0
- package/server/client-component.mjs +62 -0
- package/server/context.mjs +32 -0
- package/server/cookies.mjs +14 -0
- package/server/entry.server.jsx +972 -0
- package/server/error-boundary.jsx +2 -0
- package/server/http-headers.mjs +8 -0
- package/server/http-status.mjs +6 -0
- package/server/index.mjs +14 -0
- package/server/logger.mjs +15 -0
- package/server/module-loader.mjs +20 -0
- package/server/redirects.mjs +45 -0
- package/server/remote-component.jsx +2 -0
- package/server/request.mjs +37 -0
- package/server/revalidate.mjs +22 -0
- package/server/rewrites.mjs +0 -0
- package/server/router.jsx +6 -0
- package/server/runtime.mjs +32 -0
- package/server/symbols.mjs +24 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
import { getContext } from "../../server/context.mjs";
|
|
4
|
+
import { runtime$ } from "../../server/runtime.mjs";
|
|
5
|
+
import {
|
|
6
|
+
COLLECT_STYLESHEETS,
|
|
7
|
+
HTTP_CONTEXT,
|
|
8
|
+
MAIN_MODULE,
|
|
9
|
+
MANIFEST,
|
|
10
|
+
MODULE_LOADER,
|
|
11
|
+
} from "../../server/symbols.mjs";
|
|
12
|
+
|
|
13
|
+
const __require = createRequire(import.meta.url);
|
|
14
|
+
|
|
15
|
+
export async function init$() {
|
|
16
|
+
const serverManifest = __require.resolve(
|
|
17
|
+
"./.react-server/server/manifest.json",
|
|
18
|
+
{
|
|
19
|
+
paths: [process.cwd()],
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
const clientManifest = __require.resolve(
|
|
23
|
+
"./.react-server/client/manifest.json",
|
|
24
|
+
{
|
|
25
|
+
paths: [process.cwd()],
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
const [{ default: server }, { default: client }] = await Promise.all([
|
|
29
|
+
import(serverManifest, { assert: { type: "json" } }),
|
|
30
|
+
import(clientManifest, { assert: { type: "json" } }),
|
|
31
|
+
]);
|
|
32
|
+
const manifest = {
|
|
33
|
+
server,
|
|
34
|
+
client,
|
|
35
|
+
};
|
|
36
|
+
runtime$(MANIFEST, manifest);
|
|
37
|
+
|
|
38
|
+
const mainModule = `/${
|
|
39
|
+
Object.values(manifest.client).find(
|
|
40
|
+
(entry) => entry.src === "../../client/entry.client.jsx"
|
|
41
|
+
).file
|
|
42
|
+
}`;
|
|
43
|
+
runtime$(MAIN_MODULE, [mainModule]);
|
|
44
|
+
|
|
45
|
+
const entryCache = new Map();
|
|
46
|
+
function ssrLoadModule($$id) {
|
|
47
|
+
const httpContext = getContext(HTTP_CONTEXT);
|
|
48
|
+
const [id /*, name*/] = $$id
|
|
49
|
+
.replace(
|
|
50
|
+
`${
|
|
51
|
+
httpContext?.request?.headers?.get("x-forwarded-for") ||
|
|
52
|
+
new URL(httpContext?.url).origin
|
|
53
|
+
}/`,
|
|
54
|
+
""
|
|
55
|
+
)
|
|
56
|
+
.split("::");
|
|
57
|
+
try {
|
|
58
|
+
const moduleUri = new URL(id);
|
|
59
|
+
if (moduleUri.protocol === "http:" || moduleUri.protocol === "https:") {
|
|
60
|
+
return import(id);
|
|
61
|
+
}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
// noop
|
|
64
|
+
}
|
|
65
|
+
if (entryCache.has(id)) {
|
|
66
|
+
return import(entryCache.get(id));
|
|
67
|
+
}
|
|
68
|
+
const clientEntry = Object.values(manifest.client).find((entry) =>
|
|
69
|
+
entry.file.endsWith(id)
|
|
70
|
+
);
|
|
71
|
+
const serverEntry = Object.values(manifest.server).find((entry) =>
|
|
72
|
+
entry.src.endsWith(clientEntry.src)
|
|
73
|
+
);
|
|
74
|
+
const specifier = __require.resolve(`./.react-server/${serverEntry.file}`, {
|
|
75
|
+
paths: [process.cwd()],
|
|
76
|
+
});
|
|
77
|
+
entryCache.set(id, specifier);
|
|
78
|
+
return import(specifier);
|
|
79
|
+
}
|
|
80
|
+
runtime$(MODULE_LOADER, ssrLoadModule);
|
|
81
|
+
|
|
82
|
+
function collectStylesheets(rootModule) {
|
|
83
|
+
if (!rootModule) return [];
|
|
84
|
+
const rootManifest = Array.from(Object.values(manifest.server)).find(
|
|
85
|
+
(entry) =>
|
|
86
|
+
rootModule.endsWith(entry.file) || entry.src.endsWith(rootModule)
|
|
87
|
+
);
|
|
88
|
+
const styles = [];
|
|
89
|
+
function collectCss(entry) {
|
|
90
|
+
if (!entry) return styles;
|
|
91
|
+
if (entry.css) {
|
|
92
|
+
styles.push(...entry.css.map((href) => `/${href}`));
|
|
93
|
+
}
|
|
94
|
+
if (entry.imports) {
|
|
95
|
+
entry.imports.forEach((imported) =>
|
|
96
|
+
collectCss(manifest.server[imported])
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
collectCss(rootManifest);
|
|
101
|
+
return styles;
|
|
102
|
+
}
|
|
103
|
+
runtime$(COLLECT_STYLESHEETS, collectStylesheets);
|
|
104
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
import { forChild } from "../../config/index.mjs";
|
|
4
|
+
import { init$ as memory_cache_init$ } from "../../memory-cache/index.mjs";
|
|
5
|
+
import { ContextStorage, getContext } from "../../server/context.mjs";
|
|
6
|
+
import { logger } from "../../server/logger.mjs";
|
|
7
|
+
import { init$ as module_loader_init$ } from "../../server/module-loader.mjs";
|
|
8
|
+
import { getRuntime } from "../../server/runtime.mjs";
|
|
9
|
+
import {
|
|
10
|
+
COLLECT_STYLESHEETS,
|
|
11
|
+
CONFIG_CONTEXT,
|
|
12
|
+
CONFIG_ROOT,
|
|
13
|
+
ERROR_CONTEXT,
|
|
14
|
+
FORM_DATA_PARSER,
|
|
15
|
+
HTTP_CONTEXT,
|
|
16
|
+
LOGGER_CONTEXT,
|
|
17
|
+
MAIN_MODULE,
|
|
18
|
+
MANIFEST,
|
|
19
|
+
MEMORY_CACHE_CONTEXT,
|
|
20
|
+
MODULE_LOADER,
|
|
21
|
+
REDIRECT_CONTEXT,
|
|
22
|
+
SERVER_CONTEXT,
|
|
23
|
+
STYLES_CONTEXT,
|
|
24
|
+
} from "../../server/symbols.mjs";
|
|
25
|
+
import errorHandler from "../handlers/error.mjs";
|
|
26
|
+
import { init$ as manifest_init$ } from "./manifest.mjs";
|
|
27
|
+
|
|
28
|
+
const __require = createRequire(import.meta.url);
|
|
29
|
+
|
|
30
|
+
const defaultRoot = `${process.cwd()}/.react-server/server/index.mjs`;
|
|
31
|
+
export default async function ssrHandler(root) {
|
|
32
|
+
const config = getRuntime(CONFIG_CONTEXT);
|
|
33
|
+
const configRoot = config?.[CONFIG_ROOT] ?? {};
|
|
34
|
+
|
|
35
|
+
await manifest_init$();
|
|
36
|
+
|
|
37
|
+
const entryModule = __require.resolve(
|
|
38
|
+
`${process.cwd()}/.react-server/server/entry.mjs`
|
|
39
|
+
);
|
|
40
|
+
const rootModule = __require.resolve(
|
|
41
|
+
root ?? configRoot.entry ?? defaultRoot,
|
|
42
|
+
{
|
|
43
|
+
paths: [process.cwd()],
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
const { render } = await import(entryModule);
|
|
47
|
+
const { default: Component, init$: root_init$ } = await import(rootModule);
|
|
48
|
+
const collectStylesheets = getRuntime(COLLECT_STYLESHEETS);
|
|
49
|
+
const styles = getRuntime(COLLECT_STYLESHEETS)?.(rootModule) ?? [];
|
|
50
|
+
const mainModule = getRuntime(MAIN_MODULE);
|
|
51
|
+
const formDataParser = getRuntime(FORM_DATA_PARSER);
|
|
52
|
+
const moduleLoader = getRuntime(MODULE_LOADER);
|
|
53
|
+
const memoryCache = getRuntime(MEMORY_CACHE_CONTEXT);
|
|
54
|
+
const manifest = getRuntime(MANIFEST);
|
|
55
|
+
await module_loader_init$(moduleLoader);
|
|
56
|
+
|
|
57
|
+
return async (httpContext) => {
|
|
58
|
+
// const accept = httpContext.request.headers.get("accept");
|
|
59
|
+
// if (
|
|
60
|
+
// !accept ||
|
|
61
|
+
// !(accept.includes("text/html") || accept.includes("text/x-component"))
|
|
62
|
+
// ) {
|
|
63
|
+
// return;
|
|
64
|
+
// }
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
try {
|
|
67
|
+
ContextStorage.run(
|
|
68
|
+
{
|
|
69
|
+
[SERVER_CONTEXT]: getRuntime(SERVER_CONTEXT),
|
|
70
|
+
[CONFIG_CONTEXT]: config,
|
|
71
|
+
[HTTP_CONTEXT]: httpContext,
|
|
72
|
+
[ERROR_CONTEXT]: errorHandler,
|
|
73
|
+
[LOGGER_CONTEXT]: logger,
|
|
74
|
+
[MAIN_MODULE]: mainModule,
|
|
75
|
+
[FORM_DATA_PARSER]: formDataParser,
|
|
76
|
+
[MODULE_LOADER]: moduleLoader,
|
|
77
|
+
[MEMORY_CACHE_CONTEXT]: memoryCache,
|
|
78
|
+
[MANIFEST]: manifest,
|
|
79
|
+
[REDIRECT_CONTEXT]: {},
|
|
80
|
+
[COLLECT_STYLESHEETS]: collectStylesheets,
|
|
81
|
+
[STYLES_CONTEXT]: styles,
|
|
82
|
+
},
|
|
83
|
+
async () => {
|
|
84
|
+
const cacheModule = forChild(httpContext.url)?.cache?.module;
|
|
85
|
+
|
|
86
|
+
if (cacheModule) {
|
|
87
|
+
const { init$: cache_init$ } = await import(
|
|
88
|
+
__require.resolve(cacheModule, {
|
|
89
|
+
paths: [process.cwd()],
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
await cache_init$?.();
|
|
93
|
+
} else {
|
|
94
|
+
await memory_cache_init$?.();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const middlewares = await root_init$?.();
|
|
99
|
+
if (middlewares) {
|
|
100
|
+
const response = await middlewares(httpContext);
|
|
101
|
+
if (response) {
|
|
102
|
+
return resolve(response);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} catch (e) {
|
|
106
|
+
const redirect = getContext(REDIRECT_CONTEXT);
|
|
107
|
+
if (redirect?.response) {
|
|
108
|
+
return resolve(redirect.response);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const accept = httpContext.request.headers.get("accept");
|
|
113
|
+
if (
|
|
114
|
+
!accept ||
|
|
115
|
+
!(
|
|
116
|
+
accept.includes("text/html") ||
|
|
117
|
+
accept.includes("text/x-component") ||
|
|
118
|
+
accept.includes("application/json")
|
|
119
|
+
)
|
|
120
|
+
) {
|
|
121
|
+
return resolve();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const styles = getContext(STYLES_CONTEXT);
|
|
125
|
+
render(Component, styles).then(resolve, reject);
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
logger.error(e);
|
|
130
|
+
errorHandler(e).then(resolve);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
}
|
package/lib/sys.mjs
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function cwd() {
|
|
2
|
+
return typeof Deno !== "undefined" ? Deno.cwd() : process.cwd();
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function argv() {
|
|
6
|
+
return typeof Deno !== "undefined"
|
|
7
|
+
? [Deno.execPath(), Deno.mainModule, ...Deno.args]
|
|
8
|
+
: process.argv;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function exit(code) {
|
|
12
|
+
typeof Deno !== "undefined" ? Deno.exit(code) : process.exit(code);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getEnv(name) {
|
|
16
|
+
return typeof Deno !== "undefined" ? Deno.env.get(name) : process.env[name];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function setEnv(name, value) {
|
|
20
|
+
typeof Deno !== "undefined"
|
|
21
|
+
? Deno.env.set(name, value)
|
|
22
|
+
: (process.env[name] = value);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function copyBytesFrom(buffer) {
|
|
26
|
+
return typeof Deno !== "undefined"
|
|
27
|
+
? new Uint8Array(buffer)
|
|
28
|
+
: Buffer.copyBytesFrom(buffer);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function concat(buffers) {
|
|
32
|
+
return typeof Deno !== "undefined"
|
|
33
|
+
? new Uint8Array(buffers.reduce((acc, buf) => [...acc, ...buf], []))
|
|
34
|
+
: Buffer.concat(buffers);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function immediate(fn) {
|
|
38
|
+
return typeof Deno !== "undefined" ? fn() : setImmediate(fn);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (typeof Deno !== "undefined") {
|
|
42
|
+
globalThis.process = {
|
|
43
|
+
env: Deno.env.toObject(),
|
|
44
|
+
cwd: Deno.cwd,
|
|
45
|
+
argv: [Deno.execPath(), Deno.mainModule, ...Deno.args],
|
|
46
|
+
exit: Deno.exit,
|
|
47
|
+
emit: function () {},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function isObject(item) {
|
|
2
|
+
return (
|
|
3
|
+
item &&
|
|
4
|
+
typeof item === "object" &&
|
|
5
|
+
!Array.isArray(item) &&
|
|
6
|
+
Object.getPrototypeOf(item) === Object.prototype
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function mergeDeep(target, ...sources) {
|
|
11
|
+
if (!sources.length) return target;
|
|
12
|
+
const source = sources.shift();
|
|
13
|
+
|
|
14
|
+
if (isObject(target) && isObject(source)) {
|
|
15
|
+
for (const key in source) {
|
|
16
|
+
if (isObject(source[key])) {
|
|
17
|
+
if (!target[key])
|
|
18
|
+
Object.assign(target, {
|
|
19
|
+
[key]: {},
|
|
20
|
+
});
|
|
21
|
+
mergeDeep(target[key], source[key]);
|
|
22
|
+
} else {
|
|
23
|
+
Object.assign(target, {
|
|
24
|
+
[key]: source[key],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return mergeDeep(target, ...sources);
|
|
31
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { networkInterfaces } from "node:os";
|
|
2
|
+
|
|
3
|
+
export default function getServerAddresses(server) {
|
|
4
|
+
const serverAddress = server.address();
|
|
5
|
+
const addresses = Object.values(networkInterfaces());
|
|
6
|
+
return (
|
|
7
|
+
addresses.find((addresses) =>
|
|
8
|
+
addresses.some((address) => address.address === serverAddress.address),
|
|
9
|
+
) ||
|
|
10
|
+
addresses.flatMap((addresses) =>
|
|
11
|
+
addresses.filter((address) => address.family === "IPv4"),
|
|
12
|
+
)
|
|
13
|
+
).filter((address) => address.family === "IPv4");
|
|
14
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { context$, getContext } from "../server/context.mjs";
|
|
2
|
+
import { CACHE_CONTEXT, MEMORY_CACHE_CONTEXT } from "../server/symbols.mjs";
|
|
3
|
+
|
|
4
|
+
export class MemoryCache {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.cache = new Map();
|
|
7
|
+
this.expiry = new Map();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async get(keys) {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
|
|
13
|
+
const expiryEntries = this.expiry.entries();
|
|
14
|
+
const deleteQueue = [];
|
|
15
|
+
for (const [expiryKeys, expiry] of expiryEntries) {
|
|
16
|
+
if (expiry < now) {
|
|
17
|
+
this.expiry.delete(expiryKeys);
|
|
18
|
+
deleteQueue.push(this.delete(expiryKeys));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
await Promise.all(deleteQueue);
|
|
22
|
+
|
|
23
|
+
const cacheKeys = this.cache.keys();
|
|
24
|
+
for (const entryKeys of cacheKeys) {
|
|
25
|
+
if (
|
|
26
|
+
keys.every((key, keyIndex) => entryKeys[keyIndex] === key?.toString())
|
|
27
|
+
) {
|
|
28
|
+
return this.cache.get(entryKeys);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async set(keys, value) {
|
|
36
|
+
if (await this.hasExpiry(keys)) {
|
|
37
|
+
const cacheKeys = this.cache.keys();
|
|
38
|
+
for (const entryKeys of cacheKeys) {
|
|
39
|
+
if (
|
|
40
|
+
keys.every((key, keyIndex) => entryKeys[keyIndex] === key?.toString())
|
|
41
|
+
) {
|
|
42
|
+
this.cache.set(entryKeys, value);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
this.cache.set(
|
|
47
|
+
keys.map((key) => key?.toString()),
|
|
48
|
+
value
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async has(keys) {
|
|
54
|
+
const cacheKeys = this.cache.keys();
|
|
55
|
+
for (const entryKeys of cacheKeys) {
|
|
56
|
+
if (
|
|
57
|
+
keys.every((key, keyIndex) => entryKeys[keyIndex] === key?.toString())
|
|
58
|
+
) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async setExpiry(keys, expiry) {
|
|
67
|
+
const expiryKeys = this.expiry.keys();
|
|
68
|
+
for (const entryKeys of expiryKeys) {
|
|
69
|
+
if (
|
|
70
|
+
keys.every((key, keyIndex) => entryKeys[keyIndex] === key?.toString())
|
|
71
|
+
) {
|
|
72
|
+
this.expiry.set(entryKeys, expiry);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
this.expiry.set(
|
|
77
|
+
keys.map((key) => key?.toString()),
|
|
78
|
+
expiry
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async hasExpiry(keys) {
|
|
83
|
+
const expiryKeys = this.expiry.keys();
|
|
84
|
+
for (const entryKeys of expiryKeys) {
|
|
85
|
+
for (let keyIndex = 0; keyIndex < entryKeys.length; keyIndex++) {
|
|
86
|
+
const key = keys[keyIndex];
|
|
87
|
+
if (entryKeys[keyIndex] !== key?.toString()) {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
if (keyIndex === entryKeys.length - 1) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async delete(keys) {
|
|
100
|
+
const cacheKeys = this.cache.keys();
|
|
101
|
+
for (const entryKeys of cacheKeys) {
|
|
102
|
+
if (
|
|
103
|
+
keys.every((key, keyIndex) => entryKeys[keyIndex] === key?.toString())
|
|
104
|
+
) {
|
|
105
|
+
this.cache.delete(entryKeys);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const cache = new MemoryCache();
|
|
112
|
+
export async function init$() {
|
|
113
|
+
return context$(CACHE_CONTEXT, cache);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function useCache(keys, promise, ttl = Infinity, force = false) {
|
|
117
|
+
const cache = getContext(MEMORY_CACHE_CONTEXT);
|
|
118
|
+
let result = await cache.get(keys);
|
|
119
|
+
if (force || result === null) {
|
|
120
|
+
result = typeof promise === "function" ? await promise() : promise;
|
|
121
|
+
await cache.setExpiry(keys, Date.now() + ttl);
|
|
122
|
+
await cache.set(keys, result);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lazarv/react-server",
|
|
3
|
+
"version": "0.0.0-experimental-43e79e6-20230928",
|
|
4
|
+
"description": "Experimental React meta-framework using Vite",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"module": "server/index.mjs",
|
|
7
|
+
"bin": "bin/cli.mjs",
|
|
8
|
+
"types": "react-server.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./server/index.mjs",
|
|
11
|
+
"./client": "./client/index.jsx",
|
|
12
|
+
"./config": "./config/index.mjs",
|
|
13
|
+
"./error-boundary": "./server/error-boundary.jsx",
|
|
14
|
+
"./memory-cache": "./memory-cache/index.mjs",
|
|
15
|
+
"./navigation": "./client/navigation.jsx",
|
|
16
|
+
"./remote-component": "./server/remote-component.jsx",
|
|
17
|
+
"./router": "./server/router.jsx",
|
|
18
|
+
"./client/*": "./client/*",
|
|
19
|
+
"./server/*": "./server/*",
|
|
20
|
+
"./lib/*": "./lib/*",
|
|
21
|
+
"./*": "./*"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"react",
|
|
25
|
+
"ssr",
|
|
26
|
+
"esm",
|
|
27
|
+
"server"
|
|
28
|
+
],
|
|
29
|
+
"author": "lazarv",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/lazarv/react-server.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/lazarv/react-server/issues"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@hattip/adapter-node": "^0.0.34",
|
|
40
|
+
"@hattip/compose": "^0.0.34",
|
|
41
|
+
"@hattip/cookie": "^0.0.34",
|
|
42
|
+
"@hattip/core": "^0.0.34",
|
|
43
|
+
"@hattip/cors": "^0.0.34",
|
|
44
|
+
"@hattip/headers": "^0.0.34",
|
|
45
|
+
"@hattip/multipart": "^0.0.34",
|
|
46
|
+
"@rollup/plugin-replace": "^5.0.2",
|
|
47
|
+
"@vitejs/plugin-react": "^4.0.1",
|
|
48
|
+
"acorn": "^8.10.0",
|
|
49
|
+
"cac": "^6.7.14",
|
|
50
|
+
"esbuild": "^0.19.3",
|
|
51
|
+
"escodegen": "^2.1.0",
|
|
52
|
+
"estraverse": "^5.3.0",
|
|
53
|
+
"fast-glob": "^3.2.12",
|
|
54
|
+
"filesize": "^10.0.12",
|
|
55
|
+
"mime": "^3.0.0",
|
|
56
|
+
"module-alias": "^2.2.3",
|
|
57
|
+
"open": "^9.1.0",
|
|
58
|
+
"picocolors": "^1.0.0",
|
|
59
|
+
"pino": "^8.14.1",
|
|
60
|
+
"rimraf": "^5.0.1",
|
|
61
|
+
"sass": "^1.63.6",
|
|
62
|
+
"strip-ansi": "^7.1.0",
|
|
63
|
+
"vite": "^4.4.9"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"react": "0.0.0-experimental-41f0e9dae-20230907",
|
|
67
|
+
"react-dom": "0.0.0-experimental-41f0e9dae-20230907",
|
|
68
|
+
"react-error-boundary": "^4.0.10",
|
|
69
|
+
"react-server-dom-webpack": "0.0.0-experimental-41f0e9dae-20230907"
|
|
70
|
+
},
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=20.0.0"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"react": "0.0.0-experimental-41f0e9dae-20230907",
|
|
76
|
+
"react-dom": "0.0.0-experimental-41f0e9dae-20230907",
|
|
77
|
+
"react-error-boundary": "^4.0.10",
|
|
78
|
+
"react-server-dom-webpack": "0.0.0-experimental-41f0e9dae-20230907"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {}
|
|
81
|
+
}
|