@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,103 @@
1
+ import { Redis } from 'ioredis';
2
+ export class PresenceService {
3
+ publisher;
4
+ subscriber;
5
+ localMembers = new Map();
6
+ remoteMembers = new Map();
7
+ listeners = new Set();
8
+ instanceId = `${process.pid}-${randomHex(4)}`;
9
+ heartbeatTimer;
10
+ constructor(redisUrl) {
11
+ if (redisUrl) {
12
+ this.publisher = new Redis(redisUrl);
13
+ this.subscriber = new Redis(redisUrl);
14
+ void this.subscriber.subscribe('collab:presence');
15
+ this.subscriber.on('message', (_channel, message) => {
16
+ this.handleRemoteMessage(JSON.parse(message));
17
+ });
18
+ this.heartbeatTimer = setInterval(() => this.publishLocalHeartbeats(), 30_000);
19
+ }
20
+ }
21
+ /** Registra uma conexão local num documento. */
22
+ async join(docName, member) {
23
+ if (!this.localMembers.has(docName)) {
24
+ this.localMembers.set(docName, new Map());
25
+ }
26
+ const full = { ...member, instanceId: this.instanceId };
27
+ this.localMembers.get(docName).set(member.userId, full);
28
+ await this.publish({ kind: 'join', docName, member: full });
29
+ this.notify(docName);
30
+ }
31
+ async leave(docName, userId) {
32
+ const members = this.localMembers.get(docName);
33
+ members?.delete(userId);
34
+ await this.publish({ kind: 'leave', docName, userId, instanceId: this.instanceId });
35
+ this.notify(docName);
36
+ }
37
+ /** Membros conhecidos de um documento (locais + remotos via pub/sub). */
38
+ list(docName) {
39
+ const deduped = new Map();
40
+ for (const member of this.remoteMembers.get(docName)?.values() ?? []) {
41
+ deduped.set(member.userId, member);
42
+ }
43
+ // Local ganha do remoto (é a fonte mais fresca).
44
+ for (const member of this.localMap(docName).values()) {
45
+ deduped.set(member.userId, member);
46
+ }
47
+ return [...deduped.values()];
48
+ }
49
+ onPresenceChange(listener) {
50
+ this.listeners.add(listener);
51
+ return () => this.listeners.delete(listener);
52
+ }
53
+ async close() {
54
+ if (this.heartbeatTimer)
55
+ clearInterval(this.heartbeatTimer);
56
+ if (this.publisher)
57
+ await this.publisher.quit();
58
+ if (this.subscriber)
59
+ await this.subscriber.quit();
60
+ }
61
+ /* ───────────────────────── internals ───────────────────────── */
62
+ localMap(docName) {
63
+ return this.localMembers.get(docName) ?? new Map();
64
+ }
65
+ async publish(message) {
66
+ if (!this.publisher)
67
+ return;
68
+ await this.publisher.publish('collab:presence', JSON.stringify(message));
69
+ }
70
+ async publishLocalHeartbeats() {
71
+ for (const [docName, members] of this.localMembers) {
72
+ for (const member of members.values()) {
73
+ await this.publish({ kind: 'join', docName, member });
74
+ }
75
+ }
76
+ }
77
+ handleRemoteMessage(message) {
78
+ if (!this.remoteMembers.has(message.docName)) {
79
+ this.remoteMembers.set(message.docName, new Map());
80
+ }
81
+ const byUser = this.remoteMembers.get(message.docName);
82
+ if (message.kind === 'join' && message.member) {
83
+ byUser.set(message.member.userId, message.member);
84
+ }
85
+ else if (message.kind === 'leave' && message.userId) {
86
+ // Só remove se veio da mesma instância que registrou.
87
+ const current = byUser.get(message.userId);
88
+ if (!current || current.instanceId === message.instanceId) {
89
+ byUser.delete(message.userId);
90
+ }
91
+ }
92
+ this.notify(message.docName);
93
+ }
94
+ notify(docName) {
95
+ for (const listener of this.listeners) {
96
+ listener(docName, this.list(docName));
97
+ }
98
+ }
99
+ }
100
+ function randomHex(bytes) {
101
+ return Array.from({ length: bytes }, () => Math.floor(Math.random() * 16).toString(16)).join('');
102
+ }
103
+ //# sourceMappingURL=presence_service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence_service.js","sourceRoot":"","sources":["../../../src/services/presence_service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { CollabComment, CollabVersion, CollaborationStorage } from '../types.js';
2
+ /**
3
+ * Storage em disco pra desenvolvimento local da lib (um arquivo por doc +
4
+ * um por versão). Em produção use o LucidStorage sobre Postgres.
5
+ */
6
+ export declare class FileSystemStorage implements CollaborationStorage {
7
+ private baseDir;
8
+ constructor(baseDir?: string);
9
+ private ensure;
10
+ private docPath;
11
+ private versionPath;
12
+ private commentsPath;
13
+ loadDocument(docName: string): Promise<{
14
+ state: Uint8Array;
15
+ } | null>;
16
+ saveDocument(docName: string, state: Uint8Array): Promise<void>;
17
+ listVersions(docName: string): Promise<CollabVersion[]>;
18
+ saveVersion(docName: string, _version: CollabVersion, snapshot: Uint8Array): Promise<void>;
19
+ loadVersionSnapshot(docName: string, versionId: string): Promise<Uint8Array | null>;
20
+ listComments(docName: string, space?: string): Promise<CollabComment[]>;
21
+ saveComment(docName: string, comment: CollabComment): Promise<void>;
22
+ deleteComment(docName: string, commentId: string): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=file_system_storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file_system_storage.d.ts","sourceRoot":"","sources":["../../../src/storage/file_system_storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEtF;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,oBAAoB;IAC5D,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;YAId,MAAM;IAKpB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,YAAY;IAId,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IASpE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/D,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAKvD,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1F,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IASnF,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAUvE,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAYvE"}
@@ -0,0 +1,83 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ /**
4
+ * Storage em disco pra desenvolvimento local da lib (um arquivo por doc +
5
+ * um por versão). Em produção use o LucidStorage sobre Postgres.
6
+ */
7
+ export class FileSystemStorage {
8
+ baseDir;
9
+ constructor(baseDir) {
10
+ this.baseDir = baseDir ?? join(process.cwd(), '.collab-data');
11
+ }
12
+ async ensure() {
13
+ await mkdir(join(this.baseDir, 'versions'), { recursive: true });
14
+ await mkdir(join(this.baseDir, 'comments'), { recursive: true });
15
+ }
16
+ docPath(docName) {
17
+ return join(this.baseDir, `${encodeURIComponent(docName)}.bin`);
18
+ }
19
+ versionPath(docName, versionId) {
20
+ return join(this.baseDir, 'versions', `${encodeURIComponent(docName)}_${encodeURIComponent(versionId)}.bin`);
21
+ }
22
+ commentsPath(docName) {
23
+ return join(this.baseDir, 'comments', `${encodeURIComponent(docName)}.json`);
24
+ }
25
+ async loadDocument(docName) {
26
+ try {
27
+ const content = await readFile(this.docPath(docName));
28
+ return { state: new Uint8Array(content) };
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ async saveDocument(docName, state) {
35
+ await this.ensure();
36
+ await writeFile(this.docPath(docName), state);
37
+ }
38
+ async listVersions(docName) {
39
+ void docName;
40
+ return [];
41
+ }
42
+ async saveVersion(docName, _version, snapshot) {
43
+ await this.ensure();
44
+ await writeFile(this.versionPath(docName, _version.id), snapshot);
45
+ }
46
+ async loadVersionSnapshot(docName, versionId) {
47
+ try {
48
+ const content = await readFile(this.versionPath(docName, versionId));
49
+ return new Uint8Array(content);
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ async listComments(docName, space) {
56
+ try {
57
+ const content = await readFile(this.commentsPath(docName), 'utf-8');
58
+ const all = JSON.parse(content);
59
+ return space ? all.filter((comment) => comment.space === space) : all;
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ }
65
+ async saveComment(docName, comment) {
66
+ await this.ensure();
67
+ const existing = await this.listComments(docName);
68
+ const index = existing.findIndex((entry) => entry.id === comment.id);
69
+ if (index >= 0) {
70
+ existing[index] = comment;
71
+ }
72
+ else {
73
+ existing.push(comment);
74
+ }
75
+ await writeFile(this.commentsPath(docName), JSON.stringify(existing, null, 2));
76
+ }
77
+ async deleteComment(docName, commentId) {
78
+ await this.ensure();
79
+ const existing = await this.listComments(docName);
80
+ await writeFile(this.commentsPath(docName), JSON.stringify(existing.filter((entry) => entry.id !== commentId), null, 2));
81
+ }
82
+ }
83
+ //# sourceMappingURL=file_system_storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file_system_storage.js","sourceRoot":"","sources":["../../../src/storage/file_system_storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { CollabComment, CollabVersion, CollaborationStorage } from '../types.js';
2
+ /**
3
+ * Storage em memória — fallback de desenvolvimento quando o app não configura
4
+ * `storage` (nada sobrevive a um restart). Produção SEMPRE passa um storage
5
+ * persistente (Postgres/S3).
6
+ */
7
+ export declare class InMemoryCollaborationStorage implements CollaborationStorage {
8
+ private docs;
9
+ private versions;
10
+ private comments;
11
+ loadDocument(docName: string): Promise<{
12
+ state: Uint8Array;
13
+ } | null>;
14
+ saveDocument(docName: string, state: Uint8Array): Promise<void>;
15
+ listVersions(docName: string): Promise<CollabVersion[]>;
16
+ saveVersion(docName: string, version: CollabVersion, snapshot: Uint8Array): Promise<void>;
17
+ loadVersionSnapshot(docName: string, versionId: string): Promise<Uint8Array | null>;
18
+ listComments(docName: string, space?: string): Promise<CollabComment[]>;
19
+ saveComment(docName: string, comment: CollabComment): Promise<void>;
20
+ deleteComment(docName: string, commentId: string): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=in_memory_storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in_memory_storage.d.ts","sourceRoot":"","sources":["../../../src/storage/in_memory_storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEtF;;;;GAIG;AACH,qBAAa,4BAA6B,YAAW,oBAAoB;IACvE,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,QAAQ,CAA8E;IAC9F,OAAO,CAAC,QAAQ,CAAsC;IAEhD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAKpE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIvD,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzF,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAKnF,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAKvE,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOvE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Storage em memória — fallback de desenvolvimento quando o app não configura
3
+ * `storage` (nada sobrevive a um restart). Produção SEMPRE passa um storage
4
+ * persistente (Postgres/S3).
5
+ */
6
+ export class InMemoryCollaborationStorage {
7
+ docs = new Map();
8
+ versions = new Map();
9
+ comments = new Map();
10
+ async loadDocument(docName) {
11
+ const state = this.docs.get(docName);
12
+ return state ? { state } : null;
13
+ }
14
+ async saveDocument(docName, state) {
15
+ this.docs.set(docName, state);
16
+ }
17
+ async listVersions(docName) {
18
+ return (this.versions.get(docName) ?? []).map((entry) => entry.version);
19
+ }
20
+ async saveVersion(docName, version, snapshot) {
21
+ if (!this.versions.has(docName)) {
22
+ this.versions.set(docName, []);
23
+ }
24
+ this.versions.get(docName).push({ version, snapshot });
25
+ }
26
+ async loadVersionSnapshot(docName, versionId) {
27
+ const entry = (this.versions.get(docName) ?? []).find((v) => v.version.id === versionId);
28
+ return entry?.snapshot ?? null;
29
+ }
30
+ async listComments(docName, space) {
31
+ const all = this.comments.get(docName) ?? [];
32
+ return space ? all.filter((comment) => comment.space === space) : all;
33
+ }
34
+ async saveComment(docName, comment) {
35
+ const existing = this.comments.get(docName) ?? [];
36
+ const index = existing.findIndex((entry) => entry.id === comment.id);
37
+ if (index >= 0) {
38
+ existing[index] = comment;
39
+ }
40
+ else {
41
+ existing.push(comment);
42
+ }
43
+ this.comments.set(docName, existing);
44
+ }
45
+ async deleteComment(docName, commentId) {
46
+ const existing = this.comments.get(docName) ?? [];
47
+ this.comments.set(docName, existing.filter((entry) => entry.id !== commentId));
48
+ }
49
+ }
50
+ //# sourceMappingURL=in_memory_storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in_memory_storage.js","sourceRoot":"","sources":["../../../src/storage/in_memory_storage.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,4BAA4B;IAC/B,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAC;IACrC,QAAQ,GAAG,IAAI,GAAG,EAAmE,CAAC;IACtF,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEtD,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAe,EAAE,KAAiB;QACnD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,OAAsB,EAAE,QAAoB;QAC7E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,OAAe,EAAE,SAAiB;QAC1D,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QACzF,OAAO,KAAK,EAAE,QAAQ,IAAI,IAAI,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAe,EAAE,KAAc;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7C,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,OAAsB;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;QACrE,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,QAAQ,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAe,EAAE,SAAiB;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,GAAG,CACf,OAAO,EACP,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,CAAC,CACnD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,41 @@
1
+ import type { CollabComment, CollabVersion, CollaborationStorage } from '../types.js';
2
+ /**
3
+ * Contrato estrutural mínimo da conexão lucid — evita o dual-package do
4
+ * @adonisjs/lucid (app e lib podem resolver cópias com TS diferentes).
5
+ */
6
+ export interface LucidConnectionLike {
7
+ connection(name?: string): unknown;
8
+ }
9
+ /**
10
+ * Storage Lucid oficial — persiste docs (estado binário), versões e
11
+ * comentários ancorados em tabelas do banco do app.
12
+ *
13
+ * As tabelas são criadas no primeiro uso (IF NOT EXISTS), então o app não
14
+ * precisa de migration própria pra usar a lib em dev.
15
+ *
16
+ * @example
17
+ * const storage = new LucidStorage(db)
18
+ * const manager = new CollaborationManager({ engine: 'yjs', storage, authorize })
19
+ */
20
+ export declare class LucidStorage implements CollaborationStorage {
21
+ private db;
22
+ private connection;
23
+ private ready;
24
+ constructor(db: LucidConnectionLike, connection?: string);
25
+ /** Garante as tabelas sob demanda (lazy) — o boot não toca no banco. */
26
+ private ensure;
27
+ /** A conexão do lucid é um Knex (QueryClientContract estende o builder). */
28
+ private knex;
29
+ private ensureSchema;
30
+ loadDocument(docName: string): Promise<{
31
+ state: Uint8Array;
32
+ } | null>;
33
+ saveDocument(docName: string, state: Uint8Array, meta?: Record<string, unknown>): Promise<void>;
34
+ listVersions(docName: string): Promise<CollabVersion[]>;
35
+ saveVersion(docName: string, version: CollabVersion, _snapshot: Uint8Array): Promise<void>;
36
+ loadVersionSnapshot(docName: string, _versionId: string): Promise<Uint8Array | null>;
37
+ listComments(docName: string, space?: string): Promise<CollabComment[]>;
38
+ saveComment(docName: string, comment: CollabComment): Promise<void>;
39
+ deleteComment(docName: string, commentId: string): Promise<void>;
40
+ }
41
+ //# sourceMappingURL=lucid_storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lucid_storage.d.ts","sourceRoot":"","sources":["../../../src/storage/lucid_storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEtF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,YAAW,oBAAoB;IAG3C,OAAO,CAAC,EAAE;IAAuB,OAAO,CAAC,UAAU;IAF/D,OAAO,CAAC,KAAK,CAA8B;gBAEvB,EAAE,EAAE,mBAAmB,EAAU,UAAU,GAAE,MAAsB;IAEvF,wEAAwE;IACxE,OAAO,CAAC,MAAM;IAOd,4EAA4E;IAC5E,OAAO,CAAC,IAAI;YAIE,YAAY;IAsCpB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAOpE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB/F,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAevD,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1F,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAKpF,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAmBvE,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBnE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKvE"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Storage Lucid oficial — persiste docs (estado binário), versões e
3
+ * comentários ancorados em tabelas do banco do app.
4
+ *
5
+ * As tabelas são criadas no primeiro uso (IF NOT EXISTS), então o app não
6
+ * precisa de migration própria pra usar a lib em dev.
7
+ *
8
+ * @example
9
+ * const storage = new LucidStorage(db)
10
+ * const manager = new CollaborationManager({ engine: 'yjs', storage, authorize })
11
+ */
12
+ export class LucidStorage {
13
+ db;
14
+ connection;
15
+ ready = null;
16
+ constructor(db, connection = 'entretextos') {
17
+ this.db = db;
18
+ this.connection = connection;
19
+ }
20
+ /** Garante as tabelas sob demanda (lazy) — o boot não toca no banco. */
21
+ ensure() {
22
+ if (!this.ready) {
23
+ this.ready = this.ensureSchema();
24
+ }
25
+ return this.ready;
26
+ }
27
+ /** A conexão do lucid é um Knex (QueryClientContract estende o builder). */
28
+ knex() {
29
+ return this.db.connection(this.connection);
30
+ }
31
+ async ensureSchema() {
32
+ const knex = this.knex();
33
+ const schema = knex.schema.createTableIfNotExists('collab_documents', (t) => {
34
+ t.string('doc_name').primary();
35
+ t.binary('state');
36
+ t.jsonb('meta').nullable();
37
+ t.timestamp('created_at', { useTz: true });
38
+ t.timestamp('updated_at', { useTz: true });
39
+ });
40
+ const versions = knex.schema.createTableIfNotExists('collab_versions', (t) => {
41
+ t.string('doc_name');
42
+ t.string('id');
43
+ t.string('created_by').nullable();
44
+ t.string('label').nullable();
45
+ t.integer('seq');
46
+ t.timestamp('created_at', { useTz: true });
47
+ t.primary(['doc_name', 'id']);
48
+ });
49
+ const comments = knex.schema.createTableIfNotExists('collab_comments', (t) => {
50
+ t.string('id').primary();
51
+ t.string('doc_name');
52
+ t.string('space').defaultTo('text');
53
+ t.jsonb('anchor');
54
+ t.text('body');
55
+ t.string('user_id');
56
+ t.string('author_name').nullable();
57
+ t.timestamp('resolved_at', { useTz: true }).nullable();
58
+ t.timestamp('created_at', { useTz: true });
59
+ t.timestamp('updated_at', { useTz: true }).nullable();
60
+ t.index(['doc_name', 'space']);
61
+ });
62
+ await Promise.all([schema, versions, comments]);
63
+ }
64
+ async loadDocument(docName) {
65
+ await this.ensure();
66
+ const row = await this.knex().from('collab_documents').where('doc_name', docName).first();
67
+ if (!row?.state)
68
+ return null;
69
+ return { state: new Uint8Array(row.state) };
70
+ }
71
+ async saveDocument(docName, state, meta) {
72
+ await this.ensure();
73
+ const existing = await this.knex()
74
+ .from('collab_documents')
75
+ .where('doc_name', docName)
76
+ .first();
77
+ const payload = {
78
+ state: Buffer.from(state),
79
+ meta: meta ?? null,
80
+ updated_at: new Date(),
81
+ };
82
+ if (existing) {
83
+ await this.knex().from('collab_documents').where('doc_name', docName).update(payload);
84
+ }
85
+ else {
86
+ await this.knex().from('collab_documents').insert({
87
+ doc_name: docName,
88
+ ...payload,
89
+ created_at: new Date(),
90
+ });
91
+ }
92
+ }
93
+ async listVersions(docName) {
94
+ await this.ensure();
95
+ const rows = await this.knex()
96
+ .from('collab_versions')
97
+ .where('doc_name', docName)
98
+ .orderBy('seq', 'asc');
99
+ return rows.map((row) => ({
100
+ id: row.id,
101
+ createdBy: row.created_by ?? null,
102
+ label: row.label ?? null,
103
+ seq: row.seq,
104
+ createdAt: row.created_at?.toISOString?.() ?? String(row.created_at),
105
+ }));
106
+ }
107
+ async saveVersion(docName, version, _snapshot) {
108
+ await this.ensure();
109
+ await this.knex()
110
+ .from('collab_versions')
111
+ .insert({
112
+ doc_name: docName,
113
+ id: version.id,
114
+ created_by: version.createdBy,
115
+ label: version.label,
116
+ seq: version.seq,
117
+ created_at: new Date(version.createdAt),
118
+ })
119
+ .onConflict(['doc_name', 'id'])
120
+ .ignore();
121
+ }
122
+ async loadVersionSnapshot(docName, _versionId) {
123
+ const doc = await this.loadDocument(docName);
124
+ return doc?.state ?? null;
125
+ }
126
+ async listComments(docName, space) {
127
+ await this.ensure();
128
+ let query = this.knex().from('collab_comments').where('doc_name', docName);
129
+ if (space)
130
+ query = query.where('space', space);
131
+ const rows = await query;
132
+ return rows.map((row) => ({
133
+ id: row.id,
134
+ documentName: row.doc_name,
135
+ space: row.space ?? 'text',
136
+ anchor: row.anchor,
137
+ body: row.body,
138
+ userId: row.user_id,
139
+ authorName: row.author_name ?? null,
140
+ resolvedAt: row.resolved_at?.toISOString?.() ?? row.resolved_at ?? null,
141
+ createdAt: row.created_at?.toISOString?.() ?? String(row.created_at),
142
+ updatedAt: row.updated_at?.toISOString?.() ?? row.updated_at ?? null,
143
+ }));
144
+ }
145
+ async saveComment(docName, comment) {
146
+ await this.ensure();
147
+ const existing = await this.knex().from('collab_comments').where('id', comment.id).first();
148
+ const payload = {
149
+ doc_name: comment.documentName,
150
+ space: comment.space,
151
+ anchor: comment.anchor,
152
+ body: comment.body,
153
+ user_id: comment.userId,
154
+ author_name: comment.authorName ?? null,
155
+ resolved_at: comment.resolvedAt ? new Date(comment.resolvedAt) : null,
156
+ updated_at: new Date(),
157
+ };
158
+ if (existing) {
159
+ await this.knex().from('collab_comments').where('id', comment.id).update(payload);
160
+ }
161
+ else {
162
+ await this.knex().from('collab_comments').insert({
163
+ id: comment.id,
164
+ ...payload,
165
+ created_at: new Date(comment.createdAt),
166
+ });
167
+ }
168
+ void docName;
169
+ }
170
+ async deleteComment(docName, commentId) {
171
+ await this.ensure();
172
+ await this.knex().from('collab_comments').where('id', commentId).delete();
173
+ void docName;
174
+ }
175
+ }
176
+ //# sourceMappingURL=lucid_storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lucid_storage.js","sourceRoot":"","sources":["../../../src/storage/lucid_storage.ts"],"names":[],"mappings":"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"}