e-bon
e-bon.ro
TypeScript SDK

Events

This page has moved — real-time events now live under the standalone @e-bon/realtime package at /en/realtime.

Events

This page has moved. Real-time events are no longer part of @e-bon/sdk — they live in the standalone @e-bon/realtime package. Update your bookmarks and imports.

The full content that used to live here is now split across the new Realtime section:

  • Realtime overview — what @e-bon/realtime is and how it differs from the REST SDK.
  • Getting started — install @e-bon/realtime, instantiate RealtimeClient and register your first listener.
  • Events — the eight partner-facing event payloads and the EventMap / EventName types.
  • Reconnect and lifecycle — backoff schedule, close, suspend / resume, and the CursorStore hook.
  • Schemas — server→device and device→server wire frames.

The EventSubscriber class has been replaced by RealtimeClient from @e-bon/realtime. The listener API (on / off / once) and the event names are unchanged — only the import path and constructor differ.

Outgoing messages (devices)

The send surface below is device-only — partner integrations consume realtime, they do not produce. POS and portal SDK users can ignore this section.

Since the alpha redesign, RealtimeClient also exposes a small outgoing surface so a device can reply to dispatched commands and emit status updates over the same socket (see Realtime schemas):

import { RealtimeClient } from '@e-bon/realtime';

const rt = new RealtimeClient('https://api.e-bon.ro', { token });

// Generic send — any device→server frame validated by `clientToServerMessageSchema`.
rt.send({
  type: 'status',
  clientMessageId: makeId(),
  deviceStatus: { online: true },
});

// Convenience wrappers for the two reply shapes.
rt.sendCommandResult({
  commandId: 'cmd_abc',
  clientMessageId: makeId(),
  result: { fiscalId: 'F-100', success: true },
});

rt.sendCommandError({
  commandId: 'cmd_abc',
  clientMessageId: makeId(),
  error: { message: 'printer offline', code: 'E_DEVICE' },
});

clientMessageId idempotency contract

Every device→server frame must carry a clientMessageId. The server uses it to de-duplicate retries on at-least-once delivery — sending the same (commandId, clientMessageId) twice is safe and produces a single observed result. Generate a fresh id per reply attempt (a short random suffix concatenated with a timestamp is enough; the field is just an opaque non-empty string).

Delivery semantics (alpha)

If the underlying socket is not OPEN when you call send / sendCommandResult / sendCommandError, the frame is dropped and a console.warn is emitted — there is no in-memory outgoing queue in this release. Callers that need durable replies should re-send after the next connected event (or rely on the at-least-once cursor: the server will re-dispatch the unanswered command on the next session).