@synnaxlabs/client 0.50.0 → 0.52.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/.turbo/turbo-build.log +7 -7
- package/dist/client.cjs +58 -34
- package/dist/client.js +5059 -4398
- package/dist/eslint.config.d.ts +2 -2
- package/dist/eslint.config.d.ts.map +1 -1
- package/dist/src/access/policy/client.d.ts +90 -90
- package/dist/src/access/policy/payload.d.ts +17 -17
- package/dist/src/access/role/payload.d.ts +2 -2
- package/dist/src/arc/payload.d.ts +2 -2
- package/dist/src/channel/client.d.ts +4 -5
- package/dist/src/channel/client.d.ts.map +1 -1
- package/dist/src/channel/payload.d.ts +9 -11
- package/dist/src/channel/payload.d.ts.map +1 -1
- package/dist/src/channel/retriever.d.ts.map +1 -1
- package/dist/src/client.d.ts +10 -0
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/device/client.d.ts +14 -7
- package/dist/src/device/client.d.ts.map +1 -1
- package/dist/src/device/payload.d.ts +65 -32
- package/dist/src/device/payload.d.ts.map +1 -1
- package/dist/src/device/payload.spec.d.ts +2 -0
- package/dist/src/device/payload.spec.d.ts.map +1 -0
- package/dist/src/framer/adapter.d.ts.map +1 -1
- package/dist/src/framer/client.d.ts +2 -2
- package/dist/src/framer/frame.d.ts +5 -5
- package/dist/src/framer/frame.d.ts.map +1 -1
- package/dist/src/framer/streamer.d.ts +6 -6
- package/dist/src/framer/writer.d.ts +9 -9
- package/dist/src/group/access.spec.d.ts.map +1 -0
- package/dist/src/{ontology/group → group}/client.d.ts +3 -3
- package/dist/src/group/client.d.ts.map +1 -0
- package/dist/src/group/external.d.ts.map +1 -0
- package/dist/src/group/group.spec.d.ts.map +1 -0
- package/dist/src/group/index.d.ts.map +1 -0
- package/dist/src/{ontology/group → group}/payload.d.ts +1 -1
- package/dist/src/group/payload.d.ts.map +1 -0
- package/dist/src/index.d.ts +5 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/label/client.d.ts +27 -13
- package/dist/src/label/client.d.ts.map +1 -1
- package/dist/src/label/payload.d.ts +15 -1
- package/dist/src/label/payload.d.ts.map +1 -1
- package/dist/src/lineplot/access.spec.d.ts.map +1 -0
- package/dist/src/{workspace/lineplot → lineplot}/client.d.ts +6 -6
- package/dist/src/lineplot/client.d.ts.map +1 -0
- package/dist/src/lineplot/external.d.ts.map +1 -0
- package/dist/src/lineplot/index.d.ts.map +1 -0
- package/dist/src/lineplot/lineplot.spec.d.ts.map +1 -0
- package/dist/src/lineplot/payload.d.ts.map +1 -0
- package/dist/src/log/access.spec.d.ts.map +1 -0
- package/dist/src/{workspace/log → log}/client.d.ts +6 -6
- package/dist/src/log/client.d.ts.map +1 -0
- package/dist/src/log/external.d.ts.map +1 -0
- package/dist/src/log/index.d.ts.map +1 -0
- package/dist/src/log/log.spec.d.ts.map +1 -0
- package/dist/src/log/payload.d.ts.map +1 -0
- package/dist/src/ontology/client.d.ts +6 -10
- package/dist/src/ontology/client.d.ts.map +1 -1
- package/dist/src/ontology/payload.d.ts +22 -22
- package/dist/src/ontology/writer.d.ts +15 -15
- package/dist/src/rack/client.d.ts +2 -2
- package/dist/src/rack/payload.d.ts +44 -16
- package/dist/src/rack/payload.d.ts.map +1 -1
- package/dist/src/ranger/alias/client.d.ts +17 -0
- package/dist/src/ranger/alias/client.d.ts.map +1 -0
- package/dist/src/ranger/alias/external.d.ts +2 -0
- package/dist/src/ranger/alias/external.d.ts.map +1 -0
- package/dist/src/ranger/alias/index.d.ts +2 -0
- package/dist/src/ranger/alias/index.d.ts.map +1 -0
- package/dist/src/ranger/{alias.d.ts → alias/payload.d.ts} +14 -20
- package/dist/src/ranger/alias/payload.d.ts.map +1 -0
- package/dist/src/ranger/client.d.ts +10 -10
- package/dist/src/ranger/client.d.ts.map +1 -1
- package/dist/src/ranger/external.d.ts +20 -0
- package/dist/src/ranger/external.d.ts.map +1 -1
- package/dist/src/ranger/kv/client.d.ts +14 -0
- package/dist/src/ranger/kv/client.d.ts.map +1 -0
- package/dist/src/ranger/kv/external.d.ts +2 -0
- package/dist/src/ranger/kv/external.d.ts.map +1 -0
- package/dist/src/ranger/kv/index.d.ts +2 -0
- package/dist/src/ranger/kv/index.d.ts.map +1 -0
- package/dist/src/ranger/kv/payload.d.ts +26 -0
- package/dist/src/ranger/kv/payload.d.ts.map +1 -0
- package/dist/src/ranger/payload.d.ts +45 -3
- package/dist/src/ranger/payload.d.ts.map +1 -1
- package/dist/src/ranger/writer.d.ts +18 -4
- package/dist/src/ranger/writer.d.ts.map +1 -1
- package/dist/src/schematic/access.spec.d.ts.map +1 -0
- package/dist/src/{workspace/schematic → schematic}/client.d.ts +6 -6
- package/dist/src/schematic/client.d.ts.map +1 -0
- package/dist/src/schematic/external.d.ts.map +1 -0
- package/dist/src/schematic/index.d.ts.map +1 -0
- package/dist/src/schematic/payload.d.ts.map +1 -0
- package/dist/src/schematic/schematic.spec.d.ts.map +1 -0
- package/dist/src/schematic/symbol/access.spec.d.ts.map +1 -0
- package/dist/src/{workspace/schematic → schematic}/symbol/client.d.ts +2 -2
- package/dist/src/schematic/symbol/client.d.ts.map +1 -0
- package/dist/src/schematic/symbol/client.spec.d.ts.map +1 -0
- package/dist/src/schematic/symbol/external.d.ts.map +1 -0
- package/dist/src/schematic/symbol/index.d.ts.map +1 -0
- package/dist/src/schematic/symbol/payload.d.ts.map +1 -0
- package/dist/src/status/payload.d.ts +43 -7
- package/dist/src/status/payload.d.ts.map +1 -1
- package/dist/src/table/access.spec.d.ts.map +1 -0
- package/dist/src/{workspace/table → table}/client.d.ts +6 -6
- package/dist/src/table/client.d.ts.map +1 -0
- package/dist/src/table/external.d.ts.map +1 -0
- package/dist/src/table/index.d.ts.map +1 -0
- package/dist/src/table/payload.d.ts.map +1 -0
- package/dist/src/table/table.spec.d.ts.map +1 -0
- package/dist/src/task/client.d.ts +2 -2
- package/dist/src/task/payload.d.ts +4 -4
- package/dist/src/task/payload.d.ts.map +1 -1
- package/dist/src/user/client.d.ts +2 -2
- package/dist/src/view/client.d.ts +2 -2
- package/dist/src/workspace/client.d.ts +2 -10
- package/dist/src/workspace/client.d.ts.map +1 -1
- package/eslint.config.ts +2 -3
- package/package.json +10 -9
- package/src/arc/lsp.spec.ts +155 -283
- package/src/channel/client.ts +3 -5
- package/src/channel/payload.spec.ts +0 -57
- package/src/channel/payload.ts +7 -14
- package/src/channel/retriever.ts +2 -3
- package/src/client.ts +16 -1
- package/src/device/client.ts +89 -43
- package/src/device/payload.spec.ts +118 -0
- package/src/device/payload.ts +55 -30
- package/src/errors.spec.ts +1 -1
- package/src/framer/adapter.ts +5 -7
- package/src/framer/frame.ts +8 -8
- package/src/{ontology/group → group}/access.spec.ts +7 -7
- package/src/{ontology/group → group}/client.ts +1 -1
- package/src/group/external.ts +11 -0
- package/src/{ontology/group → group}/group.spec.ts +9 -9
- package/src/{workspace/log → group}/index.ts +1 -1
- package/src/index.ts +5 -5
- package/src/label/access.spec.ts +1 -1
- package/src/label/client.ts +1 -1
- package/src/label/label.spec.ts +4 -4
- package/src/{workspace/lineplot → lineplot}/access.spec.ts +14 -14
- package/src/{workspace/lineplot → lineplot}/client.ts +13 -13
- package/src/lineplot/external.ts +11 -0
- package/src/{ontology/group → lineplot}/index.ts +1 -1
- package/src/{workspace/lineplot → lineplot}/lineplot.spec.ts +12 -12
- package/src/{workspace/log → log}/access.spec.ts +16 -18
- package/src/{workspace/log → log}/client.ts +13 -13
- package/src/{workspace/schematic/index.ts → log/external.ts} +2 -1
- package/src/{workspace/table → log}/index.ts +1 -1
- package/src/{workspace/log → log}/log.spec.ts +10 -10
- package/src/ontology/client.ts +1 -7
- package/src/ontology/ontology.spec.ts +12 -12
- package/src/ranger/{alias.ts → alias/client.ts} +6 -37
- package/src/{workspace/lineplot → ranger/alias}/external.ts +10 -2
- package/src/{workspace/lineplot → ranger/alias}/index.ts +1 -1
- package/src/ranger/alias/payload.ts +50 -0
- package/src/ranger/client.ts +26 -19
- package/src/ranger/external.ts +22 -0
- package/src/ranger/{kv.ts → kv/client.ts} +5 -19
- package/src/{workspace/schematic → ranger/kv}/external.ts +7 -3
- package/src/ranger/kv/index.ts +10 -0
- package/src/ranger/kv/payload.ts +32 -0
- package/src/ranger/payload.ts +2 -2
- package/src/ranger/ranger.spec.ts +1 -1
- package/src/{workspace/schematic → schematic}/access.spec.ts +14 -14
- package/src/{workspace/schematic → schematic}/client.ts +14 -14
- package/src/{workspace/log → schematic}/external.ts +3 -2
- package/src/schematic/index.ts +10 -0
- package/src/{workspace/schematic → schematic}/schematic.spec.ts +17 -17
- package/src/{workspace/schematic → schematic}/symbol/access.spec.ts +19 -19
- package/src/{workspace/schematic → schematic}/symbol/client.spec.ts +16 -16
- package/src/{workspace/schematic → schematic}/symbol/client.ts +8 -8
- package/src/{ontology/group → schematic/symbol}/external.ts +2 -2
- package/src/schematic/symbol/index.ts +10 -0
- package/src/status/payload.ts +1 -1
- package/src/status/status.spec.ts +2 -2
- package/src/{workspace/table → table}/access.spec.ts +14 -14
- package/src/{workspace/table → table}/client.ts +15 -12
- package/src/table/external.ts +11 -0
- package/src/table/index.ts +10 -0
- package/src/{workspace/table → table}/table.spec.ts +12 -12
- package/src/task/payload.ts +4 -5
- package/src/workspace/client.ts +0 -12
- package/dist/src/ontology/group/access.spec.d.ts.map +0 -1
- package/dist/src/ontology/group/client.d.ts.map +0 -1
- package/dist/src/ontology/group/external.d.ts.map +0 -1
- package/dist/src/ontology/group/group.spec.d.ts.map +0 -1
- package/dist/src/ontology/group/index.d.ts.map +0 -1
- package/dist/src/ontology/group/payload.d.ts.map +0 -1
- package/dist/src/ranger/alias.d.ts.map +0 -1
- package/dist/src/ranger/kv.d.ts +0 -48
- package/dist/src/ranger/kv.d.ts.map +0 -1
- package/dist/src/workspace/lineplot/access.spec.d.ts.map +0 -1
- package/dist/src/workspace/lineplot/client.d.ts.map +0 -1
- package/dist/src/workspace/lineplot/external.d.ts.map +0 -1
- package/dist/src/workspace/lineplot/index.d.ts.map +0 -1
- package/dist/src/workspace/lineplot/lineplot.spec.d.ts.map +0 -1
- package/dist/src/workspace/lineplot/payload.d.ts.map +0 -1
- package/dist/src/workspace/log/access.spec.d.ts.map +0 -1
- package/dist/src/workspace/log/client.d.ts.map +0 -1
- package/dist/src/workspace/log/external.d.ts.map +0 -1
- package/dist/src/workspace/log/index.d.ts.map +0 -1
- package/dist/src/workspace/log/log.spec.d.ts.map +0 -1
- package/dist/src/workspace/log/payload.d.ts.map +0 -1
- package/dist/src/workspace/schematic/access.spec.d.ts.map +0 -1
- package/dist/src/workspace/schematic/client.d.ts.map +0 -1
- package/dist/src/workspace/schematic/external.d.ts.map +0 -1
- package/dist/src/workspace/schematic/index.d.ts.map +0 -1
- package/dist/src/workspace/schematic/payload.d.ts.map +0 -1
- package/dist/src/workspace/schematic/schematic.spec.d.ts.map +0 -1
- package/dist/src/workspace/schematic/symbol/access.spec.d.ts.map +0 -1
- package/dist/src/workspace/schematic/symbol/client.d.ts.map +0 -1
- package/dist/src/workspace/schematic/symbol/client.spec.d.ts.map +0 -1
- package/dist/src/workspace/schematic/symbol/external.d.ts.map +0 -1
- package/dist/src/workspace/schematic/symbol/index.d.ts.map +0 -1
- package/dist/src/workspace/schematic/symbol/payload.d.ts.map +0 -1
- package/dist/src/workspace/table/access.spec.d.ts.map +0 -1
- package/dist/src/workspace/table/client.d.ts.map +0 -1
- package/dist/src/workspace/table/external.d.ts.map +0 -1
- package/dist/src/workspace/table/index.d.ts.map +0 -1
- package/dist/src/workspace/table/payload.d.ts.map +0 -1
- package/dist/src/workspace/table/table.spec.d.ts.map +0 -1
- package/src/workspace/schematic/symbol/external.ts +0 -11
- package/src/workspace/schematic/symbol/index.ts +0 -10
- package/src/workspace/table/external.ts +0 -11
- /package/dist/src/{ontology/group → group}/access.spec.d.ts +0 -0
- /package/dist/src/{ontology/group → group}/external.d.ts +0 -0
- /package/dist/src/{ontology/group → group}/group.spec.d.ts +0 -0
- /package/dist/src/{ontology/group → group}/index.d.ts +0 -0
- /package/dist/src/{workspace/lineplot → lineplot}/access.spec.d.ts +0 -0
- /package/dist/src/{workspace/lineplot → lineplot}/external.d.ts +0 -0
- /package/dist/src/{workspace/lineplot → lineplot}/index.d.ts +0 -0
- /package/dist/src/{workspace/lineplot → lineplot}/lineplot.spec.d.ts +0 -0
- /package/dist/src/{workspace/lineplot → lineplot}/payload.d.ts +0 -0
- /package/dist/src/{workspace/log → log}/access.spec.d.ts +0 -0
- /package/dist/src/{workspace/log → log}/external.d.ts +0 -0
- /package/dist/src/{workspace/log → log}/index.d.ts +0 -0
- /package/dist/src/{workspace/log → log}/log.spec.d.ts +0 -0
- /package/dist/src/{workspace/log → log}/payload.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/access.spec.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/external.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/index.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/payload.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/schematic.spec.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/symbol/access.spec.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/symbol/client.spec.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/symbol/external.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/symbol/index.d.ts +0 -0
- /package/dist/src/{workspace/schematic → schematic}/symbol/payload.d.ts +0 -0
- /package/dist/src/{workspace/table → table}/access.spec.d.ts +0 -0
- /package/dist/src/{workspace/table → table}/external.d.ts +0 -0
- /package/dist/src/{workspace/table → table}/index.d.ts +0 -0
- /package/dist/src/{workspace/table → table}/payload.d.ts +0 -0
- /package/dist/src/{workspace/table → table}/table.spec.d.ts +0 -0
- /package/src/{ontology/group → group}/payload.ts +0 -0
- /package/src/{workspace/lineplot → lineplot}/payload.ts +0 -0
- /package/src/{workspace/log → log}/payload.ts +0 -0
- /package/src/{workspace/schematic → schematic}/payload.ts +0 -0
- /package/src/{workspace/schematic → schematic}/symbol/payload.ts +0 -0
- /package/src/{workspace/table → table}/payload.ts +0 -0
package/src/arc/lsp.spec.ts
CHANGED
|
@@ -7,52 +7,91 @@
|
|
|
7
7
|
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
8
|
// included in the file licenses/APL.txt.
|
|
9
9
|
|
|
10
|
-
import { type jsonRPC } from "@synnaxlabs/x";
|
|
11
10
|
import { describe, expect, it } from "vitest";
|
|
12
11
|
|
|
13
12
|
import { createTestClient } from "@/testutil/client";
|
|
14
13
|
|
|
14
|
+
interface JSONRPCRequest {
|
|
15
|
+
jsonrpc: "2.0";
|
|
16
|
+
id: number;
|
|
17
|
+
method: string;
|
|
18
|
+
params?: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type JSONRPCResponse =
|
|
22
|
+
| { jsonrpc: "2.0"; id: number; result: unknown }
|
|
23
|
+
| {
|
|
24
|
+
jsonrpc: "2.0";
|
|
25
|
+
id: number;
|
|
26
|
+
error: { code: number; message: string; data?: unknown };
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type LSPReceiver = {
|
|
30
|
+
receive: () => Promise<[{ content: string }, null] | [null, Error]>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const MAX_DRAIN = 50;
|
|
34
|
+
|
|
35
|
+
/** Drains messages from the stream until a JSON-RPC response with the expected id arrives. */
|
|
36
|
+
const receiveResponse = async (
|
|
37
|
+
stream: LSPReceiver,
|
|
38
|
+
expectedId: number,
|
|
39
|
+
): Promise<JSONRPCResponse> => {
|
|
40
|
+
for (let i = 0; i < MAX_DRAIN; i++) {
|
|
41
|
+
const [res, err] = await stream.receive();
|
|
42
|
+
if (err != null) throw err;
|
|
43
|
+
if (res == null) throw new Error("Expected response");
|
|
44
|
+
const msg = JSON.parse(res.content);
|
|
45
|
+
if (!("method" in msg) && "id" in msg && msg.id === expectedId)
|
|
46
|
+
return msg as JSONRPCResponse;
|
|
47
|
+
}
|
|
48
|
+
throw new Error(
|
|
49
|
+
`receiveResponse: drained ${MAX_DRAIN} messages without seeing id=${expectedId}`,
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** Drains messages from the stream until a JSON-RPC notification with the expected method arrives. */
|
|
54
|
+
const receiveNotification = async (
|
|
55
|
+
stream: LSPReceiver,
|
|
56
|
+
expectedMethod: string,
|
|
57
|
+
): Promise<JSONRPCRequest> => {
|
|
58
|
+
for (let i = 0; i < MAX_DRAIN; i++) {
|
|
59
|
+
const [res, err] = await stream.receive();
|
|
60
|
+
if (err != null) throw err;
|
|
61
|
+
if (res == null) throw new Error("Expected message");
|
|
62
|
+
const msg = JSON.parse(res.content);
|
|
63
|
+
if ("method" in msg && msg.method === expectedMethod) return msg as JSONRPCRequest;
|
|
64
|
+
}
|
|
65
|
+
throw new Error(
|
|
66
|
+
`receiveNotification: drained ${MAX_DRAIN} messages without seeing method=${expectedMethod}`,
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
15
70
|
describe("Arc LSP", () => {
|
|
16
71
|
it("should open an LSP stream and handle initialize request", async () => {
|
|
17
72
|
const client = createTestClient();
|
|
18
73
|
const stream = await client.arcs.openLSP();
|
|
19
74
|
|
|
20
|
-
|
|
21
|
-
const initializeRequest: jsonRPC.Request = {
|
|
75
|
+
const initializeRequest: JSONRPCRequest = {
|
|
22
76
|
jsonrpc: "2.0",
|
|
23
77
|
id: 1,
|
|
24
78
|
method: "initialize",
|
|
25
79
|
params: {
|
|
26
80
|
processId: null,
|
|
27
|
-
clientInfo: {
|
|
28
|
-
name: "test-client",
|
|
29
|
-
version: "1.0.0",
|
|
30
|
-
},
|
|
81
|
+
clientInfo: { name: "test-client", version: "1.0.0" },
|
|
31
82
|
rootUri: null,
|
|
32
83
|
capabilities: {},
|
|
33
84
|
},
|
|
34
85
|
};
|
|
35
86
|
|
|
36
|
-
stream.send({
|
|
37
|
-
content: JSON.stringify(initializeRequest),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// Receive response (raw JSON, no Content-Length headers)
|
|
41
|
-
const [res, err] = await stream.receive();
|
|
42
|
-
expect(err).toBeNull();
|
|
43
|
-
if (!res) throw new Error("Expected response");
|
|
87
|
+
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
44
88
|
|
|
45
|
-
|
|
46
|
-
const msg = JSON.parse(res.content) as jsonRPC.Response;
|
|
89
|
+
const msg = await receiveResponse(stream, 1);
|
|
47
90
|
expect(msg.jsonrpc).toBe("2.0");
|
|
48
91
|
expect(msg.id).toBe(1);
|
|
49
|
-
|
|
50
|
-
// Check for error response
|
|
51
92
|
if ("error" in msg) throw new Error(`LSP error: ${msg.error.message}`);
|
|
52
|
-
|
|
53
93
|
expect("result" in msg).toBe(true);
|
|
54
94
|
|
|
55
|
-
// Verify capabilities are present
|
|
56
95
|
if ("result" in msg) {
|
|
57
96
|
const result = msg.result as Record<string, unknown>;
|
|
58
97
|
expect(result).toHaveProperty("capabilities");
|
|
@@ -65,8 +104,7 @@ describe("Arc LSP", () => {
|
|
|
65
104
|
const client = createTestClient();
|
|
66
105
|
const stream = await client.arcs.openLSP();
|
|
67
106
|
|
|
68
|
-
|
|
69
|
-
const initializeRequest: jsonRPC.Request = {
|
|
107
|
+
const initializeRequest: JSONRPCRequest = {
|
|
70
108
|
jsonrpc: "2.0",
|
|
71
109
|
id: 1,
|
|
72
110
|
method: "initialize",
|
|
@@ -79,62 +117,37 @@ describe("Arc LSP", () => {
|
|
|
79
117
|
};
|
|
80
118
|
|
|
81
119
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
82
|
-
const
|
|
83
|
-
expect(initErr).toBeNull();
|
|
84
|
-
expect(initResponse).not.toBeNull();
|
|
85
|
-
if (!initResponse) throw new Error("Expected response");
|
|
86
|
-
|
|
87
|
-
// Parse raw JSON response
|
|
88
|
-
const initMsg = JSON.parse(initResponse.content) as jsonRPC.Response;
|
|
89
|
-
expect(initMsg.id).toBe(1);
|
|
90
|
-
|
|
91
|
-
// Check for error response
|
|
120
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
92
121
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
93
122
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
stream.send({ content: JSON.stringify(initializedNotification) });
|
|
123
|
+
stream.send({
|
|
124
|
+
content: JSON.stringify({
|
|
125
|
+
jsonrpc: "2.0",
|
|
126
|
+
method: "initialized",
|
|
127
|
+
params: {},
|
|
128
|
+
}),
|
|
129
|
+
});
|
|
102
130
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
131
|
+
stream.send({
|
|
132
|
+
content: JSON.stringify({
|
|
133
|
+
jsonrpc: "2.0",
|
|
134
|
+
method: "textDocument/didOpen",
|
|
135
|
+
params: {
|
|
136
|
+
textDocument: {
|
|
137
|
+
uri: "file:///test.arc",
|
|
138
|
+
languageId: "arc",
|
|
139
|
+
version: 1,
|
|
140
|
+
text: "let x = 1 + 2;",
|
|
141
|
+
},
|
|
113
142
|
},
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
stream.send({ content: JSON.stringify(didOpenNotification) });
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
118
145
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const timeoutPromise = new Promise((resolve) =>
|
|
123
|
-
setTimeout(() => resolve(null), 100),
|
|
146
|
+
const diagMsg = await receiveNotification(
|
|
147
|
+
stream,
|
|
148
|
+
"textDocument/publishDiagnostics",
|
|
124
149
|
);
|
|
125
|
-
|
|
126
|
-
const result = await Promise.race([diagnosticsPromise, timeoutPromise]);
|
|
127
|
-
|
|
128
|
-
if (result && Array.isArray(result)) {
|
|
129
|
-
const [diagResponse, diagErr] = result;
|
|
130
|
-
if (diagResponse && !diagErr) {
|
|
131
|
-
// Parse raw JSON notification
|
|
132
|
-
const diagMsg = JSON.parse(diagResponse.content) as jsonRPC.Message;
|
|
133
|
-
expect(diagMsg.jsonrpc).toBe("2.0");
|
|
134
|
-
if ("method" in diagMsg)
|
|
135
|
-
expect(diagMsg.method).toBe("textDocument/publishDiagnostics");
|
|
136
|
-
}
|
|
137
|
-
}
|
|
150
|
+
expect(diagMsg.jsonrpc).toBe("2.0");
|
|
138
151
|
|
|
139
152
|
stream.closeSend();
|
|
140
153
|
client.close();
|
|
@@ -144,8 +157,7 @@ describe("Arc LSP", () => {
|
|
|
144
157
|
const client = createTestClient();
|
|
145
158
|
const stream = await client.arcs.openLSP();
|
|
146
159
|
|
|
147
|
-
|
|
148
|
-
const initializeRequest: jsonRPC.Request = {
|
|
160
|
+
const initializeRequest: JSONRPCRequest = {
|
|
149
161
|
jsonrpc: "2.0",
|
|
150
162
|
id: 1,
|
|
151
163
|
method: "initialize",
|
|
@@ -158,14 +170,9 @@ describe("Arc LSP", () => {
|
|
|
158
170
|
};
|
|
159
171
|
|
|
160
172
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
161
|
-
const
|
|
162
|
-
expect(initRes).not.toBeNull();
|
|
163
|
-
if (!initRes) throw new Error("Expected response");
|
|
164
|
-
|
|
165
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
173
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
166
174
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
167
175
|
|
|
168
|
-
// Send initialized notification
|
|
169
176
|
stream.send({
|
|
170
177
|
content: JSON.stringify({
|
|
171
178
|
jsonrpc: "2.0",
|
|
@@ -174,7 +181,6 @@ describe("Arc LSP", () => {
|
|
|
174
181
|
}),
|
|
175
182
|
});
|
|
176
183
|
|
|
177
|
-
// Open a document
|
|
178
184
|
stream.send({
|
|
179
185
|
content: JSON.stringify({
|
|
180
186
|
jsonrpc: "2.0",
|
|
@@ -190,12 +196,9 @@ describe("Arc LSP", () => {
|
|
|
190
196
|
}),
|
|
191
197
|
});
|
|
192
198
|
|
|
193
|
-
|
|
194
|
-
const [diagResponse] = await stream.receive();
|
|
195
|
-
expect(diagResponse).not.toBeNull();
|
|
199
|
+
await receiveNotification(stream, "textDocument/publishDiagnostics");
|
|
196
200
|
|
|
197
|
-
|
|
198
|
-
const hoverRequest: jsonRPC.Request = {
|
|
201
|
+
const hoverRequest: JSONRPCRequest = {
|
|
199
202
|
jsonrpc: "2.0",
|
|
200
203
|
id: 2,
|
|
201
204
|
method: "textDocument/hover",
|
|
@@ -207,17 +210,9 @@ describe("Arc LSP", () => {
|
|
|
207
210
|
|
|
208
211
|
stream.send({ content: JSON.stringify(hoverRequest) });
|
|
209
212
|
|
|
210
|
-
const
|
|
211
|
-
expect(hoverErr).toBeNull();
|
|
212
|
-
expect(hoverResponse).not.toBeNull();
|
|
213
|
-
if (!hoverResponse) throw new Error("Expected response");
|
|
214
|
-
|
|
215
|
-
// Parse raw JSON response
|
|
216
|
-
const responseMsg = JSON.parse(hoverResponse.content) as jsonRPC.Response;
|
|
213
|
+
const responseMsg = await receiveResponse(stream, 2);
|
|
217
214
|
expect(responseMsg.jsonrpc).toBe("2.0");
|
|
218
215
|
expect(responseMsg.id).toBe(2);
|
|
219
|
-
|
|
220
|
-
// Check for error response
|
|
221
216
|
if ("error" in responseMsg)
|
|
222
217
|
throw new Error(`LSP error: ${responseMsg.error.message}`);
|
|
223
218
|
|
|
@@ -229,10 +224,9 @@ describe("Arc LSP", () => {
|
|
|
229
224
|
const client = createTestClient();
|
|
230
225
|
const stream = await client.arcs.openLSP();
|
|
231
226
|
|
|
232
|
-
const receivedMessages:
|
|
227
|
+
const receivedMessages: JSONRPCResponse[] = [];
|
|
233
228
|
|
|
234
|
-
|
|
235
|
-
const initializeRequest: jsonRPC.Request = {
|
|
229
|
+
const initializeRequest: JSONRPCRequest = {
|
|
236
230
|
jsonrpc: "2.0",
|
|
237
231
|
id: 1,
|
|
238
232
|
method: "initialize",
|
|
@@ -245,14 +239,11 @@ describe("Arc LSP", () => {
|
|
|
245
239
|
};
|
|
246
240
|
|
|
247
241
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
248
|
-
const
|
|
249
|
-
if (!initResponse) throw new Error("Expected response");
|
|
250
|
-
const initMsg = JSON.parse(initResponse.content) as jsonRPC.Response;
|
|
242
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
251
243
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
252
244
|
|
|
253
245
|
receivedMessages.push(initMsg);
|
|
254
246
|
|
|
255
|
-
// Send multiple requests with different IDs
|
|
256
247
|
const requests = [
|
|
257
248
|
{
|
|
258
249
|
jsonrpc: "2.0",
|
|
@@ -270,20 +261,14 @@ describe("Arc LSP", () => {
|
|
|
270
261
|
|
|
271
262
|
for (const req of requests) stream.send({ content: JSON.stringify(req) });
|
|
272
263
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const [response] = await stream.receive();
|
|
276
|
-
if (!response) throw new Error("Expected response");
|
|
277
|
-
const msg = JSON.parse(response.content) as jsonRPC.Response;
|
|
264
|
+
for (const req of requests) {
|
|
265
|
+
const msg = await receiveResponse(stream, req.id);
|
|
278
266
|
if ("error" in msg) throw new Error(`LSP error: ${msg.error.message}`);
|
|
279
|
-
|
|
280
267
|
receivedMessages.push(msg);
|
|
281
268
|
}
|
|
282
269
|
|
|
283
|
-
// Should have init response + 2 request responses
|
|
284
270
|
expect(receivedMessages.length).toBeGreaterThanOrEqual(3);
|
|
285
271
|
|
|
286
|
-
// Verify all responses have correct structure
|
|
287
272
|
for (const msg of receivedMessages) {
|
|
288
273
|
expect(msg.jsonrpc).toBe("2.0");
|
|
289
274
|
expect(msg.id).toBeDefined();
|
|
@@ -297,31 +282,19 @@ describe("Arc LSP", () => {
|
|
|
297
282
|
const client = createTestClient();
|
|
298
283
|
const stream = await client.arcs.openLSP();
|
|
299
284
|
|
|
300
|
-
|
|
301
|
-
const testMessage: jsonRPC.Request = {
|
|
285
|
+
const testMessage: JSONRPCRequest = {
|
|
302
286
|
jsonrpc: "2.0",
|
|
303
287
|
id: 999,
|
|
304
288
|
method: "test/method",
|
|
305
289
|
params: { data: "test" },
|
|
306
290
|
};
|
|
307
291
|
|
|
308
|
-
|
|
292
|
+
stream.send({ content: JSON.stringify(testMessage) });
|
|
309
293
|
|
|
310
|
-
|
|
311
|
-
stream.send({ content: messageContent });
|
|
312
|
-
|
|
313
|
-
// The server should respond (even if it's an error for unknown method)
|
|
314
|
-
const [response, err] = await stream.receive();
|
|
315
|
-
expect(err).toBeNull();
|
|
316
|
-
expect(response).not.toBeNull();
|
|
317
|
-
if (!response) throw new Error("Expected response");
|
|
318
|
-
|
|
319
|
-
// Response should be parseable JSON
|
|
320
|
-
const parsed = JSON.parse(response.content) as jsonRPC.Response;
|
|
294
|
+
const parsed = await receiveResponse(stream, 999);
|
|
321
295
|
expect(parsed.jsonrpc).toBe("2.0");
|
|
322
296
|
expect(parsed.id).toBe(999);
|
|
323
297
|
|
|
324
|
-
// This test expects an error response for unknown method
|
|
325
298
|
if ("error" in parsed) expect(parsed.error).toBeDefined();
|
|
326
299
|
|
|
327
300
|
stream.closeSend();
|
|
@@ -332,8 +305,7 @@ describe("Arc LSP", () => {
|
|
|
332
305
|
const client = createTestClient();
|
|
333
306
|
const stream = await client.arcs.openLSP();
|
|
334
307
|
|
|
335
|
-
|
|
336
|
-
const initializeRequest: jsonRPC.Request = {
|
|
308
|
+
const initializeRequest: JSONRPCRequest = {
|
|
337
309
|
jsonrpc: "2.0",
|
|
338
310
|
id: 1,
|
|
339
311
|
method: "initialize",
|
|
@@ -353,21 +325,15 @@ describe("Arc LSP", () => {
|
|
|
353
325
|
};
|
|
354
326
|
|
|
355
327
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
356
|
-
const
|
|
357
|
-
expect(initRes).not.toBeNull();
|
|
358
|
-
if (!initRes) throw new Error("Expected response");
|
|
359
|
-
|
|
360
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
328
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
361
329
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
362
330
|
|
|
363
|
-
// Verify server advertises semantic tokens support
|
|
364
331
|
if ("result" in initMsg) {
|
|
365
332
|
const result = initMsg.result as Record<string, unknown>;
|
|
366
333
|
const capabilities = result.capabilities as Record<string, unknown>;
|
|
367
334
|
expect(capabilities).toHaveProperty("semanticTokensProvider");
|
|
368
335
|
}
|
|
369
336
|
|
|
370
|
-
// Send initialized notification
|
|
371
337
|
stream.send({
|
|
372
338
|
content: JSON.stringify({
|
|
373
339
|
jsonrpc: "2.0",
|
|
@@ -376,7 +342,6 @@ describe("Arc LSP", () => {
|
|
|
376
342
|
}),
|
|
377
343
|
});
|
|
378
344
|
|
|
379
|
-
// Open a document with Arc code
|
|
380
345
|
const arcCode = "func add(x i32, y i32) i32 {\n return x + y\n}";
|
|
381
346
|
stream.send({
|
|
382
347
|
content: JSON.stringify({
|
|
@@ -393,11 +358,9 @@ describe("Arc LSP", () => {
|
|
|
393
358
|
}),
|
|
394
359
|
});
|
|
395
360
|
|
|
396
|
-
|
|
397
|
-
await stream.receive();
|
|
361
|
+
await receiveNotification(stream, "textDocument/publishDiagnostics");
|
|
398
362
|
|
|
399
|
-
|
|
400
|
-
const semanticTokensRequest: jsonRPC.Request = {
|
|
363
|
+
const semanticTokensRequest: JSONRPCRequest = {
|
|
401
364
|
jsonrpc: "2.0",
|
|
402
365
|
id: 2,
|
|
403
366
|
method: "textDocument/semanticTokens/full",
|
|
@@ -408,26 +371,18 @@ describe("Arc LSP", () => {
|
|
|
408
371
|
|
|
409
372
|
stream.send({ content: JSON.stringify(semanticTokensRequest) });
|
|
410
373
|
|
|
411
|
-
const
|
|
412
|
-
expect(tokenErr).toBeNull();
|
|
413
|
-
expect(tokenResponse).not.toBeNull();
|
|
414
|
-
if (!tokenResponse) throw new Error("Expected response");
|
|
415
|
-
|
|
416
|
-
const tokenMsg = JSON.parse(tokenResponse.content) as jsonRPC.Response;
|
|
374
|
+
const tokenMsg = await receiveResponse(stream, 2);
|
|
417
375
|
expect(tokenMsg.jsonrpc).toBe("2.0");
|
|
418
376
|
expect(tokenMsg.id).toBe(2);
|
|
419
|
-
|
|
420
377
|
if ("error" in tokenMsg) throw new Error(`LSP error: ${tokenMsg.error.message}`);
|
|
421
378
|
|
|
422
|
-
// Verify semantic tokens are returned
|
|
423
379
|
if ("result" in tokenMsg) {
|
|
424
380
|
const result = tokenMsg.result as Record<string, unknown>;
|
|
425
381
|
expect(result).toHaveProperty("data");
|
|
426
382
|
const data = result.data as number[];
|
|
427
383
|
expect(Array.isArray(data)).toBe(true);
|
|
428
|
-
// Should have tokens (encoded as [deltaLine, deltaStart, length, type, modifiers] * N)
|
|
429
384
|
expect(data.length).toBeGreaterThan(0);
|
|
430
|
-
// Tokens
|
|
385
|
+
// Tokens are encoded as [deltaLine, deltaStart, length, type, modifiers] * N
|
|
431
386
|
expect(data.length % 5).toBe(0);
|
|
432
387
|
}
|
|
433
388
|
|
|
@@ -440,8 +395,7 @@ describe("Arc LSP", () => {
|
|
|
440
395
|
const client = createTestClient();
|
|
441
396
|
const stream = await client.arcs.openLSP();
|
|
442
397
|
|
|
443
|
-
|
|
444
|
-
const initializeRequest: jsonRPC.Request = {
|
|
398
|
+
const initializeRequest: JSONRPCRequest = {
|
|
445
399
|
jsonrpc: "2.0",
|
|
446
400
|
id: 1,
|
|
447
401
|
method: "initialize",
|
|
@@ -454,14 +408,9 @@ describe("Arc LSP", () => {
|
|
|
454
408
|
};
|
|
455
409
|
|
|
456
410
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
457
|
-
const
|
|
458
|
-
expect(initRes).not.toBeNull();
|
|
459
|
-
if (!initRes) throw new Error("Expected response");
|
|
460
|
-
|
|
461
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
411
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
462
412
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
463
413
|
|
|
464
|
-
// Send initialized notification
|
|
465
414
|
stream.send({
|
|
466
415
|
content: JSON.stringify({
|
|
467
416
|
jsonrpc: "2.0",
|
|
@@ -470,13 +419,10 @@ describe("Arc LSP", () => {
|
|
|
470
419
|
}),
|
|
471
420
|
});
|
|
472
421
|
|
|
473
|
-
// Create metadata for block expression
|
|
474
422
|
const metadata = { is_block: true };
|
|
475
423
|
const encoded = btoa(JSON.stringify(metadata));
|
|
476
424
|
const blockURI = `arc://block/test123#${encoded}`;
|
|
477
425
|
|
|
478
|
-
// Open a document with block URI containing a simple expression
|
|
479
|
-
const blockExpression = "return x * 2";
|
|
480
426
|
stream.send({
|
|
481
427
|
content: JSON.stringify({
|
|
482
428
|
jsonrpc: "2.0",
|
|
@@ -486,30 +432,22 @@ describe("Arc LSP", () => {
|
|
|
486
432
|
uri: blockURI,
|
|
487
433
|
languageId: "arc",
|
|
488
434
|
version: 1,
|
|
489
|
-
text:
|
|
435
|
+
text: "return x * 2",
|
|
490
436
|
},
|
|
491
437
|
},
|
|
492
438
|
}),
|
|
493
439
|
});
|
|
494
440
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
if (!diagResponse) throw new Error("Expected diagnostics");
|
|
500
|
-
|
|
501
|
-
const diagMsg = JSON.parse(diagResponse.content) as jsonRPC.Message;
|
|
441
|
+
const diagMsg = await receiveNotification(
|
|
442
|
+
stream,
|
|
443
|
+
"textDocument/publishDiagnostics",
|
|
444
|
+
);
|
|
502
445
|
expect(diagMsg.jsonrpc).toBe("2.0");
|
|
503
|
-
if ("
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
// Expression should be wrapped and parsed successfully
|
|
509
|
-
const diagnostics = params.diagnostics as unknown[];
|
|
510
|
-
// May have diagnostics about undefined 'x', but should parse successfully
|
|
511
|
-
expect(Array.isArray(diagnostics)).toBe(true);
|
|
512
|
-
}
|
|
446
|
+
if ("params" in diagMsg) {
|
|
447
|
+
const params = diagMsg.params as Record<string, unknown>;
|
|
448
|
+
expect(params.uri).toBe(blockURI);
|
|
449
|
+
const diagnostics = params.diagnostics as unknown[];
|
|
450
|
+
expect(Array.isArray(diagnostics)).toBe(true);
|
|
513
451
|
}
|
|
514
452
|
|
|
515
453
|
stream.closeSend();
|
|
@@ -520,8 +458,7 @@ describe("Arc LSP", () => {
|
|
|
520
458
|
const client = createTestClient();
|
|
521
459
|
const stream = await client.arcs.openLSP();
|
|
522
460
|
|
|
523
|
-
|
|
524
|
-
const initializeRequest: jsonRPC.Request = {
|
|
461
|
+
const initializeRequest: JSONRPCRequest = {
|
|
525
462
|
jsonrpc: "2.0",
|
|
526
463
|
id: 1,
|
|
527
464
|
method: "initialize",
|
|
@@ -534,14 +471,9 @@ describe("Arc LSP", () => {
|
|
|
534
471
|
};
|
|
535
472
|
|
|
536
473
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
537
|
-
const
|
|
538
|
-
expect(initRes).not.toBeNull();
|
|
539
|
-
if (!initRes) throw new Error("Expected response");
|
|
540
|
-
|
|
541
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
474
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
542
475
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
543
476
|
|
|
544
|
-
// Send initialized notification
|
|
545
477
|
stream.send({
|
|
546
478
|
content: JSON.stringify({
|
|
547
479
|
jsonrpc: "2.0",
|
|
@@ -550,13 +482,10 @@ describe("Arc LSP", () => {
|
|
|
550
482
|
}),
|
|
551
483
|
});
|
|
552
484
|
|
|
553
|
-
// Create block URI
|
|
554
485
|
const metadata = { is_block: true };
|
|
555
486
|
const encoded = btoa(JSON.stringify(metadata));
|
|
556
487
|
const blockURI = `arc://block/syntax-error#${encoded}`;
|
|
557
488
|
|
|
558
|
-
// Open a document with invalid syntax
|
|
559
|
-
const invalidExpression = "return x +";
|
|
560
489
|
stream.send({
|
|
561
490
|
content: JSON.stringify({
|
|
562
491
|
jsonrpc: "2.0",
|
|
@@ -566,21 +495,17 @@ describe("Arc LSP", () => {
|
|
|
566
495
|
uri: blockURI,
|
|
567
496
|
languageId: "arc",
|
|
568
497
|
version: 1,
|
|
569
|
-
text:
|
|
498
|
+
text: "return x +",
|
|
570
499
|
},
|
|
571
500
|
},
|
|
572
501
|
}),
|
|
573
502
|
});
|
|
574
503
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
const diagMsg = JSON.parse(diagResponse.content) as jsonRPC.Message;
|
|
582
|
-
if ("method" in diagMsg && "params" in diagMsg) {
|
|
583
|
-
expect(diagMsg.method).toBe("textDocument/publishDiagnostics");
|
|
504
|
+
const diagMsg = await receiveNotification(
|
|
505
|
+
stream,
|
|
506
|
+
"textDocument/publishDiagnostics",
|
|
507
|
+
);
|
|
508
|
+
if ("params" in diagMsg) {
|
|
584
509
|
const params = diagMsg.params as Record<string, unknown>;
|
|
585
510
|
const diagnostics = params.diagnostics as Array<{
|
|
586
511
|
range: { start: { line: number; character: number } };
|
|
@@ -588,12 +513,9 @@ describe("Arc LSP", () => {
|
|
|
588
513
|
severity: number;
|
|
589
514
|
}>;
|
|
590
515
|
|
|
591
|
-
// Should have at least one diagnostic
|
|
592
516
|
expect(diagnostics.length).toBeGreaterThan(0);
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
const firstDiag = diagnostics[0];
|
|
596
|
-
expect(firstDiag.range.start.line).toBe(0);
|
|
517
|
+
// Position should be mapped to line 0 for original expression
|
|
518
|
+
expect(diagnostics[0].range.start.line).toBe(0);
|
|
597
519
|
}
|
|
598
520
|
|
|
599
521
|
stream.closeSend();
|
|
@@ -604,8 +526,7 @@ describe("Arc LSP", () => {
|
|
|
604
526
|
const client = createTestClient();
|
|
605
527
|
const stream = await client.arcs.openLSP();
|
|
606
528
|
|
|
607
|
-
|
|
608
|
-
const initializeRequest: jsonRPC.Request = {
|
|
529
|
+
const initializeRequest: JSONRPCRequest = {
|
|
609
530
|
jsonrpc: "2.0",
|
|
610
531
|
id: 1,
|
|
611
532
|
method: "initialize",
|
|
@@ -618,14 +539,9 @@ describe("Arc LSP", () => {
|
|
|
618
539
|
};
|
|
619
540
|
|
|
620
541
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
621
|
-
const
|
|
622
|
-
expect(initRes).not.toBeNull();
|
|
623
|
-
if (!initRes) throw new Error("Expected response");
|
|
624
|
-
|
|
625
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
542
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
626
543
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
627
544
|
|
|
628
|
-
// Send initialized notification
|
|
629
545
|
stream.send({
|
|
630
546
|
content: JSON.stringify({
|
|
631
547
|
jsonrpc: "2.0",
|
|
@@ -634,14 +550,10 @@ describe("Arc LSP", () => {
|
|
|
634
550
|
}),
|
|
635
551
|
});
|
|
636
552
|
|
|
637
|
-
// Create block URI
|
|
638
553
|
const metadata = { is_block: true };
|
|
639
554
|
const encoded = btoa(JSON.stringify(metadata));
|
|
640
555
|
const blockURI = `arc://block/multiline#${encoded}`;
|
|
641
556
|
|
|
642
|
-
// Multi-line block expression
|
|
643
|
-
const multiLineExpression =
|
|
644
|
-
"let temp = x * 2\nlet result = temp + 1\nreturn result";
|
|
645
557
|
stream.send({
|
|
646
558
|
content: JSON.stringify({
|
|
647
559
|
jsonrpc: "2.0",
|
|
@@ -651,25 +563,20 @@ describe("Arc LSP", () => {
|
|
|
651
563
|
uri: blockURI,
|
|
652
564
|
languageId: "arc",
|
|
653
565
|
version: 1,
|
|
654
|
-
text:
|
|
566
|
+
text: "let temp = x * 2\nlet result = temp + 1\nreturn result",
|
|
655
567
|
},
|
|
656
568
|
},
|
|
657
569
|
}),
|
|
658
570
|
});
|
|
659
571
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (
|
|
665
|
-
|
|
666
|
-
const diagMsg = JSON.parse(diagResponse.content) as jsonRPC.Message;
|
|
667
|
-
if ("method" in diagMsg && "params" in diagMsg) {
|
|
668
|
-
expect(diagMsg.method).toBe("textDocument/publishDiagnostics");
|
|
572
|
+
const diagMsg = await receiveNotification(
|
|
573
|
+
stream,
|
|
574
|
+
"textDocument/publishDiagnostics",
|
|
575
|
+
);
|
|
576
|
+
if ("params" in diagMsg) {
|
|
669
577
|
const params = diagMsg.params as Record<string, unknown>;
|
|
670
578
|
expect(params.uri).toBe(blockURI);
|
|
671
579
|
const diagnostics = params.diagnostics as unknown[];
|
|
672
|
-
// Should successfully parse multi-line expression
|
|
673
580
|
expect(Array.isArray(diagnostics)).toBe(true);
|
|
674
581
|
}
|
|
675
582
|
|
|
@@ -681,8 +588,7 @@ describe("Arc LSP", () => {
|
|
|
681
588
|
const client = createTestClient();
|
|
682
589
|
const stream = await client.arcs.openLSP();
|
|
683
590
|
|
|
684
|
-
|
|
685
|
-
const initializeRequest: jsonRPC.Request = {
|
|
591
|
+
const initializeRequest: JSONRPCRequest = {
|
|
686
592
|
jsonrpc: "2.0",
|
|
687
593
|
id: 1,
|
|
688
594
|
method: "initialize",
|
|
@@ -695,14 +601,9 @@ describe("Arc LSP", () => {
|
|
|
695
601
|
};
|
|
696
602
|
|
|
697
603
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
698
|
-
const
|
|
699
|
-
expect(initRes).not.toBeNull();
|
|
700
|
-
if (!initRes) throw new Error("Expected response");
|
|
701
|
-
|
|
702
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
604
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
703
605
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
704
606
|
|
|
705
|
-
// Send initialized notification
|
|
706
607
|
stream.send({
|
|
707
608
|
content: JSON.stringify({
|
|
708
609
|
jsonrpc: "2.0",
|
|
@@ -711,12 +612,10 @@ describe("Arc LSP", () => {
|
|
|
711
612
|
}),
|
|
712
613
|
});
|
|
713
614
|
|
|
714
|
-
// Create block URI
|
|
715
615
|
const metadata = { is_block: true };
|
|
716
616
|
const encoded = btoa(JSON.stringify(metadata));
|
|
717
617
|
const blockURI = `arc://block/change-test#${encoded}`;
|
|
718
618
|
|
|
719
|
-
// Open initial document
|
|
720
619
|
stream.send({
|
|
721
620
|
content: JSON.stringify({
|
|
722
621
|
jsonrpc: "2.0",
|
|
@@ -732,37 +631,24 @@ describe("Arc LSP", () => {
|
|
|
732
631
|
}),
|
|
733
632
|
});
|
|
734
633
|
|
|
735
|
-
|
|
736
|
-
await stream.receive();
|
|
634
|
+
await receiveNotification(stream, "textDocument/publishDiagnostics");
|
|
737
635
|
|
|
738
|
-
// Send didChange to update the expression
|
|
739
636
|
stream.send({
|
|
740
637
|
content: JSON.stringify({
|
|
741
638
|
jsonrpc: "2.0",
|
|
742
639
|
method: "textDocument/didChange",
|
|
743
640
|
params: {
|
|
744
|
-
textDocument: {
|
|
745
|
-
|
|
746
|
-
version: 2,
|
|
747
|
-
},
|
|
748
|
-
contentChanges: [
|
|
749
|
-
{
|
|
750
|
-
text: "return x + y",
|
|
751
|
-
},
|
|
752
|
-
],
|
|
641
|
+
textDocument: { uri: blockURI, version: 2 },
|
|
642
|
+
contentChanges: [{ text: "return x + y" }],
|
|
753
643
|
},
|
|
754
644
|
}),
|
|
755
645
|
});
|
|
756
646
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
if (
|
|
762
|
-
|
|
763
|
-
const changeDiagMsg = JSON.parse(changeDiagResponse.content) as jsonRPC.Message;
|
|
764
|
-
if ("method" in changeDiagMsg && "params" in changeDiagMsg) {
|
|
765
|
-
expect(changeDiagMsg.method).toBe("textDocument/publishDiagnostics");
|
|
647
|
+
const changeDiagMsg = await receiveNotification(
|
|
648
|
+
stream,
|
|
649
|
+
"textDocument/publishDiagnostics",
|
|
650
|
+
);
|
|
651
|
+
if ("params" in changeDiagMsg) {
|
|
766
652
|
const params = changeDiagMsg.params as Record<string, unknown>;
|
|
767
653
|
expect(params.uri).toBe(blockURI);
|
|
768
654
|
}
|
|
@@ -775,8 +661,7 @@ describe("Arc LSP", () => {
|
|
|
775
661
|
const client = createTestClient();
|
|
776
662
|
const stream = await client.arcs.openLSP();
|
|
777
663
|
|
|
778
|
-
|
|
779
|
-
const initializeRequest: jsonRPC.Request = {
|
|
664
|
+
const initializeRequest: JSONRPCRequest = {
|
|
780
665
|
jsonrpc: "2.0",
|
|
781
666
|
id: 1,
|
|
782
667
|
method: "initialize",
|
|
@@ -789,14 +674,9 @@ describe("Arc LSP", () => {
|
|
|
789
674
|
};
|
|
790
675
|
|
|
791
676
|
stream.send({ content: JSON.stringify(initializeRequest) });
|
|
792
|
-
const
|
|
793
|
-
expect(initRes).not.toBeNull();
|
|
794
|
-
if (!initRes) throw new Error("Expected response");
|
|
795
|
-
|
|
796
|
-
const initMsg = JSON.parse(initRes.content) as jsonRPC.Response;
|
|
677
|
+
const initMsg = await receiveResponse(stream, 1);
|
|
797
678
|
if ("error" in initMsg) throw new Error(`LSP error: ${initMsg.error.message}`);
|
|
798
679
|
|
|
799
|
-
// Send initialized notification
|
|
800
680
|
stream.send({
|
|
801
681
|
content: JSON.stringify({
|
|
802
682
|
jsonrpc: "2.0",
|
|
@@ -805,11 +685,9 @@ describe("Arc LSP", () => {
|
|
|
805
685
|
}),
|
|
806
686
|
});
|
|
807
687
|
|
|
808
|
-
//
|
|
688
|
+
// Block URI without metadata fragment - expression won't be wrapped
|
|
809
689
|
const invalidBlockURI = "arc://block/no-metadata";
|
|
810
690
|
|
|
811
|
-
// Open a document with invalid block expression (missing wrapping)
|
|
812
|
-
const blockExpression = "return x * 2";
|
|
813
691
|
stream.send({
|
|
814
692
|
content: JSON.stringify({
|
|
815
693
|
jsonrpc: "2.0",
|
|
@@ -819,26 +697,20 @@ describe("Arc LSP", () => {
|
|
|
819
697
|
uri: invalidBlockURI,
|
|
820
698
|
languageId: "arc",
|
|
821
699
|
version: 1,
|
|
822
|
-
text:
|
|
700
|
+
text: "return x * 2",
|
|
823
701
|
},
|
|
824
702
|
},
|
|
825
703
|
}),
|
|
826
704
|
});
|
|
827
705
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
if (
|
|
833
|
-
|
|
834
|
-
const diagMsg = JSON.parse(diagResponse.content) as jsonRPC.Message;
|
|
835
|
-
if ("method" in diagMsg && "params" in diagMsg) {
|
|
836
|
-
expect(diagMsg.method).toBe("textDocument/publishDiagnostics");
|
|
706
|
+
const diagMsg = await receiveNotification(
|
|
707
|
+
stream,
|
|
708
|
+
"textDocument/publishDiagnostics",
|
|
709
|
+
);
|
|
710
|
+
if ("params" in diagMsg) {
|
|
837
711
|
const params = diagMsg.params as Record<string, unknown>;
|
|
838
712
|
const diagnostics = params.diagnostics as Array<{ severity: number }>;
|
|
839
|
-
|
|
840
|
-
// Should have error diagnostics because expression isn't wrapped
|
|
841
|
-
const errors = diagnostics.filter((d) => d.severity === 1); // Error severity
|
|
713
|
+
const errors = diagnostics.filter((d) => d.severity === 1);
|
|
842
714
|
expect(errors.length).toBeGreaterThan(0);
|
|
843
715
|
}
|
|
844
716
|
|