Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

machine state seems to be stuck at connecting without throwing error #98

Closed
Joshua-onwuzu opened this issue Dec 15, 2023 · 6 comments
Closed

Comments

@Joshua-onwuzu
Copy link

I'm attempting to experiment with SecSync in a React application and have completed the initial setup for Yjs and TipTap using useYjsSync as per the guidelines outlined in here.

I used the provided test WebSocket server wss://secsync.fly.dev . However, I encountered an issue where my state wasn't persisting to the server. Upon inspecting the browser's network tab, I noticed that there was no WebSocket connection being established and the application didn't throw any errors, and the machine state remained stuck in the connecting state. This problem persisted even when I attempted to run the WebSocket server locally.

btw, i was able to get everything up and running together without issues from the docker setup, i am not sure what i am missing here. ws://localhost:4000 in the code below points to the backend service from the repo running locally.

here is my entire react code:

import React, { useEffect, useRef, useState } from 'react'
import sodium, { KeyPair } from 'libsodium-wrappers'
import * as Yjs from 'yjs'
import { useYjsSync } from 'secsync-react-yjs'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import Collaboration from '@tiptap/extension-collaboration'
import uuid from 'react-uuid'

const SecSync = () => {
  const [authorKeyPair] = useState<KeyPair>(() => {
    return sodium.crypto_sign_keypair()
  })
  const yDocRef = useRef<Yjs.Doc>(new Yjs.Doc())
  const documentKey = sodium.crypto_secretbox_keygen()

  const [state, send] = useYjsSync({
    yDoc: yDocRef.current,
    documentId: uuid(),
    signatureKeyPair: authorKeyPair,
    websocketHost: 'ws://localhost:4000',
    websocketSessionKey: 'your-secret-session-key',
    onDocumentUpdated: async ({ knownSnapshotInfo }) => {
      console.log(knownSnapshotInfo, 'knownSnapshotInfo')
    },
    getNewSnapshotData: async ({ id }) => {
      return {
        data: Yjs.encodeStateAsUpdateV2(yDocRef.current),
        key: documentKey,
        publicData: {},
      }
    },
    getSnapshotKey: async (snapshot) => {
      return documentKey
    },
    shouldSendSnapshot: ({ snapshotUpdatesCount }) => {
      // create a new snapshot if the active snapshot has more than 100 updates
      return snapshotUpdatesCount > 100
    },
    isValidClient: async (signingPublicKey: string) => {
      return true
    },
    sodium,
    logging: 'debug',
  })
  const editor = useEditor({
    extensions: [
      StarterKit.configure({
        // the Collaboration extension comes with its own history handling
        history: false,
      }),
      Collaboration.configure({
        document: yDocRef.current,
        field: 'page',
      }),
    ],
  })
  return (
    <div>
      <h1>SECSYNC</h1>
      <EditorContent editor={editor} />
      <div>{state.matches('connected') ? 'CONNECTED' : 'DISCONNECTED'}</div>
      {state.matches('connected') && 'Connected'}
      {state.matches('connecting') && 'Connecting …'}
      {state.matches('disconnected') && 'Disconnected'}
      {state.matches('failed') && 'Error in loading or sending data'}
      <button
        onClick={() => {
          send({ type: 'CONNECT' })
        }}
      >
        Connect
      </button>{' '}
      <button
        onClick={() => {
          send({ type: 'DISCONNECT' })
        }}
      >
        Disconnect
      </button>
    </div>
  )
}

const Test = () => {
  const [libsodiumIsReady, setLibsodiumIsReady] = useState(false)

  useEffect(() => {
    sodium.ready.then(() => {
      setLibsodiumIsReady(true)
    })
  }, [])
  if (!libsodiumIsReady) return <>Loading</>
  return <SecSync />
}

export default Test
@nikgraf
Copy link
Member

nikgraf commented May 13, 2024

hey @Joshua-onwuzu, so sorry for the late reply. Somehow this didn't end up in my Github notifications.

I recently upgrade to xstate5 and did important fixes. Will do more this week and then publish a new version. Would you be interested to try again then?

@ncallaway
Copy link

@nikgraf I also was having this problem the other day. I'd definitely be willing to test a version 0.2.0 and a 0.2.1 to test a fix

@ncallaway
Copy link

I should also mention that when I clone secsync and npm link the packages, I wasn't seeing this issue, so I strongly suspect that your recent changes fixed the issue for me. But I'd be happy to verify on a published npm package.

@nikgraf
Copy link
Member

nikgraf commented May 30, 2024

@ncallaway just published a new version, would appreciate if you you can verify that it now works

@ncallaway
Copy link

@nikgraf Just tested with secsync@0.4.0 and secsync-server@0.4.0 and it's working for me

@nikgraf
Copy link
Member

nikgraf commented Jun 2, 2024

closing the issue, let me know once it comes up again

@nikgraf nikgraf closed this as completed Jun 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants