@mearl/cloud-types
Advanced tools
+36
-0
@@ -5,2 +5,4 @@ export interface CloudMessage { | ||
| data: Record<string, any>; | ||
| /** Target a browser-side cloud connector by id / name. */ | ||
| connector?: string; | ||
| /** | ||
@@ -25,2 +27,32 @@ * Target a specific browser on the connector's machine by id / name. Omitted → | ||
| } | ||
| export interface AgentHelloMessage { | ||
| type: 'agent_hello'; | ||
| } | ||
| export interface ConnectorHelloMessage { | ||
| type: 'connector_hello'; | ||
| connectorId: string; | ||
| name: string; | ||
| version?: string; | ||
| } | ||
| export interface CloudConnectorInfo { | ||
| connectorId: string; | ||
| name: string; | ||
| version?: string; | ||
| connectedAt: string; | ||
| lastHeartbeatAt: string; | ||
| pendingRequests: number; | ||
| legacy?: boolean; | ||
| } | ||
| export interface CloudConnectorListResult { | ||
| count: number; | ||
| connectors: CloudConnectorInfo[]; | ||
| } | ||
| export type CloudConnectorSelectorResult<T> = { | ||
| status: 'matched'; | ||
| connector: T; | ||
| } | { | ||
| status: 'ambiguous'; | ||
| } | { | ||
| status: 'not_found'; | ||
| }; | ||
| export declare const MAX_BUFFER_SIZE: number; | ||
@@ -31,4 +63,8 @@ export declare const DEFAULT_REQUEST_TIMEOUT = 60; | ||
| export declare const DEFAULT_HEARTBEAT_TIMEOUT = 90; | ||
| /** Resolve connector targets with one precedence order shared by routing and diagnostics. */ | ||
| export declare function resolveCloudConnectorSelector<T extends Pick<ConnectorHelloMessage, 'connectorId' | 'name'>>(connectors: readonly T[], selector: string): CloudConnectorSelectorResult<T>; | ||
| export declare function isHeartbeatMessage(msg: any): msg is HeartbeatMessage; | ||
| export declare function isAgentHelloMessage(msg: any): msg is AgentHelloMessage; | ||
| export declare function isConnectorHelloMessage(msg: any): msg is ConnectorHelloMessage; | ||
| export declare function isCloudMessage(msg: any): msg is CloudMessage; | ||
| export declare function isCloudResponse(msg: any): msg is CloudResponse; |
+41
-1
@@ -6,7 +6,47 @@ export const MAX_BUFFER_SIZE = 10 * 1024 * 1024; | ||
| export const DEFAULT_HEARTBEAT_TIMEOUT = 90; | ||
| /** Resolve connector targets with one precedence order shared by routing and diagnostics. */ | ||
| export function resolveCloudConnectorSelector(connectors, selector) { | ||
| const normalized = selector.trim().toLowerCase(); | ||
| if (!normalized) | ||
| return { status: 'not_found' }; | ||
| const resolveMatches = (matches) => { | ||
| if (matches.length === 1) | ||
| return { status: 'matched', connector: matches[0] }; | ||
| if (matches.length > 1) | ||
| return { status: 'ambiguous' }; | ||
| return null; | ||
| }; | ||
| const exactId = resolveMatches(connectors.filter(connector => connector.connectorId.toLowerCase() === normalized)); | ||
| if (exactId) | ||
| return exactId; | ||
| const exactName = resolveMatches(connectors.filter(connector => connector.name.toLowerCase() === normalized)); | ||
| if (exactName) | ||
| return exactName; | ||
| return (resolveMatches(connectors.filter(connector => connector.connectorId.toLowerCase().includes(normalized) || | ||
| connector.name.toLowerCase().includes(normalized))) ?? { status: 'not_found' }); | ||
| } | ||
| export function isHeartbeatMessage(msg) { | ||
| return msg && (msg.type === 'ping' || msg.type === 'pong'); | ||
| } | ||
| export function isAgentHelloMessage(msg) { | ||
| return msg?.type === 'agent_hello'; | ||
| } | ||
| export function isConnectorHelloMessage(msg) { | ||
| return (msg?.type === 'connector_hello' && | ||
| typeof msg.connectorId === 'string' && | ||
| msg.connectorId.length > 0 && | ||
| msg.connectorId.length <= 128 && | ||
| /^[A-Za-z0-9._:-]+$/.test(msg.connectorId) && | ||
| typeof msg.name === 'string' && | ||
| msg.name.length > 0 && | ||
| msg.name.length <= 128 && | ||
| !/\p{Cc}/u.test(msg.name) && | ||
| (msg.version === undefined || typeof msg.version === 'string')); | ||
| } | ||
| export function isCloudMessage(msg) { | ||
| return msg && typeof msg.id === 'string' && typeof msg.action === 'string'; | ||
| return (msg && | ||
| typeof msg.id === 'string' && | ||
| typeof msg.action === 'string' && | ||
| (msg.connector === undefined || typeof msg.connector === 'string') && | ||
| (msg.browser === undefined || typeof msg.browser === 'string')); | ||
| } | ||
@@ -13,0 +53,0 @@ export function isCloudResponse(msg) { |
+1
-1
| { | ||
| "name": "@mearl/cloud-types", | ||
| "version": "2.1.0", | ||
| "version": "2.2.0", | ||
| "description": "Shared types for Mearl cloud communication packages", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+18
-5
@@ -18,2 +18,3 @@ # @mearl/cloud-types | ||
| data: Record<string, any>; | ||
| connector?: string; | ||
| browser?: string; | ||
@@ -35,2 +36,13 @@ timeoutSec?: number; | ||
| } | ||
| interface AgentHelloMessage { | ||
| type: 'agent_hello'; | ||
| } | ||
| interface ConnectorHelloMessage { | ||
| type: 'connector_hello'; | ||
| connectorId: string; | ||
| name: string; | ||
| version?: string; | ||
| } | ||
| ``` | ||
@@ -41,2 +53,4 @@ | ||
| ```typescript | ||
| isAgentHelloMessage(msg): msg is AgentHelloMessage | ||
| isConnectorHelloMessage(msg): msg is ConnectorHelloMessage | ||
| isHeartbeatMessage(msg): msg is HeartbeatMessage | ||
@@ -47,2 +61,5 @@ isCloudMessage(msg): msg is CloudMessage | ||
| `resolveCloudConnectorSelector(connectors, selector)` 按精确 ID、精确名称、唯一模糊匹配的 | ||
| 顺序解析 connector 目标,并区分匹配、歧义和未找到。 | ||
| ### 常量 | ||
@@ -61,7 +78,3 @@ | ||
| ```typescript | ||
| import { | ||
| type CloudMessage, | ||
| isCloudResponse, | ||
| DEFAULT_REQUEST_TIMEOUT, | ||
| } from '@mearl/cloud-types'; | ||
| import { type CloudMessage, isCloudResponse, DEFAULT_REQUEST_TIMEOUT } from '@mearl/cloud-types'; | ||
| ``` | ||
@@ -68,0 +81,0 @@ |
7247
93.25%121
168.89%88
17.33%