@synnaxlabs/x 0.49.3 → 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 +10 -10
- package/dist/eslint.config.d.ts +2 -2
- package/dist/eslint.config.d.ts.map +1 -1
- package/dist/src/color/color.d.ts +26 -2
- package/dist/src/color/color.d.ts.map +1 -1
- package/dist/src/color/gradient.d.ts +10 -0
- package/dist/src/color/gradient.d.ts.map +1 -1
- package/dist/src/color/palette.d.ts +22 -2
- package/dist/src/color/palette.d.ts.map +1 -1
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/kv/types.d.ts.map +1 -1
- package/dist/src/label/label.d.ts +15 -1
- package/dist/src/label/label.d.ts.map +1 -1
- package/dist/src/record/record.d.ts +23 -9
- package/dist/src/record/record.d.ts.map +1 -1
- package/dist/src/status/status.d.ts +5 -0
- package/dist/src/status/status.d.ts.map +1 -1
- package/dist/src/sync/mutex.d.ts +3 -3
- package/dist/src/zod/util.d.ts +2 -0
- package/dist/src/zod/util.d.ts.map +1 -1
- package/dist/x.cjs +11 -8
- package/dist/x.js +1106 -1129
- package/eslint.config.ts +3 -3
- package/package.json +9 -8
- package/src/array/external.ts +1 -1
- package/src/array/index.ts +1 -1
- package/src/array/nullable.ts +1 -1
- package/src/array/toArray.spec.ts +1 -1
- package/src/array/toArray.ts +1 -1
- package/src/array/update.spec.ts +1 -1
- package/src/array/update.ts +1 -1
- package/src/binary/codec.spec.ts +1 -1
- package/src/binary/codec.ts +1 -1
- package/src/binary/index.ts +1 -1
- package/src/breaker/breaker.spec.ts +1 -1
- package/src/breaker/breaker.ts +1 -1
- package/src/breaker/index.ts +1 -1
- package/src/caseconv/caseconv.spec.ts +1 -1
- package/src/caseconv/caseconv.ts +1 -1
- package/src/caseconv/index.ts +1 -1
- package/src/change/change.ts +1 -1
- package/src/change/index.ts +1 -1
- package/src/clamp/clamp.ts +1 -1
- package/src/color/color.spec.ts +27 -2
- package/src/color/color.ts +10 -4
- package/src/color/external.ts +1 -1
- package/src/color/gradient.ts +1 -1
- package/src/color/index.ts +1 -1
- package/src/color/palette.ts +1 -1
- package/src/compare/binary.spec.ts +1 -1
- package/src/compare/binary.ts +1 -1
- package/src/compare/compare.spec.ts +1 -1
- package/src/compare/compare.ts +1 -1
- package/src/compare/external.ts +1 -1
- package/src/compare/index.ts +1 -1
- package/src/control/control.ts +1 -1
- package/src/control/index.ts +1 -1
- package/src/csv/csv.spec.ts +1 -1
- package/src/csv/csv.ts +1 -1
- package/src/csv/index.ts +1 -1
- package/src/debounce/debounce.spec.ts +1 -1
- package/src/debounce/debounce.ts +1 -1
- package/src/debounce/index.ts +1 -1
- package/src/deep/copy.spec.ts +1 -1
- package/src/deep/copy.ts +1 -1
- package/src/deep/difference.spec.ts +1 -1
- package/src/deep/difference.ts +1 -1
- package/src/deep/equal.spec.ts +1 -1
- package/src/deep/equal.ts +1 -1
- package/src/deep/external.ts +1 -1
- package/src/deep/get.bench.ts +1 -1
- package/src/deep/get.spec.ts +1 -1
- package/src/deep/get.ts +1 -1
- package/src/deep/index.ts +1 -1
- package/src/deep/join.ts +1 -1
- package/src/deep/merge.spec.ts +1 -1
- package/src/deep/merge.ts +1 -1
- package/src/deep/partial.spec.ts +1 -1
- package/src/deep/partial.ts +1 -1
- package/src/deep/path.spec.ts +1 -1
- package/src/deep/path.ts +1 -1
- package/src/deep/remove.bench.ts +1 -1
- package/src/deep/remove.spec.ts +1 -1
- package/src/deep/remove.ts +1 -1
- package/src/deep/set.bench.ts +1 -1
- package/src/deep/set.spec.ts +1 -1
- package/src/deep/set.ts +1 -1
- package/src/destructor/destructor.ts +1 -1
- package/src/destructor/index.ts +1 -1
- package/src/errors/errors.spec.ts +1 -1
- package/src/errors/errors.ts +1 -1
- package/src/errors/index.ts +1 -1
- package/src/id/id.spec.ts +1 -1
- package/src/id/id.ts +1 -1
- package/src/id/index.ts +1 -1
- package/src/index.ts +1 -2
- package/src/instance/index.ts +1 -1
- package/src/instance/matcher.spec.ts +1 -1
- package/src/instance/matcher.ts +1 -1
- package/src/kv/external.ts +1 -1
- package/src/kv/index.ts +1 -1
- package/src/kv/mock.spec.ts +1 -1
- package/src/kv/mock.ts +1 -1
- package/src/kv/types.ts +2 -4
- package/src/label/index.ts +1 -1
- package/src/label/label.ts +4 -2
- package/src/link/index.ts +1 -1
- package/src/link/link.spec.ts +1 -1
- package/src/link/link.ts +1 -1
- package/src/map/index.ts +1 -1
- package/src/map/map.spec.ts +1 -1
- package/src/map/map.ts +1 -1
- package/src/math/constants.ts +1 -1
- package/src/math/external.ts +1 -1
- package/src/math/index.ts +1 -1
- package/src/math/math.spec.ts +1 -1
- package/src/math/math.ts +1 -1
- package/src/math/round.spec.ts +1 -1
- package/src/math/round.ts +1 -1
- package/src/migrate/index.ts +1 -1
- package/src/migrate/migrate.spec.ts +1 -1
- package/src/migrate/migrate.ts +5 -5
- package/src/mock/MockGLBufferController.ts +1 -1
- package/src/narrow/index.ts +1 -1
- package/src/narrow/narrow.spec.ts +1 -1
- package/src/narrow/narrow.ts +1 -1
- package/src/notation/index.ts +1 -1
- package/src/notation/notation.spec.ts +1 -1
- package/src/notation/notation.ts +1 -1
- package/src/numeric/index.ts +1 -1
- package/src/numeric/numeric.ts +1 -1
- package/src/observe/index.ts +1 -1
- package/src/observe/observe.ts +1 -1
- package/src/observe/obsever.spec.ts +1 -1
- package/src/optional/index.ts +1 -1
- package/src/optional/optional.ts +1 -1
- package/src/primitive/index.ts +1 -1
- package/src/primitive/primitive.spec.ts +1 -1
- package/src/primitive/primitive.ts +1 -1
- package/src/record/index.ts +1 -1
- package/src/record/record.spec.ts +32 -18
- package/src/record/record.ts +30 -14
- package/src/runtime/detect.ts +1 -1
- package/src/runtime/external.ts +1 -1
- package/src/runtime/index.ts +1 -1
- package/src/runtime/os.ts +1 -1
- package/src/scheduler/index.ts +1 -1
- package/src/scheduler/scheduler.spec.ts +1 -1
- package/src/scheduler/scheduler.ts +1 -1
- package/src/shallow/copy.spec.ts +1 -1
- package/src/shallow/copy.ts +1 -1
- package/src/shallow/index.ts +1 -1
- package/src/singleton/define.spec.ts +1 -1
- package/src/singleton/define.ts +1 -1
- package/src/singleton/index.ts +1 -1
- package/src/sleep/index.ts +1 -1
- package/src/sleep/sleep.ts +1 -1
- package/src/spatial/base.ts +1 -1
- package/src/spatial/bounds/bounds.spec.ts +1 -1
- package/src/spatial/bounds/bounds.ts +1 -1
- package/src/spatial/bounds/index.ts +1 -1
- package/src/spatial/box/box.spec.ts +1 -1
- package/src/spatial/box/box.ts +1 -1
- package/src/spatial/box/index.ts +1 -1
- package/src/spatial/dimensions/dimensions.spec.ts +1 -1
- package/src/spatial/dimensions/dimensions.ts +1 -1
- package/src/spatial/dimensions/index.ts +1 -1
- package/src/spatial/direction/direction.spec.ts +1 -1
- package/src/spatial/direction/direction.ts +1 -1
- package/src/spatial/direction/index.ts +1 -1
- package/src/spatial/external.ts +1 -1
- package/src/spatial/index.ts +1 -1
- package/src/spatial/location/index.ts +1 -1
- package/src/spatial/location/location.spec.ts +1 -1
- package/src/spatial/location/location.ts +1 -1
- package/src/spatial/scale/index.ts +1 -1
- package/src/spatial/scale/scale.spec.ts +1 -1
- package/src/spatial/scale/scale.ts +1 -1
- package/src/spatial/spatial.ts +1 -1
- package/src/spatial/sticky/index.ts +1 -1
- package/src/spatial/sticky/sticky.spec.ts +1 -1
- package/src/spatial/sticky/sticky.ts +1 -1
- package/src/spatial/xy/index.ts +1 -1
- package/src/spatial/xy/xy.spec.ts +1 -1
- package/src/spatial/xy/xy.ts +1 -1
- package/src/status/index.ts +1 -1
- package/src/status/status.spec.ts +168 -1
- package/src/status/status.ts +47 -1
- package/src/strings/deduplicateFileName.spec.ts +1 -1
- package/src/strings/deduplicateFileName.ts +1 -1
- package/src/strings/external.ts +1 -1
- package/src/strings/index.ts +1 -1
- package/src/strings/strings.spec.ts +1 -1
- package/src/strings/strings.ts +1 -1
- package/src/sync/index.ts +1 -1
- package/src/sync/mutex.ts +4 -4
- package/src/telem/gl.ts +1 -1
- package/src/telem/index.ts +1 -1
- package/src/telem/series.spec.ts +1 -1
- package/src/telem/series.ts +4 -4
- package/src/telem/telem.spec.ts +1 -1
- package/src/telem/telem.ts +1 -1
- package/src/testutil/index.ts +1 -1
- package/src/testutil/testutil.spec.ts +1 -1
- package/src/testutil/testutil.ts +1 -1
- package/src/types/index.ts +1 -1
- package/src/unique/index.ts +1 -1
- package/src/unique/unique.spec.ts +1 -1
- package/src/unique/unique.ts +1 -1
- package/src/url/index.ts +1 -1
- package/src/url/url.spec.ts +1 -1
- package/src/url/url.ts +1 -1
- package/src/uuid/index.ts +1 -1
- package/src/uuid/uuid.spec.ts +1 -1
- package/src/uuid/uuid.ts +1 -1
- package/src/worker/index.ts +1 -1
- package/src/worker/worker.spec.ts +1 -1
- package/src/worker/worker.ts +1 -1
- package/src/zod/external.ts +1 -1
- package/src/zod/index.ts +1 -1
- package/src/zod/nullToUndefined.spec.ts +1 -1
- package/src/zod/nullToUndefined.ts +1 -1
- package/src/zod/schemas.spec.ts +1 -1
- package/src/zod/schemas.ts +1 -1
- package/src/zod/toArray.spec.ts +1 -1
- package/src/zod/toArray.ts +1 -1
- package/src/zod/util.spec.ts +31 -1
- package/src/zod/util.ts +14 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +1 -2
- package/dist/src/jsonrpc/index.d.ts +0 -2
- package/dist/src/jsonrpc/index.d.ts.map +0 -1
- package/dist/src/jsonrpc/jsonrpc.d.ts +0 -70
- package/dist/src/jsonrpc/jsonrpc.d.ts.map +0 -1
- package/dist/src/jsonrpc/jsonrpc.spec.d.ts +0 -2
- package/dist/src/jsonrpc/jsonrpc.spec.d.ts.map +0 -1
- package/src/jsonrpc/index.ts +0 -10
- package/src/jsonrpc/jsonrpc.spec.ts +0 -135
- package/src/jsonrpc/jsonrpc.ts +0 -125
package/vite.config.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2026 Synnax Labs, Inc.
|
|
2
2
|
//
|
|
3
3
|
// Use of this software is governed by the Business Source License included in the file
|
|
4
4
|
// licenses/BSL.txt.
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
/// <reference types="vitest/config" />
|
|
11
11
|
|
|
12
12
|
import { lib } from "@synnaxlabs/vite-plugin";
|
|
13
|
-
import path from "path";
|
|
14
13
|
import { defineConfig } from "vite";
|
|
15
14
|
|
|
16
15
|
export default defineConfig({
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jsonrpc/index.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { default as z } from 'zod';
|
|
2
|
-
export declare const requestZ: z.ZodObject<{
|
|
3
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
4
|
-
method: z.ZodString;
|
|
5
|
-
params: z.ZodOptional<z.ZodAny>;
|
|
6
|
-
id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>;
|
|
7
|
-
}, z.core.$strip>;
|
|
8
|
-
export type Request = z.infer<typeof requestZ>;
|
|
9
|
-
export declare const responseZ: z.ZodUnion<readonly [z.ZodObject<{
|
|
10
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
11
|
-
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>;
|
|
12
|
-
result: z.ZodJSONSchema;
|
|
13
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
15
|
-
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>;
|
|
16
|
-
error: z.ZodObject<{
|
|
17
|
-
code: z.ZodNumber;
|
|
18
|
-
message: z.ZodOptional<z.ZodString>;
|
|
19
|
-
data: z.ZodOptional<z.ZodJSONSchema>;
|
|
20
|
-
}, z.core.$strip>;
|
|
21
|
-
}, z.core.$strip>]>;
|
|
22
|
-
export type Response = z.infer<typeof responseZ>;
|
|
23
|
-
export declare const messageZ: z.ZodUnion<readonly [z.ZodObject<{
|
|
24
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
25
|
-
method: z.ZodString;
|
|
26
|
-
params: z.ZodOptional<z.ZodAny>;
|
|
27
|
-
id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>;
|
|
28
|
-
}, z.core.$strip>, z.ZodUnion<readonly [z.ZodObject<{
|
|
29
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
30
|
-
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>;
|
|
31
|
-
result: z.ZodJSONSchema;
|
|
32
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
33
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
34
|
-
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>;
|
|
35
|
-
error: z.ZodObject<{
|
|
36
|
-
code: z.ZodNumber;
|
|
37
|
-
message: z.ZodOptional<z.ZodString>;
|
|
38
|
-
data: z.ZodOptional<z.ZodJSONSchema>;
|
|
39
|
-
}, z.core.$strip>;
|
|
40
|
-
}, z.core.$strip>]>]>;
|
|
41
|
-
export type Message = z.infer<typeof messageZ>;
|
|
42
|
-
export interface ChunkParser {
|
|
43
|
-
(chunk: Uint8Array | ArrayBuffer | string): void;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Decodes a a stream of utf-8 encoded chunks into JSON-RPC messages. This function
|
|
47
|
-
* is particularly useful for communicating with JSON-RPC based services over stdio.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
*
|
|
51
|
-
* const decoder = JSONRPC.decodeStream(console.log);
|
|
52
|
-
*
|
|
53
|
-
* decoder(`Content-Length: 42
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* {"jsonrpc":"2.0","method":"$/status/show"}Content-Length: 82
|
|
57
|
-
*
|
|
58
|
-
* {"id":5,"jsonrpc":"2.0","method":"workspace/semanticTokens/refresh","params":null}`)
|
|
59
|
-
*
|
|
60
|
-
* // Logs the following:
|
|
61
|
-
*
|
|
62
|
-
* { jsonrpc: '2.0', method: '$/status/show' }
|
|
63
|
-
* { id: 5, jsonrpc: '2.0', method: 'workspace/semanticTokens/refresh', params: null }
|
|
64
|
-
*
|
|
65
|
-
* @param onMessage - The callback to call when a message is decoded.
|
|
66
|
-
* @returns A function that accepts a chunk and decodes it into a message.
|
|
67
|
-
*/
|
|
68
|
-
export declare const streamDecodeChunks: (onMessage: (message: Message) => void) => ChunkParser;
|
|
69
|
-
export declare const encodeMessage: (message: Message) => string;
|
|
70
|
-
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsonrpc.d.ts","sourceRoot":"","sources":["../../../src/jsonrpc/jsonrpc.ts"],"names":[],"mappings":"AASA,OAAO,CAAC,MAAM,KAAK,CAAC;AAIpB,eAAO,MAAM,QAAQ;;;;;iBAQnB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAqB/C,eAAO,MAAM,SAAS;;;;;;;;;;;;mBAA8C,CAAC;AAErE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAEjD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;qBAAiC,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAE/C,MAAM,WAAW,WAAW;IAC1B,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,WAAW,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,KACpC,WAoCF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,OAAO,KAAG,MAKhD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsonrpc.spec.d.ts","sourceRoot":"","sources":["../../../src/jsonrpc/jsonrpc.spec.ts"],"names":[],"mappings":""}
|
package/src/jsonrpc/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// Copyright 2025 Synnax Labs, Inc.
|
|
2
|
-
//
|
|
3
|
-
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
-
// licenses/BSL.txt.
|
|
5
|
-
//
|
|
6
|
-
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
-
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
-
// included in the file licenses/APL.txt.
|
|
9
|
-
|
|
10
|
-
export * as jsonRPC from "@/jsonrpc/jsonrpc";
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
// Copyright 2025 Synnax Labs, Inc.
|
|
2
|
-
//
|
|
3
|
-
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
-
// licenses/BSL.txt.
|
|
5
|
-
//
|
|
6
|
-
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
-
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
-
// included in the file licenses/APL.txt.
|
|
9
|
-
|
|
10
|
-
import { describe, expect, it } from "vitest";
|
|
11
|
-
|
|
12
|
-
import { jsonRPC } from "@/jsonrpc";
|
|
13
|
-
|
|
14
|
-
describe("JSON-RPC", () => {
|
|
15
|
-
describe("streamDecodeChunks", () => {
|
|
16
|
-
it("should decode a single message", () => {
|
|
17
|
-
const messages: jsonRPC.Message[] = [];
|
|
18
|
-
const decoder = jsonRPC.streamDecodeChunks((msg) => messages.push(msg));
|
|
19
|
-
|
|
20
|
-
const input = `Content-Length: 138
|
|
21
|
-
|
|
22
|
-
{"jsonrpc":"2.0","method":"$/status/report","params":{"text":"😺Lua","tooltip":"Workspace : \\nCached files: 0/0\\nMemory usage: 1M\\n"}}`;
|
|
23
|
-
|
|
24
|
-
decoder(new TextEncoder().encode(input));
|
|
25
|
-
|
|
26
|
-
expect(messages).toHaveLength(1);
|
|
27
|
-
expect(messages[0]).toEqual({
|
|
28
|
-
jsonrpc: "2.0",
|
|
29
|
-
method: "$/status/report",
|
|
30
|
-
params: {
|
|
31
|
-
text: "😺Lua",
|
|
32
|
-
tooltip: "Workspace : \nCached files: 0/0\nMemory usage: 1M\n",
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("should handle multiple messages in a single chunk", () => {
|
|
38
|
-
const messages: jsonRPC.Message[] = [];
|
|
39
|
-
const decoder = jsonRPC.streamDecodeChunks((msg) => messages.push(msg));
|
|
40
|
-
|
|
41
|
-
const input = `Content-Length: 42
|
|
42
|
-
|
|
43
|
-
{"jsonrpc":"2.0","method":"$/status/show"}Content-Length: 82
|
|
44
|
-
|
|
45
|
-
{"id":5,"jsonrpc":"2.0","method":"workspace/semanticTokens/refresh","params":null}`;
|
|
46
|
-
|
|
47
|
-
decoder(new TextEncoder().encode(input));
|
|
48
|
-
|
|
49
|
-
expect(messages).toHaveLength(2);
|
|
50
|
-
expect(messages[0]).toEqual({
|
|
51
|
-
jsonrpc: "2.0",
|
|
52
|
-
method: "$/status/show",
|
|
53
|
-
});
|
|
54
|
-
expect(messages[1]).toEqual({
|
|
55
|
-
id: 5,
|
|
56
|
-
jsonrpc: "2.0",
|
|
57
|
-
method: "workspace/semanticTokens/refresh",
|
|
58
|
-
params: null,
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("should handle messages split across multiple chunks", () => {
|
|
63
|
-
const messages: jsonRPC.Message[] = [];
|
|
64
|
-
const decoder = jsonRPC.streamDecodeChunks((msg) => messages.push(msg));
|
|
65
|
-
|
|
66
|
-
const chunk1 = `Content-Length: 42
|
|
67
|
-
|
|
68
|
-
{"jsonrpc":"2.0",`;
|
|
69
|
-
|
|
70
|
-
const chunk2 = `"method":"$/status/show"}`;
|
|
71
|
-
|
|
72
|
-
decoder(new TextEncoder().encode(chunk1));
|
|
73
|
-
decoder(new TextEncoder().encode(chunk2));
|
|
74
|
-
|
|
75
|
-
expect(messages).toHaveLength(1);
|
|
76
|
-
expect(messages[0]).toEqual({
|
|
77
|
-
jsonrpc: "2.0",
|
|
78
|
-
method: "$/status/show",
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("should handle string input", () => {
|
|
83
|
-
const messages: jsonRPC.Message[] = [];
|
|
84
|
-
const decoder = jsonRPC.streamDecodeChunks((msg) => messages.push(msg));
|
|
85
|
-
|
|
86
|
-
const input = `Content-Length: 42
|
|
87
|
-
|
|
88
|
-
{"jsonrpc":"2.0","method":"$/status/show"}`;
|
|
89
|
-
|
|
90
|
-
decoder(input); // Pass string directly
|
|
91
|
-
|
|
92
|
-
expect(messages).toHaveLength(1);
|
|
93
|
-
expect(messages[0]).toEqual({
|
|
94
|
-
jsonrpc: "2.0",
|
|
95
|
-
method: "$/status/show",
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("should handle mixed string and Uint8Array chunks", () => {
|
|
100
|
-
const messages: jsonRPC.Message[] = [];
|
|
101
|
-
const decoder = jsonRPC.streamDecodeChunks((msg) => messages.push(msg));
|
|
102
|
-
|
|
103
|
-
const chunk1 = `Content-Length: 42
|
|
104
|
-
|
|
105
|
-
{"jsonrpc":"2.0",`;
|
|
106
|
-
|
|
107
|
-
const chunk2 = new TextEncoder().encode(`"method":"$/status/show"}`);
|
|
108
|
-
|
|
109
|
-
decoder(chunk1); // String chunk
|
|
110
|
-
decoder(chunk2); // Uint8Array chunk
|
|
111
|
-
|
|
112
|
-
expect(messages).toHaveLength(1);
|
|
113
|
-
expect(messages[0]).toEqual({
|
|
114
|
-
jsonrpc: "2.0",
|
|
115
|
-
method: "$/status/show",
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
describe("encodeMessage", () => {
|
|
120
|
-
it("should encode a message", () => {
|
|
121
|
-
const message: jsonRPC.Request = {
|
|
122
|
-
jsonrpc: "2.0",
|
|
123
|
-
id: 1,
|
|
124
|
-
method: "$/status/show",
|
|
125
|
-
};
|
|
126
|
-
const messageStr = JSON.stringify(message);
|
|
127
|
-
const encoded = jsonRPC.encodeMessage(message);
|
|
128
|
-
expect(encoded.startsWith("Content-Length:")).toBe(true);
|
|
129
|
-
const contentLength = encoded.match(/Content-Length: (\d+)/);
|
|
130
|
-
expect(contentLength).not.toBeNull();
|
|
131
|
-
expect(contentLength?.[1]).toBe(messageStr.length.toString());
|
|
132
|
-
expect(encoded.endsWith(messageStr)).toBe(true);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
});
|
package/src/jsonrpc/jsonrpc.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// Copyright 2025 Synnax Labs, Inc.
|
|
2
|
-
//
|
|
3
|
-
// Use of this software is governed by the Business Source License included in the file
|
|
4
|
-
// licenses/BSL.txt.
|
|
5
|
-
//
|
|
6
|
-
// As of the Change Date specified in that file, in accordance with the Business Source
|
|
7
|
-
// License, use of this software will be governed by the Apache License, Version 2.0,
|
|
8
|
-
// included in the file licenses/APL.txt.
|
|
9
|
-
|
|
10
|
-
import z from "zod";
|
|
11
|
-
|
|
12
|
-
import { binary } from "@/binary";
|
|
13
|
-
|
|
14
|
-
export const requestZ = z.object({
|
|
15
|
-
jsonrpc: z.literal("2.0"),
|
|
16
|
-
method: z.string(),
|
|
17
|
-
// params should be z.union([z.record(z.string(), z.json()),
|
|
18
|
-
// z.array(z.json())]).optional() but the VSCode JSON RPC implementation uses a looser
|
|
19
|
-
// definition of params then in the JSON-RPC spec.
|
|
20
|
-
params: z.any().optional(),
|
|
21
|
-
id: z.union([z.string(), z.number(), z.null()]).optional(),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export type Request = z.infer<typeof requestZ>;
|
|
25
|
-
|
|
26
|
-
const baseResponseZ = z.object({
|
|
27
|
-
jsonrpc: z.literal("2.0"),
|
|
28
|
-
id: z.union([z.string(), z.number(), z.null()]),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const successResponseZ = baseResponseZ.extend({
|
|
32
|
-
result: z.json(),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const errorResponseZ = baseResponseZ.extend({
|
|
36
|
-
error: z.object({
|
|
37
|
-
code: z.number().int(),
|
|
38
|
-
// This should be z.string(), but the VSCode JSON RPC implementation uses a looser
|
|
39
|
-
// definition of error than the JSON-RPC spec.
|
|
40
|
-
message: z.string().optional(),
|
|
41
|
-
data: z.json().optional(),
|
|
42
|
-
}),
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
export const responseZ = z.union([successResponseZ, errorResponseZ]);
|
|
46
|
-
|
|
47
|
-
export type Response = z.infer<typeof responseZ>;
|
|
48
|
-
|
|
49
|
-
export const messageZ = z.union([requestZ, responseZ]);
|
|
50
|
-
|
|
51
|
-
export type Message = z.infer<typeof messageZ>;
|
|
52
|
-
|
|
53
|
-
export interface ChunkParser {
|
|
54
|
-
(chunk: Uint8Array | ArrayBuffer | string): void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Decodes a a stream of utf-8 encoded chunks into JSON-RPC messages. This function
|
|
59
|
-
* is particularly useful for communicating with JSON-RPC based services over stdio.
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
*
|
|
63
|
-
* const decoder = JSONRPC.decodeStream(console.log);
|
|
64
|
-
*
|
|
65
|
-
* decoder(`Content-Length: 42
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* {"jsonrpc":"2.0","method":"$/status/show"}Content-Length: 82
|
|
69
|
-
*
|
|
70
|
-
* {"id":5,"jsonrpc":"2.0","method":"workspace/semanticTokens/refresh","params":null}`)
|
|
71
|
-
*
|
|
72
|
-
* // Logs the following:
|
|
73
|
-
*
|
|
74
|
-
* { jsonrpc: '2.0', method: '$/status/show' }
|
|
75
|
-
* { id: 5, jsonrpc: '2.0', method: 'workspace/semanticTokens/refresh', params: null }
|
|
76
|
-
*
|
|
77
|
-
* @param onMessage - The callback to call when a message is decoded.
|
|
78
|
-
* @returns A function that accepts a chunk and decodes it into a message.
|
|
79
|
-
*/
|
|
80
|
-
export const streamDecodeChunks = (
|
|
81
|
-
onMessage: (message: Message) => void,
|
|
82
|
-
): ChunkParser => {
|
|
83
|
-
const decoder = new TextDecoder();
|
|
84
|
-
let buffer = new Uint8Array(0);
|
|
85
|
-
let expectedLength: number | null = null;
|
|
86
|
-
|
|
87
|
-
return (chunk) => {
|
|
88
|
-
let newChunk: Uint8Array;
|
|
89
|
-
if (typeof chunk === "string") newChunk = new TextEncoder().encode(chunk);
|
|
90
|
-
else if (chunk instanceof ArrayBuffer) newChunk = new Uint8Array(chunk);
|
|
91
|
-
else newChunk = chunk;
|
|
92
|
-
|
|
93
|
-
const newBuffer = new Uint8Array(buffer.length + newChunk.length);
|
|
94
|
-
newBuffer.set(buffer);
|
|
95
|
-
newBuffer.set(newChunk, buffer.length);
|
|
96
|
-
buffer = newBuffer;
|
|
97
|
-
while (buffer.length > 0) {
|
|
98
|
-
if (expectedLength === null) {
|
|
99
|
-
const headerStr = decoder.decode(buffer);
|
|
100
|
-
const headerMatch = headerStr.match(/^Content-Length: (\d+)\r?\n\r?\n/);
|
|
101
|
-
if (!headerMatch) break;
|
|
102
|
-
|
|
103
|
-
expectedLength = parseInt(headerMatch[1]);
|
|
104
|
-
const headerByteLength = new TextEncoder().encode(headerMatch[0]).length;
|
|
105
|
-
buffer = buffer.slice(headerByteLength);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (expectedLength !== null && buffer.length >= expectedLength) {
|
|
109
|
-
const messageBytes = buffer.slice(0, expectedLength);
|
|
110
|
-
buffer = buffer.slice(expectedLength);
|
|
111
|
-
expectedLength = null;
|
|
112
|
-
const messageStr = decoder.decode(messageBytes);
|
|
113
|
-
const parsed = binary.JSON_CODEC.decodeString(messageStr, messageZ);
|
|
114
|
-
onMessage(parsed);
|
|
115
|
-
} else break;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export const encodeMessage = (message: Message): string => {
|
|
121
|
-
const messageStr = JSON.stringify(message);
|
|
122
|
-
const contentLength = new TextEncoder().encode(messageStr).length;
|
|
123
|
-
const header = `Content-Length: ${contentLength}\r\n\r\n`;
|
|
124
|
-
return header + messageStr;
|
|
125
|
-
};
|