UNPKG

@noves/intent-typescript-sdk

Version:

Noves Intent Typescript SDK

177 lines (176 loc) 7.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClientSideIntentSDK = void 0; const base_1 = require("../shared/base"); const errors_1 = require("../shared/errors"); const types_1 = require("../shared/types"); const types_2 = require("../shared/types"); class ClientSideIntentSDK extends base_1.IntentSDKBase { activeWebSocketConnections = new Map(); wsUrl; constructor() { super({ apiUrl: types_1.IntentEndpoints.API_URL, grpcUrl: types_1.IntentEndpoints.WS_URL }); this.wsUrl = types_1.IntentEndpoints.WS_URL; } async loadIntents() { try { const response = await fetch(`${types_1.IntentEndpoints.API_URL}/intents`); if (!response.ok) { throw new Error(`Failed to fetch intents: ${response.statusText}`); } const serverIntents = await response.json(); this.intents = serverIntents; } catch (error) { console.error('Failed to load intents:', error); this.intents = []; } } async getValue(intentId, params = {}, pageSize) { await this.ensureInitialized(); const intent = this.intents.find(i => i.id === intentId); if (!intent) { throw new errors_1.IntentSDKError(`Intent ${intentId} not found`); } if (!(0, types_2.isValueIntent)(intent)) { throw new errors_1.IntentSDKError(`Intent ${intentId} is not a value intent`); } try { const response = await fetch(`${types_1.IntentEndpoints.API_URL}/intents`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id: intentId, params, pageSize }), }); if (!response.ok) { throw new errors_1.IntentSDKError(`Failed to fetch intent data: ${response.statusText}`); } return await response.json(); } catch (error) { console.error('Intent execution error:', error); throw new errors_1.IntentSDKError(error instanceof Error ? error.message : 'Failed to execute intent'); } } async getStream(intentId, params, onData, onError, onComplete) { await this.ensureInitialized(); const intent = this.intents.find(i => i.id === intentId); if (!intent) { throw new errors_1.IntentSDKError(`Intent ${intentId} not found`); } if (!(0, types_2.isStreamIntent)(intent)) { throw new errors_1.IntentSDKError(`Intent ${intentId} is not a stream intent`); } if (this.activeWebSocketConnections.has(intentId)) { throw new errors_1.IntentSDKError(`Stream already exists for intent ${intentId}`); } const queryParams = new URLSearchParams({ id: intentId, cusRateLimit: "1.0", ...this.stringifyParams(params), }); return new Promise((resolve, reject) => { try { const wsUrlWithParams = `${this.wsUrl}?${queryParams.toString()}`; const ws = new WebSocket(wsUrlWithParams); let isConnected = false; ws.onopen = () => { isConnected = true; resolve(); }; ws.onmessage = (event) => { try { // Handle actual data messages if (typeof event.data === 'string' && (event.data.startsWith('{') || event.data.startsWith('['))) { const response = JSON.parse(event.data); if (response.error) { onError?.(new Error(response.error)); return; } onData(response); } else { // Handle other non-JSON data onData(event.data); } } catch (error) { console.error('Parse error:', error); onError?.(error); } }; ws.onerror = (error) => { console.error('WebSocket error:', error); onError?.(new errors_1.IntentSDKError('WebSocket connection error')); if (isConnected) { this.activeWebSocketConnections.delete(intentId); } reject(error); }; ws.onclose = (event) => { this.activeWebSocketConnections.delete(intentId); // Only treat it as an error if it wasn't an intentional close if (event.code === 4000) { onError?.(new errors_1.IntentSDKError('Invalid message format or protocol error')); } else if (event.code !== 1000 && event.code !== 1005) { // 1005 is also a normal close onError?.(new errors_1.IntentSDKError(`WebSocket closed unexpectedly with code ${event.code}`)); } if (isConnected) { onComplete?.(); } }; this.activeWebSocketConnections.set(intentId, ws); } catch (error) { console.error('Stream setup error:', error); onError?.(error); reject(error); } }); } stringifyParams(params) { return Object.entries(params).reduce((acc, [key, value]) => ({ ...acc, [key]: String(value) }), {}); } stopStream(intentId) { const ws = this.activeWebSocketConnections.get(intentId); if (ws) { ws.close(); this.activeWebSocketConnections.delete(intentId); } } async getIntents() { await this.ensureInitialized(); return this.intents; } async executeIntent(intentId, params) { const intent = this.intents.find(i => i.id === intentId); if (!intent) { throw new errors_1.IntentSDKError("Intent not found"); } if (intent.mode.includes('value')) { return this.getValue(intentId, params); } else if (intent.mode.includes('stream')) { return new Promise((resolve, reject) => { this.getStream(intentId, // Cast to StreamableIntentId since we verified it exists params, resolve, reject); }); } throw new errors_1.IntentSDKError("Invalid intent mode"); } } exports.ClientSideIntentSDK = ClientSideIntentSDK;