~repos /edge-city
git clone https://pyrossh.dev/repos/edge-city.git
edge-city is a next level meta-framework for react that runs only on edge runtimes
2292a7c2
—
pyrossh 2 years ago
remove layout in pages
- example/src/pages/_404/page.jsx +8 -11
- example/src/pages/_500/page.jsx +8 -11
- example/src/pages/about/page.jsx +15 -18
- example/src/pages/app.jsx +4 -1
- example/src/pages/page.jsx +2 -6
- example/src/pages/todos/page.jsx +26 -42
- readme.md +4 -5
example/src/pages/_404/page.jsx
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Helmet } from 'react-helmet-async';
|
|
3
|
-
import Layout from '@/components/Layout/Layout';
|
|
4
3
|
import "./page.css";
|
|
5
4
|
|
|
6
5
|
const Page = () => {
|
|
7
6
|
return (
|
|
8
|
-
<Layout>
|
|
9
|
-
|
|
7
|
+
<div className="notfound-page">
|
|
10
|
-
|
|
8
|
+
<Helmet>
|
|
11
|
-
|
|
9
|
+
<title>Page not found</title>
|
|
12
|
-
|
|
10
|
+
</Helmet>
|
|
13
|
-
|
|
11
|
+
<h1>404 - Page not found</h1>
|
|
14
|
-
|
|
12
|
+
<div className="content">
|
|
15
|
-
|
|
13
|
+
<h2>This page could not be found</h2>
|
|
16
|
-
</div>
|
|
17
14
|
</div>
|
|
18
|
-
</
|
|
15
|
+
</div>
|
|
19
16
|
)
|
|
20
17
|
}
|
|
21
18
|
|
example/src/pages/_500/page.jsx
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Helmet } from 'react-helmet-async';
|
|
3
|
-
import Layout from '@/components/Layout/Layout';
|
|
4
3
|
import "./page.css";
|
|
5
4
|
|
|
6
5
|
const Page = () => {
|
|
7
6
|
return (
|
|
8
|
-
<Layout>
|
|
9
|
-
|
|
7
|
+
<div className="err-page">
|
|
10
|
-
|
|
8
|
+
<Helmet>
|
|
11
|
-
|
|
9
|
+
<title>Oop's Something went wrong</title>
|
|
12
|
-
|
|
10
|
+
</Helmet>
|
|
13
|
-
|
|
11
|
+
<h1>Oop's Something went wrong</h1>
|
|
14
|
-
|
|
12
|
+
<div className="content">
|
|
15
|
-
|
|
13
|
+
<h2>Internal Server Error</h2>
|
|
16
|
-
</div>
|
|
17
14
|
</div>
|
|
18
|
-
</
|
|
15
|
+
</div>
|
|
19
16
|
)
|
|
20
17
|
}
|
|
21
18
|
|
example/src/pages/about/page.jsx
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Link, useRouter } from "edge-city";
|
|
3
3
|
import { Helmet } from 'react-helmet-async';
|
|
4
|
-
import Layout from '@/components/Layout/Layout';
|
|
5
4
|
import "./page.css";
|
|
6
5
|
|
|
7
6
|
export const Page = () => {
|
|
8
7
|
const router = useRouter();
|
|
9
8
|
return (
|
|
10
|
-
<Layout>
|
|
11
|
-
|
|
9
|
+
<div className="about-page">
|
|
12
|
-
|
|
10
|
+
<Helmet>
|
|
13
|
-
|
|
11
|
+
<title>About | Edge City</title>
|
|
14
|
-
|
|
12
|
+
<meta name="description" content="Showcase of using edge-city meta-framework." />
|
|
15
|
-
|
|
13
|
+
</Helmet>
|
|
16
|
-
|
|
14
|
+
<div>
|
|
17
|
-
|
|
15
|
+
<h1>About Page</h1>
|
|
18
|
-
|
|
16
|
+
<p>
|
|
19
|
-
|
|
17
|
+
Path: {router.pathname}
|
|
20
|
-
|
|
18
|
+
</p>
|
|
21
|
-
|
|
19
|
+
<p>Showcase of using edge-city meta-framework.</p>
|
|
22
|
-
</div>
|
|
23
|
-
<footer>
|
|
24
|
-
<Link href="/">Back</Link>
|
|
25
|
-
</footer>
|
|
26
20
|
</div>
|
|
21
|
+
<footer>
|
|
22
|
+
<Link href="/">Back</Link>
|
|
27
|
-
|
|
23
|
+
</footer>
|
|
24
|
+
</div>
|
|
28
25
|
)
|
|
29
26
|
}
|
|
30
27
|
|
example/src/pages/app.jsx
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { SSRProvider } from 'react-aria';
|
|
2
|
+
import Layout from '@/components/Layout/Layout';
|
|
2
3
|
|
|
3
4
|
const App = ({ children }) => {
|
|
4
5
|
return (
|
|
5
6
|
<SSRProvider>
|
|
7
|
+
<Layout>
|
|
6
|
-
|
|
8
|
+
{children}
|
|
9
|
+
</Layout>
|
|
7
10
|
</SSRProvider>
|
|
8
11
|
)
|
|
9
12
|
}
|
example/src/pages/page.jsx
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
2
|
import { useRouter } from "edge-city";
|
|
3
|
-
import Layout from '@/components/Layout/Layout';
|
|
4
3
|
import Counter from "@/components/Counter/Counter";
|
|
5
4
|
import { Helmet } from 'react-helmet-async';
|
|
6
5
|
import "./page.css";
|
|
7
6
|
|
|
8
7
|
const Page = () => {
|
|
9
8
|
const router = useRouter();
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
|
|
12
|
-
}, []);
|
|
13
9
|
return (
|
|
14
|
-
<
|
|
10
|
+
<div>
|
|
15
11
|
<Helmet>
|
|
16
12
|
<title>Edge City</title>
|
|
17
13
|
</Helmet>
|
|
@@ -22,7 +18,7 @@ const Page = () => {
|
|
|
22
18
|
</p>
|
|
23
19
|
<Counter />
|
|
24
20
|
</div>
|
|
25
|
-
</
|
|
21
|
+
</div>
|
|
26
22
|
)
|
|
27
23
|
}
|
|
28
24
|
|
example/src/pages/todos/page.jsx
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { Helmet } from 'react-helmet-async';
|
|
3
3
|
import { useQuery, useMutation } from "edge-city";
|
|
4
4
|
import { useForm } from 'react-hook-form';
|
|
5
|
-
import Layout from '@/components/Layout/Layout';
|
|
6
5
|
import Todo from "@/components/Todo/Todo";
|
|
7
6
|
import { TextField, Label, Input } from 'react-aria-components';
|
|
8
7
|
import { Button } from 'react-aria-components';
|
|
@@ -10,24 +9,6 @@ import { getTodos, createTodo } from "@/services/todos.service";
|
|
|
10
9
|
import "./page.css";
|
|
11
10
|
|
|
12
11
|
const Page = () => {
|
|
13
|
-
return (
|
|
14
|
-
<Layout>
|
|
15
|
-
<h1>Todos</h1>
|
|
16
|
-
<Helmet>
|
|
17
|
-
<title>Todos Page</title>
|
|
18
|
-
</Helmet>
|
|
19
|
-
<div>
|
|
20
|
-
<Suspense fallback="Loading...">
|
|
21
|
-
<TodoList />
|
|
22
|
-
</Suspense>
|
|
23
|
-
</div>
|
|
24
|
-
</Layout>
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default Page;
|
|
29
|
-
|
|
30
|
-
const TodoList = () => {
|
|
31
12
|
const { data, refetch } = useQuery("todos", () => getTodos());
|
|
32
13
|
const { mutate, isMutating, err } = useMutation(async ({ text }) => {
|
|
33
14
|
await createTodo({
|
|
@@ -37,29 +18,32 @@ const TodoList = () => {
|
|
|
37
18
|
await refetch();
|
|
38
19
|
});
|
|
39
20
|
const { register, handleSubmit, formState: { errors } } = useForm();
|
|
40
|
-
// useEffect(() => {
|
|
41
|
-
// setTimeout(() => {
|
|
42
|
-
// refetch();
|
|
43
|
-
// }, 3000)
|
|
44
|
-
// }, [])
|
|
45
21
|
return (
|
|
46
22
|
<div>
|
|
23
|
+
<h1>Todos</h1>
|
|
24
|
+
<Helmet>
|
|
25
|
+
<title>Todos</title>
|
|
26
|
+
</Helmet>
|
|
27
|
+
<div>
|
|
47
|
-
|
|
28
|
+
<ul>
|
|
48
|
-
|
|
29
|
+
{data.map((item) => (
|
|
49
|
-
|
|
30
|
+
<Todo key={item.id} todo={item} />
|
|
50
|
-
|
|
31
|
+
))}
|
|
51
|
-
|
|
32
|
+
</ul>
|
|
52
|
-
|
|
33
|
+
<form onSubmit={handleSubmit(mutate)}>
|
|
53
|
-
|
|
34
|
+
<TextField isRequired isReadOnly={isMutating}>
|
|
54
|
-
|
|
35
|
+
<Label>Text (required)</Label>
|
|
55
|
-
|
|
36
|
+
<Input {...register('text')} />
|
|
56
|
-
|
|
37
|
+
{err?.text && <p>{err.text._errors[0]}</p>}
|
|
57
|
-
|
|
38
|
+
</TextField>
|
|
58
|
-
|
|
39
|
+
<Button type="submit" isDisabled={isMutating}>Add Todo</Button>
|
|
59
|
-
|
|
40
|
+
{isMutating && <div>
|
|
60
|
-
|
|
41
|
+
<p>Creating...</p>
|
|
61
|
-
|
|
42
|
+
</div>}
|
|
62
|
-
|
|
43
|
+
</form>
|
|
44
|
+
</div>
|
|
63
45
|
</div>
|
|
64
46
|
)
|
|
65
|
-
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default Page;
|
readme.md
CHANGED
|
@@ -12,7 +12,7 @@ During development each request for a page is executed in a separate edge-runtim
|
|
|
12
12
|
During production each page is packaged to an esm function adapted to the platform of your choice.
|
|
13
13
|
|
|
14
14
|
## Why?
|
|
15
|
-
* Its really hard to have a streaming SSR + CSR with automatic data rehydration setup in nextjs
|
|
15
|
+
* Its really hard to have a streaming SSR + CSR with automatic data rehydration setup in nextjs 13.
|
|
16
16
|
* There is no meta-framework which runs your code in an edge simulated environment during development.
|
|
17
17
|
|
|
18
18
|
## Requirements
|
|
@@ -21,8 +21,8 @@ During production each page is packaged to an esm function adapted to the platfo
|
|
|
21
21
|
3. `vercel` for deploying to vercel edge runtime
|
|
22
22
|
|
|
23
23
|
## DB access
|
|
24
|
-
Since it runs only on edge runtimes which
|
|
24
|
+
Since it runs only on edge runtimes which run in a constrained browser environment, you have to use database drivers
|
|
25
|
-
which
|
|
25
|
+
which can run in the browser, basically utilize Ajax/Fetch/Websocket. Here is a list of some of them,
|
|
26
26
|
|
|
27
27
|
* [NeonDB serverless driver](https://github.com/neondatabase/serverless) - postgres
|
|
28
28
|
* [Platnetscale serverless driver](https://planetscale.com/docs/tutorials/planetscale-serverless-driver) - mysql
|
|
@@ -47,5 +47,4 @@ which are compatible with these API's. Here is a list of some of them,
|
|
|
47
47
|
5. Maybe move to vite for HMR goodness
|
|
48
48
|
|
|
49
49
|
### Todo[Cloudflare]
|
|
50
|
-
1. Fix 404
|
|
50
|
+
1. Fix 404 pages not routing on server
|
|
51
|
-
2. Fix neondb serverless driver
|