@chitchat/sdk-web 0.2.0-dev.1 → 0.2.0-dev.3

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/README.md CHANGED
@@ -6,17 +6,17 @@ This package is currently a **development prerelease**. Pin the version you have
6
6
 
7
7
  ## SDK foundation in v0.2
8
8
 
9
- The Web SDK now rejects text or JSON transport frames. `protobuf.encode` and optional `protobuf.encodeAuth` must return binary Protobuf bytes. Connection opening has a bounded timeout and transport failures are isolated from stale sockets.
9
+ The Web SDK now rejects text or JSON transport frames. `protobuf.encode` and optional `protobuf.encodeAuth` must return binary Protobuf bytes. With the official protocol codec, `connect()` resolves only after the gateway accepts the handshake. Connection opening has a bounded timeout and transport failures are isolated from stale sockets.
10
10
 
11
11
  ## What you need first
12
12
 
13
13
  1. A backend session endpoint created with `@chitchat/sdk-server`. It authenticates the person in your product and returns a short-lived `{ token, expiresAt }` response.
14
14
  2. An HTTPS realtime endpoint, for example `https://realtime.example.com`. The SDK converts it to `wss://realtime.example.com`.
15
- 3. A generated Protobuf codec adapter that is compatible with the ChitChat gateway’s current `chitchat.protobuf.v1` envelope and authentication frame.
15
+ 3. `@chitchat/sdk-protocol`, the official codec compatible with the ChitChat gateway’s current `chitchat.protobuf.v1` envelope and authentication frame.
16
16
  4. A durable browser outbox implementation (IndexedDB) if messages must survive page reloads.
17
17
 
18
18
  ```bash
19
- npm install @chitchat/sdk-core@development @chitchat/sdk-web@development
19
+ npm install @chitchat/sdk-core@development @chitchat/sdk-web@development @chitchat/sdk-protocol@development
20
20
  ```
21
21
 
22
22
  Do not install `@chitchat/sdk-server` in a browser application and never expose a ChitChat server API key in JavaScript, public environment variables, source maps, or logs.
@@ -26,7 +26,7 @@ Do not install `@chitchat/sdk-server` in a browser application and never expose
26
26
  ```js
27
27
  import { createBackendTokenProvider } from '@chitchat/sdk-core';
28
28
  import { createChitChatWebClient } from '@chitchat/sdk-web';
29
- import { chitchatEnvelopeCodec } from './generated/chitchat-envelope-codec.js';
29
+ import { createRealtimeEnvelopeCodec } from '@chitchat/sdk-protocol';
30
30
 
31
31
  const tokenProvider = createBackendTokenProvider({
32
32
  endpoint: 'https://api.example.com/api/chitchat/session',
@@ -37,8 +37,7 @@ const tokenProvider = createBackendTokenProvider({
37
37
  const client = createChitChatWebClient({
38
38
  endpoint: 'https://realtime.example.com',
39
39
  tokenProvider,
40
- // This must encode/decode the deployed Protobuf envelope—not JSON.
41
- protobuf: chitchatEnvelopeCodec,
40
+ protobuf: createRealtimeEnvelopeCodec({ deviceId: getStableInstallationId(), platform: 'web' }),
42
41
  storage: indexedDbOutbox
43
42
  });
44
43
 
@@ -57,27 +56,9 @@ await client.close();
57
56
  tokenProvider.invalidate();
58
57
  ```
59
58
 
60
- ## Protobuf codec requirement
61
-
62
- Pass an object with these two functions:
63
-
64
- ```js
65
- const chitchatEnvelopeCodec = {
66
- encode(frame) {
67
- // Convert the SDK frame to the exact generated Protobuf envelope bytes.
68
- // The first auth frame must match the gateway handshake schema.
69
- return generatedEnvelope.encode(frame).finish();
70
- },
71
- decode(binary) {
72
- // Convert ArrayBuffer / binary data from the gateway into an SDK frame.
73
- return generatedEnvelope.decode(new Uint8Array(binary));
74
- }
75
- };
76
- ```
77
-
78
- If the gateway has a distinct authentication envelope, add `encodeAuth({ token, protocol })` to the codec. It must also return binary bytes.
59
+ ## Official Protobuf codec
79
60
 
80
- Do not use a JSON mock codec in production. This SDK release exposes the adapter boundary; the generated ChitChat envelope codec and the production handshake compatibility test must come from the deployed platform protocol. If that codec is unavailable, do not enable realtime for users yet.
61
+ Use `createRealtimeEnvelopeCodec({ deviceId, platform })`; it produces the handshake and application envelope bytes, handles ACK translation, and rejects invalid data. Do not use a JSON mock codec in production.
81
62
 
82
63
  ## Sending and receiving
83
64
 
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ReliableRealtimeClient, ReliableRealtimeClientOptions, RealtimeFrame } from '@chitchat/sdk-core';
2
- export interface ProtobufCodec { encode(frame: RealtimeFrame): ArrayBuffer | ArrayBufferView; decode(binary: ArrayBuffer | Blob): RealtimeFrame; encodeAuth?(input: { token: string; protocol: 'chitchat.protobuf.v1' }): ArrayBuffer | ArrayBufferView; openTimeoutMs?: number; }
2
+ export interface ProtobufCodec { encode(frame: RealtimeFrame): ArrayBuffer | ArrayBufferView; decode(binary: ArrayBuffer | Blob): RealtimeFrame; encodeAuth?(input: { token: string; protocol: 'chitchat.protobuf.v1' }): ArrayBuffer | ArrayBufferView; isAuthenticationAccepted?(frame: RealtimeFrame): boolean; authenticationError?(frame: RealtimeFrame): string | null; openTimeoutMs?: number; }
3
3
  export function toWssEndpoint(endpoint: string, options?: { allowInsecureWs?: boolean }): string;
