@tensnap/protocol 0.2.0

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/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # @tensnap/protocol
2
+
3
+ `@tensnap/protocol` is the source of truth for TenSnap protocol v0.2 payload
4
+ shapes, runtime schemas, and wire codecs.
5
+
6
+ The package is intentionally about the renderer/simulator contract only. It
7
+ does not define rendering layers, React state, storage adapters, project UI, or
8
+ concrete WebSocket implementations.
9
+
10
+ ## Source Files
11
+
12
+ - [src/types.ts](./src/types.ts): message envelopes and payload interfaces.
13
+ - [src/schemas.ts](./src/schemas.ts): runtime zod schemas for protocol payloads.
14
+ - [src/codec.ts](./src/codec.ts): JSON and MessagePack protocol codecs.
15
+ - [src/binary.ts](./src/binary.ts): base64 and data URL handling for binary semantic fields.
16
+ - [src/controls.ts](./src/controls.ts): parameter and action payload definitions.
17
+ - [src/chart.ts](./src/chart.ts): chart metadata and update payload definitions.
18
+ - [src/asset.ts](./src/asset.ts): asset metadata payload definitions.
19
+
20
+ To export the complete TypeScript definitions into Markdown:
21
+
22
+ ```bash
23
+ pnpm --dir packages/protocol export:types protocol-types.md
24
+ ```
25
+
26
+ Omit the output path to print the Markdown to stdout.
27
+
28
+ ## Scope
29
+
30
+ Protocol v0.2 defines:
31
+
32
+ - the wire format between a simulator and a renderer;
33
+ - canonical message families and payload shapes;
34
+ - runtime schemas used to validate protocol payloads;
35
+ - JSON and MessagePack encoding rules;
36
+ - ownership boundaries for state synchronization, assets, screenshots,
37
+ parameters, actions, charts, environments, layers, and layer items.
38
+
39
+ Protocol v0.2 does not define:
40
+
41
+ - a concrete WebSocket, postMessage, or SSE implementation;
42
+ - renderer-specific Scenario stores or project UI state;
43
+ - React, Zustand, Tauri, browser file-system behavior, or layout state;
44
+ - drawing libraries, canvas layers, charts, or component rendering.
45
+
46
+ ## Architectural Model
47
+
48
+ Protocol v0.2 is organized around one rule:
49
+
50
+ **The renderer owns synchronized session state; the simulator is a stateless
51
+ step executor and update producer.**
52
+
53
+ The simulator owns the simulation model and emits updates. The renderer owns
54
+ the synchronized Scenario-like state that can be replayed, inspected, rendered,
55
+ snapshotted, and reconnected. Reconnection is therefore not a special hidden
56
+ mode: it is a protocol-level state-sync transaction.
57
+
58
+ This split keeps the protocol independent of deployment shape. A simulator may
59
+ run in Python, Julia, Go, Node, a worker, or a process behind WebSocket. A
60
+ renderer may be a browser app, desktop shell, benchmark harness, or headless
61
+ agent. The payload contract stays the same.
62
+
63
+ ## Naming
64
+
65
+ Protocol v0.2 uses renderer/simulator terminology. Older client/server names
66
+ are not part of the v0.2 contract.
67
+
68
+ | Old term | v0.2 term |
69
+ | --- | --- |
70
+ | client | renderer |
71
+ | server | simulator |
72
+ | server -> client | simulator -> renderer |
73
+ | client -> server | renderer -> simulator |
74
+
75
+ ## Message Families
76
+
77
+ Simulator-to-renderer messages:
78
+
79
+ - scenario metadata and sync boundaries: `metadata_update`,
80
+ `state_sync_begin`, `state_sync_end`;
81
+ - controls: `action_create`, `action_update`, `action_delete`, `action_end`,
82
+ `param_create`, `param_update`, `param_delete`, `param_sync`;
83
+ - environments and layers: `env_create`, `env_delete`, `env_layer_create`,
84
+ `env_layer_update`, `env_layer_delete`;
85
+ - layer items: `item_create`, `item_update`, `item_delete`;
86
+ - charts, assets, screenshots, and diagnostics: `chart_create`,
87
+ `chart_update`, `chart_delete`, `asset_meta`, `asset_data`,
88
+ `asset_delete`, `screenshot_request`, `log`, `error`.
89
+
90
+ Renderer-to-simulator messages:
91
+
92
+ - `state_sync`;
93
+ - `param_change`;
94
+ - `action_start`;
95
+ - `asset_sync`;
96
+ - `screenshot_response`;
97
+ - `error`.
98
+
99
+ ## Event Loop
100
+
101
+ Continuous simulation is renderer-driven:
102
+
103
+ 1. The renderer sends `action_start` for a continuous action.
104
+ 2. The simulator advances its model and emits state updates.
105
+ 3. The simulator sends `action_end` with timing metadata and an optional
106
+ `continue` flag.
107
+ 4. The renderer decides whether to schedule the next `action_start`.
108
+
109
+ This avoids a simulator-owned hidden loop. The renderer can pause, throttle,
110
+ drop frames, reconnect, or cancel continuous actions without inventing a second
111
+ control channel.
112
+
113
+ ## State Sync
114
+
115
+ `state_sync` is a renderer-to-simulator request containing the renderer's
116
+ current definitions for parameters, actions, environments, layers, and charts.
117
+ The simulator replies by replaying the required create/update/delete messages.
118
+
119
+ That replay is bracketed by `state_sync_begin` and `state_sync_end`, making
120
+ initial sync and reconnect a transaction rather than a timing convention.
121
+
122
+ ## Binary Payloads
123
+
124
+ The protocol has binary semantic fields, notably `asset_data.data` and
125
+ `screenshot_response.data`.
126
+
127
+ JSON transports encode those fields as base64 data URLs. MessagePack transports
128
+ preserve bytes as `Uint8Array`. The codec normalizes both directions so callers
129
+ work with the same semantic message shape.
130
+
131
+ See [src/codec.ts](./src/codec.ts) and [src/binary.ts](./src/binary.ts).
132
+
133
+ ## Package Boundary
134
+
135
+ `@tensnap/protocol` is a dependency of higher-level packages:
136
+
137
+ - `@tensnap/core` owns renderer-side Scenario, rendering primitives, and stores.
138
+ - `@tensnap/js` owns JavaScript simulator-side helpers and transports.
139
+ - `@tensnap/agent` owns node-side automation/session runtime code.
140
+ - application packages own concrete UI and deployment behavior.
141
+
142
+ Those packages should import payload types and codecs directly from
143
+ `@tensnap/protocol`; `@tensnap/core` is not a compatibility alias for protocol.
package/dist/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bill Toshiaki Stark
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Asset identifiers and metadata are protocol payloads, not renderer cache
4
+ * objects. Renderers may resolve them into blob URLs or local buffers, but the
5
+ * wire contract stays content-addressed by id plus hash.
6
+ */
7
+ export declare const AssetIdSchema: z.ZodString;
8
+ export type AssetId = z.infer<typeof AssetIdSchema>;
9
+ export declare const AssetMetaSchema: z.ZodObject<{
10
+ id: z.ZodString;
11
+ hash: z.ZodString;
12
+ mime: z.ZodString;
13
+ size: z.ZodNumber;
14
+ label: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ export type AssetMeta = z.infer<typeof AssetMetaSchema>;
17
+ //# sourceMappingURL=asset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../src/asset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,eAAO,MAAM,eAAe;;;;;;iBAM1B,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
package/dist/asset.js ADDED
@@ -0,0 +1,15 @@
1
+ // src/asset.ts
2
+ import { z } from "zod";
3
+ var AssetIdSchema = z.string();
4
+ var AssetMetaSchema = z.object({
5
+ id: AssetIdSchema,
6
+ hash: z.string(),
7
+ mime: z.string(),
8
+ size: z.number(),
9
+ label: z.string().optional()
10
+ });
11
+ export {
12
+ AssetIdSchema,
13
+ AssetMetaSchema
14
+ };
15
+ //# sourceMappingURL=asset.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/asset.ts"],
4
+ "sourcesContent": ["import { z } from 'zod';\n\n/**\n * Asset identifiers and metadata are protocol payloads, not renderer cache\n * objects. Renderers may resolve them into blob URLs or local buffers, but the\n * wire contract stays content-addressed by id plus hash.\n */\nexport const AssetIdSchema = z.string();\n\nexport type AssetId = z.infer<typeof AssetIdSchema>;\n\nexport const AssetMetaSchema = z.object({\n id: AssetIdSchema,\n hash: z.string(),\n mime: z.string(),\n size: z.number(),\n label: z.string().optional(),\n});\n\nexport type AssetMeta = z.infer<typeof AssetMetaSchema>;\n"],
5
+ "mappings": ";AAAA,SAAS,SAAS;AAOX,IAAM,gBAAgB,EAAE,OAAO;AAI/B,IAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,IAAI;AAAA,EACJ,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO;AAAA,EACf,OAAO,EAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,10 @@
1
+ export interface DecodedBinaryString {
2
+ bytes: Uint8Array;
3
+ mime?: string;
4
+ encoding: 'base64' | 'data-url';
5
+ }
6
+ export declare function encodeBytesAsBase64(bytes: Uint8Array): string;
7
+ export declare function encodeBytesAsDataUrl(bytes: Uint8Array, mime?: string): string;
8
+ export declare function decodeBinaryString(value: string): DecodedBinaryString;
9
+ export declare function isEncodedBinaryString(value: string): boolean;
10
+ //# sourceMappingURL=binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC;CACjC;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAe7D;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,IAAI,SAA6B,GAChC,MAAM,CAER;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAMrE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D"}
package/dist/binary.js ADDED
@@ -0,0 +1,95 @@
1
+ // src/binary.ts
2
+ var BASE64_DATA_URL_MARKER = ";base64,";
3
+ function getGlobalBuffer() {
4
+ return globalThis.Buffer;
5
+ }
6
+ function encodeBytesAsBase64(bytes) {
7
+ const buffer = getGlobalBuffer();
8
+ if (buffer) {
9
+ return buffer.from(bytes).toString("base64");
10
+ }
11
+ if (typeof btoa === "function") {
12
+ let binary = "";
13
+ for (let index = 0; index < bytes.length; index += 1) {
14
+ binary += String.fromCharCode(bytes[index]);
15
+ }
16
+ return btoa(binary);
17
+ }
18
+ throw new Error("No base64 encoder is available in this runtime.");
19
+ }
20
+ function encodeBytesAsDataUrl(bytes, mime = "application/octet-stream") {
21
+ return `data:${mime};base64,${encodeBytesAsBase64(bytes)}`;
22
+ }
23
+ function decodeBinaryString(value) {
24
+ const decoded = tryDecodeBinaryString(value);
25
+ if (!decoded) {
26
+ throw new Error("Expected a base64 string or a base64 data URL.");
27
+ }
28
+ return decoded;
29
+ }
30
+ function isEncodedBinaryString(value) {
31
+ return tryDecodeBinaryString(value) !== null;
32
+ }
33
+ function tryDecodeBinaryString(value) {
34
+ if (value.startsWith("data:")) {
35
+ const dataUrl = tryDecodeBase64DataUrl(value);
36
+ if (dataUrl) {
37
+ return dataUrl;
38
+ }
39
+ }
40
+ const bytes = tryDecodeBase64(value);
41
+ if (!bytes) {
42
+ return null;
43
+ }
44
+ return {
45
+ bytes,
46
+ encoding: "base64"
47
+ };
48
+ }
49
+ function tryDecodeBase64DataUrl(value) {
50
+ const markerIndex = value.indexOf(BASE64_DATA_URL_MARKER);
51
+ if (markerIndex === -1) {
52
+ return null;
53
+ }
54
+ const mime = value.slice(5, markerIndex) || void 0;
55
+ const base64 = value.slice(markerIndex + BASE64_DATA_URL_MARKER.length);
56
+ const bytes = tryDecodeBase64(base64);
57
+ if (!bytes) {
58
+ return null;
59
+ }
60
+ return {
61
+ bytes,
62
+ mime,
63
+ encoding: "data-url"
64
+ };
65
+ }
66
+ function tryDecodeBase64(value) {
67
+ const normalized = value.replace(/\s+/g, "");
68
+ if (!normalized || normalized.length % 4 !== 0 || /[^A-Za-z0-9+/=]/.test(normalized)) {
69
+ return null;
70
+ }
71
+ try {
72
+ const buffer = getGlobalBuffer();
73
+ if (buffer) {
74
+ return new Uint8Array(buffer.from(normalized, "base64"));
75
+ }
76
+ if (typeof atob === "function") {
77
+ const binary = atob(normalized);
78
+ const bytes = new Uint8Array(binary.length);
79
+ for (let index = 0; index < binary.length; index += 1) {
80
+ bytes[index] = binary.charCodeAt(index);
81
+ }
82
+ return bytes;
83
+ }
84
+ } catch {
85
+ return null;
86
+ }
87
+ throw new Error("No base64 decoder is available in this runtime.");
88
+ }
89
+ export {
90
+ decodeBinaryString,
91
+ encodeBytesAsBase64,
92
+ encodeBytesAsDataUrl,
93
+ isEncodedBinaryString
94
+ };
95
+ //# sourceMappingURL=binary.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/binary.ts"],
4
+ "sourcesContent": ["const BASE64_DATA_URL_MARKER = ';base64,';\n\ninterface BufferEncoderResult {\n toString(encoding: 'base64'): string;\n}\n\ninterface BufferLike {\n from(data: Uint8Array): BufferEncoderResult;\n from(data: string, encoding: 'base64'): ArrayLike<number>;\n}\n\nexport interface DecodedBinaryString {\n bytes: Uint8Array;\n mime?: string;\n encoding: 'base64' | 'data-url';\n}\n\nfunction getGlobalBuffer(): BufferLike | undefined {\n return (globalThis as { Buffer?: BufferLike }).Buffer;\n}\n\nexport function encodeBytesAsBase64(bytes: Uint8Array): string {\n const buffer = getGlobalBuffer();\n if (buffer) {\n return buffer.from(bytes).toString('base64');\n }\n\n if (typeof btoa === 'function') {\n let binary = '';\n for (let index = 0; index < bytes.length; index += 1) {\n binary += String.fromCharCode(bytes[index]);\n }\n return btoa(binary);\n }\n\n throw new Error('No base64 encoder is available in this runtime.');\n}\n\nexport function encodeBytesAsDataUrl(\n bytes: Uint8Array,\n mime = 'application/octet-stream',\n): string {\n return `data:${mime};base64,${encodeBytesAsBase64(bytes)}`;\n}\n\nexport function decodeBinaryString(value: string): DecodedBinaryString {\n const decoded = tryDecodeBinaryString(value);\n if (!decoded) {\n throw new Error('Expected a base64 string or a base64 data URL.');\n }\n return decoded;\n}\n\nexport function isEncodedBinaryString(value: string): boolean {\n return tryDecodeBinaryString(value) !== null;\n}\n\nfunction tryDecodeBinaryString(value: string): DecodedBinaryString | null {\n if (value.startsWith('data:')) {\n const dataUrl = tryDecodeBase64DataUrl(value);\n if (dataUrl) {\n return dataUrl;\n }\n }\n\n const bytes = tryDecodeBase64(value);\n if (!bytes) {\n return null;\n }\n\n return {\n bytes,\n encoding: 'base64',\n };\n}\n\nfunction tryDecodeBase64DataUrl(value: string): DecodedBinaryString | null {\n const markerIndex = value.indexOf(BASE64_DATA_URL_MARKER);\n if (markerIndex === -1) {\n return null;\n }\n\n const mime = value.slice(5, markerIndex) || undefined;\n const base64 = value.slice(markerIndex + BASE64_DATA_URL_MARKER.length);\n const bytes = tryDecodeBase64(base64);\n if (!bytes) {\n return null;\n }\n\n return {\n bytes,\n mime,\n encoding: 'data-url',\n };\n}\n\nfunction tryDecodeBase64(value: string): Uint8Array | null {\n const normalized = value.replace(/\\s+/g, '');\n if (!normalized || normalized.length % 4 !== 0 || /[^A-Za-z0-9+/=]/.test(normalized)) {\n return null;\n }\n\n try {\n const buffer = getGlobalBuffer();\n if (buffer) {\n return new Uint8Array(buffer.from(normalized, 'base64'));\n }\n\n if (typeof atob === 'function') {\n const binary = atob(normalized);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n }\n } catch {\n return null;\n }\n\n throw new Error('No base64 decoder is available in this runtime.');\n}\n"],
5
+ "mappings": ";AAAA,IAAM,yBAAyB;AAiB/B,SAAS,kBAA0C;AACjD,SAAQ,WAAuC;AACjD;AAEO,SAAS,oBAAoB,OAA2B;AAC7D,QAAM,SAAS,gBAAgB;AAC/B,MAAI,QAAQ;AACV,WAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;AAAA,EAC7C;AAEA,MAAI,OAAO,SAAS,YAAY;AAC9B,QAAI,SAAS;AACb,aAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,gBAAU,OAAO,aAAa,MAAM,KAAK,CAAC;AAAA,IAC5C;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AAEA,QAAM,IAAI,MAAM,iDAAiD;AACnE;AAEO,SAAS,qBACd,OACA,OAAO,4BACC;AACR,SAAO,QAAQ,IAAI,WAAW,oBAAoB,KAAK,CAAC;AAC1D;AAEO,SAAS,mBAAmB,OAAoC;AACrE,QAAM,UAAU,sBAAsB,KAAK;AAC3C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAwB;AAC5D,SAAO,sBAAsB,KAAK,MAAM;AAC1C;AAEA,SAAS,sBAAsB,OAA2C;AACxE,MAAI,MAAM,WAAW,OAAO,GAAG;AAC7B,UAAM,UAAU,uBAAuB,KAAK;AAC5C,QAAI,SAAS;AACX,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,QAAQ,gBAAgB,KAAK;AACnC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,uBAAuB,OAA2C;AACzE,QAAM,cAAc,MAAM,QAAQ,sBAAsB;AACxD,MAAI,gBAAgB,IAAI;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,MAAM,MAAM,GAAG,WAAW,KAAK;AAC5C,QAAM,SAAS,MAAM,MAAM,cAAc,uBAAuB,MAAM;AACtE,QAAM,QAAQ,gBAAgB,MAAM;AACpC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,gBAAgB,OAAkC;AACzD,QAAM,aAAa,MAAM,QAAQ,QAAQ,EAAE;AAC3C,MAAI,CAAC,cAAc,WAAW,SAAS,MAAM,KAAK,kBAAkB,KAAK,UAAU,GAAG;AACpF,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,SAAS,gBAAgB;AAC/B,QAAI,QAAQ;AACV,aAAO,IAAI,WAAW,OAAO,KAAK,YAAY,QAAQ,CAAC;AAAA,IACzD;AAEA,QAAI,OAAO,SAAS,YAAY;AAC9B,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,eAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,cAAM,KAAK,IAAI,OAAO,WAAW,KAAK;AAAA,MACxC;AACA,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,iDAAiD;AACnE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Protocol-level chart types describe series identity and updates only. Chart
4
+ * rendering config, layouts, and UI-specific storage live in renderer packages.
5
+ */
6
+ export declare const ChartMetadataSchema: z.ZodObject<{
7
+ id: z.ZodString;
8
+ label: z.ZodString;
9
+ color: z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strip>;
11
+ export type ChartMetadata = z.infer<typeof ChartMetadataSchema>;
12
+ export declare const ChartGroupMetadataSchema: z.ZodObject<{
13
+ id: z.ZodString;
14
+ label: z.ZodString;
15
+ color: z.ZodOptional<z.ZodString>;
16
+ dataList: z.ZodOptional<z.ZodArray<z.ZodObject<{
17
+ id: z.ZodString;
18
+ label: z.ZodString;
19
+ color: z.ZodOptional<z.ZodString>;
20
+ }, z.core.$strip>>>;
21
+ }, z.core.$strip>;
22
+ export type ChartGroupMetadata = z.infer<typeof ChartGroupMetadataSchema>;
23
+ export declare const ChartUpdateDataSchema: z.ZodObject<{
24
+ id: z.ZodString;
25
+ time: z.ZodOptional<z.ZodNumber>;
26
+ value: z.ZodUnknown;
27
+ }, z.core.$strip>;
28
+ export type ChartUpdateData = z.infer<typeof ChartUpdateDataSchema>;
29
+ export declare const ChartUpdateOperationSchema: z.ZodObject<{
30
+ id: z.ZodString;
31
+ operation: z.ZodLiteral<"clear">;
32
+ }, z.core.$strip>;
33
+ export type ChartUpdateOperation = z.infer<typeof ChartUpdateOperationSchema>;
34
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../src/chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,wBAAwB;;;;;;;;;iBAEnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,qBAAqB;;;;iBAIhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
package/dist/chart.js ADDED
@@ -0,0 +1,26 @@
1
+ // src/chart.ts
2
+ import { z } from "zod";
3
+ var ChartMetadataSchema = z.object({
4
+ id: z.string(),
5
+ label: z.string(),
6
+ color: z.string().optional()
7
+ });
8
+ var ChartGroupMetadataSchema = ChartMetadataSchema.extend({
9
+ dataList: z.array(ChartMetadataSchema).optional()
10
+ });
11
+ var ChartUpdateDataSchema = z.object({
12
+ id: z.string(),
13
+ time: z.number().optional(),
14
+ value: z.unknown()
15
+ });
16
+ var ChartUpdateOperationSchema = z.object({
17
+ id: z.string(),
18
+ operation: z.literal("clear")
19
+ });
20
+ export {
21
+ ChartGroupMetadataSchema,
22
+ ChartMetadataSchema,
23
+ ChartUpdateDataSchema,
24
+ ChartUpdateOperationSchema
25
+ };
26
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/chart.ts"],
4
+ "sourcesContent": ["import { z } from 'zod';\n\n/**\n * Protocol-level chart types describe series identity and updates only. Chart\n * rendering config, layouts, and UI-specific storage live in renderer packages.\n */\nexport const ChartMetadataSchema = z.object({\n id: z.string(),\n label: z.string(),\n color: z.string().optional(),\n});\n\nexport type ChartMetadata = z.infer<typeof ChartMetadataSchema>;\n\nexport const ChartGroupMetadataSchema = ChartMetadataSchema.extend({\n dataList: z.array(ChartMetadataSchema).optional(),\n});\n\nexport type ChartGroupMetadata = z.infer<typeof ChartGroupMetadataSchema>;\n\nexport const ChartUpdateDataSchema = z.object({\n id: z.string(),\n time: z.number().optional(),\n value: z.unknown(),\n});\n\nexport type ChartUpdateData = z.infer<typeof ChartUpdateDataSchema>;\n\nexport const ChartUpdateOperationSchema = z.object({\n id: z.string(),\n operation: z.literal('clear'),\n});\n\nexport type ChartUpdateOperation = z.infer<typeof ChartUpdateOperationSchema>;\n"],
5
+ "mappings": ";AAAA,SAAS,SAAS;AAMX,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO;AAAA,EAChB,OAAO,EAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAIM,IAAM,2BAA2B,oBAAoB,OAAO;AAAA,EACjE,UAAU,EAAE,MAAM,mBAAmB,EAAE,SAAS;AAClD,CAAC;AAIM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,OAAO,EAAE,QAAQ;AACnB,CAAC;AAIM,IAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,IAAI,EAAE,OAAO;AAAA,EACb,WAAW,EAAE,QAAQ,OAAO;AAC9B,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,12 @@
1
+ import type { AnyProtocolMessage } from './types';
2
+ export type ProtocolEncoding = 'json' | 'msgpack';
3
+ export declare function detectProtocolEncoding(data: string | Uint8Array | ArrayBuffer): ProtocolEncoding;
4
+ /**
5
+ * Encode semantic protocol messages for a transport.
6
+ *
7
+ * JSON cannot carry bytes directly, so binary semantic fields become data URLs.
8
+ * MessagePack keeps those fields as Uint8Array values.
9
+ */
10
+ export declare function encodeProtocolMessage(message: AnyProtocolMessage, encoding: ProtocolEncoding): string | Uint8Array;
11
+ export declare function decodeProtocolMessage(data: string | Uint8Array | ArrayBuffer): AnyProtocolMessage;
12
+ //# sourceMappingURL=codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAAC;AAElD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,gBAAgB,GACzB,MAAM,GAAG,UAAU,CAGrB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,kBAAkB,CAOjG"}