Skip to content

Commit 7ef32cf

Browse files
committed
docs(demo): Github app uses SSR
1 parent 36653e7 commit 7ef32cf

File tree

21 files changed

+20778
-12513
lines changed

21 files changed

+20778
-12513
lines changed

examples/github-app/package-lock.json

Lines changed: 20479 additions & 12301 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/github-app/package.json

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
"lint": "yarn g:lint src --ext .ts,.tsx",
77
"format": "run lint --fix",
88
"test:type": "run tsc",
9-
"start": "webpack serve --mode=development",
10-
"start:prod": "yarn dlx serve dist",
11-
"build:browser": "webpack --mode=production",
9+
"start": "anansi serve --dev ./src/index.tsx",
10+
"start:prod": "NODE_ENV=production WEBPACK_PUBLIC_PATH='/assets/' anansi serve ./dist-server/App.js",
11+
"build": "npm run build:client && npm run build:server",
12+
"build:client": "WEBPACK_PUBLIC_PATH='/assets/' webpack --mode=production",
13+
"build:server": "WEBPACK_PUBLIC_PATH='/assets/' webpack --mode=production --target=node --env entrypath=index.server.tsx",
1214
"build:analyze": "webpack --mode=production --env analyze",
1315
"build:profile": "webpack --mode=production --env profile",
1416
"test:pkg": "webpack --env check=nobuild"
@@ -28,6 +30,7 @@
2830
"private": true,
2931
"license": "Apache-2.0",
3032
"devDependencies": {
33+
"@anansi/cli": "3.1.88",
3134
"@anansi/babel-preset": "6.2.19",
3235
"@anansi/browserslist-config": "1.7.3",
3336
"@anansi/webpack-config": "21.1.3",
@@ -48,14 +51,16 @@
4851
"webpack-dev-server": "5.2.2"
4952
},
5053
"dependencies": {
54+
"@anansi/core": "0.21.0",
5155
"@anansi/router": "0.10.19",
52-
"@ant-design/icons": "^6.0.0",
56+
"@ant-design/cssinjs": "2.0.1",
57+
"@ant-design/icons": "6.1.0",
5358
"@babel/runtime-corejs3": "^7.26.7",
5459
"@data-client/graphql": "0.15.1-beta-20251110013913-ef632c49a03da67187b6097fe8154893cd930d30",
5560
"@data-client/img": "0.15.0-beta-20251022142546-a457d1596871fb28f1a91f2531cc259db4d55a9c",
5661
"@data-client/react": "0.15.0-beta-20251022142546-a457d1596871fb28f1a91f2531cc259db4d55a9c",
5762
"@data-client/rest": "0.15.1-beta-20251116224907-3174fe59b114d2037762a6458f5576d23e483ba4",
58-
"@js-temporal/polyfill": "^0.5.0",
63+
"@js-temporal/polyfill": "^0.5.1",
5964
"antd": "6.0.0",
6065
"core-js": "^3.40.0",
6166
"history": "^5.3.0",
@@ -64,8 +69,8 @@
6469
"react-dom": "19.2.0",
6570
"react-markdown": "10.1.0",
6671
"rehype-highlight": "7.0.2",
67-
"remark-gfm": "^4.0.0",
68-
"remark-remove-comments": "^1.0.1",
72+
"remark-gfm": "4.0.1",
73+
"remark-remove-comments": "1.1.1",
6974
"uuid": "^13.0.0"
7075
}
7176
}

examples/github-app/src/RootProvider.tsx

