Skip to content

Commit aaa097f

Browse files
committed
Feat(cosmos): add react-cosmos
1 parent 4468b48 commit aaa097f

8 files changed

+195
-11
lines changed

bun.lockb

70.4 KB
Binary file not shown.

cosmos.bunserver.ts

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { rm, stat } from "node:fs/promises";
2+
import type { ServeOptions } from "bun";
3+
import * as path from "path";
4+
5+
import cosmosConfig from "./cosmos.config.json";
6+
7+
const PROJECT_ROOT = import.meta.dir;
8+
const BUILD_DIR = path.resolve(PROJECT_ROOT, "build");
9+
10+
const waitForCosmosImports = async () => {
11+
const fpath = `${PROJECT_ROOT}/cosmos.imports.ts`;
12+
try {
13+
const cosmosImports = await stat(fpath);
14+
if (!cosmosImports.isFile()) {
15+
throw new Error(`
16+
file doesnt exist yet
17+
`);
18+
}
19+
} catch {
20+
return new Promise((resolve) => {
21+
setTimeout(() => resolve(waitForCosmosImports()), 1000);
22+
});
23+
}
24+
};
25+
26+
const buildApp = async () =>
27+
rm(BUILD_DIR, { force: true, recursive: true }).then(() =>
28+
Bun.build({
29+
entrypoints: ["./cosmos.entrypoint.tsx"],
30+
target: "browser",
31+
outdir: "build",
32+
})
33+
.then((output) => output)
34+
.catch((e) => {
35+
console.info("\n\n error in build", e);
36+
})
37+
);
38+
39+
await waitForCosmosImports();
40+
await buildApp().then((output) => {
41+
if (output.success)
42+
console.info(
43+
`app built: ${output.success}; ${output.outputs.length} files `
44+
);
45+
else {
46+
for (const message of output.logs) {
47+
// Bun will pretty print the message object
48+
console.error(message);
49+
}
50+
throw new Error(`build failed`);
51+
}
52+
});
53+
54+
const returnIndex = () => {
55+
const index = `
56+
<!DOCTYPE html>
57+
<html lang="en">
58+
<body>
59+
<script src="${BUILD_DIR}/cosmos.entrypoint.js" type="module">
60+
</script>
61+
</body>
62+
</html>
63+
`;
64+
65+
return new Response(index, {
66+
headers: {
67+
"Content-Type": "text/html",
68+
"Access-Control-Allow-Origin": "*",
69+
},
70+
});
71+
};
72+
73+
async function serveFromDir(config: {
74+
directory?: string;
75+
path: string;
76+
}): Promise<Response | null> {
77+
const filepath = path.join(config.directory || "", config.path);
78+
79+
try {
80+
const fd = await stat(filepath);
81+
if (fd && fd.isFile()) {
82+
return new Response(Bun.file(filepath), {
83+
headers: { "Access-Control-Allow-Origin": "*" },
84+
});
85+
}
86+
} catch (err) {}
87+
88+
return null;
89+
}
90+
export default {
91+
port: cosmosConfig.rendererUrl.split(":").pop(),
92+
hostname: "0.0.0.0",
93+
async fetch(req) {
94+
const reqPath = new URL(req.url).pathname;
95+
console.log(req.method, reqPath);
96+
97+
if (reqPath === "/") return returnIndex();
98+
else {
99+
const filepath = req.url.replace(cosmosConfig.rendererUrl, "");
100+
101+
const exactResponse = await serveFromDir({ path: filepath });
102+
if (exactResponse) return exactResponse;
103+
104+
const buildResponse = await serveFromDir({
105+
directory: BUILD_DIR,
106+
path: filepath,
107+
});
108+
if (buildResponse) return buildResponse;
109+
110+
return new Response("File not found", {
111+
status: 404,
112+
});
113+
}
114+
},
115+
} satisfies ServeOptions;
116+
117+
// watch imports
118+
await import("./cosmos.imports.ts").catch((e) => e);

cosmos.config.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"port": 5000,
3+
"rendererUrl": "http://0.0.0.0:5050"
4+
}

