@hydranium/protocol 1.0.0-next.123 → 1.0.0-next.127
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/lib/client/data-connection.d.ts +35 -4
- package/lib/client/data-connection.d.ts.map +1 -1
- package/lib/client/data-connection.js +67 -5
- package/lib/client/data-connection.js.map +1 -1
- package/lib/client/data-events.d.ts +5 -1
- package/lib/client/data-events.d.ts.map +1 -1
- package/lib/client/data-events.js +7 -0
- package/lib/client/data-events.js.map +1 -1
- package/lib/client/data-session.d.ts +76 -8
- package/lib/client/data-session.d.ts.map +1 -1
- package/lib/client/data-session.js +108 -19
- package/lib/client/data-session.js.map +1 -1
- package/lib/client/index.d.ts +3 -1
- package/lib/client/index.d.ts.map +1 -1
- package/lib/client/index.js +3 -1
- package/lib/client/index.js.map +1 -1
- package/lib/client/message-relay.d.ts +1 -1
- package/lib/client/message-relay.js +1 -1
- package/lib/client/post-message-transport.d.ts +64 -3
- package/lib/client/post-message-transport.d.ts.map +1 -1
- package/lib/client/post-message-transport.js +175 -1
- package/lib/client/post-message-transport.js.map +1 -1
- package/lib/client/rpc-connection.d.ts +6 -0
- package/lib/client/rpc-connection.d.ts.map +1 -1
- package/lib/client/rpc-connection.js +9 -1
- package/lib/client/rpc-connection.js.map +1 -1
- package/lib/clock.d.ts +38 -0
- package/lib/clock.d.ts.map +1 -1
- package/lib/clock.js +36 -1
- package/lib/clock.js.map +1 -1
- package/lib/data/data-protocol-methods.d.ts +2 -2
- package/lib/data/data-protocol-methods.d.ts.map +1 -1
- package/lib/data/data-protocol-methods.js +1 -0
- package/lib/data/data-protocol-methods.js.map +1 -1
- package/lib/data/data-server-protocol.d.ts +11 -1
- package/lib/data/data-server-protocol.d.ts.map +1 -1
- package/lib/data/events.d.ts +14 -0
- package/lib/data/events.d.ts.map +1 -1
- package/lib/errors.d.ts +20 -9
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +18 -9
- package/lib/errors.js.map +1 -1
- package/lib/glsp-save-model-actions.d.ts +50 -0
- package/lib/glsp-save-model-actions.d.ts.map +1 -0
- package/lib/glsp-save-model-actions.js +28 -0
- package/lib/glsp-save-model-actions.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/messages/index.d.ts +1 -1
- package/lib/messages/index.d.ts.map +1 -1
- package/lib/messages/index.js +2 -1
- package/lib/messages/index.js.map +1 -1
- package/lib/testing/data-doubles.d.ts +3 -1
- package/lib/testing/data-doubles.d.ts.map +1 -1
- package/lib/testing/data-doubles.js +6 -1
- package/lib/testing/data-doubles.js.map +1 -1
- package/lib/testing/fake-clock.d.ts +9 -1
- package/lib/testing/fake-clock.d.ts.map +1 -1
- package/lib/testing/fake-clock.js +54 -45
- package/lib/testing/fake-clock.js.map +1 -1
- package/lib/testing/node/index.d.ts +1 -0
- package/lib/testing/node/index.d.ts.map +1 -1
- package/lib/testing/node/index.js +2 -2
- package/lib/testing/node/index.js.map +1 -1
- package/lib/testing/node/message-port-pair.d.ts +25 -0
- package/lib/testing/node/message-port-pair.d.ts.map +1 -0
- package/lib/testing/node/message-port-pair.js +26 -0
- package/lib/testing/node/message-port-pair.js.map +1 -0
- package/lib/transfer-document.d.ts +8 -0
- package/lib/transfer-document.d.ts.map +1 -1
- package/lib/transfer-document.js.map +1 -1
- package/package.json +1 -1
- package/src/client/data-connection.ts +72 -6
- package/src/client/data-events.ts +9 -0
- package/src/client/data-session.ts +125 -21
- package/src/client/index.ts +3 -1
- package/src/client/message-relay.ts +1 -1
- package/src/client/post-message-transport.ts +219 -4
- package/src/client/rpc-connection.ts +10 -1
- package/src/clock.ts +56 -0
- package/src/data/data-protocol-methods.ts +1 -0
- package/src/data/data-server-protocol.ts +12 -0
- package/src/data/events.ts +16 -0
- package/src/errors.ts +24 -9
- package/src/glsp-save-model-actions.ts +59 -0
- package/src/index.ts +1 -0
- package/src/messages/index.ts +1 -1
- package/src/testing/data-doubles.ts +10 -1
- package/src/testing/fake-clock.ts +62 -47
- package/src/testing/node/index.ts +2 -2
- package/src/testing/node/message-port-pair.ts +40 -0
- package/src/transfer-document.ts +8 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;;AAElF;;;;;;;;;;;;;;GAcG;AAEH,+CAA6B;AAE7B,oCAA+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;;AAElF;;;;;;;;;;;;;;GAcG;AAEH,+CAA6B;AAE7B,oCAA+D;AAAtD,wGAAA,cAAc,OAAA;AAAE,4GAAA,kBAAkB,OAAA;AAC3C,2DAA6F;AAApF,4HAAA,0BAA0B,OAAA;AAAE,uHAAA,qBAAqB,OAAA;AAC1D,uDAAgG;AAAvF,2HAAA,2BAA2B,OAAA;AAAE,yHAAA,yBAAyB,OAAA;AAC/D,yDAKiC;AAJ9B,oHAAA,mBAAmB,OAAA;AACnB,4HAAA,2BAA2B,OAAA;AAC3B,4HAAA,2BAA2B,OAAA;AAC3B,6HAAA,4BAA4B,OAAA"}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
import { type MessageConnection } from 'vscode-jsonrpc';
|
|
33
33
|
import type { DataPort } from '../client/data-port';
|
|
34
34
|
import type { DataClientProtocol } from '../data/data-server-protocol';
|
|
35
|
-
import type { ProjectsChangedEvent, TransferDocumentDeletedEvent, TransferDocumentSavedEvent, TransferDocumentsBuiltEvent, TransferDocumentUpdatedEvent } from '../data/events';
|
|
35
|
+
import type { ProjectsChangedEvent, TransferDocumentDeletedEvent, TransferDocumentDirtyChangedEvent, TransferDocumentSavedEvent, TransferDocumentsBuiltEvent, TransferDocumentUpdatedEvent } from '../data/events';
|
|
36
36
|
import type { ResolvedMessage } from '../messages/primitives';
|
|
37
37
|
import type { Project } from '../project';
|
|
38
38
|
import type { TransferDiagnostic } from '../transfer-diagnostic';
|
|
@@ -96,6 +96,8 @@ export interface CapturingDataClient<TTransfer extends TransferElement, TDiagnos
|
|
|
96
96
|
readonly updates: TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>[];
|
|
97
97
|
/** Every `onDocumentSaved` event, in arrival order. */
|
|
98
98
|
readonly saves: TransferDocumentSavedEvent<TTransfer, TDiagnostic>[];
|
|
99
|
+
/** Every `onDocumentDirtyChanged` event, in arrival order. */
|
|
100
|
+
readonly dirtyChanges: TransferDocumentDirtyChangedEvent[];
|
|
99
101
|
/** Every `onDocumentDeleted` event, in arrival order. */
|
|
100
102
|
readonly deletions: TransferDocumentDeletedEvent[];
|
|
101
103
|
/** Every `onDocumentsBuilt` event, in arrival order. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-doubles.d.ts","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EACT,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IACjC;;;;;;;;OAQG;IACH,OAAO,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC5D;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;KAAE,EAAE,CAAC;IAC7F;;;;OAIG;IACH,WAAW,IAAI,IAAI,CAAC;IACpB,4FAA4F;IAC5F,OAAO,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAuB3E;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB,CACjC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,QAAQ,SAAS,OAAO,GAAG,OAAO;IAElC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IACtE,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;IACzE,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;IACrE,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,4BAA4B,EAAE,CAAC;IACnD,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAC/C,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACpC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,QAAQ,SAAS,OAAO,GAAG,OAAO,EACnC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAM,GAAG,mBAAmB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"data-doubles.d.ts","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EACT,oBAAoB,EACpB,4BAA4B,EAC5B,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IACjC;;;;;;;;OAQG;IACH,OAAO,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC5D;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;KAAE,EAAE,CAAC;IAC7F;;;;OAIG;IACH,WAAW,IAAI,IAAI,CAAC;IACpB,4FAA4F;IAC5F,OAAO,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAuB3E;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB,CACjC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,QAAQ,SAAS,OAAO,GAAG,OAAO;IAElC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IACtE,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;IACzE,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;IACrE,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,iCAAiC,EAAE,CAAC;IAC3D,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,4BAA4B,EAAE,CAAC;IACnD,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAC/C,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACpC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,QAAQ,SAAS,OAAO,GAAG,OAAO,EACnC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAM,GAAG,mBAAmB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAwCtI"}
|
|
@@ -81,6 +81,7 @@ function makeFakeDataPort(options) {
|
|
|
81
81
|
function makeCapturingDataClient(overrides = {}) {
|
|
82
82
|
const updates = [];
|
|
83
83
|
const saves = [];
|
|
84
|
+
const dirtyChanges = [];
|
|
84
85
|
const deletions = [];
|
|
85
86
|
const builds = [];
|
|
86
87
|
const projectsChanges = [];
|
|
@@ -93,6 +94,10 @@ function makeCapturingDataClient(overrides = {}) {
|
|
|
93
94
|
(event => {
|
|
94
95
|
saves.push(event);
|
|
95
96
|
}),
|
|
97
|
+
onDocumentDirtyChanged: overrides.onDocumentDirtyChanged ??
|
|
98
|
+
(event => {
|
|
99
|
+
dirtyChanges.push(event);
|
|
100
|
+
}),
|
|
96
101
|
onDocumentDeleted: overrides.onDocumentDeleted ??
|
|
97
102
|
(event => {
|
|
98
103
|
deletions.push(event);
|
|
@@ -106,6 +111,6 @@ function makeCapturingDataClient(overrides = {}) {
|
|
|
106
111
|
projectsChanges.push(event);
|
|
107
112
|
})
|
|
108
113
|
};
|
|
109
|
-
return { client, updates, saves, deletions, builds, projectsChanges };
|
|
114
|
+
return { client, updates, saves, dirtyChanges, deletions, builds, projectsChanges };
|
|
110
115
|
}
|
|
111
116
|
//# sourceMappingURL=data-doubles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-doubles.js","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;
|
|
1
|
+
{"version":3,"file":"data-doubles.js","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AA2FlF,4CAuBC;AAqCD,0DA4CC;AAjMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,mDAAiE;AA0DjE;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,OAA4B;IAC1D,MAAM,WAAW,GAAwB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAmD,EAAE,CAAC;IACpE,MAAM,cAAc,GAAG,IAAI,wBAAO,EAAQ,CAAC;IAC3C,OAAO;QACJ,WAAW;QACX,QAAQ;QACR,SAAS,EAAE,cAAc,CAAC,KAAK;QAC/B,KAAK,CAAC,OAAO;YACV,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3C,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7B,OAAO,UAAU,CAAC;QACrB,CAAC;QACD,WAAW,CAAC,KAAc,EAAE,OAAwB;YACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,WAAW;YACR,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,OAAO;YACJ,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;KACH,CAAC;AACL,CAAC;AAwBD;;;;;;;;;;;;GAYG;AACH,SAAgB,uBAAuB,CAIrC,YAA2E,EAAE;IAC5E,MAAM,OAAO,GAA2D,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAyD,EAAE,CAAC;IACvE,MAAM,YAAY,GAAwC,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAmC,EAAE,CAAC;IACrD,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,MAAM,eAAe,GAAqC,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAyD;QAClE,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC,CAAC;QACL,eAAe,EACZ,SAAS,CAAC,eAAe;YACzB,CAAC,KAAK,CAAC,EAAE;gBACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC,CAAC;QACL,sBAAsB,EACnB,SAAS,CAAC,sBAAsB;YAChC,CAAC,KAAK,CAAC,EAAE;gBACN,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC,CAAC;QACL,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC,CAAC;QACL,gBAAgB,EACb,SAAS,CAAC,gBAAgB;YAC1B,CAAC,KAAK,CAAC,EAAE;gBACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,CAAC;QACL,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC,CAAC;KACP,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AACvF,CAAC"}
|
|
@@ -14,9 +14,13 @@ export interface FakeClock extends Clock {
|
|
|
14
14
|
* whose deadline falls within the window — in chronological order, each at
|
|
15
15
|
* its own deadline (so `now()` inside a callback reads the fire instant, not
|
|
16
16
|
* the advance target). Timers scheduled by a callback fire too if they fall
|
|
17
|
-
* within the same window.
|
|
17
|
+
* within the same window. A {@link Clock.raceTimer} over a promise that
|
|
18
|
+
* settles through a chain still pending loses to the timer, so let that
|
|
19
|
+
* chain settle before advancing.
|
|
18
20
|
*/
|
|
19
21
|
advance(ms: number): void;
|
|
22
|
+
/** How many {@link Clock.setTimer} timers have neither fired nor been disposed. */
|
|
23
|
+
pendingTimers(): number;
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
22
26
|
* In-process {@link Clock} double for deterministic time. The real
|
|
@@ -28,6 +32,10 @@ export interface FakeClock extends Clock {
|
|
|
28
32
|
*
|
|
29
33
|
* Server-free and DI-free — lives in `@hydranium/protocol/testing` so every
|
|
30
34
|
* head can bind it without pulling in a server package.
|
|
35
|
+
*
|
|
36
|
+
* The clock is a `SystemClock` with its time replaced, so its methods live on
|
|
37
|
+
* its prototype and a spread of it carries none of them. Replace one by
|
|
38
|
+
* assigning it onto the clock, or layer over the clock with `Object.create`.
|
|
31
39
|
*/
|
|
32
40
|
export declare function makeFakeClock(options?: {
|
|
33
41
|
now?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-clock.d.ts","sourceRoot":"","sources":["../../src/testing/fake-clock.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"fake-clock.d.ts","sourceRoot":"","sources":["../../src/testing/fake-clock.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,EAA+B,MAAM,UAAU,CAAC;AAGnE,2FAA2F;AAC3F,MAAM,WAAW,SAAU,SAAQ,KAAK;IACrC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mFAAmF;IACnF,aAAa,IAAI,MAAM,CAAC;CAC1B;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,SAAS,CAEvE"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
********************************************************************************/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.makeFakeClock = makeFakeClock;
|
|
12
|
+
const clock_1 = require("../clock");
|
|
12
13
|
const util_1 = require("../util");
|
|
13
14
|
/**
|
|
14
15
|
* In-process {@link Clock} double for deterministic time. The real
|
|
@@ -20,67 +21,75 @@ const util_1 = require("../util");
|
|
|
20
21
|
*
|
|
21
22
|
* Server-free and DI-free — lives in `@hydranium/protocol/testing` so every
|
|
22
23
|
* head can bind it without pulling in a server package.
|
|
24
|
+
*
|
|
25
|
+
* The clock is a `SystemClock` with its time replaced, so its methods live on
|
|
26
|
+
* its prototype and a spread of it carries none of them. Replace one by
|
|
27
|
+
* assigning it onto the clock, or layer over the clock with `Object.create`.
|
|
23
28
|
*/
|
|
24
29
|
function makeFakeClock(options = {}) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
return new VirtualClock(options.now ?? 0);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A `SystemClock` whose time, stopwatches and timers read one virtual axis, so
|
|
34
|
+
* the `measure` and `raceTimer` it inherits run on that axis too.
|
|
35
|
+
*/
|
|
36
|
+
class VirtualClock extends clock_1.SystemClock {
|
|
37
|
+
current;
|
|
38
|
+
timers = [];
|
|
39
|
+
constructor(current) {
|
|
40
|
+
super();
|
|
41
|
+
this.current = current;
|
|
42
|
+
}
|
|
43
|
+
now() {
|
|
44
|
+
return this.current;
|
|
45
|
+
}
|
|
46
|
+
setTimer(callback, ms) {
|
|
47
|
+
const timer = { at: this.current + ms, callback, disposed: false, fired: false };
|
|
48
|
+
this.timers.push(timer);
|
|
49
|
+
return util_1.Disposable.create(() => {
|
|
50
|
+
timer.disposed = true;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
stopwatch() {
|
|
54
|
+
const read = () => this.current;
|
|
55
|
+
const start = read();
|
|
56
|
+
let lastLap = start;
|
|
30
57
|
let stopped;
|
|
31
58
|
return {
|
|
32
59
|
get elapsedMs() {
|
|
33
|
-
return (stopped ??
|
|
60
|
+
return (stopped ?? read()) - start;
|
|
34
61
|
},
|
|
35
62
|
lap() {
|
|
36
|
-
const at = stopped ??
|
|
63
|
+
const at = stopped ?? read();
|
|
37
64
|
const split = at - lastLap;
|
|
38
65
|
lastLap = at;
|
|
39
66
|
return split;
|
|
40
67
|
},
|
|
41
68
|
stop() {
|
|
42
|
-
|
|
43
|
-
stopped = current;
|
|
44
|
-
}
|
|
69
|
+
stopped ??= read();
|
|
45
70
|
return stopped - start;
|
|
46
71
|
}
|
|
47
72
|
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (result instanceof Promise) {
|
|
63
|
-
return result.then(value => ({ result: value, elapsedMs: stopwatch.elapsedMs }));
|
|
64
|
-
}
|
|
65
|
-
return { result: result, elapsedMs: stopwatch.elapsedMs };
|
|
66
|
-
}),
|
|
67
|
-
advance(ms) {
|
|
68
|
-
const target = current + ms;
|
|
69
|
-
// Fire due timers one at a time, re-scanning after each so a callback
|
|
70
|
-
// that schedules a nearer timer still fires within this window.
|
|
71
|
-
for (;;) {
|
|
72
|
-
const next = timers
|
|
73
|
-
.filter(timer => !timer.disposed && !timer.fired && timer.at <= target)
|
|
74
|
-
.sort((left, right) => left.at - right.at)[0];
|
|
75
|
-
if (!next) {
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
current = next.at;
|
|
79
|
-
next.fired = true;
|
|
80
|
-
next.callback();
|
|
73
|
+
}
|
|
74
|
+
pendingTimers() {
|
|
75
|
+
return this.timers.filter(timer => !timer.disposed && !timer.fired).length;
|
|
76
|
+
}
|
|
77
|
+
advance(ms) {
|
|
78
|
+
const target = this.current + ms;
|
|
79
|
+
// Fire due timers one at a time, re-scanning after each so a callback
|
|
80
|
+
// that schedules a nearer timer still fires within this window.
|
|
81
|
+
for (;;) {
|
|
82
|
+
const next = this.timers
|
|
83
|
+
.filter(timer => !timer.disposed && !timer.fired && timer.at <= target)
|
|
84
|
+
.sort((left, right) => left.at - right.at)[0];
|
|
85
|
+
if (!next) {
|
|
86
|
+
break;
|
|
81
87
|
}
|
|
82
|
-
current =
|
|
88
|
+
this.current = next.at;
|
|
89
|
+
next.fired = true;
|
|
90
|
+
next.callback();
|
|
83
91
|
}
|
|
84
|
-
|
|
92
|
+
this.current = target;
|
|
93
|
+
}
|
|
85
94
|
}
|
|
86
95
|
//# sourceMappingURL=fake-clock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-clock.js","sourceRoot":"","sources":["../../src/testing/fake-clock.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;
|
|
1
|
+
{"version":3,"file":"fake-clock.js","sourceRoot":"","sources":["../../src/testing/fake-clock.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AA2ClF,sCAEC;AA3CD,oCAAmE;AACnE,kCAAqC;AAyBrC;;;;;;;;;;;;;;GAcG;AACH,SAAgB,aAAa,CAAC,UAA4B,EAAE;IACzD,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,YAAa,SAAQ,mBAAW;IAGb;IAFH,MAAM,GAAgB,EAAE,CAAC;IAE5C,YAAsB,OAAe;QAClC,KAAK,EAAE,CAAC;QADW,YAAO,GAAP,OAAO,CAAQ;IAErC,CAAC;IAEQ,GAAG;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACvB,CAAC;IAEQ,QAAQ,CAAC,QAAoB,EAAE,EAAU;QAC/C,MAAM,KAAK,GAAc,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,GAAG,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC5F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,iBAAU,CAAC,MAAM,CAAC,GAAG,EAAE;YAC3B,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC;IACN,CAAC;IAEQ,SAAS;QACf,MAAM,IAAI,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,EAAE,CAAC;QACrB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,OAA2B,CAAC;QAChC,OAAO;YACJ,IAAI,SAAS;gBACV,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC;YACtC,CAAC;YACD,GAAG;gBACA,MAAM,EAAE,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC;gBAC3B,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC;YAChB,CAAC;YACD,IAAI;gBACD,OAAO,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,OAAO,GAAG,KAAK,CAAC;YAC1B,CAAC;SACH,CAAC;IACL,CAAC;IAED,aAAa;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;IAC9E,CAAC;IAED,OAAO,CAAC,EAAU;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QACjC,sEAAsE;QACtE,gEAAgE;QAChE,SAAS,CAAC;YACP,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM;iBACpB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC;iBACtE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACT,MAAM;YACT,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACzB,CAAC;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/node/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/node/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAYlF,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC"}
|
|
@@ -23,8 +23,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
// Subpath barrel for `@hydranium/protocol/testing/node` — the test transports
|
|
26
|
-
// that need a Node runtime
|
|
27
|
-
// `MessageConnection` bridge over it.
|
|
26
|
+
// that need a Node runtime.
|
|
28
27
|
//
|
|
29
28
|
// Separate from `./testing` because a `PassThrough` is in `DuplexStreamPair`'s
|
|
30
29
|
// exported type and `StreamMessageReader` comes from `vscode-jsonrpc/node`, so
|
|
@@ -34,4 +33,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
34
33
|
// their own.
|
|
35
34
|
__exportStar(require("./duplex-connection"), exports);
|
|
36
35
|
__exportStar(require("./duplex-stream"), exports);
|
|
36
|
+
__exportStar(require("./message-port-pair"), exports);
|
|
37
37
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/node/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/node/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,8EAA8E;AAC9E,4BAA4B;AAC5B,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,8EAA8E;AAC9E,aAAa;AAEb,sDAAoC;AACpC,kDAAgC;AAChC,sDAAoC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the MIT License which is available in the project root.
|
|
6
|
+
*
|
|
7
|
+
* SPDX-License-Identifier: MIT
|
|
8
|
+
********************************************************************************/
|
|
9
|
+
import type { TransferredMessagePort } from '../../client/post-message-transport';
|
|
10
|
+
/**
|
|
11
|
+
* The two ends of a `worker_threads` `MessageChannel`, typed as the transferred
|
|
12
|
+
* browser ports `createMessagePortTransport` takes. Node's port clones and keeps
|
|
13
|
+
* order as a browser's does, which is what lets a headless test stand in for a
|
|
14
|
+
* worker.
|
|
15
|
+
*
|
|
16
|
+
* `dispose` closes both ports. Node reports that as a close and a browser port
|
|
17
|
+
* reports nothing, so a test that asserts on a close does so before teardown.
|
|
18
|
+
*/
|
|
19
|
+
export interface MessagePortPair {
|
|
20
|
+
readonly port1: TransferredMessagePort;
|
|
21
|
+
readonly port2: TransferredMessagePort;
|
|
22
|
+
dispose(): void;
|
|
23
|
+
}
|
|
24
|
+
export declare function makeMessagePortPair(): MessagePortPair;
|
|
25
|
+
//# sourceMappingURL=message-port-pair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-port-pair.d.ts","sourceRoot":"","sources":["../../../src/testing/node/message-port-pair.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAGlF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAElF;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC7B,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,OAAO,IAAI,IAAI,CAAC;CAClB;AAED,wBAAgB,mBAAmB,IAAI,eAAe,CAYrD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/********************************************************************************
|
|
3
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
4
|
+
*
|
|
5
|
+
* This program and the accompanying materials are made available under the
|
|
6
|
+
* terms of the MIT License which is available in the project root.
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: MIT
|
|
9
|
+
********************************************************************************/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.makeMessagePortPair = makeMessagePortPair;
|
|
12
|
+
const node_worker_threads_1 = require("node:worker_threads");
|
|
13
|
+
function makeMessagePortPair() {
|
|
14
|
+
const channel = new node_worker_threads_1.MessageChannel();
|
|
15
|
+
return {
|
|
16
|
+
// Node's port satisfies the structural type at runtime; the cast records
|
|
17
|
+
// one platform's port standing in for the other's.
|
|
18
|
+
port1: channel.port1,
|
|
19
|
+
port2: channel.port2,
|
|
20
|
+
dispose() {
|
|
21
|
+
channel.port1.close();
|
|
22
|
+
channel.port2.close();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=message-port-pair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-port-pair.js","sourceRoot":"","sources":["../../../src/testing/node/message-port-pair.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AAoBlF,kDAYC;AA9BD,6DAAqD;AAkBrD,SAAgB,mBAAmB;IAChC,MAAM,OAAO,GAAG,IAAI,oCAAc,EAAE,CAAC;IACrC,OAAO;QACJ,yEAAyE;QACzE,mDAAmD;QACnD,KAAK,EAAE,OAAO,CAAC,KAA0C;QACzD,KAAK,EAAE,OAAO,CAAC,KAA0C;QACzD,OAAO;YACJ,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;KACH,CAAC;AACL,CAAC"}
|
|
@@ -41,6 +41,14 @@ export interface TransferDocument<TTransfer extends TransferElement, TDiagnostic
|
|
|
41
41
|
*/
|
|
42
42
|
root?: TTransfer;
|
|
43
43
|
diagnostics: TDiagnostic[];
|
|
44
|
+
/**
|
|
45
|
+
* Whether the server holds text for this document that its file does not,
|
|
46
|
+
* as the server last knew the file: set on every document a data server
|
|
47
|
+
* answers or sends that the server holds, and absent otherwise. A change
|
|
48
|
+
* after this snapshot arrives as `onDocumentDirtyChanged` to a client
|
|
49
|
+
* watching the document.
|
|
50
|
+
*/
|
|
51
|
+
dirty?: boolean;
|
|
44
52
|
}
|
|
45
53
|
/**
|
|
46
54
|
* A {@link TransferDocument} the server actually had, so `root` is present.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer-document.d.ts","sourceRoot":"","sources":["../src/transfer-document.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"transfer-document.d.ts","sourceRoot":"","sources":["../src/transfer-document.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB;IAClG,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,IAAI,gBAAgB,CACvH,SAAS,EACT,WAAW,CACb,GAAG;IACD,IAAI,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,yBAAiB,gBAAgB,CAAC;IAC/B;;;OAGG;IACH,SAAgB,QAAQ,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EACzF,QAAQ,EAAE,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,GAClD,QAAQ,IAAI,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,CAE5D;IAED;;;;;OAKG;IACH,SAAgB,YAAY,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EAC7F,QAAQ,EAAE,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,GAClD,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,CAKhD;IAED;;;;;;;OAOG;IACH,SAAgB,MAAM,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EACvF,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,WAAW,EAAO,GAC/B,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,CAE1C;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,GAAG,kBAAkB,EACvF,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,WAAW,GAAE,WAAW,EAAO,GAC/B,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,CAE1C;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transfer-document.js","sourceRoot":"","sources":["../src/transfer-document.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAIlF,uDAAmF;
|
|
1
|
+
{"version":3,"file":"transfer-document.js","sourceRoot":"","sources":["../src/transfer-document.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAIlF,uDAAmF;AAuDnF,IAAiB,gBAAgB,CAuDhC;AAvDD,WAAiB,gBAAgB;IAC9B;;;OAGG;IACH,SAAgB,QAAQ,CACrB,QAAkD;QAElD,OAAO,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC;IACtC,CAAC;IAJe,yBAAQ,WAIvB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,YAAY,CACzB,QAAkD;QAElD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,QAAQ,CAAC;IACnB,CAAC;IAPe,6BAAY,eAO3B,CAAA;IAED;;;;;;;OAOG;IACH,SAAgB,MAAM,CACnB,GAAW,EACX,cAA6B,EAAE;QAE/B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAA,4BAAiB,EAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAC/E,CAAC;IALe,uBAAM,SAKrB,CAAA;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CACnB,GAAW,EACX,OAAe,EACf,IAAe,EACf,cAA6B,EAAE;QAE/B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAA,4BAAiB,EAAC,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC1E,CAAC;IAPe,uBAAM,SAOrB,CAAA;AACJ,CAAC,EAvDgB,gBAAgB,gCAAhB,gBAAgB,QAuDhC"}
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
+
import { Emitter, type Event } from 'vscode-jsonrpc';
|
|
10
11
|
import { FRAMEWORK_CLIENT_IDS } from '../client-ids';
|
|
11
12
|
import {
|
|
12
13
|
DATA_CLIENT_PROTOCOL_METHODS,
|
|
@@ -14,7 +15,8 @@ import {
|
|
|
14
15
|
type DataClientProtocol,
|
|
15
16
|
type DataServerProtocol,
|
|
16
17
|
type DiagnosticOf,
|
|
17
|
-
type ProjectOf
|
|
18
|
+
type ProjectOf,
|
|
19
|
+
type TransferDocumentDirtyChangedEvent
|
|
18
20
|
} from '../data';
|
|
19
21
|
import type { TransferElement } from '../transfer-element';
|
|
20
22
|
import { DataEvents } from './data-events';
|
|
@@ -90,6 +92,20 @@ export class DataConnection<
|
|
|
90
92
|
> extends RpcConnection<TServer, TClient> {
|
|
91
93
|
protected readonly sessions = new Set<DataSession<TTransfer, TServer>>();
|
|
92
94
|
protected readonly sessionFactory: DataSessionFactory<TTransfer, TServer>;
|
|
95
|
+
protected readonly createSessionEmitter = new Emitter<DataSession<TTransfer, TServer>>();
|
|
96
|
+
/**
|
|
97
|
+
* Fires with each session {@link createSession} starts, before it returns,
|
|
98
|
+
* so a listener sees every session a caller can. A session started before
|
|
99
|
+
* the listener subscribed is in {@link liveSessions}.
|
|
100
|
+
*/
|
|
101
|
+
readonly onDidCreateSession: Event<DataSession<TTransfer, TServer>> = this.createSessionEmitter.event;
|
|
102
|
+
/**
|
|
103
|
+
* Per URI, the `dirty` the client was last told since a session of this
|
|
104
|
+
* connection last opened the URI. A restore tells the client its answer
|
|
105
|
+
* only where it differs, so the client hears changes and nothing else; see
|
|
106
|
+
* {@link DataSessionHost.restoreDirty}.
|
|
107
|
+
*/
|
|
108
|
+
protected readonly dirtyStates = new Map<string, boolean>();
|
|
93
109
|
|
|
94
110
|
constructor(port: DataPort, client: TClient, ...rest: DataConnectionArgs<TTransfer, TClient, TServer>) {
|
|
95
111
|
const [options = {}] = rest as [
|
|
@@ -107,12 +123,22 @@ export class DataConnection<
|
|
|
107
123
|
options.sessionFactory ?? ((clientId, host, label) => new DataSession<TTransfer, TServer>(clientId, host, label));
|
|
108
124
|
}
|
|
109
125
|
|
|
126
|
+
/**
|
|
127
|
+
* The sessions of this connection that have not ended, in the order they
|
|
128
|
+
* started. A session is listed until its `onDidDispose` fires, or until
|
|
129
|
+
* {@link dispose} clears the list.
|
|
130
|
+
*/
|
|
131
|
+
get liveSessions(): readonly DataSession<TTransfer, TServer>[] {
|
|
132
|
+
return [...this.sessions];
|
|
133
|
+
}
|
|
134
|
+
|
|
110
135
|
/**
|
|
111
136
|
* Start a participant on this connection, registered with the server under a
|
|
112
137
|
* fresh id, `label` plus `#` plus a random UUID, or under `clientId` when
|
|
113
|
-
* given.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
138
|
+
* given. Pass a `label` naming the participant; without one it is
|
|
139
|
+
* `session`. Synchronous: the registration is sent at once, and the
|
|
140
|
+
* session's calls wait for it. The server refuses an id live anywhere in
|
|
141
|
+
* its process, and every call of that session then rejects with a
|
|
116
142
|
* `DuplicateClientIdError` code.
|
|
117
143
|
*
|
|
118
144
|
* Throws for an id in {@link FRAMEWORK_CLIENT_IDS} — those are authors the
|
|
@@ -133,18 +159,56 @@ export class DataConnection<
|
|
|
133
159
|
id,
|
|
134
160
|
{
|
|
135
161
|
connected: () => this.connected(),
|
|
136
|
-
|
|
137
|
-
|
|
162
|
+
reportError: (error, reported) => this.reportError(error, reported),
|
|
163
|
+
restoreDirty: event => {
|
|
164
|
+
if (this.dirtyStates.get(event.uri) !== event.dirty) {
|
|
165
|
+
this.deliverDirty(event);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
forgetDirty: uri => this.dirtyStates.delete(uri)
|
|
138
169
|
},
|
|
139
170
|
label
|
|
140
171
|
);
|
|
141
172
|
this.sessions.add(session);
|
|
173
|
+
// Subscribed before the session is handed out, so the id is free again
|
|
174
|
+
// on this connection by the time any caller's listener runs.
|
|
175
|
+
session.onDidDispose(() => this.sessions.delete(session));
|
|
142
176
|
// A failure reaches the session's own calls, which wait for the same
|
|
143
177
|
// registration; caught here only so it is not also reported unhandled.
|
|
144
178
|
session.connected().catch(() => undefined);
|
|
179
|
+
this.createSessionEmitter.fire(session);
|
|
145
180
|
return session;
|
|
146
181
|
}
|
|
147
182
|
|
|
183
|
+
/**
|
|
184
|
+
* The client, with its `onDocumentDirtyChanged` passing through
|
|
185
|
+
* {@link deliverDirty} first, so {@link dirtyStates} holds what the server
|
|
186
|
+
* told it. Every other bound method forwards to the client unchanged, and
|
|
187
|
+
* one the client lacks stays absent, so the binding still refuses it.
|
|
188
|
+
*/
|
|
189
|
+
protected override localTarget(): TClient {
|
|
190
|
+
const client = this.client as unknown as Record<string, unknown>;
|
|
191
|
+
if (typeof client.onDocumentDirtyChanged !== 'function') {
|
|
192
|
+
return this.client;
|
|
193
|
+
}
|
|
194
|
+
const target: Record<string, unknown> = {};
|
|
195
|
+
for (const name of this.clientMethods) {
|
|
196
|
+
const method: unknown = client[name];
|
|
197
|
+
if (typeof method === 'function') {
|
|
198
|
+
target[name] = (params: unknown): unknown => (method as (params: unknown) => unknown).call(client, params);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
target.onDocumentDirtyChanged = (event: TransferDocumentDirtyChangedEvent): void => this.deliverDirty(event);
|
|
202
|
+
return target as unknown as TClient;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Record `event` in {@link dirtyStates} and hand it to the client. */
|
|
206
|
+
protected deliverDirty(event: TransferDocumentDirtyChangedEvent): void {
|
|
207
|
+
this.dirtyStates.set(event.uri, event.dirty);
|
|
208
|
+
const client = this.client as unknown as Partial<Pick<DataClientProtocol<TTransfer>, 'onDocumentDirtyChanged'>>;
|
|
209
|
+
client.onDocumentDirtyChanged?.(event);
|
|
210
|
+
}
|
|
211
|
+
|
|
148
212
|
/**
|
|
149
213
|
* After the transport dropped, reconnect on the next macrotask for the
|
|
150
214
|
* sessions with documents open, so they re-watch and follow their documents
|
|
@@ -173,7 +237,9 @@ export class DataConnection<
|
|
|
173
237
|
for (const session of [...this.sessions]) {
|
|
174
238
|
session.detach();
|
|
175
239
|
}
|
|
240
|
+
// For a factory's session whose `detach` does not fire.
|
|
176
241
|
this.sessions.clear();
|
|
242
|
+
this.createSessionEmitter.dispose();
|
|
177
243
|
super.dispose();
|
|
178
244
|
}
|
|
179
245
|
}
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
DataClientProtocol,
|
|
13
13
|
ProjectsChangedEvent,
|
|
14
14
|
TransferDocumentDeletedEvent,
|
|
15
|
+
TransferDocumentDirtyChangedEvent,
|
|
15
16
|
TransferDocumentSavedEvent,
|
|
16
17
|
TransferDocumentsBuiltEvent,
|
|
17
18
|
TransferDocumentUpdatedEvent
|
|
@@ -47,6 +48,7 @@ export class DataEvents<
|
|
|
47
48
|
> implements DataClientProtocol<TTransfer, TDiagnostic, TProject> {
|
|
48
49
|
protected readonly documentUpdatedEmitter = new Emitter<TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>>();
|
|
49
50
|
protected readonly documentSavedEmitter = new Emitter<TransferDocumentSavedEvent<TTransfer, TDiagnostic>>();
|
|
51
|
+
protected readonly documentDirtyChangedEmitter = new Emitter<TransferDocumentDirtyChangedEvent>();
|
|
50
52
|
protected readonly documentDeletedEmitter = new Emitter<TransferDocumentDeletedEvent>();
|
|
51
53
|
protected readonly documentsBuiltEmitter = new Emitter<TransferDocumentsBuiltEvent>();
|
|
52
54
|
protected readonly projectsChangedEmitter = new Emitter<ProjectsChangedEvent<TProject>>();
|
|
@@ -55,6 +57,8 @@ export class DataEvents<
|
|
|
55
57
|
readonly onDidUpdateDocument: Event<TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>> = this.documentUpdatedEmitter.event;
|
|
56
58
|
/** A watched document was persisted to disk. */
|
|
57
59
|
readonly onDidSaveDocument: Event<TransferDocumentSavedEvent<TTransfer, TDiagnostic>> = this.documentSavedEmitter.event;
|
|
60
|
+
/** A watched document's text started or stopped differing from its file. */
|
|
61
|
+
readonly onDidChangeDocumentDirty: Event<TransferDocumentDirtyChangedEvent> = this.documentDirtyChangedEmitter.event;
|
|
58
62
|
/** A document's backing file was removed, watched or not. Any watch survives. */
|
|
59
63
|
readonly onDidDeleteDocument: Event<TransferDocumentDeletedEvent> = this.documentDeletedEmitter.event;
|
|
60
64
|
/** Documents built that nobody watches — re-read anything derived from them. */
|
|
@@ -72,6 +76,10 @@ export class DataEvents<
|
|
|
72
76
|
this.documentSavedEmitter.fire(event);
|
|
73
77
|
}
|
|
74
78
|
|
|
79
|
+
onDocumentDirtyChanged(event: TransferDocumentDirtyChangedEvent): void {
|
|
80
|
+
this.documentDirtyChangedEmitter.fire(event);
|
|
81
|
+
}
|
|
82
|
+
|
|
75
83
|
onDocumentDeleted(event: TransferDocumentDeletedEvent): void {
|
|
76
84
|
this.documentDeletedEmitter.fire(event);
|
|
77
85
|
}
|
|
@@ -87,6 +95,7 @@ export class DataEvents<
|
|
|
87
95
|
dispose(): void {
|
|
88
96
|
this.documentUpdatedEmitter.dispose();
|
|
89
97
|
this.documentSavedEmitter.dispose();
|
|
98
|
+
this.documentDirtyChangedEmitter.dispose();
|
|
90
99
|
this.documentDeletedEmitter.dispose();
|
|
91
100
|
this.documentsBuiltEmitter.dispose();
|
|
92
101
|
this.projectsChangedEmitter.dispose();
|