@droponair/sdk-js 0.19.0 → 0.22.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.
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * Transport auto-select (Phase 4.6).
4
+ *
5
+ * Tiny helper that probes which transport lanes the runtime AND the platform
6
+ * BOTH support, and returns the best one for this client/host pair.
7
+ *
8
+ * Preference order (best -> fallback):
9
+ * 1. webtransport - multi-stream, lower head-of-line blocking
10
+ * 2. websocket - universal default
11
+ * 3. sse - HTTP-only fallback for restrictive networks
12
+ *
13
+ * The function fetches `<httpUrl>/api/info` once, intersects its
14
+ * `transports` array with the runtime's capabilities, and returns the
15
+ * highest-preference match. Caller then instantiates the corresponding
16
+ * primitive (`WebTransportTransport` / WebSocket / `SseTransport`) and
17
+ * uses it as their lane.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { selectTransport, WebTransportTransport, SseTransport } from '@droponair/sdk-js';
22
+ * const lane = await selectTransport({ httpUrl: 'https://sdk.droponair.com' });
23
+ * switch (lane) {
24
+ * case 'webtransport': // construct WebTransportTransport break;
25
+ * case 'sse': // construct SseTransport break;
26
+ * default: // fall through to WebSocket
27
+ * }
28
+ * ```
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.selectTransport = selectTransport;
32
+ const DEFAULT_PREFERENCE = ['webtransport', 'websocket', 'sse'];
33
+ /**
34
+ * Returns the highest-preference transport lane available on BOTH the
35
+ * runtime and the platform. Throws if no lane is supported (extremely
36
+ * unusual; WebSocket is the universal floor).
37
+ */
38
+ async function selectTransport(options) {
39
+ const httpUrl = options.httpUrl.replace(/\/+$/, '');
40
+ const fetchFn = options.fetchFn ?? globalThis.fetch.bind(globalThis);
41
+ const preference = options.preference ?? DEFAULT_PREFERENCE;
42
+ const res = await fetchFn(`${httpUrl}/api/info`);
43
+ if (!res.ok) {
44
+ throw new Error(`selectTransport: GET /api/info failed (HTTP ${res.status})`);
45
+ }
46
+ const info = await res.json();
47
+ const serverLanes = new Set(info.transports ?? ['websocket']);
48
+ const runtimeSupports = (lane) => {
49
+ switch (lane) {
50
+ case 'webtransport':
51
+ return typeof globalThis.WebTransport === 'function';
52
+ case 'websocket':
53
+ return typeof globalThis.WebSocket === 'function';
54
+ case 'sse':
55
+ return typeof globalThis.EventSource === 'function';
56
+ }
57
+ };
58
+ for (const lane of preference) {
59
+ if (serverLanes.has(lane) && runtimeSupports(lane)) {
60
+ return lane;
61
+ }
62
+ }
63
+ throw new Error('selectTransport: no transport lane supported by both runtime and platform');
64
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Internal transport interface used by `MessagingClient`. Abstracts the
3
+ * WebSocket, SSE-fallback, and WebTransport lanes behind a single
4
+ * lifecycle surface so the client can pick a lane at init time without
5
+ * the rest of the SDK caring which one is in use.
6
+ *
7
+ * Public consumers of the SDK continue to use the standalone primitives
8
+ * (`SseTransport`, `WebTransportTransport`); this interface is an internal
9
+ * adapter target only.
10
+ */
11
+ export interface MessagingTransportClose {
12
+ code: number;
13
+ reason: string;
14
+ }
15
+ export interface MessagingTransportEvents {
16
+ onOpen(handler: () => void): void;
17
+ onFrame(handler: (bytes: Uint8Array) => void): void;
18
+ onClose(handler: (info: MessagingTransportClose) => void): void;
19
+ onError(handler: (err: Error) => void): void;
20
+ }
21
+ export interface MessagingTransport extends MessagingTransportEvents {
22
+ /** Human-readable transport name, mirrors the `/api/info.transports` token. */
23
+ readonly name: 'ws' | 'sse' | 'wt';
24
+ /** Open the underlying stream. Resolves once frames can be sent and received. */
25
+ connect(): Promise<void>;
26
+ /** Send a raw protobuf frame (no framing of its own). */
27
+ send(bytes: Uint8Array): void;
28
+ /** True if the transport can accept `send()` right now. */
29
+ isOpen(): boolean;
30
+ /** Close the stream. Idempotent. `code`/`reason` are best-effort hints. */
31
+ close(code?: number, reason?: string): void;
32
+ }
33
+ export type MessagingTransportSelection = 'ws' | 'sse' | 'wt' | 'auto';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,28 @@
1
+ import { type SseTransportOptions } from './sse-transport';
2
+ import type { MessagingTransport, MessagingTransportClose } from './messaging-transport';
3
+ /**
4
+ * SSE adapter for {@link MessagingTransport}. Wraps the standalone
5
+ * {@link SseTransport} primitive so `MessagingClient` can use the HTTP
6
+ * fallback lane behind the same lifecycle API as WebSocket.
7
+ *
8
+ * v1 limitations: no auto-reconnect logic at the client layer beyond
9
+ * what EventSource already does; close events synthesize code 1000.
10
+ */
11
+ export declare class SseMessagingTransport implements MessagingTransport {
12
+ readonly name: "sse";
13
+ private inner;
14
+ private opened;
15
+ private openHandler;
16
+ private frameHandler;
17
+ private closeHandler;
18
+ private errorHandler;
19
+ constructor(options: SseTransportOptions);
20
+ onOpen(handler: () => void): void;
21
+ onFrame(handler: (bytes: Uint8Array) => void): void;
22
+ onClose(handler: (info: MessagingTransportClose) => void): void;
23
+ onError(handler: (err: Error) => void): void;
24
+ connect(): Promise<void>;
25
+ send(bytes: Uint8Array): void;
26
+ isOpen(): boolean;
27
+ close(_code?: number, _reason?: string): void;
28
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SseMessagingTransport = void 0;
4
+ const sse_transport_1 = require("./sse-transport");
5
+ /**
6
+ * SSE adapter for {@link MessagingTransport}. Wraps the standalone
7
+ * {@link SseTransport} primitive so `MessagingClient` can use the HTTP
8
+ * fallback lane behind the same lifecycle API as WebSocket.
9
+ *
10
+ * v1 limitations: no auto-reconnect logic at the client layer beyond
11
+ * what EventSource already does; close events synthesize code 1000.
12
+ */
13
+ class SseMessagingTransport {
14
+ constructor(options) {
15
+ this.name = 'sse';
16
+ this.opened = false;
17
+ this.openHandler = null;
18
+ this.frameHandler = null;
19
+ this.closeHandler = null;
20
+ this.errorHandler = null;
21
+ this.inner = new sse_transport_1.SseTransport(options);
22
+ this.inner.onFrame((bytes) => this.frameHandler?.(bytes));
23
+ this.inner.onState((state) => {
24
+ if (state === 'open') {
25
+ this.opened = true;
26
+ this.openHandler?.();
27
+ }
28
+ else if (state === 'closed') {
29
+ this.opened = false;
30
+ this.closeHandler?.({ code: 1000, reason: 'CLOSED' });
31
+ }
32
+ else if (state === 'error') {
33
+ this.errorHandler?.(new Error('SseMessagingTransport: stream error'));
34
+ }
35
+ });
36
+ }
37
+ onOpen(handler) { this.openHandler = handler; }
38
+ onFrame(handler) { this.frameHandler = handler; }
39
+ onClose(handler) { this.closeHandler = handler; }
40
+ onError(handler) { this.errorHandler = handler; }
41
+ async connect() {
42
+ await this.inner.connect();
43
+ }
44
+ send(bytes) {
45
+ // Fire-and-forget; surface failure via the error handler so the client's
46
+ // existing `this.transport.send(...)` call sites don't need to await.
47
+ this.inner.sendEnvelope(bytes).catch((err) => {
48
+ this.errorHandler?.(err instanceof Error ? err : new Error(String(err)));
49
+ });
50
+ }
51
+ isOpen() {
52
+ return this.opened;
53
+ }
54
+ close(_code, _reason) {
55
+ this.inner.close();
56
+ this.opened = false;
57
+ }
58
+ }
59
+ exports.SseMessagingTransport = SseMessagingTransport;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * WebTransport (HTTP/3) lane primitive (Phase 4.3).
3
+ *
4
+ * Standalone client for the platform's WebTransport endpoint, terminated by
5
+ * the `droponair-webtransport` Go sidecar and bridged into sdk-be `/ws`.
6
+ * Browser-native `WebTransport` API; no polyfill ships with the SDK.
7
+ *
8
+ * Browser support as of 2026-05:
9
+ * - Chromium 97+ (stable)
10
+ * - Firefox 125+ (stable)
11
+ * - Safari Technology Preview only (no stable release yet)
12
+ * - Node 22+ has experimental WebTransport behind a flag
13
+ *
14
+ * v1 surface is intentionally narrow: this exposes the bytes lane only,
15
+ * caller decodes protobuf. Full `init({ transport: 'webtransport' })`
16
+ * MessagingClient integration lands later, mirroring the SSE roadmap.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { WebTransportTransport } from '@droponair/sdk-js';
21
+ * const wt = new WebTransportTransport({
22
+ * httpUrl: 'https://sdk.droponair.com',
23
+ * getJwt: async () => myJwt,
24
+ * });
25
+ * wt.onFrame((bytes) => { ... protobuf decode ... });
26
+ * await wt.connect();
27
+ * await wt.sendEnvelope(envelopeBytes);
28
+ * ```
29
+ */
30
+ export interface WebTransportTransportOptions {
31
+ /** Base URL of the platform's REST API. The WT endpoint is derived as
32
+ * `<httpUrl>/v1/transport/wt?token=<jwt>`. */
33
+ httpUrl: string;
34
+ /** Returns a fresh JWT. Called once per connect. */
35
+ getJwt: () => Promise<string>;
36
+ }
37
+ export type WTFrameHandler = (frame: Uint8Array) => void;
38
+ export type WTStateHandler = (state: 'connecting' | 'open' | 'closed' | 'error') => void;
39
+ export declare class WebTransportTransport {
40
+ private readonly httpUrl;
41
+ private readonly getJwt;
42
+ private session;
43
+ private stream;
44
+ private writer;
45
+ private reader;
46
+ private frameHandler;
47
+ private stateHandler;
48
+ private readLoopAbort;
49
+ constructor(options: WebTransportTransportOptions);
50
+ /** Subscribe to incoming protobuf frames. Replaces any previous handler. */
51
+ onFrame(handler: WTFrameHandler): void;
52
+ /** Subscribe to lifecycle state changes. Replaces any previous handler. */
53
+ onState(handler: WTStateHandler): void;
54
+ /** Open the WebTransport session + a single bidirectional stream. */
55
+ connect(): Promise<void>;
56
+ /** Write a single protobuf Envelope to the bidirectional stream. */
57
+ sendEnvelope(envelopeBytes: Uint8Array): Promise<void>;
58
+ /** Close the session. Idempotent. */
59
+ close(): void;
60
+ private startReadLoop;
61
+ }
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * WebTransport (HTTP/3) lane primitive (Phase 4.3).
4
+ *
5
+ * Standalone client for the platform's WebTransport endpoint, terminated by
6
+ * the `droponair-webtransport` Go sidecar and bridged into sdk-be `/ws`.
7
+ * Browser-native `WebTransport` API; no polyfill ships with the SDK.
8
+ *
9
+ * Browser support as of 2026-05:
10
+ * - Chromium 97+ (stable)
11
+ * - Firefox 125+ (stable)
12
+ * - Safari Technology Preview only (no stable release yet)
13
+ * - Node 22+ has experimental WebTransport behind a flag
14
+ *
15
+ * v1 surface is intentionally narrow: this exposes the bytes lane only,
16
+ * caller decodes protobuf. Full `init({ transport: 'webtransport' })`
17
+ * MessagingClient integration lands later, mirroring the SSE roadmap.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { WebTransportTransport } from '@droponair/sdk-js';
22
+ * const wt = new WebTransportTransport({
23
+ * httpUrl: 'https://sdk.droponair.com',
24
+ * getJwt: async () => myJwt,
25
+ * });
26
+ * wt.onFrame((bytes) => { ... protobuf decode ... });
27
+ * await wt.connect();
28
+ * await wt.sendEnvelope(envelopeBytes);
29
+ * ```
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.WebTransportTransport = void 0;
33
+ class WebTransportTransport {
34
+ constructor(options) {
35
+ this.session = null;
36
+ this.stream = null;
37
+ this.writer = null;
38
+ this.reader = null;
39
+ this.frameHandler = null;
40
+ this.stateHandler = null;
41
+ this.readLoopAbort = false;
42
+ this.httpUrl = options.httpUrl.replace(/\/+$/, '');
43
+ this.getJwt = options.getJwt;
44
+ if (typeof globalThis.WebTransport !== 'function') {
45
+ throw new Error('WebTransportTransport: WebTransport is not available in this runtime. ' +
46
+ 'Requires Chromium 97+, Firefox 125+, or Node 22+ with --experimental-* flags.');
47
+ }
48
+ }
49
+ /** Subscribe to incoming protobuf frames. Replaces any previous handler. */
50
+ onFrame(handler) { this.frameHandler = handler; }
51
+ /** Subscribe to lifecycle state changes. Replaces any previous handler. */
52
+ onState(handler) { this.stateHandler = handler; }
53
+ /** Open the WebTransport session + a single bidirectional stream. */
54
+ async connect() {
55
+ this.close();
56
+ const jwt = await this.getJwt();
57
+ this.stateHandler?.('connecting');
58
+ const url = `${this.httpUrl.replace(/^http/, 'https')}/v1/transport/wt?token=${encodeURIComponent(jwt)}`;
59
+ const WT = globalThis.WebTransport;
60
+ const session = new WT(url);
61
+ this.session = session;
62
+ await session.ready;
63
+ this.stateHandler?.('open');
64
+ const stream = await session.createBidirectionalStream();
65
+ this.stream = stream;
66
+ this.writer = stream.writable.getWriter();
67
+ this.reader = stream.readable.getReader();
68
+ session.closed
69
+ .then(() => this.stateHandler?.('closed'))
70
+ .catch(() => this.stateHandler?.('error'));
71
+ this.startReadLoop().catch((e) => {
72
+ this.stateHandler?.('error');
73
+ // eslint-disable-next-line no-console
74
+ console.warn('WebTransportTransport: read loop ended', e);
75
+ });
76
+ }
77
+ /** Write a single protobuf Envelope to the bidirectional stream. */
78
+ async sendEnvelope(envelopeBytes) {
79
+ if (!this.writer) {
80
+ throw new Error('WebTransportTransport: not connected (call connect() first)');
81
+ }
82
+ await this.writer.write(envelopeBytes);
83
+ }
84
+ /** Close the session. Idempotent. */
85
+ close() {
86
+ this.readLoopAbort = true;
87
+ if (this.writer) {
88
+ try {
89
+ this.writer.releaseLock();
90
+ }
91
+ catch { }
92
+ this.writer = null;
93
+ }
94
+ if (this.reader) {
95
+ try {
96
+ this.reader.releaseLock();
97
+ }
98
+ catch { }
99
+ this.reader = null;
100
+ }
101
+ if (this.session) {
102
+ try {
103
+ this.session.close();
104
+ }
105
+ catch { }
106
+ this.session = null;
107
+ }
108
+ this.stream = null;
109
+ }
110
+ async startReadLoop() {
111
+ this.readLoopAbort = false;
112
+ if (!this.reader)
113
+ return;
114
+ while (!this.readLoopAbort) {
115
+ const { value, done } = await this.reader.read();
116
+ if (done)
117
+ return;
118
+ if (value && value.byteLength > 0) {
119
+ this.frameHandler?.(value);
120
+ }
121
+ }
122
+ }
123
+ }
124
+ exports.WebTransportTransport = WebTransportTransport;
@@ -0,0 +1,24 @@
1
+ import type { MessagingTransport, MessagingTransportClose } from './messaging-transport';
2
+ /**
3
+ * WebSocket adapter for {@link MessagingTransport}. Wraps the global
4
+ * WebSocket constructor; the client supplies the full URL (already
5
+ * carrying the JWT + deviceId query params).
6
+ */
7
+ export declare class WebSocketMessagingTransport implements MessagingTransport {
8
+ private readonly url;
9
+ readonly name: "ws";
10
+ private ws;
11
+ private openHandler;
12
+ private frameHandler;
13
+ private closeHandler;
14
+ private errorHandler;
15
+ constructor(url: string);
16
+ onOpen(handler: () => void): void;
17
+ onFrame(handler: (bytes: Uint8Array) => void): void;
18
+ onClose(handler: (info: MessagingTransportClose) => void): void;
19
+ onError(handler: (err: Error) => void): void;
20
+ connect(): Promise<void>;
21
+ send(bytes: Uint8Array): void;
22
+ isOpen(): boolean;
23
+ close(code?: number, reason?: string): void;
24
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketMessagingTransport = void 0;
4
+ /**
5
+ * WebSocket adapter for {@link MessagingTransport}. Wraps the global
6
+ * WebSocket constructor; the client supplies the full URL (already
7
+ * carrying the JWT + deviceId query params).
8
+ */
9
+ class WebSocketMessagingTransport {
10
+ constructor(url) {
11
+ this.url = url;
12
+ this.name = 'ws';
13
+ this.ws = null;
14
+ this.openHandler = null;
15
+ this.frameHandler = null;
16
+ this.closeHandler = null;
17
+ this.errorHandler = null;
18
+ }
19
+ onOpen(handler) { this.openHandler = handler; }
20
+ onFrame(handler) { this.frameHandler = handler; }
21
+ onClose(handler) { this.closeHandler = handler; }
22
+ onError(handler) { this.errorHandler = handler; }
23
+ connect() {
24
+ return new Promise((resolve, reject) => {
25
+ const ws = new WebSocket(this.url);
26
+ ws.binaryType = 'arraybuffer';
27
+ ws.onopen = () => {
28
+ this.ws = ws;
29
+ this.openHandler?.();
30
+ resolve();
31
+ };
32
+ ws.onerror = (event) => {
33
+ const err = new Error('Failed to connect DropOnAir websocket');
34
+ this.errorHandler?.(err);
35
+ // If the socket never opened, reject the connect promise.
36
+ if (ws.readyState !== WebSocket.OPEN) {
37
+ reject(err);
38
+ }
39
+ };
40
+ ws.onclose = (event) => {
41
+ this.ws = null;
42
+ this.closeHandler?.({ code: event.code, reason: event.reason });
43
+ };
44
+ ws.onmessage = (event) => {
45
+ if (event.data instanceof ArrayBuffer) {
46
+ this.frameHandler?.(new Uint8Array(event.data));
47
+ }
48
+ };
49
+ });
50
+ }
51
+ send(bytes) {
52
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
53
+ throw new Error('WebSocketMessagingTransport: not open');
54
+ }
55
+ this.ws.send(bytes);
56
+ }
57
+ isOpen() {
58
+ return !!this.ws && this.ws.readyState === WebSocket.OPEN;
59
+ }
60
+ close(code, reason) {
61
+ if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {
62
+ this.ws.close(code, reason);
63
+ }
64
+ this.ws = null;
65
+ }
66
+ }
67
+ exports.WebSocketMessagingTransport = WebSocketMessagingTransport;
@@ -0,0 +1,25 @@
1
+ import { type WebTransportTransportOptions } from './webtransport-transport';
2
+ import type { MessagingTransport, MessagingTransportClose } from './messaging-transport';
3
+ /**
4
+ * WebTransport (HTTP/3) adapter for {@link MessagingTransport}. Wraps the
5
+ * standalone {@link WebTransportTransport} primitive so `MessagingClient`
6
+ * can use the QUIC lane behind the same lifecycle API as WebSocket.
7
+ */
8
+ export declare class WtMessagingTransport implements MessagingTransport {
9
+ readonly name: "wt";
10
+ private inner;
11
+ private opened;
12
+ private openHandler;
13
+ private frameHandler;
14
+ private closeHandler;
15
+ private errorHandler;
16
+ constructor(options: WebTransportTransportOptions);
17
+ onOpen(handler: () => void): void;
18
+ onFrame(handler: (bytes: Uint8Array) => void): void;
19
+ onClose(handler: (info: MessagingTransportClose) => void): void;
20
+ onError(handler: (err: Error) => void): void;
21
+ connect(): Promise<void>;
22
+ send(bytes: Uint8Array): void;
23
+ isOpen(): boolean;
24
+ close(_code?: number, _reason?: string): void;
25
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WtMessagingTransport = void 0;
4
+ const webtransport_transport_1 = require("./webtransport-transport");
5
+ /**
6
+ * WebTransport (HTTP/3) adapter for {@link MessagingTransport}. Wraps the
7
+ * standalone {@link WebTransportTransport} primitive so `MessagingClient`
8
+ * can use the QUIC lane behind the same lifecycle API as WebSocket.
9
+ */
10
+ class WtMessagingTransport {
11
+ constructor(options) {
12
+ this.name = 'wt';
13
+ this.opened = false;
14
+ this.openHandler = null;
15
+ this.frameHandler = null;
16
+ this.closeHandler = null;
17
+ this.errorHandler = null;
18
+ this.inner = new webtransport_transport_1.WebTransportTransport(options);
19
+ this.inner.onFrame((bytes) => this.frameHandler?.(bytes));
20
+ this.inner.onState((state) => {
21
+ if (state === 'open') {
22
+ this.opened = true;
23
+ this.openHandler?.();
24
+ }
25
+ else if (state === 'closed') {
26
+ this.opened = false;
27
+ this.closeHandler?.({ code: 1000, reason: 'CLOSED' });
28
+ }
29
+ else if (state === 'error') {
30
+ this.errorHandler?.(new Error('WtMessagingTransport: session error'));
31
+ }
32
+ });
33
+ }
34
+ onOpen(handler) { this.openHandler = handler; }
35
+ onFrame(handler) { this.frameHandler = handler; }
36
+ onClose(handler) { this.closeHandler = handler; }
37
+ onError(handler) { this.errorHandler = handler; }
38
+ async connect() {
39
+ await this.inner.connect();
40
+ }
41
+ send(bytes) {
42
+ this.inner.sendEnvelope(bytes).catch((err) => {
43
+ this.errorHandler?.(err instanceof Error ? err : new Error(String(err)));
44
+ });
45
+ }
46
+ isOpen() {
47
+ return this.opened;
48
+ }
49
+ close(_code, _reason) {
50
+ this.inner.close();
51
+ this.opened = false;
52
+ }
53
+ }
54
+ exports.WtMessagingTransport = WtMessagingTransport;
package/dist/version.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * MINOR, additive feature (e.g. multi-device payloads, new call event type)
8
8
  * PATCH, bug-fix / perf improvement with no wire or API change
9
9
  */
10
- export declare const SDK_VERSION = "0.19.0";
10
+ export declare const SDK_VERSION = "0.22.0";
11
11
  /**
12
12
  * Binary encrypted-payload format version.
13
13
  * Included as the first byte of every encrypted payload so receivers can
package/dist/version.js CHANGED
@@ -10,7 +10,7 @@ exports.PROTOCOL_VERSION = exports.PAYLOAD_FORMAT_VERSION = exports.SDK_VERSION
10
10
  * MINOR, additive feature (e.g. multi-device payloads, new call event type)
11
11
  * PATCH, bug-fix / perf improvement with no wire or API change
12
12
  */
13
- exports.SDK_VERSION = '0.19.0';
13
+ exports.SDK_VERSION = '0.22.0';
14
14
  /**
15
15
  * Binary encrypted-payload format version.
16
16
  * Included as the first byte of every encrypted payload so receivers can
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droponair/sdk-js",
3
- "version": "0.19.0",
3
+ "version": "0.22.0",
4
4
  "description": "DropOnAir SDK for end-to-end encrypted messaging",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",