@hydranium/protocol 1.0.0-next.10
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/LICENSE +21 -0
- package/README.md +81 -0
- package/lib/abstract-logger.d.ts +66 -0
- package/lib/abstract-logger.d.ts.map +1 -0
- package/lib/abstract-logger.js +110 -0
- package/lib/abstract-logger.js.map +1 -0
- package/lib/browser-runtime.d.ts +124 -0
- package/lib/browser-runtime.d.ts.map +1 -0
- package/lib/browser-runtime.js +11 -0
- package/lib/browser-runtime.js.map +1 -0
- package/lib/client/data-events.d.ts +49 -0
- package/lib/client/data-events.d.ts.map +1 -0
- package/lib/client/data-events.js +60 -0
- package/lib/client/data-events.js.map +1 -0
- package/lib/client/data-port.d.ts +95 -0
- package/lib/client/data-port.d.ts.map +1 -0
- package/lib/client/data-port.js +11 -0
- package/lib/client/data-port.js.map +1 -0
- package/lib/client/data-session.d.ts +129 -0
- package/lib/client/data-session.d.ts.map +1 -0
- package/lib/client/data-session.js +179 -0
- package/lib/client/data-session.js.map +1 -0
- package/lib/client/index.d.ts +39 -0
- package/lib/client/index.d.ts.map +1 -0
- package/lib/client/index.js +55 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client/message-relay.d.ts +111 -0
- package/lib/client/message-relay.d.ts.map +1 -0
- package/lib/client/message-relay.js +139 -0
- package/lib/client/message-relay.js.map +1 -0
- package/lib/client/post-message-transport.d.ts +77 -0
- package/lib/client/post-message-transport.d.ts.map +1 -0
- package/lib/client/post-message-transport.js +95 -0
- package/lib/client/post-message-transport.js.map +1 -0
- package/lib/clock.d.ts +111 -0
- package/lib/clock.d.ts.map +1 -0
- package/lib/clock.js +74 -0
- package/lib/clock.js.map +1 -0
- package/lib/data/data-protocol-methods.d.ts +39 -0
- package/lib/data/data-protocol-methods.d.ts.map +1 -0
- package/lib/data/data-protocol-methods.js +61 -0
- package/lib/data/data-protocol-methods.js.map +1 -0
- package/lib/data/data-server-protocol.d.ts +264 -0
- package/lib/data/data-server-protocol.d.ts.map +1 -0
- package/lib/data/data-server-protocol.js +11 -0
- package/lib/data/data-server-protocol.js.map +1 -0
- package/lib/data/diagnostics.d.ts +97 -0
- package/lib/data/diagnostics.d.ts.map +1 -0
- package/lib/data/diagnostics.js +25 -0
- package/lib/data/diagnostics.js.map +1 -0
- package/lib/data/events.d.ts +107 -0
- package/lib/data/events.d.ts.map +1 -0
- package/lib/data/events.js +11 -0
- package/lib/data/events.js.map +1 -0
- package/lib/data/index.d.ts +15 -0
- package/lib/data/index.d.ts.map +1 -0
- package/lib/data/index.js +38 -0
- package/lib/data/index.js.map +1 -0
- package/lib/data/methods.d.ts +57 -0
- package/lib/data/methods.d.ts.map +1 -0
- package/lib/data/methods.js +60 -0
- package/lib/data/methods.js.map +1 -0
- package/lib/data/requests.d.ts +65 -0
- package/lib/data/requests.d.ts.map +1 -0
- package/lib/data/requests.js +11 -0
- package/lib/data/requests.js.map +1 -0
- package/lib/debouncer.d.ts +75 -0
- package/lib/debouncer.d.ts.map +1 -0
- package/lib/debouncer.js +91 -0
- package/lib/debouncer.js.map +1 -0
- package/lib/errors.d.ts +84 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +113 -0
- package/lib/errors.js.map +1 -0
- package/lib/host-diagnostics.d.ts +58 -0
- package/lib/host-diagnostics.d.ts.map +1 -0
- package/lib/host-diagnostics.js +18 -0
- package/lib/host-diagnostics.js.map +1 -0
- package/lib/index.d.ts +34 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +56 -0
- package/lib/index.js.map +1 -0
- package/lib/latency-collector.d.ts +126 -0
- package/lib/latency-collector.d.ts.map +1 -0
- package/lib/latency-collector.js +137 -0
- package/lib/latency-collector.js.map +1 -0
- package/lib/logger.d.ts +119 -0
- package/lib/logger.d.ts.map +1 -0
- package/lib/logger.js +126 -0
- package/lib/logger.js.map +1 -0
- package/lib/model-server.d.ts +352 -0
- package/lib/model-server.d.ts.map +1 -0
- package/lib/model-server.js +160 -0
- package/lib/model-server.js.map +1 -0
- package/lib/model-service/args.d.ts +64 -0
- package/lib/model-service/args.d.ts.map +1 -0
- package/lib/model-service/args.js +11 -0
- package/lib/model-service/args.js.map +1 -0
- package/lib/model-service/index.d.ts +11 -0
- package/lib/model-service/index.d.ts.map +1 -0
- package/lib/model-service/index.js +31 -0
- package/lib/model-service/index.js.map +1 -0
- package/lib/model-service/reference-candidate.d.ts +56 -0
- package/lib/model-service/reference-candidate.d.ts.map +1 -0
- package/lib/model-service/reference-candidate.js +11 -0
- package/lib/model-service/reference-candidate.js.map +1 -0
- package/lib/noop-logger.d.ts +25 -0
- package/lib/noop-logger.d.ts.map +1 -0
- package/lib/noop-logger.js +36 -0
- package/lib/noop-logger.js.map +1 -0
- package/lib/observable-value.d.ts +72 -0
- package/lib/observable-value.d.ts.map +1 -0
- package/lib/observable-value.js +52 -0
- package/lib/observable-value.js.map +1 -0
- package/lib/patch-merge.d.ts +123 -0
- package/lib/patch-merge.d.ts.map +1 -0
- package/lib/patch-merge.js +104 -0
- package/lib/patch-merge.js.map +1 -0
- package/lib/profile-session.d.ts +87 -0
- package/lib/profile-session.d.ts.map +1 -0
- package/lib/profile-session.js +98 -0
- package/lib/profile-session.js.map +1 -0
- package/lib/profiling.d.ts +83 -0
- package/lib/profiling.d.ts.map +1 -0
- package/lib/profiling.js +20 -0
- package/lib/profiling.js.map +1 -0
- package/lib/project.d.ts +121 -0
- package/lib/project.d.ts.map +1 -0
- package/lib/project.js +34 -0
- package/lib/project.js.map +1 -0
- package/lib/rpc/bind-rpc-methods.d.ts +100 -0
- package/lib/rpc/bind-rpc-methods.d.ts.map +1 -0
- package/lib/rpc/bind-rpc-methods.js +110 -0
- package/lib/rpc/bind-rpc-methods.js.map +1 -0
- package/lib/rpc/create-rpc-proxy.d.ts +188 -0
- package/lib/rpc/create-rpc-proxy.d.ts.map +1 -0
- package/lib/rpc/create-rpc-proxy.js +158 -0
- package/lib/rpc/create-rpc-proxy.js.map +1 -0
- package/lib/rpc/index.d.ts +12 -0
- package/lib/rpc/index.d.ts.map +1 -0
- package/lib/rpc/index.js +31 -0
- package/lib/rpc/index.js.map +1 -0
- package/lib/rpc/wire-prefix.d.ts +37 -0
- package/lib/rpc/wire-prefix.d.ts.map +1 -0
- package/lib/rpc/wire-prefix.js +49 -0
- package/lib/rpc/wire-prefix.js.map +1 -0
- package/lib/testing/data-doubles.d.ts +121 -0
- package/lib/testing/data-doubles.d.ts.map +1 -0
- package/lib/testing/data-doubles.js +102 -0
- package/lib/testing/data-doubles.js.map +1 -0
- package/lib/testing/fake-clock.d.ts +35 -0
- package/lib/testing/fake-clock.d.ts.map +1 -0
- package/lib/testing/fake-clock.js +86 -0
- package/lib/testing/fake-clock.js.map +1 -0
- package/lib/testing/harness.d.ts +24 -0
- package/lib/testing/harness.d.ts.map +1 -0
- package/lib/testing/harness.js +11 -0
- package/lib/testing/harness.js.map +1 -0
- package/lib/testing/index.d.ts +13 -0
- package/lib/testing/index.d.ts.map +1 -0
- package/lib/testing/index.js +41 -0
- package/lib/testing/index.js.map +1 -0
- package/lib/testing/node/duplex-connection.d.ts +25 -0
- package/lib/testing/node/duplex-connection.d.ts.map +1 -0
- package/lib/testing/node/duplex-connection.js +34 -0
- package/lib/testing/node/duplex-connection.js.map +1 -0
- package/lib/testing/node/duplex-stream.d.ts +32 -0
- package/lib/testing/node/duplex-stream.d.ts.map +1 -0
- package/lib/testing/node/duplex-stream.js +35 -0
- package/lib/testing/node/duplex-stream.js.map +1 -0
- package/lib/testing/node/index.d.ts +11 -0
- package/lib/testing/node/index.d.ts.map +1 -0
- package/lib/testing/node/index.js +37 -0
- package/lib/testing/node/index.js.map +1 -0
- package/lib/testing/wait-for.d.ts +69 -0
- package/lib/testing/wait-for.d.ts.map +1 -0
- package/lib/testing/wait-for.js +67 -0
- package/lib/testing/wait-for.js.map +1 -0
- package/lib/tracer.d.ts +115 -0
- package/lib/tracer.d.ts.map +1 -0
- package/lib/tracer.js +205 -0
- package/lib/tracer.js.map +1 -0
- package/lib/transfer-diagnostic.d.ts +73 -0
- package/lib/transfer-diagnostic.d.ts.map +1 -0
- package/lib/transfer-diagnostic.js +45 -0
- package/lib/transfer-diagnostic.js.map +1 -0
- package/lib/transfer-document.d.ts +73 -0
- package/lib/transfer-document.d.ts.map +1 -0
- package/lib/transfer-document.js +46 -0
- package/lib/transfer-document.js.map +1 -0
- package/lib/transfer-element.d.ts +39 -0
- package/lib/transfer-element.d.ts.map +1 -0
- package/lib/transfer-element.js +11 -0
- package/lib/transfer-element.js.map +1 -0
- package/lib/uri.d.ts +62 -0
- package/lib/uri.d.ts.map +1 -0
- package/lib/uri.js +28 -0
- package/lib/uri.js.map +1 -0
- package/lib/util.d.ts +147 -0
- package/lib/util.d.ts.map +1 -0
- package/lib/util.js +211 -0
- package/lib/util.js.map +1 -0
- package/package.json +100 -0
- package/src/abstract-logger.ts +120 -0
- package/src/browser-runtime.ts +135 -0
- package/src/client/data-events.ts +71 -0
- package/src/client/data-port.ts +99 -0
- package/src/client/data-session.ts +209 -0
- package/src/client/index.ts +40 -0
- package/src/client/message-relay.ts +216 -0
- package/src/client/post-message-transport.ts +167 -0
- package/src/clock.ts +173 -0
- package/src/data/data-protocol-methods.ts +79 -0
- package/src/data/data-server-protocol.ts +296 -0
- package/src/data/diagnostics.ts +116 -0
- package/src/data/events.ts +127 -0
- package/src/data/index.ts +23 -0
- package/src/data/methods.ts +59 -0
- package/src/data/requests.ts +70 -0
- package/src/debouncer.ts +118 -0
- package/src/errors.ts +127 -0
- package/src/host-diagnostics.ts +63 -0
- package/src/index.ts +41 -0
- package/src/latency-collector.ts +231 -0
- package/src/logger.ts +172 -0
- package/src/model-server.ts +479 -0
- package/src/model-service/args.ts +67 -0
- package/src/model-service/index.ts +16 -0
- package/src/model-service/reference-candidate.ts +58 -0
- package/src/noop-logger.ts +36 -0
- package/src/observable-value.ts +92 -0
- package/src/patch-merge.ts +165 -0
- package/src/profile-session.ts +164 -0
- package/src/profiling.ts +113 -0
- package/src/project.ts +125 -0
- package/src/rpc/README.md +163 -0
- package/src/rpc/bind-rpc-methods.ts +180 -0
- package/src/rpc/create-rpc-proxy.ts +292 -0
- package/src/rpc/index.ts +16 -0
- package/src/rpc/wire-prefix.ts +48 -0
- package/src/testing/data-doubles.ts +178 -0
- package/src/testing/fake-clock.ts +106 -0
- package/src/testing/harness.ts +24 -0
- package/src/testing/index.ts +26 -0
- package/src/testing/node/duplex-connection.ts +50 -0
- package/src/testing/node/duplex-stream.ts +51 -0
- package/src/testing/node/index.ts +22 -0
- package/src/testing/wait-for.ts +94 -0
- package/src/tracer.ts +277 -0
- package/src/transfer-diagnostic.ts +92 -0
- package/src/transfer-document.ts +99 -0
- package/src/transfer-element.ts +43 -0
- package/src/uri.ts +61 -0
- package/src/util.ts +250 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, 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
|
+
/**
|
|
10
|
+
* The shared path identifier under which the data-server exposes its typed
|
|
11
|
+
* RPC methods. Production adopters using vscode-jsonrpc transports use this
|
|
12
|
+
* as the connection-builder path; the data-server side uses it when
|
|
13
|
+
* registering handlers.
|
|
14
|
+
*
|
|
15
|
+
* Distinct from the LSP (`languageId`-routed) and GLSP (`diagram-type`-routed)
|
|
16
|
+
* heads — each protocol head owns its own path namespace.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DATA_SERVER_PATH = "/hydranium/data-server";
|
|
19
|
+
/**
|
|
20
|
+
* Wire-name prefix used by `createRpcProxy` and `DataServer`'s
|
|
21
|
+
* handler binding. Every property name on the typed `DataServerProtocol`
|
|
22
|
+
* (or `DataClientProtocol`) interface lowers to `<prefix><methodName>` on
|
|
23
|
+
* the wire — so renaming a TS method renames the wire method,
|
|
24
|
+
* intentionally.
|
|
25
|
+
*
|
|
26
|
+
* Adopters writing custom transports or inspecting the wire derive each
|
|
27
|
+
* wire name as `DATA_SERVER_WIRE_PREFIX + methodName`, where the method
|
|
28
|
+
* names live in `DATA_SERVER_PROTOCOL_METHODS` (request methods) and
|
|
29
|
+
* `DATA_CLIENT_PROTOCOL_METHODS` (notification methods), both exported
|
|
30
|
+
* from `./data-protocol-methods`. The interface (`DataServerProtocol`,
|
|
31
|
+
* `DataClientProtocol`) is the source of truth; the method-name arrays
|
|
32
|
+
* are typed against the interface (`as const satisfies …`) so they
|
|
33
|
+
* cannot drift.
|
|
34
|
+
*/
|
|
35
|
+
export declare const DATA_SERVER_WIRE_PREFIX = "data-server/";
|
|
36
|
+
/**
|
|
37
|
+
* Default LSP command id under which a data-server publishes its listening
|
|
38
|
+
* TCP port for client discovery. Parallel to {@link DATA_SERVER_PATH} (the
|
|
39
|
+
* service-path routing constant) — both name the data-server head's transport
|
|
40
|
+
* surface so a simple adopter needs no constants of its own.
|
|
41
|
+
*
|
|
42
|
+
* Two ends reference this id:
|
|
43
|
+
* - PUBLISH (server): the launcher registers the port under this command on
|
|
44
|
+
* the LSP connection —
|
|
45
|
+
* `publishPortOnLspConnection(conn, DATA_SERVER_PORT_COMMAND, port)`.
|
|
46
|
+
* `@hydranium/core`'s `publishPortOnLspConnection` stays command-agnostic
|
|
47
|
+
* (it publishes any port under any command); the adopter passes this
|
|
48
|
+
* constant.
|
|
49
|
+
* - EXTRACT (Theia host): `@hydranium/data-client-theia`'s
|
|
50
|
+
* `DataServerConnectionHandler` polls this command to discover the port —
|
|
51
|
+
* its `portCommand` option defaults to this value.
|
|
52
|
+
*
|
|
53
|
+
* Adopters with an established command id (e.g. `'modelserver:port'`)
|
|
54
|
+
* override both ends.
|
|
55
|
+
*/
|
|
56
|
+
export declare const DATA_SERVER_PORT_COMMAND = "hydranium/data-server/port";
|
|
57
|
+
//# sourceMappingURL=methods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/data/methods.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/********************************************************************************
|
|
3
|
+
* Copyright (c) 2026 CrossBreeze, 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.DATA_SERVER_PORT_COMMAND = exports.DATA_SERVER_WIRE_PREFIX = exports.DATA_SERVER_PATH = void 0;
|
|
12
|
+
/**
|
|
13
|
+
* The shared path identifier under which the data-server exposes its typed
|
|
14
|
+
* RPC methods. Production adopters using vscode-jsonrpc transports use this
|
|
15
|
+
* as the connection-builder path; the data-server side uses it when
|
|
16
|
+
* registering handlers.
|
|
17
|
+
*
|
|
18
|
+
* Distinct from the LSP (`languageId`-routed) and GLSP (`diagram-type`-routed)
|
|
19
|
+
* heads — each protocol head owns its own path namespace.
|
|
20
|
+
*/
|
|
21
|
+
exports.DATA_SERVER_PATH = '/hydranium/data-server';
|
|
22
|
+
/**
|
|
23
|
+
* Wire-name prefix used by `createRpcProxy` and `DataServer`'s
|
|
24
|
+
* handler binding. Every property name on the typed `DataServerProtocol`
|
|
25
|
+
* (or `DataClientProtocol`) interface lowers to `<prefix><methodName>` on
|
|
26
|
+
* the wire — so renaming a TS method renames the wire method,
|
|
27
|
+
* intentionally.
|
|
28
|
+
*
|
|
29
|
+
* Adopters writing custom transports or inspecting the wire derive each
|
|
30
|
+
* wire name as `DATA_SERVER_WIRE_PREFIX + methodName`, where the method
|
|
31
|
+
* names live in `DATA_SERVER_PROTOCOL_METHODS` (request methods) and
|
|
32
|
+
* `DATA_CLIENT_PROTOCOL_METHODS` (notification methods), both exported
|
|
33
|
+
* from `./data-protocol-methods`. The interface (`DataServerProtocol`,
|
|
34
|
+
* `DataClientProtocol`) is the source of truth; the method-name arrays
|
|
35
|
+
* are typed against the interface (`as const satisfies …`) so they
|
|
36
|
+
* cannot drift.
|
|
37
|
+
*/
|
|
38
|
+
exports.DATA_SERVER_WIRE_PREFIX = 'data-server/';
|
|
39
|
+
/**
|
|
40
|
+
* Default LSP command id under which a data-server publishes its listening
|
|
41
|
+
* TCP port for client discovery. Parallel to {@link DATA_SERVER_PATH} (the
|
|
42
|
+
* service-path routing constant) — both name the data-server head's transport
|
|
43
|
+
* surface so a simple adopter needs no constants of its own.
|
|
44
|
+
*
|
|
45
|
+
* Two ends reference this id:
|
|
46
|
+
* - PUBLISH (server): the launcher registers the port under this command on
|
|
47
|
+
* the LSP connection —
|
|
48
|
+
* `publishPortOnLspConnection(conn, DATA_SERVER_PORT_COMMAND, port)`.
|
|
49
|
+
* `@hydranium/core`'s `publishPortOnLspConnection` stays command-agnostic
|
|
50
|
+
* (it publishes any port under any command); the adopter passes this
|
|
51
|
+
* constant.
|
|
52
|
+
* - EXTRACT (Theia host): `@hydranium/data-client-theia`'s
|
|
53
|
+
* `DataServerConnectionHandler` polls this command to discover the port —
|
|
54
|
+
* its `portCommand` option defaults to this value.
|
|
55
|
+
*
|
|
56
|
+
* Adopters with an established command id (e.g. `'modelserver:port'`)
|
|
57
|
+
* override both ends.
|
|
58
|
+
*/
|
|
59
|
+
exports.DATA_SERVER_PORT_COMMAND = 'hydranium/data-server/port';
|
|
60
|
+
//# sourceMappingURL=methods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/data/methods.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF;;;;;;;;GAQG;AACU,QAAA,gBAAgB,GAAG,wBAAwB,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACU,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,wBAAwB,GAAG,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, 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 { TransferSaveArgs, TransferUpdateArgs } from '../model-service/args';
|
|
10
|
+
/** Get the current state of a single document. The server returns the latest built version. */
|
|
11
|
+
export interface GetModelDocumentArgs {
|
|
12
|
+
/** Document URI. */
|
|
13
|
+
uri: string;
|
|
14
|
+
/**
|
|
15
|
+
* When `true`, the response is settled at the validation phase so its
|
|
16
|
+
* `diagnostics` are populated. When `false`/absent, the response returns at
|
|
17
|
+
* the (faster) integrity-settled phase and `diagnostics` may be absent —
|
|
18
|
+
* they are computed asynchronously and delivered via the subscription
|
|
19
|
+
* channel (and, for an LSP head, `publishDiagnostics`).
|
|
20
|
+
*
|
|
21
|
+
* Set this for one-shot / unsubscribed callers (CLI queries, batch checks)
|
|
22
|
+
* that need diagnostics in the response itself. Mirrors Langium's
|
|
23
|
+
* `BuildOptions.validation: boolean`. Note it does not *strip* diagnostics:
|
|
24
|
+
* a document already validated still carries them; the flag only controls
|
|
25
|
+
* whether the read forces/awaits validation.
|
|
26
|
+
*/
|
|
27
|
+
includeDiagnostics?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Look up the project owning the given document URI. Membership semantics
|
|
31
|
+
* are decided by the server's `ProjectManager` (default in
|
|
32
|
+
* `AbstractProjectManager`: closest-ancestor descriptor folder); the data-
|
|
33
|
+
* server forwards the URI without interpretation.
|
|
34
|
+
*/
|
|
35
|
+
export interface GetProjectForUriArgs {
|
|
36
|
+
/** Document URI to look up. */
|
|
37
|
+
uri: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Update a document's content. Wire-side projection of the facade's
|
|
41
|
+
* {@link TransferUpdateArgs}; structurally identical so the data-server RPC
|
|
42
|
+
* handler can forward straight to the in-process `ModelService.update`
|
|
43
|
+
* without an args mapping.
|
|
44
|
+
*/
|
|
45
|
+
export type TransferUpdateDocumentArgs<TTransfer> = TransferUpdateArgs<TTransfer>;
|
|
46
|
+
/** Persist a document to disk. Wire-side projection of {@link TransferSaveArgs}. */
|
|
47
|
+
export type TransferSaveDocumentArgs<TTransfer> = TransferSaveArgs<TTransfer>;
|
|
48
|
+
/**
|
|
49
|
+
* Identifies a per-document watch on the data server. Shared by both
|
|
50
|
+
* `watchModelDocument` and `unwatchModelDocument` — the `(uri, clientId)`
|
|
51
|
+
* pair is the watch key, so unwatching names the same watch that was
|
|
52
|
+
* started. The `clientId` identifies the originator the same way it does
|
|
53
|
+
* on facade-side mutations (`TransferUpdateArgs.clientId`,
|
|
54
|
+
* `TransferSaveArgs.clientId`): it keys the per-`(uri, clientId)` watch
|
|
55
|
+
* bucket so multiple watchers on the same wire stay distinct, AND it lets
|
|
56
|
+
* each watcher recognise its own echo on inbound `onDocumentUpdated` events
|
|
57
|
+
* (the wire shape's `sourceClientId` carries the originating mutation's
|
|
58
|
+
* `clientId`).
|
|
59
|
+
*/
|
|
60
|
+
export interface WatchModelDocumentArgs {
|
|
61
|
+
uri: string;
|
|
62
|
+
/** Stable identifier for the watching client. */
|
|
63
|
+
clientId: string;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=requests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/data/requests.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAElF,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IAClC,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IAClC,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,CAAC,SAAS,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAElF,oFAAoF;AACpF,MAAM,MAAM,wBAAwB,CAAC,SAAS,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,sBAAsB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/********************************************************************************
|
|
3
|
+
* Copyright (c) 2026 CrossBreeze, 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
|
+
//# sourceMappingURL=requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/data/requests.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, 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 Clock } from './clock';
|
|
10
|
+
import { ObservableValue, type MaybeObservableValue } from './observable-value';
|
|
11
|
+
import { type Disposable } from './util';
|
|
12
|
+
/** Construction options for {@link Debouncer}. */
|
|
13
|
+
export interface DebouncerOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Trailing-edge delay in milliseconds, read per {@link Debouncer.schedule}
|
|
16
|
+
* so a setting-bound cell reshapes the live window without rebuilding the
|
|
17
|
+
* debouncer. A value `<= 0` still defers to the next tick via
|
|
18
|
+
* {@link Clock.setTimer}; callers wanting a synchronous path handle that
|
|
19
|
+
* themselves before scheduling.
|
|
20
|
+
*/
|
|
21
|
+
readonly delayMs: MaybeObservableValue<number>;
|
|
22
|
+
/**
|
|
23
|
+
* Optional starvation ceiling. When calls keep arriving faster than
|
|
24
|
+
* {@link delayMs}, the trailing edge never settles and `fn` would never
|
|
25
|
+
* run; with `maxWaitMs` set, a fire is forced once that many milliseconds
|
|
26
|
+
* have elapsed since the first pending {@link Debouncer.schedule}, so a
|
|
27
|
+
* continuous stream still makes progress. Omitted (the default) = pure
|
|
28
|
+
* trailing edge, which may defer indefinitely under a non-stop stream.
|
|
29
|
+
*/
|
|
30
|
+
readonly maxWaitMs?: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Trailing-edge debounce built on the injectable {@link Clock}, so the window
|
|
34
|
+
* is deterministically testable with `makeFakeClock` — the framework's timer
|
|
35
|
+
* seam rather than raw `setTimeout` (which `p-debounce` / `lodash.debounce`
|
|
36
|
+
* hold internally and cannot be driven by a fake clock).
|
|
37
|
+
*
|
|
38
|
+
* Owns ONLY timing. {@link fn} is zero-argument and returns nothing: the caller
|
|
39
|
+
* keeps whatever payload it is coalescing — an accumulator set, a "latest
|
|
40
|
+
* value" field — and reads it inside `fn` when the debouncer fires. That
|
|
41
|
+
* timing/payload split is what lets one primitive serve both an accumulating
|
|
42
|
+
* caller (merge changed/deleted sets) and a replacing one (last value wins).
|
|
43
|
+
*
|
|
44
|
+
* Leading-edge invocation and a result-returning ("await the debounced run")
|
|
45
|
+
* variant are deliberately omitted to keep this a pure timing primitive; both
|
|
46
|
+
* are additive later (a `leading` option; a separate promise helper) rather
|
|
47
|
+
* than a breaking change.
|
|
48
|
+
*/
|
|
49
|
+
export declare class Debouncer implements Disposable {
|
|
50
|
+
protected readonly clock: Clock;
|
|
51
|
+
protected readonly fn: () => void;
|
|
52
|
+
protected readonly delay: ObservableValue<number>;
|
|
53
|
+
protected readonly maxWaitMs?: number;
|
|
54
|
+
protected timer?: Disposable;
|
|
55
|
+
/** Virtual time of the first {@link schedule} of the current pending window; drives {@link DebouncerOptions.maxWaitMs}. */
|
|
56
|
+
protected firstScheduledAt?: number;
|
|
57
|
+
constructor(clock: Clock, fn: () => void, options: DebouncerOptions);
|
|
58
|
+
/** True while a fire is armed (scheduled, not yet fired or cancelled). */
|
|
59
|
+
get pending(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Arm — or re-arm — the trailing-edge timer. Repeated calls within the
|
|
62
|
+
* window collapse into a single {@link fn} run at the trailing edge; with
|
|
63
|
+
* {@link DebouncerOptions.maxWaitMs} set, the run is forced once that ceiling
|
|
64
|
+
* elapses since the first pending call.
|
|
65
|
+
*/
|
|
66
|
+
schedule(): void;
|
|
67
|
+
/** If a fire is pending, run {@link fn} now and clear the window; otherwise a no-op. */
|
|
68
|
+
flush(): void;
|
|
69
|
+
/** Drop a pending fire without running {@link fn}. */
|
|
70
|
+
cancel(): void;
|
|
71
|
+
/** Cancel any pending fire and release. */
|
|
72
|
+
dispose(): void;
|
|
73
|
+
protected fire(): void;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=debouncer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debouncer.d.ts","sourceRoot":"","sources":["../src/debouncer.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC/C;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,SAAU,YAAW,UAAU;IAQtC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAC/B,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI;IARpC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAClD,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC7B,2HAA2H;IAC3H,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;gBAGd,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,MAAM,IAAI,EACjC,OAAO,EAAE,gBAAgB;IAM5B,0EAA0E;IAC1E,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;OAKG;IACH,QAAQ,IAAI,IAAI;IAchB,wFAAwF;IACxF,KAAK,IAAI,IAAI;IAMb,sDAAsD;IACtD,MAAM,IAAI,IAAI;IAMd,2CAA2C;IAC3C,OAAO,IAAI,IAAI;IAIf,SAAS,CAAC,IAAI,IAAI,IAAI;CAMxB"}
|
package/lib/debouncer.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/********************************************************************************
|
|
3
|
+
* Copyright (c) 2026 CrossBreeze, 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.Debouncer = void 0;
|
|
12
|
+
const observable_value_1 = require("./observable-value");
|
|
13
|
+
/**
|
|
14
|
+
* Trailing-edge debounce built on the injectable {@link Clock}, so the window
|
|
15
|
+
* is deterministically testable with `makeFakeClock` — the framework's timer
|
|
16
|
+
* seam rather than raw `setTimeout` (which `p-debounce` / `lodash.debounce`
|
|
17
|
+
* hold internally and cannot be driven by a fake clock).
|
|
18
|
+
*
|
|
19
|
+
* Owns ONLY timing. {@link fn} is zero-argument and returns nothing: the caller
|
|
20
|
+
* keeps whatever payload it is coalescing — an accumulator set, a "latest
|
|
21
|
+
* value" field — and reads it inside `fn` when the debouncer fires. That
|
|
22
|
+
* timing/payload split is what lets one primitive serve both an accumulating
|
|
23
|
+
* caller (merge changed/deleted sets) and a replacing one (last value wins).
|
|
24
|
+
*
|
|
25
|
+
* Leading-edge invocation and a result-returning ("await the debounced run")
|
|
26
|
+
* variant are deliberately omitted to keep this a pure timing primitive; both
|
|
27
|
+
* are additive later (a `leading` option; a separate promise helper) rather
|
|
28
|
+
* than a breaking change.
|
|
29
|
+
*/
|
|
30
|
+
class Debouncer {
|
|
31
|
+
clock;
|
|
32
|
+
fn;
|
|
33
|
+
delay;
|
|
34
|
+
maxWaitMs;
|
|
35
|
+
timer;
|
|
36
|
+
/** Virtual time of the first {@link schedule} of the current pending window; drives {@link DebouncerOptions.maxWaitMs}. */
|
|
37
|
+
firstScheduledAt;
|
|
38
|
+
constructor(clock, fn, options) {
|
|
39
|
+
this.clock = clock;
|
|
40
|
+
this.fn = fn;
|
|
41
|
+
this.delay = observable_value_1.ObservableValue.from(options.delayMs);
|
|
42
|
+
this.maxWaitMs = options.maxWaitMs;
|
|
43
|
+
}
|
|
44
|
+
/** True while a fire is armed (scheduled, not yet fired or cancelled). */
|
|
45
|
+
get pending() {
|
|
46
|
+
return this.timer !== undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Arm — or re-arm — the trailing-edge timer. Repeated calls within the
|
|
50
|
+
* window collapse into a single {@link fn} run at the trailing edge; with
|
|
51
|
+
* {@link DebouncerOptions.maxWaitMs} set, the run is forced once that ceiling
|
|
52
|
+
* elapses since the first pending call.
|
|
53
|
+
*/
|
|
54
|
+
schedule() {
|
|
55
|
+
const now = this.clock.now();
|
|
56
|
+
if (this.firstScheduledAt === undefined) {
|
|
57
|
+
this.firstScheduledAt = now;
|
|
58
|
+
}
|
|
59
|
+
let wait = Math.max(0, this.delay.value);
|
|
60
|
+
if (this.maxWaitMs !== undefined) {
|
|
61
|
+
const untilCeiling = this.firstScheduledAt + this.maxWaitMs - now;
|
|
62
|
+
wait = Math.min(wait, Math.max(0, untilCeiling));
|
|
63
|
+
}
|
|
64
|
+
this.timer?.dispose();
|
|
65
|
+
this.timer = this.clock.setTimer(() => this.fire(), wait);
|
|
66
|
+
}
|
|
67
|
+
/** If a fire is pending, run {@link fn} now and clear the window; otherwise a no-op. */
|
|
68
|
+
flush() {
|
|
69
|
+
if (this.timer !== undefined) {
|
|
70
|
+
this.fire();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Drop a pending fire without running {@link fn}. */
|
|
74
|
+
cancel() {
|
|
75
|
+
this.timer?.dispose();
|
|
76
|
+
this.timer = undefined;
|
|
77
|
+
this.firstScheduledAt = undefined;
|
|
78
|
+
}
|
|
79
|
+
/** Cancel any pending fire and release. */
|
|
80
|
+
dispose() {
|
|
81
|
+
this.cancel();
|
|
82
|
+
}
|
|
83
|
+
fire() {
|
|
84
|
+
this.timer?.dispose();
|
|
85
|
+
this.timer = undefined;
|
|
86
|
+
this.firstScheduledAt = undefined;
|
|
87
|
+
this.fn();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.Debouncer = Debouncer;
|
|
91
|
+
//# sourceMappingURL=debouncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debouncer.js","sourceRoot":"","sources":["../src/debouncer.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAGlF,yDAAgF;AAwBhF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,SAAS;IAQG;IACA;IARH,KAAK,CAA0B;IAC/B,SAAS,CAAU;IAC5B,KAAK,CAAc;IAC7B,2HAA2H;IACjH,gBAAgB,CAAU;IAEpC,YACsB,KAAY,EACZ,EAAc,EACjC,OAAyB;QAFN,UAAK,GAAL,KAAK,CAAO;QACZ,OAAE,GAAF,EAAE,CAAY;QAGjC,IAAI,CAAC,KAAK,GAAG,kCAAe,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACtC,CAAC;IAED,0EAA0E;IAC1E,IAAI,OAAO;QACR,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;YAClE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,wFAAwF;IACxF,KAAK;QACF,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;IACJ,CAAC;IAED,sDAAsD;IACtD,MAAM;QACH,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACrC,CAAC;IAED,2CAA2C;IAC3C,OAAO;QACJ,IAAI,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC;IAES,IAAI;QACX,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,EAAE,EAAE,CAAC;IACb,CAAC;CACH;AAlED,8BAkEC"}
|
package/lib/errors.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, 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 { ResponseError } from 'vscode-jsonrpc';
|
|
10
|
+
/**
|
|
11
|
+
* Application-specific JSON-RPC error code for {@link ConflictError}.
|
|
12
|
+
* Outside the reserved range (-32768 .. -32000) per JSON-RPC 2.0.
|
|
13
|
+
*
|
|
14
|
+
* The code is the load-bearing identifier across realm boundaries —
|
|
15
|
+
* `code` is a first-class field on the JSON-RPC error envelope and
|
|
16
|
+
* survives wire reconstruction; the custom `Error` subclass name does
|
|
17
|
+
* not.
|
|
18
|
+
*/
|
|
19
|
+
export declare const CONFLICT_ERROR_CODE = 1001;
|
|
20
|
+
/**
|
|
21
|
+
* Structured payload carried in {@link ConflictError.data}, and the only place
|
|
22
|
+
* a post-RPC caller can read the version mismatch from.
|
|
23
|
+
*/
|
|
24
|
+
export interface ConflictErrorData {
|
|
25
|
+
readonly uri: string;
|
|
26
|
+
/** The based-on version the caller authored against. */
|
|
27
|
+
readonly expected: number;
|
|
28
|
+
/** The server's current text-document version at the time of the throw. */
|
|
29
|
+
readonly actual: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Thrown by `ModelService.update` / `ModelService.save` when the caller-
|
|
33
|
+
* supplied based-on version no longer matches the server's current text-
|
|
34
|
+
* document version for the same URI — i.e. the snapshot the caller
|
|
35
|
+
* authored against has been superseded by an intervening edit.
|
|
36
|
+
*
|
|
37
|
+
* Extends vscode-jsonrpc's {@link ResponseError} so the typed
|
|
38
|
+
* {@link ConflictErrorData} payload rides on the standard JSON-RPC
|
|
39
|
+
* error envelope (`code`, `message`, `data`) — all three fields are
|
|
40
|
+
* preserved by RPC reconstruction. Adopters that catch the error on
|
|
41
|
+
* the receiving side of an RPC call read the version mismatch from
|
|
42
|
+
* `err.data` (the instance is reconstructed as a generic
|
|
43
|
+
* `ResponseError`, so subclass getters / fields do not survive).
|
|
44
|
+
*
|
|
45
|
+
* Detection is opt-in via the optional `baseVersion` field on
|
|
46
|
+
* `TransferUpdateArgs` / `TransferSaveArgs`; callers that omit the field get
|
|
47
|
+
* no gating. This mirrors LSP's `OptionalVersionedTextDocumentIdentifier`
|
|
48
|
+
* posture, so headless / CLI / batch tooling with no meaningful based-on
|
|
49
|
+
* version can opt out explicitly.
|
|
50
|
+
*
|
|
51
|
+
* Three reasonable adopter recovery strategies:
|
|
52
|
+
*
|
|
53
|
+
* | Strategy | Use case |
|
|
54
|
+
* |---|---|
|
|
55
|
+
* | Drop + refetch | Form-widget save; user can re-trigger if they still want the edit. |
|
|
56
|
+
* | Refetch + replay user edit | Specific structural edits (`setField`, drag-position). Adopter responsibility. |
|
|
57
|
+
* | Surface to user | Large edits, multi-step transactions. Adopter UI. |
|
|
58
|
+
*
|
|
59
|
+
* The framework provides the **detection**; adopters provide the **policy**.
|
|
60
|
+
* No auto-retry or auto-merge ships by default.
|
|
61
|
+
*/
|
|
62
|
+
export declare class ConflictError extends ResponseError<ConflictErrorData> {
|
|
63
|
+
constructor(uri: string, expected: number, actual: number);
|
|
64
|
+
get uri(): string;
|
|
65
|
+
get expected(): number;
|
|
66
|
+
get actual(): number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Type guard for {@link ConflictError}. Detection ladder:
|
|
70
|
+
*
|
|
71
|
+
* 1. `error.name === 'ConflictError'` — direct in-process throw, no
|
|
72
|
+
* RPC round-trip.
|
|
73
|
+
* 2. `(error as ResponseError).code === CONFLICT_ERROR_CODE` — the
|
|
74
|
+
* canonical wire-side check; the JSON-RPC `code` field is preserved
|
|
75
|
+
* across reconstruction, so any adopter catching after an RPC call
|
|
76
|
+
* hits this branch.
|
|
77
|
+
* 3. `error.message.includes('Stale-based update for ')` — fallback
|
|
78
|
+
* for transports that re-wrap the message and drop the code (rare).
|
|
79
|
+
*
|
|
80
|
+
* `instanceof ConflictError` alone would silently return `false` on the
|
|
81
|
+
* reconstructed shape, so callers do not use it.
|
|
82
|
+
*/
|
|
83
|
+
export declare function isConflictError(error: unknown): error is ConflictError;
|
|
84
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,aAAc,SAAQ,aAAa,CAAC,iBAAiB,CAAC;gBACpD,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAezD,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;CACH;AAOD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAYtE"}
|
package/lib/errors.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/********************************************************************************
|
|
3
|
+
* Copyright (c) 2026 CrossBreeze, 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.ConflictError = exports.CONFLICT_ERROR_CODE = void 0;
|
|
12
|
+
exports.isConflictError = isConflictError;
|
|
13
|
+
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
|
|
14
|
+
/**
|
|
15
|
+
* Application-specific JSON-RPC error code for {@link ConflictError}.
|
|
16
|
+
* Outside the reserved range (-32768 .. -32000) per JSON-RPC 2.0.
|
|
17
|
+
*
|
|
18
|
+
* The code is the load-bearing identifier across realm boundaries —
|
|
19
|
+
* `code` is a first-class field on the JSON-RPC error envelope and
|
|
20
|
+
* survives wire reconstruction; the custom `Error` subclass name does
|
|
21
|
+
* not.
|
|
22
|
+
*/
|
|
23
|
+
exports.CONFLICT_ERROR_CODE = 1001;
|
|
24
|
+
/**
|
|
25
|
+
* Thrown by `ModelService.update` / `ModelService.save` when the caller-
|
|
26
|
+
* supplied based-on version no longer matches the server's current text-
|
|
27
|
+
* document version for the same URI — i.e. the snapshot the caller
|
|
28
|
+
* authored against has been superseded by an intervening edit.
|
|
29
|
+
*
|
|
30
|
+
* Extends vscode-jsonrpc's {@link ResponseError} so the typed
|
|
31
|
+
* {@link ConflictErrorData} payload rides on the standard JSON-RPC
|
|
32
|
+
* error envelope (`code`, `message`, `data`) — all three fields are
|
|
33
|
+
* preserved by RPC reconstruction. Adopters that catch the error on
|
|
34
|
+
* the receiving side of an RPC call read the version mismatch from
|
|
35
|
+
* `err.data` (the instance is reconstructed as a generic
|
|
36
|
+
* `ResponseError`, so subclass getters / fields do not survive).
|
|
37
|
+
*
|
|
38
|
+
* Detection is opt-in via the optional `baseVersion` field on
|
|
39
|
+
* `TransferUpdateArgs` / `TransferSaveArgs`; callers that omit the field get
|
|
40
|
+
* no gating. This mirrors LSP's `OptionalVersionedTextDocumentIdentifier`
|
|
41
|
+
* posture, so headless / CLI / batch tooling with no meaningful based-on
|
|
42
|
+
* version can opt out explicitly.
|
|
43
|
+
*
|
|
44
|
+
* Three reasonable adopter recovery strategies:
|
|
45
|
+
*
|
|
46
|
+
* | Strategy | Use case |
|
|
47
|
+
* |---|---|
|
|
48
|
+
* | Drop + refetch | Form-widget save; user can re-trigger if they still want the edit. |
|
|
49
|
+
* | Refetch + replay user edit | Specific structural edits (`setField`, drag-position). Adopter responsibility. |
|
|
50
|
+
* | Surface to user | Large edits, multi-step transactions. Adopter UI. |
|
|
51
|
+
*
|
|
52
|
+
* The framework provides the **detection**; adopters provide the **policy**.
|
|
53
|
+
* No auto-retry or auto-merge ships by default.
|
|
54
|
+
*/
|
|
55
|
+
class ConflictError extends vscode_jsonrpc_1.ResponseError {
|
|
56
|
+
constructor(uri, expected, actual) {
|
|
57
|
+
super(exports.CONFLICT_ERROR_CODE, `Stale-based update for ${uri}: expected v${expected}, server is at v${actual}`, {
|
|
58
|
+
uri,
|
|
59
|
+
expected,
|
|
60
|
+
actual
|
|
61
|
+
});
|
|
62
|
+
this.name = 'ConflictError';
|
|
63
|
+
// ResponseError's constructor calls `Object.setPrototypeOf(this,
|
|
64
|
+
// ResponseError.prototype)` to keep its own prototype chain intact across
|
|
65
|
+
// transpilation targets; that resets us to ResponseError, hiding the
|
|
66
|
+
// ConflictError-specific getters. Restore the prototype here so
|
|
67
|
+
// `err.uri` / `.expected` / `.actual` resolve through this class.
|
|
68
|
+
Object.setPrototypeOf(this, ConflictError.prototype);
|
|
69
|
+
}
|
|
70
|
+
get uri() {
|
|
71
|
+
return this.data.uri;
|
|
72
|
+
}
|
|
73
|
+
get expected() {
|
|
74
|
+
return this.data.expected;
|
|
75
|
+
}
|
|
76
|
+
get actual() {
|
|
77
|
+
return this.data.actual;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.ConflictError = ConflictError;
|
|
81
|
+
/** Marker substring present in every {@link ConflictError} message, used by
|
|
82
|
+
* {@link isConflictError} as a fallback when a transport re-wraps the error
|
|
83
|
+
* and drops the JSON-RPC code. */
|
|
84
|
+
const CONFLICT_ERROR_MESSAGE_MARKER = 'Stale-based update for ';
|
|
85
|
+
/**
|
|
86
|
+
* Type guard for {@link ConflictError}. Detection ladder:
|
|
87
|
+
*
|
|
88
|
+
* 1. `error.name === 'ConflictError'` — direct in-process throw, no
|
|
89
|
+
* RPC round-trip.
|
|
90
|
+
* 2. `(error as ResponseError).code === CONFLICT_ERROR_CODE` — the
|
|
91
|
+
* canonical wire-side check; the JSON-RPC `code` field is preserved
|
|
92
|
+
* across reconstruction, so any adopter catching after an RPC call
|
|
93
|
+
* hits this branch.
|
|
94
|
+
* 3. `error.message.includes('Stale-based update for ')` — fallback
|
|
95
|
+
* for transports that re-wrap the message and drop the code (rare).
|
|
96
|
+
*
|
|
97
|
+
* `instanceof ConflictError` alone would silently return `false` on the
|
|
98
|
+
* reconstructed shape, so callers do not use it.
|
|
99
|
+
*/
|
|
100
|
+
function isConflictError(error) {
|
|
101
|
+
if (!(error instanceof Error)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
if (error.name === 'ConflictError') {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
const code = error.code;
|
|
108
|
+
if (code === exports.CONFLICT_ERROR_CODE) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
return typeof error.message === 'string' && error.message.includes(CONFLICT_ERROR_MESSAGE_MARKER);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AA2GlF,0CAYC;AArHD,mDAA+C;AAE/C;;;;;;;;GAQG;AACU,QAAA,mBAAmB,GAAG,IAAI,CAAC;AAcxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAa,aAAc,SAAQ,8BAAgC;IAChE,YAAY,GAAW,EAAE,QAAgB,EAAE,MAAc;QACtD,KAAK,CAAC,2BAAmB,EAAE,0BAA0B,GAAG,eAAe,QAAQ,mBAAmB,MAAM,EAAE,EAAE;YACzG,GAAG;YACH,QAAQ;YACR,MAAM;SACR,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,iEAAiE;QACjE,0EAA0E;QAC1E,qEAAqE;QACrE,gEAAgE;QAChE,kEAAkE;QAClE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,GAAG;QACJ,OAAO,IAAI,CAAC,IAAK,CAAC,GAAG,CAAC;IACzB,CAAC;IAED,IAAI,QAAQ;QACT,OAAO,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAED,IAAI,MAAM;QACP,OAAO,IAAI,CAAC,IAAK,CAAC,MAAM,CAAC;IAC5B,CAAC;CACH;AA3BD,sCA2BC;AAED;;mCAEmC;AACnC,MAAM,6BAA6B,GAAG,yBAAyB,CAAC;AAEhE;;;;;;;;;;;;;;GAcG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC3C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAI,KAAyC,CAAC,IAAI,CAAC;IAC7D,IAAI,IAAI,KAAK,2BAAmB,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACf,CAAC;IACD,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AACrG,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, 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
|
+
/**
|
|
10
|
+
* Diagnostics contract for the HOST (parent) process — the Theia backend
|
|
11
|
+
* itself, the process that runs the data-client connection handlers and any
|
|
12
|
+
* in-process services. Distinct from `DataServerDiagnosticsProtocol`,
|
|
13
|
+
* which targets the separate data-server child (the heavy model store): the
|
|
14
|
+
* host process is reached by an ordinary in-process Theia RPC service, NOT over
|
|
15
|
+
* the data-server socket. Universal (`process.memoryUsage()` always works) and
|
|
16
|
+
* cheap, so the framework wires it by default for every host that opts the
|
|
17
|
+
* data-client backend module in.
|
|
18
|
+
*
|
|
19
|
+
* Returns are plain formatted strings — the caller (a command, a log sink, the
|
|
20
|
+
* pod's stdout) decides how to surface them.
|
|
21
|
+
*/
|
|
22
|
+
/** Arguments for {@link HostDiagnosticsProtocol.dumpHostState}. */
|
|
23
|
+
export interface DumpHostStateArgs {
|
|
24
|
+
/** Optional label folded into the snapshot heading (e.g. an ISO timestamp). */
|
|
25
|
+
label?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Arguments for {@link HostDiagnosticsProtocol.writeHostHeapSnapshot}. */
|
|
28
|
+
export interface WriteHostHeapSnapshotArgs {
|
|
29
|
+
/** Optional label folded into the snapshot filename. */
|
|
30
|
+
label?: string;
|
|
31
|
+
/** Directory to write into; defaults to the OS temp dir when absent or not present on disk. */
|
|
32
|
+
directory?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Memory diagnostics the running HOST (Theia backend) process exposes. Computed
|
|
36
|
+
* in-process: the snapshots reflect the parent process, the counterpart to the
|
|
37
|
+
* data-server child's `DataServerDiagnosticsProtocol`.
|
|
38
|
+
*/
|
|
39
|
+
export interface HostDiagnosticsProtocol {
|
|
40
|
+
/**
|
|
41
|
+
* Capture a host-process memory snapshot — heap, rss, external, V8 limit —
|
|
42
|
+
* and return it formatted. The host hosts no Langium documents, so this is
|
|
43
|
+
* the lighter `formatProcessMemory` view, not `formatServerState`.
|
|
44
|
+
*/
|
|
45
|
+
dumpHostState(args: DumpHostStateArgs): Promise<string>;
|
|
46
|
+
/**
|
|
47
|
+
* Write a V8 heap snapshot of the host process to disk (full GC first;
|
|
48
|
+
* briefly pauses the process) and return the absolute file path.
|
|
49
|
+
*/
|
|
50
|
+
writeHostHeapSnapshot(args: WriteHostHeapSnapshotArgs): Promise<string>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Theia service path the host-diagnostics RPC service is registered under. An
|
|
54
|
+
* ordinary in-process backend service (`RpcConnectionHandler`), unlike the
|
|
55
|
+
* socket-forwarded `DATA_SERVER_PATH`.
|
|
56
|
+
*/
|
|
57
|
+
export declare const HOST_DIAGNOSTICS_PATH = "/hydranium/host-diagnostics";
|
|
58
|
+
//# sourceMappingURL=host-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-diagnostics.d.ts","sourceRoot":"","sources":["../src/host-diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;GAYG;AAEH,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAC/B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACvC,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACrC;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExD;;;OAGG;IACH,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1E;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,gCAAgC,CAAC"}
|