@base44-preview/sdk 0.8.36-pr.212.0d64c77 → 0.8.36-pr.212.71a10c2
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
|
@@ -12,7 +12,7 @@ import { createAppLogsModule } from "./modules/app-logs.js";
|
|
|
12
12
|
import { createUsersModule } from "./modules/users.js";
|
|
13
13
|
import { RoomsSocket } from "./utils/socket-utils.js";
|
|
14
14
|
import { createAnalyticsModule } from "./modules/analytics.js";
|
|
15
|
-
import { createRealtimeModule
|
|
15
|
+
import { createRealtimeModule } from "./modules/realtime.js";
|
|
16
16
|
/**
|
|
17
17
|
* Creates a Base44 client.
|
|
18
18
|
*
|
|
@@ -124,21 +124,6 @@ export function createClient(config) {
|
|
|
124
124
|
appBaseUrl: normalizedAppBaseUrl,
|
|
125
125
|
serverUrl,
|
|
126
126
|
});
|
|
127
|
-
// Current user session token (axios defaults are the single source of truth —
|
|
128
|
-
// createClient({token}) and every setToken() land there). Used for in-band
|
|
129
|
-
// realtime auth; read lazily so refreshes are always picked up.
|
|
130
|
-
const getUserToken = () => {
|
|
131
|
-
var _a;
|
|
132
|
-
const h = (_a = axiosClient.defaults.headers.common) === null || _a === void 0 ? void 0 : _a["Authorization"];
|
|
133
|
-
return typeof h === "string" && h.startsWith("Bearer ") ? h.slice(7) : null;
|
|
134
|
-
};
|
|
135
|
-
// Login / token refresh must reach long-lived realtime sockets too, so the
|
|
136
|
-
// handler-side credential never goes stale mid-connection.
|
|
137
|
-
const originalSetToken = userAuthModule.setToken.bind(userAuthModule);
|
|
138
|
-
userAuthModule.setToken = (newToken, saveToStorage) => {
|
|
139
|
-
originalSetToken(newToken, saveToStorage);
|
|
140
|
-
pushUserTokenToActiveSockets(newToken);
|
|
141
|
-
};
|
|
142
127
|
// Apply the access token before any module that may issue authenticated
|
|
143
128
|
// requests during construction (notably analytics, which fires an init
|
|
144
129
|
// event whose flush calls auth.me()). Without this, the first User/me
|
|
@@ -190,22 +175,13 @@ export function createClient(config) {
|
|
|
190
175
|
appId,
|
|
191
176
|
dispatcherWsUrl: resolvedDispatcherWsUrl,
|
|
192
177
|
webSocketImpl,
|
|
193
|
-
getUserToken,
|
|
194
178
|
getToken: async (handlerName, instanceId, connId) => {
|
|
195
179
|
// axiosClient interceptors unwrap response.data, so the result is the body directly.
|
|
196
180
|
// conn_id rides inside the signed token (not a WS query param) so it survives
|
|
197
181
|
// proxies that strip params; the dispatcher forwards it as the handler's conn.id.
|
|
198
182
|
// Base44-Functions-Version rides along (like function calls) so live apps get
|
|
199
183
|
// tokens for the *published* realtime script and previews get the draft.
|
|
200
|
-
const data = await axiosClient.post(`/apps/${appId}/realtime-token`, {
|
|
201
|
-
handler_name: handlerName,
|
|
202
|
-
instance_id: instanceId,
|
|
203
|
-
conn_id: connId,
|
|
204
|
-
// Declares "an __auth message follows right after connect" — the
|
|
205
|
-
// handler delays handleConnect until it arrives (signed into the
|
|
206
|
-
// token so old SDKs, which never send __auth, are never waited on).
|
|
207
|
-
supports_inband_auth: getUserToken() != null,
|
|
208
|
-
}, functionsVersion
|
|
184
|
+
const data = await axiosClient.post(`/apps/${appId}/realtime-token`, { handler_name: handlerName, instance_id: instanceId, conn_id: connId }, functionsVersion
|
|
209
185
|
? { headers: { "Base44-Functions-Version": functionsVersion } }
|
|
210
186
|
: undefined);
|
|
211
187
|
return data.token;
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
/** Push a (new) user session token to every open realtime socket — called on
|
|
2
|
-
* login/refresh so long-lived connections keep a valid credential server-side. */
|
|
3
|
-
export declare function pushUserTokenToActiveSockets(token: string): void;
|
|
4
1
|
export declare function createRealtimeModule(config: {
|
|
5
2
|
appId: string;
|
|
6
3
|
getToken(handlerName: string, instanceId: string, connId: string): Promise<string>;
|
|
7
|
-
/** Current user session token, if signed in. Sent in-band ({type:"__auth"})
|
|
8
|
-
* right after every socket open — never in the URL — so the handler can act
|
|
9
|
-
* as this user (createUserClient / RLS). */
|
|
10
|
-
getUserToken?: () => string | null;
|
|
11
4
|
dispatcherWsUrl: string;
|
|
12
5
|
/** WebSocket implementation for runtimes without a global one (Node < 22). */
|
|
13
6
|
webSocketImpl?: unknown;
|
package/dist/modules/realtime.js
CHANGED
|
@@ -4,19 +4,6 @@ const activeSockets = new Map();
|
|
|
4
4
|
function socketKey(handlerName, instanceId) {
|
|
5
5
|
return `${handlerName}:${instanceId}`;
|
|
6
6
|
}
|
|
7
|
-
/** Push a (new) user session token to every open realtime socket — called on
|
|
8
|
-
* login/refresh so long-lived connections keep a valid credential server-side. */
|
|
9
|
-
export function pushUserTokenToActiveSockets(token) {
|
|
10
|
-
if (!token)
|
|
11
|
-
return;
|
|
12
|
-
const payload = JSON.stringify({ type: "__auth", token });
|
|
13
|
-
for (const ws of activeSockets.values()) {
|
|
14
|
-
try {
|
|
15
|
-
ws.send(payload);
|
|
16
|
-
}
|
|
17
|
-
catch ( /* not open — the open handler will send */_a) { /* not open — the open handler will send */ }
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
7
|
export function createRealtimeModule(config) {
|
|
21
8
|
return new Proxy({}, {
|
|
22
9
|
get(_, handlerName) {
|
|
@@ -43,28 +30,11 @@ export function createRealtimeModule(config) {
|
|
|
43
30
|
query: () => config.getToken(handlerName, instanceId, connId).then((token) => ({ token })),
|
|
44
31
|
});
|
|
45
32
|
activeSockets.set(key, ws);
|
|
46
|
-
// In-band credential delivery (Supabase-style): the user token rides the
|
|
47
|
-
// open socket, never the URL. Sent on every open (incl. reconnects); the
|
|
48
|
-
// server may also nudge with {type:"__auth_required"} (e.g. just before
|
|
49
|
-
// the held token expires) and we answer with the current one.
|
|
50
|
-
const sendAuth = () => {
|
|
51
|
-
var _a;
|
|
52
|
-
const t = (_a = config.getUserToken) === null || _a === void 0 ? void 0 : _a.call(config);
|
|
53
|
-
if (t) {
|
|
54
|
-
try {
|
|
55
|
-
ws.send(JSON.stringify({ type: "__auth", token: t }));
|
|
56
|
-
}
|
|
57
|
-
catch ( /* not open */_b) { /* not open */ }
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
ws.addEventListener("open", sendAuth);
|
|
61
33
|
// Heartbeat / half-open detection. PartySocket only reconnects on a
|
|
62
34
|
// browser close/error event, so a silently-dead connection (TCP alive,
|
|
63
35
|
// no data — common behind proxies/LBs) hangs until the OS idle timeout
|
|
64
36
|
// (~60s). We ping periodically and force a reconnect if nothing comes
|
|
65
37
|
// back within DEAD_MS, cutting detection from ~60s to a few seconds.
|
|
66
|
-
// Pairs with the handler's setWebSocketAutoResponse("__ping"→"__pong"),
|
|
67
|
-
// so idle handlers (no app broadcasts) still keep the connection proven.
|
|
68
38
|
const PING_MS = 1000;
|
|
69
39
|
const DEAD_MS = 3000;
|
|
70
40
|
let lastMsg = Date.now();
|
|
@@ -83,10 +53,6 @@ export function createRealtimeModule(config) {
|
|
|
83
53
|
const msgType = data && typeof data === "object" ? data.type : undefined;
|
|
84
54
|
if (msgType === "__pong")
|
|
85
55
|
return;
|
|
86
|
-
if (msgType === "__auth_required") {
|
|
87
|
-
sendAuth();
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
56
|
callback(data);
|
|
91
57
|
});
|
|
92
58
|
const heartbeat = setInterval(() => {
|
|
@@ -73,8 +73,7 @@ export declare abstract class RealtimeHandler<Incoming = unknown, Outgoing = unk
|
|
|
73
73
|
* the app's row-level security, evaluated as that user at call time. The
|
|
74
74
|
* default wherever a `conn` is in scope (connect/message/close).
|
|
75
75
|
*
|
|
76
|
-
* Throws
|
|
77
|
-
* signed-out session, or an app SDK that predates in-band auth).
|
|
76
|
+
* Throws for anonymous connections (no signed-in user to act as).
|
|
78
77
|
*/
|
|
79
78
|
protected createUserClient(conn: Conn): Base44Client;
|
|
80
79
|
/**
|
package/dist/realtime-handler.js
CHANGED
|
@@ -61,8 +61,7 @@ export class RealtimeHandler {
|
|
|
61
61
|
* the app's row-level security, evaluated as that user at call time. The
|
|
62
62
|
* default wherever a `conn` is in scope (connect/message/close).
|
|
63
63
|
*
|
|
64
|
-
* Throws
|
|
65
|
-
* signed-out session, or an app SDK that predates in-band auth).
|
|
64
|
+
* Throws for anonymous connections (no signed-in user to act as).
|
|
66
65
|
*/
|
|
67
66
|
createUserClient(conn) {
|
|
68
67
|
void conn;
|