cosmos.entrypoint.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { mountDomRenderer } from "react-cosmos-dom";
2+
import * as mountArgs from "./cosmos.imports";
3+
4+
mountDomRenderer(mountArgs);

cosmos.imports.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// This file is automatically generated by Cosmos. Add it to .gitignore and
2+
// only edit if you know what you're doing.
3+
4+
import { RendererConfig, UserModuleWrappers } from 'react-cosmos-core';
5+
6+
import * as fixture0 from './src/fixtures/example.fixture';
7+
8+
export const rendererConfig: RendererConfig = {
9+
"playgroundUrl": "http://localhost:5000",
10+
"rendererUrl": "http://0.0.0.0:5050"
11+
};
12+
13+
const fixtures = {
14+
'src/fixtures/example.fixture.tsx': { module: fixture0 }
15+
};
16+
17+
const decorators = {};
18+
19+
export const moduleWrappers: UserModuleWrappers = {
20+
lazy: false,
21+
fixtures,
22+
decorators
23+
};

package.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
"main": "dist/index.js",
88
"module": "src/index.ts",
99
"scripts": {
10+
"cosmos": "bun run cosmos:start & bun run cosmos:bun",
11+
"cosmos:bun": "bun --watch cosmos.bunserver.ts",
12+
"cosmos:start": "cosmos --expose-imports",
1013
"barrels": "bunx barrelsby --config ./barrels.json",
1114
"build": "rm -rf ./dist/* && bun build src/index.ts --outdir ./dist",
1215
"lint": "bunx eslint src --fix --resolve-plugins-relative-to .",
@@ -20,14 +23,17 @@
2023
"react": "^18.2"
2124
},
2225
"devDependencies": {
23-
"@types/react": "18.2.7",
26+
"react-cosmos-core": "^6.0.0-alpha.0",
27+
"react-cosmos-dom": "next",
28+
"react-cosmos": "next",
29+
"@types/react": "18.2.9",
2430
"barrels": "1.6.6",
2531
"bun-types": "canary",
2632
"eslint-config-prettier": "8.8.0",
2733
"eslint-config-react-app": "7.0.1",
2834
"eslint-plugin-jsx-a11y": "6.7.1",
2935
"eslint-plugin-react": "7.32.2",
30-
"eslint": "8.41.0",
36+
"eslint": "8.42.0",
3137
"framer-motion": "10.12.16",
3238
"npm-check-updates": "16.10.12",
3339
"prettier": "2.8.8",

src/fixtures/example.fixture.tsx

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { ReactFP, FPContainer, FPItem } from "src/index";
2+
3+
export default function App() {
4+
return (
5+
<ReactFP>
6+
<FPContainer>
7+
<FPItem
8+
style={{
9+
backgroundColor: "lime",
10+
height: "80vh", // defaults to 100vh
11+
padding: "1em",
12+
}}
13+
>
14+
1
15+
</FPItem>
16+
17+
<FPItem
18+
style={{
19+
backgroundColor: "coral",
20+
padding: "1em",
21+
}}
22+
>
23+
2
24+
</FPItem>
25+
26+
<FPItem
27+
style={{
28+
backgroundColor: "firebrick",
29+
padding: "1em",
30+
}}
31+
>
32+
3
33+
</FPItem>
34+
</FPContainer>
35+
</ReactFP>
36+
);
37+
}

tsconfig.json

+1-9
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,11 @@
1010
"**/node_modules",
1111
"**/.git",
1212
"**/build",
13-
"**/.turbo",
1413
"**/dist",
1514
"**/lib"
1615
]
1716
},
18-
"exclude": [
19-
"**/node_modules",
20-
"**/.git",
21-
"**/build",
22-
"**/.turbo",
23-
"**/dist",
24-
"**/lib"
25-
],
17+
"exclude": ["**/node_modules", "**/.git", "**/build", "**/dist", "**/lib"],
2618
"compilerOptions": {
2719
"allowImportingTsExtensions": true,
2820
"allowJs": true,

0 commit comments

Comments
 (0)