1- import { deserialize } from '@/lib/deserialize'
2- import { isAuthenticated } from '@/lib/isAuthenticated'
3- import { serialize } from '@/lib/serialize'
4- import { createFileRoute , redirect } from '@tanstack/react-router'
5- import sodium , { KeyPair } from 'libsodium-wrappers'
6- import { useEffect , useState } from 'react'
7- import { useYjsSync } from 'secsync-react-yjs'
8- import { createStore } from 'tinybase'
9- import { createYjsPersister } from 'tinybase/persisters/persister-yjs'
10- import { Provider , useCreatePersister , useCreateStore } from 'tinybase/ui-react'
11- import { Inspector } from 'tinybase/ui-react-inspector'
12- import * as Yjs from 'yjs'
13- import { EventsPage } from '../../components/events-page'
1+ import { deserialize } from "@/lib/deserialize" ;
2+ import { isAuthenticated } from "@/lib/isAuthenticated" ;
3+ import { serialize } from "@/lib/serialize" ;
4+ import { createFileRoute , redirect } from "@tanstack/react-router" ;
5+ import sodium , { KeyPair } from "libsodium-wrappers" ;
6+ import { useEffect , useState } from "react" ;
7+ import { useYjsSync } from "secsync-react-yjs" ;
8+ import { createStore } from "tinybase" ;
9+ import { createYjsPersister } from "tinybase/persisters/persister-yjs" ;
10+ import {
11+ Provider ,
12+ useCreatePersister ,
13+ useCreateStore ,
14+ } from "tinybase/ui-react" ;
15+ import { Inspector } from "tinybase/ui-react-inspector" ;
16+ import * as Yjs from "yjs" ;
17+ import { EventsPage } from "../../components/events-page" ;
1418
15- const websocketEndpoint = ' ws://localhost:3030'
19+ const websocketEndpoint = " ws://localhost:3030" ;
1620
17- export const Route = createFileRoute ( ' /space-old/$spaceId' ) ( {
21+ export const Route = createFileRoute ( " /space-old/$spaceId" ) ( {
1822 component : SpaceWithKey ,
1923 beforeLoad : ( ) => {
2024 if ( ! isAuthenticated ( ) ) {
2125 throw redirect ( {
22- to : ' /login' ,
26+ to : " /login" ,
2327 search : {
2428 // Use the current location to power a redirect after login
2529 // (Do not use `router.state.resolvedLocation` as it can
2630 // potentially lag behind the actual current location)
2731 redirect : location . href ,
2832 } ,
29- } )
33+ } ) ;
3034 }
3135 } ,
32- } )
36+ } ) ;
3337
3438function SpaceWithKey ( ) {
35- const { spaceId } = Route . useParams ( )
39+ const { spaceId } = Route . useParams ( ) ;
3640 // ensuring the Space component is unmounted and remounted when the spaceId changes
3741 // this is needed since secsync and possibly tinybase don't handle the spaceId change well
38- return < Space key = { spaceId } />
42+ return < Space key = { spaceId } /> ;
3943}
4044
4145export function Space ( ) {
42- const { spaceId } = Route . useParams ( )
46+ const { spaceId } = Route . useParams ( ) ;
4347 const spaceKey = sodium . from_base64 (
44- ' Wzrx2kLy6kd3FBqcNOOwaYQ2S1My9zofdX49CL-k_ko' ,
45- )
48+ " Wzrx2kLy6kd3FBqcNOOwaYQ2S1My9zofdX49CL-k_ko"
49+ ) ;
4650
4751 const store = useCreateStore ( ( ) => {
4852 // Create the TinyBase Store and initialize the Store's data
4953 return createStore ( ) . setTablesSchema ( {
5054 events : {
51- name : { type : ' string' } ,
52- date : { type : ' string' } ,
53- location : { type : ' string' } ,
54- description : { type : ' string' } ,
55+ name : { type : " string" } ,
56+ date : { type : " string" } ,
57+ location : { type : " string" } ,
58+ description : { type : " string" } ,
5559 } ,
56- } )
57- } )
60+ } ) ;
61+ } ) ;
5862
5963 const [ { yDoc, pendingChanges } ] = useState ( ( ) => {
60- console . log ( ' create new yDoc' )
61- const yDoc = new Yjs . Doc ( )
64+ console . log ( " create new yDoc" ) ;
65+ const yDoc = new Yjs . Doc ( ) ;
6266
6367 // load full document
64- const serializedDoc = localStorage . getItem ( `space:state:${ spaceId } ` )
68+ const serializedDoc = localStorage . getItem ( `space:state:${ spaceId } ` ) ;
6569 if ( serializedDoc ) {
66- console . log ( ' load serializedDoc' , serializedDoc )
67- Yjs . applyUpdateV2 ( yDoc , deserialize ( serializedDoc ) )
70+ console . log ( " load serializedDoc" , serializedDoc ) ;
71+ Yjs . applyUpdateV2 ( yDoc , deserialize ( serializedDoc ) ) ;
6872 }
6973
7074 // loads the pendingChanges from localStorage
71- const pendingChanges = localStorage . getItem ( `space:pending:${ spaceId } ` )
75+ const pendingChanges = localStorage . getItem ( `space:pending:${ spaceId } ` ) ;
7276
7377 return {
7478 yDoc,
7579 pendingChanges : pendingChanges ? deserialize ( pendingChanges ) : [ ] ,
76- }
77- } )
80+ } ;
81+ } ) ;
7882
7983 // update the document in localStorage after every change (could be debounced)
8084 useEffect ( ( ) => {
8185 const onUpdate = ( ) => {
82- console . log ( ' persist to localstorage' )
83- const fullYDoc = Yjs . encodeStateAsUpdateV2 ( yDoc )
84- localStorage . setItem ( `space:state:${ spaceId } ` , serialize ( fullYDoc ) )
85- }
86- yDoc . on ( ' updateV2' , onUpdate )
86+ console . log ( " persist to localstorage" ) ;
87+ const fullYDoc = Yjs . encodeStateAsUpdateV2 ( yDoc ) ;
88+ localStorage . setItem ( `space:state:${ spaceId } ` , serialize ( fullYDoc ) ) ;
89+ } ;
90+ yDoc . on ( " updateV2" , onUpdate ) ;
8791
8892 return ( ) => {
89- yDoc . off ( 'updateV2' , onUpdate )
90- }
91- } , [ ] )
93+ yDoc . off ( "updateV2" , onUpdate ) ;
94+ } ;
95+ // eslint-disable-next-line react-hooks/exhaustive-deps
96+ } , [ ] ) ;
9297
9398 useCreatePersister (
9499 store ,
95100 ( store ) =>
96- createYjsPersister ( store , yDoc , ' space' , ( error ) => {
97- console . log ( ' YjsPersister Error:' , error )
101+ createYjsPersister ( store , yDoc , " space" , ( error ) => {
102+ console . log ( " YjsPersister Error:" , error ) ;
98103 } ) ,
99104 [ ] ,
100105 async ( persister ) => {
101106 // must be called before startAutoLoad to avoid a loading error in case the document is empty
102- await persister . startAutoLoad ( )
103- await persister . startAutoSave ( )
104- } ,
105- )
107+ await persister . startAutoLoad ( ) ;
108+ await persister . startAutoSave ( ) ;
109+ }
110+ ) ;
106111
107112 const [ authorKeyPair ] = useState < KeyPair > ( ( ) => {
108- return sodium . crypto_sign_keypair ( )
109- } )
113+ return sodium . crypto_sign_keypair ( ) ;
114+ } ) ;
110115
111116 useYjsSync ( {
112117 yDoc,
113118 pendingChanges,
114119 // callback to store the pending changes in
115120 onPendingChangesUpdated : ( allChanges ) => {
116- localStorage . setItem ( `space:pending:${ spaceId } ` , serialize ( allChanges ) )
121+ localStorage . setItem ( `space:pending:${ spaceId } ` , serialize ( allChanges ) ) ;
117122 } ,
118123 documentId : spaceId ,
119124 signatureKeyPair : authorKeyPair ,
120125 websocketEndpoint,
121- websocketSessionKey : ' your-secret-session-key' ,
122- getNewSnapshotData : async ( { id } ) => {
126+ websocketSessionKey : " your-secret-session-key" ,
127+ getNewSnapshotData : async ( ) => {
123128 return {
124129 data : Yjs . encodeStateAsUpdateV2 ( yDoc ) ,
125130 key : spaceKey ,
126131 publicData : { } ,
127- }
132+ } ;
128133 } ,
129134 getSnapshotKey : async ( ) => {
130- return spaceKey
135+ return spaceKey ;
131136 } ,
132137 shouldSendSnapshot : ( { snapshotUpdatesCount } ) => {
133138 // create a new snapshot if the active snapshot has more than 100 updates
134- return snapshotUpdatesCount > 100
139+ return snapshotUpdatesCount > 100 ;
135140 } ,
136- isValidClient : async ( signingPublicKey : string ) => {
137- return true
141+ isValidClient : async ( ) => {
142+ return true ;
138143 } ,
139144 sodium,
140- logging : ' debug' ,
141- } )
145+ logging : " debug" ,
146+ } ) ;
142147
143148 return (
144149 < Provider store = { store } >
@@ -147,5 +152,5 @@ export function Space() {
147152 </ >
148153 < Inspector />
149154 </ Provider >
150- )
155+ ) ;
151156}
0 commit comments