@furlow/pipes 0.1.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/dist/database/index.d.ts +3 -0
- package/dist/database/index.js +8 -0
- package/dist/database/index.js.map +1 -0
- package/dist/file/index.d.ts +3 -0
- package/dist/file/index.js +8 -0
- package/dist/file/index.js.map +1 -0
- package/dist/http/index.d.ts +61 -0
- package/dist/http/index.js +156 -0
- package/dist/http/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1282 -0
- package/dist/index.js.map +1 -0
- package/dist/mqtt/index.d.ts +82 -0
- package/dist/mqtt/index.js +277 -0
- package/dist/mqtt/index.js.map +1 -0
- package/dist/tcp/index.d.ts +167 -0
- package/dist/tcp/index.js +462 -0
- package/dist/tcp/index.js.map +1 -0
- package/dist/types-BW9r2ksN.d.ts +152 -0
- package/dist/webhook/index.d.ts +70 -0
- package/dist/webhook/index.js +169 -0
- package/dist/webhook/index.js.map +1 -0
- package/dist/websocket/index.d.ts +84 -0
- package/dist/websocket/index.js +226 -0
- package/dist/websocket/index.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/http/index.ts","../src/websocket/index.ts","../src/webhook/index.ts","../src/mqtt/index.ts","../src/tcp/index.ts","../src/tcp/udp.ts"],"sourcesContent":["/**\n * HTTP pipe for REST API integrations\n */\n\nimport axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios';\nimport type { HttpPipeConfig, Pipe, PipeResponse } from '../types.js';\n\nexport interface HttpPipeOptions {\n name: string;\n config: HttpPipeConfig;\n}\n\nexport class HttpPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'http';\n private client: AxiosInstance;\n private config: HttpPipeConfig;\n private requestCount = 0;\n private windowStart = Date.now();\n\n constructor(options: HttpPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n\n this.client = axios.create({\n baseURL: options.config.base_url,\n timeout: this.parseDuration(options.config.timeout ?? '30s'),\n headers: options.config.headers as Record<string, string>,\n });\n\n // Add auth interceptor\n if (options.config.auth) {\n this.client.interceptors.request.use((config) => {\n const auth = options.config.auth!;\n switch (auth.type) {\n case 'bearer':\n config.headers.Authorization = `Bearer ${auth.token}`;\n break;\n case 'basic':\n const credentials = Buffer.from(`${auth.username}:${auth.password}`).toString('base64');\n config.headers.Authorization = `Basic ${credentials}`;\n break;\n case 'header':\n const headerName = auth.header_name ?? 'Authorization';\n config.headers[headerName] = auth.token as string;\n break;\n }\n return config;\n });\n }\n }\n\n isConnected(): boolean {\n return true; // HTTP is stateless\n }\n\n /**\n * Make an HTTP request\n */\n async request<T = unknown>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n options: {\n body?: Record<string, unknown>;\n headers?: Record<string, string>;\n params?: Record<string, string>;\n } = {}\n ): Promise<PipeResponse<T>> {\n // Check rate limit\n if (this.config.rate_limit) {\n const now = Date.now();\n const windowMs = this.parseDuration(this.config.rate_limit.per);\n\n if (now - this.windowStart >= windowMs) {\n this.requestCount = 0;\n this.windowStart = now;\n }\n\n if (this.requestCount >= this.config.rate_limit.requests) {\n return {\n success: false,\n error: 'Rate limit exceeded',\n status: 429,\n };\n }\n\n this.requestCount++;\n }\n\n const config: AxiosRequestConfig = {\n method,\n url: path,\n data: options.body,\n headers: options.headers,\n params: options.params,\n };\n\n try {\n const response = await this.requestWithRetry(config);\n\n return {\n success: true,\n data: response.data as T,\n status: response.status,\n headers: response.headers as Record<string, string>,\n };\n } catch (error) {\n if (axios.isAxiosError(error)) {\n return {\n success: false,\n error: error.message,\n status: error.response?.status,\n data: error.response?.data as T,\n };\n }\n\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Make a request with retry logic\n */\n private async requestWithRetry(\n config: AxiosRequestConfig,\n attempt = 0\n ): Promise<any> {\n try {\n return await this.client.request(config);\n } catch (error) {\n const maxAttempts = this.config.retry?.attempts ?? 0;\n const delay = this.parseDuration(this.config.retry?.delay ?? '1s');\n\n if (attempt < maxAttempts && axios.isAxiosError(error)) {\n // Retry on 5xx errors or network errors\n if (!error.response || error.response.status >= 500) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n return this.requestWithRetry(config, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Convenience methods\n */\n async get<T = unknown>(\n path: string,\n options?: { headers?: Record<string, string>; params?: Record<string, string> }\n ): Promise<PipeResponse<T>> {\n return this.request<T>('GET', path, options);\n }\n\n async post<T = unknown>(\n path: string,\n body?: Record<string, unknown>,\n options?: { headers?: Record<string, string> }\n ): Promise<PipeResponse<T>> {\n return this.request<T>('POST', path, { body, ...options });\n }\n\n async put<T = unknown>(\n path: string,\n body?: Record<string, unknown>,\n options?: { headers?: Record<string, string> }\n ): Promise<PipeResponse<T>> {\n return this.request<T>('PUT', path, { body, ...options });\n }\n\n async patch<T = unknown>(\n path: string,\n body?: Record<string, unknown>,\n options?: { headers?: Record<string, string> }\n ): Promise<PipeResponse<T>> {\n return this.request<T>('PATCH', path, { body, ...options });\n }\n\n async delete<T = unknown>(\n path: string,\n options?: { headers?: Record<string, string> }\n ): Promise<PipeResponse<T>> {\n return this.request<T>('DELETE', path, options);\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m|h)?$/);\n if (!match) return 30000;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2] ?? 's';\n\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return value * 1000;\n }\n }\n}\n\n/**\n * Create an HTTP pipe\n */\nexport function createHttpPipe(options: HttpPipeOptions): HttpPipe {\n return new HttpPipe(options);\n}\n","/**\n * WebSocket pipe for bidirectional communication\n */\n\nimport WebSocket from 'ws';\nimport type { Pipe, PipeResponse, WebSocketPipeConfig } from '../types.js';\n\nexport interface WebSocketPipeOptions {\n name: string;\n config: WebSocketPipeConfig;\n}\n\nexport type WebSocketMessageHandler = (data: unknown) => void | Promise<void>;\n\nexport class WebSocketPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'websocket';\n private ws: WebSocket | null = null;\n private config: WebSocketPipeConfig;\n private reconnectAttempts = 0;\n private reconnecting = false;\n private heartbeatInterval: NodeJS.Timeout | null = null;\n private messageHandlers: Map<string, WebSocketMessageHandler[]> = new Map();\n private connected = false;\n\n constructor(options: WebSocketPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n const headers = this.config.headers as Record<string, string>;\n this.ws = new WebSocket(this.config.url, { headers });\n\n this.ws.on('open', () => {\n this.connected = true;\n this.reconnectAttempts = 0;\n this.reconnecting = false;\n this.startHeartbeat();\n resolve();\n });\n\n this.ws.on('message', (data) => {\n this.handleMessage(data);\n });\n\n this.ws.on('close', () => {\n this.connected = false;\n this.stopHeartbeat();\n this.handleDisconnect();\n });\n\n this.ws.on('error', (error) => {\n if (!this.connected) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the server\n */\n async disconnect(): Promise<void> {\n this.stopHeartbeat();\n this.reconnecting = false;\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n\n this.connected = false;\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected && this.ws?.readyState === WebSocket.OPEN;\n }\n\n /**\n * Send a message\n */\n send(data: unknown): boolean {\n if (!this.isConnected()) {\n return false;\n }\n\n const message = typeof data === 'string' ? data : JSON.stringify(data);\n this.ws!.send(message);\n return true;\n }\n\n /**\n * Send and wait for a response (request-response pattern)\n */\n async request<T = unknown>(\n data: unknown,\n options: { timeout?: number; responseEvent?: string } = {}\n ): Promise<PipeResponse<T>> {\n const { timeout = 30000, responseEvent = 'response' } = options;\n\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n this.off(responseEvent, handler);\n resolve({ success: false, error: 'Request timeout' });\n }, timeout);\n\n const handler = (response: unknown) => {\n clearTimeout(timer);\n this.off(responseEvent, handler);\n resolve({ success: true, data: response as T });\n };\n\n this.on(responseEvent, handler);\n this.send(data);\n });\n }\n\n /**\n * Register a message handler\n */\n on(event: string, handler: WebSocketMessageHandler): void {\n const handlers = this.messageHandlers.get(event) ?? [];\n handlers.push(handler);\n this.messageHandlers.set(event, handlers);\n }\n\n /**\n * Remove a message handler\n */\n off(event: string, handler: WebSocketMessageHandler): void {\n const handlers = this.messageHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event to handlers\n */\n private emit(event: string, data: unknown): void {\n const handlers = this.messageHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`WebSocket handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming messages\n */\n private handleMessage(rawData: WebSocket.RawData): void {\n let data: unknown;\n\n try {\n const str = rawData.toString();\n data = JSON.parse(str);\n } catch {\n data = rawData.toString();\n }\n\n // Emit to 'message' handlers\n this.emit('message', data);\n\n // Check for event field in JSON messages\n if (typeof data === 'object' && data !== null && 'event' in data) {\n const event = (data as { event: string }).event;\n this.emit(event, data);\n }\n }\n\n /**\n * Handle disconnection\n */\n private handleDisconnect(): void {\n if (!this.config.reconnect?.enabled || this.reconnecting) {\n return;\n }\n\n const maxAttempts = this.config.reconnect.max_attempts ?? 10;\n const delay = this.parseDuration(this.config.reconnect.delay ?? '5s');\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.emit('reconnect_failed', { attempts: this.reconnectAttempts });\n return;\n }\n\n this.reconnecting = true;\n this.reconnectAttempts++;\n\n setTimeout(async () => {\n try {\n await this.connect();\n this.emit('reconnected', { attempts: this.reconnectAttempts });\n } catch {\n this.reconnecting = false;\n this.handleDisconnect();\n }\n }, delay);\n }\n\n /**\n * Start heartbeat\n */\n private startHeartbeat(): void {\n if (!this.config.heartbeat?.interval) return;\n\n const interval = this.parseDuration(this.config.heartbeat.interval);\n const message = this.config.heartbeat.message ?? 'ping';\n\n this.heartbeatInterval = setInterval(() => {\n if (this.isConnected()) {\n this.send(message);\n }\n }, interval);\n }\n\n /**\n * Stop heartbeat\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m|h)?$/);\n if (!match) return 5000;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2] ?? 's';\n\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return value * 1000;\n }\n }\n}\n\n/**\n * Create a WebSocket pipe\n */\nexport function createWebSocketPipe(options: WebSocketPipeOptions): WebSocketPipe {\n return new WebSocketPipe(options);\n}\n","/**\n * Webhook pipe for incoming and outgoing webhooks\n */\n\nimport { createHmac } from 'node:crypto';\nimport type { Pipe, PipeResponse, WebhookPipeConfig } from '../types.js';\n\nexport interface WebhookPipeOptions {\n name: string;\n config: WebhookPipeConfig;\n}\n\nexport type WebhookHandler = (\n body: unknown,\n headers: Record<string, string>\n) => void | Promise<void>;\n\nexport class WebhookPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'webhook';\n private config: WebhookPipeConfig;\n private handlers: WebhookHandler[] = [];\n\n constructor(options: WebhookPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n isConnected(): boolean {\n return true;\n }\n\n /**\n * Get the webhook path\n */\n getPath(): string {\n return this.config.path;\n }\n\n /**\n * Get the expected method\n */\n getMethod(): string {\n return this.config.method ?? 'POST';\n }\n\n /**\n * Register a handler for incoming webhooks\n */\n onWebhook(handler: WebhookHandler): () => void {\n this.handlers.push(handler);\n return () => {\n const index = this.handlers.indexOf(handler);\n if (index !== -1) {\n this.handlers.splice(index, 1);\n }\n };\n }\n\n /**\n * Handle an incoming webhook request\n */\n async handleRequest(\n body: unknown,\n headers: Record<string, string>\n ): Promise<PipeResponse> {\n // Verify signature if configured\n if (this.config.verification) {\n const valid = this.verifySignature(body, headers);\n if (!valid) {\n return { success: false, error: 'Invalid signature', status: 401 };\n }\n }\n\n // Call handlers\n for (const handler of this.handlers) {\n try {\n await handler(body, headers);\n } catch (error) {\n console.error(`Webhook handler error:`, error);\n }\n }\n\n // Check for config handlers\n if (this.config.handlers) {\n // These would be processed by the action executor\n }\n\n return { success: true, status: 200 };\n }\n\n /**\n * Verify webhook signature\n */\n private verifySignature(\n body: unknown,\n headers: Record<string, string>\n ): boolean {\n if (!this.config.verification) return true;\n\n const { type, secret, header, algorithm } = this.config.verification;\n const signatureHeader = header ?? 'x-signature';\n const receivedSignature = headers[signatureHeader.toLowerCase()];\n\n if (!receivedSignature || !secret) {\n return false;\n }\n\n const bodyString = typeof body === 'string' ? body : JSON.stringify(body);\n\n switch (type) {\n case 'hmac': {\n const algo = algorithm ?? 'sha256';\n const expectedSignature = createHmac(algo, secret)\n .update(bodyString)\n .digest('hex');\n\n // Handle both raw and prefixed signatures\n const cleanReceived = receivedSignature.replace(/^sha\\d+=/, '');\n return this.timingSafeEqual(cleanReceived, expectedSignature);\n }\n\n case 'token': {\n return receivedSignature === secret;\n }\n\n case 'signature': {\n // Custom signature verification\n // This would depend on the specific service\n return true;\n }\n\n default:\n return true;\n }\n }\n\n /**\n * Timing-safe string comparison\n */\n private timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n }\n}\n\n/**\n * Outgoing webhook sender\n */\nexport class WebhookSender {\n /**\n * Send a Discord webhook\n */\n static async sendDiscordWebhook(\n url: string,\n options: {\n content?: string;\n username?: string;\n avatar_url?: string;\n embeds?: Record<string, unknown>[];\n }\n ): Promise<PipeResponse> {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(options),\n });\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status}`,\n status: response.status,\n };\n }\n\n return { success: true, status: response.status };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n\n /**\n * Send a generic webhook\n */\n static async send(\n url: string,\n body: unknown,\n options: { headers?: Record<string, string>; method?: string } = {}\n ): Promise<PipeResponse> {\n try {\n const response = await fetch(url, {\n method: options.method ?? 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n body: typeof body === 'string' ? body : JSON.stringify(body),\n });\n\n let data: unknown;\n try {\n data = await response.json();\n } catch {\n data = await response.text();\n }\n\n return {\n success: response.ok,\n data,\n status: response.status,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n }\n}\n\n/**\n * Create a webhook pipe\n */\nexport function createWebhookPipe(options: WebhookPipeOptions): WebhookPipe {\n return new WebhookPipe(options);\n}\n","/**\n * MQTT pipe for IoT and real-time integrations\n */\n\nimport mqtt, { MqttClient, IClientOptions, IClientPublishOptions } from 'mqtt';\nimport type { Pipe, PipeResponse, MqttPipeConfig, MqttQoS } from '../types.js';\n\nexport interface MqttPipeOptions {\n name: string;\n config: MqttPipeConfig;\n}\n\nexport type MqttMessageHandler = (\n topic: string,\n payload: Buffer | string | Record<string, unknown>,\n packet: unknown\n) => void | Promise<void>;\n\nexport class MqttPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'mqtt';\n private client: MqttClient | null = null;\n private config: MqttPipeConfig;\n private connected = false;\n private reconnectAttempts = 0;\n private messageHandlers: Map<string, MqttMessageHandler[]> = new Map();\n private wildcardHandlers: Map<string, MqttMessageHandler[]> = new Map();\n\n constructor(options: MqttPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Connect to the MQTT broker\n */\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const protocol = this.config.protocol ?? 'mqtt';\n const port = this.config.port ?? (protocol === 'mqtts' || protocol === 'wss' ? 8883 : 1883);\n const url = `${protocol}://${this.config.broker}:${port}`;\n\n const options: IClientOptions = {\n keepalive: this.config.keepalive ?? 60,\n clean: this.config.clean ?? true,\n reconnectPeriod: this.config.reconnect?.enabled !== false\n ? this.parseDuration(this.config.reconnect?.delay ?? '5s')\n : 0,\n };\n\n // Authentication\n if (this.config.auth) {\n if (this.config.auth.username) options.username = this.config.auth.username;\n if (this.config.auth.password) options.password = this.config.auth.password;\n if (this.config.auth.clientId) options.clientId = this.config.auth.clientId;\n }\n\n // Last Will and Testament\n if (this.config.will) {\n options.will = {\n topic: this.config.will.topic,\n payload: Buffer.from(this.config.will.payload),\n qos: this.config.will.qos ?? 0,\n retain: this.config.will.retain ?? false,\n };\n }\n\n try {\n this.client = mqtt.connect(url, options);\n\n this.client.on('connect', () => {\n this.connected = true;\n this.reconnectAttempts = 0;\n this.emit('connected', {});\n resolve();\n });\n\n this.client.on('message', (topic, payload, packet) => {\n this.handleMessage(topic, payload, packet);\n });\n\n this.client.on('error', (error) => {\n if (!this.connected) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n this.client.on('close', () => {\n this.connected = false;\n this.emit('disconnected', {});\n });\n\n this.client.on('reconnect', () => {\n this.reconnectAttempts++;\n this.emit('reconnecting', { attempts: this.reconnectAttempts });\n });\n\n this.client.on('offline', () => {\n this.connected = false;\n this.emit('offline', {});\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the broker\n */\n async disconnect(): Promise<void> {\n return new Promise((resolve) => {\n if (this.client) {\n this.client.end(false, {}, () => {\n this.client = null;\n this.connected = false;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected && this.client?.connected === true;\n }\n\n /**\n * Subscribe to a topic\n */\n async subscribe(\n topic: string,\n options: { qos?: MqttQoS } = {}\n ): Promise<PipeResponse> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n this.client!.subscribe(topic, { qos: options.qos ?? 0 }, (error, granted) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true, data: granted });\n }\n });\n });\n }\n\n /**\n * Unsubscribe from a topic\n */\n async unsubscribe(topic: string): Promise<PipeResponse> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n this.client!.unsubscribe(topic, {}, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Publish a message to a topic\n */\n async publish(\n topic: string,\n message: string | Buffer | Record<string, unknown>,\n options: { qos?: MqttQoS; retain?: boolean } = {}\n ): Promise<PipeResponse> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n const payload = typeof message === 'object' && !Buffer.isBuffer(message)\n ? JSON.stringify(message)\n : message;\n\n const publishOptions: IClientPublishOptions = {\n qos: options.qos ?? 0,\n retain: options.retain ?? false,\n };\n\n return new Promise((resolve) => {\n this.client!.publish(topic, payload, publishOptions, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Register a handler for a specific topic\n * Supports MQTT wildcards: + (single level), # (multi level)\n */\n on(topic: string, handler: MqttMessageHandler): void {\n if (topic.includes('+') || topic.includes('#')) {\n // Wildcard topic - store in wildcardHandlers\n const handlers = this.wildcardHandlers.get(topic) ?? [];\n handlers.push(handler);\n this.wildcardHandlers.set(topic, handlers);\n } else {\n // Exact topic\n const handlers = this.messageHandlers.get(topic) ?? [];\n handlers.push(handler);\n this.messageHandlers.set(topic, handlers);\n }\n }\n\n /**\n * Remove a handler\n */\n off(topic: string, handler: MqttMessageHandler): void {\n const map = topic.includes('+') || topic.includes('#')\n ? this.wildcardHandlers\n : this.messageHandlers;\n\n const handlers = map.get(topic) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit to handlers\n */\n private emit(event: string, data: unknown): void {\n const handlers = this.messageHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(event, data as Buffer, {});\n } catch (error) {\n console.error(`MQTT handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming messages\n */\n private handleMessage(topic: string, payload: Buffer, packet: unknown): void {\n // Parse payload\n let parsedPayload: Buffer | string | Record<string, unknown> = payload;\n try {\n const str = payload.toString();\n parsedPayload = JSON.parse(str);\n } catch {\n parsedPayload = payload.toString();\n }\n\n // Call exact topic handlers\n const exactHandlers = this.messageHandlers.get(topic) ?? [];\n for (const handler of exactHandlers) {\n try {\n handler(topic, parsedPayload, packet);\n } catch (error) {\n console.error(`MQTT handler error for topic \"${topic}\":`, error);\n }\n }\n\n // Check wildcard handlers\n for (const [pattern, handlers] of this.wildcardHandlers) {\n if (this.topicMatches(pattern, topic)) {\n for (const handler of handlers) {\n try {\n handler(topic, parsedPayload, packet);\n } catch (error) {\n console.error(`MQTT wildcard handler error for pattern \"${pattern}\":`, error);\n }\n }\n }\n }\n\n // Emit to generic message handlers\n this.emit('message', { topic, payload: parsedPayload, packet });\n }\n\n /**\n * Check if a topic matches a pattern with MQTT wildcards\n */\n private topicMatches(pattern: string, topic: string): boolean {\n const patternParts = pattern.split('/');\n const topicParts = topic.split('/');\n\n for (let i = 0; i < patternParts.length; i++) {\n const patternPart = patternParts[i];\n\n // Multi-level wildcard matches everything remaining\n if (patternPart === '#') {\n return true;\n }\n\n // Topic is shorter than pattern\n if (i >= topicParts.length) {\n return false;\n }\n\n // Single-level wildcard matches any single level\n if (patternPart === '+') {\n continue;\n }\n\n // Exact match required\n if (patternPart !== topicParts[i]) {\n return false;\n }\n }\n\n // Pattern and topic should be same length (unless # was used)\n return patternParts.length === topicParts.length;\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m|h)?$/);\n if (!match) return 5000;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2] ?? 's';\n\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return value * 1000;\n }\n }\n}\n\n/**\n * Create an MQTT pipe\n */\nexport function createMqttPipe(options: MqttPipeOptions): MqttPipe {\n return new MqttPipe(options);\n}\n","/**\n * TCP pipe for raw socket communication\n */\n\nimport { Socket, createConnection, createServer, Server } from 'net';\nimport type { Pipe, PipeResponse, TcpPipeConfig } from '../types.js';\n\nexport interface TcpPipeOptions {\n name: string;\n config: TcpPipeConfig;\n}\n\nexport type TcpDataHandler = (data: Buffer | string) => void | Promise<void>;\nexport type TcpEventHandler = (data?: unknown) => void | Promise<void>;\n\nexport class TcpPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'tcp';\n private socket: Socket | null = null;\n private server: Server | null = null;\n private config: TcpPipeConfig;\n private connected = false;\n private reconnectAttempts = 0;\n private reconnecting = false;\n private dataHandlers: TcpDataHandler[] = [];\n private eventHandlers: Map<string, TcpEventHandler[]> = new Map();\n\n constructor(options: TcpPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Connect to a TCP server (client mode)\n */\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.socket = createConnection({\n host: this.config.host,\n port: this.config.port,\n });\n\n this.socket.setEncoding(this.config.encoding ?? 'utf8');\n\n this.socket.on('connect', () => {\n this.connected = true;\n this.reconnectAttempts = 0;\n this.reconnecting = false;\n this.emit('connected');\n resolve();\n });\n\n this.socket.on('data', (data) => {\n this.handleData(data);\n });\n\n this.socket.on('close', () => {\n this.connected = false;\n this.emit('disconnected');\n this.handleDisconnect();\n });\n\n this.socket.on('error', (error) => {\n if (!this.connected) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n this.socket.on('end', () => {\n this.connected = false;\n this.emit('end');\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Start a TCP server (server mode)\n */\n async listen(port?: number): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.server = createServer((socket) => {\n socket.setEncoding(this.config.encoding ?? 'utf8');\n\n socket.on('data', (data) => {\n this.handleData(data);\n });\n\n socket.on('error', (error) => {\n this.emit('client_error', error);\n });\n\n this.emit('connection', socket);\n });\n\n this.server.on('error', (error) => {\n reject(error);\n });\n\n this.server.listen(port ?? this.config.port, () => {\n this.connected = true;\n this.emit('listening');\n resolve();\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect / close\n */\n async disconnect(): Promise<void> {\n this.reconnecting = false;\n\n return new Promise((resolve) => {\n if (this.socket) {\n this.socket.end(() => {\n this.socket?.destroy();\n this.socket = null;\n this.connected = false;\n resolve();\n });\n } else if (this.server) {\n this.server.close(() => {\n this.server = null;\n this.connected = false;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Send data\n */\n async send(data: Buffer | string): Promise<PipeResponse> {\n if (!this.socket || !this.connected) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n this.socket!.write(data, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Send and wait for response (request-response pattern)\n */\n async request<T = string>(\n data: Buffer | string,\n options: { timeout?: number } = {}\n ): Promise<PipeResponse<T>> {\n const { timeout = 30000 } = options;\n\n if (!this.socket || !this.connected) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n this.offData(handler);\n resolve({ success: false, error: 'Request timeout' });\n }, timeout);\n\n const handler = (response: Buffer | string) => {\n clearTimeout(timer);\n this.offData(handler);\n resolve({ success: true, data: response as T });\n };\n\n this.onData(handler);\n this.send(data);\n });\n }\n\n /**\n * Register a data handler\n */\n onData(handler: TcpDataHandler): void {\n this.dataHandlers.push(handler);\n }\n\n /**\n * Remove a data handler\n */\n offData(handler: TcpDataHandler): void {\n const index = this.dataHandlers.indexOf(handler);\n if (index !== -1) {\n this.dataHandlers.splice(index, 1);\n }\n }\n\n /**\n * Register an event handler\n */\n on(event: string, handler: TcpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n handlers.push(handler);\n this.eventHandlers.set(event, handlers);\n }\n\n /**\n * Remove an event handler\n */\n off(event: string, handler: TcpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: string, data?: unknown): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`TCP handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming data\n */\n private handleData(data: Buffer | string): void {\n for (const handler of this.dataHandlers) {\n try {\n handler(data);\n } catch (error) {\n console.error('TCP data handler error:', error);\n }\n }\n this.emit('data', data);\n }\n\n /**\n * Handle disconnection with reconnect logic\n */\n private handleDisconnect(): void {\n if (!this.config.reconnect?.enabled || this.reconnecting) {\n return;\n }\n\n const maxAttempts = this.config.reconnect.max_attempts ?? 10;\n const delay = this.parseDuration(this.config.reconnect.delay ?? '5s');\n\n if (this.reconnectAttempts >= maxAttempts) {\n this.emit('reconnect_failed', { attempts: this.reconnectAttempts });\n return;\n }\n\n this.reconnecting = true;\n this.reconnectAttempts++;\n\n setTimeout(async () => {\n try {\n await this.connect();\n this.emit('reconnected', { attempts: this.reconnectAttempts });\n } catch {\n this.reconnecting = false;\n this.handleDisconnect();\n }\n }, delay);\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m|h)?$/);\n if (!match) return 5000;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2] ?? 's';\n\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return value * 1000;\n }\n }\n}\n\n/**\n * Create a TCP pipe\n */\nexport function createTcpPipe(options: TcpPipeOptions): TcpPipe {\n return new TcpPipe(options);\n}\n\n// Re-export UDP pipe\nexport * from './udp.js';\n","/**\n * UDP pipe for datagram communication\n */\n\nimport { createSocket, Socket, RemoteInfo } from 'dgram';\nimport type { Pipe, PipeResponse, UdpPipeConfig } from '../types.js';\n\nexport interface UdpPipeOptions {\n name: string;\n config: UdpPipeConfig;\n}\n\nexport interface UdpMessage {\n data: Buffer;\n rinfo: RemoteInfo;\n}\n\nexport type UdpMessageHandler = (msg: UdpMessage) => void | Promise<void>;\nexport type UdpEventHandler = (data?: unknown) => void | Promise<void>;\n\nexport class UdpPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'udp';\n private socket: Socket | null = null;\n private config: UdpPipeConfig;\n private bound = false;\n private messageHandlers: UdpMessageHandler[] = [];\n private eventHandlers: Map<string, UdpEventHandler[]> = new Map();\n\n constructor(options: UdpPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Bind to a port to receive messages\n */\n async bind(port?: number): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.socket = createSocket('udp4');\n\n this.socket.on('message', (msg, rinfo) => {\n this.handleMessage(msg, rinfo);\n });\n\n this.socket.on('error', (error) => {\n if (!this.bound) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n this.socket.on('listening', () => {\n this.bound = true;\n const address = this.socket!.address();\n this.emit('listening', address);\n resolve();\n });\n\n // Setup broadcast if configured\n if (this.config.broadcast) {\n this.socket.setBroadcast(true);\n }\n\n // Bind to port\n const bindPort = port ?? this.config.port;\n const bindHost = this.config.host ?? '0.0.0.0';\n this.socket.bind(bindPort, bindHost, () => {\n // Join multicast group if configured\n if (this.config.multicast) {\n this.socket!.addMembership(this.config.multicast);\n }\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Close the socket\n */\n async disconnect(): Promise<void> {\n return new Promise((resolve) => {\n if (this.socket) {\n this.socket.close(() => {\n this.socket = null;\n this.bound = false;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Check if bound\n */\n isConnected(): boolean {\n return this.bound;\n }\n\n /**\n * Send data to a specific host and port\n */\n async send(\n data: Buffer | string,\n host: string,\n port: number\n ): Promise<PipeResponse> {\n if (!this.socket) {\n // Create socket if not exists (for send-only mode)\n this.socket = createSocket('udp4');\n if (this.config.broadcast) {\n this.socket.setBroadcast(true);\n }\n }\n\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n\n return new Promise((resolve) => {\n this.socket!.send(buffer, port, host, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Broadcast data to all hosts on the network\n */\n async broadcast(\n data: Buffer | string,\n port: number,\n address = '255.255.255.255'\n ): Promise<PipeResponse> {\n if (!this.socket) {\n this.socket = createSocket('udp4');\n this.socket.setBroadcast(true);\n }\n\n const buffer = typeof data === 'string' ? Buffer.from(data) : data;\n\n return new Promise((resolve) => {\n this.socket!.send(buffer, port, address, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Send to multicast group\n */\n async multicast(\n data: Buffer | string,\n port: number,\n group?: string\n ): Promise<PipeResponse> {\n const multicastGroup = group ?? this.config.multicast;\n if (!multicastGroup) {\n return { success: false, error: 'No multicast group configured' };\n }\n\n return this.send(data, multicastGroup, port);\n }\n\n /**\n * Register a message handler\n */\n onMessage(handler: UdpMessageHandler): void {\n this.messageHandlers.push(handler);\n }\n\n /**\n * Remove a message handler\n */\n offMessage(handler: UdpMessageHandler): void {\n const index = this.messageHandlers.indexOf(handler);\n if (index !== -1) {\n this.messageHandlers.splice(index, 1);\n }\n }\n\n /**\n * Register an event handler\n */\n on(event: string, handler: UdpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n handlers.push(handler);\n this.eventHandlers.set(event, handlers);\n }\n\n /**\n * Remove an event handler\n */\n off(event: string, handler: UdpEventHandler): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event\n */\n private emit(event: string, data?: unknown): void {\n const handlers = this.eventHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n console.error(`UDP handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming messages\n */\n private handleMessage(data: Buffer, rinfo: RemoteInfo): void {\n const msg: UdpMessage = { data, rinfo };\n\n for (const handler of this.messageHandlers) {\n try {\n handler(msg);\n } catch (error) {\n console.error('UDP message handler error:', error);\n }\n }\n\n this.emit('message', msg);\n }\n}\n\n/**\n * Create a UDP pipe\n */\nexport function createUdpPipe(options: UdpPipeOptions): UdpPipe {\n return new UdpPipe(options);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { P as Pipe, d as MqttPipeConfig, e as MqttQoS, f as PipeResponse } from '../types-BW9r2ksN.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MQTT pipe for IoT and real-time integrations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface MqttPipeOptions {
|
|
8
|
+
name: string;
|
|
9
|
+
config: MqttPipeConfig;
|
|
10
|
+
}
|
|
11
|
+
type MqttMessageHandler = (topic: string, payload: Buffer | string | Record<string, unknown>, packet: unknown) => void | Promise<void>;
|
|
12
|
+
declare class MqttPipe implements Pipe {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly type = "mqtt";
|
|
15
|
+
private client;
|
|
16
|
+
private config;
|
|
17
|
+
private connected;
|
|
18
|
+
private reconnectAttempts;
|
|
19
|
+
private messageHandlers;
|
|
20
|
+
private wildcardHandlers;
|
|
21
|
+
constructor(options: MqttPipeOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Connect to the MQTT broker
|
|
24
|
+
*/
|
|
25
|
+
connect(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Disconnect from the broker
|
|
28
|
+
*/
|
|
29
|
+
disconnect(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Check if connected
|
|
32
|
+
*/
|
|
33
|
+
isConnected(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Subscribe to a topic
|
|
36
|
+
*/
|
|
37
|
+
subscribe(topic: string, options?: {
|
|
38
|
+
qos?: MqttQoS;
|
|
39
|
+
}): Promise<PipeResponse>;
|
|
40
|
+
/**
|
|
41
|
+
* Unsubscribe from a topic
|
|
42
|
+
*/
|
|
43
|
+
unsubscribe(topic: string): Promise<PipeResponse>;
|
|
44
|
+
/**
|
|
45
|
+
* Publish a message to a topic
|
|
46
|
+
*/
|
|
47
|
+
publish(topic: string, message: string | Buffer | Record<string, unknown>, options?: {
|
|
48
|
+
qos?: MqttQoS;
|
|
49
|
+
retain?: boolean;
|
|
50
|
+
}): Promise<PipeResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Register a handler for a specific topic
|
|
53
|
+
* Supports MQTT wildcards: + (single level), # (multi level)
|
|
54
|
+
*/
|
|
55
|
+
on(topic: string, handler: MqttMessageHandler): void;
|
|
56
|
+
/**
|
|
57
|
+
* Remove a handler
|
|
58
|
+
*/
|
|
59
|
+
off(topic: string, handler: MqttMessageHandler): void;
|
|
60
|
+
/**
|
|
61
|
+
* Emit to handlers
|
|
62
|
+
*/
|
|
63
|
+
private emit;
|
|
64
|
+
/**
|
|
65
|
+
* Handle incoming messages
|
|
66
|
+
*/
|
|
67
|
+
private handleMessage;
|
|
68
|
+
/**
|
|
69
|
+
* Check if a topic matches a pattern with MQTT wildcards
|
|
70
|
+
*/
|
|
71
|
+
private topicMatches;
|
|
72
|
+
/**
|
|
73
|
+
* Parse duration string to milliseconds
|
|
74
|
+
*/
|
|
75
|
+
private parseDuration;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Create an MQTT pipe
|
|
79
|
+
*/
|
|
80
|
+
declare function createMqttPipe(options: MqttPipeOptions): MqttPipe;
|
|
81
|
+
|
|
82
|
+
export { type MqttMessageHandler, MqttPipe, type MqttPipeOptions, createMqttPipe };
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
// src/mqtt/index.ts
|
|
2
|
+
import mqtt from "mqtt";
|
|
3
|
+
var MqttPipe = class {
|
|
4
|
+
name;
|
|
5
|
+
type = "mqtt";
|
|
6
|
+
client = null;
|
|
7
|
+
config;
|
|
8
|
+
connected = false;
|
|
9
|
+
reconnectAttempts = 0;
|
|
10
|
+
messageHandlers = /* @__PURE__ */ new Map();
|
|
11
|
+
wildcardHandlers = /* @__PURE__ */ new Map();
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.name = options.name;
|
|
14
|
+
this.config = options.config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Connect to the MQTT broker
|
|
18
|
+
*/
|
|
19
|
+
async connect() {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const protocol = this.config.protocol ?? "mqtt";
|
|
22
|
+
const port = this.config.port ?? (protocol === "mqtts" || protocol === "wss" ? 8883 : 1883);
|
|
23
|
+
const url = `${protocol}://${this.config.broker}:${port}`;
|
|
24
|
+
const options = {
|
|
25
|
+
keepalive: this.config.keepalive ?? 60,
|
|
26
|
+
clean: this.config.clean ?? true,
|
|
27
|
+
reconnectPeriod: this.config.reconnect?.enabled !== false ? this.parseDuration(this.config.reconnect?.delay ?? "5s") : 0
|
|
28
|
+
};
|
|
29
|
+
if (this.config.auth) {
|
|
30
|
+
if (this.config.auth.username) options.username = this.config.auth.username;
|
|
31
|
+
if (this.config.auth.password) options.password = this.config.auth.password;
|
|
32
|
+
if (this.config.auth.clientId) options.clientId = this.config.auth.clientId;
|
|
33
|
+
}
|
|
34
|
+
if (this.config.will) {
|
|
35
|
+
options.will = {
|
|
36
|
+
topic: this.config.will.topic,
|
|
37
|
+
payload: Buffer.from(this.config.will.payload),
|
|
38
|
+
qos: this.config.will.qos ?? 0,
|
|
39
|
+
retain: this.config.will.retain ?? false
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
this.client = mqtt.connect(url, options);
|
|
44
|
+
this.client.on("connect", () => {
|
|
45
|
+
this.connected = true;
|
|
46
|
+
this.reconnectAttempts = 0;
|
|
47
|
+
this.emit("connected", {});
|
|
48
|
+
resolve();
|
|
49
|
+
});
|
|
50
|
+
this.client.on("message", (topic, payload, packet) => {
|
|
51
|
+
this.handleMessage(topic, payload, packet);
|
|
52
|
+
});
|
|
53
|
+
this.client.on("error", (error) => {
|
|
54
|
+
if (!this.connected) {
|
|
55
|
+
reject(error);
|
|
56
|
+
}
|
|
57
|
+
this.emit("error", error);
|
|
58
|
+
});
|
|
59
|
+
this.client.on("close", () => {
|
|
60
|
+
this.connected = false;
|
|
61
|
+
this.emit("disconnected", {});
|
|
62
|
+
});
|
|
63
|
+
this.client.on("reconnect", () => {
|
|
64
|
+
this.reconnectAttempts++;
|
|
65
|
+
this.emit("reconnecting", { attempts: this.reconnectAttempts });
|
|
66
|
+
});
|
|
67
|
+
this.client.on("offline", () => {
|
|
68
|
+
this.connected = false;
|
|
69
|
+
this.emit("offline", {});
|
|
70
|
+
});
|
|
71
|
+
} catch (error) {
|
|
72
|
+
reject(error);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Disconnect from the broker
|
|
78
|
+
*/
|
|
79
|
+
async disconnect() {
|
|
80
|
+
return new Promise((resolve) => {
|
|
81
|
+
if (this.client) {
|
|
82
|
+
this.client.end(false, {}, () => {
|
|
83
|
+
this.client = null;
|
|
84
|
+
this.connected = false;
|
|
85
|
+
resolve();
|
|
86
|
+
});
|
|
87
|
+
} else {
|
|
88
|
+
resolve();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if connected
|
|
94
|
+
*/
|
|
95
|
+
isConnected() {
|
|
96
|
+
return this.connected && this.client?.connected === true;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Subscribe to a topic
|
|
100
|
+
*/
|
|
101
|
+
async subscribe(topic, options = {}) {
|
|
102
|
+
if (!this.isConnected()) {
|
|
103
|
+
return { success: false, error: "Not connected" };
|
|
104
|
+
}
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
this.client.subscribe(topic, { qos: options.qos ?? 0 }, (error, granted) => {
|
|
107
|
+
if (error) {
|
|
108
|
+
resolve({ success: false, error: error.message });
|
|
109
|
+
} else {
|
|
110
|
+
resolve({ success: true, data: granted });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Unsubscribe from a topic
|
|
117
|
+
*/
|
|
118
|
+
async unsubscribe(topic) {
|
|
119
|
+
if (!this.isConnected()) {
|
|
120
|
+
return { success: false, error: "Not connected" };
|
|
121
|
+
}
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
this.client.unsubscribe(topic, {}, (error) => {
|
|
124
|
+
if (error) {
|
|
125
|
+
resolve({ success: false, error: error.message });
|
|
126
|
+
} else {
|
|
127
|
+
resolve({ success: true });
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Publish a message to a topic
|
|
134
|
+
*/
|
|
135
|
+
async publish(topic, message, options = {}) {
|
|
136
|
+
if (!this.isConnected()) {
|
|
137
|
+
return { success: false, error: "Not connected" };
|
|
138
|
+
}
|
|
139
|
+
const payload = typeof message === "object" && !Buffer.isBuffer(message) ? JSON.stringify(message) : message;
|
|
140
|
+
const publishOptions = {
|
|
141
|
+
qos: options.qos ?? 0,
|
|
142
|
+
retain: options.retain ?? false
|
|
143
|
+
};
|
|
144
|
+
return new Promise((resolve) => {
|
|
145
|
+
this.client.publish(topic, payload, publishOptions, (error) => {
|
|
146
|
+
if (error) {
|
|
147
|
+
resolve({ success: false, error: error.message });
|
|
148
|
+
} else {
|
|
149
|
+
resolve({ success: true });
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Register a handler for a specific topic
|
|
156
|
+
* Supports MQTT wildcards: + (single level), # (multi level)
|
|
157
|
+
*/
|
|
158
|
+
on(topic, handler) {
|
|
159
|
+
if (topic.includes("+") || topic.includes("#")) {
|
|
160
|
+
const handlers = this.wildcardHandlers.get(topic) ?? [];
|
|
161
|
+
handlers.push(handler);
|
|
162
|
+
this.wildcardHandlers.set(topic, handlers);
|
|
163
|
+
} else {
|
|
164
|
+
const handlers = this.messageHandlers.get(topic) ?? [];
|
|
165
|
+
handlers.push(handler);
|
|
166
|
+
this.messageHandlers.set(topic, handlers);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Remove a handler
|
|
171
|
+
*/
|
|
172
|
+
off(topic, handler) {
|
|
173
|
+
const map = topic.includes("+") || topic.includes("#") ? this.wildcardHandlers : this.messageHandlers;
|
|
174
|
+
const handlers = map.get(topic) ?? [];
|
|
175
|
+
const index = handlers.indexOf(handler);
|
|
176
|
+
if (index !== -1) {
|
|
177
|
+
handlers.splice(index, 1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Emit to handlers
|
|
182
|
+
*/
|
|
183
|
+
emit(event, data) {
|
|
184
|
+
const handlers = this.messageHandlers.get(event) ?? [];
|
|
185
|
+
for (const handler of handlers) {
|
|
186
|
+
try {
|
|
187
|
+
handler(event, data, {});
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.error(`MQTT handler error for "${event}":`, error);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Handle incoming messages
|
|
195
|
+
*/
|
|
196
|
+
handleMessage(topic, payload, packet) {
|
|
197
|
+
let parsedPayload = payload;
|
|
198
|
+
try {
|
|
199
|
+
const str = payload.toString();
|
|
200
|
+
parsedPayload = JSON.parse(str);
|
|
201
|
+
} catch {
|
|
202
|
+
parsedPayload = payload.toString();
|
|
203
|
+
}
|
|
204
|
+
const exactHandlers = this.messageHandlers.get(topic) ?? [];
|
|
205
|
+
for (const handler of exactHandlers) {
|
|
206
|
+
try {
|
|
207
|
+
handler(topic, parsedPayload, packet);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
console.error(`MQTT handler error for topic "${topic}":`, error);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
for (const [pattern, handlers] of this.wildcardHandlers) {
|
|
213
|
+
if (this.topicMatches(pattern, topic)) {
|
|
214
|
+
for (const handler of handlers) {
|
|
215
|
+
try {
|
|
216
|
+
handler(topic, parsedPayload, packet);
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.error(`MQTT wildcard handler error for pattern "${pattern}":`, error);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
this.emit("message", { topic, payload: parsedPayload, packet });
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Check if a topic matches a pattern with MQTT wildcards
|
|
227
|
+
*/
|
|
228
|
+
topicMatches(pattern, topic) {
|
|
229
|
+
const patternParts = pattern.split("/");
|
|
230
|
+
const topicParts = topic.split("/");
|
|
231
|
+
for (let i = 0; i < patternParts.length; i++) {
|
|
232
|
+
const patternPart = patternParts[i];
|
|
233
|
+
if (patternPart === "#") {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
if (i >= topicParts.length) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
if (patternPart === "+") {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (patternPart !== topicParts[i]) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return patternParts.length === topicParts.length;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Parse duration string to milliseconds
|
|
250
|
+
*/
|
|
251
|
+
parseDuration(duration) {
|
|
252
|
+
const match = duration.match(/^(\d+)(ms|s|m|h)?$/);
|
|
253
|
+
if (!match) return 5e3;
|
|
254
|
+
const value = parseInt(match[1], 10);
|
|
255
|
+
const unit = match[2] ?? "s";
|
|
256
|
+
switch (unit) {
|
|
257
|
+
case "ms":
|
|
258
|
+
return value;
|
|
259
|
+
case "s":
|
|
260
|
+
return value * 1e3;
|
|
261
|
+
case "m":
|
|
262
|
+
return value * 60 * 1e3;
|
|
263
|
+
case "h":
|
|
264
|
+
return value * 60 * 60 * 1e3;
|
|
265
|
+
default:
|
|
266
|
+
return value * 1e3;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
function createMqttPipe(options) {
|
|
271
|
+
return new MqttPipe(options);
|
|
272
|
+
}
|
|
273
|
+
export {
|
|
274
|
+
MqttPipe,
|
|
275
|
+
createMqttPipe
|
|
276
|
+
};
|
|
277
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/mqtt/index.ts"],"sourcesContent":["/**\n * MQTT pipe for IoT and real-time integrations\n */\n\nimport mqtt, { MqttClient, IClientOptions, IClientPublishOptions } from 'mqtt';\nimport type { Pipe, PipeResponse, MqttPipeConfig, MqttQoS } from '../types.js';\n\nexport interface MqttPipeOptions {\n name: string;\n config: MqttPipeConfig;\n}\n\nexport type MqttMessageHandler = (\n topic: string,\n payload: Buffer | string | Record<string, unknown>,\n packet: unknown\n) => void | Promise<void>;\n\nexport class MqttPipe implements Pipe {\n public readonly name: string;\n public readonly type = 'mqtt';\n private client: MqttClient | null = null;\n private config: MqttPipeConfig;\n private connected = false;\n private reconnectAttempts = 0;\n private messageHandlers: Map<string, MqttMessageHandler[]> = new Map();\n private wildcardHandlers: Map<string, MqttMessageHandler[]> = new Map();\n\n constructor(options: MqttPipeOptions) {\n this.name = options.name;\n this.config = options.config;\n }\n\n /**\n * Connect to the MQTT broker\n */\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const protocol = this.config.protocol ?? 'mqtt';\n const port = this.config.port ?? (protocol === 'mqtts' || protocol === 'wss' ? 8883 : 1883);\n const url = `${protocol}://${this.config.broker}:${port}`;\n\n const options: IClientOptions = {\n keepalive: this.config.keepalive ?? 60,\n clean: this.config.clean ?? true,\n reconnectPeriod: this.config.reconnect?.enabled !== false\n ? this.parseDuration(this.config.reconnect?.delay ?? '5s')\n : 0,\n };\n\n // Authentication\n if (this.config.auth) {\n if (this.config.auth.username) options.username = this.config.auth.username;\n if (this.config.auth.password) options.password = this.config.auth.password;\n if (this.config.auth.clientId) options.clientId = this.config.auth.clientId;\n }\n\n // Last Will and Testament\n if (this.config.will) {\n options.will = {\n topic: this.config.will.topic,\n payload: Buffer.from(this.config.will.payload),\n qos: this.config.will.qos ?? 0,\n retain: this.config.will.retain ?? false,\n };\n }\n\n try {\n this.client = mqtt.connect(url, options);\n\n this.client.on('connect', () => {\n this.connected = true;\n this.reconnectAttempts = 0;\n this.emit('connected', {});\n resolve();\n });\n\n this.client.on('message', (topic, payload, packet) => {\n this.handleMessage(topic, payload, packet);\n });\n\n this.client.on('error', (error) => {\n if (!this.connected) {\n reject(error);\n }\n this.emit('error', error);\n });\n\n this.client.on('close', () => {\n this.connected = false;\n this.emit('disconnected', {});\n });\n\n this.client.on('reconnect', () => {\n this.reconnectAttempts++;\n this.emit('reconnecting', { attempts: this.reconnectAttempts });\n });\n\n this.client.on('offline', () => {\n this.connected = false;\n this.emit('offline', {});\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Disconnect from the broker\n */\n async disconnect(): Promise<void> {\n return new Promise((resolve) => {\n if (this.client) {\n this.client.end(false, {}, () => {\n this.client = null;\n this.connected = false;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected && this.client?.connected === true;\n }\n\n /**\n * Subscribe to a topic\n */\n async subscribe(\n topic: string,\n options: { qos?: MqttQoS } = {}\n ): Promise<PipeResponse> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n this.client!.subscribe(topic, { qos: options.qos ?? 0 }, (error, granted) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true, data: granted });\n }\n });\n });\n }\n\n /**\n * Unsubscribe from a topic\n */\n async unsubscribe(topic: string): Promise<PipeResponse> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n return new Promise((resolve) => {\n this.client!.unsubscribe(topic, {}, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Publish a message to a topic\n */\n async publish(\n topic: string,\n message: string | Buffer | Record<string, unknown>,\n options: { qos?: MqttQoS; retain?: boolean } = {}\n ): Promise<PipeResponse> {\n if (!this.isConnected()) {\n return { success: false, error: 'Not connected' };\n }\n\n const payload = typeof message === 'object' && !Buffer.isBuffer(message)\n ? JSON.stringify(message)\n : message;\n\n const publishOptions: IClientPublishOptions = {\n qos: options.qos ?? 0,\n retain: options.retain ?? false,\n };\n\n return new Promise((resolve) => {\n this.client!.publish(topic, payload, publishOptions, (error) => {\n if (error) {\n resolve({ success: false, error: error.message });\n } else {\n resolve({ success: true });\n }\n });\n });\n }\n\n /**\n * Register a handler for a specific topic\n * Supports MQTT wildcards: + (single level), # (multi level)\n */\n on(topic: string, handler: MqttMessageHandler): void {\n if (topic.includes('+') || topic.includes('#')) {\n // Wildcard topic - store in wildcardHandlers\n const handlers = this.wildcardHandlers.get(topic) ?? [];\n handlers.push(handler);\n this.wildcardHandlers.set(topic, handlers);\n } else {\n // Exact topic\n const handlers = this.messageHandlers.get(topic) ?? [];\n handlers.push(handler);\n this.messageHandlers.set(topic, handlers);\n }\n }\n\n /**\n * Remove a handler\n */\n off(topic: string, handler: MqttMessageHandler): void {\n const map = topic.includes('+') || topic.includes('#')\n ? this.wildcardHandlers\n : this.messageHandlers;\n\n const handlers = map.get(topic) ?? [];\n const index = handlers.indexOf(handler);\n if (index !== -1) {\n handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit to handlers\n */\n private emit(event: string, data: unknown): void {\n const handlers = this.messageHandlers.get(event) ?? [];\n for (const handler of handlers) {\n try {\n handler(event, data as Buffer, {});\n } catch (error) {\n console.error(`MQTT handler error for \"${event}\":`, error);\n }\n }\n }\n\n /**\n * Handle incoming messages\n */\n private handleMessage(topic: string, payload: Buffer, packet: unknown): void {\n // Parse payload\n let parsedPayload: Buffer | string | Record<string, unknown> = payload;\n try {\n const str = payload.toString();\n parsedPayload = JSON.parse(str);\n } catch {\n parsedPayload = payload.toString();\n }\n\n // Call exact topic handlers\n const exactHandlers = this.messageHandlers.get(topic) ?? [];\n for (const handler of exactHandlers) {\n try {\n handler(topic, parsedPayload, packet);\n } catch (error) {\n console.error(`MQTT handler error for topic \"${topic}\":`, error);\n }\n }\n\n // Check wildcard handlers\n for (const [pattern, handlers] of this.wildcardHandlers) {\n if (this.topicMatches(pattern, topic)) {\n for (const handler of handlers) {\n try {\n handler(topic, parsedPayload, packet);\n } catch (error) {\n console.error(`MQTT wildcard handler error for pattern \"${pattern}\":`, error);\n }\n }\n }\n }\n\n // Emit to generic message handlers\n this.emit('message', { topic, payload: parsedPayload, packet });\n }\n\n /**\n * Check if a topic matches a pattern with MQTT wildcards\n */\n private topicMatches(pattern: string, topic: string): boolean {\n const patternParts = pattern.split('/');\n const topicParts = topic.split('/');\n\n for (let i = 0; i < patternParts.length; i++) {\n const patternPart = patternParts[i];\n\n // Multi-level wildcard matches everything remaining\n if (patternPart === '#') {\n return true;\n }\n\n // Topic is shorter than pattern\n if (i >= topicParts.length) {\n return false;\n }\n\n // Single-level wildcard matches any single level\n if (patternPart === '+') {\n continue;\n }\n\n // Exact match required\n if (patternPart !== topicParts[i]) {\n return false;\n }\n }\n\n // Pattern and topic should be same length (unless # was used)\n return patternParts.length === topicParts.length;\n }\n\n /**\n * Parse duration string to milliseconds\n */\n private parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m|h)?$/);\n if (!match) return 5000;\n\n const value = parseInt(match[1]!, 10);\n const unit = match[2] ?? 's';\n\n switch (unit) {\n case 'ms':\n return value;\n case 's':\n return value * 1000;\n case 'm':\n return value * 60 * 1000;\n case 'h':\n return value * 60 * 60 * 1000;\n default:\n return value * 1000;\n }\n }\n}\n\n/**\n * Create an MQTT pipe\n */\nexport function createMqttPipe(options: MqttPipeOptions): MqttPipe {\n return new MqttPipe(options);\n}\n"],"mappings":"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","names":[]}
|