diff --git a/apps/app/package.json b/apps/app/package.json index 16fd0ca..84f3934 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -51,6 +51,7 @@ "react-native-screens": "3.31.1", "react-native-svg": "15.2.0", "react-native-web": "~0.19.10", + "react-yjs": "^0.0.3", "secsync": "^0.5.0", "secsync-react-yjs": "^0.5.0", "tailwind-merge": "^2.3.0", diff --git a/apps/app/src/components/document.tsx b/apps/app/src/components/document.tsx index 62668da..49ad4d8 100644 --- a/apps/app/src/components/document.tsx +++ b/apps/app/src/components/document.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useRef, useState } from "react"; import { View } from "react-native"; import sodium, { KeyPair } from "react-native-libsodium"; +import { useY } from "react-yjs"; import { generateId } from "secsync"; import { useYjsSync } from "secsync-react-yjs"; import * as Yjs from "yjs"; @@ -12,7 +13,6 @@ import { Checkbox } from "../components/checkbox"; import { DocumentMembers } from "../components/documentMember"; import { SubtleInput } from "../components/subtleInput"; import { UpdateDocumentNameForm } from "../components/updateDocumentNameForm"; -import { useYData } from "../hooks/useYData"; import { convertChecklistToArrayAndSort } from "../utils/convertChecklistToArrayAndSort"; import { deserialize } from "../utils/deserialize"; import { getDocumentStorage } from "../utils/documentStorage"; @@ -72,7 +72,7 @@ const Document: React.FC = ({ documentKey, documentId }) => { }, []); const yDocument: Yjs.Map> = yDocRef.current.getMap("document"); - const document = useYData<{ [k: string]: ChecklistItem }>(yDocument); + const document = useY(yDocument); const checklist = document ? convertChecklistToArrayAndSort(document) : []; const [newTodoText, setNewTodoText] = useState(""); @@ -89,7 +89,6 @@ const Document: React.FC = ({ documentKey, documentId }) => { documentId, signatureKeyPair: authorKeyPair, websocketEndpoint, - websocketSessionKey: "your-secret-session-key", getNewSnapshotData: async ({ id }) => { return { data: Yjs.encodeStateAsUpdateV2(yDocRef.current), diff --git a/apps/app/src/hooks/useYArray.ts b/apps/app/src/hooks/useYArray.ts deleted file mode 100644 index 47447ac..0000000 --- a/apps/app/src/hooks/useYArray.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useRef, useSyncExternalStore } from "react"; -import * as Yjs from "yjs"; - -export const useYArray = (yArray: Yjs.Array) => { - const cachedMyListRef = useRef([]); - const array = useSyncExternalStore( - (callback) => { - yArray.observe(callback); - return () => yArray.unobserve(callback); - }, - () => { - // React requires reference equality - const newList = yArray.toArray(); - if (JSON.stringify(cachedMyListRef.current) === JSON.stringify(newList)) { - return cachedMyListRef.current; - } else { - cachedMyListRef.current = newList; - return cachedMyListRef.current; - } - }, - () => [] - ); - return array; -}; diff --git a/apps/app/src/hooks/useYData.ts b/apps/app/src/hooks/useYData.ts deleted file mode 100644 index 972a3db..0000000 --- a/apps/app/src/hooks/useYData.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { useRef, useSyncExternalStore } from "react"; -import * as Yjs from "yjs"; - -export function useYData(yData: Yjs.Map) { - const cachedDataRef = useRef(null); - const array = useSyncExternalStore( - (callback) => { - yData.observeDeep(callback); - return () => yData.unobserveDeep(callback); - }, - () => { - // React requires reference equality - const newStructure = yData.toJSON() as Type; - if ( - JSON.stringify(cachedDataRef.current) === JSON.stringify(newStructure) - ) { - return cachedDataRef.current; - } else { - cachedDataRef.current = newStructure; - return cachedDataRef.current; - } - }, - () => null - ); - return array; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e11bc3d..1f20af9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,7 +43,7 @@ importers: version: 1.0.7(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@react-navigation/drawer': specifier: ^6.6.15 - version: 6.6.15(@react-navigation/native@6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) + version: 6.6.15(grotwgcasf65a6jatlzx6z242a) '@react-navigation/native': specifier: ^6.0.2 version: 6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) @@ -88,7 +88,7 @@ importers: version: 6.3.1(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) expo-router: specifier: ~3.5.14 - version: 3.5.16(@react-navigation/drawer@6.6.15(@react-navigation/native@6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(expo-constants@16.0.2(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-linking@6.3.1(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0)(typescript@5.3.3) + version: 3.5.16(2qnt4bqjla5c7ivnjea5ivivsa) expo-secure-store: specifier: ~13.0.1 version: 13.0.1(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))) @@ -149,6 +149,9 @@ importers: react-native-web: specifier: ~0.19.10 version: 0.19.12(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-yjs: + specifier: ^0.0.3 + version: 0.0.3(react@18.2.0)(yjs@13.6.16) secsync: specifier: ^0.5.0 version: 0.5.0 @@ -5273,6 +5276,12 @@ packages: peerDependencies: react: ^18.2.0 + react-yjs@0.0.3: + resolution: {integrity: sha512-8HYkqb6jliEX2fZW9hHm6tOyAden8y3TVwmxvGTvNfrHQ+j9SgIj/S25mVn4aoja4KP6ZZz13yVt203dzCNxhg==} + peerDependencies: + react: ^18 || ^19 + yjs: ^13.6.16 + react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -8700,8 +8709,8 @@ snapshots: react-is: 16.13.1 use-latest-callback: 0.1.9(react@18.2.0) - ? '@react-navigation/drawer@6.6.15(@react-navigation/native@6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0)' - : dependencies: + '@react-navigation/drawer@6.6.15(grotwgcasf65a6jatlzx6z242a)': + dependencies: '@react-navigation/elements': 1.3.30(@react-navigation/native@6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) '@react-navigation/native': 6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) color: 4.2.3 @@ -10277,8 +10286,8 @@ snapshots: dependencies: invariant: 2.2.4 - ? expo-router@3.5.16(@react-navigation/drawer@6.6.15(@react-navigation/native@6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(expo-constants@16.0.2(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-linking@6.3.1(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))))(expo-modules-autolinking@1.11.1)(expo-status-bar@1.12.1)(expo@51.0.12(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7)))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0)(typescript@5.3.3) - : dependencies: + expo-router@3.5.16(2qnt4bqjla5c7ivnjea5ivivsa): + dependencies: '@expo/metro-runtime': 3.2.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0)) '@expo/server': 0.4.3(typescript@5.3.3) '@radix-ui/react-slot': 1.0.1(react@18.2.0) @@ -10295,7 +10304,7 @@ snapshots: react-native-screens: 3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) schema-utils: 4.2.0 optionalDependencies: - '@react-navigation/drawer': 6.6.15(@react-navigation/native@6.1.17(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-gesture-handler@2.16.2(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.10.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native-screens@3.31.1(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) + '@react-navigation/drawer': 6.6.15(grotwgcasf65a6jatlzx6z242a) react-native-reanimated: 3.10.1(@babel/core@7.24.7)(react-native@0.74.1(@babel/core@7.24.7)(@babel/preset-env@7.24.7(@babel/core@7.24.7))(@types/react@18.2.79)(react@18.2.0))(react@18.2.0) transitivePeerDependencies: - encoding @@ -12784,6 +12793,11 @@ snapshots: react-shallow-renderer: 16.15.0(react@18.2.0) scheduler: 0.23.2 + react-yjs@0.0.3(react@18.2.0)(yjs@13.6.16): + dependencies: + react: 18.2.0 + yjs: 13.6.16 + react@18.2.0: dependencies: loose-envify: 1.4.0