@adonis-agora/collaboration 0.11.0 → 0.13.0
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.
- package/CHANGELOG.md +156 -0
- package/dist/providers/collaboration_provider.d.ts.map +1 -1
- package/dist/providers/collaboration_provider.js +4 -0
- package/dist/providers/collaboration_provider.js.map +1 -1
- package/dist/src/auth/secret.d.ts +48 -0
- package/dist/src/auth/secret.d.ts.map +1 -0
- package/dist/src/auth/secret.js +95 -0
- package/dist/src/auth/secret.js.map +1 -0
- package/dist/src/auth/token.d.ts +111 -14
- package/dist/src/auth/token.d.ts.map +1 -1
- package/dist/src/auth/token.js +95 -14
- package/dist/src/auth/token.js.map +1 -1
- package/dist/src/collaboration_manager.d.ts +72 -7
- package/dist/src/collaboration_manager.d.ts.map +1 -1
- package/dist/src/collaboration_manager.js +131 -1
- package/dist/src/collaboration_manager.js.map +1 -1
- package/dist/src/define_config.d.ts +5 -0
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/documents.d.ts +100 -0
- package/dist/src/documents.d.ts.map +1 -1
- package/dist/src/documents.js +49 -0
- package/dist/src/documents.js.map +1 -1
- package/dist/src/driver.d.ts +53 -0
- package/dist/src/driver.d.ts.map +1 -1
- package/dist/src/driver.js +4 -1
- package/dist/src/driver.js.map +1 -1
- package/dist/src/drivers/automerge/automerge_driver.d.ts +25 -0
- package/dist/src/drivers/automerge/automerge_driver.d.ts.map +1 -1
- package/dist/src/drivers/automerge/automerge_driver.js +105 -16
- package/dist/src/drivers/automerge/automerge_driver.js.map +1 -1
- package/dist/src/drivers/partykit/partykit_driver.d.ts +5 -0
- package/dist/src/drivers/partykit/partykit_driver.d.ts.map +1 -1
- package/dist/src/drivers/partykit/partykit_driver.js +13 -7
- package/dist/src/drivers/partykit/partykit_driver.js.map +1 -1
- package/dist/src/drivers/yjs/yjs_driver.d.ts +16 -4
- package/dist/src/drivers/yjs/yjs_driver.d.ts.map +1 -1
- package/dist/src/drivers/yjs/yjs_driver.js +168 -17
- package/dist/src/drivers/yjs/yjs_driver.js.map +1 -1
- package/dist/src/http/types.d.ts +21 -3
- package/dist/src/http/types.d.ts.map +1 -1
- package/dist/src/http/types.js.map +1 -1
- package/dist/src/index.d.ts +9 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/observability.d.ts +11 -0
- package/dist/src/observability.d.ts.map +1 -1
- package/dist/src/observability.js +18 -0
- package/dist/src/observability.js.map +1 -1
- package/dist/src/routes.d.ts +74 -2
- package/dist/src/routes.d.ts.map +1 -1
- package/dist/src/routes.js +147 -9
- package/dist/src/routes.js.map +1 -1
- package/dist/src/types.d.ts +45 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/stubs/config/collaboration.stub +8 -0
- package/dist/stubs/partykit/worker/party.ts.stub +35 -4
- package/package.json +1 -1
package/dist/src/auth/token.js
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { resolveTokenSecret } from './secret.js';
|
|
3
|
+
/**
|
|
4
|
+
* Lifetime of a collaboration token, in seconds.
|
|
5
|
+
*
|
|
6
|
+
* Named rather than inlined because three places need the same number: the
|
|
7
|
+
* signature's `exp`, the `expiresAt` the issuer reports back so a caller
|
|
8
|
+
* holding the token ahead of time can tell it is already dead, and the
|
|
9
|
+
* client's decision to discard a page-prop token instead of opening a socket
|
|
10
|
+
* with it.
|
|
11
|
+
*
|
|
12
|
+
* Five minutes is what the edge format has always used, and the self-hosted
|
|
13
|
+
* one now matches it deliberately: the token is spent within milliseconds of
|
|
14
|
+
* being issued (the browser fetches it and connects), and a long-lived one
|
|
15
|
+
* would only widen the window in which a leaked URL still opens a document.
|
|
16
|
+
* The socket it opens is not cut short by expiry — `authorize` runs once at
|
|
17
|
+
* the handshake and the connection then lives on its own.
|
|
18
|
+
*/
|
|
19
|
+
export const COLLAB_TOKEN_TTL_SECONDS = 300;
|
|
20
|
+
/**
|
|
21
|
+
* The old name of {@link COLLAB_TOKEN_TTL_SECONDS}, kept because it is public
|
|
22
|
+
* API that apps and the worker template already read. One number, because one
|
|
23
|
+
* wire format: a second constant would eventually drift from this one and the
|
|
24
|
+
* drift would show up as tokens that expire earlier than the client thinks.
|
|
25
|
+
*/
|
|
26
|
+
export const PARTYKIT_TOKEN_TTL_SECONDS = COLLAB_TOKEN_TTL_SECONDS;
|
|
2
27
|
/** Signs a minimal HS256 JWT — no external dependency. */
|
|
3
|
-
export function
|
|
28
|
+
export function signCollabToken(payload, secret, expiresInSeconds = COLLAB_TOKEN_TTL_SECONDS) {
|
|
4
29
|
const header = { alg: 'HS256', typ: 'JWT' };
|
|
5
30
|
const now = Math.floor(Date.now() / 1000);
|
|
6
31
|
const body = { ...payload, iat: now, exp: now + expiresInSeconds };
|
|
@@ -9,20 +34,43 @@ export function signPartyKitToken(payload, secret, expiresInSeconds = 300) {
|
|
|
9
34
|
const signature = createHmac('sha256', secret).update(unsigned).digest('base64url');
|
|
10
35
|
return `${unsigned}.${signature}`;
|
|
11
36
|
}
|
|
12
|
-
/**
|
|
13
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Verifies signature, expiry and document binding of a token issued by
|
|
39
|
+
* {@link signCollabToken}. Returns `null` for every failure — a verifier that
|
|
40
|
+
* distinguishes "bad signature" from "wrong document" in its return value
|
|
41
|
+
* invites a caller to treat one of them as recoverable.
|
|
42
|
+
*
|
|
43
|
+
* `expectedDocName` is required rather than optional on purpose: every caller
|
|
44
|
+
* knows which document is being opened, and an optional argument is one a
|
|
45
|
+
* caller forgets — which is exactly the bug this parameter exists to prevent.
|
|
46
|
+
*/
|
|
47
|
+
export function verifyCollabToken(token, secret, expectedDocName) {
|
|
14
48
|
const parts = token.split('.');
|
|
15
49
|
if (parts.length !== 3)
|
|
16
50
|
return null;
|
|
17
51
|
const [header, body, signature] = parts;
|
|
18
52
|
const expected = createHmac('sha256', secret).update(`${header}.${body}`).digest();
|
|
19
53
|
const received = Buffer.from(signature, 'base64url');
|
|
54
|
+
// Constant time, and length-checked first because timingSafeEqual throws on
|
|
55
|
+
// a length mismatch instead of answering false.
|
|
20
56
|
if (received.length !== expected.length || !timingSafeEqual(received, expected)) {
|
|
21
57
|
return null;
|
|
22
58
|
}
|
|
23
59
|
try {
|
|
24
60
|
const parsed = JSON.parse(Buffer.from(body, 'base64url').toString());
|
|
25
|
-
|
|
61
|
+
// `exp` is checked for presence before being compared: an absent one makes
|
|
62
|
+
// `parsed.exp * 1000` NaN, and `NaN < Date.now()` is false — so a token
|
|
63
|
+
// with no expiry read as "not expired" and lived forever. Nothing this
|
|
64
|
+
// module signs omits it, so that needed the signing key to reach; a
|
|
65
|
+
// credential that never expires is still exactly the property this format
|
|
66
|
+
// exists to remove, and it must not be representable.
|
|
67
|
+
if (!parsed.userId || !parsed.docName)
|
|
68
|
+
return null;
|
|
69
|
+
if (typeof parsed.exp !== 'number' || !Number.isFinite(parsed.exp))
|
|
70
|
+
return null;
|
|
71
|
+
if (parsed.exp * 1000 < Date.now())
|
|
72
|
+
return null;
|
|
73
|
+
if (parsed.docName !== expectedDocName)
|
|
26
74
|
return null;
|
|
27
75
|
return parsed;
|
|
28
76
|
}
|
|
@@ -30,16 +78,42 @@ export function verifyPartyKitToken(token, secret) {
|
|
|
30
78
|
return null;
|
|
31
79
|
}
|
|
32
80
|
}
|
|
33
|
-
/**
|
|
34
|
-
export function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
81
|
+
/** The connection context a verified token stands for. */
|
|
82
|
+
export function tokenContext(payload) {
|
|
83
|
+
return {
|
|
84
|
+
userId: payload.userId,
|
|
85
|
+
...(payload.user ? { user: payload.user } : {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Verifies a self-hosted token against the key resolved from the app —
|
|
90
|
+
* what a driver's handshake calls.
|
|
91
|
+
*
|
|
92
|
+
* Throws (rather than returning `null`) when there is no key to verify
|
|
93
|
+
* against: a missing secret is a misconfiguration of the server, not a bad
|
|
94
|
+
* token from the client, and the two must not produce the same message in the
|
|
95
|
+
* logs. Either way nothing is authenticated.
|
|
96
|
+
*/
|
|
97
|
+
export async function verifySelfHostedToken(token, docName, source) {
|
|
98
|
+
const secret = await resolveTokenSecret(source);
|
|
99
|
+
const payload = verifyCollabToken(token, secret, docName);
|
|
100
|
+
return payload ? tokenContext(payload) : null;
|
|
42
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Signs the edge JWT. Same format and same TTL as every other collaboration
|
|
104
|
+
* token; the difference is the key, which the PartyKit worker holds
|
|
105
|
+
* (`COLLAB_JWT_SECRET`) and this process only shares with it.
|
|
106
|
+
*/
|
|
107
|
+
export const signPartyKitToken = signCollabToken;
|
|
108
|
+
/**
|
|
109
|
+
* Verifies an edge JWT, including its document binding.
|
|
110
|
+
*
|
|
111
|
+
* The worker template runs the same three checks in WebCrypto — signature,
|
|
112
|
+
* `exp`, and `docName` against the room being connected to. Keep them in
|
|
113
|
+
* step: the room is the document, so a token that opens a room it was not
|
|
114
|
+
* issued for is the same hole on the edge that it is here.
|
|
115
|
+
*/
|
|
116
|
+
export const verifyPartyKitToken = verifyCollabToken;
|
|
43
117
|
/** Builds the browser-facing WebSocket URL for an engine. */
|
|
44
118
|
export function buildWsUrl(config, docName) {
|
|
45
119
|
if (config.engine === 'partykit') {
|
|
@@ -103,12 +177,19 @@ export async function issueToken(config, user, docName, authorize) {
|
|
|
103
177
|
token: signPartyKitToken({ userId: user.id, docName }, config.partykit.jwtSecret),
|
|
104
178
|
wsUrl: buildWsUrl(config, docName),
|
|
105
179
|
engine: config.engine,
|
|
180
|
+
expiresAt: Date.now() + COLLAB_TOKEN_TTL_SECONDS * 1000,
|
|
106
181
|
};
|
|
107
182
|
}
|
|
183
|
+
// Self-hosted. Signed with the app's key, bound to this document and dead
|
|
184
|
+
// in five minutes — resolved before anything is returned, so a server with
|
|
185
|
+
// no key configured refuses to issue rather than handing out a credential
|
|
186
|
+
// its own handshake will reject.
|
|
187
|
+
const secret = await resolveTokenSecret(config.tokenSecret);
|
|
108
188
|
return {
|
|
109
|
-
token:
|
|
189
|
+
token: signCollabToken({ userId: user.id, docName, ...(ctx.user ? { user: ctx.user } : {}) }, secret),
|
|
110
190
|
wsUrl: buildWsUrl(config, docName),
|
|
111
191
|
engine: config.engine,
|
|
192
|
+
expiresAt: Date.now() + COLLAB_TOKEN_TTL_SECONDS * 1000,
|
|
112
193
|
};
|
|
113
194
|
}
|
|
114
195
|
//# sourceMappingURL=token.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../../src/auth/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../../src/auth/token.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,16 +4,11 @@ import { PartyKitDriver } from './drivers/partykit/partykit_driver.js';
|
|
|
4
4
|
import { YjsDriver } from './drivers/yjs/yjs_driver.js';
|
|
5
5
|
import { CommentService } from './services/comment_service.js';
|
|
6
6
|
import { type PresenceMember, PresenceService, type PresenceStore } from './services/presence_service.js';
|
|
7
|
-
import type { CollabConnectionContext, CollabDiffSummary, CollaborationConfig, CollaborationEngine, CollabPermission, CollabVersion, PruneVersionsOptions } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Library facade. Each document resolves to an engine (per-doc via
|
|
10
|
-
* `config.engineFor`, default `config.engine`) and a driver instance per
|
|
11
|
-
* engine is built lazily on first use. Self-hosted drivers attach their
|
|
12
|
-
* WebSocket to the HTTP server the first time a document uses them.
|
|
13
|
-
*/
|
|
7
|
+
import type { CollabConnectionContext, CollabDiffSummary, CollaborationConfig, CollaborationEngine, CollabPermission, CollabVersion, LiveDocumentResult, PruneVersionsOptions } from './types.js';
|
|
14
8
|
export declare class CollaborationManager {
|
|
15
9
|
#private;
|
|
16
10
|
private readonly config;
|
|
11
|
+
private tokenSecretPromise;
|
|
17
12
|
private readonly drivers;
|
|
18
13
|
private server?;
|
|
19
14
|
comments: CommentService;
|
|
@@ -33,6 +28,20 @@ export declare class CollaborationManager {
|
|
|
33
28
|
*/
|
|
34
29
|
authorize(ctx: CollabConnectionContext, docName: string): Promise<CollabPermission>;
|
|
35
30
|
get engine(): string;
|
|
31
|
+
/**
|
|
32
|
+
* The key that signs and verifies this app's collaboration tokens.
|
|
33
|
+
*
|
|
34
|
+
* Public for the same reason `authorize` is: the credential has two ends —
|
|
35
|
+
* the REST route that issues it and the WebSocket handshake that checks it
|
|
36
|
+
* — and they must resolve it identically. The routes ask the manager rather
|
|
37
|
+
* than repeating the resolution order, so `tokenSecret` in
|
|
38
|
+
* `config/collaboration.ts` (or on this constructor) applies to both, and
|
|
39
|
+
* neither can silently fall back to a different key.
|
|
40
|
+
*
|
|
41
|
+
* Memoized on the promise rather than the value, so two documents opening
|
|
42
|
+
* at once share one read of the app config instead of racing it.
|
|
43
|
+
*/
|
|
44
|
+
tokenSecret(): Promise<string>;
|
|
36
45
|
/** Attaches the WebSocket(s) to the Adonis HTTP server. No-op on edge. */
|
|
37
46
|
attach(server: import('node:http').Server): Promise<void>;
|
|
38
47
|
getDocumentState({ docName }: {
|
|
@@ -41,6 +50,52 @@ export declare class CollaborationManager {
|
|
|
41
50
|
getDocumentText({ docName }: {
|
|
42
51
|
docName: string;
|
|
43
52
|
}): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Runs `run` against the **live** document — the in-process CRDT instance
|
|
55
|
+
* the connected clients are syncing with — and says whether there was one.
|
|
56
|
+
*
|
|
57
|
+
* `getDocumentState` answers with a copy, which is enough to export a
|
|
58
|
+
* document and not enough to change one: an external edit (a Drive webhook,
|
|
59
|
+
* a cron) has to land in the instance people are typing into, or it either
|
|
60
|
+
* loses the keystrokes since the last flush or is lost by them. So this is
|
|
61
|
+
* scoped rather than a getter — the document is only borrowed for the
|
|
62
|
+
* duration of `run`, and a caller cannot stash a `Y.Doc` that Hocuspocus
|
|
63
|
+
* will unload out from under it.
|
|
64
|
+
*
|
|
65
|
+
* The callback gets the engine's real document, deliberately. The manager
|
|
66
|
+
* is engine-agnostic everywhere it routes; here it hands over the one thing
|
|
67
|
+
* a wrapper could not replace (`transact()` that fans out to clients), and
|
|
68
|
+
* keeps its agnosticism by *asking* whether the engine has such a document
|
|
69
|
+
* instead of assuming it: a PartyKit document lives on the edge and comes
|
|
70
|
+
* back `{ live: false, reason: 'engine-has-no-live-document' }` with the
|
|
71
|
+
* callback never run, not a cast that explodes.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const result = await collaboration.current.withLiveDocument({
|
|
75
|
+
* docName,
|
|
76
|
+
* run: (doc) => {
|
|
77
|
+
* doc.transact(() => applyExternalChange(doc))
|
|
78
|
+
* return doc.getXmlFragment('default').toString()
|
|
79
|
+
* },
|
|
80
|
+
* })
|
|
81
|
+
* if (!result.live) await mergeIntoStorageInstead()
|
|
82
|
+
*/
|
|
83
|
+
withLiveDocument<T>({ docName, run, }: {
|
|
84
|
+
docName: string;
|
|
85
|
+
run: (document: import('yjs').Doc) => T | Promise<T>;
|
|
86
|
+
}): Promise<LiveDocumentResult<T>>;
|
|
87
|
+
/**
|
|
88
|
+
* Whether this process is holding the document open right now.
|
|
89
|
+
*
|
|
90
|
+
* The cheap question on its own, for callers deciding *where* to write
|
|
91
|
+
* before they know what to write. It is a snapshot of a live fact — the
|
|
92
|
+
* last client can disconnect a millisecond later — so anything that then
|
|
93
|
+
* touches the document should go through {@link withLiveDocument} and read
|
|
94
|
+
* its `live` flag rather than trusting this answer.
|
|
95
|
+
*/
|
|
96
|
+
hasLiveDocument({ docName }: {
|
|
97
|
+
docName: string;
|
|
98
|
+
}): Promise<boolean>;
|
|
44
99
|
createVersion({ docName, createdBy, label, }: {
|
|
45
100
|
docName: string;
|
|
46
101
|
createdBy: string | null;
|
|
@@ -49,6 +104,16 @@ export declare class CollaborationManager {
|
|
|
49
104
|
listVersions({ docName }: {
|
|
50
105
|
docName: string;
|
|
51
106
|
}): Promise<CollabVersion[]>;
|
|
107
|
+
/**
|
|
108
|
+
* Binary state stored for one version — `getDocumentState` for a point in
|
|
109
|
+
* the history. Extracting the text of a version, diffing it against
|
|
110
|
+
* something the library does not know about, exporting it: all of that
|
|
111
|
+
* needs the bytes, and `listVersions` only hands out metadata.
|
|
112
|
+
*/
|
|
113
|
+
getVersionState({ docName, versionId, }: {
|
|
114
|
+
docName: string;
|
|
115
|
+
versionId: string;
|
|
116
|
+
}): Promise<Uint8Array>;
|
|
52
117
|
restoreVersion({ docName, versionId, restoredBy, }: {
|
|
53
118
|
docName: string;
|
|
54
119
|
versionId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collaboration_manager.d.ts","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collaboration_manager.d.ts","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveTokenSecret } from './auth/secret.js';
|
|
2
|
+
import { documentPatternParams, matchDocumentPattern } from './documents.js';
|
|
3
|
+
import { supportsLiveDocuments } from './driver.js';
|
|
2
4
|
import { AutomergeDriver } from './drivers/automerge/automerge_driver.js';
|
|
3
5
|
import { PartyKitDriver } from './drivers/partykit/partykit_driver.js';
|
|
4
6
|
import { resolveStorage } from './drivers/shared.js';
|
|
5
7
|
import { YjsDriver } from './drivers/yjs/yjs_driver.js';
|
|
8
|
+
import { reportCollaborationWarning } from './observability.js';
|
|
6
9
|
import { CommentService } from './services/comment_service.js';
|
|
7
10
|
import { PresenceService, } from './services/presence_service.js';
|
|
8
11
|
/**
|
|
@@ -11,14 +14,29 @@ import { PresenceService, } from './services/presence_service.js';
|
|
|
11
14
|
* engine is built lazily on first use. Self-hosted drivers attach their
|
|
12
15
|
* WebSocket to the HTTP server the first time a document uses them.
|
|
13
16
|
*/
|
|
17
|
+
/**
|
|
18
|
+
* A pattern without a `:segment` matches exactly one document — almost never
|
|
19
|
+
* what a `documents` entry means. Say so once, at boot, with the fix.
|
|
20
|
+
*/
|
|
21
|
+
function warnAboutSingleDocumentPatterns(documents) {
|
|
22
|
+
for (const pattern of Object.keys(documents ?? {})) {
|
|
23
|
+
if (documentPatternParams(pattern).length > 0)
|
|
24
|
+
continue;
|
|
25
|
+
reportCollaborationWarning({ pattern }, `document pattern "${pattern}" has no ":param" segment, so it matches exactly one document ` +
|
|
26
|
+
`named "${pattern}" — not "${pattern}/<id>". If it is a collection, declare ` +
|
|
27
|
+
`"${pattern}/:id" or use defineCollection("${pattern}", …).`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
14
30
|
export class CollaborationManager {
|
|
15
31
|
config;
|
|
32
|
+
tokenSecretPromise;
|
|
16
33
|
drivers = new Map();
|
|
17
34
|
server;
|
|
18
35
|
comments;
|
|
19
36
|
presence;
|
|
20
37
|
constructor(config, presenceStore) {
|
|
21
38
|
this.config = config;
|
|
39
|
+
warnAboutSingleDocumentPatterns(config.documents);
|
|
22
40
|
this.comments = new CommentService(resolveStorage(config.storage));
|
|
23
41
|
if (presenceStore) {
|
|
24
42
|
this.presence = new PresenceService(presenceStore);
|
|
@@ -64,9 +82,52 @@ export class CollaborationManager {
|
|
|
64
82
|
return this.config.authorize(ctx, docName);
|
|
65
83
|
return { canRead: false, canWrite: false, canComment: false };
|
|
66
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Initial content for a document nothing has stored yet: the matched
|
|
87
|
+
* declaration's `load`, or nothing.
|
|
88
|
+
*
|
|
89
|
+
* Resolved here, next to `authorize`, because both answers come from the
|
|
90
|
+
* same declaration and the same pattern match — a driver that had to find
|
|
91
|
+
* the declaration itself would be a second matcher to keep in step with the
|
|
92
|
+
* first. Private: the drivers ask, at the one moment the answer is usable.
|
|
93
|
+
*/
|
|
94
|
+
async #seedFor(docName) {
|
|
95
|
+
const declared = this.#documentFor(docName);
|
|
96
|
+
if (!declared?.declaration.load)
|
|
97
|
+
return undefined;
|
|
98
|
+
return declared.declaration.load({ docName, params: declared.params });
|
|
99
|
+
}
|
|
67
100
|
get engine() {
|
|
68
101
|
return this.config.engine ?? 'yjs';
|
|
69
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* The key that signs and verifies this app's collaboration tokens.
|
|
105
|
+
*
|
|
106
|
+
* Public for the same reason `authorize` is: the credential has two ends —
|
|
107
|
+
* the REST route that issues it and the WebSocket handshake that checks it
|
|
108
|
+
* — and they must resolve it identically. The routes ask the manager rather
|
|
109
|
+
* than repeating the resolution order, so `tokenSecret` in
|
|
110
|
+
* `config/collaboration.ts` (or on this constructor) applies to both, and
|
|
111
|
+
* neither can silently fall back to a different key.
|
|
112
|
+
*
|
|
113
|
+
* Memoized on the promise rather than the value, so two documents opening
|
|
114
|
+
* at once share one read of the app config instead of racing it.
|
|
115
|
+
*/
|
|
116
|
+
tokenSecret() {
|
|
117
|
+
if (!this.tokenSecretPromise) {
|
|
118
|
+
const resolving = resolveTokenSecret(this.config.tokenSecret);
|
|
119
|
+
this.tokenSecretPromise = resolving;
|
|
120
|
+
// The failure is never memoized — a manager built before the app
|
|
121
|
+
// finished booting has no app key to read yet, and remembering that as
|
|
122
|
+
// "there is no key" would outlive the condition that caused it. The
|
|
123
|
+
// handler also keeps the rejection from surfacing as unhandled; every
|
|
124
|
+
// caller still sees it through the promise this returns.
|
|
125
|
+
void resolving.catch(() => {
|
|
126
|
+
this.tokenSecretPromise = undefined;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return this.tokenSecretPromise;
|
|
130
|
+
}
|
|
70
131
|
#buildDriver(engine) {
|
|
71
132
|
const storage = this.config.storage;
|
|
72
133
|
if (engine === 'partykit' || engine === 'partyserver') {
|
|
@@ -77,6 +138,13 @@ export class CollaborationManager {
|
|
|
77
138
|
}
|
|
78
139
|
const shared = {
|
|
79
140
|
authorize: (ctx, docName) => this.authorize(ctx, docName),
|
|
141
|
+
// Deferred, not resolved here: the default key is the app's `appKey`,
|
|
142
|
+
// and drivers are built before the app is necessarily booted. Passing
|
|
143
|
+
// the same accessor the token route uses is what keeps the two ends of
|
|
144
|
+
// the credential on one source — sign with one key and verify with
|
|
145
|
+
// another and every handshake fails with nothing to point at.
|
|
146
|
+
tokenSecret: () => this.tokenSecret(),
|
|
147
|
+
seedDocument: (docName) => this.#seedFor(docName),
|
|
80
148
|
...(storage ? { storage } : {}),
|
|
81
149
|
// Without this the presence store the provider builds from `redisUrl`
|
|
82
150
|
// is never reached: the drivers' join/leave both guard on
|
|
@@ -120,12 +188,74 @@ export class CollaborationManager {
|
|
|
120
188
|
getDocumentText({ docName }) {
|
|
121
189
|
return this.#driverFor(docName).then((driver) => driver.getDocumentText(docName));
|
|
122
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Runs `run` against the **live** document — the in-process CRDT instance
|
|
193
|
+
* the connected clients are syncing with — and says whether there was one.
|
|
194
|
+
*
|
|
195
|
+
* `getDocumentState` answers with a copy, which is enough to export a
|
|
196
|
+
* document and not enough to change one: an external edit (a Drive webhook,
|
|
197
|
+
* a cron) has to land in the instance people are typing into, or it either
|
|
198
|
+
* loses the keystrokes since the last flush or is lost by them. So this is
|
|
199
|
+
* scoped rather than a getter — the document is only borrowed for the
|
|
200
|
+
* duration of `run`, and a caller cannot stash a `Y.Doc` that Hocuspocus
|
|
201
|
+
* will unload out from under it.
|
|
202
|
+
*
|
|
203
|
+
* The callback gets the engine's real document, deliberately. The manager
|
|
204
|
+
* is engine-agnostic everywhere it routes; here it hands over the one thing
|
|
205
|
+
* a wrapper could not replace (`transact()` that fans out to clients), and
|
|
206
|
+
* keeps its agnosticism by *asking* whether the engine has such a document
|
|
207
|
+
* instead of assuming it: a PartyKit document lives on the edge and comes
|
|
208
|
+
* back `{ live: false, reason: 'engine-has-no-live-document' }` with the
|
|
209
|
+
* callback never run, not a cast that explodes.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* const result = await collaboration.current.withLiveDocument({
|
|
213
|
+
* docName,
|
|
214
|
+
* run: (doc) => {
|
|
215
|
+
* doc.transact(() => applyExternalChange(doc))
|
|
216
|
+
* return doc.getXmlFragment('default').toString()
|
|
217
|
+
* },
|
|
218
|
+
* })
|
|
219
|
+
* if (!result.live) await mergeIntoStorageInstead()
|
|
220
|
+
*/
|
|
221
|
+
async withLiveDocument({ docName, run, }) {
|
|
222
|
+
const driver = await this.#driverFor(docName);
|
|
223
|
+
if (!supportsLiveDocuments(driver)) {
|
|
224
|
+
return { live: false, reason: 'engine-has-no-live-document' };
|
|
225
|
+
}
|
|
226
|
+
const document = driver.liveDocument(docName);
|
|
227
|
+
if (!document)
|
|
228
|
+
return { live: false, reason: 'not-loaded' };
|
|
229
|
+
return { live: true, value: await run(document) };
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Whether this process is holding the document open right now.
|
|
233
|
+
*
|
|
234
|
+
* The cheap question on its own, for callers deciding *where* to write
|
|
235
|
+
* before they know what to write. It is a snapshot of a live fact — the
|
|
236
|
+
* last client can disconnect a millisecond later — so anything that then
|
|
237
|
+
* touches the document should go through {@link withLiveDocument} and read
|
|
238
|
+
* its `live` flag rather than trusting this answer.
|
|
239
|
+
*/
|
|
240
|
+
async hasLiveDocument({ docName }) {
|
|
241
|
+
const driver = await this.#driverFor(docName);
|
|
242
|
+
return supportsLiveDocuments(driver) && driver.liveDocument(docName) !== undefined;
|
|
243
|
+
}
|
|
123
244
|
createVersion({ docName, createdBy, label = null, }) {
|
|
124
245
|
return this.#driverFor(docName).then((driver) => driver.createVersion(docName, createdBy, label));
|
|
125
246
|
}
|
|
126
247
|
listVersions({ docName }) {
|
|
127
248
|
return this.#driverFor(docName).then((driver) => driver.listVersions(docName));
|
|
128
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Binary state stored for one version — `getDocumentState` for a point in
|
|
252
|
+
* the history. Extracting the text of a version, diffing it against
|
|
253
|
+
* something the library does not know about, exporting it: all of that
|
|
254
|
+
* needs the bytes, and `listVersions` only hands out metadata.
|
|
255
|
+
*/
|
|
256
|
+
getVersionState({ docName, versionId, }) {
|
|
257
|
+
return this.#driverFor(docName).then((driver) => driver.getVersionState(docName, versionId));
|
|
258
|
+
}
|
|
129
259
|
restoreVersion({ docName, versionId, restoredBy, }) {
|
|
130
260
|
return this.#driverFor(docName).then((driver) => driver.restoreVersion(docName, versionId, restoredBy));
|
|
131
261
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collaboration_manager.js","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"collaboration_manager.js","sourceRoot":"","sources":["../../src/collaboration_manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,11 @@ export type CollaborationAppConfig = {
|
|
|
13
13
|
path?: string;
|
|
14
14
|
redisUrl?: string;
|
|
15
15
|
debounce?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Signing key for collaboration tokens. Defaults to a key derived from the
|
|
18
|
+
* app's `appKey` — set this only for a dedicated secret.
|
|
19
|
+
*/
|
|
20
|
+
tokenSecret?: string;
|
|
16
21
|
authorize?: CollaborationConfig['authorize'];
|
|
17
22
|
/** Omitted = in-memory (dev only). Production passes a persistent storage. */
|
|
18
23
|
storage?: CollaborationConfig['storage'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,OAAO,CAAC,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACzC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACP,qBAAqB;QACrB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,iCAAiC;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,qEAAqE;QACrE,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;QACvB,8DAA8D;QAC9D,WAAW,CAAC,EAAE,aAAa,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,MAAM,IAAI;KACnD,CAAC,IAAI,OAAO,GAAG,yBAAyB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;CAC7D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,yBAAyB,CAAC,OAAO,SAAS,MAAM,IAAI,IAAI,CAClE,sBAAsB,EACtB,WAAW,CACZ,GAAG;IACF,SAAS,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAS,MAAM,GAAG,KAAK,EACzD,MAAM,EAAE,yBAAyB,CAAC,OAAO,CAAC,GACzC,yBAAyB,CAAC,OAAO,CAAC,CAEpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GACvE,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GACrC,KAAK,CAAC;AAEV;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,CAAC,OAAO,SAAS,MAAM,IACtD,OAAO,SAAS,GAAG,MAAM,IAAI,KAAK,MAAM,IAAI,EAAE,GAC1C,IAAI,SAAS,GAAG,MAAM,IAAI,MAAM,IAAI,EAAE,GACpC,GAAG,IAAI,IAAI,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,GAClD,GAAG,IAAI,IAAI,MAAM,EAAE,GACrB,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,OAAO,CAAC,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACzC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE;QACP,qBAAqB;QACrB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,iCAAiC;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,qEAAqE;QACrE,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;QACvB,8DAA8D;QAC9D,WAAW,CAAC,EAAE,aAAa,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,MAAM,IAAI;KACnD,CAAC,IAAI,OAAO,GAAG,yBAAyB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;CAC7D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,yBAAyB,CAAC,OAAO,SAAS,MAAM,IAAI,IAAI,CAClE,sBAAsB,EACtB,WAAW,CACZ,GAAG;IACF,SAAS,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAS,MAAM,GAAG,KAAK,EACzD,MAAM,EAAE,yBAAyB,CAAC,OAAO,CAAC,GACzC,yBAAyB,CAAC,OAAO,CAAC,CAEpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GACvE,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GACrC,KAAK,CAAC;AAEV;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,CAAC,OAAO,SAAS,MAAM,IACtD,OAAO,SAAS,GAAG,MAAM,IAAI,KAAK,MAAM,IAAI,EAAE,GAC1C,IAAI,SAAS,GAAG,MAAM,IAAI,MAAM,IAAI,EAAE,GACpC,GAAG,IAAI,IAAI,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,GAClD,GAAG,IAAI,IAAI,MAAM,EAAE,GACrB,OAAO,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AA+DA;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAC1B,MAA0C;IAE1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|