~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


baa15a96 Peter John

2 years ago
fix css flash
Files changed (3) hide show
  1. packages/parotta/cli.js +17 -24
  2. packages/parotta/router.js +25 -23
  3. readme.md +4 -5
packages/parotta/cli.js CHANGED
@@ -132,6 +132,22 @@ const renderPage = async (url) => {
132
132
  }, {})
133
133
  const components = mapDeps("components");
134
134
  const containers = mapDeps("containers");
135
+ const importMap = {
136
+ "radix3": `https://esm.sh/radix3`,
137
+ "history": "https://esm.sh/history@5.3.0",
138
+ "react": `https://esm.sh/react@18.2.0${devTag}`,
139
+ // TODO: need to remove this in prod
140
+ "react/jsx-dev-runtime": `https://esm.sh/react@18.2.0${devTag}/jsx-dev-runtime`,
141
+ "react-dom/client": `https://esm.sh/react-dom@18.2.0${devTag}/client`,
142
+ "nprogress": "https://esm.sh/nprogress@0.2.0",
143
+ // "parotta/router": `https://esm.sh/parotta@${version}/router.js`,
144
+ // "parotta/error": `https://esm.sh/parotta@${version}/error.js`,
145
+ "parotta/router": `/parotta/router.js`,
146
+ "parotta/error": `/parotta/error.js`,
147
+ ...nodeDeps,
148
+ ...components,
149
+ ...containers,
150
+ };
135
151
  const history = createMemoryHistory({
136
152
  initialEntries: [url.pathname + url.search],
137
153
  });
