SDK · JavaScript/TypeScript

Isomorphic TypeScript client SDK for the imcore IM server. Standard WebSocket + JSON envelope; zero runtime dependencies.

Install

npm install @imcore/sdk
# Node / React Native also need a WebSocket implementation:
npm install ws

Usage

import { ImcoreClient } from '@imcore/sdk';
// Browser: native WebSocket is used automatically.
// Node/RN: pass one in.
// import WebSocket from 'ws';

const im = new ImcoreClient({
  url: 'wss://your-host/acc',
  auth: { token: '<jwt>', login: { userID: '1001', userName: 'alice' } },
  // webSocketImpl: WebSocket,        // Node/RN: pass a WebSocket constructor
  // requestTimeoutMs: 10000,         // default: 10 000 ms per request
  // successCode: 200,                // default: 200 (server success code)
  // reconnect: { initialDelayMs: 500, maxDelayMs: 15000 },  // backoff defaults
  // heartbeatIntervalMs: 25000,      // default: 25 000 ms between heartbeats
  // timers: ...,                     // injectable timer API (useful in tests)
  // logger: console,                 // default: console; pass a custom logger
});

im.onStatus((s) => console.log('status', s));     // idle|connecting|open|authenticated|closed
im.on('chat_message', (m) => console.log('msg', m));
im.on('reconnected', () => {
  // re-pull conversation lists + cursor history here (SDK does not auto-reconcile in v1)
});

// connect() resolves only after the server acknowledges login (code 200).
// It REJECTS if the server refuses login (e.g. bad token), so use try/catch:
try {
  await im.connect();
} catch (err) {
  console.error('login refused', err); // err is a RequestError with .code set
}
await im.dm.send({ targetUserID: '1002', text: 'hi' });
const history = await im.dm.history({ targetUserID: '1002', limit: 20 });

// Offline-safe send: queues while disconnected, adds tempID for server-side
// idempotency, and can be flushed after reconnect/auth.
const queued = await im.dm.sendQueued({ targetUserID: '1002', text: 'works offline' });
if (queued.status === 'queued') {
  console.log('queued tempID', queued.tempID);
}
await im.offline.flush();

// Local cache is updated from live pushes and successful send acks.
const messages = await im.cache.getMessages('dm:1001:1002');
const conversations = await im.cache.getConversations();

// Register platform push tokens obtained from APNs/FCM/vendor SDKs.
await im.push.register({
  deviceID: 'ios-001',
  platform: 'ios',
  vendor: 'apns',
  pushToken: '<device-token>',
  appID: 'com.example.app',
});

// Escape hatch for any command not yet wrapped:
await im.request('chat_group_create', { name: 'team' });
im.send('chat_dm_typing', { targetUserID: '1002' });

Scope (v1)

Transport core + seq-correlated request/response + typed DM/group/room send/receive/history, local message/conversation cache, tempID-backed offline send queue, and push device registration. Not included: media upload helpers, E2EE key management, service workers / APNs / FCM token acquisition, framework bindings, or UI components.

Development

npm install
npm test          # unit tests (mock WebSocket, no server needed)
npm run build     # ESM + CJS + d.ts
npm run typecheck

# Integration test against a live server:
IMCORE_TEST_WS_URL=wss://host/acc IMCORE_TEST_WS_TOKEN=<jwt> \
IMCORE_TEST_USER_ID=1001 IMCORE_TEST_PEER_ID=1002 npm test