@palantir/pack.state.foundry-event 0.0.2 → 0.1.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/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-transpileBrowser.log +1 -1
- package/.turbo/turbo-transpileCjs.log +1 -1
- package/.turbo/turbo-transpileEsm.log +1 -1
- package/.turbo/turbo-transpileTypes.log +1 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +14 -0
- package/build/browser/index.js +5 -5
- package/build/browser/index.js.map +1 -1
- package/build/cjs/index.cjs +5 -5
- package/build/cjs/index.cjs.map +1 -1
- package/build/esm/index.js +5 -5
- package/build/esm/index.js.map +1 -1
- package/build/types/FoundryEventService.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/FoundryEventService.ts +6 -5
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @palantir/pack.state.foundry-event@0.0
|
|
2
|
+
> @palantir/pack.state.foundry-event@0.1.0 lint /home/runner/work/pack/pack/packages/state/foundry-event
|
|
3
3
|
> eslint ./src && dprint check --config $(find-up dprint.json) --allow-no-files
|
|
4
4
|
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @palantir/pack.state.foundry-event@0.0
|
|
2
|
+
> @palantir/pack.state.foundry-event@0.1.0 transpileBrowser /home/runner/work/pack/pack/packages/state/foundry-event
|
|
3
3
|
> monorepo-transpile -f esm -m bundle -t browser
|
|
4
4
|
|
|
5
5
|
👍
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @palantir/pack.state.foundry-event@0.0
|
|
2
|
+
> @palantir/pack.state.foundry-event@0.1.0 transpileCjs /home/runner/work/pack/pack/packages/state/foundry-event
|
|
3
3
|
> monorepo-transpile -f cjs -m bundle -t node
|
|
4
4
|
|
|
5
5
|
👍
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @palantir/pack.state.foundry-event@0.0
|
|
2
|
+
> @palantir/pack.state.foundry-event@0.1.0 transpileEsm /home/runner/work/pack/pack/packages/state/foundry-event
|
|
3
3
|
> monorepo-transpile -f esm -m bundle -t node
|
|
4
4
|
|
|
5
5
|
👍
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @palantir/pack.state.foundry-event@0.0
|
|
2
|
+
> @palantir/pack.state.foundry-event@0.1.0 transpileTypes /home/runner/work/pack/pack/packages/state/foundry-event
|
|
3
3
|
> monorepo-transpile -f esm -m types -t node
|
|
4
4
|
|
|
5
5
|
👍
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @palantir/pack.state.foundry-event
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- dfeaeb0: Fix bug in core, where multiple yDocs could get created, causing the initial update to be dropped
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [dfeaeb0]
|
|
12
|
+
- @palantir/pack.document-schema.model-types@0.2.0
|
|
13
|
+
- @palantir/pack.state.core@0.2.0
|
|
14
|
+
- @palantir/pack.auth@0.1.0
|
|
15
|
+
- @palantir/pack.core@0.2.0
|
|
16
|
+
|
|
3
17
|
## 0.0.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/build/browser/index.js
CHANGED
|
@@ -237,7 +237,7 @@ var FoundryEventService = class {
|
|
|
237
237
|
lastRevisionId: void 0,
|
|
238
238
|
localYDocUpdateHandler: void 0,
|
|
239
239
|
presenceSubscriptionId: void 0,
|
|
240
|
-
yDoc
|
|
240
|
+
yDoc
|
|
241
241
|
};
|
|
242
242
|
this.sessions.set(sessionId, session);
|
|
243
243
|
}
|
|
@@ -285,7 +285,7 @@ var FoundryEventService = class {
|
|
|
285
285
|
if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {
|
|
286
286
|
return;
|
|
287
287
|
}
|
|
288
|
-
this.handleDocumentUpdateMessage(session, message, onStatusChange);
|
|
288
|
+
this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);
|
|
289
289
|
}, () => ({
|
|
290
290
|
clientId: session.clientId,
|
|
291
291
|
lastRevisionId: session.lastRevisionId?.toString()
|
|
@@ -414,7 +414,7 @@ var FoundryEventService = class {
|
|
|
414
414
|
return;
|
|
415
415
|
}
|
|
416
416
|
if (internalSession.localYDocUpdateHandler != null) {
|
|
417
|
-
internalSession.yDoc
|
|
417
|
+
internalSession.yDoc?.off("update", internalSession.localYDocUpdateHandler);
|
|
418
418
|
internalSession.localYDocUpdateHandler = void 0;
|
|
419
419
|
}
|
|
420
420
|
if (internalSession.activitySubscriptionId) {
|
|
@@ -428,7 +428,7 @@ var FoundryEventService = class {
|
|
|
428
428
|
this.sessions.delete(sessionId);
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
|
-
handleDocumentUpdateMessage(session, message, onStatusChange) {
|
|
431
|
+
handleDocumentUpdateMessage(session, message, yDoc, onStatusChange) {
|
|
432
432
|
switch (message.type) {
|
|
433
433
|
case "error":
|
|
434
434
|
const {
|
|
@@ -478,7 +478,7 @@ var FoundryEventService = class {
|
|
|
478
478
|
});
|
|
479
479
|
session.lastRevisionId = Number(revisionId);
|
|
480
480
|
if (data != null) {
|
|
481
|
-
y.applyUpdate(
|
|
481
|
+
y.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);
|
|
482
482
|
}
|
|
483
483
|
onStatusChange({
|
|
484
484
|
load: DocumentLoadStatus.LOADED
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cometd/EventServiceCometD.ts","../../src/FoundryEventService.ts"],"names":["getAuthModule"],"mappings":";;;;;;;;;;AAoBA,IAAM,kBAAA,GAAqB,cAAA;AAC3B,IAAM,aAAA,GAAgB,cAAA;AACtB,IAAM,yBAAA,GAA4B,gBAAA;AAClC,IAAM,sBAAA,GAAyB,iBAAA;AACxB,IAAM,qBAAN,MAAyB;AAAA,EAC9B,MAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA,uBAAuB,GAAA,EAAI;AAAA,EAC3B,cAAA,GAAiB,IAAI,cAAA,EAAe;AAAA,EACpC,sBAAA,GAAyB,CAAA;AAAA,EACzB,WAAA,CAAY,GAAA,EAAK,MAAA,GAAS,IAAI,QAAO,EAAG;AACtC,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,SAAS,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,EAAC,EAAG;AAAA,MACxC,SAAA,EAAW;AAAA,KACZ,CAAA;AACD,IAAA,IAAA,CAAK,eAAA,EAAgB;AACrB,IAAA,IAAA,CAAK,MAAA,CAAO,iBAAA,CAAkB,aAAA,EAAe,IAAI,cAAc,CAAA;AAC/D,IAAA,IAAA,CAAK,MAAA,CAAO,iBAAA,CAAkB,yBAAA,EAA2B,IAAA,CAAK,cAAc,CAAA;AAO5E,IAAA,aAAA,CAAc,GAAG,CAAA,CAAE,aAAA,CAAc,CAAA,KAAA,KAAS;AACxC,MAAA,IAAA,CAAK,cAAA,CAAe,SAAS,KAAK,CAAA;AAAA,IACpC,CAAC,CAAA;AAAA,EACH;AAAA,EACA,UAAA,GAAa;AACX,IAAA,IAAI,IAAA,CAAK,qBAAqB,IAAA,EAAM;AAClC,MAAA,OAAO,IAAA,CAAK,iBAAA;AAAA,IACd;AACA,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW;AAC9C,MAAA,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,sBAAA,EAAwB,CAAC;AAAA,QAC/C,QAAA;AAAA,QACA,cAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,OACF,KAAM;AACJ,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,IAAA,CAAK,MAAA,CAAO,KAAK,6BAAA,EAA+B;AAAA,YAC9C,QAAA;AAAA,YACA;AAAA,WACD,CAAA;AACD,UAAA,OAAA,EAAQ;AACR,UAAA,IAAA,CAAK,MAAA,CAAO,MAAM,MAAM;AACtB,YAAA,IAAA,CAAK,gBAAA,CAAiB,OAAA,CAAQ,CAAC,YAAA,EAAc,cAAA,KAAmB;AAC9D,cAAA,IAAA,CAAK,MAAA,CAAO,MAAM,0BAAA,EAA4B;AAAA,gBAC5C,SAAS,YAAA,CAAa,YAAA;AAAA,gBACtB;AAAA,eACD,CAAA;AACD,cAAA,MAAM,cAAA,GAAiB,aAAa,sBAAA,IAAyB;AAC7D,cAAA,YAAA,CAAa,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,aAAa,MAAA,EAAQ;AAAA,gBACjE,GAAA,EAAK;AAAA,eACN,CAAA;AAAA,YACH,CAAC,CAAA;AAAA,UACH,CAAC,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,MAAA,CAAO,KAAK,yBAAA,EAA2B;AAAA,YAC1C,QAAA;AAAA,YACA;AAAA,WACD,CAAA;AAAA,QACH;AAAA,MACF,CAAC,CAAA;AACD,MAAA,MAAM,UAAA,GAAa,aAAA,CAAc,IAAA,CAAK,GAAG,CAAA;AACzC,MAAA,KAAK,UAAA,CAAW,QAAA,EAAS,CAAE,IAAA,CAAK,CAAA,KAAA,KAAS;AACvC,QAAA,IAAA,CAAK,MAAA,CAAO,KAAK,gCAAgC,CAAA;AACjD,QAAA,IAAA,CAAK,cAAA,CAAe,SAAS,KAAK,CAAA;AAClC,QAAA,IAAA,CAAK,OAAO,SAAA,EAAU;AAAA,MACxB,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,iBAAA;AAAA,EACd;AAAA,EACA,MAAM,SAAA,CAAU,OAAA,EAAS,SAAA,EAAW,sBAAA,EAAwB;AAC1D,IAAA,MAAM,KAAK,UAAA,EAAW;AACtB,IAAA,MAAM,cAAA,GAAA,CAAkB,IAAA,CAAK,sBAAA,EAAA,EAA0B,QAAA,CAAS,EAAE,CAAA;AAClE,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,iBAAiB,CAAA,YAAA,KAAgB;AACrC,QAAA,IAAI,CAAC,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,cAAc,CAAA,EAAG;AAC9C,UAAA,IAAA,CAAK,MAAA,CAAO,KAAK,4CAAA,EAA8C;AAAA,YAC7D,OAAA;AAAA,YACA;AAAA,WACD,CAAA;AACD,UAAA;AAAA,QACF;AACA,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,6BAAA,EAA+B;AAAA,UAC/C,OAAA;AAAA,UACA,cAAA;AAAA,UACA,OAAA,EAAS,aAAa,IAAA,IAAQ;AAAA,SAC/B,CAAA;AACD,QAAA,SAAA,CAAU,aAAa,IAAI,CAAA;AAAA,MAC7B,CAAA;AACA,MAAA,MAAM,oBAAoB,CAAA,OAAA,KAAW;AACnC,QAAA,IAAI,QAAQ,UAAA,EAAY;AACtB,UAAA,IAAA,CAAK,MAAA,CAAO,MAAM,oCAAA,EAAsC;AAAA,YACtD,OAAA;AAAA,YACA;AAAA,WACD,CAAA;AACD,UAAA,OAAA,CAAQ,cAAc,CAAA;AAAA,QACxB,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,cAAc,CAAA;AAE3C,UAAA,MAAM,qBAAqB,SAAA,IAAa,OAAA,IAAW,OAAO,OAAA,CAAQ,OAAA,KAAY,YAAY,OAAA,CAAQ,OAAA,IAAW,YAAY,OAAA,CAAQ,OAAA,IAAW,OAAO,OAAA,CAAQ,OAAA,CAAQ,WAAW,QAAA,GAAW,OAAA,CAAQ,QAAQ,MAAA,GAAS,MAAA;AAClN,UAAA,IAAA,CAAK,MAAA,CAAO,MAAM,iCAAA,EAAmC;AAAA,YACnD,OAAA;AAAA,YACA,OAAO,OAAA,CAAQ,KAAA;AAAA,YACf;AAAA,WACD,CAAA;AACD,UAAA,MAAM,eAAe,OAAA,CAAQ,KAAA,KAAU,sBAAsB,IAAA,GAAO,CAAA,+CAAA,EAAkD,kBAAkB,CAAA,CAAA,CAAA,GAAM,uCAAA,CAAA;AAC9I,UAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,+BAAA,EAAkC,OAAO,CAAA,EAAA,EAAK,YAAY,EAAE,CAAC,CAAA;AAAA,QAChF;AAAA,MACF,CAAA;AACA,MAAA,MAAM,MAAM,sBAAA,IAAyB;AACrC,MAAA,MAAM,qBAAqB,GAAA,IAAO,IAAA,GAAO,KAAK,MAAA,CAAO,SAAA,CAAU,SAAS,cAAA,EAAgB;AAAA,QACtF;AAAA,OACF,EAAG,iBAAiB,CAAA,GAAI,IAAA,CAAK,OAAO,SAAA,CAAU,OAAA,EAAS,gBAAgB,iBAAiB,CAAA;AACxF,MAAA,IAAA,CAAK,gBAAA,CAAiB,IAAI,cAAA,EAAgB;AAAA,QACxC,MAAA,EAAQ,kBAAA;AAAA,QACR,sBAAA;AAAA,QACA,YAAA,EAAc;AAAA,OACf,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAAA,EACA,YAAY,cAAA,EAAgB;AAC1B,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,cAAc,CAAA;AAC7D,IAAA,IAAI,gBAAgB,IAAA,EAAM;AACxB,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,sDAAA,EAAwD;AAAA,QACvE;AAAA,OACD,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,MAAM;AAAA,MACJ,MAAA;AAAA,MACA;AAAA,KACF,GAAI,YAAA;AACJ,IAAA,IAAA,CAAK,gBAAA,CAAiB,OAAO,cAAc,CAAA;AAC3C,IAAA,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,MAAA,EAAQ,CAAA,OAAA,KAAW;AACzC,MAAA,IAAI,CAAC,QAAQ,UAAA,EAAY;AACvB,QAAA,IAAA,CAAK,MAAA,CAAO,KAAK,wCAAA,EAA0C;AAAA,UACzD,YAAA;AAAA,UACA,cAAA;AAAA,UACA,OAAO,OAAA,CAAQ;AAAA,SAChB,CAAA;AAAA,MACH;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EACA,MAAM,OAAA,CAAQ,OAAA,EAAS,OAAA,EAAS;AAC9B,IAAA,MAAM,KAAK,UAAA,EAAW;AACtB,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,OAAA,EAAS,OAAA,EAAS,CAAA,OAAA,KAAW;AAC/C,QAAA,IAAI,QAAQ,UAAA,EAAY;AACtB,UAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,gCAAA,EAAkC,OAAA,EAAS;AAAA,YAC3D;AAAA,WACD,CAAA;AACD,UAAA,OAAA,EAAQ;AAAA,QACV,CAAA,MAAO;AACL,UAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,OAAO,CAAA,CAAA,EAAI;AAAA,YACzD,OAAO,OAAA,CAAQ;AAAA,WAChB,CAAA;AACD,UAAA,IAAA,CAAK,MAAA,CAAO,MAAM,mBAAA,EAAqB;AAAA,YACrC,OAAA;AAAA,YACA;AAAA,WACD,CAAA;AACD,UAAA,MAAA,CAAO,KAAK,CAAA;AAAA,QACd;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAAA,EACA,YAAY,QAAA,EAAU;AACpB,IAAA,IAAA,CAAK,gBAAgB,QAAQ,CAAA;AAAA,EAC/B;AAAA,EACA,gBAAgB,QAAA,EAAU;AACxB,IAAA,MAAM,GAAA,GAAM,qBAAA,CAAsB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AACjD,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,qBAAA,EAAuB;AAAA,MACtC;AAAA,KACD,CAAA;AACD,IAAA,IAAA,CAAK,OAAO,SAAA,CAAU;AAAA,MACpB,GAAA;AAAA;AAAA,MAEA,eAAA,EAAiB,GAAA;AAAA,MACjB,QAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH;AACF;AACA,SAAS,sBAAsB,SAAA,EAAW;AACxC,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,CAAA,EAAG,SAAA,CAAU,OAAO,UAAU,CAAA,OAAA,CAAA,EAAW,SAAA,CAAU,MAAA,CAAO,OAAO,CAAA;AACzF,EAAA,OAAA,CAAQ,QAAA,CAAS,OAAA,CAAQ,QAAA,EAAU,IAAI,CAAA;AAEvC,EAAA,OAAO,OAAA,CAAQ,IAAA;AACjB;AACA,IAAM,iBAAN,MAAqB;AAAA,EACnB,YAAA;AAAA,EACA,SAAS,KAAA,EAAO;AACd,IAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AAAA,EACtB;AAAA,EACA,WAAW,CAAA,OAAA,KAAW;AAEpB,IAAA,IAAI,OAAA,CAAQ,YAAY,sBAAA,EAAwB;AAC9C,MAAA,IAAI,KAAK,YAAA,EAAc;AACrB,QAAA,OAAA,CAAQ,QAAQ,EAAC;AACjB,QAAA,OAAA,CAAQ,GAAA,CAAI,kBAAkB,CAAA,GAAI,IAAA,CAAK,YAAA;AAAA,MACzC;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AACF,CAAA;ACvMA,IAAM,oBAAA,GAAuB,QAAA;AAC7B,IAAM,2BAAA,GAA8B,CAAA,UAAA,KAAc,CAAA,UAAA,EAAa,UAAU,CAAA,QAAA,CAAA;AACzE,IAAM,2BAAA,GAA8B,CAAA,UAAA,KAAc,CAAA,UAAA,EAAa,UAAU,CAAA,QAAA,CAAA;AACzE,IAAM,4BAAA,GAA+B,CAAA,UAAA,KAAc,CAAA,UAAA,EAAa,UAAU,CAAA,SAAA,CAAA;AAC1E,IAAM,4BAAA,GAA+B,CAAA,UAAA,KAAc,CAAA,UAAA,EAAa,UAAU,CAAA,SAAA,CAAA;AAC1E,IAAM,mCAAA,GAAsC,CAAA,UAAA,KAAc,CAAA,UAAA,EAAa,UAAU,CAAA,iBAAA,CAAA;AAK1E,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA,uBAAe,GAAA,EAAI;AAAA,EACnB,WAAA,CAAY,KAAK,MAAA,EAAQ;AACvB,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,kBAAA,CAAmB,GAAA,EAAK,MAAM,CAAA;AACtD,IAAA,IAAA,CAAK,SAAS,GAAA,CAAI,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,EAAC,EAAG;AAAA,MACxC,KAAA,EAAO,OAAA;AAAA,MACP,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH;AAAA,EACA,kBAAA,CAAmB,YAAY,IAAA,EAAM;AACnC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA;AAC9C,IAAA,IAAI,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AACzC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,GAAU;AAAA,QACR,sBAAA,EAAwB,MAAA;AAAA,QACxB,QAAA,EAAU,OAAO,UAAA,EAAW;AAAA,QAC5B,UAAA;AAAA,QACA,sBAAA,EAAwB,MAAA;AAAA,QACxB,cAAA,EAAgB,MAAA;AAAA,QAChB,sBAAA,EAAwB,MAAA;AAAA,QACxB,sBAAA,EAAwB,MAAA;AAAA,QACxB,IAAA,EAAM,IAAA,IAAQ,IAAM,CAAA,CAAA,GAAA;AAAI,OAC1B;AACA,MAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA;AAAA,IACtC;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EACA,iBAAA,CAAkB,UAAA,EAAY,IAAA,EAAM,cAAA,EAAgB;AAClD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,kBAAA,CAAmB,UAAA,EAAY,IAAI,CAAA;AACxD,IAAA,IAAI,OAAA,CAAQ,0BAA0B,IAAA,EAAM;AAC1C,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+CAAA,EAAkD,UAAU,CAAA,CAAE,CAAA;AAAA,IAChF;AACA,IAAA,MAAM,sBAAA,GAAyB,CAAC,MAAA,EAAQ,MAAA,KAAW;AACjD,MAAA,IAAI,WAAW,oBAAA,EAAsB;AACnC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,iBAAiB,OAAA,CAAQ,cAAA;AAC/B,MAAA,IAAI,kBAAkB,IAAA,EAAM;AAC1B,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,2GAAA,EAA6G;AAAA,UAC7H,KAAA,EAAO;AAAA,SACR,CAAA;AACD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,gBAAA,GAAmB,4BAA4B,UAAU,CAAA;AAC/D,MAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,MAAA,MAAM,cAAc,iBAAA,CAAkB,MAAM,CAAA,GAAI,6BAAA,CAA8B,MAAM,CAAA,GAAI,MAAA;AACxF,MAAA,KAAK,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,gBAAA,EAAkB;AAAA,QAC/C,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,WAAA;AAAA,QACA,MAAA;AAAA,QACA,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,MAAA,CAAO,cAAA,CAAe,MAAM;AAAA;AACpC,OACD,CAAA,CAAE,KAAA,CAAM,CAAA,KAAA,KAAS;AAChB,QAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,mCAAA,EAAqC,KAAA,EAAO;AAAA,UAC5D,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH,CAAC,CAAA;AAAA,IACH,CAAA;AACA,IAAA,OAAA,CAAQ,sBAAA,GAAyB,sBAAA;AACjC,IAAA,IAAA,CAAK,EAAA,CAAG,UAAU,sBAAsB,CAAA;AACxC,IAAA,cAAA,CAAe;AAAA,MACb,MAAM,kBAAA,CAAmB;AAAA,KAC1B,CAAA;AACD,IAAA,MAAM,SAAA,GAAY,4BAA4B,UAAU,CAAA;AACxD,IAAA,IAAA,CAAK,YAAA,CAAa,SAAA,CAAU,SAAA,EAAW,CAAA,OAAA,KAAW;AAChD,MAAA,IAAI,OAAA,CAAQ,2BAA2B,sBAAA,EAAwB;AAC7D,QAAA;AAAA,MACF;AACA,MAAA,IAAA,CAAK,2BAAA,CAA4B,OAAA,EAAS,OAAA,EAAS,cAAc,CAAA;AAAA,IACnE,GAAG,OAAO;AAAA,MACR,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,cAAA,EAAgB,OAAA,CAAQ,cAAA,EAAgB,QAAA;AAAS,KACnD,CAAE,CAAA,CAAE,IAAA,CAAK,CAAA,cAAA,KAAkB;AACzB,MAAA,IAAI,OAAA,CAAQ,2BAA2B,sBAAA,EAAwB;AAC7D,QAAA,OAAA,CAAQ,sBAAA,GAAyB,cAAA;AAAA,MACnC,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,YAAA,CAAa,YAAY,cAAc,CAAA;AAC5C,QAAA,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,YAAA,CAAa,UAAU,CAAC,CAAA;AAAA,MACpD;AAAA,IACF,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,CAAA,KAAK;AACZ,MAAA,IAAI,OAAA,CAAQ,2BAA2B,sBAAA,EAAwB;AAC7D,QAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,4CAAA,EAA8C;AAAA,UACpE,KAAA,EAAO;AAAA,SACR,CAAA;AACD,QAAA,cAAA,CAAe;AAAA,UACb,KAAA;AAAA,UACA,MAAM,kBAAA,CAAmB;AAAA,SAC1B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,MAAA,CAAO,KAAK,gEAAA,EAAkE;AAAA,UACjF,KAAA,EAAO,UAAA;AAAA,UACP,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAAA,IACF,CAAC,CAAA;AACD,IAAA,OAAO;AAAA,MACL,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,YAAY,OAAA,CAAQ;AAAA,KACtB;AAAA,EACF;AAAA,EACA,0BAAA,CAA2B,YAAY,QAAA,EAAU;AAC/C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,kBAAA,CAAmB,UAAU,CAAA;AAClD,IAAA,MAAM,SAAA,GAAY,6BAA6B,UAAU,CAAA;AACzD,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,SAAA,CAAU,SAAA,EAAW,CAAA,KAAA,KAAS;AACrD,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,yBAAA,EAA2B;AAAA,QAC3C,KAAA,EAAO,UAAA;AAAA,QACP;AAAA,OACD,CAAA;AACD,MAAA,QAAA,CAAS,KAAK,CAAA;AAAA,IAChB,CAAC,CAAA,CAAE,IAAA,CAAK,CAAA,cAAA,KAAkB;AACxB,MAAA,OAAA,CAAQ,sBAAA,GAAyB,cAAA;AACjC,MAAA,OAAO,cAAA;AAAA,IACT,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,CAAA,KAAK;AACZ,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,yCAAA,EAA2C,CAAA,EAAG;AAAA,QAC9D,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,MAAM,IAAI,MAAM,yCAAA,EAA2C;AAAA,QACzD,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAAA,EACA,0BAAA,CAA2B,UAAA,EAAY,QAAA,EAAU,OAAA,GAAU,EAAC,EAAG;AAC7D,IAAA,MAAM;AAAA,MACJ,iBAAA,GAAoB;AAAA,KACtB,GAAI,OAAA;AACJ,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,kBAAA,CAAmB,UAAU,CAAA;AAClD,IAAA,MAAM,SAAA,GAAY,6BAA6B,UAAU,CAAA;AACzD,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,SAAA,CAAU,SAAA,EAAW,CAAA,MAAA,KAAU;AAItD,MAAA,MAAM,cAAcA,aAAAA,CAAc,IAAA,CAAK,GAAG,CAAA,CAAE,cAAA,CAAe,IAAI,CAAA,EAAG,MAAA;AAClE,MAAA,IAAI,iBAAA,IAAqB,eAAe,IAAA,EAAM;AAC5C,QAAA,QAAQ,OAAO,IAAA;AAAM,UACnB,KAAK,qBAAA;AACH,YAAA,IAAI,MAAA,CAAO,mBAAA,CAAoB,MAAA,KAAW,WAAA,EAAa;AACrD,cAAA;AAAA,YACF;AACA,YAAA;AAAA,UACF,KAAK,qBAAA;AACH,YAAA,IAAI,MAAA,CAAO,mBAAA,CAAoB,MAAA,KAAW,WAAA,EAAa;AACrD,cAAA;AAAA,YACF;AACA,YAAA;AAGA;AACJ,MACF;AACA,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,0BAAA,EAA4B;AAAA,QAC5C,KAAA,EAAO,UAAA;AAAA,QACP,YAAY,MAAA,CAAO;AAAA,OACpB,CAAA;AACD,MAAA,QAAA,CAAS,MAAM,CAAA;AAAA,IACjB,CAAC,CAAA,CAAE,IAAA,CAAK,CAAA,cAAA,KAAkB;AACxB,MAAA,OAAA,CAAQ,sBAAA,GAAyB,cAAA;AACjC,MAAA,OAAO,cAAA;AAAA,IACT,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,CAAA,KAAK;AACZ,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,yCAAA,EAA2C,CAAA,EAAG;AAAA,QAC9D,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,MAAM,IAAI,MAAM,yCAAA,EAA2C;AAAA,QACzD,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAAA,EACA,qBAAA,CAAsB,UAAA,EAAY,SAAA,EAAW,SAAA,EAAW;AACtD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,kBAAA,CAAmB,UAAU,CAAA;AAClD,IAAA,MAAM,SAAA,GAAY,oCAAoC,UAAU,CAAA;AAChE,IAAA,MAAM,WAAA,GAAc;AAAA,MAClB,SAAA;AAAA,MACA;AAAA,KACF;AAGA,IAAA,MAAM,SAASA,aAAAA,CAAc,IAAA,CAAK,GAAG,CAAA,CAAE,cAAA,CAAe,IAAI,CAAA,EAAG,MAAA;AAC7D,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,IAChD;AACA,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,SAAA,EAAW;AAAA,MAC1C,MAAA,EAAQ;AAAA,QACN,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,SAAA,EAAW,WAAA;AAAA;AAAA,QAEX;AAAA,OACF;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA,CAAE,KAAA,CAAM,CAAA,KAAA,KAAS;AAChB,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,mCAAA,EAAqC,KAAA,EAAO;AAAA,QAC5D,KAAA,EAAO;AAAA,OACR,CAAA;AACD,MAAA,MAAM,KAAA;AAAA,IACR,CAAC,CAAA;AAAA,EACH;AAAA,EACA,iBAAiB,OAAA,EAAS;AACxB,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,UAAU,CAAA;AACtD,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AACnD,IAAA,IAAI,mBAAmB,IAAA,EAAM;AAC3B,MAAA,IAAA,CAAK,MAAA,CAAO,KAAK,4CAAA,EAA8C;AAAA,QAC7D,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,UAAU,OAAA,CAAQ;AAAA,OACnB,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,eAAA,CAAgB,0BAA0B,IAAA,EAAM;AAClD,MAAA,eAAA,CAAgB,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,eAAA,CAAgB,sBAAsB,CAAA;AACzE,MAAA,eAAA,CAAgB,sBAAA,GAAyB,MAAA;AAAA,IAC3C;AACA,IAAA,IAAI,gBAAgB,sBAAA,EAAwB;AAC1C,MAAA,IAAA,CAAK,YAAA,CAAa,WAAA,CAAY,eAAA,CAAgB,sBAAsB,CAAA;AAAA,IACtE;AACA,IAAA,IAAI,gBAAgB,sBAAA,EAAwB;AAC1C,MAAA,IAAA,CAAK,YAAA,CAAa,WAAA,CAAY,eAAA,CAAgB,sBAAsB,CAAA;AAAA,IACtE;AACA,IAAA,IAAI,gBAAgB,sBAAA,EAAwB;AAC1C,MAAA,IAAA,CAAK,YAAA,CAAa,WAAA,CAAY,eAAA,CAAgB,sBAAsB,CAAA;AACpE,MAAA,IAAA,CAAK,QAAA,CAAS,OAAO,SAAS,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EACA,2BAAA,CAA4B,OAAA,EAAS,OAAA,EAAS,cAAA,EAAgB;AAC5D,IAAA,QAAQ,QAAQ,IAAA;AAAM,MACpB,KAAK,OAAA;AACH,QAAA,MAAM;AAAA,UACJ,IAAA;AAAA,UACA,IAAA;AAAA,UACA;AAAA,SACF,GAAI,OAAA;AACJ,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,wCAAA,EAA0C;AAAA,UAC1D,OAAO,OAAA,CAAQ,UAAA;AAAA,UACf,IAAA;AAAA,UACA,eAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,cAAA,CAAe;AAAA,UACb,KAAA,EAAO,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,eAAe,CAAA,CAAA,CAAA,EAAK;AAAA,YACnE,KAAA,EAAO;AAAA,WACR,CAAA;AAAA,UACD,MAAM,kBAAA,CAAmB;AAAA,SAC1B,CAAA;AACD,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,MAAM;AAAA,UACJ,cAAA;AAAA,UACA,QAAA;AAAA,UACA,UAAA;AAAA,UACA;AAAA,SACF,GAAI,OAAA;AACJ,QAAA,MAAM,IAAA,GAAO,MAAA,IAAU,IAAA,IAAQ,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAW,MAAA,CAAO,YAAA,CAAa,MAAA,CAAO,IAAI,CAAA,GAAI,MAAA;AACpG,QAAA,MAAM,aAAA,GAAgB;AAAA,UACpB,cAAA;AAAA,UACA,QAAA;AAAA,UACA,UAAA;AAAA,UACA,UAAA,EAAY,MAAM,UAAA,IAAc;AAAA,SAClC;AAGA,QAAA,IAAI,QAAQ,cAAA,IAAkB,IAAA,IAAQ,OAAO,cAAc,CAAA,KAAM,QAAQ,cAAA,EAAgB;AACvF,UAAA,IAAA,CAAK,MAAA,CAAO,MAAM,0CAAA,EAA4C;AAAA,YAC5D,OAAO,OAAA,CAAQ,UAAA;AAAA,YACf,gBAAgB,OAAA,CAAQ,cAAA;AAAA,YACxB,OAAA,EAAS;AAAA,WACV,CAAA;AACD,UAAA;AAAA,QACF;AACA,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,6BAAA,EAA+B;AAAA,UAC/C,OAAO,OAAA,CAAQ,UAAA;AAAA,UACf,gBAAgB,OAAA,CAAQ,cAAA;AAAA,UACxB,OAAA,EAAS;AAAA,SACV,CAAA;AACD,QAAA,OAAA,CAAQ,cAAA,GAAiB,OAAO,UAAU,CAAA;AAC1C,QAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,UAAE,CAAA,CAAA,WAAA,CAAY,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,oBAAoB,CAAA;AAAA,QACxD;AACA,QAAA,cAAA,CAAe;AAAA,UACb,MAAM,kBAAA,CAAmB;AAAA,SAC1B,CAAA;AACD,QAAA;AAAA,MACF;AAEE,QAAA,MAAM;AAAA,UACJ;AAAA,SACF,GAAI,OAAA;AACJ,QAAA,QAAA,CAAS,CAAA,2BAAA,EAA8B,IAAI,CAAA,CAAA,EAAI,MAAM;AACnD,UAAA,IAAA,CAAK,MAAA,CAAO,KAAK,wFAAA,EAA0F;AAAA,YACzG,OAAO,OAAA,CAAQ,UAAA;AAAA,YACf,UAAA,EAAY;AAAA,WACb,CAAA;AAAA,QACH,CAAC,CAAA;AACD,QAAA;AAAA;AACJ,EACF;AAAA,EACA,aAAa,UAAA,EAAY;AACvB,IAAA,OAAO,UAAA;AAAA,EACT;AACF;AACO,SAAS,yBAAA,CAA0B,KAAK,MAAA,EAAQ;AACrD,EAAA,OAAO,IAAI,mBAAA,CAAoB,GAAA,EAAK,MAAM,CAAA;AAC5C;AACA,SAAS,kBAAkB,GAAA,EAAK;AAC9B,EAAA,OAAO,OAAO,IAAA,IAAQ,OAAO,GAAA,KAAQ,QAAA,IAAY,UAAU,GAAA,IAAO,OAAA,IAAW,GAAA,IAAO,OAAO,IAAI,KAAA,KAAU,QAAA,IAAY,IAAI,KAAA,IAAS,IAAA,IAAQ,YAAY,GAAA,CAAI,KAAA;AAC5J;AACA,SAAS,8BAA8B,eAAA,EAAiB;AACtD,EAAA,OAAO;AAAA,IACL,SAAA,EAAW;AAAA,MACT,MAAM,eAAA,CAAgB,IAAA;AAAA,MACtB,OAAA,EAAS;AAAA,KACX;AAAA,IACA,SAAA,EAAW,WAAA,CAAY,eAAA,CAAgB,KAAK,CAAA,CAAE;AAAA,GAChD;AACF","file":"index.js","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { AckExtension, CometD } from \"cometd\";\n// side-effect shenanigans imports the class impl to cometd module\nimport \"cometd/AckExtension.js\";\nconst BEARER_TOKEN_FIELD = \"bearer-token\";\nconst EXTENSION_ACK = \"AckExtension\";\nconst EXTENSION_HANDSHAKE_TOKEN = \"handshakeToken\";\nconst META_CHANNEL_HANDSHAKE = \"/meta/handshake\";\nexport class EventServiceCometD {\n logger;\n initializePromise;\n subscriptionById = new Map();\n tokenExtension = new TokenExtension();\n nextSubscriptionHandle = 0;\n constructor(app, cometd = new CometD()) {\n this.app = app;\n this.cometd = cometd;\n this.logger = app.config.logger.child({}, {\n msgPrefix: \"EventServiceCometD\"\n });\n this.configureCometd();\n this.cometd.registerExtension(EXTENSION_ACK, new AckExtension());\n this.cometd.registerExtension(EXTENSION_HANDSHAKE_TOKEN, this.tokenExtension);\n\n // TODO: Support binary messages\n // this.cometd.registerExtension(BINARY_EXTENSION_NAME, new BinaryExtension());\n\n // Any time the token changes, update the extension so reconnection requests use the new token.\n // This will also be called on initial token set when the auth module is initialized.\n getAuthModule(app).onTokenChange(token => {\n this.tokenExtension.setToken(token);\n });\n }\n initialize() {\n if (this.initializePromise != null) {\n return this.initializePromise;\n }\n this.initializePromise = new Promise(resolve => {\n this.cometd.addListener(META_CHANNEL_HANDSHAKE, ({\n clientId,\n connectionType,\n error,\n successful\n }) => {\n if (successful) {\n this.logger.info(\"CometD handshake successful\", {\n clientId,\n connectionType\n });\n resolve();\n this.cometd.batch(() => {\n this.subscriptionById.forEach((subscription, subscriptionId) => {\n this.logger.debug(\"Resubscribing to channel\", {\n channel: subscription.eventChannel,\n subscriptionId\n });\n const subscribeProps = subscription.getSubscriptionRequest?.();\n subscription.handle = this.cometd.resubscribe(subscription.handle, {\n ext: subscribeProps\n });\n });\n });\n } else {\n this.logger.warn(\"CometD handshake failed\", {\n clientId,\n error\n });\n }\n });\n const authModule = getAuthModule(this.app);\n void authModule.getToken().then(token => {\n this.logger.info(\"Initializing CometD with token\");\n this.tokenExtension.setToken(token);\n this.cometd.handshake();\n });\n });\n return this.initializePromise;\n }\n async subscribe(channel, onMessage, getSubscriptionRequest) {\n await this.initialize();\n const subscriptionId = (this.nextSubscriptionHandle++).toString(10);\n return new Promise((resolve, reject) => {\n const messageHandler = receivedData => {\n if (!this.subscriptionById.has(subscriptionId)) {\n this.logger.info(\"Dropping message for unsubscribing channel\", {\n channel,\n subscriptionId\n });\n return;\n }\n this.logger.debug(\"Received message on channel\", {\n channel,\n subscriptionId,\n hasData: receivedData.data != null\n });\n onMessage(receivedData.data);\n };\n const subscribeCallback = message => {\n if (message.successful) {\n this.logger.debug(\"Successfully subscribed to channel\", {\n channel,\n subscriptionId\n });\n resolve(subscriptionId);\n } else {\n this.subscriptionById.delete(subscriptionId);\n // TODO: Is failure really expected? It's not on the type...\n const maybeFailureReason = \"failure\" in message && typeof message.failure === \"object\" && message.failure && \"reason\" in message.failure && typeof message.failure.reason === \"string\" ? message.failure.reason : undefined;\n this.logger.error(\"Failed to subscribe to channel \", {\n channel,\n error: message.error,\n maybeFailureReason\n });\n const errorMessage = message.error ?? (maybeFailureReason != null ? `(no error message provided by server, a guess: ${maybeFailureReason})` : \"(no error message provided by server)\");\n reject(new Error(`Failed to subscribe to channel ${channel}: ${errorMessage}`));\n }\n };\n const ext = getSubscriptionRequest?.();\n const subscriptionHandle = ext != null ? this.cometd.subscribe(channel, messageHandler, {\n ext\n }, subscribeCallback) : this.cometd.subscribe(channel, messageHandler, subscribeCallback);\n this.subscriptionById.set(subscriptionId, {\n handle: subscriptionHandle,\n getSubscriptionRequest,\n eventChannel: channel\n });\n });\n }\n unsubscribe(subscriptionId) {\n const subscription = this.subscriptionById.get(subscriptionId);\n if (subscription == null) {\n this.logger.warn(\"Attempted to unsubscribe from unknown subscriptionId\", {\n subscriptionId\n });\n return;\n }\n const {\n handle,\n eventChannel\n } = subscription;\n this.subscriptionById.delete(subscriptionId);\n this.cometd.unsubscribe(handle, message => {\n if (!message.successful) {\n this.logger.warn(\"Server unsubscribe confirmation failed\", {\n eventChannel,\n subscriptionId,\n error: message.error\n });\n }\n });\n }\n async publish(channel, content) {\n await this.initialize();\n return new Promise((resolve, reject) => {\n this.cometd.publish(channel, content, message => {\n if (message.successful) {\n this.logger.debug(\"Successfully published message\", channel, {\n content\n });\n resolve();\n } else {\n const error = new Error(`Failed to publish to ${channel}`, {\n cause: message.error\n });\n this.logger.error(\"Failed to publish\", {\n channel,\n error\n });\n reject(error);\n }\n });\n });\n }\n setLogLevel(logLevel) {\n this.configureCometd(logLevel);\n }\n configureCometd(logLevel) {\n const url = getCometDWebsocketUrl(this.app.config);\n this.logger.info(\"Configuring cometD \", {\n url\n });\n this.cometd.configure({\n url,\n // NOTE : Allow higher latency on busy networks to avoid retry loops when servers or networks fall behind.\n maxNetworkDelay: 30_000,\n logLevel,\n autoBatch: true\n });\n }\n}\nfunction getCometDWebsocketUrl(appConfig) {\n const httpUrl = new URL(`${appConfig.remote.packWsPath}/cometd`, appConfig.remote.baseUrl);\n httpUrl.protocol.replace(/https?/, \"ws\");\n // TODO: likely need a specific port for ingest - all of this should be in in appConfig\n return httpUrl.href;\n}\nclass TokenExtension {\n currentToken;\n setToken(token) {\n this.currentToken = token;\n }\n outgoing = message => {\n // Always use the latest token when doing a handshake (handles reconnects)\n if (message.channel === META_CHANNEL_HANDSHAKE) {\n if (this.currentToken) {\n message.ext ??= {};\n message.ext[BEARER_TOKEN_FIELD] = this.currentToken;\n }\n }\n return message;\n };\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { generateId, justOnce } from \"@palantir/pack.core\";\nimport { getMetadata, Metadata } from \"@palantir/pack.document-schema.model-types\";\nimport { DocumentLoadStatus } from \"@palantir/pack.state.core\";\nimport { Base64 } from \"js-base64\";\nimport * as y from \"yjs\";\nimport { EventServiceCometD } from \"./cometd/EventServiceCometD.js\";\n\n// TODO: replace with @osdk/foundry.pack types when they land.\n\n// TODO: presence api should have an eventType so we don't need extra wrapper here.\n\nconst UPDATE_ORIGIN_REMOTE = \"remote\";\nconst getDocumentUpdatesChannelId = documentId => `/document/${documentId}/updates`;\nconst getDocumentPublishChannelId = documentId => `/document/${documentId}/publish`;\nconst getDocumentActivityChannelId = documentId => `/document/${documentId}/activity`;\nconst getDocumentPresenceChannelId = documentId => `/document/${documentId}/presence`;\nconst getDocumentPresencePublishChannelId = documentId => `/document/${documentId}/presence-publish`;\n/**\n * This manages event subscriptions and publishing of document related events via\n * our PACK Foundry backend's cometd service.\n */\nexport class FoundryEventService {\n eventService;\n logger;\n sessions = new Map();\n constructor(app, cometd) {\n this.app = app;\n this.eventService = new EventServiceCometD(app, cometd);\n this.logger = app.config.logger.child({}, {\n level: \"debug\",\n msgPrefix: \"FoundryEventService\"\n });\n }\n getOrCreateSession(documentId, yDoc) {\n const sessionId = this.getSessionId(documentId);\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = {\n activitySubscriptionId: undefined,\n clientId: crypto.randomUUID(),\n documentId,\n documentSubscriptionId: undefined,\n lastRevisionId: undefined,\n localYDocUpdateHandler: undefined,\n presenceSubscriptionId: undefined,\n yDoc: yDoc ?? new y.Doc()\n };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n startDocumentSync(documentId, yDoc, onStatusChange) {\n const session = this.getOrCreateSession(documentId, yDoc);\n if (session.documentSubscriptionId != null) {\n throw new Error(`Document data sync already active for document ${documentId}`);\n }\n const localYDocUpdateHandler = (update, origin) => {\n if (origin === UPDATE_ORIGIN_REMOTE) {\n return;\n }\n const lastRevisionId = session.lastRevisionId;\n if (lastRevisionId == null) {\n this.logger.error(\"Cannot publish document update before initial load is complete. The local state will remain inconsistent.\", {\n docId: documentId\n });\n return;\n }\n const publishChannelId = getDocumentPublishChannelId(documentId);\n const editId = generateId();\n const description = isEditDescription(origin) ? createDocumentEditDescription(origin) : undefined;\n void this.eventService.publish(publishChannelId, {\n clientId: session.clientId,\n description,\n editId,\n yjsUpdate: {\n data: Base64.fromUint8Array(update)\n }\n }).catch(error => {\n this.logger.error(\"Failed to publish document update\", error, {\n docId: documentId\n });\n });\n };\n session.localYDocUpdateHandler = localYDocUpdateHandler;\n yDoc.on(\"update\", localYDocUpdateHandler);\n onStatusChange({\n load: DocumentLoadStatus.LOADING\n });\n const channelId = getDocumentUpdatesChannelId(documentId);\n this.eventService.subscribe(channelId, message => {\n if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {\n return;\n }\n this.handleDocumentUpdateMessage(session, message, onStatusChange);\n }, () => ({\n clientId: session.clientId,\n lastRevisionId: session.lastRevisionId?.toString()\n })).then(subscriptionId => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n session.documentSubscriptionId = subscriptionId;\n } else {\n this.eventService.unsubscribe(subscriptionId);\n this.sessions.delete(this.getSessionId(documentId));\n }\n }).catch(e => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n const error = new Error(\"Failed to setup document data subscription\", {\n cause: e\n });\n onStatusChange({\n error,\n load: DocumentLoadStatus.ERROR\n });\n } else {\n this.logger.warn(\"Document data subscription error after subscription was closed\", {\n docId: documentId,\n error: e\n });\n }\n });\n return {\n clientId: session.clientId,\n documentId: session.documentId\n };\n }\n subscribeToActivityUpdates(documentId, callback) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentActivityChannelId(documentId);\n return this.eventService.subscribe(channelId, event => {\n this.logger.debug(\"Received activity event\", {\n docId: documentId,\n event\n });\n callback(event);\n }).then(subscriptionId => {\n session.activitySubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to activity updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to activity updates\", {\n cause: e\n });\n });\n }\n subscribeToPresenceUpdates(documentId, callback, options = {}) {\n const {\n ignoreSelfUpdates = true\n } = options;\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresenceChannelId(documentId);\n return this.eventService.subscribe(channelId, update => {\n // TODO: api should provide clientId so we filter on our presence messages only,\n // but allow apps to decide what they do with same-user-different-client messages ie\n // from different tabs or devices.\n const localUserId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (ignoreSelfUpdates && localUserId != null) {\n switch (update.type) {\n case \"presenceChangeEvent\":\n if (update.presenceChangeEvent.userId === localUserId) {\n return;\n }\n break;\n case \"customPresenceEvent\":\n if (update.customPresenceEvent.userId === localUserId) {\n return;\n }\n break;\n default:\n update;\n break;\n }\n }\n this.logger.debug(\"Received presence update\", {\n docId: documentId,\n updateType: update.type\n });\n callback(update);\n }).then(subscriptionId => {\n session.presenceSubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to presence updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to presence updates\", {\n cause: e\n });\n });\n }\n publishCustomPresence(documentId, eventType, eventData) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresencePublishChannelId(documentId);\n const messageData = {\n eventData,\n eventType\n };\n // TODO: maybe the session should hold userId\n // Though would need better reconnection handling to ensure userId doesn't change.\n const userId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (userId == null) {\n throw new Error(\"Could not get current userId\");\n }\n return this.eventService.publish(channelId, {\n custom: {\n clientId: session.clientId,\n eventData: messageData,\n // FIXME: why do we have to send this, we are authenticated\n userId\n },\n type: \"custom\"\n }).catch(error => {\n this.logger.error(\"Failed to publish custom presence\", error, {\n docId: documentId\n });\n throw error;\n });\n }\n stopDocumentSync(session) {\n const sessionId = this.getSessionId(session.documentId);\n const internalSession = this.sessions.get(sessionId);\n if (internalSession == null) {\n this.logger.warn(\"Attempted to stop sync for unknown session\", {\n documentId: session.documentId,\n clientId: session.clientId\n });\n return;\n }\n if (internalSession.localYDocUpdateHandler != null) {\n internalSession.yDoc.off(\"update\", internalSession.localYDocUpdateHandler);\n internalSession.localYDocUpdateHandler = undefined;\n }\n if (internalSession.activitySubscriptionId) {\n this.eventService.unsubscribe(internalSession.activitySubscriptionId);\n }\n if (internalSession.presenceSubscriptionId) {\n this.eventService.unsubscribe(internalSession.presenceSubscriptionId);\n }\n if (internalSession.documentSubscriptionId) {\n this.eventService.unsubscribe(internalSession.documentSubscriptionId);\n this.sessions.delete(sessionId);\n }\n }\n handleDocumentUpdateMessage(session, message, onStatusChange) {\n switch (message.type) {\n case \"error\":\n const {\n args,\n code,\n errorInstanceId\n } = message;\n this.logger.error(\"Received document update error message\", {\n docId: session.documentId,\n code,\n errorInstanceId,\n args\n });\n onStatusChange({\n error: new Error(`Subscription in error state [${errorInstanceId}]`, {\n cause: message\n }),\n load: DocumentLoadStatus.ERROR\n });\n break;\n case \"update\":\n const {\n baseRevisionId,\n clientId,\n revisionId,\n update\n } = message;\n const data = update != null && typeof update.data === \"string\" ? Base64.toUint8Array(update.data) : undefined;\n const messageDetail = {\n baseRevisionId,\n clientId,\n revisionId,\n updateSize: data?.byteLength ?? 0\n };\n\n // FIXME: the typescript generators for api types come out as string, hard to be clear that they are numbers.\n if (session.lastRevisionId != null && Number(baseRevisionId) !== session.lastRevisionId) {\n this.logger.error(\"Got unexpected update for baseRevisionId\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n return;\n }\n this.logger.debug(\"Applying remote Y.js update\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n session.lastRevisionId = Number(revisionId);\n if (data != null) {\n y.applyUpdate(session.yDoc, data, UPDATE_ORIGIN_REMOTE);\n }\n onStatusChange({\n load: DocumentLoadStatus.LOADED\n });\n break;\n default:\n message;\n const {\n type\n } = message;\n justOnce(`unknown-collab-update-type:${type}`, () => {\n this.logger.warn(\"Received unknown DocumentUpdateMessage type. This is only warned the first occurrence.\", {\n docId: session.documentId,\n updateType: type\n });\n });\n break;\n }\n }\n getSessionId(documentId) {\n return documentId;\n }\n}\nexport function createFoundryEventService(app, cometd) {\n return new FoundryEventService(app, cometd);\n}\nfunction isEditDescription(obj) {\n return obj != null && typeof obj === \"object\" && \"data\" in obj && \"model\" in obj && typeof obj.model === \"object\" && obj.model != null && Metadata in obj.model;\n}\nfunction createDocumentEditDescription(editDescription) {\n return {\n eventData: {\n data: editDescription.data,\n version: 1\n },\n eventType: getMetadata(editDescription.model).name\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cometd/EventServiceCometD.ts","../../src/FoundryEventService.ts"],"names":["getAuthModule"],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { AckExtension, CometD } from \"cometd\";\n// side-effect shenanigans imports the class impl to cometd module\nimport \"cometd/AckExtension.js\";\nconst BEARER_TOKEN_FIELD = \"bearer-token\";\nconst EXTENSION_ACK = \"AckExtension\";\nconst EXTENSION_HANDSHAKE_TOKEN = \"handshakeToken\";\nconst META_CHANNEL_HANDSHAKE = \"/meta/handshake\";\nexport class EventServiceCometD {\n logger;\n initializePromise;\n subscriptionById = new Map();\n tokenExtension = new TokenExtension();\n nextSubscriptionHandle = 0;\n constructor(app, cometd = new CometD()) {\n this.app = app;\n this.cometd = cometd;\n this.logger = app.config.logger.child({}, {\n msgPrefix: \"EventServiceCometD\"\n });\n this.configureCometd();\n this.cometd.registerExtension(EXTENSION_ACK, new AckExtension());\n this.cometd.registerExtension(EXTENSION_HANDSHAKE_TOKEN, this.tokenExtension);\n\n // TODO: Support binary messages\n // this.cometd.registerExtension(BINARY_EXTENSION_NAME, new BinaryExtension());\n\n // Any time the token changes, update the extension so reconnection requests use the new token.\n // This will also be called on initial token set when the auth module is initialized.\n getAuthModule(app).onTokenChange(token => {\n this.tokenExtension.setToken(token);\n });\n }\n initialize() {\n if (this.initializePromise != null) {\n return this.initializePromise;\n }\n this.initializePromise = new Promise(resolve => {\n this.cometd.addListener(META_CHANNEL_HANDSHAKE, ({\n clientId,\n connectionType,\n error,\n successful\n }) => {\n if (successful) {\n this.logger.info(\"CometD handshake successful\", {\n clientId,\n connectionType\n });\n resolve();\n this.cometd.batch(() => {\n this.subscriptionById.forEach((subscription, subscriptionId) => {\n this.logger.debug(\"Resubscribing to channel\", {\n channel: subscription.eventChannel,\n subscriptionId\n });\n const subscribeProps = subscription.getSubscriptionRequest?.();\n subscription.handle = this.cometd.resubscribe(subscription.handle, {\n ext: subscribeProps\n });\n });\n });\n } else {\n this.logger.warn(\"CometD handshake failed\", {\n clientId,\n error\n });\n }\n });\n const authModule = getAuthModule(this.app);\n void authModule.getToken().then(token => {\n this.logger.info(\"Initializing CometD with token\");\n this.tokenExtension.setToken(token);\n this.cometd.handshake();\n });\n });\n return this.initializePromise;\n }\n async subscribe(channel, onMessage, getSubscriptionRequest) {\n await this.initialize();\n const subscriptionId = (this.nextSubscriptionHandle++).toString(10);\n return new Promise((resolve, reject) => {\n const messageHandler = receivedData => {\n if (!this.subscriptionById.has(subscriptionId)) {\n this.logger.info(\"Dropping message for unsubscribing channel\", {\n channel,\n subscriptionId\n });\n return;\n }\n this.logger.debug(\"Received message on channel\", {\n channel,\n subscriptionId,\n hasData: receivedData.data != null\n });\n onMessage(receivedData.data);\n };\n const subscribeCallback = message => {\n if (message.successful) {\n this.logger.debug(\"Successfully subscribed to channel\", {\n channel,\n subscriptionId\n });\n resolve(subscriptionId);\n } else {\n this.subscriptionById.delete(subscriptionId);\n // TODO: Is failure really expected? It's not on the type...\n const maybeFailureReason = \"failure\" in message && typeof message.failure === \"object\" && message.failure && \"reason\" in message.failure && typeof message.failure.reason === \"string\" ? message.failure.reason : undefined;\n this.logger.error(\"Failed to subscribe to channel \", {\n channel,\n error: message.error,\n maybeFailureReason\n });\n const errorMessage = message.error ?? (maybeFailureReason != null ? `(no error message provided by server, a guess: ${maybeFailureReason})` : \"(no error message provided by server)\");\n reject(new Error(`Failed to subscribe to channel ${channel}: ${errorMessage}`));\n }\n };\n const ext = getSubscriptionRequest?.();\n const subscriptionHandle = ext != null ? this.cometd.subscribe(channel, messageHandler, {\n ext\n }, subscribeCallback) : this.cometd.subscribe(channel, messageHandler, subscribeCallback);\n this.subscriptionById.set(subscriptionId, {\n handle: subscriptionHandle,\n getSubscriptionRequest,\n eventChannel: channel\n });\n });\n }\n unsubscribe(subscriptionId) {\n const subscription = this.subscriptionById.get(subscriptionId);\n if (subscription == null) {\n this.logger.warn(\"Attempted to unsubscribe from unknown subscriptionId\", {\n subscriptionId\n });\n return;\n }\n const {\n handle,\n eventChannel\n } = subscription;\n this.subscriptionById.delete(subscriptionId);\n this.cometd.unsubscribe(handle, message => {\n if (!message.successful) {\n this.logger.warn(\"Server unsubscribe confirmation failed\", {\n eventChannel,\n subscriptionId,\n error: message.error\n });\n }\n });\n }\n async publish(channel, content) {\n await this.initialize();\n return new Promise((resolve, reject) => {\n this.cometd.publish(channel, content, message => {\n if (message.successful) {\n this.logger.debug(\"Successfully published message\", channel, {\n content\n });\n resolve();\n } else {\n const error = new Error(`Failed to publish to ${channel}`, {\n cause: message.error\n });\n this.logger.error(\"Failed to publish\", {\n channel,\n error\n });\n reject(error);\n }\n });\n });\n }\n setLogLevel(logLevel) {\n this.configureCometd(logLevel);\n }\n configureCometd(logLevel) {\n const url = getCometDWebsocketUrl(this.app.config);\n this.logger.info(\"Configuring cometD \", {\n url\n });\n this.cometd.configure({\n url,\n // NOTE : Allow higher latency on busy networks to avoid retry loops when servers or networks fall behind.\n maxNetworkDelay: 30_000,\n logLevel,\n autoBatch: true\n });\n }\n}\nfunction getCometDWebsocketUrl(appConfig) {\n const httpUrl = new URL(`${appConfig.remote.packWsPath}/cometd`, appConfig.remote.baseUrl);\n httpUrl.protocol.replace(/https?/, \"ws\");\n // TODO: likely need a specific port for ingest - all of this should be in in appConfig\n return httpUrl.href;\n}\nclass TokenExtension {\n currentToken;\n setToken(token) {\n this.currentToken = token;\n }\n outgoing = message => {\n // Always use the latest token when doing a handshake (handles reconnects)\n if (message.channel === META_CHANNEL_HANDSHAKE) {\n if (this.currentToken) {\n message.ext ??= {};\n message.ext[BEARER_TOKEN_FIELD] = this.currentToken;\n }\n }\n return message;\n };\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { generateId, justOnce } from \"@palantir/pack.core\";\nimport { getMetadata, Metadata } from \"@palantir/pack.document-schema.model-types\";\nimport { DocumentLoadStatus } from \"@palantir/pack.state.core\";\nimport { Base64 } from \"js-base64\";\nimport * as y from \"yjs\";\nimport { EventServiceCometD } from \"./cometd/EventServiceCometD.js\";\n\n// TODO: replace with @osdk/foundry.pack types when they land.\n\n// TODO: presence api should have an eventType so we don't need extra wrapper here.\n\nconst UPDATE_ORIGIN_REMOTE = \"remote\";\nconst getDocumentUpdatesChannelId = documentId => `/document/${documentId}/updates`;\nconst getDocumentPublishChannelId = documentId => `/document/${documentId}/publish`;\nconst getDocumentActivityChannelId = documentId => `/document/${documentId}/activity`;\nconst getDocumentPresenceChannelId = documentId => `/document/${documentId}/presence`;\nconst getDocumentPresencePublishChannelId = documentId => `/document/${documentId}/presence-publish`;\n/**\n * This manages event subscriptions and publishing of document related events via\n * our PACK Foundry backend's cometd service.\n */\nexport class FoundryEventService {\n eventService;\n logger;\n sessions = new Map();\n constructor(app, cometd) {\n this.app = app;\n this.eventService = new EventServiceCometD(app, cometd);\n this.logger = app.config.logger.child({}, {\n level: \"debug\",\n msgPrefix: \"FoundryEventService\"\n });\n }\n getOrCreateSession(documentId, yDoc) {\n const sessionId = this.getSessionId(documentId);\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = {\n activitySubscriptionId: undefined,\n clientId: crypto.randomUUID(),\n documentId,\n documentSubscriptionId: undefined,\n lastRevisionId: undefined,\n localYDocUpdateHandler: undefined,\n presenceSubscriptionId: undefined,\n yDoc\n };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n startDocumentSync(documentId, yDoc, onStatusChange) {\n const session = this.getOrCreateSession(documentId, yDoc);\n if (session.documentSubscriptionId != null) {\n throw new Error(`Document data sync already active for document ${documentId}`);\n }\n const localYDocUpdateHandler = (update, origin) => {\n if (origin === UPDATE_ORIGIN_REMOTE) {\n return;\n }\n const lastRevisionId = session.lastRevisionId;\n if (lastRevisionId == null) {\n this.logger.error(\"Cannot publish document update before initial load is complete. The local state will remain inconsistent.\", {\n docId: documentId\n });\n return;\n }\n const publishChannelId = getDocumentPublishChannelId(documentId);\n const editId = generateId();\n const description = isEditDescription(origin) ? createDocumentEditDescription(origin) : undefined;\n void this.eventService.publish(publishChannelId, {\n clientId: session.clientId,\n description,\n editId,\n yjsUpdate: {\n data: Base64.fromUint8Array(update)\n }\n }).catch(error => {\n this.logger.error(\"Failed to publish document update\", error, {\n docId: documentId\n });\n });\n };\n session.localYDocUpdateHandler = localYDocUpdateHandler;\n yDoc.on(\"update\", localYDocUpdateHandler);\n onStatusChange({\n load: DocumentLoadStatus.LOADING\n });\n const channelId = getDocumentUpdatesChannelId(documentId);\n this.eventService.subscribe(channelId, message => {\n if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {\n return;\n }\n this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);\n }, () => ({\n clientId: session.clientId,\n lastRevisionId: session.lastRevisionId?.toString()\n })).then(subscriptionId => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n session.documentSubscriptionId = subscriptionId;\n } else {\n this.eventService.unsubscribe(subscriptionId);\n this.sessions.delete(this.getSessionId(documentId));\n }\n }).catch(e => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n const error = new Error(\"Failed to setup document data subscription\", {\n cause: e\n });\n onStatusChange({\n error,\n load: DocumentLoadStatus.ERROR\n });\n } else {\n this.logger.warn(\"Document data subscription error after subscription was closed\", {\n docId: documentId,\n error: e\n });\n }\n });\n return {\n clientId: session.clientId,\n documentId: session.documentId\n };\n }\n subscribeToActivityUpdates(documentId, callback) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentActivityChannelId(documentId);\n return this.eventService.subscribe(channelId, event => {\n this.logger.debug(\"Received activity event\", {\n docId: documentId,\n event\n });\n callback(event);\n }).then(subscriptionId => {\n session.activitySubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to activity updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to activity updates\", {\n cause: e\n });\n });\n }\n subscribeToPresenceUpdates(documentId, callback, options = {}) {\n const {\n ignoreSelfUpdates = true\n } = options;\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresenceChannelId(documentId);\n return this.eventService.subscribe(channelId, update => {\n // TODO: api should provide clientId so we filter on our presence messages only,\n // but allow apps to decide what they do with same-user-different-client messages ie\n // from different tabs or devices.\n const localUserId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (ignoreSelfUpdates && localUserId != null) {\n switch (update.type) {\n case \"presenceChangeEvent\":\n if (update.presenceChangeEvent.userId === localUserId) {\n return;\n }\n break;\n case \"customPresenceEvent\":\n if (update.customPresenceEvent.userId === localUserId) {\n return;\n }\n break;\n default:\n update;\n break;\n }\n }\n this.logger.debug(\"Received presence update\", {\n docId: documentId,\n updateType: update.type\n });\n callback(update);\n }).then(subscriptionId => {\n session.presenceSubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to presence updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to presence updates\", {\n cause: e\n });\n });\n }\n publishCustomPresence(documentId, eventType, eventData) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresencePublishChannelId(documentId);\n const messageData = {\n eventData,\n eventType\n };\n // TODO: maybe the session should hold userId\n // Though would need better reconnection handling to ensure userId doesn't change.\n const userId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (userId == null) {\n throw new Error(\"Could not get current userId\");\n }\n return this.eventService.publish(channelId, {\n custom: {\n clientId: session.clientId,\n eventData: messageData,\n // FIXME: why do we have to send this, we are authenticated\n userId\n },\n type: \"custom\"\n }).catch(error => {\n this.logger.error(\"Failed to publish custom presence\", error, {\n docId: documentId\n });\n throw error;\n });\n }\n stopDocumentSync(session) {\n const sessionId = this.getSessionId(session.documentId);\n const internalSession = this.sessions.get(sessionId);\n if (internalSession == null) {\n this.logger.warn(\"Attempted to stop sync for unknown session\", {\n documentId: session.documentId,\n clientId: session.clientId\n });\n return;\n }\n if (internalSession.localYDocUpdateHandler != null) {\n internalSession.yDoc?.off(\"update\", internalSession.localYDocUpdateHandler);\n internalSession.localYDocUpdateHandler = undefined;\n }\n if (internalSession.activitySubscriptionId) {\n this.eventService.unsubscribe(internalSession.activitySubscriptionId);\n }\n if (internalSession.presenceSubscriptionId) {\n this.eventService.unsubscribe(internalSession.presenceSubscriptionId);\n }\n if (internalSession.documentSubscriptionId) {\n this.eventService.unsubscribe(internalSession.documentSubscriptionId);\n this.sessions.delete(sessionId);\n }\n }\n handleDocumentUpdateMessage(session, message, yDoc, onStatusChange) {\n switch (message.type) {\n case \"error\":\n const {\n args,\n code,\n errorInstanceId\n } = message;\n this.logger.error(\"Received document update error message\", {\n docId: session.documentId,\n code,\n errorInstanceId,\n args\n });\n onStatusChange({\n error: new Error(`Subscription in error state [${errorInstanceId}]`, {\n cause: message\n }),\n load: DocumentLoadStatus.ERROR\n });\n break;\n case \"update\":\n const {\n baseRevisionId,\n clientId,\n revisionId,\n update\n } = message;\n const data = update != null && typeof update.data === \"string\" ? Base64.toUint8Array(update.data) : undefined;\n const messageDetail = {\n baseRevisionId,\n clientId,\n revisionId,\n updateSize: data?.byteLength ?? 0\n };\n\n // FIXME: the typescript generators for api types come out as string, hard to be clear that they are numbers.\n if (session.lastRevisionId != null && Number(baseRevisionId) !== session.lastRevisionId) {\n this.logger.error(\"Got unexpected update for baseRevisionId\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n return;\n }\n this.logger.debug(\"Applying remote Y.js update\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n session.lastRevisionId = Number(revisionId);\n if (data != null) {\n y.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);\n }\n onStatusChange({\n load: DocumentLoadStatus.LOADED\n });\n break;\n default:\n message;\n const {\n type\n } = message;\n justOnce(`unknown-collab-update-type:${type}`, () => {\n this.logger.warn(\"Received unknown DocumentUpdateMessage type. This is only warned the first occurrence.\", {\n docId: session.documentId,\n updateType: type\n });\n });\n break;\n }\n }\n getSessionId(documentId) {\n return documentId;\n }\n}\nexport function createFoundryEventService(app, cometd) {\n return new FoundryEventService(app, cometd);\n}\nfunction isEditDescription(obj) {\n return obj != null && typeof obj === \"object\" && \"data\" in obj && \"model\" in obj && typeof obj.model === \"object\" && obj.model != null && Metadata in obj.model;\n}\nfunction createDocumentEditDescription(editDescription) {\n return {\n eventData: {\n data: editDescription.data,\n version: 1\n },\n eventType: getMetadata(editDescription.model).name\n };\n}"]}
|
package/build/cjs/index.cjs
CHANGED
|
@@ -259,7 +259,7 @@ var FoundryEventService = class {
|
|
|
259
259
|
lastRevisionId: void 0,
|
|
260
260
|
localYDocUpdateHandler: void 0,
|
|
261
261
|
presenceSubscriptionId: void 0,
|
|
262
|
-
yDoc
|
|
262
|
+
yDoc
|
|
263
263
|
};
|
|
264
264
|
this.sessions.set(sessionId, session);
|
|
265
265
|
}
|
|
@@ -307,7 +307,7 @@ var FoundryEventService = class {
|
|
|
307
307
|
if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
|
-
this.handleDocumentUpdateMessage(session, message, onStatusChange);
|
|
310
|
+
this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);
|
|
311
311
|
}, () => ({
|
|
312
312
|
clientId: session.clientId,
|
|
313
313
|
lastRevisionId: session.lastRevisionId?.toString()
|
|
@@ -436,7 +436,7 @@ var FoundryEventService = class {
|
|
|
436
436
|
return;
|
|
437
437
|
}
|
|
438
438
|
if (internalSession.localYDocUpdateHandler != null) {
|
|
439
|
-
internalSession.yDoc
|
|
439
|
+
internalSession.yDoc?.off("update", internalSession.localYDocUpdateHandler);
|
|
440
440
|
internalSession.localYDocUpdateHandler = void 0;
|
|
441
441
|
}
|
|
442
442
|
if (internalSession.activitySubscriptionId) {
|
|
@@ -450,7 +450,7 @@ var FoundryEventService = class {
|
|
|
450
450
|
this.sessions.delete(sessionId);
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
|
-
handleDocumentUpdateMessage(session, message, onStatusChange) {
|
|
453
|
+
handleDocumentUpdateMessage(session, message, yDoc, onStatusChange) {
|
|
454
454
|
switch (message.type) {
|
|
455
455
|
case "error":
|
|
456
456
|
const {
|
|
@@ -500,7 +500,7 @@ var FoundryEventService = class {
|
|
|
500
500
|
});
|
|
501
501
|
session.lastRevisionId = Number(revisionId);
|
|
502
502
|
if (data != null) {
|
|
503
|
-
y__namespace.applyUpdate(
|
|
503
|
+
y__namespace.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);
|
|
504
504
|
}
|
|
505
505
|
onStatusChange({
|
|
506
506
|
load: pack_state_core.DocumentLoadStatus.LOADED
|
package/build/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cometd/EventServiceCometD.ts","../../src/FoundryEventService.ts"],"names":["cometd","CometD","AckExtension","getAuthModule","y","generateId","Base64","DocumentLoadStatus","justOnce","Metadata","getMetadata"],"mappings":"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","file":"index.cjs","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { AckExtension, CometD } from \"cometd\";\n// side-effect shenanigans imports the class impl to cometd module\nimport \"cometd/AckExtension.js\";\nconst BEARER_TOKEN_FIELD = \"bearer-token\";\nconst EXTENSION_ACK = \"AckExtension\";\nconst EXTENSION_HANDSHAKE_TOKEN = \"handshakeToken\";\nconst META_CHANNEL_HANDSHAKE = \"/meta/handshake\";\nexport class EventServiceCometD {\n logger;\n initializePromise;\n subscriptionById = new Map();\n tokenExtension = new TokenExtension();\n nextSubscriptionHandle = 0;\n constructor(app, cometd = new CometD()) {\n this.app = app;\n this.cometd = cometd;\n this.logger = app.config.logger.child({}, {\n msgPrefix: \"EventServiceCometD\"\n });\n this.configureCometd();\n this.cometd.registerExtension(EXTENSION_ACK, new AckExtension());\n this.cometd.registerExtension(EXTENSION_HANDSHAKE_TOKEN, this.tokenExtension);\n\n // TODO: Support binary messages\n // this.cometd.registerExtension(BINARY_EXTENSION_NAME, new BinaryExtension());\n\n // Any time the token changes, update the extension so reconnection requests use the new token.\n // This will also be called on initial token set when the auth module is initialized.\n getAuthModule(app).onTokenChange(token => {\n this.tokenExtension.setToken(token);\n });\n }\n initialize() {\n if (this.initializePromise != null) {\n return this.initializePromise;\n }\n this.initializePromise = new Promise(resolve => {\n this.cometd.addListener(META_CHANNEL_HANDSHAKE, ({\n clientId,\n connectionType,\n error,\n successful\n }) => {\n if (successful) {\n this.logger.info(\"CometD handshake successful\", {\n clientId,\n connectionType\n });\n resolve();\n this.cometd.batch(() => {\n this.subscriptionById.forEach((subscription, subscriptionId) => {\n this.logger.debug(\"Resubscribing to channel\", {\n channel: subscription.eventChannel,\n subscriptionId\n });\n const subscribeProps = subscription.getSubscriptionRequest?.();\n subscription.handle = this.cometd.resubscribe(subscription.handle, {\n ext: subscribeProps\n });\n });\n });\n } else {\n this.logger.warn(\"CometD handshake failed\", {\n clientId,\n error\n });\n }\n });\n const authModule = getAuthModule(this.app);\n void authModule.getToken().then(token => {\n this.logger.info(\"Initializing CometD with token\");\n this.tokenExtension.setToken(token);\n this.cometd.handshake();\n });\n });\n return this.initializePromise;\n }\n async subscribe(channel, onMessage, getSubscriptionRequest) {\n await this.initialize();\n const subscriptionId = (this.nextSubscriptionHandle++).toString(10);\n return new Promise((resolve, reject) => {\n const messageHandler = receivedData => {\n if (!this.subscriptionById.has(subscriptionId)) {\n this.logger.info(\"Dropping message for unsubscribing channel\", {\n channel,\n subscriptionId\n });\n return;\n }\n this.logger.debug(\"Received message on channel\", {\n channel,\n subscriptionId,\n hasData: receivedData.data != null\n });\n onMessage(receivedData.data);\n };\n const subscribeCallback = message => {\n if (message.successful) {\n this.logger.debug(\"Successfully subscribed to channel\", {\n channel,\n subscriptionId\n });\n resolve(subscriptionId);\n } else {\n this.subscriptionById.delete(subscriptionId);\n // TODO: Is failure really expected? It's not on the type...\n const maybeFailureReason = \"failure\" in message && typeof message.failure === \"object\" && message.failure && \"reason\" in message.failure && typeof message.failure.reason === \"string\" ? message.failure.reason : undefined;\n this.logger.error(\"Failed to subscribe to channel \", {\n channel,\n error: message.error,\n maybeFailureReason\n });\n const errorMessage = message.error ?? (maybeFailureReason != null ? `(no error message provided by server, a guess: ${maybeFailureReason})` : \"(no error message provided by server)\");\n reject(new Error(`Failed to subscribe to channel ${channel}: ${errorMessage}`));\n }\n };\n const ext = getSubscriptionRequest?.();\n const subscriptionHandle = ext != null ? this.cometd.subscribe(channel, messageHandler, {\n ext\n }, subscribeCallback) : this.cometd.subscribe(channel, messageHandler, subscribeCallback);\n this.subscriptionById.set(subscriptionId, {\n handle: subscriptionHandle,\n getSubscriptionRequest,\n eventChannel: channel\n });\n });\n }\n unsubscribe(subscriptionId) {\n const subscription = this.subscriptionById.get(subscriptionId);\n if (subscription == null) {\n this.logger.warn(\"Attempted to unsubscribe from unknown subscriptionId\", {\n subscriptionId\n });\n return;\n }\n const {\n handle,\n eventChannel\n } = subscription;\n this.subscriptionById.delete(subscriptionId);\n this.cometd.unsubscribe(handle, message => {\n if (!message.successful) {\n this.logger.warn(\"Server unsubscribe confirmation failed\", {\n eventChannel,\n subscriptionId,\n error: message.error\n });\n }\n });\n }\n async publish(channel, content) {\n await this.initialize();\n return new Promise((resolve, reject) => {\n this.cometd.publish(channel, content, message => {\n if (message.successful) {\n this.logger.debug(\"Successfully published message\", channel, {\n content\n });\n resolve();\n } else {\n const error = new Error(`Failed to publish to ${channel}`, {\n cause: message.error\n });\n this.logger.error(\"Failed to publish\", {\n channel,\n error\n });\n reject(error);\n }\n });\n });\n }\n setLogLevel(logLevel) {\n this.configureCometd(logLevel);\n }\n configureCometd(logLevel) {\n const url = getCometDWebsocketUrl(this.app.config);\n this.logger.info(\"Configuring cometD \", {\n url\n });\n this.cometd.configure({\n url,\n // NOTE : Allow higher latency on busy networks to avoid retry loops when servers or networks fall behind.\n maxNetworkDelay: 30_000,\n logLevel,\n autoBatch: true\n });\n }\n}\nfunction getCometDWebsocketUrl(appConfig) {\n const httpUrl = new URL(`${appConfig.remote.packWsPath}/cometd`, appConfig.remote.baseUrl);\n httpUrl.protocol.replace(/https?/, \"ws\");\n // TODO: likely need a specific port for ingest - all of this should be in in appConfig\n return httpUrl.href;\n}\nclass TokenExtension {\n currentToken;\n setToken(token) {\n this.currentToken = token;\n }\n outgoing = message => {\n // Always use the latest token when doing a handshake (handles reconnects)\n if (message.channel === META_CHANNEL_HANDSHAKE) {\n if (this.currentToken) {\n message.ext ??= {};\n message.ext[BEARER_TOKEN_FIELD] = this.currentToken;\n }\n }\n return message;\n };\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { generateId, justOnce } from \"@palantir/pack.core\";\nimport { getMetadata, Metadata } from \"@palantir/pack.document-schema.model-types\";\nimport { DocumentLoadStatus } from \"@palantir/pack.state.core\";\nimport { Base64 } from \"js-base64\";\nimport * as y from \"yjs\";\nimport { EventServiceCometD } from \"./cometd/EventServiceCometD.js\";\n\n// TODO: replace with @osdk/foundry.pack types when they land.\n\n// TODO: presence api should have an eventType so we don't need extra wrapper here.\n\nconst UPDATE_ORIGIN_REMOTE = \"remote\";\nconst getDocumentUpdatesChannelId = documentId => `/document/${documentId}/updates`;\nconst getDocumentPublishChannelId = documentId => `/document/${documentId}/publish`;\nconst getDocumentActivityChannelId = documentId => `/document/${documentId}/activity`;\nconst getDocumentPresenceChannelId = documentId => `/document/${documentId}/presence`;\nconst getDocumentPresencePublishChannelId = documentId => `/document/${documentId}/presence-publish`;\n/**\n * This manages event subscriptions and publishing of document related events via\n * our PACK Foundry backend's cometd service.\n */\nexport class FoundryEventService {\n eventService;\n logger;\n sessions = new Map();\n constructor(app, cometd) {\n this.app = app;\n this.eventService = new EventServiceCometD(app, cometd);\n this.logger = app.config.logger.child({}, {\n level: \"debug\",\n msgPrefix: \"FoundryEventService\"\n });\n }\n getOrCreateSession(documentId, yDoc) {\n const sessionId = this.getSessionId(documentId);\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = {\n activitySubscriptionId: undefined,\n clientId: crypto.randomUUID(),\n documentId,\n documentSubscriptionId: undefined,\n lastRevisionId: undefined,\n localYDocUpdateHandler: undefined,\n presenceSubscriptionId: undefined,\n yDoc: yDoc ?? new y.Doc()\n };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n startDocumentSync(documentId, yDoc, onStatusChange) {\n const session = this.getOrCreateSession(documentId, yDoc);\n if (session.documentSubscriptionId != null) {\n throw new Error(`Document data sync already active for document ${documentId}`);\n }\n const localYDocUpdateHandler = (update, origin) => {\n if (origin === UPDATE_ORIGIN_REMOTE) {\n return;\n }\n const lastRevisionId = session.lastRevisionId;\n if (lastRevisionId == null) {\n this.logger.error(\"Cannot publish document update before initial load is complete. The local state will remain inconsistent.\", {\n docId: documentId\n });\n return;\n }\n const publishChannelId = getDocumentPublishChannelId(documentId);\n const editId = generateId();\n const description = isEditDescription(origin) ? createDocumentEditDescription(origin) : undefined;\n void this.eventService.publish(publishChannelId, {\n clientId: session.clientId,\n description,\n editId,\n yjsUpdate: {\n data: Base64.fromUint8Array(update)\n }\n }).catch(error => {\n this.logger.error(\"Failed to publish document update\", error, {\n docId: documentId\n });\n });\n };\n session.localYDocUpdateHandler = localYDocUpdateHandler;\n yDoc.on(\"update\", localYDocUpdateHandler);\n onStatusChange({\n load: DocumentLoadStatus.LOADING\n });\n const channelId = getDocumentUpdatesChannelId(documentId);\n this.eventService.subscribe(channelId, message => {\n if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {\n return;\n }\n this.handleDocumentUpdateMessage(session, message, onStatusChange);\n }, () => ({\n clientId: session.clientId,\n lastRevisionId: session.lastRevisionId?.toString()\n })).then(subscriptionId => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n session.documentSubscriptionId = subscriptionId;\n } else {\n this.eventService.unsubscribe(subscriptionId);\n this.sessions.delete(this.getSessionId(documentId));\n }\n }).catch(e => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n const error = new Error(\"Failed to setup document data subscription\", {\n cause: e\n });\n onStatusChange({\n error,\n load: DocumentLoadStatus.ERROR\n });\n } else {\n this.logger.warn(\"Document data subscription error after subscription was closed\", {\n docId: documentId,\n error: e\n });\n }\n });\n return {\n clientId: session.clientId,\n documentId: session.documentId\n };\n }\n subscribeToActivityUpdates(documentId, callback) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentActivityChannelId(documentId);\n return this.eventService.subscribe(channelId, event => {\n this.logger.debug(\"Received activity event\", {\n docId: documentId,\n event\n });\n callback(event);\n }).then(subscriptionId => {\n session.activitySubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to activity updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to activity updates\", {\n cause: e\n });\n });\n }\n subscribeToPresenceUpdates(documentId, callback, options = {}) {\n const {\n ignoreSelfUpdates = true\n } = options;\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresenceChannelId(documentId);\n return this.eventService.subscribe(channelId, update => {\n // TODO: api should provide clientId so we filter on our presence messages only,\n // but allow apps to decide what they do with same-user-different-client messages ie\n // from different tabs or devices.\n const localUserId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (ignoreSelfUpdates && localUserId != null) {\n switch (update.type) {\n case \"presenceChangeEvent\":\n if (update.presenceChangeEvent.userId === localUserId) {\n return;\n }\n break;\n case \"customPresenceEvent\":\n if (update.customPresenceEvent.userId === localUserId) {\n return;\n }\n break;\n default:\n update;\n break;\n }\n }\n this.logger.debug(\"Received presence update\", {\n docId: documentId,\n updateType: update.type\n });\n callback(update);\n }).then(subscriptionId => {\n session.presenceSubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to presence updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to presence updates\", {\n cause: e\n });\n });\n }\n publishCustomPresence(documentId, eventType, eventData) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresencePublishChannelId(documentId);\n const messageData = {\n eventData,\n eventType\n };\n // TODO: maybe the session should hold userId\n // Though would need better reconnection handling to ensure userId doesn't change.\n const userId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (userId == null) {\n throw new Error(\"Could not get current userId\");\n }\n return this.eventService.publish(channelId, {\n custom: {\n clientId: session.clientId,\n eventData: messageData,\n // FIXME: why do we have to send this, we are authenticated\n userId\n },\n type: \"custom\"\n }).catch(error => {\n this.logger.error(\"Failed to publish custom presence\", error, {\n docId: documentId\n });\n throw error;\n });\n }\n stopDocumentSync(session) {\n const sessionId = this.getSessionId(session.documentId);\n const internalSession = this.sessions.get(sessionId);\n if (internalSession == null) {\n this.logger.warn(\"Attempted to stop sync for unknown session\", {\n documentId: session.documentId,\n clientId: session.clientId\n });\n return;\n }\n if (internalSession.localYDocUpdateHandler != null) {\n internalSession.yDoc.off(\"update\", internalSession.localYDocUpdateHandler);\n internalSession.localYDocUpdateHandler = undefined;\n }\n if (internalSession.activitySubscriptionId) {\n this.eventService.unsubscribe(internalSession.activitySubscriptionId);\n }\n if (internalSession.presenceSubscriptionId) {\n this.eventService.unsubscribe(internalSession.presenceSubscriptionId);\n }\n if (internalSession.documentSubscriptionId) {\n this.eventService.unsubscribe(internalSession.documentSubscriptionId);\n this.sessions.delete(sessionId);\n }\n }\n handleDocumentUpdateMessage(session, message, onStatusChange) {\n switch (message.type) {\n case \"error\":\n const {\n args,\n code,\n errorInstanceId\n } = message;\n this.logger.error(\"Received document update error message\", {\n docId: session.documentId,\n code,\n errorInstanceId,\n args\n });\n onStatusChange({\n error: new Error(`Subscription in error state [${errorInstanceId}]`, {\n cause: message\n }),\n load: DocumentLoadStatus.ERROR\n });\n break;\n case \"update\":\n const {\n baseRevisionId,\n clientId,\n revisionId,\n update\n } = message;\n const data = update != null && typeof update.data === \"string\" ? Base64.toUint8Array(update.data) : undefined;\n const messageDetail = {\n baseRevisionId,\n clientId,\n revisionId,\n updateSize: data?.byteLength ?? 0\n };\n\n // FIXME: the typescript generators for api types come out as string, hard to be clear that they are numbers.\n if (session.lastRevisionId != null && Number(baseRevisionId) !== session.lastRevisionId) {\n this.logger.error(\"Got unexpected update for baseRevisionId\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n return;\n }\n this.logger.debug(\"Applying remote Y.js update\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n session.lastRevisionId = Number(revisionId);\n if (data != null) {\n y.applyUpdate(session.yDoc, data, UPDATE_ORIGIN_REMOTE);\n }\n onStatusChange({\n load: DocumentLoadStatus.LOADED\n });\n break;\n default:\n message;\n const {\n type\n } = message;\n justOnce(`unknown-collab-update-type:${type}`, () => {\n this.logger.warn(\"Received unknown DocumentUpdateMessage type. This is only warned the first occurrence.\", {\n docId: session.documentId,\n updateType: type\n });\n });\n break;\n }\n }\n getSessionId(documentId) {\n return documentId;\n }\n}\nexport function createFoundryEventService(app, cometd) {\n return new FoundryEventService(app, cometd);\n}\nfunction isEditDescription(obj) {\n return obj != null && typeof obj === \"object\" && \"data\" in obj && \"model\" in obj && typeof obj.model === \"object\" && obj.model != null && Metadata in obj.model;\n}\nfunction createDocumentEditDescription(editDescription) {\n return {\n eventData: {\n data: editDescription.data,\n version: 1\n },\n eventType: getMetadata(editDescription.model).name\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cometd/EventServiceCometD.ts","../../src/FoundryEventService.ts"],"names":["cometd","CometD","AckExtension","getAuthModule","generateId","Base64","DocumentLoadStatus","y","justOnce","Metadata","getMetadata"],"mappings":"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","file":"index.cjs","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { AckExtension, CometD } from \"cometd\";\n// side-effect shenanigans imports the class impl to cometd module\nimport \"cometd/AckExtension.js\";\nconst BEARER_TOKEN_FIELD = \"bearer-token\";\nconst EXTENSION_ACK = \"AckExtension\";\nconst EXTENSION_HANDSHAKE_TOKEN = \"handshakeToken\";\nconst META_CHANNEL_HANDSHAKE = \"/meta/handshake\";\nexport class EventServiceCometD {\n logger;\n initializePromise;\n subscriptionById = new Map();\n tokenExtension = new TokenExtension();\n nextSubscriptionHandle = 0;\n constructor(app, cometd = new CometD()) {\n this.app = app;\n this.cometd = cometd;\n this.logger = app.config.logger.child({}, {\n msgPrefix: \"EventServiceCometD\"\n });\n this.configureCometd();\n this.cometd.registerExtension(EXTENSION_ACK, new AckExtension());\n this.cometd.registerExtension(EXTENSION_HANDSHAKE_TOKEN, this.tokenExtension);\n\n // TODO: Support binary messages\n // this.cometd.registerExtension(BINARY_EXTENSION_NAME, new BinaryExtension());\n\n // Any time the token changes, update the extension so reconnection requests use the new token.\n // This will also be called on initial token set when the auth module is initialized.\n getAuthModule(app).onTokenChange(token => {\n this.tokenExtension.setToken(token);\n });\n }\n initialize() {\n if (this.initializePromise != null) {\n return this.initializePromise;\n }\n this.initializePromise = new Promise(resolve => {\n this.cometd.addListener(META_CHANNEL_HANDSHAKE, ({\n clientId,\n connectionType,\n error,\n successful\n }) => {\n if (successful) {\n this.logger.info(\"CometD handshake successful\", {\n clientId,\n connectionType\n });\n resolve();\n this.cometd.batch(() => {\n this.subscriptionById.forEach((subscription, subscriptionId) => {\n this.logger.debug(\"Resubscribing to channel\", {\n channel: subscription.eventChannel,\n subscriptionId\n });\n const subscribeProps = subscription.getSubscriptionRequest?.();\n subscription.handle = this.cometd.resubscribe(subscription.handle, {\n ext: subscribeProps\n });\n });\n });\n } else {\n this.logger.warn(\"CometD handshake failed\", {\n clientId,\n error\n });\n }\n });\n const authModule = getAuthModule(this.app);\n void authModule.getToken().then(token => {\n this.logger.info(\"Initializing CometD with token\");\n this.tokenExtension.setToken(token);\n this.cometd.handshake();\n });\n });\n return this.initializePromise;\n }\n async subscribe(channel, onMessage, getSubscriptionRequest) {\n await this.initialize();\n const subscriptionId = (this.nextSubscriptionHandle++).toString(10);\n return new Promise((resolve, reject) => {\n const messageHandler = receivedData => {\n if (!this.subscriptionById.has(subscriptionId)) {\n this.logger.info(\"Dropping message for unsubscribing channel\", {\n channel,\n subscriptionId\n });\n return;\n }\n this.logger.debug(\"Received message on channel\", {\n channel,\n subscriptionId,\n hasData: receivedData.data != null\n });\n onMessage(receivedData.data);\n };\n const subscribeCallback = message => {\n if (message.successful) {\n this.logger.debug(\"Successfully subscribed to channel\", {\n channel,\n subscriptionId\n });\n resolve(subscriptionId);\n } else {\n this.subscriptionById.delete(subscriptionId);\n // TODO: Is failure really expected? It's not on the type...\n const maybeFailureReason = \"failure\" in message && typeof message.failure === \"object\" && message.failure && \"reason\" in message.failure && typeof message.failure.reason === \"string\" ? message.failure.reason : undefined;\n this.logger.error(\"Failed to subscribe to channel \", {\n channel,\n error: message.error,\n maybeFailureReason\n });\n const errorMessage = message.error ?? (maybeFailureReason != null ? `(no error message provided by server, a guess: ${maybeFailureReason})` : \"(no error message provided by server)\");\n reject(new Error(`Failed to subscribe to channel ${channel}: ${errorMessage}`));\n }\n };\n const ext = getSubscriptionRequest?.();\n const subscriptionHandle = ext != null ? this.cometd.subscribe(channel, messageHandler, {\n ext\n }, subscribeCallback) : this.cometd.subscribe(channel, messageHandler, subscribeCallback);\n this.subscriptionById.set(subscriptionId, {\n handle: subscriptionHandle,\n getSubscriptionRequest,\n eventChannel: channel\n });\n });\n }\n unsubscribe(subscriptionId) {\n const subscription = this.subscriptionById.get(subscriptionId);\n if (subscription == null) {\n this.logger.warn(\"Attempted to unsubscribe from unknown subscriptionId\", {\n subscriptionId\n });\n return;\n }\n const {\n handle,\n eventChannel\n } = subscription;\n this.subscriptionById.delete(subscriptionId);\n this.cometd.unsubscribe(handle, message => {\n if (!message.successful) {\n this.logger.warn(\"Server unsubscribe confirmation failed\", {\n eventChannel,\n subscriptionId,\n error: message.error\n });\n }\n });\n }\n async publish(channel, content) {\n await this.initialize();\n return new Promise((resolve, reject) => {\n this.cometd.publish(channel, content, message => {\n if (message.successful) {\n this.logger.debug(\"Successfully published message\", channel, {\n content\n });\n resolve();\n } else {\n const error = new Error(`Failed to publish to ${channel}`, {\n cause: message.error\n });\n this.logger.error(\"Failed to publish\", {\n channel,\n error\n });\n reject(error);\n }\n });\n });\n }\n setLogLevel(logLevel) {\n this.configureCometd(logLevel);\n }\n configureCometd(logLevel) {\n const url = getCometDWebsocketUrl(this.app.config);\n this.logger.info(\"Configuring cometD \", {\n url\n });\n this.cometd.configure({\n url,\n // NOTE : Allow higher latency on busy networks to avoid retry loops when servers or networks fall behind.\n maxNetworkDelay: 30_000,\n logLevel,\n autoBatch: true\n });\n }\n}\nfunction getCometDWebsocketUrl(appConfig) {\n const httpUrl = new URL(`${appConfig.remote.packWsPath}/cometd`, appConfig.remote.baseUrl);\n httpUrl.protocol.replace(/https?/, \"ws\");\n // TODO: likely need a specific port for ingest - all of this should be in in appConfig\n return httpUrl.href;\n}\nclass TokenExtension {\n currentToken;\n setToken(token) {\n this.currentToken = token;\n }\n outgoing = message => {\n // Always use the latest token when doing a handshake (handles reconnects)\n if (message.channel === META_CHANNEL_HANDSHAKE) {\n if (this.currentToken) {\n message.ext ??= {};\n message.ext[BEARER_TOKEN_FIELD] = this.currentToken;\n }\n }\n return message;\n };\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { generateId, justOnce } from \"@palantir/pack.core\";\nimport { getMetadata, Metadata } from \"@palantir/pack.document-schema.model-types\";\nimport { DocumentLoadStatus } from \"@palantir/pack.state.core\";\nimport { Base64 } from \"js-base64\";\nimport * as y from \"yjs\";\nimport { EventServiceCometD } from \"./cometd/EventServiceCometD.js\";\n\n// TODO: replace with @osdk/foundry.pack types when they land.\n\n// TODO: presence api should have an eventType so we don't need extra wrapper here.\n\nconst UPDATE_ORIGIN_REMOTE = \"remote\";\nconst getDocumentUpdatesChannelId = documentId => `/document/${documentId}/updates`;\nconst getDocumentPublishChannelId = documentId => `/document/${documentId}/publish`;\nconst getDocumentActivityChannelId = documentId => `/document/${documentId}/activity`;\nconst getDocumentPresenceChannelId = documentId => `/document/${documentId}/presence`;\nconst getDocumentPresencePublishChannelId = documentId => `/document/${documentId}/presence-publish`;\n/**\n * This manages event subscriptions and publishing of document related events via\n * our PACK Foundry backend's cometd service.\n */\nexport class FoundryEventService {\n eventService;\n logger;\n sessions = new Map();\n constructor(app, cometd) {\n this.app = app;\n this.eventService = new EventServiceCometD(app, cometd);\n this.logger = app.config.logger.child({}, {\n level: \"debug\",\n msgPrefix: \"FoundryEventService\"\n });\n }\n getOrCreateSession(documentId, yDoc) {\n const sessionId = this.getSessionId(documentId);\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = {\n activitySubscriptionId: undefined,\n clientId: crypto.randomUUID(),\n documentId,\n documentSubscriptionId: undefined,\n lastRevisionId: undefined,\n localYDocUpdateHandler: undefined,\n presenceSubscriptionId: undefined,\n yDoc\n };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n startDocumentSync(documentId, yDoc, onStatusChange) {\n const session = this.getOrCreateSession(documentId, yDoc);\n if (session.documentSubscriptionId != null) {\n throw new Error(`Document data sync already active for document ${documentId}`);\n }\n const localYDocUpdateHandler = (update, origin) => {\n if (origin === UPDATE_ORIGIN_REMOTE) {\n return;\n }\n const lastRevisionId = session.lastRevisionId;\n if (lastRevisionId == null) {\n this.logger.error(\"Cannot publish document update before initial load is complete. The local state will remain inconsistent.\", {\n docId: documentId\n });\n return;\n }\n const publishChannelId = getDocumentPublishChannelId(documentId);\n const editId = generateId();\n const description = isEditDescription(origin) ? createDocumentEditDescription(origin) : undefined;\n void this.eventService.publish(publishChannelId, {\n clientId: session.clientId,\n description,\n editId,\n yjsUpdate: {\n data: Base64.fromUint8Array(update)\n }\n }).catch(error => {\n this.logger.error(\"Failed to publish document update\", error, {\n docId: documentId\n });\n });\n };\n session.localYDocUpdateHandler = localYDocUpdateHandler;\n yDoc.on(\"update\", localYDocUpdateHandler);\n onStatusChange({\n load: DocumentLoadStatus.LOADING\n });\n const channelId = getDocumentUpdatesChannelId(documentId);\n this.eventService.subscribe(channelId, message => {\n if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {\n return;\n }\n this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);\n }, () => ({\n clientId: session.clientId,\n lastRevisionId: session.lastRevisionId?.toString()\n })).then(subscriptionId => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n session.documentSubscriptionId = subscriptionId;\n } else {\n this.eventService.unsubscribe(subscriptionId);\n this.sessions.delete(this.getSessionId(documentId));\n }\n }).catch(e => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n const error = new Error(\"Failed to setup document data subscription\", {\n cause: e\n });\n onStatusChange({\n error,\n load: DocumentLoadStatus.ERROR\n });\n } else {\n this.logger.warn(\"Document data subscription error after subscription was closed\", {\n docId: documentId,\n error: e\n });\n }\n });\n return {\n clientId: session.clientId,\n documentId: session.documentId\n };\n }\n subscribeToActivityUpdates(documentId, callback) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentActivityChannelId(documentId);\n return this.eventService.subscribe(channelId, event => {\n this.logger.debug(\"Received activity event\", {\n docId: documentId,\n event\n });\n callback(event);\n }).then(subscriptionId => {\n session.activitySubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to activity updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to activity updates\", {\n cause: e\n });\n });\n }\n subscribeToPresenceUpdates(documentId, callback, options = {}) {\n const {\n ignoreSelfUpdates = true\n } = options;\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresenceChannelId(documentId);\n return this.eventService.subscribe(channelId, update => {\n // TODO: api should provide clientId so we filter on our presence messages only,\n // but allow apps to decide what they do with same-user-different-client messages ie\n // from different tabs or devices.\n const localUserId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (ignoreSelfUpdates && localUserId != null) {\n switch (update.type) {\n case \"presenceChangeEvent\":\n if (update.presenceChangeEvent.userId === localUserId) {\n return;\n }\n break;\n case \"customPresenceEvent\":\n if (update.customPresenceEvent.userId === localUserId) {\n return;\n }\n break;\n default:\n update;\n break;\n }\n }\n this.logger.debug(\"Received presence update\", {\n docId: documentId,\n updateType: update.type\n });\n callback(update);\n }).then(subscriptionId => {\n session.presenceSubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to presence updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to presence updates\", {\n cause: e\n });\n });\n }\n publishCustomPresence(documentId, eventType, eventData) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresencePublishChannelId(documentId);\n const messageData = {\n eventData,\n eventType\n };\n // TODO: maybe the session should hold userId\n // Though would need better reconnection handling to ensure userId doesn't change.\n const userId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (userId == null) {\n throw new Error(\"Could not get current userId\");\n }\n return this.eventService.publish(channelId, {\n custom: {\n clientId: session.clientId,\n eventData: messageData,\n // FIXME: why do we have to send this, we are authenticated\n userId\n },\n type: \"custom\"\n }).catch(error => {\n this.logger.error(\"Failed to publish custom presence\", error, {\n docId: documentId\n });\n throw error;\n });\n }\n stopDocumentSync(session) {\n const sessionId = this.getSessionId(session.documentId);\n const internalSession = this.sessions.get(sessionId);\n if (internalSession == null) {\n this.logger.warn(\"Attempted to stop sync for unknown session\", {\n documentId: session.documentId,\n clientId: session.clientId\n });\n return;\n }\n if (internalSession.localYDocUpdateHandler != null) {\n internalSession.yDoc?.off(\"update\", internalSession.localYDocUpdateHandler);\n internalSession.localYDocUpdateHandler = undefined;\n }\n if (internalSession.activitySubscriptionId) {\n this.eventService.unsubscribe(internalSession.activitySubscriptionId);\n }\n if (internalSession.presenceSubscriptionId) {\n this.eventService.unsubscribe(internalSession.presenceSubscriptionId);\n }\n if (internalSession.documentSubscriptionId) {\n this.eventService.unsubscribe(internalSession.documentSubscriptionId);\n this.sessions.delete(sessionId);\n }\n }\n handleDocumentUpdateMessage(session, message, yDoc, onStatusChange) {\n switch (message.type) {\n case \"error\":\n const {\n args,\n code,\n errorInstanceId\n } = message;\n this.logger.error(\"Received document update error message\", {\n docId: session.documentId,\n code,\n errorInstanceId,\n args\n });\n onStatusChange({\n error: new Error(`Subscription in error state [${errorInstanceId}]`, {\n cause: message\n }),\n load: DocumentLoadStatus.ERROR\n });\n break;\n case \"update\":\n const {\n baseRevisionId,\n clientId,\n revisionId,\n update\n } = message;\n const data = update != null && typeof update.data === \"string\" ? Base64.toUint8Array(update.data) : undefined;\n const messageDetail = {\n baseRevisionId,\n clientId,\n revisionId,\n updateSize: data?.byteLength ?? 0\n };\n\n // FIXME: the typescript generators for api types come out as string, hard to be clear that they are numbers.\n if (session.lastRevisionId != null && Number(baseRevisionId) !== session.lastRevisionId) {\n this.logger.error(\"Got unexpected update for baseRevisionId\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n return;\n }\n this.logger.debug(\"Applying remote Y.js update\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n session.lastRevisionId = Number(revisionId);\n if (data != null) {\n y.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);\n }\n onStatusChange({\n load: DocumentLoadStatus.LOADED\n });\n break;\n default:\n message;\n const {\n type\n } = message;\n justOnce(`unknown-collab-update-type:${type}`, () => {\n this.logger.warn(\"Received unknown DocumentUpdateMessage type. This is only warned the first occurrence.\", {\n docId: session.documentId,\n updateType: type\n });\n });\n break;\n }\n }\n getSessionId(documentId) {\n return documentId;\n }\n}\nexport function createFoundryEventService(app, cometd) {\n return new FoundryEventService(app, cometd);\n}\nfunction isEditDescription(obj) {\n return obj != null && typeof obj === \"object\" && \"data\" in obj && \"model\" in obj && typeof obj.model === \"object\" && obj.model != null && Metadata in obj.model;\n}\nfunction createDocumentEditDescription(editDescription) {\n return {\n eventData: {\n data: editDescription.data,\n version: 1\n },\n eventType: getMetadata(editDescription.model).name\n };\n}"]}
|
package/build/esm/index.js
CHANGED
|
@@ -237,7 +237,7 @@ var FoundryEventService = class {
|
|
|
237
237
|
lastRevisionId: void 0,
|
|
238
238
|
localYDocUpdateHandler: void 0,
|
|
239
239
|
presenceSubscriptionId: void 0,
|
|
240
|
-
yDoc
|
|
240
|
+
yDoc
|
|
241
241
|
};
|
|
242
242
|
this.sessions.set(sessionId, session);
|
|
243
243
|
}
|
|
@@ -285,7 +285,7 @@ var FoundryEventService = class {
|
|
|
285
285
|
if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {
|
|
286
286
|
return;
|
|
287
287
|
}
|
|
288
|
-
this.handleDocumentUpdateMessage(session, message, onStatusChange);
|
|
288
|
+
this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);
|
|
289
289
|
}, () => ({
|
|
290
290
|
clientId: session.clientId,
|
|
291
291
|
lastRevisionId: session.lastRevisionId?.toString()
|
|
@@ -414,7 +414,7 @@ var FoundryEventService = class {
|
|
|
414
414
|
return;
|
|
415
415
|
}
|
|
416
416
|
if (internalSession.localYDocUpdateHandler != null) {
|
|
417
|
-
internalSession.yDoc
|
|
417
|
+
internalSession.yDoc?.off("update", internalSession.localYDocUpdateHandler);
|
|
418
418
|
internalSession.localYDocUpdateHandler = void 0;
|
|
419
419
|
}
|
|
420
420
|
if (internalSession.activitySubscriptionId) {
|
|
@@ -428,7 +428,7 @@ var FoundryEventService = class {
|
|
|
428
428
|
this.sessions.delete(sessionId);
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
|
-
handleDocumentUpdateMessage(session, message, onStatusChange) {
|
|
431
|
+
handleDocumentUpdateMessage(session, message, yDoc, onStatusChange) {
|
|
432
432
|
switch (message.type) {
|
|
433
433
|
case "error":
|
|
434
434
|
const {
|
|
@@ -478,7 +478,7 @@ var FoundryEventService = class {
|
|
|
478
478
|
});
|
|
479
479
|
session.lastRevisionId = Number(revisionId);
|
|
480
480
|
if (data != null) {
|
|
481
|
-
y.applyUpdate(
|
|
481
|
+
y.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);
|
|
482
482
|
}
|
|
483
483
|
onStatusChange({
|
|
484
484
|
load: DocumentLoadStatus.LOADED
|
package/build/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cometd/EventServiceCometD.ts","../../src/FoundryEventService.ts"],"names":["getAuthModule"],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { AckExtension, CometD } from \"cometd\";\n// side-effect shenanigans imports the class impl to cometd module\nimport \"cometd/AckExtension.js\";\nconst BEARER_TOKEN_FIELD = \"bearer-token\";\nconst EXTENSION_ACK = \"AckExtension\";\nconst EXTENSION_HANDSHAKE_TOKEN = \"handshakeToken\";\nconst META_CHANNEL_HANDSHAKE = \"/meta/handshake\";\nexport class EventServiceCometD {\n logger;\n initializePromise;\n subscriptionById = new Map();\n tokenExtension = new TokenExtension();\n nextSubscriptionHandle = 0;\n constructor(app, cometd = new CometD()) {\n this.app = app;\n this.cometd = cometd;\n this.logger = app.config.logger.child({}, {\n msgPrefix: \"EventServiceCometD\"\n });\n this.configureCometd();\n this.cometd.registerExtension(EXTENSION_ACK, new AckExtension());\n this.cometd.registerExtension(EXTENSION_HANDSHAKE_TOKEN, this.tokenExtension);\n\n // TODO: Support binary messages\n // this.cometd.registerExtension(BINARY_EXTENSION_NAME, new BinaryExtension());\n\n // Any time the token changes, update the extension so reconnection requests use the new token.\n // This will also be called on initial token set when the auth module is initialized.\n getAuthModule(app).onTokenChange(token => {\n this.tokenExtension.setToken(token);\n });\n }\n initialize() {\n if (this.initializePromise != null) {\n return this.initializePromise;\n }\n this.initializePromise = new Promise(resolve => {\n this.cometd.addListener(META_CHANNEL_HANDSHAKE, ({\n clientId,\n connectionType,\n error,\n successful\n }) => {\n if (successful) {\n this.logger.info(\"CometD handshake successful\", {\n clientId,\n connectionType\n });\n resolve();\n this.cometd.batch(() => {\n this.subscriptionById.forEach((subscription, subscriptionId) => {\n this.logger.debug(\"Resubscribing to channel\", {\n channel: subscription.eventChannel,\n subscriptionId\n });\n const subscribeProps = subscription.getSubscriptionRequest?.();\n subscription.handle = this.cometd.resubscribe(subscription.handle, {\n ext: subscribeProps\n });\n });\n });\n } else {\n this.logger.warn(\"CometD handshake failed\", {\n clientId,\n error\n });\n }\n });\n const authModule = getAuthModule(this.app);\n void authModule.getToken().then(token => {\n this.logger.info(\"Initializing CometD with token\");\n this.tokenExtension.setToken(token);\n this.cometd.handshake();\n });\n });\n return this.initializePromise;\n }\n async subscribe(channel, onMessage, getSubscriptionRequest) {\n await this.initialize();\n const subscriptionId = (this.nextSubscriptionHandle++).toString(10);\n return new Promise((resolve, reject) => {\n const messageHandler = receivedData => {\n if (!this.subscriptionById.has(subscriptionId)) {\n this.logger.info(\"Dropping message for unsubscribing channel\", {\n channel,\n subscriptionId\n });\n return;\n }\n this.logger.debug(\"Received message on channel\", {\n channel,\n subscriptionId,\n hasData: receivedData.data != null\n });\n onMessage(receivedData.data);\n };\n const subscribeCallback = message => {\n if (message.successful) {\n this.logger.debug(\"Successfully subscribed to channel\", {\n channel,\n subscriptionId\n });\n resolve(subscriptionId);\n } else {\n this.subscriptionById.delete(subscriptionId);\n // TODO: Is failure really expected? It's not on the type...\n const maybeFailureReason = \"failure\" in message && typeof message.failure === \"object\" && message.failure && \"reason\" in message.failure && typeof message.failure.reason === \"string\" ? message.failure.reason : undefined;\n this.logger.error(\"Failed to subscribe to channel \", {\n channel,\n error: message.error,\n maybeFailureReason\n });\n const errorMessage = message.error ?? (maybeFailureReason != null ? `(no error message provided by server, a guess: ${maybeFailureReason})` : \"(no error message provided by server)\");\n reject(new Error(`Failed to subscribe to channel ${channel}: ${errorMessage}`));\n }\n };\n const ext = getSubscriptionRequest?.();\n const subscriptionHandle = ext != null ? this.cometd.subscribe(channel, messageHandler, {\n ext\n }, subscribeCallback) : this.cometd.subscribe(channel, messageHandler, subscribeCallback);\n this.subscriptionById.set(subscriptionId, {\n handle: subscriptionHandle,\n getSubscriptionRequest,\n eventChannel: channel\n });\n });\n }\n unsubscribe(subscriptionId) {\n const subscription = this.subscriptionById.get(subscriptionId);\n if (subscription == null) {\n this.logger.warn(\"Attempted to unsubscribe from unknown subscriptionId\", {\n subscriptionId\n });\n return;\n }\n const {\n handle,\n eventChannel\n } = subscription;\n this.subscriptionById.delete(subscriptionId);\n this.cometd.unsubscribe(handle, message => {\n if (!message.successful) {\n this.logger.warn(\"Server unsubscribe confirmation failed\", {\n eventChannel,\n subscriptionId,\n error: message.error\n });\n }\n });\n }\n async publish(channel, content) {\n await this.initialize();\n return new Promise((resolve, reject) => {\n this.cometd.publish(channel, content, message => {\n if (message.successful) {\n this.logger.debug(\"Successfully published message\", channel, {\n content\n });\n resolve();\n } else {\n const error = new Error(`Failed to publish to ${channel}`, {\n cause: message.error\n });\n this.logger.error(\"Failed to publish\", {\n channel,\n error\n });\n reject(error);\n }\n });\n });\n }\n setLogLevel(logLevel) {\n this.configureCometd(logLevel);\n }\n configureCometd(logLevel) {\n const url = getCometDWebsocketUrl(this.app.config);\n this.logger.info(\"Configuring cometD \", {\n url\n });\n this.cometd.configure({\n url,\n // NOTE : Allow higher latency on busy networks to avoid retry loops when servers or networks fall behind.\n maxNetworkDelay: 30_000,\n logLevel,\n autoBatch: true\n });\n }\n}\nfunction getCometDWebsocketUrl(appConfig) {\n const httpUrl = new URL(`${appConfig.remote.packWsPath}/cometd`, appConfig.remote.baseUrl);\n httpUrl.protocol.replace(/https?/, \"ws\");\n // TODO: likely need a specific port for ingest - all of this should be in in appConfig\n return httpUrl.href;\n}\nclass TokenExtension {\n currentToken;\n setToken(token) {\n this.currentToken = token;\n }\n outgoing = message => {\n // Always use the latest token when doing a handshake (handles reconnects)\n if (message.channel === META_CHANNEL_HANDSHAKE) {\n if (this.currentToken) {\n message.ext ??= {};\n message.ext[BEARER_TOKEN_FIELD] = this.currentToken;\n }\n }\n return message;\n };\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { generateId, justOnce } from \"@palantir/pack.core\";\nimport { getMetadata, Metadata } from \"@palantir/pack.document-schema.model-types\";\nimport { DocumentLoadStatus } from \"@palantir/pack.state.core\";\nimport { Base64 } from \"js-base64\";\nimport * as y from \"yjs\";\nimport { EventServiceCometD } from \"./cometd/EventServiceCometD.js\";\n\n// TODO: replace with @osdk/foundry.pack types when they land.\n\n// TODO: presence api should have an eventType so we don't need extra wrapper here.\n\nconst UPDATE_ORIGIN_REMOTE = \"remote\";\nconst getDocumentUpdatesChannelId = documentId => `/document/${documentId}/updates`;\nconst getDocumentPublishChannelId = documentId => `/document/${documentId}/publish`;\nconst getDocumentActivityChannelId = documentId => `/document/${documentId}/activity`;\nconst getDocumentPresenceChannelId = documentId => `/document/${documentId}/presence`;\nconst getDocumentPresencePublishChannelId = documentId => `/document/${documentId}/presence-publish`;\n/**\n * This manages event subscriptions and publishing of document related events via\n * our PACK Foundry backend's cometd service.\n */\nexport class FoundryEventService {\n eventService;\n logger;\n sessions = new Map();\n constructor(app, cometd) {\n this.app = app;\n this.eventService = new EventServiceCometD(app, cometd);\n this.logger = app.config.logger.child({}, {\n level: \"debug\",\n msgPrefix: \"FoundryEventService\"\n });\n }\n getOrCreateSession(documentId, yDoc) {\n const sessionId = this.getSessionId(documentId);\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = {\n activitySubscriptionId: undefined,\n clientId: crypto.randomUUID(),\n documentId,\n documentSubscriptionId: undefined,\n lastRevisionId: undefined,\n localYDocUpdateHandler: undefined,\n presenceSubscriptionId: undefined,\n yDoc: yDoc ?? new y.Doc()\n };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n startDocumentSync(documentId, yDoc, onStatusChange) {\n const session = this.getOrCreateSession(documentId, yDoc);\n if (session.documentSubscriptionId != null) {\n throw new Error(`Document data sync already active for document ${documentId}`);\n }\n const localYDocUpdateHandler = (update, origin) => {\n if (origin === UPDATE_ORIGIN_REMOTE) {\n return;\n }\n const lastRevisionId = session.lastRevisionId;\n if (lastRevisionId == null) {\n this.logger.error(\"Cannot publish document update before initial load is complete. The local state will remain inconsistent.\", {\n docId: documentId\n });\n return;\n }\n const publishChannelId = getDocumentPublishChannelId(documentId);\n const editId = generateId();\n const description = isEditDescription(origin) ? createDocumentEditDescription(origin) : undefined;\n void this.eventService.publish(publishChannelId, {\n clientId: session.clientId,\n description,\n editId,\n yjsUpdate: {\n data: Base64.fromUint8Array(update)\n }\n }).catch(error => {\n this.logger.error(\"Failed to publish document update\", error, {\n docId: documentId\n });\n });\n };\n session.localYDocUpdateHandler = localYDocUpdateHandler;\n yDoc.on(\"update\", localYDocUpdateHandler);\n onStatusChange({\n load: DocumentLoadStatus.LOADING\n });\n const channelId = getDocumentUpdatesChannelId(documentId);\n this.eventService.subscribe(channelId, message => {\n if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {\n return;\n }\n this.handleDocumentUpdateMessage(session, message, onStatusChange);\n }, () => ({\n clientId: session.clientId,\n lastRevisionId: session.lastRevisionId?.toString()\n })).then(subscriptionId => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n session.documentSubscriptionId = subscriptionId;\n } else {\n this.eventService.unsubscribe(subscriptionId);\n this.sessions.delete(this.getSessionId(documentId));\n }\n }).catch(e => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n const error = new Error(\"Failed to setup document data subscription\", {\n cause: e\n });\n onStatusChange({\n error,\n load: DocumentLoadStatus.ERROR\n });\n } else {\n this.logger.warn(\"Document data subscription error after subscription was closed\", {\n docId: documentId,\n error: e\n });\n }\n });\n return {\n clientId: session.clientId,\n documentId: session.documentId\n };\n }\n subscribeToActivityUpdates(documentId, callback) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentActivityChannelId(documentId);\n return this.eventService.subscribe(channelId, event => {\n this.logger.debug(\"Received activity event\", {\n docId: documentId,\n event\n });\n callback(event);\n }).then(subscriptionId => {\n session.activitySubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to activity updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to activity updates\", {\n cause: e\n });\n });\n }\n subscribeToPresenceUpdates(documentId, callback, options = {}) {\n const {\n ignoreSelfUpdates = true\n } = options;\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresenceChannelId(documentId);\n return this.eventService.subscribe(channelId, update => {\n // TODO: api should provide clientId so we filter on our presence messages only,\n // but allow apps to decide what they do with same-user-different-client messages ie\n // from different tabs or devices.\n const localUserId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (ignoreSelfUpdates && localUserId != null) {\n switch (update.type) {\n case \"presenceChangeEvent\":\n if (update.presenceChangeEvent.userId === localUserId) {\n return;\n }\n break;\n case \"customPresenceEvent\":\n if (update.customPresenceEvent.userId === localUserId) {\n return;\n }\n break;\n default:\n update;\n break;\n }\n }\n this.logger.debug(\"Received presence update\", {\n docId: documentId,\n updateType: update.type\n });\n callback(update);\n }).then(subscriptionId => {\n session.presenceSubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to presence updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to presence updates\", {\n cause: e\n });\n });\n }\n publishCustomPresence(documentId, eventType, eventData) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresencePublishChannelId(documentId);\n const messageData = {\n eventData,\n eventType\n };\n // TODO: maybe the session should hold userId\n // Though would need better reconnection handling to ensure userId doesn't change.\n const userId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (userId == null) {\n throw new Error(\"Could not get current userId\");\n }\n return this.eventService.publish(channelId, {\n custom: {\n clientId: session.clientId,\n eventData: messageData,\n // FIXME: why do we have to send this, we are authenticated\n userId\n },\n type: \"custom\"\n }).catch(error => {\n this.logger.error(\"Failed to publish custom presence\", error, {\n docId: documentId\n });\n throw error;\n });\n }\n stopDocumentSync(session) {\n const sessionId = this.getSessionId(session.documentId);\n const internalSession = this.sessions.get(sessionId);\n if (internalSession == null) {\n this.logger.warn(\"Attempted to stop sync for unknown session\", {\n documentId: session.documentId,\n clientId: session.clientId\n });\n return;\n }\n if (internalSession.localYDocUpdateHandler != null) {\n internalSession.yDoc.off(\"update\", internalSession.localYDocUpdateHandler);\n internalSession.localYDocUpdateHandler = undefined;\n }\n if (internalSession.activitySubscriptionId) {\n this.eventService.unsubscribe(internalSession.activitySubscriptionId);\n }\n if (internalSession.presenceSubscriptionId) {\n this.eventService.unsubscribe(internalSession.presenceSubscriptionId);\n }\n if (internalSession.documentSubscriptionId) {\n this.eventService.unsubscribe(internalSession.documentSubscriptionId);\n this.sessions.delete(sessionId);\n }\n }\n handleDocumentUpdateMessage(session, message, onStatusChange) {\n switch (message.type) {\n case \"error\":\n const {\n args,\n code,\n errorInstanceId\n } = message;\n this.logger.error(\"Received document update error message\", {\n docId: session.documentId,\n code,\n errorInstanceId,\n args\n });\n onStatusChange({\n error: new Error(`Subscription in error state [${errorInstanceId}]`, {\n cause: message\n }),\n load: DocumentLoadStatus.ERROR\n });\n break;\n case \"update\":\n const {\n baseRevisionId,\n clientId,\n revisionId,\n update\n } = message;\n const data = update != null && typeof update.data === \"string\" ? Base64.toUint8Array(update.data) : undefined;\n const messageDetail = {\n baseRevisionId,\n clientId,\n revisionId,\n updateSize: data?.byteLength ?? 0\n };\n\n // FIXME: the typescript generators for api types come out as string, hard to be clear that they are numbers.\n if (session.lastRevisionId != null && Number(baseRevisionId) !== session.lastRevisionId) {\n this.logger.error(\"Got unexpected update for baseRevisionId\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n return;\n }\n this.logger.debug(\"Applying remote Y.js update\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n session.lastRevisionId = Number(revisionId);\n if (data != null) {\n y.applyUpdate(session.yDoc, data, UPDATE_ORIGIN_REMOTE);\n }\n onStatusChange({\n load: DocumentLoadStatus.LOADED\n });\n break;\n default:\n message;\n const {\n type\n } = message;\n justOnce(`unknown-collab-update-type:${type}`, () => {\n this.logger.warn(\"Received unknown DocumentUpdateMessage type. This is only warned the first occurrence.\", {\n docId: session.documentId,\n updateType: type\n });\n });\n break;\n }\n }\n getSessionId(documentId) {\n return documentId;\n }\n}\nexport function createFoundryEventService(app, cometd) {\n return new FoundryEventService(app, cometd);\n}\nfunction isEditDescription(obj) {\n return obj != null && typeof obj === \"object\" && \"data\" in obj && \"model\" in obj && typeof obj.model === \"object\" && obj.model != null && Metadata in obj.model;\n}\nfunction createDocumentEditDescription(editDescription) {\n return {\n eventData: {\n data: editDescription.data,\n version: 1\n },\n eventType: getMetadata(editDescription.model).name\n };\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cometd/EventServiceCometD.ts","../../src/FoundryEventService.ts"],"names":["getAuthModule"],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { AckExtension, CometD } from \"cometd\";\n// side-effect shenanigans imports the class impl to cometd module\nimport \"cometd/AckExtension.js\";\nconst BEARER_TOKEN_FIELD = \"bearer-token\";\nconst EXTENSION_ACK = \"AckExtension\";\nconst EXTENSION_HANDSHAKE_TOKEN = \"handshakeToken\";\nconst META_CHANNEL_HANDSHAKE = \"/meta/handshake\";\nexport class EventServiceCometD {\n logger;\n initializePromise;\n subscriptionById = new Map();\n tokenExtension = new TokenExtension();\n nextSubscriptionHandle = 0;\n constructor(app, cometd = new CometD()) {\n this.app = app;\n this.cometd = cometd;\n this.logger = app.config.logger.child({}, {\n msgPrefix: \"EventServiceCometD\"\n });\n this.configureCometd();\n this.cometd.registerExtension(EXTENSION_ACK, new AckExtension());\n this.cometd.registerExtension(EXTENSION_HANDSHAKE_TOKEN, this.tokenExtension);\n\n // TODO: Support binary messages\n // this.cometd.registerExtension(BINARY_EXTENSION_NAME, new BinaryExtension());\n\n // Any time the token changes, update the extension so reconnection requests use the new token.\n // This will also be called on initial token set when the auth module is initialized.\n getAuthModule(app).onTokenChange(token => {\n this.tokenExtension.setToken(token);\n });\n }\n initialize() {\n if (this.initializePromise != null) {\n return this.initializePromise;\n }\n this.initializePromise = new Promise(resolve => {\n this.cometd.addListener(META_CHANNEL_HANDSHAKE, ({\n clientId,\n connectionType,\n error,\n successful\n }) => {\n if (successful) {\n this.logger.info(\"CometD handshake successful\", {\n clientId,\n connectionType\n });\n resolve();\n this.cometd.batch(() => {\n this.subscriptionById.forEach((subscription, subscriptionId) => {\n this.logger.debug(\"Resubscribing to channel\", {\n channel: subscription.eventChannel,\n subscriptionId\n });\n const subscribeProps = subscription.getSubscriptionRequest?.();\n subscription.handle = this.cometd.resubscribe(subscription.handle, {\n ext: subscribeProps\n });\n });\n });\n } else {\n this.logger.warn(\"CometD handshake failed\", {\n clientId,\n error\n });\n }\n });\n const authModule = getAuthModule(this.app);\n void authModule.getToken().then(token => {\n this.logger.info(\"Initializing CometD with token\");\n this.tokenExtension.setToken(token);\n this.cometd.handshake();\n });\n });\n return this.initializePromise;\n }\n async subscribe(channel, onMessage, getSubscriptionRequest) {\n await this.initialize();\n const subscriptionId = (this.nextSubscriptionHandle++).toString(10);\n return new Promise((resolve, reject) => {\n const messageHandler = receivedData => {\n if (!this.subscriptionById.has(subscriptionId)) {\n this.logger.info(\"Dropping message for unsubscribing channel\", {\n channel,\n subscriptionId\n });\n return;\n }\n this.logger.debug(\"Received message on channel\", {\n channel,\n subscriptionId,\n hasData: receivedData.data != null\n });\n onMessage(receivedData.data);\n };\n const subscribeCallback = message => {\n if (message.successful) {\n this.logger.debug(\"Successfully subscribed to channel\", {\n channel,\n subscriptionId\n });\n resolve(subscriptionId);\n } else {\n this.subscriptionById.delete(subscriptionId);\n // TODO: Is failure really expected? It's not on the type...\n const maybeFailureReason = \"failure\" in message && typeof message.failure === \"object\" && message.failure && \"reason\" in message.failure && typeof message.failure.reason === \"string\" ? message.failure.reason : undefined;\n this.logger.error(\"Failed to subscribe to channel \", {\n channel,\n error: message.error,\n maybeFailureReason\n });\n const errorMessage = message.error ?? (maybeFailureReason != null ? `(no error message provided by server, a guess: ${maybeFailureReason})` : \"(no error message provided by server)\");\n reject(new Error(`Failed to subscribe to channel ${channel}: ${errorMessage}`));\n }\n };\n const ext = getSubscriptionRequest?.();\n const subscriptionHandle = ext != null ? this.cometd.subscribe(channel, messageHandler, {\n ext\n }, subscribeCallback) : this.cometd.subscribe(channel, messageHandler, subscribeCallback);\n this.subscriptionById.set(subscriptionId, {\n handle: subscriptionHandle,\n getSubscriptionRequest,\n eventChannel: channel\n });\n });\n }\n unsubscribe(subscriptionId) {\n const subscription = this.subscriptionById.get(subscriptionId);\n if (subscription == null) {\n this.logger.warn(\"Attempted to unsubscribe from unknown subscriptionId\", {\n subscriptionId\n });\n return;\n }\n const {\n handle,\n eventChannel\n } = subscription;\n this.subscriptionById.delete(subscriptionId);\n this.cometd.unsubscribe(handle, message => {\n if (!message.successful) {\n this.logger.warn(\"Server unsubscribe confirmation failed\", {\n eventChannel,\n subscriptionId,\n error: message.error\n });\n }\n });\n }\n async publish(channel, content) {\n await this.initialize();\n return new Promise((resolve, reject) => {\n this.cometd.publish(channel, content, message => {\n if (message.successful) {\n this.logger.debug(\"Successfully published message\", channel, {\n content\n });\n resolve();\n } else {\n const error = new Error(`Failed to publish to ${channel}`, {\n cause: message.error\n });\n this.logger.error(\"Failed to publish\", {\n channel,\n error\n });\n reject(error);\n }\n });\n });\n }\n setLogLevel(logLevel) {\n this.configureCometd(logLevel);\n }\n configureCometd(logLevel) {\n const url = getCometDWebsocketUrl(this.app.config);\n this.logger.info(\"Configuring cometD \", {\n url\n });\n this.cometd.configure({\n url,\n // NOTE : Allow higher latency on busy networks to avoid retry loops when servers or networks fall behind.\n maxNetworkDelay: 30_000,\n logLevel,\n autoBatch: true\n });\n }\n}\nfunction getCometDWebsocketUrl(appConfig) {\n const httpUrl = new URL(`${appConfig.remote.packWsPath}/cometd`, appConfig.remote.baseUrl);\n httpUrl.protocol.replace(/https?/, \"ws\");\n // TODO: likely need a specific port for ingest - all of this should be in in appConfig\n return httpUrl.href;\n}\nclass TokenExtension {\n currentToken;\n setToken(token) {\n this.currentToken = token;\n }\n outgoing = message => {\n // Always use the latest token when doing a handshake (handles reconnects)\n if (message.channel === META_CHANNEL_HANDSHAKE) {\n if (this.currentToken) {\n message.ext ??= {};\n message.ext[BEARER_TOKEN_FIELD] = this.currentToken;\n }\n }\n return message;\n };\n}","/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getAuthModule } from \"@palantir/pack.auth\";\nimport { generateId, justOnce } from \"@palantir/pack.core\";\nimport { getMetadata, Metadata } from \"@palantir/pack.document-schema.model-types\";\nimport { DocumentLoadStatus } from \"@palantir/pack.state.core\";\nimport { Base64 } from \"js-base64\";\nimport * as y from \"yjs\";\nimport { EventServiceCometD } from \"./cometd/EventServiceCometD.js\";\n\n// TODO: replace with @osdk/foundry.pack types when they land.\n\n// TODO: presence api should have an eventType so we don't need extra wrapper here.\n\nconst UPDATE_ORIGIN_REMOTE = \"remote\";\nconst getDocumentUpdatesChannelId = documentId => `/document/${documentId}/updates`;\nconst getDocumentPublishChannelId = documentId => `/document/${documentId}/publish`;\nconst getDocumentActivityChannelId = documentId => `/document/${documentId}/activity`;\nconst getDocumentPresenceChannelId = documentId => `/document/${documentId}/presence`;\nconst getDocumentPresencePublishChannelId = documentId => `/document/${documentId}/presence-publish`;\n/**\n * This manages event subscriptions and publishing of document related events via\n * our PACK Foundry backend's cometd service.\n */\nexport class FoundryEventService {\n eventService;\n logger;\n sessions = new Map();\n constructor(app, cometd) {\n this.app = app;\n this.eventService = new EventServiceCometD(app, cometd);\n this.logger = app.config.logger.child({}, {\n level: \"debug\",\n msgPrefix: \"FoundryEventService\"\n });\n }\n getOrCreateSession(documentId, yDoc) {\n const sessionId = this.getSessionId(documentId);\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = {\n activitySubscriptionId: undefined,\n clientId: crypto.randomUUID(),\n documentId,\n documentSubscriptionId: undefined,\n lastRevisionId: undefined,\n localYDocUpdateHandler: undefined,\n presenceSubscriptionId: undefined,\n yDoc\n };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n startDocumentSync(documentId, yDoc, onStatusChange) {\n const session = this.getOrCreateSession(documentId, yDoc);\n if (session.documentSubscriptionId != null) {\n throw new Error(`Document data sync already active for document ${documentId}`);\n }\n const localYDocUpdateHandler = (update, origin) => {\n if (origin === UPDATE_ORIGIN_REMOTE) {\n return;\n }\n const lastRevisionId = session.lastRevisionId;\n if (lastRevisionId == null) {\n this.logger.error(\"Cannot publish document update before initial load is complete. The local state will remain inconsistent.\", {\n docId: documentId\n });\n return;\n }\n const publishChannelId = getDocumentPublishChannelId(documentId);\n const editId = generateId();\n const description = isEditDescription(origin) ? createDocumentEditDescription(origin) : undefined;\n void this.eventService.publish(publishChannelId, {\n clientId: session.clientId,\n description,\n editId,\n yjsUpdate: {\n data: Base64.fromUint8Array(update)\n }\n }).catch(error => {\n this.logger.error(\"Failed to publish document update\", error, {\n docId: documentId\n });\n });\n };\n session.localYDocUpdateHandler = localYDocUpdateHandler;\n yDoc.on(\"update\", localYDocUpdateHandler);\n onStatusChange({\n load: DocumentLoadStatus.LOADING\n });\n const channelId = getDocumentUpdatesChannelId(documentId);\n this.eventService.subscribe(channelId, message => {\n if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {\n return;\n }\n this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);\n }, () => ({\n clientId: session.clientId,\n lastRevisionId: session.lastRevisionId?.toString()\n })).then(subscriptionId => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n session.documentSubscriptionId = subscriptionId;\n } else {\n this.eventService.unsubscribe(subscriptionId);\n this.sessions.delete(this.getSessionId(documentId));\n }\n }).catch(e => {\n if (session.localYDocUpdateHandler === localYDocUpdateHandler) {\n const error = new Error(\"Failed to setup document data subscription\", {\n cause: e\n });\n onStatusChange({\n error,\n load: DocumentLoadStatus.ERROR\n });\n } else {\n this.logger.warn(\"Document data subscription error after subscription was closed\", {\n docId: documentId,\n error: e\n });\n }\n });\n return {\n clientId: session.clientId,\n documentId: session.documentId\n };\n }\n subscribeToActivityUpdates(documentId, callback) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentActivityChannelId(documentId);\n return this.eventService.subscribe(channelId, event => {\n this.logger.debug(\"Received activity event\", {\n docId: documentId,\n event\n });\n callback(event);\n }).then(subscriptionId => {\n session.activitySubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to activity updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to activity updates\", {\n cause: e\n });\n });\n }\n subscribeToPresenceUpdates(documentId, callback, options = {}) {\n const {\n ignoreSelfUpdates = true\n } = options;\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresenceChannelId(documentId);\n return this.eventService.subscribe(channelId, update => {\n // TODO: api should provide clientId so we filter on our presence messages only,\n // but allow apps to decide what they do with same-user-different-client messages ie\n // from different tabs or devices.\n const localUserId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (ignoreSelfUpdates && localUserId != null) {\n switch (update.type) {\n case \"presenceChangeEvent\":\n if (update.presenceChangeEvent.userId === localUserId) {\n return;\n }\n break;\n case \"customPresenceEvent\":\n if (update.customPresenceEvent.userId === localUserId) {\n return;\n }\n break;\n default:\n update;\n break;\n }\n }\n this.logger.debug(\"Received presence update\", {\n docId: documentId,\n updateType: update.type\n });\n callback(update);\n }).then(subscriptionId => {\n session.presenceSubscriptionId = subscriptionId;\n return subscriptionId;\n }).catch(e => {\n this.logger.error(\"Failed to subscribe to presence updates\", e, {\n docId: documentId\n });\n throw new Error(\"Failed to subscribe to presence updates\", {\n cause: e\n });\n });\n }\n publishCustomPresence(documentId, eventType, eventData) {\n const session = this.getOrCreateSession(documentId);\n const channelId = getDocumentPresencePublishChannelId(documentId);\n const messageData = {\n eventData,\n eventType\n };\n // TODO: maybe the session should hold userId\n // Though would need better reconnection handling to ensure userId doesn't change.\n const userId = getAuthModule(this.app).getCurrentUser(true)?.userId;\n if (userId == null) {\n throw new Error(\"Could not get current userId\");\n }\n return this.eventService.publish(channelId, {\n custom: {\n clientId: session.clientId,\n eventData: messageData,\n // FIXME: why do we have to send this, we are authenticated\n userId\n },\n type: \"custom\"\n }).catch(error => {\n this.logger.error(\"Failed to publish custom presence\", error, {\n docId: documentId\n });\n throw error;\n });\n }\n stopDocumentSync(session) {\n const sessionId = this.getSessionId(session.documentId);\n const internalSession = this.sessions.get(sessionId);\n if (internalSession == null) {\n this.logger.warn(\"Attempted to stop sync for unknown session\", {\n documentId: session.documentId,\n clientId: session.clientId\n });\n return;\n }\n if (internalSession.localYDocUpdateHandler != null) {\n internalSession.yDoc?.off(\"update\", internalSession.localYDocUpdateHandler);\n internalSession.localYDocUpdateHandler = undefined;\n }\n if (internalSession.activitySubscriptionId) {\n this.eventService.unsubscribe(internalSession.activitySubscriptionId);\n }\n if (internalSession.presenceSubscriptionId) {\n this.eventService.unsubscribe(internalSession.presenceSubscriptionId);\n }\n if (internalSession.documentSubscriptionId) {\n this.eventService.unsubscribe(internalSession.documentSubscriptionId);\n this.sessions.delete(sessionId);\n }\n }\n handleDocumentUpdateMessage(session, message, yDoc, onStatusChange) {\n switch (message.type) {\n case \"error\":\n const {\n args,\n code,\n errorInstanceId\n } = message;\n this.logger.error(\"Received document update error message\", {\n docId: session.documentId,\n code,\n errorInstanceId,\n args\n });\n onStatusChange({\n error: new Error(`Subscription in error state [${errorInstanceId}]`, {\n cause: message\n }),\n load: DocumentLoadStatus.ERROR\n });\n break;\n case \"update\":\n const {\n baseRevisionId,\n clientId,\n revisionId,\n update\n } = message;\n const data = update != null && typeof update.data === \"string\" ? Base64.toUint8Array(update.data) : undefined;\n const messageDetail = {\n baseRevisionId,\n clientId,\n revisionId,\n updateSize: data?.byteLength ?? 0\n };\n\n // FIXME: the typescript generators for api types come out as string, hard to be clear that they are numbers.\n if (session.lastRevisionId != null && Number(baseRevisionId) !== session.lastRevisionId) {\n this.logger.error(\"Got unexpected update for baseRevisionId\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n return;\n }\n this.logger.debug(\"Applying remote Y.js update\", {\n docId: session.documentId,\n lastRevisionId: session.lastRevisionId,\n message: messageDetail\n });\n session.lastRevisionId = Number(revisionId);\n if (data != null) {\n y.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);\n }\n onStatusChange({\n load: DocumentLoadStatus.LOADED\n });\n break;\n default:\n message;\n const {\n type\n } = message;\n justOnce(`unknown-collab-update-type:${type}`, () => {\n this.logger.warn(\"Received unknown DocumentUpdateMessage type. This is only warned the first occurrence.\", {\n docId: session.documentId,\n updateType: type\n });\n });\n break;\n }\n }\n getSessionId(documentId) {\n return documentId;\n }\n}\nexport function createFoundryEventService(app, cometd) {\n return new FoundryEventService(app, cometd);\n}\nfunction isEditDescription(obj) {\n return obj != null && typeof obj === \"object\" && \"data\" in obj && \"model\" in obj && typeof obj.model === \"object\" && obj.model != null && Metadata in obj.model;\n}\nfunction createDocumentEditDescription(editDescription) {\n return {\n eventData: {\n data: editDescription.data,\n version: 1\n },\n eventType: getMetadata(editDescription.model).name\n };\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAiBA,cACE,6BACA,UAKA,cACK;AAEP,cAAoC,uBAAuB;AAC3D,cACO,kBAIA;AACP,cAAkC,0BAA0B;AAC5D,cAAc,cAAc;AAE5B,YAAY,OAAO;AAEnB,cAEE,sBAGK;AAGP,iBAAiB,4BAA4B;UAClC;;AAGX,iBAAiB,6BAA6B;UACnC,MAAM;UACN,QAAQ;EACf,QAAQ;EACR,UAAU;EACV;;;AAIJ,YAAY,yBAAyB;AAErC,iBAAiB,4BAA4B;UAClC,MAAM;UACN,qBAAqB;WACnB,QAAQ;WACR,QAAQ,YAAY;;;AAIjC,iBAAiB,oBAAoB;UAC1B,MAAM;UACN,qBAAqB;WACnB,QAAQ;WACR,UAAU;WACV;;;AAIb,YAAY,8BAA8B,8BAA8B;AAmCxE,iBAAiB,YAAY;UAClB;UACA,YAAY;;;;;;AAgBvB,OAAO,cAAM,oBAAoB;CAM7B;CALF,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CAEjB,YACE,AAAiBA,KAAK,iBACtB,SAAS;CASX,QAAQ;CAqBR,kBACE,YAAY,YACZ,MAAM,EAAE,KACR,iBAAiB,QAAQ,QAAQ,+BAChC;CA4FH,2BACE,YAAY,YACZ,WAAW,OAAO,uCACjB,QAAQ;CAyBX,2BACE,YAAY,YACZ,WAAW,QAAQ,sCACnB,UAAS,8BACR,QAAQ;CAgDX,sBACE,YAAY,YACZ,mBACA,qBACC;CA+BH,iBAAiB,SAAS;CA+B1B,QAAQ;
|
|
1
|
+
{"mappings":"AAiBA,cACE,6BACA,UAKA,cACK;AAEP,cAAoC,uBAAuB;AAC3D,cACO,kBAIA;AACP,cAAkC,0BAA0B;AAC5D,cAAc,cAAc;AAE5B,YAAY,OAAO;AAEnB,cAEE,sBAGK;AAGP,iBAAiB,4BAA4B;UAClC;;AAGX,iBAAiB,6BAA6B;UACnC,MAAM;UACN,QAAQ;EACf,QAAQ;EACR,UAAU;EACV;;;AAIJ,YAAY,yBAAyB;AAErC,iBAAiB,4BAA4B;UAClC,MAAM;UACN,qBAAqB;WACnB,QAAQ;WACR,QAAQ,YAAY;;;AAIjC,iBAAiB,oBAAoB;UAC1B,MAAM;UACN,qBAAqB;WACnB,QAAQ;WACR,UAAU;WACV;;;AAIb,YAAY,8BAA8B,8BAA8B;AAmCxE,iBAAiB,YAAY;UAClB;UACA,YAAY;;;;;;AAgBvB,OAAO,cAAM,oBAAoB;CAM7B;CALF,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CAEjB,YACE,AAAiBA,KAAK,iBACtB,SAAS;CASX,QAAQ;CAqBR,kBACE,YAAY,YACZ,MAAM,EAAE,KACR,iBAAiB,QAAQ,QAAQ,+BAChC;CA4FH,2BACE,YAAY,YACZ,WAAW,OAAO,uCACjB,QAAQ;CAyBX,2BACE,YAAY,YACZ,WAAW,QAAQ,sCACnB,UAAS,8BACR,QAAQ;CAgDX,sBACE,YAAY,YACZ,mBACA,qBACC;CA+BH,iBAAiB,SAAS;CA+B1B,QAAQ;CA4ER,QAAQ;;AAKV,OAAO,iBAAS,0BACd,KAAK,iBACL,SAAS,SACR","names":["app: PackAppInternal"],"sources":["../../src/FoundryEventService.ts"],"version":3,"file":"FoundryEventService.d.ts"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@palantir/pack.state.foundry-event",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "PACK event service for real-time document synchronization",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"cometd": "^7.0.19",
|
|
34
34
|
"js-base64": "^3.7.8",
|
|
35
35
|
"yjs": "^13.6.27",
|
|
36
|
-
"@palantir/pack.
|
|
37
|
-
"@palantir/pack.
|
|
38
|
-
"@palantir/pack.document-schema.model-types": "0.
|
|
39
|
-
"@palantir/pack.
|
|
36
|
+
"@palantir/pack.state.core": "0.2.0",
|
|
37
|
+
"@palantir/pack.auth": "0.1.0",
|
|
38
|
+
"@palantir/pack.document-schema.model-types": "0.2.0",
|
|
39
|
+
"@palantir/pack.core": "0.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^20.19.17",
|
|
@@ -123,7 +123,7 @@ interface SyncSessionInternal extends SyncSession {
|
|
|
123
123
|
lastRevisionId?: number;
|
|
124
124
|
localYDocUpdateHandler?: (update: Uint8Array, origin: unknown) => void;
|
|
125
125
|
presenceSubscriptionId?: SubscriptionId;
|
|
126
|
-
yDoc
|
|
126
|
+
yDoc?: y.Doc;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
@@ -159,7 +159,7 @@ export class FoundryEventService {
|
|
|
159
159
|
lastRevisionId: undefined,
|
|
160
160
|
localYDocUpdateHandler: undefined,
|
|
161
161
|
presenceSubscriptionId: undefined,
|
|
162
|
-
yDoc
|
|
162
|
+
yDoc,
|
|
163
163
|
};
|
|
164
164
|
this.sessions.set(sessionId, session);
|
|
165
165
|
}
|
|
@@ -229,7 +229,7 @@ export class FoundryEventService {
|
|
|
229
229
|
if (session.localYDocUpdateHandler !== localYDocUpdateHandler) {
|
|
230
230
|
return;
|
|
231
231
|
}
|
|
232
|
-
this.handleDocumentUpdateMessage(session, message, onStatusChange);
|
|
232
|
+
this.handleDocumentUpdateMessage(session, message, yDoc, onStatusChange);
|
|
233
233
|
},
|
|
234
234
|
() => ({
|
|
235
235
|
clientId: session.clientId,
|
|
@@ -391,7 +391,7 @@ export class FoundryEventService {
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
if (internalSession.localYDocUpdateHandler != null) {
|
|
394
|
-
internalSession.yDoc
|
|
394
|
+
internalSession.yDoc?.off("update", internalSession.localYDocUpdateHandler);
|
|
395
395
|
internalSession.localYDocUpdateHandler = undefined;
|
|
396
396
|
}
|
|
397
397
|
|
|
@@ -412,6 +412,7 @@ export class FoundryEventService {
|
|
|
412
412
|
private handleDocumentUpdateMessage(
|
|
413
413
|
session: SyncSessionInternal,
|
|
414
414
|
message: DocumentUpdateMessage,
|
|
415
|
+
yDoc: y.Doc,
|
|
415
416
|
onStatusChange: (status: Partial<DocumentSyncStatus>) => void,
|
|
416
417
|
): void {
|
|
417
418
|
switch (message.type) {
|
|
@@ -460,7 +461,7 @@ export class FoundryEventService {
|
|
|
460
461
|
|
|
461
462
|
session.lastRevisionId = Number(revisionId);
|
|
462
463
|
if (data != null) {
|
|
463
|
-
y.applyUpdate(
|
|
464
|
+
y.applyUpdate(yDoc, data, UPDATE_ORIGIN_REMOTE);
|
|
464
465
|
}
|
|
465
466
|
|
|
466
467
|
onStatusChange({
|