4
4
  export function createWssTransportFactory(options: ProtobufCodec & { WebSocketImpl?: typeof WebSocket; allowInsecureWs?: boolean }): ReliableRealtimeClientOptions['webTransportFactory'];
5
5
  export function createChitChatWebClient(options: Omit<ReliableRealtimeClientOptions, 'runtime' | 'webTransportFactory'> & { protobuf: ProtobufCodec; allowInsecureWs?: boolean }): ReliableRealtimeClient;
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "@chitchat/sdk-web",
3
- "version": "0.2.0-dev.1",
3
+ "version": "0.2.0-dev.3",
4
+ "description": "Browser WSS transport for the ChitChat Developer Platform",
5
+ "repository": { "type": "git", "url": "git+https://github.com/07Akashh/E2E-Chat.git", "directory": "developer-web/sdk/chitchat-web" },
6
+ "bugs": { "url": "https://github.com/07Akashh/E2E-Chat/issues" },
7
+ "homepage": "https://github.com/07Akashh/E2E-Chat/tree/main/docs/developer-platform",
4
8
  "main": "src/index.js",
5
9
  "exports": { ".": { "types": "./index.d.ts", "require": "./src/index.js", "import": "./src/index.js" } },
6
10
  "types": "index.d.ts",
7
- "files": ["src", "index.d.ts", "README.md", "LICENSE"],
11
+ "files": ["src", "index.d.ts", "README.md"],
8
12
  "engines": { "node": ">=18" },
9
- "dependencies": { "@chitchat/sdk-core": "0.2.0-dev.1" },
13
+ "dependencies": { "@chitchat/sdk-core": "0.2.0-dev.2" },
14
+ "keywords": ["chitchat", "realtime", "websocket", "wss", "protobuf"],
15
+ "sideEffects": false,
10
16
  "license": "UNLICENSED",
11
17
  "publishConfig": { "access": "public", "tag": "development" }
12
18
  }
package/src/index.js CHANGED
@@ -20,11 +20,12 @@ const binaryFrame = (value, name) => {
20
20
  return value;
21
21
  };
22
22
 
23
- const createWssTransportFactory = ({ WebSocketImpl = globalThis.WebSocket, encode, decode, encodeAuth, allowInsecureWs = false, openTimeoutMs = 15_000 }) => {
23
+ const createWssTransportFactory = ({ WebSocketImpl = globalThis.WebSocket, encode, decode, encodeAuth, isAuthenticationAccepted, authenticationError, allowInsecureWs = false, openTimeoutMs = 15_000 }) => {
24
24
  if (!WebSocketImpl || typeof encode !== 'function' || typeof decode !== 'function') throw new Error('WebSocket implementation and protobuf encode/decode functions are required');
25
+ if (typeof isAuthenticationAccepted !== 'function') throw new Error('isAuthenticationAccepted is required so the SDK can verify the realtime handshake');
25
26
  if (typeof openTimeoutMs !== 'number' || !Number.isFinite(openTimeoutMs) || openTimeoutMs < 100 || openTimeoutMs > 120_000) throw new Error('openTimeoutMs must be between 100 and 120000');
26
27
  return async ({ endpoint, token, protocol }) => {
27
- let socket; let onMessage = () => {}; let onClose = () => {}; let opened = false;
28
+ let socket; let onMessage = () => {}; let onClose = () => {}; let opened = false; let authenticationPending = true;
28
29
  const encodeFrame = (frame) => binaryFrame(encode(frame), 'protobuf.encode');
29
30
  const encodeAuthentication = () => binaryFrame(encodeAuth ? encodeAuth({ token, protocol }) : encode({ type: 'auth', token, protocol }), 'protobuf authentication encoder');
30
31
  return {
@@ -39,7 +40,7 @@ const createWssTransportFactory = ({ WebSocketImpl = globalThis.WebSocket, encod
39
40
  socket.binaryType = 'arraybuffer';
40
41
  timer = setTimeout(() => { try { socket.close(); } catch (_) {} finish(reject, new Error('WSS connection timed out')); }, openTimeoutMs);
41
42
  socket.onopen = () => {
42
- try { socket.send(encodeAuthentication()); opened = true; finish(resolve); }
43
+ try { socket.send(encodeAuthentication()); }
43
44
  catch (error) { finish(reject, error); try { socket.close(); } catch (_) {} }
44
45
  };
45
46
  socket.onerror = () => finish(reject, new Error('WSS connection failed'));
@@ -48,8 +49,15 @@ const createWssTransportFactory = ({ WebSocketImpl = globalThis.WebSocket, encod
48
49
  onClose({ code: event.code, reason: event.reason });
49
50
  };
50
51
  socket.onmessage = (event) => {
51
- try { onMessage(decode(event.data)); }
52
- catch (_) { try { socket.close(); } catch (_) {} onClose({ code: 'PROTOCOL_DECODE_ERROR', reason: 'Invalid Protobuf frame' }); }
52
+ try {
53
+ const frame = decode(event.data);
54
+ if (authenticationPending) {
55
+ const rejection = typeof authenticationError === 'function' ? authenticationError(frame) : null;
56
+ if (rejection) { finish(reject, new Error(rejection)); try { socket.close(); } catch (_) {} return; }
57
+ if (isAuthenticationAccepted(frame)) { authenticationPending = false; opened = true; finish(resolve); onMessage(frame); return; }
58
+ }
59
+ onMessage(frame);
60
+ } catch (_) { try { socket.close(); } catch (_) {} onClose({ code: 'PROTOCOL_DECODE_ERROR', reason: 'Invalid Protobuf frame' }); }
53
61
  };
54
62
  } catch (error) { finish(reject, error); }
55
63
  }),