@adonis-agora/collaboration 0.1.4 → 0.2.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 (110) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +172 -0
  3. package/dist/commands/collaboration_init.d.ts +26 -0
  4. package/dist/commands/collaboration_init.d.ts.map +1 -0
  5. package/dist/commands/collaboration_init.js +83 -0
  6. package/dist/commands/collaboration_init.js.map +1 -0
  7. package/dist/commands/commands.json +1 -0
  8. package/dist/commands/main.d.ts +16 -0
  9. package/dist/commands/main.d.ts.map +1 -0
  10. package/dist/commands/main.js +20 -0
  11. package/dist/commands/main.js.map +1 -0
  12. package/dist/commands/make_collab_document.d.ts +23 -0
  13. package/dist/commands/make_collab_document.d.ts.map +1 -0
  14. package/dist/commands/make_collab_document.js +75 -0
  15. package/dist/commands/make_collab_document.js.map +1 -0
  16. package/dist/configure.d.ts +3 -1
  17. package/dist/configure.d.ts.map +1 -1
  18. package/dist/configure.js +6 -1
  19. package/dist/configure.js.map +1 -1
  20. package/dist/providers/collaboration_provider.d.ts +6 -2
  21. package/dist/providers/collaboration_provider.d.ts.map +1 -1
  22. package/dist/providers/collaboration_provider.js +36 -17
  23. package/dist/providers/collaboration_provider.js.map +1 -1
  24. package/dist/src/auth/token.d.ts +59 -0
  25. package/dist/src/auth/token.d.ts.map +1 -0
  26. package/dist/src/auth/token.js +91 -0
  27. package/dist/src/auth/token.js.map +1 -0
  28. package/dist/src/codegen/documents_registry.d.ts +28 -0
  29. package/dist/src/codegen/documents_registry.d.ts.map +1 -0
  30. package/dist/src/codegen/documents_registry.js +50 -0
  31. package/dist/src/codegen/documents_registry.js.map +1 -0
  32. package/dist/src/codegen_init.d.ts +3 -0
  33. package/dist/src/codegen_init.d.ts.map +1 -0
  34. package/dist/src/codegen_init.js +45 -0
  35. package/dist/src/codegen_init.js.map +1 -0
  36. package/dist/src/collaboration_manager.d.ts +20 -11
  37. package/dist/src/collaboration_manager.d.ts.map +1 -1
  38. package/dist/src/collaboration_manager.js +46 -17
  39. package/dist/src/collaboration_manager.js.map +1 -1
  40. package/dist/src/define_config.d.ts +25 -6
  41. package/dist/src/define_config.d.ts.map +1 -1
  42. package/dist/src/define_config.js +2 -2
  43. package/dist/src/define_config.js.map +1 -1
  44. package/dist/src/driver.d.ts +26 -32
  45. package/dist/src/driver.d.ts.map +1 -1
  46. package/dist/src/drivers/automerge/automerge_driver.d.ts +7 -12
  47. package/dist/src/drivers/automerge/automerge_driver.d.ts.map +1 -1
  48. package/dist/src/drivers/automerge/automerge_driver.js +37 -75
  49. package/dist/src/drivers/automerge/automerge_driver.js.map +1 -1
  50. package/dist/src/drivers/partykit/partykit_driver.d.ts +54 -0
  51. package/dist/src/drivers/partykit/partykit_driver.d.ts.map +1 -0
  52. package/dist/src/drivers/partykit/partykit_driver.js +162 -0
  53. package/dist/src/drivers/partykit/partykit_driver.js.map +1 -0
  54. package/dist/src/drivers/shared.d.ts +17 -0
  55. package/dist/src/drivers/shared.d.ts.map +1 -0
  56. package/dist/src/drivers/shared.js +46 -0
  57. package/dist/src/drivers/shared.js.map +1 -0
  58. package/dist/src/drivers/yjs/yjs_driver.d.ts +18 -12
  59. package/dist/src/drivers/yjs/yjs_driver.d.ts.map +1 -1
  60. package/dist/src/drivers/yjs/yjs_driver.js +50 -94
  61. package/dist/src/drivers/yjs/yjs_driver.js.map +1 -1
  62. package/dist/src/http/types.d.ts +79 -0
  63. package/dist/src/http/types.d.ts.map +1 -0
  64. package/dist/src/http/types.js +8 -0
  65. package/dist/src/http/types.js.map +1 -0
  66. package/dist/src/index.d.ts +7 -3
  67. package/dist/src/index.d.ts.map +1 -1
  68. package/dist/src/index.js +7 -2
  69. package/dist/src/index.js.map +1 -1
  70. package/dist/src/routes.d.ts +29 -0
  71. package/dist/src/routes.d.ts.map +1 -0
  72. package/dist/src/routes.js +189 -0
  73. package/dist/src/routes.js.map +1 -0
  74. package/dist/src/services/booted_app.js +1 -1
  75. package/dist/src/services/booted_app.js.map +1 -1
  76. package/dist/src/services/comment_service.d.ts +5 -4
  77. package/dist/src/services/comment_service.d.ts.map +1 -1
  78. package/dist/src/services/comment_service.js +5 -4
  79. package/dist/src/services/comment_service.js.map +1 -1
  80. package/dist/src/services/main.js +2 -2
  81. package/dist/src/services/main.js.map +1 -1
  82. package/dist/src/storage/file_system_storage.d.ts +2 -2
  83. package/dist/src/storage/file_system_storage.js +2 -2
  84. package/dist/src/storage/in_memory_storage.d.ts +3 -3
  85. package/dist/src/storage/in_memory_storage.js +3 -3
  86. package/dist/src/storage/lucid_storage.d.ts +9 -8
  87. package/dist/src/storage/lucid_storage.d.ts.map +1 -1
  88. package/dist/src/storage/lucid_storage.js +13 -12
  89. package/dist/src/storage/lucid_storage.js.map +1 -1
  90. package/dist/src/types.d.ts +62 -35
  91. package/dist/src/types.d.ts.map +1 -1
  92. package/dist/src/types.js +5 -6
  93. package/dist/src/types.js.map +1 -1
  94. package/dist/src/versioning.d.ts +3 -3
  95. package/dist/src/versioning.d.ts.map +1 -1
  96. package/dist/src/versioning.js +3 -3
  97. package/dist/src/versioning.js.map +1 -1
  98. package/dist/stubs/collaboration/document_types.stub +41 -0
  99. package/dist/stubs/collaboration/documents_dir.stub +3 -0
  100. package/dist/stubs/collaboration/migrations/collab_comments.stub +29 -0
  101. package/dist/stubs/collaboration/migrations/collab_documents.stub +23 -0
  102. package/dist/stubs/collaboration/migrations/collab_versions.stub +26 -0
  103. package/dist/stubs/partykit/worker/package.json.stub +21 -0
  104. package/dist/stubs/partykit/worker/party.ts.stub +175 -0
  105. package/dist/stubs/partykit/worker/partykit.toml.stub +14 -0
  106. package/package.json +19 -4
  107. package/dist/src/services/presence_service.d.ts +0 -44
  108. package/dist/src/services/presence_service.d.ts.map +0 -1
  109. package/dist/src/services/presence_service.js +0 -103
  110. package/dist/src/services/presence_service.js.map +0 -1
