Skip to content

Commit c3c5290

Browse files
committed
unfix: storing encoded doc in supa storage... not working
1 parent 768edf0 commit c3c5290

File tree

6 files changed

+131
-49
lines changed

6 files changed

+131
-49
lines changed

app/src/components/Graph.tsx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import klay from "cytoscape-klay";
55
import cytoscapeSvg from "cytoscape-svg";
66
import throttle from "lodash.throttle";
77
import React, {
8+
Dispatch,
89
MutableRefObject,
10+
SetStateAction,
911
useCallback,
1012
useEffect,
1113
useMemo,
@@ -30,10 +32,11 @@ import {
3032
import { isError } from "../lib/helpers";
3133
import { getAnimationSettings } from "../lib/hooks";
3234
import { Parsers, universalParse, useParser } from "../lib/parsers";
35+
import { useYDoc } from "../lib/realtime";
3336
import { Theme } from "../lib/themes/constants";
3437
import original from "../lib/themes/original";
3538
import { useContextMenuState } from "../lib/useContextMenuState";
36-
import { Doc } from "../lib/useDoc";
39+
import { Doc, useDetailsStore } from "../lib/useDoc";
3740
import { useGraphStore } from "../lib/useGraphStore";
3841
import { useHoverLine } from "../lib/useHoverLine";
3942
import { useParseError } from "../lib/useParseError";
@@ -68,6 +71,7 @@ export default function Graph({ shouldResize }: { shouldResize: number }) {
6871
const theme = useCurrentTheme(themeKey) as unknown as Theme;
6972
const bg = useBackgroundColor(theme);
7073
const userStyle = useUserStyle();
74+
const [graphReady, setGraphReady] = useState(false);
7175

7276
const getSize = useRef<TGetSize>(getGetSize(theme));
7377
const parser = useParser();
@@ -95,6 +99,7 @@ export default function Graph({ shouldResize }: { shouldResize: number }) {
9599

96100
// Initialize Graph
97101
useEffect(() => {
102+
if (graphInitialized.current) return;
98103
return initializeGraph({
99104
errorCatcher,
100105
cy,
@@ -121,7 +126,13 @@ export default function Graph({ shouldResize }: { shouldResize: number }) {
121126

122127
const throttleUpdate = useMemo(
123128
() =>
124-
getGraphUpdater({ cy, errorCatcher, graphInitialized, getSize, parser }),
129+
getGraphUpdater({
130+
cy,
131+
errorCatcher,
132+
graphInitialized,
133+
getSize,
134+
parser,
135+
}),
125136
[parser]
126137
);
127138

@@ -271,14 +282,20 @@ function getGraphUpdater({
271282
// TODO: what happens if you add animate false and run() here?
272283
errorCatcher.current.layout(layout);
273284

285+
const isHosted = useDetailsStore.getState().isHosted;
286+
const isReady = useYDoc.getState().isReady;
287+
const isReadyToAnimate = !isHosted || isReady;
288+
274289
// Update
275290
cy.current.json({ elements });
276291
if (layout.name !== "preset") {
277292
cy.current
278293
.layout({
279-
animate: graphInitialized.current
280-
? elements.length < 200
281-
? shouldAnimate
294+
animate: isReadyToAnimate
295+
? graphInitialized.current
296+
? elements.length < 200
297+
? shouldAnimate
298+
: false
282299
: false
283300
: false,
284301
animationDuration: shouldAnimate ? 333 : 0,
@@ -301,6 +318,8 @@ function getGraphUpdater({
301318

302319
// Update Graph Store
303320
useGraphStore.setState({ layout, elements });
321+
322+
//
304323
} catch (e) {
305324
errorCatcher.current.destroy();
306325
errorCatcher.current = cytoscape();

app/src/components/TextEditor.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export function TextEditor({
100100
onMount={(editor, monaco) => {
101101
registerLanguages(monaco);
102102
editorRef.current = editor;
103+
window.__monaco_editor = editor;
103104
monacoRef.current = monaco;
104105
// @ts-ignore
105106
window.monacoRef = monacoRef.current;

app/src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import reportWebVitals from "./reportWebVitals";
1515
declare global {
1616
interface Window {
1717
Buffer: typeof Buffer;
18+
__monaco_editor?: any;
1819
}
1920
}
2021
window.Buffer = Buffer;

app/src/lib/realtime.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ import { logError } from "./sentry";
1010

1111
type IStandAloneCodeEditor = Parameters<OnMount>[0];
1212

13-
const useYDoc = create<{
13+
type UseYDoc = {
1414
ydoc?: Y.Doc;
1515
provider?: WebsocketProvider;
16-
}>()(
17-
devtools(() => ({}), {
18-
name: "useYDoc",
19-
})
16+
isReady: boolean;
17+
};
18+
19+
export const useYDoc = create<UseYDoc>()(
20+
devtools<UseYDoc>(
21+
() => ({
22+
isReady: false,
23+
}),
24+
{
25+
name: "useYDoc",
26+
}
27+
)
2028
);
2129

2230
// Create a Yjs document
@@ -37,16 +45,18 @@ export function setupYDoc(type: "hosted" | "public", id: string) {
3745

3846
// Create a provider
3947
const provider = new WebsocketProvider(providerUrl, roomName, ydoc);
48+
provider.on("synced", (isSynced: boolean) => {
49+
useYDoc.setState({ isReady: isSynced });
50+
});
4051

4152
// set references in store
4253
useYDoc.setState({ ydoc, provider });
4354
}
4455

4556
export function cleanupYDoc() {
46-
console.log("Cleanup ydoc");
4757
const provider = useYDoc.getState().provider;
4858
if (provider) provider.disconnect();
49-
useYDoc.setState({ ydoc: undefined, provider: undefined });
59+
useYDoc.setState({ ydoc: undefined, provider: undefined, isReady: false });
5060
}
5161

5262
/**

app/src/pages/EditHosted.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import EditorError from "../components/EditorError";
1010
import { EditorOptions } from "../components/EditorOptions";
1111
import { EditorWrapper } from "../components/EditorWrapper";
1212
import { EditWrapper } from "../components/EditWrapper";
13+
import Loading from "../components/Loading";
1314
import Main from "../components/Main";
1415
import { EditLayoutTab } from "../components/Tabs/EditLayoutTab";
1516
import { EditMetaTab } from "../components/Tabs/EditMetaTab";
@@ -18,7 +19,7 @@ import { TextEditor } from "../components/TextEditor";
1819
import { setDocText } from "../lib/docHelpers";
1920
import { useIsValidSponsor } from "../lib/hooks";
2021
import { getHostedChart } from "../lib/queries";
21-
import { cleanupYDoc, setupYDoc } from "../lib/realtime";
22+
import { cleanupYDoc, setupYDoc, useYDoc } from "../lib/realtime";
2223
import { useDetailsStore } from "../lib/useDoc";
2324
import { useTrackLastChart } from "../lib/useLastChart";
2425
import editStyles from "./Edit.module.css";
@@ -59,8 +60,15 @@ export default function EditHosted() {
5960
useTrackLastChart(url);
6061
const isValidSponsor = useIsValidSponsor();
6162

63+
const isReady = useYDoc((state) => state.isReady);
64+
6265
return (
6366
<EditWrapper>
67+
{!isReady && (
68+
<div className="absolute top-0 left-0 w-full h-full flex items-center justify-center bg-white dark:bg-gray-900 z-50 opacity-40">
69+
<Loading color="color-foreground" />
70+
</div>
71+
)}
6472
<Main>
6573
<EditorWrapper>
6674
<Tabs.Root defaultValue="Document" className={editStyles.Tabs}>

wss/src/server.mjs

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,43 @@ const server = new Hocuspocus({
1818
fetch: async ({ documentName }) => {
1919
// create ydoc
2020
const ydoc = new Y.Doc();
21-
// create ytext
22-
const ytext = ydoc.getText("text");
23-
// meta
24-
const ymeta = ydoc.getMap("meta");
21+
2522
try {
2623
const [docType, id] = documentName.split("_");
27-
console.log({
28-
docType,
29-
id,
30-
});
31-
if (docType === "hosted") {
32-
console.log("Looking up hosted chart: ", id);
24+
25+
if (!id) throw new Error("Invalid Chart ID");
26+
27+
console.log("fetching document: ", id);
28+
// check to see if this is in storage
29+
const result = await supabase.storage
30+
.from("documents")
31+
.download(id + `?updated`);
32+
if (result.data) {
33+
// return result.data;
34+
// this is the ydoc, return it
35+
console.log("found in storage");
36+
console.log(typeof result.data);
37+
const arrayBuffer = await result.data.arrayBuffer();
38+
const buffer = Buffer.from(arrayBuffer);
39+
console.log("Return original");
40+
return buffer;
41+
// return result.data;
42+
// return result.data.arrayBuffer();
43+
} else {
44+
console.log(result);
45+
// need to create a ydoc and store in storage
46+
// then return it
47+
// create ytext
48+
const ytext = ydoc.getText("text");
49+
50+
// meta
51+
const ymeta = ydoc.getMap("meta");
52+
3353
const { data, error } = await supabase
3454
.from("user_charts")
3555
.select("id,name,chart,updated_at,created_at,public_id,is_public")
3656
.eq("id", id);
57+
3758
if (error) throw error;
3859
if (!data || data.length === 0) throw new Error("Invalid Chart ID");
3960
if (data.length > 1) throw new Error("Multiple Charts Found");
@@ -56,9 +77,16 @@ const server = new Hocuspocus({
5677
}
5778
});
5879
});
59-
} else if (docType === "public") {
60-
console.log("Need to lookup public chart!");
61-
// Potentially this should be outside of the database extension
80+
81+
// store the ydoc in storage
82+
const ydocState = Y.encodeStateAsUpdate(ydoc);
83+
const { error: storageError } = await supabase.storage
84+
.from("documents")
85+
.upload(id + `?updated`, ydocState, {
86+
upsert: true,
87+
cacheControl: "0",
88+
});
89+
if (storageError) throw storageError;
6290
}
6391
} catch (e) {
6492
console.log(e);
@@ -69,29 +97,44 @@ const server = new Hocuspocus({
6997
store: async ({ documentName, state }) => {
7098
const [_docType, id] = documentName.split("_");
7199

72-
// get "text" string from state buffer
73-
const ydoc = new Y.Doc();
74-
Y.applyUpdate(ydoc, state);
75-
const ytext = ydoc.getText("text");
76-
const text = ytext.toString();
77-
78-
// get meta
79-
const ymeta = ydoc.getMap("meta");
80-
/**
81-
* @type {object}
82-
* */
83-
const meta = {};
84-
ymeta.forEach((value, key) => {
85-
meta[key] = value;
86-
});
87-
88-
const chart = docToString({ text, meta });
89-
const { error } = await supabase
90-
.from("user_charts")
91-
.update({ chart })
92-
.eq("id", id);
93-
if (error) throw error;
94-
return true;
100+
// store the ydoc in storage
101+
const updatedAt = new Date().toISOString();
102+
const { error, data } = await supabase.storage
103+
.from("documents")
104+
.upload(id + `?updated`, state, {
105+
upsert: true,
106+
cacheControl: "0",
107+
});
108+
console.log("stored successfully");
109+
console.log(data);
110+
if (error) {
111+
console.log(error);
112+
throw error;
113+
}
114+
115+
// // get "text" string from state buffer
116+
// const ydoc = new Y.Doc();
117+
// Y.applyUpdate(ydoc, state);
118+
// const ytext = ydoc.getText("text");
119+
// const text = ytext.toString();
120+
121+
// // get meta
122+
// const ymeta = ydoc.getMap("meta");
123+
// /**
124+
// * @type {object}
125+
// * */
126+
// const meta = {};
127+
// ymeta.forEach((value, key) => {
128+
// meta[key] = value;
129+
// });
130+
131+
// const chart = docToString({ text, meta });
132+
// const { error } = await supabase
133+
// .from("user_charts")
134+
// .update({ chart })
135+
// .eq("id", id);
136+
// if (error) throw error;
137+
// return true;
95138
},
96139
}),
97140
],

0 commit comments

Comments
 (0)