websocket-text-relay 1.1.2 → 1.1.3
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/.prettierignore +3 -0
- package/.prettierrc +4 -0
- package/changelog.md +7 -0
- package/docs/code-structure.md +1 -1
- package/eslint.config.js +28 -0
- package/package.json +15 -10
- package/{index.js → src/index.js} +23 -21
- package/src/language-server/JsonRpcInterface.js +59 -29
- package/src/language-server/JsonRpcInterface.test.js +102 -72
- package/src/language-server/LspReader.js +30 -20
- package/src/language-server/LspReader.test.js +147 -65
- package/src/language-server/LspWriter.js +5 -5
- package/src/language-server/LspWriter.test.js +31 -24
- package/src/ui/css/fonts.css +0 -1
- package/src/ui/css/main.css +7 -7
- package/src/ui/index.html +4 -4
- package/src/ui/js/components/ActivityTimeseriesGraph.js +83 -32
- package/src/ui/js/components/HeaderSummary.js +11 -5
- package/src/ui/js/components/ServerStatus.js +19 -7
- package/src/ui/js/components/SessionLabels.js +197 -49
- package/src/ui/js/components/SessionWedges.js +44 -24
- package/src/ui/js/components/StatusRing.js +20 -8
- package/src/ui/js/components/grids.js +14 -7
- package/src/ui/js/index.js +23 -19
- package/src/ui/js/main.js +53 -21
- package/src/ui/js/util/DependencyManager.js +5 -5
- package/src/ui/js/util/EventEmitter.js +11 -7
- package/src/ui/js/util/WebsocketClient.js +28 -22
- package/src/ui/js/util/constants.js +2 -2
- package/src/ui/js/util/drawing.js +58 -28
- package/src/websocket-interface/WebsocketClient.js +15 -15
- package/src/websocket-interface/WebsocketInterface.js +30 -22
- package/src/websocket-interface/WtrSession.js +49 -33
- package/src/websocket-interface/httpServer.js +11 -10
- package/src/websocket-interface/sessionManager.js +16 -13
- package/src/websocket-interface/util.js +1 -1
- package/src/websocket-interface/websocketApi.js +51 -34
- package/src/websocket-interface/websocketServer.js +9 -9
- package/start.js +1 -1
- package/.eslintrc +0 -29
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
import { PassThrough } from
|
|
1
|
+
import { PassThrough } from "node:stream"
|
|
2
2
|
import { describe, it, expect, beforeAll } from "vitest"
|
|
3
|
-
import { LspReader } from
|
|
4
|
-
import { parseErrorCode, parseHeaderErrorMessage, parseJsonErrorMessage } from
|
|
3
|
+
import { LspReader } from "./LspReader.js"
|
|
4
|
+
import { parseErrorCode, parseHeaderErrorMessage, parseJsonErrorMessage } from "./constants.js"
|
|
5
5
|
|
|
6
6
|
describe("LspReader", () => {
|
|
7
7
|
describe("simple case", () => {
|
|
8
8
|
describe("when a message comes through the input stream", () => {
|
|
9
9
|
const inputData = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`
|
|
10
|
-
const expectedMessageObj = {
|
|
10
|
+
const expectedMessageObj = {
|
|
11
|
+
jsonrpc: "2.0",
|
|
12
|
+
id: "0",
|
|
13
|
+
method: "test/test-method",
|
|
14
|
+
params: { a: "1" },
|
|
15
|
+
}
|
|
11
16
|
let actualMessageObj
|
|
12
17
|
|
|
13
18
|
beforeAll(() => {
|
|
14
19
|
const inputStream = new PassThrough()
|
|
15
20
|
const lspReader = new LspReader()
|
|
16
21
|
inputStream.pipe(lspReader)
|
|
17
|
-
lspReader.on(
|
|
22
|
+
lspReader.on("data", (message) => {
|
|
18
23
|
actualMessageObj = message
|
|
19
24
|
})
|
|
20
25
|
inputStream.write(inputData)
|
|
@@ -27,14 +32,19 @@ describe("LspReader", () => {
|
|
|
27
32
|
|
|
28
33
|
describe("when content-length header isn't capitalized", () => {
|
|
29
34
|
const inputData = `content-length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`
|
|
30
|
-
const expectedMessageObj = {
|
|
35
|
+
const expectedMessageObj = {
|
|
36
|
+
jsonrpc: "2.0",
|
|
37
|
+
id: "0",
|
|
38
|
+
method: "test/test-method",
|
|
39
|
+
params: { a: "1" },
|
|
40
|
+
}
|
|
31
41
|
let actualMessageObj
|
|
32
42
|
|
|
33
43
|
beforeAll(() => {
|
|
34
44
|
const inputStream = new PassThrough()
|
|
35
45
|
const lspReader = new LspReader()
|
|
36
46
|
inputStream.pipe(lspReader)
|
|
37
|
-
lspReader.on(
|
|
47
|
+
lspReader.on("data", (message) => {
|
|
38
48
|
actualMessageObj = message
|
|
39
49
|
})
|
|
40
50
|
inputStream.write(inputData)
|
|
@@ -49,7 +59,7 @@ describe("LspReader", () => {
|
|
|
49
59
|
describe("error cases", () => {
|
|
50
60
|
describe("when Content-Length header is missing", () => {
|
|
51
61
|
const inputData = `Bad-Header: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`
|
|
52
|
-
const expectedError = {code: parseErrorCode, message: parseHeaderErrorMessage}
|
|
62
|
+
const expectedError = { code: parseErrorCode, message: parseHeaderErrorMessage }
|
|
53
63
|
let actualMessageObj = null
|
|
54
64
|
let actualError
|
|
55
65
|
|
|
@@ -57,10 +67,10 @@ describe("LspReader", () => {
|
|
|
57
67
|
const inputStream = new PassThrough()
|
|
58
68
|
const lspReader = new LspReader()
|
|
59
69
|
inputStream.pipe(lspReader)
|
|
60
|
-
lspReader.on(
|
|
70
|
+
lspReader.on("data", (message) => {
|
|
61
71
|
actualMessageObj = message
|
|
62
72
|
})
|
|
63
|
-
lspReader.on(
|
|
73
|
+
lspReader.on("parse-error", (error) => {
|
|
64
74
|
actualError = error
|
|
65
75
|
})
|
|
66
76
|
inputStream.write(inputData)
|
|
@@ -78,10 +88,15 @@ describe("LspReader", () => {
|
|
|
78
88
|
describe("when recovering from a bad header error", () => {
|
|
79
89
|
const inputData = [
|
|
80
90
|
`Bad-Header: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
81
|
-
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}
|
|
91
|
+
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}`,
|
|
82
92
|
]
|
|
83
|
-
const expectedError = {code: parseErrorCode, message: parseHeaderErrorMessage}
|
|
84
|
-
const expectedObject = {
|
|
93
|
+
const expectedError = { code: parseErrorCode, message: parseHeaderErrorMessage }
|
|
94
|
+
const expectedObject = {
|
|
95
|
+
jsonrpc: "2.0",
|
|
96
|
+
id: "1",
|
|
97
|
+
method: "test/test-method",
|
|
98
|
+
params: { b: "2" },
|
|
99
|
+
}
|
|
85
100
|
let actualMessageObjs = []
|
|
86
101
|
let actualErrors = []
|
|
87
102
|
|
|
@@ -89,10 +104,10 @@ describe("LspReader", () => {
|
|
|
89
104
|
const inputStream = new PassThrough()
|
|
90
105
|
const lspReader = new LspReader()
|
|
91
106
|
inputStream.pipe(lspReader)
|
|
92
|
-
lspReader.on(
|
|
107
|
+
lspReader.on("data", (message) => {
|
|
93
108
|
actualMessageObjs.push(message)
|
|
94
109
|
})
|
|
95
|
-
lspReader.on(
|
|
110
|
+
lspReader.on("parse-error", (error) => {
|
|
96
111
|
actualErrors.push(error)
|
|
97
112
|
})
|
|
98
113
|
inputData.forEach((data) => {
|
|
@@ -114,10 +129,15 @@ describe("LspReader", () => {
|
|
|
114
129
|
describe("when recovering from an invalid JSON error", () => {
|
|
115
130
|
const inputData = [
|
|
116
131
|
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}>`,
|
|
117
|
-
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}
|
|
132
|
+
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}`,
|
|
118
133
|
]
|
|
119
|
-
const expectedError = {code: parseErrorCode, message: parseJsonErrorMessage}
|
|
120
|
-
const expectedObject = {
|
|
134
|
+
const expectedError = { code: parseErrorCode, message: parseJsonErrorMessage }
|
|
135
|
+
const expectedObject = {
|
|
136
|
+
jsonrpc: "2.0",
|
|
137
|
+
id: "1",
|
|
138
|
+
method: "test/test-method",
|
|
139
|
+
params: { b: "2" },
|
|
140
|
+
}
|
|
121
141
|
let actualMessageObjs = []
|
|
122
142
|
let actualErrors = []
|
|
123
143
|
|
|
@@ -125,10 +145,10 @@ describe("LspReader", () => {
|
|
|
125
145
|
const inputStream = new PassThrough()
|
|
126
146
|
const lspReader = new LspReader()
|
|
127
147
|
inputStream.pipe(lspReader)
|
|
128
|
-
lspReader.on(
|
|
148
|
+
lspReader.on("data", (message) => {
|
|
129
149
|
actualMessageObjs.push(message)
|
|
130
150
|
})
|
|
131
|
-
lspReader.on(
|
|
151
|
+
lspReader.on("parse-error", (error) => {
|
|
132
152
|
actualErrors.push(error)
|
|
133
153
|
})
|
|
134
154
|
inputData.forEach((data) => {
|
|
@@ -149,7 +169,7 @@ describe("LspReader", () => {
|
|
|
149
169
|
|
|
150
170
|
describe("when JSON is invalid", () => {
|
|
151
171
|
const inputData = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}>`
|
|
152
|
-
const expectedError = {code: parseErrorCode, message: parseJsonErrorMessage}
|
|
172
|
+
const expectedError = { code: parseErrorCode, message: parseJsonErrorMessage }
|
|
153
173
|
let actualMessageObj = null
|
|
154
174
|
let actualError
|
|
155
175
|
|
|
@@ -157,10 +177,10 @@ describe("LspReader", () => {
|
|
|
157
177
|
const inputStream = new PassThrough()
|
|
158
178
|
const lspReader = new LspReader()
|
|
159
179
|
inputStream.pipe(lspReader)
|
|
160
|
-
lspReader.on(
|
|
180
|
+
lspReader.on("data", (message) => {
|
|
161
181
|
actualMessageObj = message
|
|
162
182
|
})
|
|
163
|
-
lspReader.on(
|
|
183
|
+
lspReader.on("parse-error", (error) => {
|
|
164
184
|
actualError = error
|
|
165
185
|
})
|
|
166
186
|
inputStream.write(inputData)
|
|
@@ -178,8 +198,16 @@ describe("LspReader", () => {
|
|
|
178
198
|
|
|
179
199
|
describe("single message buffering cases", () => {
|
|
180
200
|
describe("when the message is split in the middle of the header", () => {
|
|
181
|
-
const inputData = [
|
|
182
|
-
|
|
201
|
+
const inputData = [
|
|
202
|
+
`Content-Len`,
|
|
203
|
+
`gth: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
204
|
+
]
|
|
205
|
+
const expectedMessageObj = {
|
|
206
|
+
jsonrpc: "2.0",
|
|
207
|
+
id: "0",
|
|
208
|
+
method: "test/test-method",
|
|
209
|
+
params: { a: "1" },
|
|
210
|
+
}
|
|
183
211
|
let actualMessageObj
|
|
184
212
|
let actualError = null
|
|
185
213
|
|
|
@@ -187,10 +215,10 @@ describe("LspReader", () => {
|
|
|
187
215
|
const inputStream = new PassThrough()
|
|
188
216
|
const lspReader = new LspReader()
|
|
189
217
|
inputStream.pipe(lspReader)
|
|
190
|
-
lspReader.on(
|
|
218
|
+
lspReader.on("data", (message) => {
|
|
191
219
|
actualMessageObj = message
|
|
192
220
|
})
|
|
193
|
-
lspReader.on(
|
|
221
|
+
lspReader.on("parse-error", (error) => {
|
|
194
222
|
actualError = error
|
|
195
223
|
})
|
|
196
224
|
|
|
@@ -209,8 +237,23 @@ describe("LspReader", () => {
|
|
|
209
237
|
})
|
|
210
238
|
|
|
211
239
|
describe("when the message is split in the middle of the header many times", () => {
|
|
212
|
-
const inputData = [
|
|
213
|
-
|
|
240
|
+
const inputData = [
|
|
241
|
+
`Cont`,
|
|
242
|
+
`ent-L`,
|
|
243
|
+
`en`,
|
|
244
|
+
`gth`,
|
|
245
|
+
`: 7`,
|
|
246
|
+
`3\r`,
|
|
247
|
+
`\n`,
|
|
248
|
+
`\r\n`,
|
|
249
|
+
`{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
250
|
+
]
|
|
251
|
+
const expectedMessageObj = {
|
|
252
|
+
jsonrpc: "2.0",
|
|
253
|
+
id: "0",
|
|
254
|
+
method: "test/test-method",
|
|
255
|
+
params: { a: "1" },
|
|
256
|
+
}
|
|
214
257
|
let actualMessageObj
|
|
215
258
|
let actualError = null
|
|
216
259
|
|
|
@@ -218,10 +261,10 @@ describe("LspReader", () => {
|
|
|
218
261
|
const inputStream = new PassThrough()
|
|
219
262
|
const lspReader = new LspReader()
|
|
220
263
|
inputStream.pipe(lspReader)
|
|
221
|
-
lspReader.on(
|
|
264
|
+
lspReader.on("data", (message) => {
|
|
222
265
|
actualMessageObj = message
|
|
223
266
|
})
|
|
224
|
-
lspReader.on(
|
|
267
|
+
lspReader.on("parse-error", (error) => {
|
|
225
268
|
actualError = error
|
|
226
269
|
})
|
|
227
270
|
|
|
@@ -240,8 +283,16 @@ describe("LspReader", () => {
|
|
|
240
283
|
})
|
|
241
284
|
|
|
242
285
|
describe("when the message is split in the middle of the JSON", () => {
|
|
243
|
-
const inputData = [
|
|
244
|
-
|
|
286
|
+
const inputData = [
|
|
287
|
+
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0",`,
|
|
288
|
+
`"id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
289
|
+
]
|
|
290
|
+
const expectedMessageObj = {
|
|
291
|
+
jsonrpc: "2.0",
|
|
292
|
+
id: "0",
|
|
293
|
+
method: "test/test-method",
|
|
294
|
+
params: { a: "1" },
|
|
295
|
+
}
|
|
245
296
|
let actualMessageObj
|
|
246
297
|
let actualError = null
|
|
247
298
|
|
|
@@ -249,10 +300,10 @@ describe("LspReader", () => {
|
|
|
249
300
|
const inputStream = new PassThrough()
|
|
250
301
|
const lspReader = new LspReader()
|
|
251
302
|
inputStream.pipe(lspReader)
|
|
252
|
-
lspReader.on(
|
|
303
|
+
lspReader.on("data", (message) => {
|
|
253
304
|
actualMessageObj = message
|
|
254
305
|
})
|
|
255
|
-
lspReader.on(
|
|
306
|
+
lspReader.on("parse-error", (error) => {
|
|
256
307
|
actualError = error
|
|
257
308
|
})
|
|
258
309
|
|
|
@@ -271,8 +322,26 @@ describe("LspReader", () => {
|
|
|
271
322
|
})
|
|
272
323
|
|
|
273
324
|
describe("when the message is split in the middle of the header and JSON many times", () => {
|
|
274
|
-
const inputData = [
|
|
275
|
-
|
|
325
|
+
const inputData = [
|
|
326
|
+
`Con`,
|
|
327
|
+
`tent-Len`,
|
|
328
|
+
`gth: 73\r`,
|
|
329
|
+
`\n`,
|
|
330
|
+
`\r\n`,
|
|
331
|
+
`{`,
|
|
332
|
+
`"jso`,
|
|
333
|
+
`nrpc":"2.0"`,
|
|
334
|
+
`,"id":"0","method":"te`,
|
|
335
|
+
`st/test-method","params":{"a":`,
|
|
336
|
+
`"1"}`,
|
|
337
|
+
`}`,
|
|
338
|
+
]
|
|
339
|
+
const expectedMessageObj = {
|
|
340
|
+
jsonrpc: "2.0",
|
|
341
|
+
id: "0",
|
|
342
|
+
method: "test/test-method",
|
|
343
|
+
params: { a: "1" },
|
|
344
|
+
}
|
|
276
345
|
let actualMessageObj
|
|
277
346
|
let actualError = null
|
|
278
347
|
|
|
@@ -280,10 +349,10 @@ describe("LspReader", () => {
|
|
|
280
349
|
const inputStream = new PassThrough()
|
|
281
350
|
const lspReader = new LspReader()
|
|
282
351
|
inputStream.pipe(lspReader)
|
|
283
|
-
lspReader.on(
|
|
352
|
+
lspReader.on("data", (message) => {
|
|
284
353
|
actualMessageObj = message
|
|
285
354
|
})
|
|
286
|
-
lspReader.on(
|
|
355
|
+
lspReader.on("parse-error", (error) => {
|
|
287
356
|
actualError = error
|
|
288
357
|
})
|
|
289
358
|
|
|
@@ -305,17 +374,22 @@ describe("LspReader", () => {
|
|
|
305
374
|
describe("when the buffer needs resizing", () => {
|
|
306
375
|
describe("when a message larger than the buffer size comes through the input stream", () => {
|
|
307
376
|
const inputData = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`
|
|
308
|
-
const expectedMessageObj = {
|
|
377
|
+
const expectedMessageObj = {
|
|
378
|
+
jsonrpc: "2.0",
|
|
379
|
+
id: "0",
|
|
380
|
+
method: "test/test-method",
|
|
381
|
+
params: { a: "1" },
|
|
382
|
+
}
|
|
309
383
|
let lspReader
|
|
310
384
|
let actualMessageObj
|
|
311
385
|
let actualInitialBufferSize
|
|
312
386
|
|
|
313
387
|
beforeAll(() => {
|
|
314
388
|
const inputStream = new PassThrough()
|
|
315
|
-
lspReader = new LspReader({initialBufferSize: 10})
|
|
389
|
+
lspReader = new LspReader({ initialBufferSize: 10 })
|
|
316
390
|
actualInitialBufferSize = lspReader.buffer.length
|
|
317
391
|
inputStream.pipe(lspReader)
|
|
318
|
-
lspReader.on(
|
|
392
|
+
lspReader.on("data", (message) => {
|
|
319
393
|
actualMessageObj = message
|
|
320
394
|
})
|
|
321
395
|
inputStream.write(inputData)
|
|
@@ -339,8 +413,16 @@ describe("LspReader", () => {
|
|
|
339
413
|
})
|
|
340
414
|
|
|
341
415
|
describe("when a buffer that already has data needs resizing", () => {
|
|
342
|
-
const inputData = [
|
|
343
|
-
|
|
416
|
+
const inputData = [
|
|
417
|
+
`Content-Len`,
|
|
418
|
+
`gth: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
419
|
+
]
|
|
420
|
+
const expectedMessageObj = {
|
|
421
|
+
jsonrpc: "2.0",
|
|
422
|
+
id: "0",
|
|
423
|
+
method: "test/test-method",
|
|
424
|
+
params: { a: "1" },
|
|
425
|
+
}
|
|
344
426
|
let actualMessageObj
|
|
345
427
|
let lspReader
|
|
346
428
|
let actualInitialBufferSize
|
|
@@ -348,13 +430,13 @@ describe("LspReader", () => {
|
|
|
348
430
|
|
|
349
431
|
beforeAll(() => {
|
|
350
432
|
const inputStream = new PassThrough()
|
|
351
|
-
lspReader = new LspReader({initialBufferSize: 70})
|
|
433
|
+
lspReader = new LspReader({ initialBufferSize: 70 })
|
|
352
434
|
actualInitialBufferSize = lspReader.buffer.length
|
|
353
435
|
inputStream.pipe(lspReader)
|
|
354
|
-
lspReader.on(
|
|
436
|
+
lspReader.on("data", (message) => {
|
|
355
437
|
actualMessageObj = message
|
|
356
438
|
})
|
|
357
|
-
lspReader.on(
|
|
439
|
+
lspReader.on("parse-error", (error) => {
|
|
358
440
|
actualError = error
|
|
359
441
|
})
|
|
360
442
|
|
|
@@ -390,13 +472,13 @@ describe("LspReader", () => {
|
|
|
390
472
|
const inputData = [
|
|
391
473
|
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
392
474
|
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}`,
|
|
393
|
-
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}
|
|
475
|
+
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}`,
|
|
394
476
|
]
|
|
395
477
|
|
|
396
478
|
const expectedMessageObjs = [
|
|
397
|
-
{
|
|
398
|
-
{
|
|
399
|
-
{
|
|
479
|
+
{ jsonrpc: "2.0", id: "0", method: "test/test-method", params: { a: "1" } },
|
|
480
|
+
{ jsonrpc: "2.0", id: "1", method: "test/test-method", params: { b: "2" } },
|
|
481
|
+
{ jsonrpc: "2.0", id: "2", method: "test/test-method", params: { c: "3" } },
|
|
400
482
|
]
|
|
401
483
|
let actualMessageObjs = []
|
|
402
484
|
let actualError = null
|
|
@@ -405,10 +487,10 @@ describe("LspReader", () => {
|
|
|
405
487
|
const inputStream = new PassThrough()
|
|
406
488
|
const lspReader = new LspReader()
|
|
407
489
|
inputStream.pipe(lspReader)
|
|
408
|
-
lspReader.on(
|
|
490
|
+
lspReader.on("data", (message) => {
|
|
409
491
|
actualMessageObjs.push(message)
|
|
410
492
|
})
|
|
411
|
-
lspReader.on(
|
|
493
|
+
lspReader.on("parse-error", (error) => {
|
|
412
494
|
actualError = error
|
|
413
495
|
})
|
|
414
496
|
|
|
@@ -430,14 +512,14 @@ describe("LspReader", () => {
|
|
|
430
512
|
const inputDataMessages = [
|
|
431
513
|
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`,
|
|
432
514
|
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}`,
|
|
433
|
-
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}
|
|
515
|
+
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}`,
|
|
434
516
|
]
|
|
435
517
|
const inputData = inputDataMessages.join("")
|
|
436
518
|
|
|
437
519
|
const expectedMessageObjs = [
|
|
438
|
-
{
|
|
439
|
-
{
|
|
440
|
-
{
|
|
520
|
+
{ jsonrpc: "2.0", id: "0", method: "test/test-method", params: { a: "1" } },
|
|
521
|
+
{ jsonrpc: "2.0", id: "1", method: "test/test-method", params: { b: "2" } },
|
|
522
|
+
{ jsonrpc: "2.0", id: "2", method: "test/test-method", params: { c: "3" } },
|
|
441
523
|
]
|
|
442
524
|
let actualMessageObjs = []
|
|
443
525
|
let actualError = null
|
|
@@ -446,10 +528,10 @@ describe("LspReader", () => {
|
|
|
446
528
|
const inputStream = new PassThrough()
|
|
447
529
|
const lspReader = new LspReader()
|
|
448
530
|
inputStream.pipe(lspReader)
|
|
449
|
-
lspReader.on(
|
|
531
|
+
lspReader.on("data", (message) => {
|
|
450
532
|
actualMessageObjs.push(message)
|
|
451
533
|
})
|
|
452
|
-
lspReader.on(
|
|
534
|
+
lspReader.on("parse-error", (error) => {
|
|
453
535
|
actualError = error
|
|
454
536
|
})
|
|
455
537
|
|
|
@@ -469,13 +551,13 @@ describe("LspReader", () => {
|
|
|
469
551
|
describe("when the next message has an incomplete header", () => {
|
|
470
552
|
const inputData = [
|
|
471
553
|
`Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}Content-Lengt`,
|
|
472
|
-
`h: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}
|
|
554
|
+
`h: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}`,
|
|
473
555
|
]
|
|
474
556
|
|
|
475
557
|
const expectedMessageObjs = [
|
|
476
|
-
{
|
|
477
|
-
{
|
|
478
|
-
{
|
|
558
|
+
{ jsonrpc: "2.0", id: "0", method: "test/test-method", params: { a: "1" } },
|
|
559
|
+
{ jsonrpc: "2.0", id: "1", method: "test/test-method", params: { b: "2" } },
|
|
560
|
+
{ jsonrpc: "2.0", id: "2", method: "test/test-method", params: { c: "3" } },
|
|
479
561
|
]
|
|
480
562
|
let actualMessageObjs = []
|
|
481
563
|
let actualError = null
|
|
@@ -484,10 +566,10 @@ describe("LspReader", () => {
|
|
|
484
566
|
const inputStream = new PassThrough()
|
|
485
567
|
const lspReader = new LspReader()
|
|
486
568
|
inputStream.pipe(lspReader)
|
|
487
|
-
lspReader.on(
|
|
569
|
+
lspReader.on("data", (message) => {
|
|
488
570
|
actualMessageObjs.push(message)
|
|
489
571
|
})
|
|
490
|
-
lspReader.on(
|
|
572
|
+
lspReader.on("parse-error", (error) => {
|
|
491
573
|
actualError = error
|
|
492
574
|
})
|
|
493
575
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { headerKey } from
|
|
1
|
+
import { headerKey } from "./constants.js"
|
|
2
2
|
|
|
3
3
|
const jsonrpc = "2.0"
|
|
4
4
|
|
|
@@ -17,7 +17,7 @@ export const writeToOutput = (outputStream, messageObj) => {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const writeResponse = (outputStream, id, error, result) => {
|
|
20
|
-
const response = {jsonrpc, id}
|
|
20
|
+
const response = { jsonrpc, id }
|
|
21
21
|
if (error) {
|
|
22
22
|
response.error = error
|
|
23
23
|
} else {
|
|
@@ -27,18 +27,18 @@ export const writeResponse = (outputStream, id, error, result) => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export const writeNotification = (outputStream, method, params) => {
|
|
30
|
-
const message = {jsonrpc, method, params}
|
|
30
|
+
const message = { jsonrpc, method, params }
|
|
31
31
|
writeToOutput(outputStream, message)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
let requestId = 0
|
|
35
35
|
const nextRequestId = () => String(requestId++)
|
|
36
36
|
// only to be used for testing!
|
|
37
|
-
export const TESTONLY_resetRequestId = () => requestId = 0
|
|
37
|
+
export const TESTONLY_resetRequestId = () => (requestId = 0)
|
|
38
38
|
|
|
39
39
|
export const writeRequest = (outputStream, method, params) => {
|
|
40
40
|
const id = nextRequestId()
|
|
41
|
-
const request = {jsonrpc, id, method, params}
|
|
41
|
+
const request = { jsonrpc, id, method, params }
|
|
42
42
|
writeToOutput(outputStream, request)
|
|
43
43
|
return id
|
|
44
44
|
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { Writable } from
|
|
1
|
+
import { Writable } from "node:stream"
|
|
2
2
|
import { describe, it, expect, beforeAll } from "vitest"
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
TESTONLY_resetRequestId,
|
|
5
|
+
createHeader,
|
|
6
|
+
writeNotification,
|
|
7
|
+
writeRequest,
|
|
8
|
+
writeResponse,
|
|
9
|
+
writeToOutput,
|
|
10
|
+
} from "./LspWriter.js"
|
|
4
11
|
|
|
5
12
|
describe("LspWriter", () => {
|
|
6
13
|
describe("createHeader", () => {
|
|
@@ -15,7 +22,7 @@ describe("LspWriter", () => {
|
|
|
15
22
|
})
|
|
16
23
|
|
|
17
24
|
describe("With some content", () => {
|
|
18
|
-
const messageObj = {
|
|
25
|
+
const messageObj = { a: "1" }
|
|
19
26
|
const expectedHeader = "Content-Length: 9\r\n\r\n"
|
|
20
27
|
|
|
21
28
|
it("Should create header with correct length", () => {
|
|
@@ -25,7 +32,7 @@ describe("LspWriter", () => {
|
|
|
25
32
|
})
|
|
26
33
|
|
|
27
34
|
describe("With multi byte characters", () => {
|
|
28
|
-
const messageObj = {
|
|
35
|
+
const messageObj = { a: "🌊" }
|
|
29
36
|
const expectedHeader = "Content-Length: 12\r\n\r\n"
|
|
30
37
|
|
|
31
38
|
it("Should create header with correct byte length, not string length", () => {
|
|
@@ -37,16 +44,16 @@ describe("LspWriter", () => {
|
|
|
37
44
|
|
|
38
45
|
describe("writeToOutput", () => {
|
|
39
46
|
describe("simple object", () => {
|
|
40
|
-
const messageObj = {
|
|
47
|
+
const messageObj = { a: "1" }
|
|
41
48
|
const expectedOutput = `Content-Length: 9\r\n\r\n{"a":"1"}`
|
|
42
49
|
let actualOutput = ""
|
|
43
50
|
|
|
44
51
|
beforeAll(() => {
|
|
45
52
|
const outputStream = new Writable({
|
|
46
|
-
write
|
|
53
|
+
write(data, _enc, next) {
|
|
47
54
|
actualOutput += data.toString()
|
|
48
55
|
next()
|
|
49
|
-
}
|
|
56
|
+
},
|
|
50
57
|
})
|
|
51
58
|
writeToOutput(outputStream, messageObj)
|
|
52
59
|
})
|
|
@@ -59,17 +66,17 @@ describe("LspWriter", () => {
|
|
|
59
66
|
|
|
60
67
|
describe("writeResponse", () => {
|
|
61
68
|
describe("successful response", () => {
|
|
62
|
-
const result = {
|
|
69
|
+
const result = { a: "1" }
|
|
63
70
|
const error = null
|
|
64
71
|
const expectedOutput = `Content-Length: 45\r\n\r\n{"jsonrpc":"2.0","id":"0","result":{"a":"1"}}`
|
|
65
72
|
let actualOutput = ""
|
|
66
73
|
|
|
67
74
|
beforeAll(() => {
|
|
68
75
|
const outputStream = new Writable({
|
|
69
|
-
write
|
|
76
|
+
write(data, _enc, next) {
|
|
70
77
|
actualOutput += data.toString()
|
|
71
78
|
next()
|
|
72
|
-
}
|
|
79
|
+
},
|
|
73
80
|
})
|
|
74
81
|
writeResponse(outputStream, "0", error, result)
|
|
75
82
|
})
|
|
@@ -81,16 +88,16 @@ describe("LspWriter", () => {
|
|
|
81
88
|
|
|
82
89
|
describe("error response", () => {
|
|
83
90
|
const result = null
|
|
84
|
-
const error = {code: 1, message: "test error", data: {t: 5}}
|
|
91
|
+
const error = { code: 1, message: "test error", data: { t: 5 } }
|
|
85
92
|
const expectedOutput = `Content-Length: 83\r\n\r\n{"jsonrpc":"2.0","id":"0","error":{"code":1,"message":"test error","data":{"t":5}}}`
|
|
86
93
|
let actualOutput = ""
|
|
87
94
|
|
|
88
95
|
beforeAll(() => {
|
|
89
96
|
const outputStream = new Writable({
|
|
90
|
-
write
|
|
97
|
+
write(data, _enc, next) {
|
|
91
98
|
actualOutput += data.toString()
|
|
92
99
|
next()
|
|
93
|
-
}
|
|
100
|
+
},
|
|
94
101
|
})
|
|
95
102
|
writeResponse(outputStream, "0", error, result)
|
|
96
103
|
})
|
|
@@ -104,16 +111,16 @@ describe("LspWriter", () => {
|
|
|
104
111
|
describe("writeNotification", () => {
|
|
105
112
|
describe("simple parameters", () => {
|
|
106
113
|
const method = "test/test-method"
|
|
107
|
-
const parameters = {
|
|
114
|
+
const parameters = { a: "1" }
|
|
108
115
|
const expectedOutput = `Content-Length: 64\r\n\r\n{"jsonrpc":"2.0","method":"test/test-method","params":{"a":"1"}}`
|
|
109
116
|
let actualOutput = ""
|
|
110
117
|
|
|
111
118
|
beforeAll(() => {
|
|
112
119
|
const outputStream = new Writable({
|
|
113
|
-
write
|
|
120
|
+
write(data, _enc, next) {
|
|
114
121
|
actualOutput += data.toString()
|
|
115
122
|
next()
|
|
116
|
-
}
|
|
123
|
+
},
|
|
117
124
|
})
|
|
118
125
|
writeNotification(outputStream, method, parameters)
|
|
119
126
|
})
|
|
@@ -127,17 +134,17 @@ describe("LspWriter", () => {
|
|
|
127
134
|
describe("writeReqest", () => {
|
|
128
135
|
describe("single request", () => {
|
|
129
136
|
const method = "test/test-method"
|
|
130
|
-
const parameters = {
|
|
137
|
+
const parameters = { a: "1" }
|
|
131
138
|
const expectedOutput = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`
|
|
132
139
|
let actualOutput = ""
|
|
133
140
|
|
|
134
141
|
beforeAll(() => {
|
|
135
142
|
TESTONLY_resetRequestId()
|
|
136
143
|
const outputStream = new Writable({
|
|
137
|
-
write
|
|
144
|
+
write(data, _enc, next) {
|
|
138
145
|
actualOutput += data.toString()
|
|
139
146
|
next()
|
|
140
|
-
}
|
|
147
|
+
},
|
|
141
148
|
})
|
|
142
149
|
writeRequest(outputStream, method, parameters)
|
|
143
150
|
})
|
|
@@ -149,9 +156,9 @@ describe("LspWriter", () => {
|
|
|
149
156
|
|
|
150
157
|
describe("multiple requests", () => {
|
|
151
158
|
const method = "test/test-method"
|
|
152
|
-
const params1 = {
|
|
153
|
-
const params2 = {
|
|
154
|
-
const params3 = {
|
|
159
|
+
const params1 = { a: "1" }
|
|
160
|
+
const params2 = { b: "2" }
|
|
161
|
+
const params3 = { c: "3" }
|
|
155
162
|
const expectedOutput1 = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"0","method":"test/test-method","params":{"a":"1"}}`
|
|
156
163
|
const expectedOutput2 = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"1","method":"test/test-method","params":{"b":"2"}}`
|
|
157
164
|
const expectedOutput3 = `Content-Length: 73\r\n\r\n{"jsonrpc":"2.0","id":"2","method":"test/test-method","params":{"c":"3"}}`
|
|
@@ -161,10 +168,10 @@ describe("LspWriter", () => {
|
|
|
161
168
|
beforeAll(() => {
|
|
162
169
|
TESTONLY_resetRequestId()
|
|
163
170
|
const outputStream = new Writable({
|
|
164
|
-
write
|
|
171
|
+
write(data, _enc, next) {
|
|
165
172
|
actualOutput += data.toString()
|
|
166
173
|
next()
|
|
167
|
-
}
|
|
174
|
+
},
|
|
168
175
|
})
|
|
169
176
|
writeRequest(outputStream, method, params1)
|
|
170
177
|
writeRequest(outputStream, method, params2)
|
package/src/ui/css/fonts.css
CHANGED