@@ -7,13 +7,13 @@ import React, {
77 useEffect ,
88} from 'react'
99import { Flow , PipeData , PipeMeta } from 'src/types/flows'
10- import { useParams } from 'react-router'
1110import { FlowListContext , FlowListProvider } from 'src/flows/context/flow.list'
1211import { v4 as UUID } from 'uuid'
1312import { DEFAULT_PROJECT_NAME , PIPE_DEFINITIONS } from 'src/flows'
1413import { isFlagEnabled } from 'src/shared/utils/featureFlag'
1514import * as Y from 'yjs'
1615import { WebsocketProvider } from 'y-websocket'
16+ import { serialize , hydrate } from 'src/flows/context/flow.list'
1717
1818export interface FlowContextType {
1919 name : string
@@ -45,13 +45,10 @@ export const FlowProvider: FC = ({children}) => {
4545 const { flows, update, currentID} = useContext ( FlowListContext )
4646 const [ currentFlow , setCurrentFlow ] = useState < Flow > ( )
4747
48- const yDoc = useRef ( new Y . Doc ( ) )
4948 const provider = useRef < WebsocketProvider > ( )
50-
51- const { id : flowId } = useParams < { id : string } > ( )
52-
49+ const yDoc = useRef ( new Y . Doc ( ) )
5350 function disconnectProvider ( ) {
54- if ( provider . current ?. wsconnected ) {
51+ if ( provider . current ) {
5552 provider . current . disconnect ( )
5653 }
5754 }
@@ -68,38 +65,49 @@ export const FlowProvider: FC = ({children}) => {
6865 }
6966 } , [ flows , currentID ] )
7067
68+ const syncFunc = useCallback (
69+ ( isSynced : boolean ) => {
70+ if ( ! isSynced || ! yDoc . current ) {
71+ return
72+ }
73+ const { flowUpdateData} = yDoc . current . getMap ( 'flowUpdateData' ) ?. toJSON ( )
74+ if ( ! flowUpdateData && currentFlow ) {
75+ yDoc . current
76+ . getMap ( 'flowUpdateData' )
77+ . set ( 'flowUpdateData' , serialize ( currentFlow ) )
78+ }
79+ } ,
80+ [ currentFlow ]
81+ )
82+
7183 useEffect ( ( ) => {
72- if ( isFlagEnabled ( 'sharedFlowEditing' ) ) {
84+ const doc = yDoc . current
85+ if ( isFlagEnabled ( 'sharedFlowEditing' ) && currentID ) {
7386 provider . current = new WebsocketProvider (
87+ // 'ws://localhost:1223', // todo(ariel): replace this with an actual API that we setup
7488 'wss://demos.yjs.dev' , // todo(ariel): replace this with an actual API that we setup
75- flowId , // todo(ariel): we might need to confine this to an org, depends on how multi-org plays out
76- yDoc . current
89+ currentID ,
90+ doc
7791 )
78- provider . current . on ( 'sync' , isSynced => {
79- if ( isSynced ) {
80- const localState = yDoc . current . getMap ( 'localState' ) ?. toJSON ( )
81- if ( ! localState ) {
82- yDoc . current . getMap ( 'localState' ) . set ( 'localState' , currentFlow )
83- }
84- }
85- } )
86- yDoc . current . on ( 'update' , ( ) => {
87- const { localState} = yDoc . current . getMap ( 'localState' ) . toJSON ( )
88- setCurrentFlow ( prev => {
89- if ( btoa ( JSON . stringify ( prev ) ) === btoa ( JSON . stringify ( localState ) ) ) {
90- return prev
91- }
92- return localState
93- } )
94- } )
92+
93+ provider . current . on ( 'sync' , syncFunc )
9594 }
9695
96+ const onUpdate = ( ) => {
97+ const { flowUpdateData} = doc . getMap ( 'flowUpdateData' ) . toJSON ( )
98+ const hydrated = hydrate ( flowUpdateData ?. data )
99+
100+ setCurrentFlow ( hydrated )
101+ }
102+
103+ doc . on ( 'update' , onUpdate )
97104 return ( ) => {
98105 if ( isFlagEnabled ( 'sharedFlowEditing' ) ) {
99106 disconnectProvider ( )
100107 }
108+ doc . off ( 'update' , onUpdate )
101109 }
102- } , [ flowId ] )
110+ } , [ currentID ] )
103111
104112 const updateData = useCallback (
105113 ( id : string , data : Partial < PipeData > ) => {
@@ -110,11 +118,9 @@ export const FlowProvider: FC = ({children}) => {
110118 ...( flowCopy . data . byID [ id ] || { } ) ,
111119 ...data ,
112120 }
113- const update = {
114- ...flowCopy ,
115- ...flowCopy . data . byID [ id ] ,
116- }
117- yDoc . current . getMap ( 'localState' ) . set ( 'localState' , update )
121+ yDoc . current
122+ . getMap ( 'flowUpdateData' )
123+ . set ( 'flowUpdateData' , serialize ( flowCopy ) )
118124 }
119125 return
120126 }
@@ -154,11 +160,9 @@ export const FlowProvider: FC = ({children}) => {
154160 ...meta ,
155161 }
156162
157- const update = {
158- ...flowCopy ,
159- ...flowCopy . meta . byID [ id ] ,
160- }
161- yDoc . current . getMap ( 'localState' ) . set ( 'localState' , update )
163+ yDoc . current
164+ . getMap ( 'flowUpdateData' )
165+ . set ( 'flowUpdateData' , serialize ( flowCopy ) )
162166 }
163167 return
164168 }
@@ -198,9 +202,9 @@ export const FlowProvider: FC = ({children}) => {
198202 for ( const ni in flow ) {
199203 flowCopy [ ni ] = flow [ ni ]
200204 }
201- yDoc . current . getMap ( 'localState' ) . set ( 'localState' , {
202- ... flowCopy ,
203- } )
205+ yDoc . current
206+ . getMap ( 'flowUpdateData' )
207+ . set ( 'flowUpdateData' , serialize ( flowCopy ) )
204208 }
205209 return
206210 }
@@ -248,9 +252,9 @@ export const FlowProvider: FC = ({children}) => {
248252 flowCopy . data . allIDs . push ( id )
249253 flowCopy . meta . allIDs . push ( id )
250254 }
251- yDoc . current . getMap ( 'localState' ) . set ( 'localState' , {
252- ... flowCopy ,
253- } )
255+ yDoc . current
256+ . getMap ( 'flowUpdateData' )
257+ . set ( 'flowUpdateData' , serialize ( flowCopy ) )
254258 return
255259 }
256260 if ( isFlagEnabled ( 'ephemeralNotebook' ) && ! currentFlow . id ) {
@@ -299,9 +303,9 @@ export const FlowProvider: FC = ({children}) => {
299303
300304 delete flowCopy . data . byID [ id ]
301305 delete flowCopy . meta . byID [ id ]
302- yDoc . current . getMap ( 'localState' ) . set ( 'localState' , {
303- ... flowCopy ,
304- } )
306+ yDoc . current
307+ . getMap ( 'flowUpdateData' )
308+ . set ( 'flowUpdateData' , serialize ( flowCopy ) )
305309 return
306310 }
307311 if ( isFlagEnabled ( 'ephemeralNotebook' ) && ! currentFlow . id ) {
0 commit comments