@@ -141,6 +157,7 @@ const renderPage = async (url) => {
141
157
  <Header
142
158
  history={history}
143
159
  radixRouter={clientRouter}
160
+ importMap={importMap}
144
161
  />
145
162
  </head>
146
163
  <body>
@@ -153,29 +170,6 @@ const renderPage = async (url) => {
153
170
  </div>
154
171
  {config.hydrate &&
155
172
  <>
156
- <script type="importmap" dangerouslySetInnerHTML={{
157
- __html: JSON.stringify(
158
- {
159
- "imports": {
160
- "radix3": `https://esm.sh/radix3`,
161
- "history": "https://esm.sh/history@5.3.0",
162
- "react": `https://esm.sh/react@18.2.0${devTag}`,
163
- // TODO: need to remove this in prod
164
- "react/jsx-dev-runtime": `https://esm.sh/react@18.2.0${devTag}/jsx-dev-runtime`,
165
- "react-dom/client": `https://esm.sh/react-dom@18.2.0${devTag}/client`,
166
- "nprogress": "https://esm.sh/nprogress@0.2.0",
167
- // "parotta/router": `https://esm.sh/parotta@${version}/router.js`,
168
- // "parotta/error": `https://esm.sh/parotta@${version}/error.js`,
169
- "parotta/router": `/parotta/router.js`,
170
- "parotta/error": `/parotta/error.js`,
171
- ...nodeDeps,
172
- ...components,
173
- ...containers,
174
- }
175
- }
176
- )
177
- }}>
178
- </script>
179
173
  <script type="module" defer={true} dangerouslySetInnerHTML={{
180
174
  __html: `
181
175
  import React from "react";
@@ -258,7 +252,6 @@ const renderJs = async (src) => {
258
252
  return new Response(js, {
259
253
  headers: {
260
254
  'Content-Type': 'application/javascript',
261
- // 'Link': `</routes/about/page.css>; rel=prefetch`,
262
255
  },
263
256
  status: 200,
264
257
  });
packages/parotta/router.js CHANGED
@@ -3,7 +3,7 @@ import nProgress from "nprogress";
3
3
 
4
4
  export const isClient = () => typeof window !== 'undefined';
5
5
  export const domain = () => isClient() ? window.origin : "http://0.0.0.0:3000";
6
- export const basePath = () => isClient() ? "" : process.cwd()
6
+ export const basePath = () => isClient() ? "" : process.cwd();
7
7
  export const globalCache = new Map();
8
8
  export const useFetchCache = () => {
9
9
  const [_, rerender] = useState(false);
@@ -69,35 +69,30 @@ const getMatch = (radixRouter, pathname) => {
69
69
 
70
70
  const getCssUrl = (pathname) => `/routes${pathname === "/" ? "/page.css" : pathname + "/page.css"}`;
71
71
 
72
- export const Header = ({ history, radixRouter }) => {
72
+ export const Header = ({ history, radixRouter, importMap }) => {
73
- // const pathname = useSyncExternalStore(history.listen, (v) => v ? v.location.pathname : history.location.pathname, () => history.location.pathname);
73
+ const pathname = useSyncExternalStore(history.listen, (v) => v ? v.location.pathname : history.location.pathname, () => history.location.pathname);
74
- // const match = getMatch(radixRouter, pathname);
74
+ const match = getMatch(radixRouter, pathname);
75
- const [match, setMatch] = useState(() => getMatch(radixRouter, history.location.pathname));
75
+ const initialCss = useMemo(() => getCssUrl(history.location.pathname), []);
76
- useEffect(() => {
77
- return history.listen(({ location }) => {
78
- // document.getElementById("pageCss").href = getCssUrl(location.pathname);
79
- setMatch(getMatch(radixRouter, location.pathname));
80
- });
81
- }, []);
82
- return React.createElement(React.Suspense, {
76
+ return React.createElement(React.Fragment, {
83
77
  children: [
84
78
  React.createElement("link", {
85
79
  rel: "stylesheet",
86
80
  href: "https://unpkg.com/nprogress@0.2.0/nprogress.css",
87
81
  }),
88
82
  React.createElement("link", {
89
- id: "pageCss",
90
83
  rel: "stylesheet",
91
- href: "/routes/page.css",
92
- // getCssUrl(history.location.pathname)
93
- }),
94
- React.createElement("link", {
95
- rel: "stylesheet",
84
+ href: initialCss,
96
- href: "/routes/about/page.css",
97
85
  }),
98
86
  React.createElement(React.Suspense, {
99
87
  children: React.createElement(match.Head, {}),
100
88
  }),
89
+ React.createElement("script", {
90
+ id: "importmap",
91
+ type: "importmap",
92
+ dangerouslySetInnerHTML: {
93
+ __html: JSON.stringify({ "imports": importMap }),
94
+ }
95
+ })
101
96
  ]
102
97
  });
103
98
  }
@@ -117,10 +112,17 @@ export const Router = ({ App, history, radixRouter }) => {
117
112
  const [match, setMatch] = useState(() => getMatch(radixRouter, history.location.pathname));
118
113
  useEffect(() => {
119
114
  return history.listen(({ location }) => {
115
+ var link = document.createElement('link');
116
+ link.setAttribute("rel", "stylesheet");
117
+ link.setAttribute("type", "text/css");
118
+ link.onload = () => {
120
- nProgress.start();
119
+ nProgress.start();
121
- startTransition(() => {
120
+ startTransition(() => {
122
- setMatch(getMatch(radixRouter, location.pathname));
121
+ setMatch(getMatch(radixRouter, location.pathname));
123
- })
122
+ })
123
+ };
124
+ link.setAttribute("href", getCssUrl(location.pathname));
125
+ document.getElementsByTagName("head")[0].appendChild(link);
124
126
  });
125
127
  }, [])
126
128
  console.log('Router');
readme.md CHANGED
@@ -5,8 +5,7 @@ It uses File system routing with SSR with streaming + CSR as the method to rende
5
5
  It is very opionated and has set of idiomatic ways of doing things.
6
6
 
7
7
  ### Todo
8
- 1. Hydrate fetch cache
8
+ 1. Prefetching assets
9
- 2. Improve css loading
10
- 3. Improve react page loading (try to remove flash)
11
- 4. Add build step
9
+ 2. Add build step
12
- 5. Deploy to Docker, Deno deploy, Cloudflare workers, Vercel edge functions, Bun edge (whenever it releases)
10
+ 3. Deploy to Docker, Deno deploy, Cloudflare workers, Vercel edge functions, Bun edge (whenever it releases)
11
+ 4. Hydrate fetch cache