@@ -1,16 +1,21 @@
1
1
  import { CollaborationManager } from '../src/collaboration_manager.js';
2
+ import { collaborationRoutes } from '../src/routes.js';
2
3
  import { setBootedApp } from '../src/services/booted_app.js';
3
4
  /**
4
5
  * Wires `@adonis-agora/collaboration` into the AdonisJS application:
5
6
  *
6
7
  * - `register()` hands the booted app to `services/main` and binds the
7
8
  * `CollaborationManager` singleton from `config/collaboration.ts`;
8
- * - `boot()` attaches the collaboration WebSocket upgrade to the Adonis HTTP
9
- * server (path from config, default `/collaboration`);
9
+ * - `boot()`/`ready()` attaches the collaboration WebSocket upgrade to the
10
+ * Adonis HTTP server (path from config, default `/collaboration`);
11
+ * - `ready()` registers the built-in REST endpoints automatically unless
12
+ * `routes.enabled: false` — then call `collaborationRoutes(router)` in
13
+ * `start/routes.ts` with your own middleware;
10
14
  * - `shutdown()` flushes pending stores and closes all connections.
11
15
  */
12
16
  export default class CollaborationServiceProvider {
13
17
  app;
18
+ config;
14
19
  constructor(app) {
15
20
  this.app = app;
16
21
  }
@@ -19,32 +24,28 @@ export default class CollaborationServiceProvider {
19
24
  // copy bin/server booted, never a pnpm-split non-booted one (see services/booted_app.ts).
20
25
  setBootedApp(this.app);
21
26
  const config = this.app.config.get('collaboration');
27
+ this.config = config;
22
28
  this.app.container.singleton(CollaborationManager, () => {
23
29
  if (!config?.authorize) {
24
- throw new Error('Configure authorize() em config/collaboration.ts — a lib nunca autoriza por padrão');
30
+ throw new Error('Configure authorize() in config/collaboration.ts — the library never authorizes by default');
25
31
  }
26
32
  const managerConfig = {
27
33
  engine: config.engine ?? 'yjs',
28
- authorize: (ctx, docName) => config.authorize(ctx, docName),
34
+ authorize: config.authorize,
29
35
  path: config.path ?? '/collaboration',
30
36
  debounce: config.debounce ?? 2000,
37
+ ...(config.storage ? { storage: config.storage } : {}),
38
+ ...(config.redisUrl ? { redis: { url: config.redisUrl } } : {}),
39
+ ...(config.partykit ? { partykit: config.partykit } : {}),
31
40
  };
32
- if (config.storage) {
33
- managerConfig.storage = config.storage;
34
- }
35
- if (config.redisUrl) {
36
- managerConfig.redis = { url: config.redisUrl };
37
- }
38
41
  return new CollaborationManager(managerConfig);
39
42
  });
40
43
  }
41
44
  async ready() {
42
- // O attach fica no `ready` (fase 4 do ciclo de vida): o Ignitor já criou
43
- // o node HTTP server em `start()` (fase 3), então getNodeServer() existe.
44
- // Em comandos ace não há HTTP server — a colaboração simplesmente não
45
- // sobe (o manager segue disponível pra uso programático).
46
- // Sem HTTP server fora do processo web (ace/console, test, repl) — a
47
- // colaboração não sobe; o manager segue disponível pra uso programático.
45
+ // Attach happens in `ready()` (lifecycle phase 4): Ignitor created the
46
+ // node HTTP server during `start()` (phase 3), so getNodeServer() exists.
47
+ // Outside the web process (ace/console/test/repl) there is no HTTP
48
+ // server — collaboration does not start; the manager stays available.
48
49
  const env = this.app.getEnvironment();
49
50
  if (env !== 'web') {
50
51
  return;
@@ -53,9 +54,27 @@ export default class CollaborationServiceProvider {
53
54
  const adonisServer = (await this.app.container.make('server'));
54
55
  const nodeServer = adonisServer.getNodeServer?.();
55
56
  if (!nodeServer) {
56
- throw new Error('[@adonis-agora/collaboration] getNodeServer() indisponível no ready() — verifique a versão do @adonisjs/http-server');
57
+ throw new Error('[@adonis-agora/collaboration] getNodeServer() unavailable in ready() — check @adonisjs/http-server version');
57
58
  }
58
59
  await manager.attach(nodeServer);
60
+ // Auto-register built-in REST endpoints unless explicitly disabled.
61
+ const routes = this.config?.routes;
62
+ if (routes?.enabled === false) {
63
+ return;
64
+ }
65
+ const router = (await this.app.container.make('router'));
66
+ const runtimeOptions = {
67
+ managerFallback: () => this.app.container.make(CollaborationManager),
68
+ };
69
+ if (routes?.prefix !== undefined)
70
+ runtimeOptions.prefix = routes.prefix;
71
+ if (routes?.middleware !== undefined)
72
+ runtimeOptions.middleware = routes.middleware;
73
+ if (routes?.resolveUser !== undefined)
74
+ runtimeOptions.resolveUser = routes.resolveUser;
75
+ if (this.config?.authorize !== undefined)
76
+ runtimeOptions.authorize = this.config.authorize;
77
+ await collaborationRoutes(router, runtimeOptions);
59
78
  }
60
79
  async shutdown() {
61
80
  const manager = await this.app.container.make(CollaborationManager);
@@ -1 +1 @@
1
- {"version":3,"file":"collaboration_provider.js","sourceRoot":"","sources":["../../providers/collaboration_provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAO7D;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA4B;IACzB;IAAtB,YAAsB,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAEjD,QAAQ;QACN,+FAA+F;QAC/F,0FAA0F;QAC1F,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAyB,eAAe,CAAC,CAAC;QAE5E,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,EAAE,GAAG,EAAE;YACtD,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;YACJ,CAAC;YAED,MAAM,aAAa,GAAwB;gBACzC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,KAAK;gBAC9B,SAAS,EAAE,CAAC,GAA4B,EAAE,OAAe,EAA6B,EAAE,CACtF,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC;gBAChC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,gBAAgB;gBACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;aAClC,CAAC;YAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,aAAa,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YACzC,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACpB,aAAa,CAAC,KAAK,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;YACjD,CAAC;YAED,OAAO,IAAI,oBAAoB,CAAC,aAAa,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,yEAAyE;QACzE,0EAA0E;QAC1E,sEAAsE;QACtE,0DAA0D;QAC1D,qEAAqE;QACrE,yEAAyE;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAY,CAAC;QAChD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAEpE,MAAM,YAAY,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAE5D,CAAC;QAEF,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC;QAClD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACpE,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF"}
1
+ {"version":3,"file":"collaboration_provider.js","sourceRoot":"","sources":["../../providers/collaboration_provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { CollabConnectionContext, CollabPermission, PartyKitConfig } from '../types.js';
2
+ /**
3
+ * The token/auth module — the single seam for issuing and verifying
4
+ * collaboration credentials.
5
+ *
6
+ * Two wire formats, chosen by engine:
7
+ * - `partykit` → HS256 JWT (verified by the edge worker via WebCrypto)
8
+ * - self-hosted (`yjs`/`automerge`) → legacy base64 JSON payload accepted
9
+ * by the driver handshake
10
+ *
11
+ * `issueToken` also enforces `config.authorize` on the REST path — the
12
+ * permission seam must hold outside the WebSocket handshake too.
13
+ */
14
+ export interface TokenIssuerConfig {
15
+ engine: string;
16
+ /** WS path of the embedded Hocuspocus server (self-hosted engines). */
17
+ path?: string;
18
+ partykit?: Partial<Pick<PartyKitConfig, 'roomHost' | 'jwtSecret' | 'party'>>;
19
+ }
20
+ /** Minimal authorize contract — mirrors CollaborationConfig.authorize. */
21
+ export type AuthorizeFn = (ctx: CollabConnectionContext, docName: string) => Promise<CollabPermission>;
22
+ /** Signs a minimal HS256 JWT — no external dependency. */
23
+ export declare function signPartyKitToken(payload: {
24
+ userId: string;
25
+ docName: string;
26
+ user?: {
27
+ name?: string;
28
+ avatarUrl?: string | null;
29
+ };
30
+ }, secret: string, expiresInSeconds?: number): string;
31
+ /** Verifies signature + expiry of a token issued by {@link signPartyKitToken}. */
32
+ export declare function verifyPartyKitToken(token: string, secret: string): {
33
+ userId: string;
34
+ docName: string;
35
+ exp: number;
36
+ } | null;
37
+ /** Parses the legacy base64 payload used by self-hosted driver handshakes. */
38
+ export declare function parseLegacyToken(token: string): CollabConnectionContext | null;
39
+ /** Builds the browser-facing WebSocket URL for an engine. */
40
+ export declare function buildWsUrl(config: TokenIssuerConfig, docName: string): string;
41
+ /** Result of a successful token issue. */
42
+ export interface IssuedToken {
43
+ token: string;
44
+ wsUrl: string;
45
+ engine: string;
46
+ }
47
+ /** Thrown when authorize() denies read access for the document. */
48
+ export declare class CollabForbiddenError extends Error {
49
+ constructor(docName: string);
50
+ }
51
+ /**
52
+ * Issues an ephemeral credential for `docName`, enforcing the permission
53
+ * seam via `authorize` when one is provided.
54
+ */
55
+ export declare function issueToken(config: TokenIssuerConfig, user: {
56
+ id: string;
57
+ name?: string | null;
58
+ }, docName: string, authorize?: AuthorizeFn): Promise<IssuedToken>;
59
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/auth/token.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7F;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;CAC9E;AAED,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GAAG,CACxB,GAAG,EAAE,uBAAuB,EAC5B,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CAAE,EACjG,MAAM,EAAE,MAAM,EACd,gBAAgB,SAAM,GACrB,MAAM,CAQR;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoBzD;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAO9E;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,mEAAmE;AACnE,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAC1C,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC,WAAW,CAAC,CA4BtB"}
@@ -0,0 +1,91 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+ /** Signs a minimal HS256 JWT — no external dependency. */
3
+ export function signPartyKitToken(payload, secret, expiresInSeconds = 300) {
4
+ const header = { alg: 'HS256', typ: 'JWT' };
5
+ const now = Math.floor(Date.now() / 1000);
6
+ const body = { ...payload, iat: now, exp: now + expiresInSeconds };
7
+ const encode = (value) => Buffer.from(JSON.stringify(value)).toString('base64url');
8
+ const unsigned = `${encode(header)}.${encode(body)}`;
9
+ const signature = createHmac('sha256', secret).update(unsigned).digest('base64url');
10
+ return `${unsigned}.${signature}`;
11
+ }
12
+ /** Verifies signature + expiry of a token issued by {@link signPartyKitToken}. */
13
+ export function verifyPartyKitToken(token, secret) {
14
+ const parts = token.split('.');
15
+ if (parts.length !== 3)
16
+ return null;
17
+ const [header, body, signature] = parts;
18
+ const expected = createHmac('sha256', secret).update(`${header}.${body}`).digest();
19
+ const received = Buffer.from(signature, 'base64url');
20
+ if (received.length !== expected.length || !timingSafeEqual(received, expected)) {
21
+ return null;
22
+ }
23
+ try {
24
+ const parsed = JSON.parse(Buffer.from(body, 'base64url').toString());
25
+ if (!parsed.userId || !parsed.docName || parsed.exp * 1000 < Date.now())
26
+ return null;
27
+ return parsed;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /** Parses the legacy base64 payload used by self-hosted driver handshakes. */
34
+ export function parseLegacyToken(token) {
35
+ try {
36
+ const parsed = JSON.parse(Buffer.from(token, 'base64').toString());
37
+ return parsed.userId ? parsed : null;
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ }
43
+ /** Builds the browser-facing WebSocket URL for an engine. */
44
+ export function buildWsUrl(config, docName) {
45
+ if (config.engine === 'partykit') {
46
+ const { roomHost, party } = config.partykit ?? {};
47
+ const scheme = roomHost?.startsWith('localhost') || roomHost?.startsWith('127.0.0.1') ? 'ws' : 'wss';
48
+ const host = roomHost?.replace(/^https?:\/\//, '') ?? '';
49
+ return `${scheme}://${host}/parties/${party ?? 'main'}/${encodeURIComponent(docName)}`;
50
+ }
51
+ return config.path ?? '/collaboration';
52
+ }
53
+ /** Thrown when authorize() denies read access for the document. */
54
+ export class CollabForbiddenError extends Error {
55
+ constructor(docName) {
56
+ super(`no access to document "${docName}"`);
57
+ this.name = 'CollabForbiddenError';
58
+ }
59
+ }
60
+ /**
61
+ * Issues an ephemeral credential for `docName`, enforcing the permission
62
+ * seam via `authorize` when one is provided.
63
+ */
64
+ export async function issueToken(config, user, docName, authorize) {
65
+ const ctx = {
66
+ userId: user.id,
67
+ ...(user.name ? { user: { name: user.name } } : {}),
68
+ };
69
+ let permission;
70
+ if (authorize) {
71
+ permission = await authorize(ctx, docName);
72
+ if (!permission.canRead)
73
+ throw new CollabForbiddenError(docName);
74
+ }
75
+ if (config.engine === 'partykit') {
76
+ if (!config.partykit?.jwtSecret) {
77
+ throw new Error('config.partykit.jwtSecret is required when engine=partykit');
78
+ }
79
+ return {
80
+ token: signPartyKitToken({ userId: user.id, docName }, config.partykit.jwtSecret),
81
+ wsUrl: buildWsUrl(config, docName),
82
+ engine: config.engine,
83
+ };
84
+ }
85
+ return {
86
+ token: Buffer.from(JSON.stringify(ctx)).toString('base64'),
87
+ wsUrl: buildWsUrl(config, docName),
88
+ engine: config.engine,
89
+ };
90
+ }
91
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../../src/auth/token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Renderer for the collaborative-documents registry generated at
3
+ * `.adonisjs/collaboration/documents.ts` by the Assembler `init` hook.
4
+ *
5
+ * Pure function so it is trivially testable — the hook only adapts
6
+ * vfs/buffer and delegates here.
7
+ */
8
+ /** File discovered by the IndexGenerator. */
9
+ export interface RegistryFile {
10
+ /** Extension-less relative key from the vfs (e.g. 'researches/writing_types'). */
11
+ vfsKey: string;
12
+ /** Import path already resolved via helpers.toImportPath. */
13
+ importPath: string;
14
+ }
15
+ /**
16
+ * Converts a vfs key into a document name — same convention as
17
+ * `make:collab-document`: the '_types' suffix is stripped.
18
+ *
19
+ * 'researches/writing_types' -> 'researches/writing'
20
+ */
21
+ export declare function documentKeyFromVfsKey(vfsKey: string): string;
22
+ /**
23
+ * Renders the typed registry lines. The map is type-only (`typeof import`),
24
+ * so the file produces no runtime code — consumed by tsc and re-exportable
25
+ * to the frontend through manifest/config types.
26
+ */
27
+ export declare function renderDocumentsRegistry(files: RegistryFile[]): string[];
28
+ //# sourceMappingURL=documents_registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents_registry.d.ts","sourceRoot":"","sources":["../../../src/codegen/documents_registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,6CAA6C;AAC7C,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAiDvE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Renderer for the collaborative-documents registry generated at
3
+ * `.adonisjs/collaboration/documents.ts` by the Assembler `init` hook.
4
+ *
5
+ * Pure function so it is trivially testable — the hook only adapts
6
+ * vfs/buffer and delegates here.
7
+ */
8
+ /**
9
+ * Converts a vfs key into a document name — same convention as
10
+ * `make:collab-document`: the '_types' suffix is stripped.
11
+ *
12
+ * 'researches/writing_types' -> 'researches/writing'
13
+ */
14
+ export function documentKeyFromVfsKey(vfsKey) {
15
+ return vfsKey.replace(/_types$/, '');
16
+ }
17
+ /**
18
+ * Renders the typed registry lines. The map is type-only (`typeof import`),
19
+ * so the file produces no runtime code — consumed by tsc and re-exportable
20
+ * to the frontend through manifest/config types.
21
+ */
22
+ export function renderDocumentsRegistry(files) {
23
+ const seen = new Set();
24
+ const unique = files.filter((file) => {
25
+ const key = documentKeyFromVfsKey(file.vfsKey);
26
+ if (seen.has(key))
27
+ return false;
28
+ seen.add(key);
29
+ return true;
30
+ });
31
+ const lines = [
32
+ '/**',
33
+ ' * Generated by @adonis-agora/collaboration — do not edit.',
34
+ ' * Refresh with `node ace codegen`.',
35
+ ' */',
36
+ ];
37
+ if (unique.length === 0) {
38
+ lines.push('', '/** No collaborative documents declared yet. Use `node ace make:collab-document`. */', 'export type CollabDocumentName = never;', '', 'export type CollabDocumentDefinition<Name extends CollabDocumentName> = Name extends never', ' ? never', ' : unknown;');
39
+ return lines;
40
+ }
41
+ lines.push('', 'type CollabDocumentModules = {');
42
+ for (const file of unique) {
43
+ const key = documentKeyFromVfsKey(file.vfsKey);
44
+ // Always quote — doc names may contain slashes/hyphens.
45
+ lines.push(` '${key}': typeof import('${file.importPath}');`);
46
+ }
47
+ lines.push('};', '', '/** Valid collaborative document names in this app. */', 'export type CollabDocumentName = keyof CollabDocumentModules;', '', '/** Document definition module (the *_types default export). */', 'export type CollabDocumentDefinition<Name extends CollabDocumentName> =', ' CollabDocumentModules[Name][', "'default'", '];');
48
+ return lines;
49
+ }
50
+ //# sourceMappingURL=documents_registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents_registry.js","sourceRoot":"","sources":["../../../src/codegen/documents_registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAqB;IAC3D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACnC,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAa;QACtB,KAAK;QACL,4DAA4D;QAC5D,qCAAqC;QACrC,KAAK;KACN,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CACR,EAAE,EACF,sFAAsF,EACtF,yCAAyC,EACzC,EAAE,EACF,4FAA4F,EAC5F,WAAW,EACX,cAAc,CACf,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,gCAAgC,CAAC,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,wDAAwD;QACxD,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,qBAAqB,IAAI,CAAC,UAAU,KAAK,CAAC,CAAC;IACjE,CAAC;IACD,KAAK,CAAC,IAAI,CACR,IAAI,EACJ,EAAE,EACF,wDAAwD,EACxD,+DAA+D,EAC/D,EAAE,EACF,iEAAiE,EACjE,yEAAyE,EACzE,gCAAgC,EAChC,WAAW,EACX,IAAI,CACL,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: (...args: unknown[]) => unknown;
2
+ export default _default;
3
+ //# sourceMappingURL=codegen_init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen_init.d.ts","sourceRoot":"","sources":["../../src/codegen_init.ts"],"names":[],"mappings":"wBA6D2B,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO;AAA1D,wBAA2D"}
@@ -0,0 +1,45 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { hooks } from '@adonisjs/core/app';
3
+ import { renderDocumentsRegistry } from './codegen/documents_registry.js';
4
+ /**
5
+ * Assembler `init` hook (AdonisJS v7 codegen).
6
+ *
7
+ * Registers an IndexGenerator source that scans `app/collaboration/documents`
8
+ * and generates `.adonisjs/collaboration/documents.ts` — the typed registry
9
+ * of collaborative documents (`CollabDocumentName`,
10
+ * `CollabDocumentDefinition`), refreshed by `node ace codegen`, the dev
11
+ * server, test runner and production build.
12
+ *
13
+ * Registered in adonisrc.ts by `node ace configure`:
14
+ *
15
+ * ```
16
+ * hooks: {
17
+ * init: [() => import('@adonis-agora/collaboration/codegen_init')]
18
+ * }
19
+ * ```
20
+ */
21
+ // The wrapper's inferred return type references non-portable @poppinss
22
+ // internals — annotate explicitly so the declaration emit stays portable.
23
+ const initHook = hooks.init((_parent, _hooksManager, indexGenerator) => {
24
+ const source = './app/collaboration/documents';
25
+ // Directory not created yet: nothing to index (make:collab-document creates it).
26
+ if (!existsSync(source)) {
27
+ return;
28
+ }
29
+ indexGenerator.add('collabDocuments', {
30
+ source,
31
+ glob: ['**/*.ts'],
32
+ output: './.adonisjs/collaboration/documents.ts',
33
+ as: (vfs, buffer, _config, helpers) => {
34
+ const files = Object.entries(vfs.asList()).map(([vfsKey, absolutePath]) => ({
35
+ vfsKey,
36
+ importPath: helpers.toImportPath(absolutePath),
37
+ }));
38
+ for (const line of renderDocumentsRegistry(files)) {
39
+ buffer.writeLine(line);
40
+ }
41
+ },
42
+ });
43
+ });
44
+ export default initHook;
45
+ //# sourceMappingURL=codegen_init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen_init.js","sourceRoot":"","sources":["../../src/codegen_init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAyB,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAEjG;;;;;;;;;;;;;;;;GAgBG;AACH,uEAAuE;AACvE,0EAA0E;AAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CACzB,CACE,OAAgB,EAChB,aAAsB,EACtB,cAEC,EACD,EAAE;IACF,MAAM,MAAM,GAAG,+BAA+B,CAAC;IAE/C,iFAAiF;IACjF,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,cAAc,CAAC,GAAG,CAAC,iBAAiB,EAAE;QACpC,MAAM;QACN,IAAI,EAAE,CAAC,SAAS,CAAC;QACjB,MAAM,EAAE,wCAAwC;QAChD,EAAE,EAAE,CACF,GAAyC,EACzC,MAA4C,EAC5C,OAAgB,EAChB,OAAmD,EACnD,EAAE;YACF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1E,MAAM;gBACN,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC;aAC/C,CAAC,CAAC,CAAC;YAEJ,KAAK,MAAM,IAAI,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClD,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CACF,CAAC;AAEF,eAAe,QAA2C,CAAC"}
@@ -1,34 +1,43 @@
1
1
  import type { CollaborationDriver } from './driver.js';
2
2
  import { AutomergeDriver } from './drivers/automerge/automerge_driver.js';
3
+ import { PartyKitDriver } from './drivers/partykit/partykit_driver.js';
3
4
  import { YjsDriver } from './drivers/yjs/yjs_driver.js';
4
5
  import { CommentService } from './services/comment_service.js';
5
- import { type PresenceMember, PresenceService } from './services/presence_service.js';
6
6
  import type { CollabDiffSummary, CollabVersion, CollaborationConfig } from './types.js';
7
7
  /**
8
- * Fachada da lib: escolhe o driver pela config e expõe a API unificada
9
- * (documento + versões + presença + comentários) pro app hospedeiro.
8
+ * Library facade: picks the driver for the configured engine and exposes the
9
+ * unified API (documents + versions + comments) to the host app.
10
+ *
11
+ * Seams:
12
+ * - drivers connect only through the registry below;
13
+ * - comments live exclusively here (`manager.comments`) — drivers never
14
+ * touch them;
15
+ * - presence is owned by each engine at runtime (edge worker awareness or
16
+ * client-side), not by this process.
10
17
  */
11
18
  export declare class CollaborationManager {
12
19
  private config;
13
20
  private driver;
14
- presence: PresenceService;
15
21
  comments: CommentService;
16
22
  constructor(config: CollaborationConfig);
17
23
  get engine(): string;
18
- /** Anexa o WebSocket do driver no server HTTP do Adonis. */
24
+ /** Attaches the driver's WebSocket to the Adonis HTTP server. No-op on edge. */
19
25
  attach(server: import('node:http').Server): Promise<void>;
20
- /** Estado binário atual (pra push externo — Google Drive, export…). */
26
+ /** Current binary state (for external push — Google Drive, export...). */
21
27
  getDocumentState(docName: string): Promise<Uint8Array>;
22
- /** Texto plano (LanguageTool, RAG, índices de comentários). */
28
+ /** Plain text (LanguageTool, RAG, comment indexes). */
23
29
  getDocumentText(docName: string): Promise<string>;
24
30
  createVersion(docName: string, createdBy: string | null, label?: string | null): Promise<CollabVersion>;
25
31
  listVersions(docName: string): Promise<CollabVersion[]>;
26
32
  restoreVersion(docName: string, versionId: string, restoredBy: string | null): Promise<void>;
27
33
  diffVersions(docName: string, aId: string, bId: string): Promise<CollabDiffSummary>;
28
- /** Membros online num documento (todas as instâncias). */
29
- listPresence(docName: string): PresenceMember[];
34
+ /**
35
+ * Persists an external snapshot (e.g. PartyKit worker post-debounce).
36
+ * Requires a configured storage backend.
37
+ */
38
+ persistDocument(docName: string, state: Uint8Array): Promise<void>;
30
39
  close(): Promise<void>;
31
40
  }
32
- export { YjsDriver, AutomergeDriver };
33
- export type { CollaborationDriver, CollaborationConfig, PresenceMember };
41
+ export { YjsDriver, AutomergeDriver, PartyKitDriver };
42
+ export type { CollaborationConfig, CollaborationDriver };
34
43
  //# sourceMappingURL=collaboration_manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collaboration_manager.d.ts","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,KAAK,cAAc,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtF,OAAO,KAAK,EAAiB,iBAAiB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEvG;;;GAGG;AACH,qBAAa,oBAAoB;IAKnB,OAAO,CAAC,MAAM;IAJ1B,OAAO,CAAC,MAAM,CAAsB;IACpC,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,cAAc,CAAC;gBAEL,MAAM,EAAE,mBAAmB;IAQ/C,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,4DAA4D;IACtD,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,uEAAuE;IACvE,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAItD,+DAA+D;IAC/D,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjD,aAAa,CACX,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,aAAa,CAAC;IAIzB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIvD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5F,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAInF,0DAA0D;IAC1D,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE;IAIzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B;AAED,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;AACtC,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"collaboration_manager.d.ts","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAExF;;;;;;;;;;GAUG;AACH,qBAAa,oBAAoB;IAInB,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,MAAM,CAAsB;IACpC,QAAQ,EAAE,cAAc,CAAC;gBAEL,MAAM,EAAE,mBAAmB;IA0B/C,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,gFAAgF;IAC1E,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,0EAA0E;IAC1E,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAItD,uDAAuD;IACvD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjD,aAAa,CACX,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,aAAa,CAAC;IAIzB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIvD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5F,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAInF;;;OAGG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IASlE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,CAAC"}
@@ -1,36 +1,60 @@
1
1
  import { AutomergeDriver } from './drivers/automerge/automerge_driver.js';
2
+ import { PartyKitDriver } from './drivers/partykit/partykit_driver.js';
3
+ import { resolveStorage } from './drivers/shared.js';
2
4
  import { YjsDriver } from './drivers/yjs/yjs_driver.js';
3
5
  import { CommentService } from './services/comment_service.js';
4
- import { PresenceService } from './services/presence_service.js';
5
- import { InMemoryCollaborationStorage } from './storage/in_memory_storage.js';
6
6
  /**
7
- * Fachada da lib: escolhe o driver pela config e expõe a API unificada
8
- * (documento + versões + presença + comentários) pro app hospedeiro.
7
+ * Library facade: picks the driver for the configured engine and exposes the
8
+ * unified API (documents + versions + comments) to the host app.
9
+ *
10
+ * Seams:
11
+ * - drivers connect only through the registry below;
12
+ * - comments live exclusively here (`manager.comments`) — drivers never
13
+ * touch them;
14
+ * - presence is owned by each engine at runtime (edge worker awareness or
15
+ * client-side), not by this process.
9
16
  */
10
17
  export class CollaborationManager {
11
18
  config;
12
19
  driver;
13
- presence;
14
20
  comments;
15
21
  constructor(config) {
16
22
  this.config = config;
17
- this.driver =
18
- config.engine === 'automerge' ? new AutomergeDriver(config) : new YjsDriver(config);
19
- this.presence = new PresenceService(config.redis?.url);
20
- this.comments = new CommentService(config.storage ?? new InMemoryCollaborationStorage());
23
+ const engine = config.engine ?? 'yjs';
24
+ const storage = config.storage;
25
+ if (engine === 'partykit') {
26
+ this.driver = new PartyKitDriver({
27
+ ...(storage ? { storage } : {}),
28
+ partykit: config.partykit,
29
+ });
30
+ }
31
+ else {
32
+ const shared = {
33
+ authorize: config.authorize,
34
+ };
35
+ const opts = {
36
+ ...shared,
37
+ ...(storage ? { storage } : {}),
38
+ ...(config.path !== undefined ? { path: config.path } : {}),
39
+ ...(config.debounce !== undefined ? { debounce: config.debounce } : {}),
40
+ };
41
+ this.driver = engine === 'automerge' ? new AutomergeDriver(opts) : new YjsDriver(opts);
42
+ }
43
+ // Single comments seam — one service, one storage instance.
44
+ this.comments = new CommentService(resolveStorage(storage));
21
45
  }
22
46
  get engine() {
23
47
  return this.driver.engine;
24
48
  }
25
- /** Anexa o WebSocket do driver no server HTTP do Adonis. */
49
+ /** Attaches the driver's WebSocket to the Adonis HTTP server. No-op on edge. */
26
50
  async attach(server) {
27
51
  await this.driver.attach(server);
28
52
  }
29
- /** Estado binário atual (pra push externo — Google Drive, export…). */
53
+ /** Current binary state (for external push — Google Drive, export...). */
30
54
  getDocumentState(docName) {
31
55
  return this.driver.getDocumentState(docName);
32
56
  }
33
- /** Texto plano (LanguageTool, RAG, índices de comentários). */
57
+ /** Plain text (LanguageTool, RAG, comment indexes). */
34
58
  getDocumentText(docName) {
35
59
  return this.driver.getDocumentText(docName);
36
60
  }
@@ -46,14 +70,19 @@ export class CollaborationManager {
46
70
  diffVersions(docName, aId, bId) {
47
71
  return this.driver.diffVersions(docName, aId, bId);
48
72
  }
49
- /** Membros online num documento (todas as instâncias). */
50
- listPresence(docName) {
51
- return this.presence.list(docName);
73
+ /**
74
+ * Persists an external snapshot (e.g. PartyKit worker post-debounce).
75
+ * Requires a configured storage backend.
76
+ */
77
+ async persistDocument(docName, state) {
78
+ if (!this.config.storage) {
79
+ throw new Error('persistDocument requires a storage backend — configure storage in config/collaboration.ts');
80
+ }
81
+ await this.config.storage.saveDocument(docName, state);
52
82
  }
53
83
  async close() {
54
84
  await this.driver.close();
55
- await this.presence.close();
56
85
  }
57
86
  }
58
- export { YjsDriver, AutomergeDriver };
87
+ export { YjsDriver, AutomergeDriver, PartyKitDriver };
59
88
  //# sourceMappingURL=collaboration_manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collaboration_manager.js","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAuB,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAG9E;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAKX;IAJZ,MAAM,CAAsB;IACpC,QAAQ,CAAkB;IAC1B,QAAQ,CAAiB;IAEzB,YAAoB,MAA2B;QAA3B,WAAM,GAAN,MAAM,CAAqB;QAC7C,IAAI,CAAC,MAAM;YACT,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAEtF,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,4BAA4B,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,MAAM,CAAC,MAAkC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,uEAAuE;IACvE,gBAAgB,CAAC,OAAe;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,+DAA+D;IAC/D,eAAe,CAAC,OAAe;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,aAAa,CACX,OAAe,EACf,SAAwB,EACxB,KAAqB;QAErB,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC;IACtE,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,cAAc,CAAC,OAAe,EAAE,SAAiB,EAAE,UAAyB;QAC1E,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACpE,CAAC;IAED,YAAY,CAAC,OAAe,EAAE,GAAW,EAAE,GAAW;QACpD,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,0DAA0D;IAC1D,YAAY,CAAC,OAAe;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;CACF;AAED,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"collaboration_manager.js","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"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"}