@adonis-agora/collaboration 0.1.1

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 (75) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/configure.d.ts +10 -0
  3. package/dist/configure.d.ts.map +1 -0
  4. package/dist/configure.js +16 -0
  5. package/dist/configure.js.map +1 -0
  6. package/dist/providers/collaboration_provider.d.ts +18 -0
  7. package/dist/providers/collaboration_provider.d.ts.map +1 -0
  8. package/dist/providers/collaboration_provider.js +65 -0
  9. package/dist/providers/collaboration_provider.js.map +1 -0
  10. package/dist/src/collaboration_manager.d.ts +34 -0
  11. package/dist/src/collaboration_manager.d.ts.map +1 -0
  12. package/dist/src/collaboration_manager.js +59 -0
  13. package/dist/src/collaboration_manager.js.map +1 -0
  14. package/dist/src/define_config.d.ts +20 -0
  15. package/dist/src/define_config.d.ts.map +1 -0
  16. package/dist/src/define_config.js +8 -0
  17. package/dist/src/define_config.js.map +1 -0
  18. package/dist/src/driver.d.ts +49 -0
  19. package/dist/src/driver.d.ts.map +1 -0
  20. package/dist/src/driver.js +2 -0
  21. package/dist/src/driver.js.map +1 -0
  22. package/dist/src/drivers/automerge/automerge_driver.d.ts +30 -0
  23. package/dist/src/drivers/automerge/automerge_driver.d.ts.map +1 -0
  24. package/dist/src/drivers/automerge/automerge_driver.js +209 -0
  25. package/dist/src/drivers/automerge/automerge_driver.js.map +1 -0
  26. package/dist/src/drivers/yjs/yjs_driver.d.ts +30 -0
  27. package/dist/src/drivers/yjs/yjs_driver.d.ts.map +1 -0
  28. package/dist/src/drivers/yjs/yjs_driver.js +232 -0
  29. package/dist/src/drivers/yjs/yjs_driver.js.map +1 -0
  30. package/dist/src/index.d.ts +9 -0
  31. package/dist/src/index.d.ts.map +1 -0
  32. package/dist/src/index.js +8 -0
  33. package/dist/src/index.js.map +1 -0
  34. package/dist/src/services/booted_app.d.ts +10 -0
  35. package/dist/src/services/booted_app.d.ts.map +1 -0
  36. package/dist/src/services/booted_app.js +42 -0
  37. package/dist/src/services/booted_app.js.map +1 -0
  38. package/dist/src/services/comment_service.d.ts +17 -0
  39. package/dist/src/services/comment_service.d.ts.map +1 -0
  40. package/dist/src/services/comment_service.js +53 -0
  41. package/dist/src/services/comment_service.js.map +1 -0
  42. package/dist/src/services/main.d.ts +6 -0
  43. package/dist/src/services/main.d.ts.map +1 -0
  44. package/dist/src/services/main.js +29 -0
  45. package/dist/src/services/main.js.map +1 -0
  46. package/dist/src/services/presence_service.d.ts +44 -0
  47. package/dist/src/services/presence_service.d.ts.map +1 -0
  48. package/dist/src/services/presence_service.js +103 -0
  49. package/dist/src/services/presence_service.js.map +1 -0
  50. package/dist/src/storage/file_system_storage.d.ts +24 -0
  51. package/dist/src/storage/file_system_storage.d.ts.map +1 -0
  52. package/dist/src/storage/file_system_storage.js +83 -0
  53. package/dist/src/storage/file_system_storage.js.map +1 -0
  54. package/dist/src/storage/in_memory_storage.d.ts +22 -0
  55. package/dist/src/storage/in_memory_storage.d.ts.map +1 -0
  56. package/dist/src/storage/in_memory_storage.js +50 -0
  57. package/dist/src/storage/in_memory_storage.js.map +1 -0
  58. package/dist/src/storage/lucid_storage.d.ts +41 -0
  59. package/dist/src/storage/lucid_storage.d.ts.map +1 -0
  60. package/dist/src/storage/lucid_storage.js +176 -0
  61. package/dist/src/storage/lucid_storage.js.map +1 -0
  62. package/dist/src/types.d.ts +121 -0
  63. package/dist/src/types.d.ts.map +1 -0
  64. package/dist/src/types.js +11 -0
  65. package/dist/src/types.js.map +1 -0
  66. package/dist/src/versioning.d.ts +9 -0
  67. package/dist/src/versioning.d.ts.map +1 -0
  68. package/dist/src/versioning.js +19 -0
  69. package/dist/src/versioning.js.map +1 -0
  70. package/dist/stubs/config/collaboration.stub +39 -0
  71. package/dist/stubs/main.d.ts +3 -0
  72. package/dist/stubs/main.d.ts.map +1 -0
  73. package/dist/stubs/main.js +4 -0
  74. package/dist/stubs/main.js.map +1 -0
  75. package/package.json +124 -0
