@base44-preview/sdk 0.8.35-pr.212.48756fd → 0.8.35-pr.212.4e8e6d7

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/dist/client.js CHANGED
@@ -172,9 +172,11 @@ export function createClient(config) {
172
172
  realtime: createRealtimeModule({
173
173
  appId,
174
174
  dispatcherWsUrl: resolvedDispatcherWsUrl,
175
- getToken: async (handlerName, instanceId) => {
176
- // axiosClient interceptors unwrap response.data, so the result is the body directly
177
- const data = await axiosClient.post(`/apps/${appId}/realtime-token`, { handler_name: handlerName, instance_id: instanceId });
175
+ getToken: async (handlerName, instanceId, connId) => {
176
+ // axiosClient interceptors unwrap response.data, so the result is the body directly.
177
+ // conn_id rides inside the signed token (not a WS query param) so it survives
178
+ // proxies that strip params; the dispatcher forwards it as the handler's conn.id.
179
+ const data = await axiosClient.post(`/apps/${appId}/realtime-token`, { handler_name: handlerName, instance_id: instanceId, conn_id: connId });
178
180
  return data.token;
179
181
  },
180
182
  }),
@@ -1,6 +1,6 @@
1
1
  export declare function createRealtimeModule(config: {
2
2
  appId: string;
3
- getToken(handlerName: string, instanceId: string): Promise<string>;
3
+ getToken(handlerName: string, instanceId: string, connId: string): Promise<string>;
4
4
  dispatcherWsUrl: string;
5
5
  }): Record<string, RealtimeHandler>;
6
6
  /** Handle for an active realtime subscription. */
@@ -9,19 +9,23 @@ export function createRealtimeModule(config) {
9
9
  get(_, handlerName) {
10
10
  return {
11
11
  subscribe(instanceId, callback, options) {
12
- var _a;
12
+ var _a, _b;
13
13
  const key = socketKey(handlerName, instanceId);
14
14
  // close existing if any
15
15
  (_a = activeSockets.get(key)) === null || _a === void 0 ? void 0 : _a.close();
16
+ // Connection id: caller-supplied (stable — reuse across reconnects/tabs as
17
+ // you see fit) or auto-generated per subscription. It travels INSIDE the
18
+ // signed realtime token (never as a WS query param, which proxies strip);
19
+ // the dispatcher forwards the verified claim as partyserver's _pk, so the
20
+ // handler sees this exact value as conn.id. Reconnects re-mint the token
21
+ // with the same id, so conn.id is stable across reconnects.
22
+ const connId = (_b = options === null || options === void 0 ? void 0 : options.id) !== null && _b !== void 0 ? _b : crypto.randomUUID();
16
23
  // query as async fn: called on every (re)connect, fetches a fresh token each time
17
24
  const ws = new PartySocket({
18
25
  host: config.dispatcherWsUrl,
19
26
  party: handlerName,
20
27
  room: instanceId,
21
- // Connection id: caller-supplied (stable reuse across reconnects/tabs as
22
- // you see fit) or auto-generated per connection. Server sees it as conn.id.
23
- id: options === null || options === void 0 ? void 0 : options.id,
24
- query: () => config.getToken(handlerName, instanceId).then((token) => ({ token })),
28
+ query: () => config.getToken(handlerName, instanceId, connId).then((token) => ({ token })),
25
29
  });
26
30
  activeSockets.set(key, ws);
27
31
  // Heartbeat / half-open detection. PartySocket only reconnects on a
@@ -64,7 +68,7 @@ export function createRealtimeModule(config) {
64
68
  }
65
69
  }, PING_MS);
66
70
  return {
67
- id: ws.id, // the connection id (same value the handler sees as conn.id)
71
+ id: connId, // the connection id (same value the handler sees as conn.id)
68
72
  unsubscribe() {
69
73
  clearInterval(heartbeat);
70
74
  activeSockets.delete(key);
@@ -10,8 +10,8 @@
10
10
  * declare module "@base44/sdk" {
11
11
  * interface RealtimeHandlerRegistry {
12
12
  * ChatRoom: {
13
- * inbound: { type: "joined" | "left" | "message"; userId?: string; from?: string; text?: string };
14
- * outbound: { text: string };
13
+ * toClient: { type: "joined" | "left" | "message"; userId?: string; from?: string; text?: string };
14
+ * toServer: { type: "message"; text: string };
15
15
  * };
16
16
  * }
17
17
  * }
@@ -26,11 +26,11 @@ export interface RealtimeHandlerRegistry {
26
26
  export interface RealtimeHandlerNameRegistry {
27
27
  }
28
28
  type AllHandlerNames = keyof RealtimeHandlerRegistry | keyof RealtimeHandlerNameRegistry;
29
- type InboundFor<N extends string> = N extends keyof RealtimeHandlerRegistry ? RealtimeHandlerRegistry[N] extends {
30
- inbound: infer I;
29
+ type ToClientFor<N extends string> = N extends keyof RealtimeHandlerRegistry ? RealtimeHandlerRegistry[N] extends {
30
+ toClient: infer I;
31
31
  } ? I : unknown : unknown;
32
- type OutboundFor<N extends string> = N extends keyof RealtimeHandlerRegistry ? RealtimeHandlerRegistry[N] extends {
33
- outbound: infer O;
32
+ type ToServerFor<N extends string> = N extends keyof RealtimeHandlerRegistry ? RealtimeHandlerRegistry[N] extends {
33
+ toServer: infer O;
34
34
  } ? O : unknown : unknown;
35
35
  /**
36
36
  * Client for a single named RealtimeHandler.
@@ -45,11 +45,11 @@ export interface RealtimeHandlerClient<N extends string = string> {
45
45
  * reconnect reuses the same server-side connection); omit it for an auto-generated
46
46
  * per-connection id.
47
47
  */
48
- subscribe(instanceId: string, callback: (data: InboundFor<N>) => void, options?: {
48
+ subscribe(instanceId: string, callback: (data: ToClientFor<N>) => void, options?: {
49
49
  id?: string;
50
50
  }): RealtimeSubscription;
51
51
  /** Send a message over the open socket. Throws if not subscribed. */
52
- send(instanceId: string, data: OutboundFor<N>): void;
52
+ send(instanceId: string, data: ToServerFor<N>): void;
53
53
  }
54
54
  /** Handle for an active realtime subscription. */
55
55
  export interface RealtimeSubscription {
@@ -9,7 +9,11 @@
9
9
  * Cloudflare Durable Object implementation — this file provides types only.
10
10
  */
11
11
  import type { Base44Client } from "./client.types.js";
12
- export interface Conn {
12
+ /**
13
+ * A single client connection. `Send` is the message type this connection accepts
14
+ * via {@link send} — the handler's *outgoing* (server→client) messages.
15
+ */
16
+ export interface Conn<Send = unknown> {
13
17
  /** Unique per-connection id (one per socket/tab), the same value the client
14
18
  * receives from `subscribe()`. Use this — not userId — to identify a distinct
15
19
  * client, so multiple tabs of the same user are separate connections. */
@@ -17,7 +21,7 @@ export interface Conn {
17
21
  userId: string;
18
22
  appId: string;
19
23
  instanceId: string;
20
- send(data: unknown): void;
24
+ send(data: Send): void;
21
25
  reject(code: number, reason: string): void;
22
26
  }
23
27
  export interface Storage {
@@ -25,10 +29,25 @@ export interface Storage {
25
29
  put(key: string, value: unknown): Promise<void>;
26
30
  delete(key: string): Promise<boolean>;
27
31
  }
28
- export declare abstract class RealtimeHandler<_State = unknown, Message = unknown> {
29
- abstract handleConnect(conn: Conn): void | Promise<void>;
30
- abstract handleMessage(conn: Conn, msg: Message): void | Promise<void>;
31
- abstract handleClose(conn: Conn): void | Promise<void>;
32
+ /**
33
+ * Base class for a Realtime Handler.
34
+ *
35
+ * @typeParam Incoming - messages this handler *receives* from clients
36
+ * (`handleMessage`'s `msg`) — the schema's `toServer` section.
37
+ * @typeParam Outgoing - messages this handler *sends* to clients
38
+ * (`conn.send`/`broadcast`) — the schema's `toClient` section.
39
+ *
40
+ * With a generated `schema.jsonc`, wire both from the registry so they can't drift
41
+ * from the client's types:
42
+ * ```ts
43
+ * type Reg = RealtimeHandlerRegistry["MyHandler"];
44
+ * class MyHandler extends RealtimeHandler<Reg["toServer"], Reg["toClient"]> { ... }
45
+ * ```
46
+ */
47
+ export declare abstract class RealtimeHandler<Incoming = unknown, Outgoing = unknown> {
48
+ abstract handleConnect(conn: Conn<Outgoing>): void | Promise<void>;
49
+ abstract handleMessage(conn: Conn<Outgoing>, msg: Incoming): void | Promise<void>;
50
+ abstract handleClose(conn: Conn<Outgoing>): void | Promise<void>;
32
51
  abstract handleTick(): void | Promise<void>;
33
52
  onStart(): void | Promise<void>;
34
53
  /**
@@ -43,8 +62,8 @@ export declare abstract class RealtimeHandler<_State = unknown, Message = unknow
43
62
  */
44
63
  protected tickIntervalMs: number;
45
64
  protected shouldTick?(): boolean;
46
- protected broadcast(_data: unknown): void;
47
- protected getConnections(): Conn[];
65
+ protected broadcast(_data: Outgoing): void;
66
+ protected getConnections(): Conn<Outgoing>[];
48
67
  protected startLoop(_ms: number): Promise<void>;
49
68
  protected stopLoop(): Promise<void>;
50
69
  protected get instanceId(): string;
@@ -8,6 +8,21 @@
8
8
  * At deploy time the bundler replaces this import with the compiled
9
9
  * Cloudflare Durable Object implementation — this file provides types only.
10
10
  */
11
+ /**
12
+ * Base class for a Realtime Handler.
13
+ *
14
+ * @typeParam Incoming - messages this handler *receives* from clients
15
+ * (`handleMessage`'s `msg`) — the schema's `toServer` section.
16
+ * @typeParam Outgoing - messages this handler *sends* to clients
17
+ * (`conn.send`/`broadcast`) — the schema's `toClient` section.
18
+ *
19
+ * With a generated `schema.jsonc`, wire both from the registry so they can't drift
20
+ * from the client's types:
21
+ * ```ts
22
+ * type Reg = RealtimeHandlerRegistry["MyHandler"];
23
+ * class MyHandler extends RealtimeHandler<Reg["toServer"], Reg["toClient"]> { ... }
24
+ * ```
25
+ */
11
26
  export class RealtimeHandler {
12
27
  constructor() {
13
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/sdk",
3
- "version": "0.8.35-pr.212.48756fd",
3
+ "version": "0.8.35-pr.212.4e8e6d7",
4
4
  "description": "JavaScript SDK for Base44 API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",