refactor(crdt): implement proxy-resilient Yjs dual-transport sync with indexeddb offline-first and debounced sqlite persistence
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m11s

This commit is contained in:
sandrodach committed 2026-10-26 19:54:51 +01:00
1 parent 297f3ed111
commit f3b3f07e04
10 files changed
+1248 -484

No files matched your search

+18 -28
View File
@@ -62,6 +62,7 @@ type Hub struct {
sseUserRooms map[string]map[*SSEClient]bool
sseRooms map[string]map[*SSEClient]bool
locks map[string]*docLockItem
docRooms map[string]*DocRoom
crdtStore CRDTStore
}
@@ -74,6 +75,7 @@ func NewHub() *Hub {
sseUserRooms: make(map[string]map[*SSEClient]bool),
sseRooms: make(map[string]map[*SSEClient]bool),
locks: make(map[string]*docLockItem),
docRooms: make(map[string]*DocRoom),
}
go h.cleanupLocksLoop()
return h
@@ -811,23 +813,14 @@ func (c *Client) readPump() {
}
case "CRDT_JOIN":
c.hub.JoinRoom(c, "doc:"+docID)
if c.hub.crdtStore != nil {
stateBlob, updates, err := c.hub.crdtStore.GetDocumentCRDTState(docID)
if err == nil && (len(stateBlob) > 0 || len(updates) > 0) {
var b64Updates []string
for _, u := range updates {
b64Updates = append(b64Updates, base64.StdEncoding.EncodeToString(u))
}
b64State := ""
if len(stateBlob) > 0 {
b64State = base64.StdEncoding.EncodeToString(stateBlob)
}
c.SendEvent("CRDT_INIT", map[string]interface{}{
"docId": docID,
"state": b64State,
"updates": b64Updates,
})
}
room := c.hub.GetOrCreateDocRoom(docID)
b64State, b64Updates := room.GetInitialSnapshot()
if len(b64State) > 0 || len(b64Updates) > 0 {
c.SendEvent("CRDT_INIT", map[string]interface{}{
"docId": docID,
"state": b64State,
"updates": b64Updates,
})
}
case "CRDT_UPDATE":
var p struct {
@@ -835,15 +828,9 @@ func (c *Client) readPump() {
}
_ = json.Unmarshal(incoming.Payload, &p)
if p.Update != "" {
c.hub.BroadcastRoom("doc:"+docID, "CRDT_UPDATE", map[string]interface{}{
"docId": docID,
"update": p.Update,
"fromUserId": c.userID,
}, c)
if c.hub.crdtStore != nil {
if raw, err := base64.StdEncoding.DecodeString(p.Update); err == nil && len(raw) > 0 {
_ = c.hub.crdtStore.AppendDocumentCRDTUpdate(docID, raw, c.userID)
}
if raw, err := base64.StdEncoding.DecodeString(p.Update); err == nil && len(raw) > 0 {
room := c.hub.GetOrCreateDocRoom(docID)
room.ApplyUpdate(raw, c.userID, nil, nil)
}
}
case "CRDT_COMPACT":
@@ -851,13 +838,16 @@ func (c *Client) readPump() {
State string `json:"state"`
}
_ = json.Unmarshal(incoming.Payload, &p)
if p.State != "" && c.hub.crdtStore != nil {
if p.State != "" {
if raw, err := base64.StdEncoding.DecodeString(p.State); err == nil && len(raw) > 0 {
_ = c.hub.crdtStore.SaveDocumentCRDTState(docID, raw, c.userID)
room := c.hub.GetOrCreateDocRoom(docID)
room.CompactState(raw, c.userID)
}
}
case "CRDT_AWARENESS":
c.hub.BroadcastRoom("doc:"+docID, "CRDT_AWARENESS", incoming.Payload, c)
room := c.hub.GetOrCreateDocRoom(docID)
room.BroadcastAwareness(incoming.Payload, c.userID, nil, nil)
case "CRDT_LEAVE":
c.hub.LeaveRoom(c, "doc:"+docID)
c.hub.BroadcastRoom("doc:"+docID, "CRDT_AWARENESS_LEAVE", map[string]interface{}{