~repos /edge-city

#react#js#ssr

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
Files changed (2) hide show
  1. pages/todos/page.jsx +10 -10
  2. 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 { useRpc } from "parotta/runtime";
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, isRefetching, refetch } = useRpc(getTodos, {});
12
+ const { data, refetch } = useQuery(getTodos, {});
13
- const [text, setText] = useState();
14
- const onSubmit = async () => {
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={onSubmit}>Add Todo</Button>
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 useCache = (k) => {
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 useRpc = (fn, params) => {
56
+ export const useQuery = (fn, params) => {
58
57
  const [isRefetching, setIsRefetching] = useState(false);
59
58
  const [err, setErr] = useState(null);
60
- const key = `${fn.name}:${JSON.stringify(params)}`;
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
- }, [key])
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) => {