Lines changed: 0 additions & 60 deletions
This file was deleted.
File renamed without changes.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
Controller,
3+
LogoutManager,
4+
getDefaultManagers,
5+
type Manager,
6+
} from '@data-client/react';
7+
import { ErrorBoundary } from '@data-client/react';
8+
import type { ReactNode } from 'react';
9+
10+
import Boundary from '@/Boundary';
11+
import { AuthdProvider } from '@/navigation/authdContext';
12+
import { unAuth } from '@/resources/Auth';
13+
14+
export const getManagers: () => Manager[] = () => {
15+
return [
16+
new LogoutManager({
17+
handleLogout(controller: Controller) {
18+
unAuth();
19+
controller.resetEntireStore();
20+
},
21+
}),
22+
...getDefaultManagers(),
23+
];
24+
};
25+
26+
export default function RootProvider({ children }: { children: ReactNode }) {
27+
return (
28+
<ErrorBoundary fallbackComponent={ErrorFallback}>
29+
<AuthdProvider>
30+
<ErrorBoundary fallbackComponent={ErrorFallback}>
31+
<Boundary>{children}</Boundary>
32+
</ErrorBoundary>
33+
</AuthdProvider>
34+
</ErrorBoundary>
35+
);
36+
}
37+
38+
function ErrorFallback({
39+
error,
40+
resetErrorBoundary,
41+
}: {
42+
error: Error;
43+
resetErrorBoundary: () => void;
44+
className?: string;
45+
}) {
46+
return (
47+
<div role="alert">
48+
<p>Something went wrong:</p>
49+
<pre>{error?.message}</pre>
50+
<button onClick={resetErrorBoundary}>Try again</button>
51+
</div>
52+
);
53+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import App from './App';
2+
import RootProvider, { getManagers } from './RootProvider';
3+
4+
export const app = (
5+
<RootProvider>
6+
<App />
7+
</RootProvider>
8+
);
9+
10+
export default app;
11+
export { RootProvider, App, getManagers };

examples/github-app/src/components/human.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { Temporal } from '@js-temporal/polyfill';
22

3-
const REL = new Intl.RelativeTimeFormat(navigator.language || 'en-US', {
4-
localeMatcher: 'best fit',
5-
numeric: 'auto',
6-
style: 'long',
7-
});
8-
9-
export function humanTime(date: Temporal.Instant) {
3+
export function humanTime(date: Temporal.Instant, language: string) {
4+
const REL = new Intl.RelativeTimeFormat(language, {
5+
localeMatcher: 'best fit',
6+
numeric: 'auto',
7+
style: 'long',
8+
});
109
const duration = date.until(Temporal.Now.instant(), {
1110
largestUnit: 'second',
1211
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {
2+
laySpouts,
3+
documentSpout,
4+
dataClientSpout,
5+
prefetchSpout,
6+
routerSpout,
7+
JSONSpout,
8+
appSpout,
9+
antdSpout,
10+
navigatorSpout,
11+
} from '@anansi/core/server';
12+
import { useController } from '@data-client/react';
13+
14+
import app from '@/app';
15+
import { getManagers } from '@/app/RootProvider';
16+
17+
import { createRouter } from './routing';
18+
19+
const csPolicy = {
20+
'base-uri': "'self'",
21+
'object-src': "'none'",
22+
'script-src': ["'self'", "'unsafe-inline'"],
23+
'style-src': ["'unsafe-inline'", "'self'"],
24+
};
25+
26+
const spouts = prefetchSpout('controller')(
27+
documentSpout({ title: 'Github App', lang: 'en', csPolicy })(
28+
antdSpout()(
29+
JSONSpout()(
30+
navigatorSpout()(
31+
dataClientSpout({ getManagers })(
32+
routerSpout({ useResolveWith: useController, createRouter })(
33+
appSpout(app),
34+
),
35+
),
36+
),
37+
),
38+
),
39+
),
40+
);
41+
42+
export default laySpouts(spouts);

examples/github-app/src/index.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1-
import ReactDOM from 'react-dom/client';
1+
import {
2+
floodSpouts,
3+
documentSpout,
4+
dataClientSpout,
5+
routerSpout,
6+
JSONSpout,
7+
appSpout,
8+
antdSpout,
9+
navigatorSpout,
10+
} from '@anansi/core';
11+
import { useController } from '@data-client/react';
212

3-
import App from './App';
4-
import RootProvider from './RootProvider';
13+
import app from '@/app';
14+
import { getManagers } from '@/app/RootProvider';
515

6-
const content = (
7-
<RootProvider>
8-
<App />
9-
</RootProvider>
10-
);
16+
import { createRouter } from './routing';
1117

12-
ReactDOM.createRoot(document.getElementById('react') || document.body).render(
13-
content,
18+
const spouts = documentSpout({ title: 'Github App' })(
19+
antdSpout()(
20+
JSONSpout()(
21+
navigatorSpout()(
22+
dataClientSpout({ getManagers })(
23+
routerSpout({ useResolveWith: useController, createRouter })(
24+
appSpout(app),
25+
),
26+
),
27+
),
28+
),
29+
),
1430
);
31+
32+
export default floodSpouts(spouts);

examples/github-app/src/pages/IssueDetail/CommentInline.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useNavigator } from '@anansi/core';
12
import { Link, useRoutes } from '@anansi/router';
23
import { EllipsisOutlined } from '@ant-design/icons';
34
import { useCache, useController } from '@data-client/react';
@@ -19,6 +20,7 @@ import CommentForm from './CommentForm';
1920
const { Meta } = Card;
2021

2122
function CommentInline({ comment }: { comment: Comment }) {
23+
const { language } = useNavigator();
2224
const [editing, setEditing] = useState(false);
2325
return (
2426
<Card style={{ marginTop: 16 }} className={commentList}>
@@ -35,9 +37,7 @@ function CommentInline({ comment }: { comment: Comment }) {
3537
{comment.user.login}
3638
</Link>{' '}
3739
commented on{' '}
38-
{new Intl.DateTimeFormat(navigator.language).format(
39-
comment.createdAt,
40-
)}
40+
{new Intl.DateTimeFormat(language).format(comment.createdAt)}
4141
</span>
4242
<CommentControls comment={comment} setEditing={setEditing} />
4343
</FlexRow>

0 commit comments

Comments
 (0)