1- import { Effect } from "effect" ;
1+ import { Effect , flow , Option } from "effect" ;
22import { LoroDoc } from "loro-crdt" ;
33import { ApiClient } from "../api-client" ;
44import { Dexie } from "../dexie" ;
5- import type { WorkspaceTable } from "../schema" ;
65import { TempWorkspace } from "./temp-workspace" ;
76import { WorkspaceManager } from "./workspace-manager" ;
87
@@ -22,85 +21,134 @@ export class Sync extends Effect.Service<Sync>()("Sync", {
2221 return {
2322 push : ( {
2423 snapshot,
25- workspace ,
24+ workspaceId ,
2625 snapshotId,
2726 } : {
28- workspace : WorkspaceTable ;
27+ workspaceId : string ;
2928 snapshotId : string ;
3029 snapshot : globalThis . Uint8Array ;
3130 } ) =>
32- Effect . gen ( function * ( ) {
33- const clientId = yield * initClient ;
34- yield * Effect . log ( `Pushing snapshot ${ snapshotId } ` ) ;
31+ manager . getById ( { workspaceId } ) . pipe (
32+ Effect . flatMap (
33+ flow (
34+ Option . fromNullable ,
35+ Option . match ( {
36+ onNone : ( ) => Effect . log ( "No workspace found" ) ,
37+ onSome : ( workspace ) =>
38+ Effect . gen ( function * ( ) {
39+ const clientId = yield * initClient ;
40+ yield * Effect . log ( `Pushing snapshot ${ snapshotId } ` ) ;
3541
36- const response = yield * Effect . fromNullable ( workspace . token ) . pipe (
37- Effect . flatMap ( ( token ) =>
38- client . syncData
39- . push ( {
40- headers : { "x-api-key" : token } ,
41- path : { workspaceId : workspace . workspaceId } ,
42- payload : { snapshot, snapshotId } ,
43- } )
44- . pipe (
45- Effect . map ( ( response ) => ( {
46- ...response ,
47- token,
48- } ) )
49- )
50- ) ,
51- Effect . catchTag ( "NoSuchElementException" , ( ) =>
52- client . syncAuth
53- . generateToken ( {
54- payload : {
55- clientId,
56- snapshot,
57- snapshotId,
58- workspaceId : workspace . workspaceId ,
59- } ,
60- } )
61- . pipe (
62- Effect . tap ( ( { token } ) =>
63- manager . setToken ( {
64- workspaceId : workspace . workspaceId ,
65- token,
66- } )
67- )
68- )
69- )
70- ) ;
42+ const response = yield * Effect . fromNullable (
43+ workspace . token
44+ ) . pipe (
45+ Effect . flatMap ( ( token ) =>
46+ client . syncData
47+ . push ( {
48+ headers : { "x-api-key" : token } ,
49+ path : { workspaceId : workspace . workspaceId } ,
50+ payload : { snapshot, snapshotId } ,
51+ } )
52+ . pipe (
53+ Effect . map ( ( response ) => ( {
54+ ...response ,
55+ token,
56+ } ) )
57+ )
58+ ) ,
59+ Effect . catchTag ( "NoSuchElementException" , ( ) =>
60+ client . syncAuth
61+ . generateToken ( {
62+ payload : {
63+ clientId,
64+ snapshot,
65+ snapshotId,
66+ workspaceId : workspace . workspaceId ,
67+ } ,
68+ } )
69+ . pipe (
70+ Effect . tap ( ( { token } ) =>
71+ manager . setToken ( {
72+ workspaceId : workspace . workspaceId ,
73+ token,
74+ } )
75+ )
76+ )
77+ )
78+ ) ;
7179
72- const doc = new LoroDoc ( ) ;
73- doc . import ( response . snapshot ) ;
74- yield * Effect . all ( [
75- manager . put ( {
76- workspaceId : response . workspaceId ,
77- snapshot : response . snapshot ,
78- token : response . token ,
79- version : doc . version ( ) . encode ( ) ,
80- } ) ,
81- temp . clean ( {
82- workspaceId : workspace . workspaceId ,
83- } ) ,
84- ] ) ;
85- } ) ,
80+ const doc = new LoroDoc ( ) ;
81+ doc . import ( response . snapshot ) ;
82+ yield * Effect . all ( [
83+ manager . put ( {
84+ workspaceId : response . workspaceId ,
85+ snapshot : response . snapshot ,
86+ token : response . token ,
87+ version : doc . version ( ) . encode ( ) ,
88+ } ) ,
89+ temp . clean ( {
90+ workspaceId : workspace . workspaceId ,
91+ } ) ,
92+ ] ) ;
93+ } ) ,
94+ } )
95+ )
96+ )
97+ ) ,
8698
8799 pull : ( { workspaceId } : { workspaceId : string } ) =>
100+ manager . getById ( { workspaceId } ) . pipe (
101+ Effect . flatMap (
102+ flow (
103+ Option . fromNullable ,
104+ Option . flatMap ( ( workspace ) =>
105+ Option . fromNullable ( workspace . token )
106+ ) ,
107+ Option . match ( {
108+ onNone : ( ) =>
109+ Effect . log ( "No token found" ) . pipe ( Effect . map ( ( ) => null ) ) ,
110+ onSome : ( token ) =>
111+ Effect . gen ( function * ( ) {
112+ yield * Effect . log ( `Pulling from ${ workspaceId } ` ) ;
113+
114+ const response = yield * client . syncData . pull ( {
115+ headers : { "x-api-key" : token } ,
116+ path : { workspaceId } ,
117+ } ) ;
118+
119+ const doc = new LoroDoc ( ) ;
120+ doc . import ( response . snapshot ) ;
121+ yield * manager . put ( {
122+ token,
123+ workspaceId,
124+ snapshot : response . snapshot ,
125+ version : doc . version ( ) . encode ( ) ,
126+ } ) ;
127+
128+ return response ;
129+ } ) ,
130+ } )
131+ )
132+ )
133+ ) ,
134+
135+ join : ( { workspaceId } : { workspaceId : string } ) =>
88136 Effect . gen ( function * ( ) {
89137 const clientId = yield * initClient ;
90- yield * Effect . log ( `Pulling from ${ workspaceId } ` ) ;
91-
92- const response = yield * client . syncData . pull ( {
93- path : { workspaceId, clientId } ,
138+ const response = yield * client . syncData . join ( {
139+ path : { clientId, workspaceId } ,
94140 } ) ;
95141
96142 const doc = new LoroDoc ( ) ;
97143 doc . import ( response . snapshot ) ;
98144 yield * manager . put ( {
99- workspaceId : response . workspaceId ,
100- snapshot : response . snapshot ,
145+ workspaceId,
101146 token : response . token ,
147+ snapshot : response . snapshot ,
102148 version : doc . version ( ) . encode ( ) ,
103149 } ) ;
150+
151+ return response ;
104152 } ) ,
105153 } ;
106154 } ) ,
0 commit comments