ugly-app 0.1.233 → 0.1.234

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cli/version.d.ts +1 -1
  2. package/dist/cli/version.js +1 -1
  3. package/dist/collab/client/CollabProvider.d.ts +36 -0
  4. package/dist/collab/client/CollabProvider.d.ts.map +1 -0
  5. package/dist/collab/client/CollabProvider.js +152 -0
  6. package/dist/collab/client/CollabProvider.js.map +1 -0
  7. package/dist/collab/client/collabUtils.d.ts +3 -0
  8. package/dist/collab/client/collabUtils.d.ts.map +1 -0
  9. package/dist/collab/client/collabUtils.js +17 -0
  10. package/dist/collab/client/collabUtils.js.map +1 -0
  11. package/dist/collab/client/index.d.ts +5 -0
  12. package/dist/collab/client/index.d.ts.map +1 -0
  13. package/dist/collab/client/index.js +4 -0
  14. package/dist/collab/client/index.js.map +1 -0
  15. package/dist/collab/client/useCollab.d.ts +14 -0
  16. package/dist/collab/client/useCollab.d.ts.map +1 -0
  17. package/dist/collab/client/useCollab.js +38 -0
  18. package/dist/collab/client/useCollab.js.map +1 -0
  19. package/dist/collab/server/CollabServer.d.ts +64 -0
  20. package/dist/collab/server/CollabServer.d.ts.map +1 -0
  21. package/dist/collab/server/CollabServer.js +381 -0
  22. package/dist/collab/server/CollabServer.js.map +1 -0
  23. package/dist/collab/server/index.d.ts +20 -0
  24. package/dist/collab/server/index.d.ts.map +1 -0
  25. package/dist/collab/server/index.js +21 -0
  26. package/dist/collab/server/index.js.map +1 -0
  27. package/dist/collab/shared/CollabTypes.d.ts +31 -0
  28. package/dist/collab/shared/CollabTypes.d.ts.map +1 -0
  29. package/dist/collab/shared/CollabTypes.js +3 -0
  30. package/dist/collab/shared/CollabTypes.js.map +1 -0
  31. package/dist/server/Email.d.ts +4 -7
  32. package/dist/server/Email.d.ts.map +1 -1
  33. package/dist/server/Email.js +26 -37
  34. package/dist/server/Email.js.map +1 -1
  35. package/package.json +10 -3
  36. package/src/cli/version.ts +1 -1
  37. package/src/collab/client/CollabProvider.ts +187 -0
  38. package/src/collab/client/collabUtils.ts +18 -0
  39. package/src/collab/client/index.ts +12 -0
  40. package/src/collab/client/useCollab.ts +56 -0
  41. package/src/collab/server/CollabServer.ts +530 -0
  42. package/src/collab/server/index.ts +36 -0
  43. package/src/collab/shared/CollabTypes.ts +44 -0
  44. package/src/server/Email.ts +28 -43
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.1.233";
1
+ export declare const CLI_VERSION = "0.1.234";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.233";
2
+ export const CLI_VERSION = "0.1.234";
3
3
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,36 @@
1
+ import * as Y from 'yjs';
2
+ /**
3
+ * Transport interface for sending collab messages over a WebSocket.
4
+ * The consuming app wires this to its own socket implementation.
5
+ */
6
+ export interface CollabTransport {
7
+ /** RPC — sends a message and waits for a response. */
8
+ send(type: string, data: object): Promise<unknown>;
9
+ /** Fire-and-forget — sends a message with no response expected. */
10
+ emit(type: string, data: object): void;
11
+ }
12
+ type PeerIdsCallback = (peerIds: string[]) => void;
13
+ export declare class CollabClient {
14
+ readonly ydoc: Y.Doc;
15
+ readonly docId: string;
16
+ private connected;
17
+ private destroyed;
18
+ private pendingUpdates;
19
+ private onPeersChange;
20
+ private transport;
21
+ private updateHandler;
22
+ private awarenessHandler;
23
+ private peersHandler;
24
+ private reconnectHandler;
25
+ constructor(docId: string, transport: CollabTransport | null);
26
+ setTransport(transport: CollabTransport | null): void;
27
+ setPeersCallback(cb: PeerIdsCallback): void;
28
+ connect(): Promise<void>;
29
+ private handleLocalUpdate;
30
+ private sendUpdate;
31
+ disconnect(): void;
32
+ destroy(): void;
33
+ isConnected(): boolean;
34
+ }
35
+ export {};
36
+ //# sourceMappingURL=CollabProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollabProvider.d.ts","sourceRoot":"","sources":["../../../src/collab/client/CollabProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAUzB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,mEAAmE;IACnE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,KAAK,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAEnD,qBAAa,YAAY;IACvB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,SAAS,CAAyB;IAG1C,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,gBAAgB,CAA+C;IACvE,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,gBAAgB,CAA+C;gBAE3D,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI;IAoD5D,YAAY,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI;IAIrD,gBAAgB,CAAC,EAAE,EAAE,eAAe,GAAG,IAAI;IAIrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC9B,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,UAAU;IAQlB,UAAU,IAAI,IAAI;IAQlB,OAAO,IAAI,IAAI;IAqBf,WAAW,IAAI,OAAO;CAGvB"}
@@ -0,0 +1,152 @@
1
+ import * as Y from 'yjs';
2
+ import { base64Decode, base64Encode } from './collabUtils.js';
3
+ export class CollabClient {
4
+ ydoc;
5
+ docId;
6
+ connected = false;
7
+ destroyed = false;
8
+ pendingUpdates = [];
9
+ onPeersChange = null;
10
+ transport;
11
+ // Event listener cleanup references
12
+ updateHandler = null;
13
+ awarenessHandler = null;
14
+ peersHandler = null;
15
+ reconnectHandler = null;
16
+ constructor(docId, transport) {
17
+ this.docId = docId;
18
+ this.transport = transport;
19
+ this.ydoc = new Y.Doc();
20
+ // Listen for local Yjs updates
21
+ this.ydoc.on('update', (update, origin) => {
22
+ if (origin === 'remote')
23
+ return;
24
+ this.handleLocalUpdate(update);
25
+ });
26
+ // Listen for remote events from WebSocket (dispatched as CustomEvents on window)
27
+ this.updateHandler = (event) => {
28
+ const msg = event.detail;
29
+ if (msg.docId !== this.docId)
30
+ return;
31
+ try {
32
+ const update = base64Decode(msg.update);
33
+ Y.applyUpdate(this.ydoc, update, 'remote');
34
+ }
35
+ catch (error) {
36
+ console.error('[Collab] Failed to apply remote update', error);
37
+ }
38
+ };
39
+ this.awarenessHandler = (event) => {
40
+ const msg = event.detail;
41
+ if (msg.docId !== this.docId)
42
+ return;
43
+ // Awareness is handled at a higher level if needed
44
+ };
45
+ this.peersHandler = (event) => {
46
+ const msg = event.detail;
47
+ if (msg.docId !== this.docId)
48
+ return;
49
+ this.onPeersChange?.(msg.peerIds);
50
+ };
51
+ this.reconnectHandler = (event) => {
52
+ const detail = event.detail;
53
+ if (detail.state === 'connected' && detail.wasReconnect) {
54
+ this.connected = false;
55
+ void this.connect();
56
+ }
57
+ };
58
+ window.addEventListener('collab:update', this.updateHandler);
59
+ window.addEventListener('collab:awareness', this.awarenessHandler);
60
+ window.addEventListener('collab:peers', this.peersHandler);
61
+ window.addEventListener('ws-connection-state', this.reconnectHandler);
62
+ }
63
+ setTransport(transport) {
64
+ this.transport = transport;
65
+ }
66
+ setPeersCallback(cb) {
67
+ this.onPeersChange = cb;
68
+ }
69
+ async connect() {
70
+ if (this.destroyed || this.connected || !this.transport)
71
+ return;
72
+ try {
73
+ const stateVector = Y.encodeStateVector(this.ydoc);
74
+ const input = {
75
+ docId: this.docId,
76
+ stateVector: base64Encode(stateVector),
77
+ };
78
+ const response = (await this.transport.send('collab:join', input));
79
+ if (this.destroyed)
80
+ return;
81
+ if (response.update) {
82
+ const update = base64Decode(response.update);
83
+ Y.applyUpdate(this.ydoc, update, 'remote');
84
+ }
85
+ this.connected = true;
86
+ if (response.peerIds) {
87
+ this.onPeersChange?.(response.peerIds);
88
+ }
89
+ // Flush pending updates
90
+ for (const update of this.pendingUpdates) {
91
+ this.sendUpdate(update);
92
+ }
93
+ this.pendingUpdates = [];
94
+ }
95
+ catch (error) {
96
+ console.error('[Collab] Failed to join', error);
97
+ }
98
+ }
99
+ handleLocalUpdate(update) {
100
+ if (this.destroyed)
101
+ return;
102
+ if (this.connected) {
103
+ this.sendUpdate(update);
104
+ }
105
+ else {
106
+ this.pendingUpdates.push(update);
107
+ if (this.pendingUpdates.length > 1000) {
108
+ const merged = Y.mergeUpdatesV2(this.pendingUpdates);
109
+ this.pendingUpdates = [merged];
110
+ }
111
+ }
112
+ }
113
+ sendUpdate(update) {
114
+ if (!this.transport)
115
+ return;
116
+ this.transport.emit('collab:update', {
117
+ docId: this.docId,
118
+ update: base64Encode(update),
119
+ });
120
+ }
121
+ disconnect() {
122
+ if (!this.connected)
123
+ return;
124
+ if (this.transport) {
125
+ this.transport.emit('collab:leave', { docId: this.docId });
126
+ }
127
+ this.connected = false;
128
+ }
129
+ destroy() {
130
+ if (this.destroyed)
131
+ return;
132
+ this.destroyed = true;
133
+ this.disconnect();
134
+ if (this.updateHandler) {
135
+ window.removeEventListener('collab:update', this.updateHandler);
136
+ }
137
+ if (this.awarenessHandler) {
138
+ window.removeEventListener('collab:awareness', this.awarenessHandler);
139
+ }
140
+ if (this.peersHandler) {
141
+ window.removeEventListener('collab:peers', this.peersHandler);
142
+ }
143
+ if (this.reconnectHandler) {
144
+ window.removeEventListener('ws-connection-state', this.reconnectHandler);
145
+ }
146
+ this.ydoc.destroy();
147
+ }
148
+ isConnected() {
149
+ return this.connected;
150
+ }
151
+ }
152
+ //# sourceMappingURL=CollabProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollabProvider.js","sourceRoot":"","sources":["../../../src/collab/client/CollabProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function base64Encode(data: Uint8Array): string;
2
+ export declare function base64Decode(base64: string): Uint8Array;
3
+ //# sourceMappingURL=collabUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collabUtils.d.ts","sourceRoot":"","sources":["../../../src/collab/client/collabUtils.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMrD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAOvD"}
@@ -0,0 +1,17 @@
1
+ // Base64 encode/decode for Yjs binary data (browser-safe)
2
+ export function base64Encode(data) {
3
+ let binary = '';
4
+ for (let i = 0; i < data.length; i++) {
5
+ binary += String.fromCharCode(data[i]);
6
+ }
7
+ return btoa(binary);
8
+ }
9
+ export function base64Decode(base64) {
10
+ const binary = atob(base64);
11
+ const data = new Uint8Array(binary.length);
12
+ for (let i = 0; i < binary.length; i++) {
13
+ data[i] = binary.charCodeAt(i);
14
+ }
15
+ return data;
16
+ }
17
+ //# sourceMappingURL=collabUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collabUtils.js","sourceRoot":"","sources":["../../../src/collab/client/collabUtils.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,MAAM,UAAU,YAAY,CAAC,IAAgB;IAC3C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { CollabClient, type CollabTransport } from './CollabProvider.js';
2
+ export { useCollab, type UseCollabOptions, type UseCollabResult } from './useCollab.js';
3
+ export { base64Encode, base64Decode } from './collabUtils.js';
4
+ export type { CollabJoinInput, CollabSyncOutput, CollabUpdateMessage, CollabAwarenessMessage, CollabLeaveInput, CollabPeersMessage, CollabDocState, } from '../shared/CollabTypes.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collab/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACf,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { CollabClient } from './CollabProvider.js';
2
+ export { useCollab } from './useCollab.js';
3
+ export { base64Encode, base64Decode } from './collabUtils.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/collab/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwB,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,SAAS,EAA+C,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { CollabClient, type CollabTransport } from './CollabProvider.js';
2
+ export interface UseCollabOptions {
3
+ docId: string;
4
+ enabled: boolean;
5
+ transport: CollabTransport | null;
6
+ }
7
+ export interface UseCollabResult {
8
+ provider: CollabClient | null;
9
+ ydoc: CollabClient['ydoc'] | null;
10
+ peerIds: string[];
11
+ connected: boolean;
12
+ }
13
+ export declare function useCollab(options: UseCollabOptions): UseCollabResult;
14
+ //# sourceMappingURL=useCollab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCollab.d.ts","sourceRoot":"","sources":["../../../src/collab/client/useCollab.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAuCpE"}
@@ -0,0 +1,38 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { CollabClient } from './CollabProvider.js';
3
+ export function useCollab(options) {
4
+ const { docId, enabled, transport } = options;
5
+ const [provider, setProvider] = useState(null);
6
+ const [peerIds, setPeerIds] = useState([]);
7
+ const [connected, setConnected] = useState(false);
8
+ const providerRef = useRef(null);
9
+ useEffect(() => {
10
+ if (!enabled || !docId)
11
+ return;
12
+ const client = new CollabClient(docId, transport);
13
+ providerRef.current = client;
14
+ client.setPeersCallback((newPeerIds) => {
15
+ setPeerIds(newPeerIds);
16
+ });
17
+ void client.connect().then(() => {
18
+ if (client.isConnected()) {
19
+ setProvider(client);
20
+ setConnected(true);
21
+ }
22
+ });
23
+ return () => {
24
+ client.destroy();
25
+ providerRef.current = null;
26
+ setProvider(null);
27
+ setPeerIds([]);
28
+ setConnected(false);
29
+ };
30
+ }, [docId, enabled, transport]);
31
+ return {
32
+ provider,
33
+ ydoc: provider?.ydoc ?? null,
34
+ peerIds,
35
+ connected,
36
+ };
37
+ }
38
+ //# sourceMappingURL=useCollab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCollab.js","sourceRoot":"","sources":["../../../src/collab/client/useCollab.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,YAAY,EAAwB,MAAM,qBAAqB,CAAC;AAezE,MAAM,UAAU,SAAS,CAAC,OAAyB;IACjD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC,CAAC;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK;YAAE,OAAO;QAE/B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClD,WAAW,CAAC,OAAO,GAAG,MAAM,CAAC;QAE7B,MAAM,CAAC,gBAAgB,CAAC,CAAC,UAAU,EAAE,EAAE;YACrC,UAAU,CAAC,UAAU,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;gBACzB,WAAW,CAAC,MAAM,CAAC,CAAC;gBACpB,YAAY,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YAC3B,WAAW,CAAC,IAAI,CAAC,CAAC;YAClB,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAEhC,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,QAAQ,EAAE,IAAI,IAAI,IAAI;QAC5B,OAAO;QACP,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type WebSocket from 'ws';
2
+ import * as Y from 'yjs';
3
+ import type { CollabDocState } from '../shared/CollabTypes.js';
4
+ export interface CollabConfig {
5
+ /**
6
+ * Load the current Yjs state for a document.
7
+ * Return the base64-encoded yjsState string, or null if no state exists.
8
+ */
9
+ loadState(docId: string): Promise<string | null>;
10
+ /**
11
+ * Persist the Yjs state for a document.
12
+ * Called with the full base64-encoded state and a serialized content string
13
+ * (if a serialize callback is provided).
14
+ */
15
+ saveState(docId: string, collabState: CollabDocState, serialized: string | null): Promise<void>;
16
+ /**
17
+ * Optional: Initialize a Yjs doc from existing content when no collab state
18
+ * exists yet. Called with an empty Y.Doc — the implementation should populate it.
19
+ */
20
+ initializeDoc?(ydoc: Y.Doc, docId: string): Promise<void>;
21
+ /**
22
+ * Optional: Serialize a Yjs doc to a string for persistence alongside the
23
+ * binary Yjs state. Useful for maintaining a searchable/readable representation.
24
+ */
25
+ serialize?(ydoc: Y.Doc): string;
26
+ /**
27
+ * Optional: Called when an error occurs. Defaults to console.error.
28
+ */
29
+ onError?(message: string, error: unknown, context?: Record<string, unknown>): void;
30
+ /** Debounce interval for persistence in ms. Default: 3000 */
31
+ persistDebounceMs?: number;
32
+ /** Max wait before forced persistence in ms. Default: 30000 */
33
+ persistMaxWaitMs?: number;
34
+ /** Idle timeout before unloading a document in ms. Default: 300000 (5 min) */
35
+ idleCleanupMs?: number;
36
+ }
37
+ /**
38
+ * Manages collaborative editing for multiple documents using Yjs CRDTs.
39
+ * Cross-server sync via NATS, debounced persistence, idle cleanup.
40
+ */
41
+ export declare class CollabServer {
42
+ private readonly config;
43
+ private readonly activeDocuments;
44
+ private readonly socketDocs;
45
+ constructor(config: CollabConfig);
46
+ private logError;
47
+ private loadDocument;
48
+ private unloadDocument;
49
+ private schedulePersist;
50
+ private persistDocument;
51
+ private broadcastToLocalPeers;
52
+ private broadcastPeerList;
53
+ join(ws: WebSocket, docId: string, userId: string, stateVector: string, messageId: string | undefined): Promise<void>;
54
+ handleUpdate(docId: string, userId: string, update: string): void;
55
+ handleAwareness(docId: string, userId: string, states: string): void;
56
+ leave(ws: WebSocket, docId: string, userId: string): void;
57
+ cleanupSocket(ws: WebSocket, userId: string): void;
58
+ /**
59
+ * Returns a socket message handler suitable for use with
60
+ * `configurator.addSocketMessageHandler()`.
61
+ */
62
+ createSocketHandler(): (ws: WebSocket, userId: string, msg: unknown) => boolean;
63
+ }
64
+ //# sourceMappingURL=CollabServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollabServer.d.ts","sourceRoot":"","sources":["../../../src/collab/server/CollabServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAChC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAIzB,OAAO,KAAK,EAEV,cAAc,EAIf,MAAM,0BAA0B,CAAC;AAIlC,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEjD;;;;OAIG;IACH,SAAS,CACP,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,cAAc,EAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;OAGG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC;IAEhC;;OAEG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEnF,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwDD;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGR;IAEf,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqC;gBAEpD,MAAM,EAAE,YAAY;IAShC,OAAO,CAAC,QAAQ;YAUF,YAAY;YA6GZ,cAAc;IAoB5B,OAAO,CAAC,eAAe;YAeT,eAAe;IA0C7B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,iBAAiB;IAQnB,IAAI,CACR,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,IAAI,CAAC;IA2ChB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAyBjE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBpE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAoCzD,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUlD;;;OAGG;IACH,mBAAmB,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO;CAoChF"}