pixelass commited on
Commit
e5ae926
•
1 Parent(s): a86df80

feat: 100% browser yeah baby yeah

Browse files
.env.local.example CHANGED
@@ -1 +1 @@
1
- OPENAI_API_KEY=
 
1
+ OPENAI_API_KEY=
.gitignore CHANGED
@@ -70,7 +70,7 @@ typings/
70
 
71
  # dotenv environment variables file
72
  .env
73
- .env.test
74
 
75
  # parcel-bundler cache (https://parceljs.org/)
76
  .cache
 
70
 
71
  # dotenv environment variables file
72
  .env
73
+ .env.local
74
 
75
  # parcel-bundler cache (https://parceljs.org/)
76
  .cache
package-lock.json CHANGED
The diff for this file is too large to render. See raw diff
 
package.json CHANGED
@@ -17,13 +17,26 @@
17
  "url": "https://github.com/pixelass/"
18
  },
19
  "scripts": {
20
- "dev": "concurrently 'npm:dev-*'",
21
- "dev-ui": "next dev",
22
- "dev-frame": "webpack serve --config ./config/webpack.config.dev.js",
23
  "prepare": "husky install",
24
  "spj": "npx sort-package-json",
25
  "toc": "npx markdown-toc README.md -i"
26
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  "dependencies": {
28
  "@emotion/cache": "11.10.7",
29
  "@emotion/react": "11.10.6",
@@ -32,6 +45,7 @@
32
  "@mui/icons-material": "5.11.16",
33
  "@mui/material": "5.12.0",
34
  "axios": "1.3.5",
 
35
  "eslint": "8.37.0",
36
  "eslint-config-next": "13.2.4",
37
  "jotai": "2.0.4",
@@ -46,14 +60,8 @@
46
  "devDependencies": {
47
  "@semantic-release/git": "^10.0.1",
48
  "@types/react-syntax-highlighter": "^15.5.6",
49
- "concurrently": "^8.0.1",
50
- "css-loader": "^6.7.3",
51
- "html-webpack-plugin": "^5.5.0",
52
  "husky": "^8.0.3",
53
- "style-loader": "^3.3.2",
54
- "webpack": "^5.77.0",
55
- "webpack-cli": "^5.0.1",
56
- "webpack-dev-server": "^4.13.2"
57
  },
58
  "engines": {
59
  "node": ">= 18"
 
17
  "url": "https://github.com/pixelass/"
18
  },
19
  "scripts": {
20
+ "dev": "next dev",
 
 
21
  "prepare": "husky install",
22
  "spj": "npx sort-package-json",
23
  "toc": "npx markdown-toc README.md -i"
24
  },
25
+ "lint-staged": {
26
+ "*.js": [
27
+ "npx prettier --write"
28
+ ],
29
+ "package.json": [
30
+ "npx sort-package-json",
31
+ "npx prettier --write"
32
+ ],
33
+ "*.md": [
34
+ "npx prettier --write"
35
+ ],
36
+ "README.md": [
37
+ "npx markdown-toc -i"
38
+ ]
39
+ },
40
  "dependencies": {
41
  "@emotion/cache": "11.10.7",
42
  "@emotion/react": "11.10.6",
 
45
  "@mui/icons-material": "5.11.16",
46
  "@mui/material": "5.12.0",
47
  "axios": "1.3.5",
48
+ "esdeka": "0.1.18",
49
  "eslint": "8.37.0",
50
  "eslint-config-next": "13.2.4",
51
  "jotai": "2.0.4",
 
60
  "devDependencies": {
61
  "@semantic-release/git": "^10.0.1",
62
  "@types/react-syntax-highlighter": "^15.5.6",
 
 
 
63
  "husky": "^8.0.3",
64
+ "prettier": "^2.8.7"
 
 
 
65
  },
66
  "engines": {
67
  "node": ">= 18"
project/public/index.html DELETED
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <title>fail3</title>
5
- <meta charset="utf-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1" />
7
-
8
- <link rel="stylesheet" href="./style.css" />
9
- </head>
10
- <body>
11
- <canvas id="canvas"></canvas>
12
- <script src="utils.js"></script>
13
- <!-- WEBPACK will inject the bundle.js here -->
14
- </body>
15
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
project/public/style.css DELETED
@@ -1,10 +0,0 @@
1
- * {
2
- box-sizing: border-box;
3
- margin: 0;
4
- padding: 0;
5
- }
6
-
7
- html,
8
- body {
9
- overflow: hidden;
10
- }
 
 
 
 
 
 
 
 
 
 
 
project/public/utils.js DELETED
@@ -1,9 +0,0 @@
1
- const canvas = document.querySelector("#canvas");
2
- function handleResize() {
3
- requestAnimationFrame(() => {
4
- canvas.width = window.innerWidth;
5
- canvas.height = window.innerHeight;
6
- });
7
- }
8
- handleResize();
9
- window.addEventListener("resize", handleResize, { passive: true });
 
 
 
 
 
 
 
 
 
 
project/src/.gitkeep DELETED
File without changes
public/js/utils.js ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const canvas = document.querySelector("#canvas");
2
+ const ctx = canvas.getContext("2d");
3
+
4
+ function handleResize() {
5
+ requestAnimationFrame(() => {
6
+ canvas.width = window.innerWidth;
7
+ canvas.height = window.innerHeight;
8
+ });
9
+ }
10
+ handleResize();
11
+ window.addEventListener("resize", handleResize, { passive: true });
12
+
13
+ const clients = {
14
+ host: "__ESDEKA::host__",
15
+ guest: "__ESDEKA::guest__",
16
+ };
17
+
18
+ // Shared communicators
19
+
20
+ function subscribe(channel, callback) {
21
+ function handleMessage(event) {
22
+ if (
23
+ event.data.client &&
24
+ Object.values(clients).includes(event.data.client) &&
25
+ event.data.channel === channel
26
+ ) {
27
+ callback(event);
28
+ }
29
+ }
30
+ window.addEventListener("message", handleMessage);
31
+
32
+ return () => {
33
+ window.removeEventListener("message", handleMessage);
34
+ };
35
+ }
36
+ const host = {};
37
+ // Guest communicators
38
+
39
+ function answer(window_, channel, targetOrigin = "*") {
40
+ window_.postMessage(
41
+ {
42
+ client: clients.guest,
43
+ channel,
44
+ action: {
45
+ type: "answer",
46
+ },
47
+ },
48
+ targetOrigin
49
+ );
50
+ }
51
+
52
+ function handleTemplate(template) {
53
+ for (let i = 1; i < 100_000_000; i++) {
54
+ window.clearInterval(i);
55
+ window.cancelAnimationFrame(i);
56
+ window.clearTimeout(i);
57
+ }
58
+
59
+ Function("Template", `${template};`)();
60
+ }
61
+
62
+ subscribe("fail4", event => {
63
+ console.log("GUEST", event);
64
+ const { action } = event.data;
65
+ switch (action.type) {
66
+ case "call":
67
+ host.current = event.source;
68
+ answer(event.source, "fail4");
69
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
70
+ handleTemplate(action.payload.template);
71
+ break;
72
+ case "broadcast":
73
+ console.log("broadcast", action.payload.template);
74
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
75
+ handleTemplate(action.payload.template);
76
+ break;
77
+ default:
78
+ break;
79
+ }
80
+ });
src/pages/api/gpt.ts CHANGED
@@ -9,9 +9,9 @@ export default async function handler(request: NextApiRequest, response: NextApi
9
  const answer = await toOpenAI(request.body);
10
  return response.status(200).json(answer);
11
  } catch (error) {
12
- return response.status((error as AxiosError).status ?? 500).end();
13
  }
14
  default:
15
- return response.status(405).end();
16
  }
17
  }
 
9
  const answer = await toOpenAI(request.body);
10
  return response.status(200).json(answer);
11
  } catch (error) {
12
+ return response.status((error as AxiosError).status ?? 500).json({});
13
  }
14
  default:
15
+ return response.status(405).json({});
16
  }
