-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathApp.tsx
More file actions
112 lines (97 loc) · 3.53 KB
/
App.tsx
File metadata and controls
112 lines (97 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { Repo } from "@automerge/automerge-repo";
import { BrowserWebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb";
import { type FirebaseOptions, initializeApp } from "firebase/app";
import invariant from "tiny-invariant";
import * as uuid from "uuid";
import { MultiProvider } from "@solid-primitives/context";
import { Navigate, type RouteDefinition, type RouteSectionProps, Router } from "@solidjs/router";
import { FirebaseProvider } from "solid-firebase";
import { Show, createResource, lazy, useContext } from "solid-js";
import type { JsonValue } from "catcolab-api";
import { RepoContext, RpcContext, createRpcClient } from "./api";
import { newModelDocument } from "./model/document";
import { HelpContainer, lazyMdx } from "./page/help_page";
import { TheoryLibraryContext, stdTheories } from "./stdlib";
const serverUrl = import.meta.env.VITE_SERVER_URL;
const repoUrl = import.meta.env.VITE_AUTOMERGE_REPO_URL;
const firebaseOptions = JSON.parse(import.meta.env.VITE_FIREBASE_OPTIONS) as FirebaseOptions;
const Root = (props: RouteSectionProps<unknown>) => {
invariant(serverUrl, "Must set environment variable VITE_SERVER_URL");
invariant(repoUrl, "Must set environment variable VITE_AUTOMERGE_REPO_URL");
const firebaseApp = initializeApp(firebaseOptions);
const client = createRpcClient(serverUrl, firebaseApp);
const repo = new Repo({
storage: new IndexedDBStorageAdapter("catcolab"),
network: [new BrowserWebSocketClientAdapter(repoUrl)],
});
return (
<MultiProvider
values={[
[RpcContext, client],
[RepoContext, repo],
[TheoryLibraryContext, stdTheories],
]}
>
<FirebaseProvider app={firebaseApp}>{props.children}</FirebaseProvider>
</MultiProvider>
);
};
function CreateModel() {
const rpc = useContext(RpcContext);
invariant(rpc, "Missing context to create model");
const init = newModelDocument();
const [ref] = createResource<string>(async () => {
const result = await rpc.new_ref.mutate({
content: init as JsonValue,
permissions: {
anyone: "Read",
},
});
invariant(result.tag === "Ok", "Failed to create model");
return result.content;
});
return <Show when={ref()}>{(ref) => <Navigate href={`/model/${ref()}`} />}</Show>;
}
const refIsUUIDFilter = {
ref: (ref: string) => uuid.validate(ref),
};
const routes: RouteDefinition[] = [
{
path: "/",
component: CreateModel,
},
{
path: "/model/:ref",
matchFilters: refIsUUIDFilter,
component: lazy(() => import("./model/model_editor")),
},
{
path: "/diagram/:ref",
matchFilters: refIsUUIDFilter,
component: lazy(() => import("./diagram/diagram_editor")),
},
{
path: "/analysis/:ref",
matchFilters: refIsUUIDFilter,
component: lazy(() => import("./analysis/analysis_editor")),
},
{
path: "/help",
component: HelpContainer,
children: [
{
path: "/",
component: lazyMdx(() => import("./help/index.mdx")),
},
{
path: "/credits",
component: lazyMdx(() => import("./help/credits.mdx")),
},
],
},
];
function App() {
return <Router root={Root}>{routes}</Router>;
}
export default App;