~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
aab74def
—
Peter John 2 years ago
Improve runtime
- pages/todos/page.jsx +10 -10
- parotta/runtime.js +26 -6
pages/todos/page.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Suspense, useState } from 'react';
|
|
2
2
|
import { Helmet } from 'react-helmet-async';
|
|
3
|
-
import {
|
|
3
|
+
import { useQuery, useMutation } from "parotta/runtime";
|
|
4
4
|
import Todo from "@/components/Todo/Todo";
|
|
5
5
|
import { TextField, Label, Input } from 'react-aria-components';
|
|
6
6
|
import { Button } from 'react-aria-components';
|
|
@@ -9,32 +9,32 @@ import Layout from '@/components/Layout/Layout';
|
|
|
9
9
|
import "./page.css";
|
|
10
10
|
|
|
11
11
|
const TodoList = () => {
|
|
12
|
-
const { data,
|
|
12
|
+
const { data, refetch } = useQuery(getTodos, {});
|
|
13
|
-
const [text, setText] = useState();
|
|
14
|
-
const
|
|
13
|
+
const { mutate, isMutating } = useMutation(async () => {
|
|
15
14
|
await createTodo({
|
|
16
15
|
text,
|
|
17
16
|
completed: false,
|
|
18
17
|
createdAt: new Date(),
|
|
19
18
|
})
|
|
20
19
|
await refetch();
|
|
21
|
-
}
|
|
20
|
+
});
|
|
21
|
+
const [text, setText] = useState();
|
|
22
22
|
return (
|
|
23
23
|
<div>
|
|
24
24
|
<ul>
|
|
25
25
|
{data.map((item) => (
|
|
26
26
|
<Todo key={item.id} todo={item} />
|
|
27
27
|
))}
|
|
28
|
-
{isRefetching && <div>
|
|
29
|
-
<p>Refetching...</p>
|
|
30
|
-
</div>}
|
|
31
28
|
</ul>
|
|
32
29
|
<div>
|
|
33
|
-
<TextField isRequired>
|
|
30
|
+
<TextField isRequired isReadOnly={isMutating}>
|
|
34
31
|
<Label>Text (required)</Label>
|
|
35
32
|
<Input value={text} onChange={(e) => setText(e.target.value)} />
|
|
36
33
|
</TextField>
|
|
37
|
-
<Button onPress={
|
|
34
|
+
<Button onPress={mutate} isDisabled={isMutating}>Add Todo</Button>
|
|
35
|
+
{isMutating && <div>
|
|
36
|
+
<p>Creating...</p>
|
|
37
|
+
</div>}
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
)
|
parotta/runtime.js
CHANGED
|
@@ -7,7 +7,6 @@ import { ErrorBoundary } from "react-error-boundary";
|
|
|
7
7
|
export const domain = () => typeof window !== 'undefined' ? window.origin : "http://0.0.0.0:3000";
|
|
8
8
|
|
|
9
9
|
export const rpc = (serviceName) => async (params = {}) => {
|
|
10
|
-
console.log('serviceName', serviceName);
|
|
11
10
|
const res = await fetch(`${domain()}/services/${serviceName}`, {
|
|
12
11
|
method: "POST",
|
|
13
12
|
headers: {
|
|
@@ -29,7 +28,7 @@ export const RpcContext = createContext(undefined);
|
|
|
29
28
|
// });
|
|
30
29
|
// }
|
|
31
30
|
|
|
32
|
-
export const
|
|
31
|
+
export const useRpcCache = (k) => {
|
|
33
32
|
const ctx = useContext(RpcContext);
|
|
34
33
|
const [_, rerender] = useState(false);
|
|
35
34
|
const get = () => ctx[k]
|
|
@@ -54,11 +53,10 @@ export const useCache = (k) => {
|
|
|
54
53
|
* @param {*} params
|
|
55
54
|
* @returns
|
|
56
55
|
*/
|
|
57
|
-
export const
|
|
56
|
+
export const useQuery = (fn, params) => {
|
|
58
57
|
const [isRefetching, setIsRefetching] = useState(false);
|
|
59
58
|
const [err, setErr] = useState(null);
|
|
60
|
-
const
|
|
59
|
+
const cache = useRpcCache(`${fn.name}:${JSON.stringify(params)}`);
|
|
61
|
-
const cache = useCache(key);
|
|
62
60
|
const refetch = useCallback(async () => {
|
|
63
61
|
try {
|
|
64
62
|
setIsRefetching(true);
|
|
@@ -70,7 +68,7 @@ export const useRpc = (fn, params) => {
|
|
|
70
68
|
} finally {
|
|
71
69
|
setIsRefetching(false);
|
|
72
70
|
}
|
|
73
|
-
}, [
|
|
71
|
+
}, [fn]);
|
|
74
72
|
const value = cache.get();
|
|
75
73
|
if (value) {
|
|
76
74
|
if (value instanceof Promise) {
|
|
@@ -84,6 +82,28 @@ export const useRpc = (fn, params) => {
|
|
|
84
82
|
throw cache.get();
|
|
85
83
|
}
|
|
86
84
|
|
|
85
|
+
export const useMutation = (fn) => {
|
|
86
|
+
const [isMutating, setIsMutating] = useState(false);
|
|
87
|
+
const [err, setErr] = useState(null);
|
|
88
|
+
const mutate = useCallback(async (params) => {
|
|
89
|
+
try {
|
|
90
|
+
setIsMutating(true);
|
|
91
|
+
setErr(null);
|
|
92
|
+
await fn(params);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
setErr(err)
|
|
95
|
+
throw err;
|
|
96
|
+
} finally {
|
|
97
|
+
setIsMutating(false);
|
|
98
|
+
}
|
|
99
|
+
}, [fn])
|
|
100
|
+
return {
|
|
101
|
+
mutate,
|
|
102
|
+
isMutating,
|
|
103
|
+
err,
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
87
107
|
export const RouterContext = createContext(undefined);
|
|
88
108
|
|
|
89
109
|
const getMatch = (radixRouter, pathname) => {
|