@@ -0,0 +1,30 @@
1
+ import type { CollaborationDriver } from '../../driver.js';
2
+ import type { CollabComment, CollabDiffSummary, CollabVersion, CollaborationConfig } from '../../types.js';
3
+ export declare class YjsDriver implements CollaborationDriver {
4
+ #private;
5
+ readonly engine = "yjs";
6
+ private hocuspocus;
7
+ private wss?;
8
+ private config;
9
+ private commentsService;
10
+ constructor(config: CollaborationConfig);
11
+ private liveDoc;
12
+ private hydrate;
13
+ private ensureDoc;
14
+ attach(server: import('node:http').Server): Promise<void>;
15
+ getDocumentState(docName: string): Promise<Uint8Array>;
16
+ getDocumentText(docName: string): Promise<string>;
17
+ createVersion(docName: string, createdBy: string | null, label: string | null): Promise<CollabVersion>;
18
+ listVersions(docName: string): Promise<CollabVersion[]>;
19
+ restoreVersion(docName: string, versionId: string, restoredBy: string | null): Promise<void>;
20
+ diffVersions(docName: string, aId: string, bId: string): Promise<CollabDiffSummary>;
21
+ private versionState;
22
+ listComments(docName: string, space?: string): Promise<CollabComment[]>;
23
+ createComment(docName: string, comment: Omit<CollabComment, 'id' | 'createdAt' | 'updatedAt' | 'resolvedAt'>): Promise<CollabComment>;
24
+ resolveComment(docName: string, commentId: string, resolved: boolean): Promise<CollabComment | null>;
25
+ deleteComment(docName: string, commentId: string): Promise<boolean>;
26
+ close(): Promise<void>;
27
+ }
28
+ /** Converte o JSON Tiptap em texto plano (\n\n entre blocos). */
29
+ export declare function tiptapJsonToText(node: Record<string, unknown> | null): string;
30
+ //# sourceMappingURL=yjs_driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yjs_driver.d.ts","sourceRoot":"","sources":["../../../../src/drivers/yjs/yjs_driver.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EAEjB,aAAa,EACb,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAkBxB,qBAAa,SAAU,YAAW,mBAAmB;;IACnD,QAAQ,CAAC,MAAM,SAAS;IAExB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAkB;IAC9B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,eAAe,CAAiB;gBAY5B,MAAM,EAAE,mBAAmB;IA6BvC,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;YAQD,SAAS;IAQjB,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBzD,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAStD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAajD,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,aAAa,CAAC;IASnB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIvD,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,IAAI,CAAC;IAgBV,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAY3E,YAAY;IAQpB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIvE,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC,GAC5E,OAAO,CAAC,aAAa,CAAC;IAInB,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAI1B,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAInE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS7B;AAYD,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,CAuB7E"}
@@ -0,0 +1,232 @@
1
+ import { Hocuspocus } from '@hocuspocus/server';
2
+ import { TiptapTransformer } from '@hocuspocus/transformer';
3
+ import { WebSocketServer } from 'ws';
4
+ import * as Y from 'yjs';
5
+ import { CommentService } from '../../services/comment_service.js';
6
+ import { InMemoryCollaborationStorage } from '../../storage/in_memory_storage.js';
7
+ import { createVersionMetadata, seqVersions } from '../../versioning.js';
8
+ /**
9
+ * Driver Yjs: Hocuspocus como engine de sync (protocolo y-protocols sobre
10
+ * WebSocket), com version control implementado em cima de updates binários
11
+ * completos — o que o Automerge tem nativo (history) a gente provê aqui:
12
+ *
13
+ * - `createVersion`: guarda o update binário completo + metadados;
14
+ * - `restoreVersion`: aplica o conteúdo da versão no doc vivo via transação
15
+ * — clientes conectados recebem em tempo real pelo protocolo de sync;
16
+ * - `diffVersions`: materializa as duas versões e compara por linha.
17
+ * - Comentários ancorados: delegam pro CommentService (anchor genérica).
18
+ */
19
+ /** Permissões por conexão (userId:docName), preenchidas no authenticate. */
20
+ const permissions = new Map();
21
+ export class YjsDriver {
22
+ engine = 'yjs';
23
+ hocuspocus;
24
+ wss;
25
+ config;
26
+ commentsService;
27
+ #memoryStorage;
28
+ /** Storage configurado ou in-memory (dev). */
29
+ #storage() {
30
+ if (this.config.storage) {
31
+ return this.config.storage;
32
+ }
33
+ this.#memoryStorage ??= new InMemoryCollaborationStorage();
34
+ return this.#memoryStorage;
35
+ }
36
+ constructor(config) {
37
+ this.config = config;
38
+ this.commentsService = new CommentService(config.storage ?? new InMemoryCollaborationStorage());
39
+ // Capturados fora do callback: o `this` dentro dos hooks do Hocuspocus
40
+ // não é a instância do driver.
41
+ const storage = () => this.#storage();
42
+ this.hocuspocus = new Hocuspocus({
43
+ async onAuthenticate({ documentName, token }) {
44
+ const ctx = JSON.parse(Buffer.from(token, 'base64').toString());
45
+ const permission = await config.authorize(ctx, documentName);
46
+ if (!permission.canRead) {
47
+ throw new Error('Sem acesso a este documento');
48
+ }
49
+ permissions.set(`${ctx.userId}:${documentName}`, permission);
50
+ },
51
+ async onStoreDocument({ documentName, document }) {
52
+ await storage().saveDocument(documentName, Y.encodeStateAsUpdate(document));
53
+ },
54
+ debounce: config.debounce ?? 2000,
55
+ });
56
+ }
57
+ liveDoc(name) {
58
+ // Document do Hocuspocus estende Y.Doc diretamente.
59
+ return this.hocuspocus.documents.get(name);
60
+ }
61
+ hydrate(state) {
62
+ const doc = new Y.Doc();
63
+ if (state.byteLength > 0) {
64
+ Y.applyUpdate(doc, state);
65
+ }
66
+ return doc;
67
+ }
68
+ async ensureDoc(name) {
69
+ const existing = this.liveDoc(name);
70
+ if (existing)
71
+ return existing;
72
+ const stored = await this.#storage().loadDocument(name);
73
+ return this.hydrate(stored?.state ?? new Uint8Array());
74
+ }
75
+ async attach(server) {
76
+ const path = this.config.path ?? '/collaboration';
77
+ const wss = new WebSocketServer({ noServer: true });
78
+ this.wss = wss;
79
+ server.on('upgrade', (request, socket, head) => {
80
+ const parsed = new URL(request.url ?? '/', 'http://localhost');
81
+ if (parsed.pathname !== path)
82
+ return;
83
+ wss.handleUpgrade(request, socket, head, (ws) => {
84
+ // O Hocuspocus espera um Request da Fetch API; convertemos o
85
+ // IncomingMessage do node pra um Request mínimo com a URL real.
86
+ const fetchRequest = new Request(parsed, {
87
+ headers: request.headers,
88
+ });
89
+ this.hocuspocus.handleConnection(ws, fetchRequest);
90
+ });
91
+ });
92
+ }
93
+ async getDocumentState(docName) {
94
+ const live = this.liveDoc(docName);
95
+ if (live) {
96
+ return Y.encodeStateAsUpdate(live);
97
+ }
98
+ const stored = await this.#storage().loadDocument(docName);
99
+ return stored?.state ?? new Uint8Array();
100
+ }
101
+ async getDocumentText(docName) {
102
+ const doc = await this.ensureDoc(docName);
103
+ try {
104
+ const json = TiptapTransformer.fromYdoc(doc);
105
+ const defaultDoc = json.default ?? json;
106
+ return tiptapJsonToText(defaultDoc);
107
+ }
108
+ catch {
109
+ // Doc vazio ou fora do layout Tiptap.
110
+ return '';
111
+ }
112
+ }
113
+ async createVersion(docName, createdBy, label) {
114
+ const doc = await this.ensureDoc(docName);
115
+ const existing = await this.#storage().listVersions(docName);
116
+ const version = createVersionMetadata(createdBy, label, seqVersions(existing));
117
+ await this.#storage().saveVersion(docName, version, Y.encodeStateAsUpdate(doc));
118
+ return version;
119
+ }
120
+ async listVersions(docName) {
121
+ return this.#storage().listVersions(docName);
122
+ }
123
+ async restoreVersion(docName, versionId, restoredBy) {
124
+ void restoredBy;
125
+ const state = await this.versionState(docName, versionId);
126
+ const restoredDoc = this.hydrate(state);
127
+ // Aplica o conteúdo restaurado no doc vivo — clientes conectados recebem
128
+ // a mudança em tempo real via protocolo de sync do Hocuspocus.
129
+ const live = await this.ensureDoc(docName);
130
+ live.transact(() => {
131
+ applyRestoredContent(live, restoredDoc);
132
+ });
133
+ await this.#storage().saveDocument(docName, Y.encodeStateAsUpdate(live));
134
+ }
135
+ async diffVersions(docName, aId, bId) {
136
+ const [aState, bState] = await Promise.all([
137
+ this.versionState(docName, aId),
138
+ this.versionState(docName, bId),
139
+ ]);
140
+ const textA = tiptapJsonToText(safeTiptapFromYdoc(this.hydrate(aState)));
141
+ const textB = tiptapJsonToText(safeTiptapFromYdoc(this.hydrate(bState)));
142
+ return simpleLineDiff(textA, textB);
143
+ }
144
+ async versionState(docName, versionId) {
145
+ const persisted = await this.#storage().loadVersionSnapshot(docName, versionId);
146
+ if (!persisted)
147
+ throw new Error(`Versão ${versionId} não encontrada`);
148
+ return persisted;
149
+ }
150
+ /* ───────────────────────── comentários ancorados ───────────────────────── */
151
+ async listComments(docName, space) {
152
+ return this.commentsService.list(docName, space);
153
+ }
154
+ async createComment(docName, comment) {
155
+ return this.commentsService.create(docName, comment);
156
+ }
157
+ async resolveComment(docName, commentId, resolved) {
158
+ return this.commentsService.resolve(docName, commentId, resolved);
159
+ }
160
+ async deleteComment(docName, commentId) {
161
+ return this.commentsService.remove(docName, commentId);
162
+ }
163
+ async close() {
164
+ // Persiste docs pendentes e fecha conexões (a classe Hocuspocus não tem
165
+ // destroy — o Server embutido é que tem).
166
+ this.hocuspocus.flushPendingStores();
167
+ this.hocuspocus.closeConnections();
168
+ return new Promise((resolve) => {
169
+ this.wss?.close(() => resolve());
170
+ });
171
+ }
172
+ }
173
+ /* ───────────────────────── helpers locais ───────────────────────── */
174
+ function safeTiptapFromYdoc(doc) {
175
+ try {
176
+ return TiptapTransformer.fromYdoc(doc);
177
+ }
178
+ catch {
179
+ return {};
180
+ }
181
+ }
182
+ /** Converte o JSON Tiptap em texto plano (\n\n entre blocos). */
183
+ export function tiptapJsonToText(node) {
184
+ if (!node || !Array.isArray(node.content))
185
+ return '';
186
+ let text = '';
187
+ const walk = (current) => {
188
+ if (current.type === 'text' && typeof current.text === 'string') {
189
+ text += current.text;
190
+ return;
191
+ }
192
+ if (Array.isArray(current.content)) {
193
+ for (const child of current.content) {
194
+ walk(child);
195
+ }
196
+ }
197
+ if (typeof current.type === 'string' &&
198
+ ['paragraph', 'heading', 'blockquote', 'codeBlock', 'listItem'].includes(current.type)) {
199
+ text += '\n\n';
200
+ }
201
+ };
202
+ walk(node);
203
+ return text.trimEnd();
204
+ }
205
+ /** Diff por linha simples o suficiente pra resumo (+adicionadas / -removidas). */
206
+ function simpleLineDiff(a, b) {
207
+ const linesA = new Set(a.split('\n'));
208
+ const linesB = new Set(b.split('\n'));
209
+ let added = 0;
210
+ for (const line of linesB) {
211
+ if (!linesA.has(line))
212
+ added++;
213
+ }
214
+ let removed = 0;
215
+ for (const line of linesA) {
216
+ if (!linesB.has(line))
217
+ removed++;
218
+ }
219
+ return { added, removed };
220
+ }
221
+ /**
222
+ * Substitui o conteúdo do doc vivo aplicando o update completo do doc
223
+ * restaurado (merge CRDT é idempotente; o delete anterior remove o estado
224
+ * divergente e o update traz o conteúdo antigo de volta).
225
+ */
226
+ function applyRestoredContent(live, restored) {
227
+ const liveFragment = live.getXmlFragment('default');
228
+ liveFragment.delete(0, liveFragment.length);
229
+ const update = Y.encodeStateAsUpdate(restored);
230
+ Y.applyUpdate(live, update);
231
+ }
232
+ //# sourceMappingURL=yjs_driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yjs_driver.js","sourceRoot":"","sources":["../../../../src/drivers/yjs/yjs_driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { CollaborationManager } from './collaboration_manager.js';
2
+ export { YjsDriver } from './drivers/yjs/yjs_driver.js';
3
+ export { AutomergeDriver } from './drivers/automerge/automerge_driver.js';
4
+ export { CommentService } from './services/comment_service.js';
5
+ export { PresenceService, type PresenceMember } from './services/presence_service.js';
6
+ export { LucidStorage } from './storage/lucid_storage.js';
7
+ export { defineConfig, type CollaborationAppConfig, } from './define_config.js';
8
+ export type { CollabComment, CommentAnchor, CollaborationEngine, CollaborationConfig, CollaborationStorage, CollabConnectionContext, CollabPermission, CollabVersion, CollabDiffSummary, } from './types.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,YAAY,EACZ,KAAK,sBAAsB,GAC5B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { CollaborationManager } from './collaboration_manager.js';
2
+ export { YjsDriver } from './drivers/yjs/yjs_driver.js';
3
+ export { AutomergeDriver } from './drivers/automerge/automerge_driver.js';
4
+ export { CommentService } from './services/comment_service.js';
5
+ export { PresenceService } from './services/presence_service.js';
6
+ export { LucidStorage } from './storage/lucid_storage.js';
7
+ export { defineConfig, } from './define_config.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAuB,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,YAAY,GAEb,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /** Record the booted app. Called once by the provider during `register()`. */
3
+ export declare function setBootedApp(app: ApplicationService): void;
4
+ /**
5
+ * Resolves with the provider-captured booted app. `services/main` awaits this (instead of importing
6
+ * `@adonisjs/core/services/app`) before reading the container, so its eager population is driven by
7
+ * the SAME app copy `bin/server` booted.
8
+ */
9
+ export declare function whenBootedApp(timeoutMs?: number): Promise<ApplicationService>;
10
+ //# sourceMappingURL=booted_app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"booted_app.d.ts","sourceRoot":"","sources":["../../../src/services/booted_app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAkB/D,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAI1D;AAKD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,SAAS,SAAgC,GACxC,OAAO,CAAC,kBAAkB,CAAC,CAc7B"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The booted {@link ApplicationService}, captured by `CollaborationProvider.register()` — which the
3
+ * application instantiates with its OWN booted app instance.
4
+ *
5
+ * Why capture it here instead of `import app from '@adonisjs/core/services/app'`: in a pnpm
6
+ * (workspace / hoisted) install this package can resolve a DIFFERENT physical copy of
7
+ * `@adonisjs/core` than the one `bin/server` booted. The instance the provider RECEIVES is always
8
+ * the booted one, so reading it here is immune to a core copy / peer-variant split.
9
+ * Mirrors `@adonis-agora/durable`'s `booted_app`.
10
+ */
11
+ let bootedApp;
12
+ let resolveBootedApp;
13
+ const bootedAppPromise = new Promise((resolve) => {
14
+ resolveBootedApp = resolve;
15
+ });
16
+ /** Record the booted app. Called once by the provider during `register()`. */
17
+ export function setBootedApp(app) {
18
+ if (bootedApp)
19
+ return;
20
+ bootedApp = app;
21
+ resolveBootedApp(app);
22
+ }
23
+ /** Default window `whenBootedApp` waits for the provider before rejecting. */
24
+ const DEFAULT_BOOTED_APP_TIMEOUT_MS = 5_000;
25
+ /**
26
+ * Resolves with the provider-captured booted app. `services/main` awaits this (instead of importing
27
+ * `@adonisjs/core/services/app`) before reading the container, so its eager population is driven by
28
+ * the SAME app copy `bin/server` booted.
29
+ */
30
+ export function whenBootedApp(timeoutMs = DEFAULT_BOOTED_APP_TIMEOUT_MS) {
31
+ if (bootedApp)
32
+ return Promise.resolve(bootedApp);
33
+ setTimeout(() => {
34
+ resolveBootedApp({
35
+ get booted() {
36
+ throw new Error('@adonis-agora/collaboration: services/main aguardando boot — instale o provider com `node ace configure @adonis-agora/collaboration`');
37
+ },
38
+ });
39
+ }, timeoutMs);
40
+ return bootedAppPromise;
41
+ }
42
+ //# sourceMappingURL=booted_app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"booted_app.js","sourceRoot":"","sources":["../../../src/services/booted_app.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,IAAI,SAAyC,CAAC;AAC9C,IAAI,gBAAmD,CAAC;AACxD,MAAM,gBAAgB,GAAG,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;IACnE,gBAAgB,GAAG,OAAO,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,GAAuB;IAClD,IAAI,SAAS;QAAE,OAAO;IACtB,SAAS,GAAG,GAAG,CAAC;IAChB,gBAAgB,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,8EAA8E;AAC9E,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAS,GAAG,6BAA6B;IAEzC,IAAI,SAAS;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEjD,UAAU,CAAC,GAAG,EAAE;QACd,gBAAgB,CAAC;YACf,IAAI,MAAM;gBACR,MAAM,IAAI,KAAK,CACb,sIAAsI,CACvI,CAAC;YACJ,CAAC;SAC+B,CAAC,CAAC;IACtC,CAAC,EAAE,SAAS,CAAC,CAAC;IAEd,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { CollabComment, CollaborationStorage } from '../types.js';
2
+ /**
3
+ * Serviço de comentários ancorados — genérico por tipo de conteúdo.
4
+ *
5
+ * A lib é dona do lifecycle (criar, resolver/reabrir, remover) e da âncora
6
+ * (CommentAnchor). Quem interpreta a âncora é o resolver do app — a lib não
7
+ * sabe o que é um canvas tldraw nem offsets de texto; só persiste e ordena.
8
+ */
9
+ export declare class CommentService {
10
+ private storage;
11
+ constructor(storage: CollaborationStorage);
12
+ list(docName: string, space?: string): Promise<CollabComment[]>;
13
+ create(docName: string, comment: Omit<CollabComment, 'id' | 'createdAt' | 'updatedAt' | 'resolvedAt'>): Promise<CollabComment>;
14
+ resolve(docName: string, commentId: string, resolved: boolean): Promise<CollabComment | null>;
15
+ remove(docName: string, commentId: string): Promise<boolean>;
16
+ }
17
+ //# sourceMappingURL=comment_service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment_service.d.ts","sourceRoot":"","sources":["../../../src/services/comment_service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEvE;;;;;;GAMG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,oBAAoB;IAE3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAK/D,MAAM,CACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC,GAC5E,OAAO,CAAC,aAAa,CAAC;IAcnB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAc7F,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAOnE"}
@@ -0,0 +1,53 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /**
3
+ * Serviço de comentários ancorados — genérico por tipo de conteúdo.
4
+ *
5
+ * A lib é dona do lifecycle (criar, resolver/reabrir, remover) e da âncora
6
+ * (CommentAnchor). Quem interpreta a âncora é o resolver do app — a lib não
7
+ * sabe o que é um canvas tldraw nem offsets de texto; só persiste e ordena.
8
+ */
9
+ export class CommentService {
10
+ storage;
11
+ constructor(storage) {
12
+ this.storage = storage;
13
+ }
14
+ async list(docName, space) {
15
+ const comments = await this.storage.listComments(docName, space);
16
+ return comments.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
17
+ }
18
+ async create(docName, comment) {
19
+ const now = new Date().toISOString();
20
+ const created = {
21
+ ...comment,
22
+ documentName: docName,
23
+ id: randomUUID(),
24
+ resolvedAt: null,
25
+ createdAt: now,
26
+ updatedAt: null,
27
+ };
28
+ await this.storage.saveComment(docName, created);
29
+ return created;
30
+ }
31
+ async resolve(docName, commentId, resolved) {
32
+ const comments = await this.storage.listComments(docName);
33
+ const target = comments.find((comment) => comment.id === commentId);
34
+ if (!target)
35
+ return null;
36
+ const updated = {
37
+ ...target,
38
+ resolvedAt: resolved ? new Date().toISOString() : null,
39
+ updatedAt: new Date().toISOString(),
40
+ };
41
+ await this.storage.saveComment(docName, updated);
42
+ return updated;
43
+ }
44
+ async remove(docName, commentId) {
45
+ const comments = await this.storage.listComments(docName);
46
+ const exists = comments.some((comment) => comment.id === commentId);
47
+ if (!exists)
48
+ return false;
49
+ await this.storage.deleteComment(docName, commentId);
50
+ return true;
51
+ }
52
+ }
53
+ //# sourceMappingURL=comment_service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment_service.js","sourceRoot":"","sources":["../../../src/services/comment_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IACL;IAApB,YAAoB,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAErD,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,KAAc;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACjE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,MAAM,CACV,OAAe,EACf,OAA6E;QAE7E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,OAAO,GAAkB;YAC7B,GAAG,OAAO;YACV,YAAY,EAAE,OAAO;YACrB,EAAE,EAAE,UAAU,EAAE;YAChB,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,IAAI;SAChB,CAAC;QACF,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe,EAAE,SAAiB,EAAE,QAAiB;QACjE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,OAAO,GAAkB;YAC7B,GAAG,MAAM;YACT,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;YACtD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,SAAiB;QAC7C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import { CollaborationManager } from '../collaboration_manager.js';
2
+ declare const _default: {
3
+ readonly current: CollaborationManager;
4
+ };
5
+ export default _default;
6
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/services/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;;sBAyBlD,oBAAoB;;AADrC,wBASE"}
@@ -0,0 +1,29 @@
1
+ import { CollaborationManager } from '../collaboration_manager.js';
2
+ import { whenBootedApp } from './booted_app.js';
3
+ /**
4
+ * The singleton {@link CollaborationManager} — populated by
5
+ * `CollaborationProvider` from `config/collaboration.ts`.
6
+ *
7
+ * ```ts
8
+ * import collaboration from '@adonis-agora/collaboration/services/main'
9
+ *
10
+ * const text = await collaboration.getDocumentText('researches/<id>/writing')
11
+ * const version = await collaboration.createVersion(docName, userId, 'antes da revisão')
12
+ * ```
13
+ */
14
+ let manager;
15
+ const app = await whenBootedApp();
16
+ await app.booted(async () => {
17
+ const config = app.config.get('collaboration', {});
18
+ manager = await app.container.make(CollaborationManager);
19
+ void config;
20
+ });
21
+ export default {
22
+ get current() {
23
+ if (!manager) {
24
+ throw new Error('CollaborationManager ainda não inicializou — aguarde o boot do app ou instale o provider');
25
+ }
26
+ return manager;
27
+ },
28
+ };
29
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/services/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,IAAI,OAA6B,CAAC;AAElC,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;AAClC,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;IAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAyB,eAAe,EAAE,EAAW,CAAC,CAAC;IACpF,OAAO,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACzD,KAAK,MAAM,CAAC;AACd,CAAC,CAAC,CAAC;AAEH,eAAe;IACb,IAAI,OAAO;QACT,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Presença cross-instance da colaboração.
3
+ *
4
+ * Mesma filosofia do @adonisjs/transmit: cada instância conhece as conexões
5
+ * LOCAIS (em memória) e propaga eventos via Redis pub/sub pra que qualquer
6
+ * instância enxergue quem está online no documento inteiro — não só na
7
+ * instância que recebeu a conexão.
8
+ *
9
+ * Canal: `collab:presence` (payload identifica o docName).
10
+ * - heartbeat local → publish de join/leave;
11
+ * - subscriber atualiza o mapa agregado e notifica os callbacks.
12
+ */
13
+ export interface PresenceMember {
14
+ userId: string;
15
+ name?: string;
16
+ avatarUrl?: string | null;
17
+ /** Instância que segura a conexão (id do processo). */
18
+ instanceId: string;
19
+ }
20
+ type PresenceListener = (docName: string, members: PresenceMember[]) => void;
21
+ export declare class PresenceService {
22
+ private publisher?;
23
+ private subscriber?;
24
+ private localMembers;
25
+ private remoteMembers;
26
+ private listeners;
27
+ private instanceId;
28
+ private heartbeatTimer?;
29
+ constructor(redisUrl?: string);
30
+ /** Registra uma conexão local num documento. */
31
+ join(docName: string, member: Omit<PresenceMember, 'instanceId'>): Promise<void>;
32
+ leave(docName: string, userId: string): Promise<void>;
33
+ /** Membros conhecidos de um documento (locais + remotos via pub/sub). */
34
+ list(docName: string): PresenceMember[];
35
+ onPresenceChange(listener: PresenceListener): () => void;
36
+ close(): Promise<void>;
37
+ private localMap;
38
+ private publish;
39
+ private publishLocalHeartbeats;
40
+ private handleRemoteMessage;
41
+ private notify;
42
+ }
43
+ export {};
44
+ //# sourceMappingURL=presence_service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence_service.d.ts","sourceRoot":"","sources":["../../../src/services/presence_service.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;AAU7E,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAkD;IACtE,OAAO,CAAC,aAAa,CAAkD;IACvE,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,cAAc,CAAC,CAAiC;gBAE5C,QAAQ,CAAC,EAAE,MAAM;IAY7B,gDAAgD;IAC1C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhF,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3D,yEAAyE;IACzE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE;IAYvC,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAKlD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,OAAO,CAAC,QAAQ;YAIF,OAAO;YAKP,sBAAsB;IAQpC,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,MAAM;CAKf"}