17
  }
src/pages/api/run.ts CHANGED
@@ -9,10 +9,10 @@ export default async function handler(request: NextApiRequest, response: NextApi
9
  case "POST":
10
  if (request.body.content) {
11
  await fs.writeFile(outputFile, request.body.content);
12
- return response.status(200).end();
13
  }
14
- return response.status(500).end();
15
  default:
16
- return response.status(405).end();
17
  }
18
  }
 
9
  case "POST":
10
  if (request.body.content) {
11
  await fs.writeFile(outputFile, request.body.content);
12
+ return response.status(200).json({});
13
  }
14
+ return response.status(500).json({});
15
  default:
16
+ return response.status(405).json({});
17
  }
18
  }
src/pages/index.tsx CHANGED
@@ -30,9 +30,13 @@ import Toolbar from "@mui/material/Toolbar";
30
  import ListItemIcon from "@mui/material/ListItemIcon";
31
  import ListItemButton from "@mui/material/ListItemButton";
32
  import ListItemText from "@mui/material/ListItemText";
 
33
 
34
  const base = {
35
- default: "/** 1.Base Script */const canvas=document.querySelector('canvas');",
 
 
 
36
  };
37
 
38
  const fontMono = Fira_Code({
@@ -53,14 +57,71 @@ export default function Home() {
53
  ]);
54
  const [loading, setLoading] = useState(false);
55
 
 
 
 
 
 
 
56
  useEffect(() => {
57
- const current = answers.find(({ id }) => id === runningId);
58
- if (current) {
59
- void axios.post("/api/run", {
60
- content: current.content,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  });
 
 
 
62
  }
63
- }, [runningId, answers]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  const current = answers.find(({ id }) => id === activeId);
66
 
@@ -114,14 +175,14 @@ export default function Home() {
114
  color="inherit"
115
  aria-label="Clear Prompt"
116
  onClick={async () => {
117
- await axios.post("/api/run", {
118
- content:
119
- "/** 1.Base Script */const canvas=document.querySelector('canvas');",
120
- });
 
 
121
  setActiveId("1");
122
- setTemplate(
123
- "/** 1.Base Script */const canvas=document.querySelector('canvas');"
124
- );
125
  }}
126
  >
127
  <ClearIcon />
@@ -266,7 +327,7 @@ export default function Home() {
266
  ref={ref}
267
  component="iframe"
268
  sx={{ width: "100%", flex: 1, m: 0, border: 0 }}
269
- src="//localhost:8080"
270
  />
271
  </Stack>
272
  </Stack>
 
30
  import ListItemIcon from "@mui/material/ListItemIcon";
31
  import ListItemButton from "@mui/material/ListItemButton";
32
  import ListItemText from "@mui/material/ListItemText";
33
+ import { useHost } from "esdeka/react";
34
 
35
  const base = {
36
+ default: `/** 1.Base Script */
37
+ const canvas=document.querySelector('canvas');
38
+ const ctx=canvas.getContext('2d');
39
+ `,
40
  };
41
 
42
  const fontMono = Fira_Code({
 
57
  ]);
58
  const [loading, setLoading] = useState(false);
59
 
60
+ const { broadcast, call, subscribe } = useHost(ref, "fail4");
61
+
62
+ const connection = useRef(false);
63
+ const [tries, setTries] = useState(5);
64
+
65
+ // Send a connection request
66
  useEffect(() => {
67
+ if (connection.current || tries <= 0) {
68
+ return () => {
69
+ /* Consistency */
70
+ };
71
+ }
72
+
73
+ const timeout = setTimeout(() => {
74
+ call({ template: "console.log('it works')" });
75
+ setTries(tries - 1);
76
+ }, 200);
77
+
78
+ call({ template: "console.log('it works')" });
79
+
80
+ return () => {
81
+ clearTimeout(timeout);
82
+ };
83
+ }, [call, tries]);
84
+
85
+ useEffect(() => {
86
+ if (!connection.current) {
87
+ const unsubscribe = subscribe(event => {
88
+ const { action } = event.data;
89
+ switch (action.type) {
90
+ case "answer":
91
+ connection.current = true;
92
+ break;
93
+ default:
94
+ break;
95
+ }
96
  });
97
+ return () => {
98
+ unsubscribe();
99
+ };
100
  }
101
+ return () => {
102
+ /* Consistency */
103
+ };
104
+ }, [subscribe]);
105
+
106
+ // Broadcast store to guest
107
+ useEffect(() => {
108
+ const current = answers.find(({ id }) => id === runningId);
109
+ if (connection.current && current) {
110
+ broadcast({ template: current.content });
111
+ }
112
+ return () => {
113
+ /* Consistency */
114
+ };
115
+ }, [broadcast, runningId, answers]);
116
+
117
+ // useEffect(() => {
118
+ // const current = answers.find(({ id }) => id === runningId);
119
+ // if (current) {
120
+ // void axios.post("/api/run", {
121
+ // content: current.content,
122
+ // });
123
+ // }
124
+ // }, [runningId, answers]);
125
 
126
  const current = answers.find(({ id }) => id === activeId);
127
 
 
175
  color="inherit"
176
  aria-label="Clear Prompt"
177
  onClick={async () => {
178
+ broadcast({ template: base.default });
179
+
180
+ //await axios.post("/api/run", {
181
+ // content:
182
+ // base.default,
183
+ //});
184
  setActiveId("1");
185
+ setTemplate(base.default);
 
 
186
  }}
187
  >
188
  <ClearIcon />
 
327
  ref={ref}
328
  component="iframe"
329
  sx={{ width: "100%", flex: 1, m: 0, border: 0 }}
330
+ src="/live"
331
  />
332
  </Stack>
333
  </Stack>
src/pages/live.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import Script from "next/script";
2
+
3
+ export default function Page() {
4
+ return (
5
+ <>
6
+ <canvas id="canvas" />
7
+ <Script src="/js/utils.js" />
8
+ </>
9
+ );
10
+ }