@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,479 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2023 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
|
+
/**
|
|
11
|
+
* Generic model-server protocol types: lifecycle arguments, events, and
|
|
12
|
+
* cross-reference shapes. Free of any specific grammar, AST type, or
|
|
13
|
+
* language identifier — consumers parameterise the document/root types
|
|
14
|
+
* over `TRoot`.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { TransferClientArgs } from './model-service/args';
|
|
18
|
+
import type { ReferenceCandidate } from './model-service/reference-candidate';
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Client / server arguments
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
// `TransferClientArgs` / `TransferUpdateArgs` / `TransferSaveArgs` live in
|
|
25
|
+
// `./model-service/args.ts` and are re-exported by the main barrel via
|
|
26
|
+
// `./model-service`. The legacy LSP-style protocol (Open / Close / events)
|
|
27
|
+
// defined here only consumes them as a supertype.
|
|
28
|
+
|
|
29
|
+
/** Open a document on behalf of a client. */
|
|
30
|
+
export interface OpenModelArgs extends TransferClientArgs {
|
|
31
|
+
/**
|
|
32
|
+
* Overrides the language the URI's extension would resolve to. Supply it
|
|
33
|
+
* only when the extension does not decide — an unregistered extension, or a
|
|
34
|
+
* document being opened under a language other than its own. A wrong value
|
|
35
|
+
* routes the document to the wrong grammar and it parses as garbage rather
|
|
36
|
+
* than failing.
|
|
37
|
+
*/
|
|
38
|
+
languageId?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Seeds the shared version sequence, defaulting to `0`. Only the FIRST open
|
|
41
|
+
* of a URI consumes it; after that the server owns the sequence and advances
|
|
42
|
+
* it itself, so callers never fabricate later numbers.
|
|
43
|
+
*/
|
|
44
|
+
version?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Content to open the document with instead of reading the file. Absent
|
|
47
|
+
* means read from the filesystem, which is the normal case.
|
|
48
|
+
*
|
|
49
|
+
* Honoured only on the first open of a URI: opening an already-open document
|
|
50
|
+
* is a no-op, so passing `text` for one silently changes nothing. Write
|
|
51
|
+
* through the update path instead.
|
|
52
|
+
*/
|
|
53
|
+
text?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Close a previously-opened document for the client. */
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
58
|
+
export interface CloseModelArgs extends TransferClientArgs {}
|
|
59
|
+
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Update / save events
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
export interface TransferUpdatedEvent<TDocument> {
|
|
65
|
+
document: TDocument;
|
|
66
|
+
sourceClientId: string;
|
|
67
|
+
/** See `ModelDocumentUpdateReason` in `./data/events` for the canonical reason set + semantics. */
|
|
68
|
+
reason: 'changed' | 'deleted' | 'rebuilt' | 'saved';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface TransferSavedEvent<TDocument> {
|
|
72
|
+
/** The document as persisted — the state that reached disk, not the state at request time. */
|
|
73
|
+
document: TDocument;
|
|
74
|
+
/**
|
|
75
|
+
* The client whose save produced this. Every co-editing client receives the
|
|
76
|
+
* event including the originator, so a recipient compares it against its own
|
|
77
|
+
* id to recognise its own echo; acting on that echo is how an update loop
|
|
78
|
+
* starts.
|
|
79
|
+
*/
|
|
80
|
+
sourceClientId: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Cross-reference shapes
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The source-side address for a reference query: where the lookup is asked
|
|
89
|
+
* from. One of three shapes — a {@link DocumentSource} (the root of a
|
|
90
|
+
* document at the given URI), an {@link ElementSource} (an element resolved
|
|
91
|
+
* by its qualified name), or a {@link SyntheticSource} (a transient
|
|
92
|
+
* element that does not yet exist on disk, used during element-creation
|
|
93
|
+
* flows).
|
|
94
|
+
*
|
|
95
|
+
* Construct via the {@link ReferenceSource} namespace factories
|
|
96
|
+
* (`ReferenceSource.document(uri)` / `.element(name, type?)` /
|
|
97
|
+
* `.synthetic(uri, type)`) rather than tag-field literals — the factories
|
|
98
|
+
* surface the three variants via autocomplete and centralise any future
|
|
99
|
+
* shape changes.
|
|
100
|
+
*/
|
|
101
|
+
export type ReferenceSource = DocumentSource | ElementSource | SyntheticSource;
|
|
102
|
+
|
|
103
|
+
/** A reference anchored at the root element of a document, identified by URI. */
|
|
104
|
+
export interface DocumentSource {
|
|
105
|
+
uri: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Narrow an unknown value to a {@link DocumentSource}. Not exclusive within
|
|
110
|
+
* {@link ReferenceSource}: a {@link SyntheticSource} also carries `uri`, so
|
|
111
|
+
* discriminating the union must try {@link isSyntheticSource} first.
|
|
112
|
+
*/
|
|
113
|
+
export function isDocumentSource(object: unknown): object is DocumentSource {
|
|
114
|
+
return !!object && typeof object === 'object' && 'uri' in object && typeof object.uri === 'string';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* A reference to an element identified by its **qualified name**, optionally
|
|
119
|
+
* narrowed by type.
|
|
120
|
+
*
|
|
121
|
+
* The name is the form a source-text writer would type — normally the
|
|
122
|
+
* project-qualified name (see `NameProvider.getProjectQualifiedName`). It is
|
|
123
|
+
* **not** rename-stable and is distinct from an element *key*: rename the
|
|
124
|
+
* element and this address changes. Clients that need a handle surviving
|
|
125
|
+
* renames address the element some other way; this shape addresses by name.
|
|
126
|
+
*/
|
|
127
|
+
export interface ElementSource {
|
|
128
|
+
/**
|
|
129
|
+
* The qualified name as a source-text writer would spell it — normally the
|
|
130
|
+
* project-qualified form. Resolution is by exact match against the index, so
|
|
131
|
+
* a partially-qualified or differently-cased spelling simply finds nothing
|
|
132
|
+
* rather than falling back to a looser search.
|
|
133
|
+
*/
|
|
134
|
+
name: string;
|
|
135
|
+
/**
|
|
136
|
+
* Disambiguates when one name is claimed by several AST types. Absent means
|
|
137
|
+
* "any type", which for an ambiguous name resolves arbitrarily rather than
|
|
138
|
+
* failing — pass it whenever the caller knows what it is addressing.
|
|
139
|
+
*/
|
|
140
|
+
type?: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function isElementSource(object: unknown): object is ElementSource {
|
|
144
|
+
return !!object && typeof object === 'object' && 'name' in object && typeof object.name === 'string';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** An element of a document that does not yet exist on disk — used during element creation flows. */
|
|
148
|
+
export interface SyntheticSource {
|
|
149
|
+
/**
|
|
150
|
+
* The document the element would belong to. That document must already be
|
|
151
|
+
* LOADED — the default resolution takes its parse root as the synthetic
|
|
152
|
+
* node's container and answers `undefined` when it is not, so a URI for a
|
|
153
|
+
* file that exists on disk but was never opened resolves to nothing.
|
|
154
|
+
*/
|
|
155
|
+
uri: string;
|
|
156
|
+
/**
|
|
157
|
+
* The AST type the element will have. Required here, unlike on an
|
|
158
|
+
* {@link ElementSource}, because no node exists yet from which to infer it —
|
|
159
|
+
* it is what scoping filters candidates against.
|
|
160
|
+
*/
|
|
161
|
+
type: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function isSyntheticSource(object: unknown): object is SyntheticSource {
|
|
165
|
+
return (
|
|
166
|
+
!!object &&
|
|
167
|
+
typeof object === 'object' &&
|
|
168
|
+
'uri' in object &&
|
|
169
|
+
typeof object.uri === 'string' &&
|
|
170
|
+
'type' in object &&
|
|
171
|
+
typeof object.type === 'string'
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Factory helpers for the {@link ReferenceSource} variants. Use instead of
|
|
177
|
+
* tag-field literals so a future shape change lands in one place.
|
|
178
|
+
*/
|
|
179
|
+
export namespace ReferenceSource {
|
|
180
|
+
export function document(uri: string): DocumentSource {
|
|
181
|
+
return { uri };
|
|
182
|
+
}
|
|
183
|
+
export function element(name: string, type?: string): ElementSource {
|
|
184
|
+
return { name, type };
|
|
185
|
+
}
|
|
186
|
+
export function synthetic(uri: string, type: string): SyntheticSource {
|
|
187
|
+
return { uri, type };
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* One step in a synthetic navigation path from a {@link ReferenceSource}
|
|
193
|
+
* toward the property whose references we want to query. Each step describes
|
|
194
|
+
* a transient AST node that does not yet exist in the document — e.g. an
|
|
195
|
+
* element being created via UI flow — and is spliced into the chain so the
|
|
196
|
+
* scope provider sees the world *as if* the synthetic child were already
|
|
197
|
+
* placed at that slot.
|
|
198
|
+
*
|
|
199
|
+
* The field names mirror Langium's `$type` / `$containerProperty` so adopter
|
|
200
|
+
* callsites read consistently with AST-side code.
|
|
201
|
+
*
|
|
202
|
+
* Construct via {@link SyntheticStep.of} rather than a tag-field literal.
|
|
203
|
+
*/
|
|
204
|
+
export interface SyntheticStep {
|
|
205
|
+
/**
|
|
206
|
+
* The AST `$type` the spliced node claims. Scoping filters candidates
|
|
207
|
+
* against it, so a type the grammar does not declare yields an empty scope
|
|
208
|
+
* rather than an error.
|
|
209
|
+
*/
|
|
210
|
+
type: string;
|
|
211
|
+
/**
|
|
212
|
+
* The containment slot on the parent step, or on the source for the first
|
|
213
|
+
* step. It must name a real containment property of that parent: the walk
|
|
214
|
+
* builds the node unconditionally, so a wrong slot produces a plausible node
|
|
215
|
+
* in a place the grammar has no rule for, and the emptiness surfaces later
|
|
216
|
+
* as "no candidates".
|
|
217
|
+
*/
|
|
218
|
+
containerProperty: string;
|
|
219
|
+
/**
|
|
220
|
+
* Which element of an array-valued {@link containerProperty} the step
|
|
221
|
+
* addresses. **Mandatory for an array slot** on the resolving read
|
|
222
|
+
* (`ScopeProvider.resolveReferenceSource` given a whole context), which
|
|
223
|
+
* stops rather than descend into the array itself; a scope query reads it
|
|
224
|
+
* only as the stub's `$containerIndex`, since a fabricated node has no
|
|
225
|
+
* siblings to sit between.
|
|
226
|
+
*
|
|
227
|
+
* Absent means the slot holds a single node. Naming an out-of-range element
|
|
228
|
+
* resolves to nothing rather than failing.
|
|
229
|
+
*/
|
|
230
|
+
index?: number;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Narrow an unknown value to a {@link SyntheticStep} — for a consumer
|
|
235
|
+
* validating a step that arrived over the wire. Framework code builds steps
|
|
236
|
+
* through {@link SyntheticStep.of} and never needs the check, so the absent
|
|
237
|
+
* in-repo caller is the seam working rather than unused surface.
|
|
238
|
+
*/
|
|
239
|
+
export function isSyntheticStep(object: unknown): object is SyntheticStep {
|
|
240
|
+
return (
|
|
241
|
+
!!object &&
|
|
242
|
+
typeof object === 'object' &&
|
|
243
|
+
'type' in object &&
|
|
244
|
+
typeof object.type === 'string' &&
|
|
245
|
+
'containerProperty' in object &&
|
|
246
|
+
typeof object.containerProperty === 'string'
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export namespace SyntheticStep {
|
|
251
|
+
/**
|
|
252
|
+
* Construct a single {@link SyntheticStep} — "which slot of the parent, of
|
|
253
|
+
* which AST type". Pass `index` to pin the step to an existing array
|
|
254
|
+
* element instead of a transient synthetic node.
|
|
255
|
+
*/
|
|
256
|
+
export function of(containerProperty: string, type: string, index?: number): SyntheticStep {
|
|
257
|
+
return { containerProperty, type, index };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Construct a sequence of {@link SyntheticStep}s from `(containerProperty,
|
|
262
|
+
* type)` tuples. Convenience for 3+ step paths where repeating
|
|
263
|
+
* `SyntheticStep.of(...)` per entry is visually noisy. For 1-2 step paths
|
|
264
|
+
* the per-step factory typically reads more clearly.
|
|
265
|
+
*/
|
|
266
|
+
export function chain(...steps: ReadonlyArray<Parameters<typeof of>>): SyntheticStep[] {
|
|
267
|
+
return steps.map(step => of(...step));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Describes the question "what reachable elements are valid for this property
|
|
273
|
+
* of this (possibly synthetic) source-side element?". The server resolves it
|
|
274
|
+
* to a list of reference candidates ({@link ReferenceCandidate} in
|
|
275
|
+
* `@hydranium/protocol/model-service`).
|
|
276
|
+
*
|
|
277
|
+
* Build via {@link ReferenceContext.builder} — the staged builder enforces
|
|
278
|
+
* the `source -> path -> property` order at compile time.
|
|
279
|
+
*/
|
|
280
|
+
export interface ReferenceContext {
|
|
281
|
+
/** Where the query originates — the source-side {@link ReferenceSource} the lookup is anchored at. */
|
|
282
|
+
source: ReferenceSource;
|
|
283
|
+
/**
|
|
284
|
+
* Synthetic navigation path from the source toward the leaf whose
|
|
285
|
+
* references we want. Each entry is a transient AST node spliced into
|
|
286
|
+
* the navigation chain — useful for elements that are being created or
|
|
287
|
+
* that cannot yet be identified canonically. Empty / absent for queries
|
|
288
|
+
* whose source IS the leaf.
|
|
289
|
+
*/
|
|
290
|
+
syntheticPath?: SyntheticStep[];
|
|
291
|
+
/**
|
|
292
|
+
* The property of the leaf element (final step in {@link syntheticPath},
|
|
293
|
+
* or the source when the path is empty) whose reachable references we
|
|
294
|
+
* want to retrieve.
|
|
295
|
+
*/
|
|
296
|
+
property: string;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Narrow a value to a {@link ReferenceContext}, discriminating it from a bare
|
|
301
|
+
* {@link ReferenceSource}. No source variant carries either `source` or
|
|
302
|
+
* `property`, so the pair is unambiguous — which is what lets one resolver
|
|
303
|
+
* accept both an anchor and a whole context.
|
|
304
|
+
*/
|
|
305
|
+
export function isReferenceContext(object: unknown): object is ReferenceContext {
|
|
306
|
+
return (
|
|
307
|
+
!!object &&
|
|
308
|
+
typeof object === 'object' &&
|
|
309
|
+
'source' in object &&
|
|
310
|
+
'property' in object &&
|
|
311
|
+
typeof (object as ReferenceContext).property === 'string'
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* A concrete reference-resolution request: a {@link ReferenceContext} plus the
|
|
317
|
+
* written value to resolve. Extending the context makes resolution literally
|
|
318
|
+
* "the candidate query, narrowed to one value" — and a request carries a
|
|
319
|
+
* `syntheticPath` for free, so a reference anchored at a nested synthetic
|
|
320
|
+
* source resolves the same way it lists candidates.
|
|
321
|
+
*
|
|
322
|
+
* Build via {@link ReferenceRequest.builder} — same staged order as
|
|
323
|
+
* {@link ReferenceContext.builder}, ending with a mandatory `value`.
|
|
324
|
+
*/
|
|
325
|
+
export interface ReferenceRequest extends ReferenceContext {
|
|
326
|
+
/** The textual value (the `$refText`) of the reference we are resolving. */
|
|
327
|
+
value: string;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// ---------------------------------------------------------------------------
|
|
331
|
+
// Staged builders for ReferenceContext / ReferenceRequest
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* First builder stage: pick the {@link ReferenceSource} variant. Generic over
|
|
336
|
+
* the stage that `property()` lands on, so the context and request builders
|
|
337
|
+
* share the source/path stages and differ only at the terminal.
|
|
338
|
+
*/
|
|
339
|
+
export interface ReferenceSourceStage<TAfterProperty> {
|
|
340
|
+
/** Anchor at the semantic root of a loaded document — a {@link DocumentSource}. */
|
|
341
|
+
document(uri: string): ReferencePathStage<TAfterProperty>;
|
|
342
|
+
/** Anchor at an element addressed by qualified name — an {@link ElementSource}. */
|
|
343
|
+
element(name: string, type?: string): ReferencePathStage<TAfterProperty>;
|
|
344
|
+
/** Anchor at an element that does not exist yet — a {@link SyntheticSource}. */
|
|
345
|
+
synthetic(uri: string, type: string): ReferencePathStage<TAfterProperty>;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Second builder stage: append synthetic {@link SyntheticStep}s (repeatable,
|
|
350
|
+
* optional), then close on the leaf property. `step()` is unavailable after
|
|
351
|
+
* `property()`, which enforces the `source -> path -> property` order.
|
|
352
|
+
*/
|
|
353
|
+
export interface ReferencePathStage<TAfterProperty> {
|
|
354
|
+
/**
|
|
355
|
+
* Append one {@link SyntheticStep}, outermost first, and return a new stage
|
|
356
|
+
* carrying the extended path. The builder is persistent, so a stage held in
|
|
357
|
+
* a variable is a reusable prefix: stepping off it twice builds two paths,
|
|
358
|
+
* and neither can be changed afterwards by the other.
|
|
359
|
+
*/
|
|
360
|
+
step(containerProperty: string, type: string, index?: number): ReferencePathStage<TAfterProperty>;
|
|
361
|
+
/** Name the leaf property and close the builder. */
|
|
362
|
+
property(property: string): TAfterProperty;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** Context terminal — `property()` closed the chain; build the context. */
|
|
366
|
+
export interface ReferenceContextBuildStage {
|
|
367
|
+
build(): ReferenceContext;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Request value stage — the value is mandatory before {@link ReferenceRequestBuildStage.build}. */
|
|
371
|
+
export interface ReferenceRequestValueStage {
|
|
372
|
+
value(value: string): ReferenceRequestBuildStage;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/** Request terminal — build the request. */
|
|
376
|
+
export interface ReferenceRequestBuildStage {
|
|
377
|
+
build(): ReferenceRequest;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Shared builder engine for both reference builders. Accumulates the source
|
|
382
|
+
* and the synthetic path, then hands the assembled {@link ReferenceContext} to
|
|
383
|
+
* `onProperty`, which produces the builder-specific terminal stage.
|
|
384
|
+
*
|
|
385
|
+
* **Persistent, not accumulating.** Each `step()` returns a NEW stage over a
|
|
386
|
+
* copied path, and `property()` copies again into the context it emits. A
|
|
387
|
+
* mutable builder would make a held stage a shared cursor — two branches off it
|
|
388
|
+
* would build one path between them, and two contexts built from it would alias
|
|
389
|
+
* a single array that a later `step()` could still change underneath both.
|
|
390
|
+
* Copying a path of two or three entries costs nothing next to a scope query.
|
|
391
|
+
*/
|
|
392
|
+
function referenceBuilder<TAfterProperty>(onProperty: (context: ReferenceContext) => TAfterProperty): ReferenceSourceStage<TAfterProperty> {
|
|
393
|
+
const pathStageFor = (source: ReferenceSource, steps: readonly SyntheticStep[]): ReferencePathStage<TAfterProperty> => ({
|
|
394
|
+
step(containerProperty, type, index) {
|
|
395
|
+
return pathStageFor(source, [...steps, { containerProperty, type, index }]);
|
|
396
|
+
},
|
|
397
|
+
property(property) {
|
|
398
|
+
return onProperty(steps.length > 0 ? { source, property, syntheticPath: [...steps] } : { source, property });
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
return {
|
|
402
|
+
document: uri => pathStageFor({ uri }, []),
|
|
403
|
+
element: (name, type) => pathStageFor({ name, type }, []),
|
|
404
|
+
synthetic: (uri, type) => pathStageFor({ uri, type }, [])
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export namespace ReferenceContext {
|
|
409
|
+
/** Staged builder entry — `source -> path -> property -> build`. */
|
|
410
|
+
export function builder(): ReferenceSourceStage<ReferenceContextBuildStage> {
|
|
411
|
+
return referenceBuilder(context => ({ build: () => context }));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export namespace ReferenceRequest {
|
|
416
|
+
/** Staged builder entry — `source -> path -> property -> value -> build`. */
|
|
417
|
+
export function builder(): ReferenceSourceStage<ReferenceRequestValueStage> {
|
|
418
|
+
return referenceBuilder(context => ({
|
|
419
|
+
value: (value: string) => ({ build: () => ({ ...context, value }) })
|
|
420
|
+
}));
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Promote a {@link ReferenceContext} to a request using a selected
|
|
425
|
+
* candidate's value — the find -> select -> resolve flow. The candidate
|
|
426
|
+
* supplies only the value (it is target-side); the source / property /
|
|
427
|
+
* synthetic path come from the context the candidates were listed for.
|
|
428
|
+
* Accepts any {@link ReferenceCandidate} (a `ReferenceTarget` works too).
|
|
429
|
+
*/
|
|
430
|
+
export function from(context: ReferenceContext, candidate: ReferenceCandidate): ReferenceRequest {
|
|
431
|
+
return { ...context, value: candidate.value };
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Naming tier for `findNextName`-style lookups — which uniqueness
|
|
437
|
+
* scope a proposed name must be unique within. This is NOT the
|
|
438
|
+
* name-qualification axis, which decides how a name is spelled; the two are
|
|
439
|
+
* independent even though each spells two of its members `local` and
|
|
440
|
+
* `project`, and conflating them reads as an argument to rename `tier`.
|
|
441
|
+
*
|
|
442
|
+
* - `'local'` — unique within the document (the document root is the
|
|
443
|
+
* uniqueness container).
|
|
444
|
+
* - `'project'` — unique within the owning project's document-qualified
|
|
445
|
+
* namespace.
|
|
446
|
+
* - `'public'` — unique within the project-qualified (cross-project)
|
|
447
|
+
* namespace.
|
|
448
|
+
*/
|
|
449
|
+
export type NameTier = 'local' | 'project' | 'public';
|
|
450
|
+
|
|
451
|
+
/** Arguments for a next-free-name lookup. */
|
|
452
|
+
export interface FindNextNameArgs {
|
|
453
|
+
/**
|
|
454
|
+
* Locates the document, and via its project the qualification context. The
|
|
455
|
+
* create-element flow is the main caller, so this may name a document that
|
|
456
|
+
* does not exist yet; only the `'local'` tier needs it to resolve to one.
|
|
457
|
+
*/
|
|
458
|
+
uri: string;
|
|
459
|
+
/**
|
|
460
|
+
* The AST `$type` of the element being named. Collisions are only looked for
|
|
461
|
+
* among elements of that same type, so the returned name may still be taken
|
|
462
|
+
* by an element of another type.
|
|
463
|
+
*/
|
|
464
|
+
type: string;
|
|
465
|
+
/**
|
|
466
|
+
* The desired base name, returned unchanged when it is already free and
|
|
467
|
+
* otherwise used as the stem a suffix is appended to. Any occurrence of the
|
|
468
|
+
* name separator is replaced first, so a proposal cannot smuggle in a
|
|
469
|
+
* qualified name.
|
|
470
|
+
*/
|
|
471
|
+
proposal: string;
|
|
472
|
+
/**
|
|
473
|
+
* Which uniqueness scope the returned name must be free in — how wide a net
|
|
474
|
+
* to check for collisions. The result is always a bare own-name whatever the
|
|
475
|
+
* tier; this never changes how the name is spelled. Defaults to `'project'`.
|
|
476
|
+
* See {@link NameTier} for what each tier covers.
|
|
477
|
+
*/
|
|
478
|
+
tier?: NameTier;
|
|
479
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
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
|
+
/**
|
|
11
|
+
* Argument shapes for the in-process `ModelService` facade — the
|
|
12
|
+
* canonical home for the lifecycle operation signatures. Implementation
|
|
13
|
+
* lives in `@hydranium/core/langium/model-service`; this protocol
|
|
14
|
+
* package owns the types so wire-side projections (the data-server
|
|
15
|
+
* protocol in `./data`) can structurally extend them rather than
|
|
16
|
+
* mirroring them by hand.
|
|
17
|
+
*
|
|
18
|
+
* `./model-server.ts` re-exports them, so an import from either path
|
|
19
|
+
* resolves.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** Identifies a client-document binding. Every facade operation carries these fields. */
|
|
23
|
+
export interface TransferClientArgs {
|
|
24
|
+
/** Document URI. */
|
|
25
|
+
uri: string;
|
|
26
|
+
/** Stable identifier for the client invoking the operation. */
|
|
27
|
+
clientId: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Update a document's content via the in-process facade. `model` may be
|
|
32
|
+
* the structured (transfer-model or AST) root or its serialised textual
|
|
33
|
+
* form — implementations decide which is faster on their transport.
|
|
34
|
+
* Generic over `T` so adopters parameterise the structured shape against
|
|
35
|
+
* their grammar's transfer-model overlay; passing a string is always
|
|
36
|
+
* allowed.
|
|
37
|
+
*/
|
|
38
|
+
export interface TransferUpdateArgs<T> extends TransferClientArgs {
|
|
39
|
+
/** Structured model root or its serialised textual form. */
|
|
40
|
+
model: T | string;
|
|
41
|
+
/**
|
|
42
|
+
* Optional based-on version: the text-document version this update
|
|
43
|
+
* was authored against. When set, the server compares against its
|
|
44
|
+
* current text-document version for `uri` and throws
|
|
45
|
+
* `ConflictError` on mismatch. Omit to opt out of the gate — mirrors
|
|
46
|
+
* LSP's `OptionalVersionedTextDocumentIdentifier` posture, intended
|
|
47
|
+
* for headless / CLI / batch tooling without a meaningful based-on
|
|
48
|
+
* version.
|
|
49
|
+
*/
|
|
50
|
+
baseVersion?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Persist a document to disk via the in-process facade. Same `model`
|
|
55
|
+
* shape as {@link TransferUpdateArgs}.
|
|
56
|
+
*/
|
|
57
|
+
export interface TransferSaveArgs<T> extends TransferClientArgs {
|
|
58
|
+
/** Structured model root or its serialised textual form. */
|
|
59
|
+
model: T | string;
|
|
60
|
+
/**
|
|
61
|
+
* Optional based-on version — same semantics as
|
|
62
|
+
* {@link TransferUpdateArgs.baseVersion}. `save` delegates the gating
|
|
63
|
+
* check to its inner `update`, so this field threads through to the
|
|
64
|
+
* same `ConflictError` site.
|
|
65
|
+
*/
|
|
66
|
+
baseVersion?: number;
|
|
67
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
// Subpath barrel for the in-process `ModelService` facade contract. The
|
|
11
|
+
// implementation lives in `@hydranium/core`; this package owns the
|
|
12
|
+
// argument types so both the framework facade and the data-server wire
|
|
13
|
+
// protocol can structurally agree on the lifecycle shape.
|
|
14
|
+
|
|
15
|
+
export * from './args';
|
|
16
|
+
export * from './reference-candidate';
|
|
@@ -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
|
+
import type { TransferElement } from '../transfer-element';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* UI-facing descriptor of an AST element that may be assigned as the value
|
|
14
|
+
* of a reference. Carries the URI of the owning document, the AST type, the
|
|
15
|
+
* display label, and the persisted reference value.
|
|
16
|
+
*
|
|
17
|
+
* Produced by the reference-candidate pipeline in `@hydranium/core`
|
|
18
|
+
* (`ReferenceCandidateProvider.find`). Consumed by UI surfaces —
|
|
19
|
+
* command-palettes, drop-target action providers, completion popups — that
|
|
20
|
+
* present ranked, deduped reference candidates to the user.
|
|
21
|
+
*
|
|
22
|
+
* **Why two label fields**: `label` is what the user sees in the dropdown;
|
|
23
|
+
* `value` is what gets persisted as the reference's `$refText` when the
|
|
24
|
+
* user selects this element. Separating them lets the server present a
|
|
25
|
+
* human-readable display name (e.g. `node.name`) while storing the
|
|
26
|
+
* canonical reference identifier (e.g. `node.id`). Both fields are
|
|
27
|
+
* required — producers without a display/value distinction set the same
|
|
28
|
+
* string in both, so consumers never need to remember a fallback rule.
|
|
29
|
+
*/
|
|
30
|
+
export interface ReferenceCandidate {
|
|
31
|
+
/** URI of the document declaring the referenced element. */
|
|
32
|
+
uri: string;
|
|
33
|
+
/** AST `$type` of the referenced element — useful for icon dispatch. */
|
|
34
|
+
type: string;
|
|
35
|
+
/** Display label shown to the user in dropdowns and chips. */
|
|
36
|
+
label: string;
|
|
37
|
+
/** String stored as `$refText` when the user selects this element. */
|
|
38
|
+
value: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Result of resolving a `ReferenceRequest` to its target — a
|
|
43
|
+
* {@link ReferenceCandidate} plus the resolved node's transfer subtree.
|
|
44
|
+
*
|
|
45
|
+
* A candidate and a target are the same kind of thing (an addressable
|
|
46
|
+
* reference target): `find` lists candidates, `resolveReference` returns the
|
|
47
|
+
* one a value matched. The target additionally carries `element` because it
|
|
48
|
+
* is a single result that can afford the payload, where candidates come as a
|
|
49
|
+
* list and stay lightweight. The encoded `element` is just the resolved
|
|
50
|
+
* node's subtree, NOT the whole document root — callers that want the full
|
|
51
|
+
* document fetch it via `getModelDocument(uri)`.
|
|
52
|
+
*
|
|
53
|
+
* Generic over the transfer root type so adopters get their typed overlay.
|
|
54
|
+
*/
|
|
55
|
+
export interface ReferenceTarget<TTransfer extends TransferElement = TransferElement> extends ReferenceCandidate {
|
|
56
|
+
/** The resolved target node, encoded as a transfer subtree. */
|
|
57
|
+
element: TTransfer;
|
|
58
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
import { AbstractLogger } from './abstract-logger';
|
|
11
|
+
import { type LogLevel, type Logger } from './logger';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* {@link Logger} implementation that discards every message. Intended for
|
|
15
|
+
* programmatic / in-process consumers (test harnesses, non-LSP hosts) that
|
|
16
|
+
* use the framework services but don't have a vscode-jsonrpc connection to
|
|
17
|
+
* forward log output through.
|
|
18
|
+
*
|
|
19
|
+
* Chaining methods (`for`, `sub`, `with`) return a noop instance of the same
|
|
20
|
+
* class; `withUri` short-circuits to the same instance.
|
|
21
|
+
*/
|
|
22
|
+
export class NoopLogger extends AbstractLogger implements Logger {
|
|
23
|
+
protected emit(_level: LogLevel, _label: string, _message: string, _args: readonly unknown[]): void {
|
|
24
|
+
// noop — every message is discarded.
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override withUri(_uri: string): this {
|
|
28
|
+
// Composing a no-op label is wasted work — return the same instance.
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected derive(component: string): this {
|
|
33
|
+
const Subclass = this.constructor as new (component?: string) => this;
|
|
34
|
+
return new Subclass(component);
|
|
35
|
+
}
|
|
36
|
+
}
|