@broadcastingplatforms/sdk 0.0.0-dev.9cfcfc6
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/auth-CRWthQ_B.d.mts +1176 -0
- package/dist/auth-CRWthQ_B.d.ts +1176 -0
- package/dist/auth.d.mts +1 -0
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +456 -0
- package/dist/auth.mjs +433 -0
- package/dist/base-client-BmVTsKhL.d.mts +70 -0
- package/dist/base-client-Dk56EJj-.d.ts +70 -0
- package/dist/browser-client.d.mts +47 -0
- package/dist/browser-client.d.ts +47 -0
- package/dist/browser-client.js +1983 -0
- package/dist/browser-client.mjs +1952 -0
- package/dist/channels.d.mts +1 -0
- package/dist/channels.d.ts +1 -0
- package/dist/channels.js +78 -0
- package/dist/channels.mjs +55 -0
- package/dist/chat.d.mts +1 -0
- package/dist/chat.d.ts +1 -0
- package/dist/chat.js +105 -0
- package/dist/chat.mjs +80 -0
- package/dist/errors.d.mts +68 -0
- package/dist/errors.d.ts +68 -0
- package/dist/errors.js +151 -0
- package/dist/errors.mjs +127 -0
- package/dist/http.d.mts +1 -0
- package/dist/http.d.ts +1 -0
- package/dist/http.js +323 -0
- package/dist/http.mjs +298 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2072 -0
- package/dist/index.mjs +2025 -0
- package/dist/realtime.d.mts +9 -0
- package/dist/realtime.d.ts +9 -0
- package/dist/realtime.js +1050 -0
- package/dist/realtime.mjs +1021 -0
- package/dist/resource.d.mts +1 -0
- package/dist/resource.d.ts +1 -0
- package/dist/resource.js +52 -0
- package/dist/resource.mjs +27 -0
- package/dist/server-client.d.mts +60 -0
- package/dist/server-client.d.ts +60 -0
- package/dist/server-client.js +1984 -0
- package/dist/server-client.mjs +1954 -0
- package/dist/storage.d.mts +149 -0
- package/dist/storage.d.ts +149 -0
- package/dist/storage.js +243 -0
- package/dist/storage.mjs +211 -0
- package/dist/streams.d.mts +1 -0
- package/dist/streams.d.ts +1 -0
- package/dist/streams.js +267 -0
- package/dist/streams.mjs +242 -0
- package/dist/types.d.mts +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +19 -0
- package/dist/types.mjs +1 -0
- package/package.json +139 -0
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
|
|
11
|
+
// src/errors.ts
|
|
12
|
+
var SDKError = class extends Error {
|
|
13
|
+
/**
|
|
14
|
+
* Construct an SDKError. Signature is compatible with Error.
|
|
15
|
+
* You can pass in a message or an options object, as with the Error constructor.
|
|
16
|
+
* Additional fields (code, etc) may be added via the second argument.
|
|
17
|
+
*/
|
|
18
|
+
constructor(message, details = {}) {
|
|
19
|
+
const resolvedMessage = message ?? (typeof details.message === "string" ? details.message : "Unknown error");
|
|
20
|
+
super(resolvedMessage);
|
|
21
|
+
/**
|
|
22
|
+
* Canonical SDK error code.
|
|
23
|
+
*/
|
|
24
|
+
__publicField(this, "code");
|
|
25
|
+
/**
|
|
26
|
+
* HTTP status code if available.
|
|
27
|
+
*/
|
|
28
|
+
__publicField(this, "statusCode");
|
|
29
|
+
/**
|
|
30
|
+
* End-user safe message.
|
|
31
|
+
*/
|
|
32
|
+
__publicField(this, "userMessage");
|
|
33
|
+
/**
|
|
34
|
+
* Optional request metadata (null when unavailable).
|
|
35
|
+
*/
|
|
36
|
+
__publicField(this, "request");
|
|
37
|
+
/**
|
|
38
|
+
* Optional response metadata (null when unavailable).
|
|
39
|
+
*/
|
|
40
|
+
__publicField(this, "response");
|
|
41
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
42
|
+
if (details && typeof details === "object") {
|
|
43
|
+
for (const [key, value] of Object.entries(details)) {
|
|
44
|
+
if (!["name", "message", "stack"].includes(key)) {
|
|
45
|
+
this[key] = value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
this.name = "SDKError";
|
|
50
|
+
this.code = details.code ?? "unknown_error";
|
|
51
|
+
this.statusCode = typeof details.statusCode === "number" ? details.statusCode : void 0;
|
|
52
|
+
this.userMessage = typeof details.userMessage === "string" ? details.userMessage : this.message;
|
|
53
|
+
this.request = details.request ?? null;
|
|
54
|
+
this.response = details.response ?? null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Serialize the error into a plain object, preserving extra fields.
|
|
58
|
+
*/
|
|
59
|
+
toJSON() {
|
|
60
|
+
const extras = { ...this };
|
|
61
|
+
delete extras.code;
|
|
62
|
+
delete extras.statusCode;
|
|
63
|
+
delete extras.message;
|
|
64
|
+
delete extras.userMessage;
|
|
65
|
+
delete extras.request;
|
|
66
|
+
delete extras.response;
|
|
67
|
+
delete extras.form;
|
|
68
|
+
delete extras.cause;
|
|
69
|
+
return {
|
|
70
|
+
...extras,
|
|
71
|
+
code: this.code,
|
|
72
|
+
statusCode: this.statusCode,
|
|
73
|
+
message: this.message,
|
|
74
|
+
userMessage: this.userMessage,
|
|
75
|
+
request: this.request,
|
|
76
|
+
response: this.response
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var STATUS_CODE_DEFAULTS = {
|
|
81
|
+
401: {
|
|
82
|
+
code: "authentication_required",
|
|
83
|
+
message: "Authentication required",
|
|
84
|
+
userMessage: "Please log in to continue. Your session may have expired."
|
|
85
|
+
},
|
|
86
|
+
403: {
|
|
87
|
+
code: "permission_denied",
|
|
88
|
+
message: "Permission denied",
|
|
89
|
+
userMessage: "You do not have permission to perform this action."
|
|
90
|
+
},
|
|
91
|
+
404: {
|
|
92
|
+
code: "not_found",
|
|
93
|
+
message: "Resource not found",
|
|
94
|
+
userMessage: "The requested resource was not found."
|
|
95
|
+
},
|
|
96
|
+
422: {
|
|
97
|
+
code: "validation_failed",
|
|
98
|
+
message: "Validation failed",
|
|
99
|
+
userMessage: "The provided information is invalid. Please check your input and try again."
|
|
100
|
+
},
|
|
101
|
+
429: {
|
|
102
|
+
code: "rate_limited",
|
|
103
|
+
message: "Rate limit exceeded",
|
|
104
|
+
userMessage: "Too many requests. Please wait a moment and try again."
|
|
105
|
+
},
|
|
106
|
+
500: {
|
|
107
|
+
code: "server_error",
|
|
108
|
+
message: "Internal server error",
|
|
109
|
+
userMessage: "Something went wrong on our end. Please try again later."
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var DEFAULT_ERROR = {
|
|
113
|
+
code: "unknown_error",
|
|
114
|
+
userMessage: "An unexpected error occurred. Please try again."
|
|
115
|
+
};
|
|
116
|
+
function createSdkError(message, details = {}) {
|
|
117
|
+
const statusCode = details.response?.status;
|
|
118
|
+
const statusValues = statusCode && STATUS_CODE_DEFAULTS[statusCode] ? STATUS_CODE_DEFAULTS[statusCode] : DEFAULT_ERROR;
|
|
119
|
+
const enrichedDetails = {
|
|
120
|
+
...details,
|
|
121
|
+
statusCode,
|
|
122
|
+
code: details.code ?? statusValues.code,
|
|
123
|
+
userMessage: details.userMessage ?? statusValues.userMessage,
|
|
124
|
+
request: details.request ?? null,
|
|
125
|
+
response: details.response ?? null
|
|
126
|
+
};
|
|
127
|
+
return new SDKError(message, enrichedDetails);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/realtime.ts
|
|
131
|
+
var resolvePusher = () => {
|
|
132
|
+
const injected = globalThis.__SDK_Pusher;
|
|
133
|
+
if (injected) {
|
|
134
|
+
return injected;
|
|
135
|
+
}
|
|
136
|
+
const globalPusher = globalThis.Pusher;
|
|
137
|
+
if (globalPusher) {
|
|
138
|
+
return globalPusher;
|
|
139
|
+
}
|
|
140
|
+
if (typeof __require === "function") {
|
|
141
|
+
try {
|
|
142
|
+
const module = __require("pusher-js");
|
|
143
|
+
return module.default ?? module;
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const dynamicImport = import("pusher-js");
|
|
148
|
+
return dynamicImport.then((module) => {
|
|
149
|
+
const resolvedModule = module;
|
|
150
|
+
return resolvedModule.default ?? module;
|
|
151
|
+
}).catch(() => {
|
|
152
|
+
throw createSdkError(
|
|
153
|
+
"Pusher constructor not found. Provide globalThis.__SDK_Pusher/globalThis.Pusher, or ensure pusher-js is resolvable from a CJS context (ESM runtimes must inject the global constructor)."
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
var isPromise = (value) => Boolean(value && typeof value.then === "function");
|
|
158
|
+
var normalizeAuthEndpoint = (baseUrl, authEndpoint) => {
|
|
159
|
+
if (authEndpoint) {
|
|
160
|
+
return authEndpoint;
|
|
161
|
+
}
|
|
162
|
+
if (!baseUrl) {
|
|
163
|
+
return "/api/broadcasting/auth";
|
|
164
|
+
}
|
|
165
|
+
const trimmed = baseUrl.replace(/\/+$/, "");
|
|
166
|
+
if (trimmed.endsWith("/api")) {
|
|
167
|
+
return `${trimmed}/broadcasting/auth`;
|
|
168
|
+
}
|
|
169
|
+
return `${trimmed}/api/broadcasting/auth`;
|
|
170
|
+
};
|
|
171
|
+
var normalizePresenceMembers = (members) => {
|
|
172
|
+
if (!members) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
if (Array.isArray(members)) {
|
|
176
|
+
return members;
|
|
177
|
+
}
|
|
178
|
+
const memberRecord = members.members;
|
|
179
|
+
if (memberRecord && typeof memberRecord === "object") {
|
|
180
|
+
return Object.values(memberRecord);
|
|
181
|
+
}
|
|
182
|
+
if (typeof members === "object") {
|
|
183
|
+
return Object.values(members);
|
|
184
|
+
}
|
|
185
|
+
return [];
|
|
186
|
+
};
|
|
187
|
+
var createPresenceBindings = () => ({
|
|
188
|
+
here: /* @__PURE__ */ new Map(),
|
|
189
|
+
joining: /* @__PURE__ */ new Map(),
|
|
190
|
+
leaving: /* @__PURE__ */ new Map()
|
|
191
|
+
});
|
|
192
|
+
var NoopRealtimeChannel = class {
|
|
193
|
+
listen() {
|
|
194
|
+
}
|
|
195
|
+
stopListening() {
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Register a no-op presence callback.
|
|
199
|
+
* @returns Unsubscribe function.
|
|
200
|
+
*/
|
|
201
|
+
here(_callback) {
|
|
202
|
+
return () => void 0;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Register a no-op presence callback.
|
|
206
|
+
* @returns Unsubscribe function.
|
|
207
|
+
*/
|
|
208
|
+
joining(_callback) {
|
|
209
|
+
return () => void 0;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Register a no-op presence callback.
|
|
213
|
+
* @returns Unsubscribe function.
|
|
214
|
+
*/
|
|
215
|
+
leaving(_callback) {
|
|
216
|
+
return () => void 0;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
var NoopRealtimeTransport = class {
|
|
220
|
+
constructor() {
|
|
221
|
+
/**
|
|
222
|
+
* Raw realtime provider instance.
|
|
223
|
+
*/
|
|
224
|
+
__publicField(this, "pusher", null);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Subscribe to a public channel.
|
|
228
|
+
*/
|
|
229
|
+
channel() {
|
|
230
|
+
return new NoopRealtimeChannel();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Subscribe to a private channel.
|
|
234
|
+
*/
|
|
235
|
+
"private"() {
|
|
236
|
+
return new NoopRealtimeChannel();
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Subscribe to a presence channel.
|
|
240
|
+
*/
|
|
241
|
+
join() {
|
|
242
|
+
return new NoopRealtimeChannel();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Leave a channel.
|
|
246
|
+
*/
|
|
247
|
+
leave() {
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Disconnect the realtime client.
|
|
251
|
+
*/
|
|
252
|
+
disconnect() {
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Update the auth token for realtime subscriptions.
|
|
256
|
+
*/
|
|
257
|
+
setToken() {
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Listen for connection state changes.
|
|
261
|
+
*/
|
|
262
|
+
onConnectionStateChange(callback) {
|
|
263
|
+
callback("disconnected");
|
|
264
|
+
return () => void 0;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
var PusherRealtimeTransport = class {
|
|
268
|
+
/**
|
|
269
|
+
* Create a new Pusher-backed realtime transport.
|
|
270
|
+
* @param options - Realtime client configuration.
|
|
271
|
+
*/
|
|
272
|
+
constructor(options) {
|
|
273
|
+
__publicField(this, "pusher", null);
|
|
274
|
+
__publicField(this, "options");
|
|
275
|
+
/**
|
|
276
|
+
* Resolved Pusher constructor used during initialization.
|
|
277
|
+
*/
|
|
278
|
+
__publicField(this, "pusherConstructor", null);
|
|
279
|
+
/**
|
|
280
|
+
* Initialization promise when awaiting async token resolution.
|
|
281
|
+
*/
|
|
282
|
+
__publicField(this, "initializationPromise", null);
|
|
283
|
+
/**
|
|
284
|
+
* Track whether disconnect was invoked before initialization finished.
|
|
285
|
+
*/
|
|
286
|
+
__publicField(this, "isDisconnected", false);
|
|
287
|
+
__publicField(this, "subscriptions", /* @__PURE__ */ new Map());
|
|
288
|
+
__publicField(this, "connectionListeners", /* @__PURE__ */ new Set());
|
|
289
|
+
/**
|
|
290
|
+
* Mutable auth header map shared with the Pusher instance.
|
|
291
|
+
*/
|
|
292
|
+
__publicField(this, "authHeaders", {});
|
|
293
|
+
__publicField(this, "token", null);
|
|
294
|
+
__publicField(this, "currentState", "connecting");
|
|
295
|
+
/**
|
|
296
|
+
* Track whether connection listeners are currently being notified.
|
|
297
|
+
*/
|
|
298
|
+
__publicField(this, "isNotifyingState", false);
|
|
299
|
+
/**
|
|
300
|
+
* Queue connection state transitions to preserve delivery order.
|
|
301
|
+
*/
|
|
302
|
+
__publicField(this, "pendingStates", []);
|
|
303
|
+
this.options = options;
|
|
304
|
+
const pendingResolutions = [];
|
|
305
|
+
const pusherResolution = resolvePusher();
|
|
306
|
+
if (isPromise(pusherResolution)) {
|
|
307
|
+
pendingResolutions.push(
|
|
308
|
+
pusherResolution.then((constructor) => {
|
|
309
|
+
this.pusherConstructor = constructor;
|
|
310
|
+
})
|
|
311
|
+
);
|
|
312
|
+
} else {
|
|
313
|
+
this.pusherConstructor = pusherResolution;
|
|
314
|
+
}
|
|
315
|
+
const tokenResolution = this.resolveTokenFromOptions();
|
|
316
|
+
if (isPromise(tokenResolution)) {
|
|
317
|
+
pendingResolutions.push(tokenResolution);
|
|
318
|
+
}
|
|
319
|
+
if (pendingResolutions.length > 0) {
|
|
320
|
+
this.initializationPromise = Promise.all(pendingResolutions).then(() => {
|
|
321
|
+
if (this.isDisconnected) {
|
|
322
|
+
this.initializationPromise = null;
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
this.initialize();
|
|
326
|
+
}).catch((error) => {
|
|
327
|
+
this.handleInitializationFailure(error);
|
|
328
|
+
});
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
this.initialize();
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Subscribe to a public channel.
|
|
335
|
+
*/
|
|
336
|
+
channel(name) {
|
|
337
|
+
return this.subscribe(name, "public");
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Subscribe to a private channel.
|
|
341
|
+
*/
|
|
342
|
+
"private"(name) {
|
|
343
|
+
return this.subscribe(name, "private");
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Subscribe to a presence channel.
|
|
347
|
+
*/
|
|
348
|
+
join(name) {
|
|
349
|
+
return this.subscribe(name, "presence");
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Leave a channel.
|
|
353
|
+
*/
|
|
354
|
+
leave(name) {
|
|
355
|
+
const subscription = this.subscriptions.get(name) ?? this.subscriptions.get(this.getChannelName(name, "presence")) ?? this.subscriptions.get(this.getChannelName(name, "private"));
|
|
356
|
+
if (!subscription) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (!this.pusher) {
|
|
360
|
+
this.subscriptions.delete(subscription.channelName);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
this.pusher.unsubscribe(subscription.channelName);
|
|
364
|
+
this.subscriptions.delete(subscription.channelName);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Disconnect the realtime client.
|
|
368
|
+
*/
|
|
369
|
+
disconnect() {
|
|
370
|
+
this.isDisconnected = true;
|
|
371
|
+
if (!this.pusher) {
|
|
372
|
+
this.subscriptions.clear();
|
|
373
|
+
this.handleConnectionState("disconnected");
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
this.pusher.disconnect();
|
|
377
|
+
this.pusher = null;
|
|
378
|
+
this.subscriptions.clear();
|
|
379
|
+
this.handleConnectionState("disconnected");
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Update the auth token for realtime subscriptions.
|
|
383
|
+
*/
|
|
384
|
+
setToken(token) {
|
|
385
|
+
this.applyToken(token);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Listen for connection state changes.
|
|
389
|
+
*/
|
|
390
|
+
onConnectionStateChange(callback) {
|
|
391
|
+
this.connectionListeners.add(callback);
|
|
392
|
+
callback(this.currentState);
|
|
393
|
+
return () => {
|
|
394
|
+
this.connectionListeners.delete(callback);
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Record initialization failures without throwing unhandled rejections.
|
|
399
|
+
* @param error - Initialization failure.
|
|
400
|
+
*/
|
|
401
|
+
handleInitializationFailure(error) {
|
|
402
|
+
void error;
|
|
403
|
+
this.initializationPromise = null;
|
|
404
|
+
this.pusher = null;
|
|
405
|
+
this.handleConnectionState("failed");
|
|
406
|
+
}
|
|
407
|
+
initialize() {
|
|
408
|
+
if (!this.pusherConstructor) {
|
|
409
|
+
throw createSdkError(
|
|
410
|
+
"Pusher constructor not found. Provide globalThis.__SDK_Pusher/globalThis.Pusher, or ensure pusher-js is resolvable from a CJS context (ESM runtimes must inject the global constructor)."
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
const authEndpoint = normalizeAuthEndpoint(
|
|
414
|
+
this.options.baseUrl,
|
|
415
|
+
this.options.authEndpoint
|
|
416
|
+
);
|
|
417
|
+
this.pusher = new this.pusherConstructor(this.options.appKey, {
|
|
418
|
+
wsHost: this.options.wsHost,
|
|
419
|
+
wsPort: this.options.wsPort ?? 443,
|
|
420
|
+
wssPort: this.options.wssPort ?? 443,
|
|
421
|
+
forceTLS: this.options.forceTLS ?? true,
|
|
422
|
+
enabledTransports: this.options.enabledTransports ?? ["ws", "wss"],
|
|
423
|
+
cluster: this.options.cluster ?? "",
|
|
424
|
+
authEndpoint,
|
|
425
|
+
auth: {
|
|
426
|
+
headers: this.authHeaders
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
this.pusher.connection.bind("state_change", (states) => {
|
|
430
|
+
this.handleConnectionState(states.current);
|
|
431
|
+
});
|
|
432
|
+
this.handleConnectionState(this.pusher.connection.state);
|
|
433
|
+
this.initializationPromise = null;
|
|
434
|
+
this.flushPendingSubscriptions(this.pusher);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Subscribe any queued channels after initialization completes.
|
|
438
|
+
* @param pusher - Initialized Pusher client instance.
|
|
439
|
+
*/
|
|
440
|
+
flushPendingSubscriptions(pusher) {
|
|
441
|
+
for (const subscription of this.subscriptions.values()) {
|
|
442
|
+
if (!subscription.pending) {
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
const channel = pusher.subscribe(
|
|
446
|
+
subscription.channelName
|
|
447
|
+
);
|
|
448
|
+
subscription.channel = channel;
|
|
449
|
+
subscription.pending = false;
|
|
450
|
+
this.bindListeners(subscription);
|
|
451
|
+
this.rebindPresenceCallbacks(subscription);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Resolve an initial token from the options provider if available.
|
|
456
|
+
* @returns A promise when async token resolution is in progress.
|
|
457
|
+
* @throws {SDKError} When token resolution fails.
|
|
458
|
+
*/
|
|
459
|
+
resolveTokenFromOptions() {
|
|
460
|
+
if (!this.options.getToken) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
try {
|
|
464
|
+
const result = this.options.getToken();
|
|
465
|
+
if (isPromise(result)) {
|
|
466
|
+
return result.then((token) => {
|
|
467
|
+
this.applyToken(token);
|
|
468
|
+
}).catch((error) => {
|
|
469
|
+
throw this.normalizeTokenError(error, "Failed to resolve auth token.");
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
this.applyToken(result ?? null);
|
|
473
|
+
} catch (error) {
|
|
474
|
+
throw this.normalizeTokenError(error, "Failed to resolve auth token.");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Normalize token resolution errors into SDKError instances.
|
|
479
|
+
* @param error - Error to normalize.
|
|
480
|
+
* @param fallbackMessage - Fallback error message.
|
|
481
|
+
* @returns Normalized SDKError instance.
|
|
482
|
+
*/
|
|
483
|
+
normalizeTokenError(error, fallbackMessage) {
|
|
484
|
+
if (error instanceof SDKError) {
|
|
485
|
+
return error;
|
|
486
|
+
}
|
|
487
|
+
const message = error instanceof Error ? error.message : fallbackMessage;
|
|
488
|
+
return createSdkError(message);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Apply a new auth token to the client configuration.
|
|
492
|
+
* Refresh auth subscriptions whenever the token changes.
|
|
493
|
+
*/
|
|
494
|
+
applyToken(token) {
|
|
495
|
+
if (token === this.token) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
this.token = token;
|
|
499
|
+
this.syncAuthHeaders();
|
|
500
|
+
if (!this.pusher) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
this.refreshAuthSubscriptions();
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Sync the auth header map with the current token.
|
|
507
|
+
*/
|
|
508
|
+
syncAuthHeaders() {
|
|
509
|
+
if (this.token) {
|
|
510
|
+
this.authHeaders.Authorization = `Bearer ${this.token}`;
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
delete this.authHeaders.Authorization;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Normalize and broadcast realtime connection state changes.
|
|
517
|
+
*/
|
|
518
|
+
handleConnectionState(state) {
|
|
519
|
+
const mapped = this.mapConnectionState(state);
|
|
520
|
+
if (mapped === this.currentState) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
this.currentState = mapped;
|
|
524
|
+
this.pendingStates.push(mapped);
|
|
525
|
+
if (this.isNotifyingState) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
this.isNotifyingState = true;
|
|
529
|
+
let firstError = null;
|
|
530
|
+
try {
|
|
531
|
+
while (this.pendingStates.length) {
|
|
532
|
+
const nextState = this.pendingStates.shift();
|
|
533
|
+
if (!nextState) {
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
const listeners = Array.from(this.connectionListeners);
|
|
537
|
+
for (const listener of listeners) {
|
|
538
|
+
try {
|
|
539
|
+
listener(nextState);
|
|
540
|
+
} catch (error) {
|
|
541
|
+
if (!firstError) {
|
|
542
|
+
firstError = error;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
} finally {
|
|
548
|
+
this.isNotifyingState = false;
|
|
549
|
+
}
|
|
550
|
+
if (firstError) {
|
|
551
|
+
throw firstError;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
mapConnectionState(state) {
|
|
555
|
+
switch (state) {
|
|
556
|
+
case "initialized":
|
|
557
|
+
case "connecting":
|
|
558
|
+
return "connecting";
|
|
559
|
+
case "connected":
|
|
560
|
+
return "connected";
|
|
561
|
+
case "disconnected":
|
|
562
|
+
return "disconnected";
|
|
563
|
+
case "unavailable":
|
|
564
|
+
return "unavailable";
|
|
565
|
+
case "failed":
|
|
566
|
+
return "failed";
|
|
567
|
+
default:
|
|
568
|
+
return "disconnected";
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
subscribe(name, type) {
|
|
572
|
+
if (this.isDisconnected) {
|
|
573
|
+
return new NoopRealtimeChannel();
|
|
574
|
+
}
|
|
575
|
+
const channelName = this.getChannelName(name, type);
|
|
576
|
+
const existing = this.subscriptions.get(channelName);
|
|
577
|
+
if (existing) {
|
|
578
|
+
return this.createChannelWrapper(existing);
|
|
579
|
+
}
|
|
580
|
+
if (!this.pusher) {
|
|
581
|
+
if (this.initializationPromise) {
|
|
582
|
+
const subscription2 = this.createPendingSubscription(
|
|
583
|
+
name,
|
|
584
|
+
channelName,
|
|
585
|
+
type
|
|
586
|
+
);
|
|
587
|
+
this.subscriptions.set(channelName, subscription2);
|
|
588
|
+
return this.createChannelWrapper(subscription2);
|
|
589
|
+
}
|
|
590
|
+
return new NoopRealtimeChannel();
|
|
591
|
+
}
|
|
592
|
+
const channel = this.pusher.subscribe(channelName);
|
|
593
|
+
const subscription = {
|
|
594
|
+
name,
|
|
595
|
+
channelName,
|
|
596
|
+
type,
|
|
597
|
+
channel,
|
|
598
|
+
listeners: /* @__PURE__ */ new Map(),
|
|
599
|
+
presence: {
|
|
600
|
+
here: /* @__PURE__ */ new Set(),
|
|
601
|
+
joining: /* @__PURE__ */ new Set(),
|
|
602
|
+
leaving: /* @__PURE__ */ new Set()
|
|
603
|
+
},
|
|
604
|
+
presenceBindings: createPresenceBindings()
|
|
605
|
+
};
|
|
606
|
+
this.subscriptions.set(channelName, subscription);
|
|
607
|
+
return this.createChannelWrapper(subscription);
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Create a placeholder channel while initialization is pending.
|
|
611
|
+
*/
|
|
612
|
+
createPendingChannel(type) {
|
|
613
|
+
const channel = {
|
|
614
|
+
bind: () => void 0,
|
|
615
|
+
unbind: () => void 0,
|
|
616
|
+
unbind_all: () => void 0
|
|
617
|
+
};
|
|
618
|
+
if (type === "presence") {
|
|
619
|
+
return {
|
|
620
|
+
...channel,
|
|
621
|
+
members: void 0
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
return channel;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Create a subscription record before the Pusher client is ready.
|
|
628
|
+
*/
|
|
629
|
+
createPendingSubscription(name, channelName, type) {
|
|
630
|
+
return {
|
|
631
|
+
name,
|
|
632
|
+
channelName,
|
|
633
|
+
type,
|
|
634
|
+
channel: this.createPendingChannel(type),
|
|
635
|
+
listeners: /* @__PURE__ */ new Map(),
|
|
636
|
+
presence: {
|
|
637
|
+
here: /* @__PURE__ */ new Set(),
|
|
638
|
+
joining: /* @__PURE__ */ new Set(),
|
|
639
|
+
leaving: /* @__PURE__ */ new Set()
|
|
640
|
+
},
|
|
641
|
+
presenceBindings: createPresenceBindings(),
|
|
642
|
+
pending: true
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Bind non-presence event listeners to the current channel.
|
|
647
|
+
* @param subscription - Target subscription record.
|
|
648
|
+
*/
|
|
649
|
+
bindListeners(subscription) {
|
|
650
|
+
const channel = subscription.channel;
|
|
651
|
+
for (const [event, callbacks] of subscription.listeners.entries()) {
|
|
652
|
+
for (const callback of callbacks) {
|
|
653
|
+
channel.bind(event, callback);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Rebind presence callbacks to the current channel instance.
|
|
659
|
+
* @param subscription - Target subscription record.
|
|
660
|
+
* @param options - Optional rebinding configuration.
|
|
661
|
+
* @param options.emitHere - When true, emit the current member list immediately.
|
|
662
|
+
*/
|
|
663
|
+
rebindPresenceCallbacks(subscription, options = {}) {
|
|
664
|
+
if (subscription.type !== "presence") {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
const emitHere = options.emitHere ?? true;
|
|
668
|
+
subscription.presenceBindings = createPresenceBindings();
|
|
669
|
+
for (const callback of subscription.presence.here) {
|
|
670
|
+
this.bindPresenceListener(subscription, "here", callback);
|
|
671
|
+
}
|
|
672
|
+
for (const callback of subscription.presence.joining) {
|
|
673
|
+
this.bindPresenceListener(subscription, "joining", callback);
|
|
674
|
+
}
|
|
675
|
+
for (const callback of subscription.presence.leaving) {
|
|
676
|
+
this.bindPresenceListener(subscription, "leaving", callback);
|
|
677
|
+
}
|
|
678
|
+
const presenceChannel = subscription.channel;
|
|
679
|
+
const members = normalizePresenceMembers(presenceChannel.members);
|
|
680
|
+
if (emitHere && members.length) {
|
|
681
|
+
for (const callback of subscription.presence.here) {
|
|
682
|
+
callback(members);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Bind a presence listener for the current subscription channel.
|
|
688
|
+
*/
|
|
689
|
+
bindPresenceListener(subscription, type, callback) {
|
|
690
|
+
const presenceChannel = subscription.channel;
|
|
691
|
+
if (type === "here") {
|
|
692
|
+
const bindings2 = subscription.presenceBindings.here;
|
|
693
|
+
const hereCallback = callback;
|
|
694
|
+
if (bindings2.has(hereCallback)) {
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const handler2 = (members) => hereCallback(normalizePresenceMembers(members));
|
|
698
|
+
presenceChannel.bind("pusher:subscription_succeeded", handler2);
|
|
699
|
+
bindings2.set(hereCallback, handler2);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
if (type === "joining") {
|
|
703
|
+
const bindings2 = subscription.presenceBindings.joining;
|
|
704
|
+
const joiningCallback = callback;
|
|
705
|
+
if (bindings2.has(joiningCallback)) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
const handler2 = (payload) => joiningCallback(payload);
|
|
709
|
+
presenceChannel.bind("pusher:member_added", handler2);
|
|
710
|
+
bindings2.set(joiningCallback, handler2);
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
const bindings = subscription.presenceBindings.leaving;
|
|
714
|
+
const leavingCallback = callback;
|
|
715
|
+
if (bindings.has(leavingCallback)) {
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
const handler = (payload) => leavingCallback(payload);
|
|
719
|
+
presenceChannel.bind("pusher:member_removed", handler);
|
|
720
|
+
bindings.set(leavingCallback, handler);
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Remove a presence listener for the current subscription channel.
|
|
724
|
+
*/
|
|
725
|
+
removePresenceListener(subscription, type, callback) {
|
|
726
|
+
if (subscription.type !== "presence") {
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
const presenceChannel = subscription.channel;
|
|
730
|
+
if (type === "here") {
|
|
731
|
+
const hereCallback = callback;
|
|
732
|
+
subscription.presence.here.delete(hereCallback);
|
|
733
|
+
const bindings2 = subscription.presenceBindings.here;
|
|
734
|
+
const handler2 = bindings2.get(hereCallback);
|
|
735
|
+
if (handler2) {
|
|
736
|
+
presenceChannel.unbind(
|
|
737
|
+
"pusher:subscription_succeeded",
|
|
738
|
+
handler2
|
|
739
|
+
);
|
|
740
|
+
bindings2.delete(hereCallback);
|
|
741
|
+
}
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
if (type === "joining") {
|
|
745
|
+
const joiningCallback = callback;
|
|
746
|
+
subscription.presence.joining.delete(joiningCallback);
|
|
747
|
+
const bindings2 = subscription.presenceBindings.joining;
|
|
748
|
+
const handler2 = bindings2.get(joiningCallback);
|
|
749
|
+
if (handler2) {
|
|
750
|
+
presenceChannel.unbind(
|
|
751
|
+
"pusher:member_added",
|
|
752
|
+
handler2
|
|
753
|
+
);
|
|
754
|
+
bindings2.delete(joiningCallback);
|
|
755
|
+
}
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
const leavingCallback = callback;
|
|
759
|
+
subscription.presence.leaving.delete(leavingCallback);
|
|
760
|
+
const bindings = subscription.presenceBindings.leaving;
|
|
761
|
+
const handler = bindings.get(leavingCallback);
|
|
762
|
+
if (handler) {
|
|
763
|
+
presenceChannel.unbind(
|
|
764
|
+
"pusher:member_removed",
|
|
765
|
+
handler
|
|
766
|
+
);
|
|
767
|
+
bindings.delete(leavingCallback);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
createChannelWrapper(subscription) {
|
|
771
|
+
if (subscription.type === "presence") {
|
|
772
|
+
return this.createPresenceChannelWrapper(subscription);
|
|
773
|
+
}
|
|
774
|
+
return this.createBaseChannelWrapper(subscription);
|
|
775
|
+
}
|
|
776
|
+
createBaseChannelWrapper(subscription) {
|
|
777
|
+
return {
|
|
778
|
+
listen: (event, callback) => {
|
|
779
|
+
this.addListener(subscription, event, callback);
|
|
780
|
+
},
|
|
781
|
+
stopListening: (event, callback) => {
|
|
782
|
+
this.removeListener(subscription, event, callback);
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Create a presence channel wrapper with unsubscribe support.
|
|
788
|
+
*/
|
|
789
|
+
createPresenceChannelWrapper(subscription) {
|
|
790
|
+
const channel = this.createBaseChannelWrapper(subscription);
|
|
791
|
+
return {
|
|
792
|
+
...channel,
|
|
793
|
+
here: (callback) => {
|
|
794
|
+
subscription.presence.here.add(callback);
|
|
795
|
+
this.bindPresenceListener(subscription, "here", callback);
|
|
796
|
+
const presenceChannel = subscription.channel;
|
|
797
|
+
const members = normalizePresenceMembers(presenceChannel.members);
|
|
798
|
+
if (members.length) {
|
|
799
|
+
callback(members);
|
|
800
|
+
}
|
|
801
|
+
return () => {
|
|
802
|
+
this.removePresenceListener(subscription, "here", callback);
|
|
803
|
+
};
|
|
804
|
+
},
|
|
805
|
+
joining: (callback) => {
|
|
806
|
+
subscription.presence.joining.add(callback);
|
|
807
|
+
this.bindPresenceListener(subscription, "joining", callback);
|
|
808
|
+
return () => {
|
|
809
|
+
this.removePresenceListener(subscription, "joining", callback);
|
|
810
|
+
};
|
|
811
|
+
},
|
|
812
|
+
leaving: (callback) => {
|
|
813
|
+
subscription.presence.leaving.add(callback);
|
|
814
|
+
this.bindPresenceListener(subscription, "leaving", callback);
|
|
815
|
+
return () => {
|
|
816
|
+
this.removePresenceListener(subscription, "leaving", callback);
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Refresh private and presence subscriptions after auth changes.
|
|
823
|
+
*/
|
|
824
|
+
refreshAuthSubscriptions() {
|
|
825
|
+
if (!this.pusher) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
for (const subscription of this.subscriptions.values()) {
|
|
829
|
+
if (subscription.type === "public") {
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
this.pusher.unsubscribe(subscription.channelName);
|
|
833
|
+
if (!this.token) {
|
|
834
|
+
subscription.channel.unbind_all();
|
|
835
|
+
subscription.channel = this.createPendingChannel(subscription.type);
|
|
836
|
+
subscription.presenceBindings = createPresenceBindings();
|
|
837
|
+
continue;
|
|
838
|
+
}
|
|
839
|
+
const channel = this.pusher.subscribe(
|
|
840
|
+
subscription.channelName
|
|
841
|
+
);
|
|
842
|
+
subscription.channel = channel;
|
|
843
|
+
this.bindListeners(subscription);
|
|
844
|
+
this.rebindPresenceCallbacks(subscription);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Register a listener for a realtime event.
|
|
849
|
+
* @param subscription - Target subscription record.
|
|
850
|
+
* @param event - Realtime event name (leading dot is optional).
|
|
851
|
+
* @param callback - Event handler callback.
|
|
852
|
+
*/
|
|
853
|
+
addListener(subscription, event, callback) {
|
|
854
|
+
const normalizedEvent = event.startsWith(".") ? event.slice(1) : event;
|
|
855
|
+
let callbacks = subscription.listeners.get(normalizedEvent);
|
|
856
|
+
if (!callbacks) {
|
|
857
|
+
callbacks = /* @__PURE__ */ new Set();
|
|
858
|
+
subscription.listeners.set(normalizedEvent, callbacks);
|
|
859
|
+
}
|
|
860
|
+
if (callbacks.has(callback)) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
callbacks.add(callback);
|
|
864
|
+
subscription.channel.bind(
|
|
865
|
+
normalizedEvent,
|
|
866
|
+
callback
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Remove listeners for a realtime event.
|
|
871
|
+
* @param subscription - Target subscription record.
|
|
872
|
+
* @param event - Realtime event name to stop listening for.
|
|
873
|
+
* @param callback - Specific handler to remove if provided.
|
|
874
|
+
*/
|
|
875
|
+
removeListener(subscription, event, callback) {
|
|
876
|
+
if (!event) {
|
|
877
|
+
subscription.listeners.clear();
|
|
878
|
+
subscription.channel.unbind_all();
|
|
879
|
+
this.rebindPresenceCallbacks(subscription, { emitHere: false });
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
const normalizedEvent = event.startsWith(".") ? event.slice(1) : event;
|
|
883
|
+
if (!subscription.listeners.has(normalizedEvent)) {
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
if (callback) {
|
|
887
|
+
subscription.listeners.get(normalizedEvent)?.delete(callback);
|
|
888
|
+
subscription.channel.unbind(
|
|
889
|
+
normalizedEvent,
|
|
890
|
+
callback
|
|
891
|
+
);
|
|
892
|
+
if (subscription.listeners.get(normalizedEvent)?.size === 0) {
|
|
893
|
+
subscription.listeners.delete(normalizedEvent);
|
|
894
|
+
}
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
subscription.listeners.delete(normalizedEvent);
|
|
898
|
+
subscription.channel.unbind(normalizedEvent);
|
|
899
|
+
}
|
|
900
|
+
getChannelName(name, type) {
|
|
901
|
+
switch (type) {
|
|
902
|
+
case "private":
|
|
903
|
+
return name.startsWith("private-") ? name : `private-${name}`;
|
|
904
|
+
case "presence":
|
|
905
|
+
return name.startsWith("presence-") ? name : `presence-${name}`;
|
|
906
|
+
default:
|
|
907
|
+
return name;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
var RealtimeNamespace = class {
|
|
912
|
+
/**
|
|
913
|
+
* Create a new realtime namespace client.
|
|
914
|
+
* @param transport - Transport implementation for realtime operations.
|
|
915
|
+
*/
|
|
916
|
+
constructor(transport) {
|
|
917
|
+
__publicField(this, "chat");
|
|
918
|
+
__publicField(this, "transport");
|
|
919
|
+
this.transport = transport;
|
|
920
|
+
this.chat = this.createChatNamespace();
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Raw Pusher client instance for advanced usage.
|
|
924
|
+
*/
|
|
925
|
+
get pusher() {
|
|
926
|
+
return this.transport.pusher;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Subscribe to a public channel.
|
|
930
|
+
*/
|
|
931
|
+
channel(name) {
|
|
932
|
+
return this.transport.channel(name);
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Subscribe to a private channel.
|
|
936
|
+
*/
|
|
937
|
+
"private"(name) {
|
|
938
|
+
return this.transport.private(name);
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Subscribe to a presence channel.
|
|
942
|
+
*/
|
|
943
|
+
join(name) {
|
|
944
|
+
return this.transport.join(name);
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Leave a channel.
|
|
948
|
+
*/
|
|
949
|
+
leave(name) {
|
|
950
|
+
this.transport.leave(name);
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Disconnect the realtime client.
|
|
954
|
+
*/
|
|
955
|
+
disconnect() {
|
|
956
|
+
this.transport.disconnect();
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Update the auth token for realtime subscriptions.
|
|
960
|
+
*/
|
|
961
|
+
setToken(token) {
|
|
962
|
+
this.transport.setToken(token);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Listen for connection state changes.
|
|
966
|
+
*/
|
|
967
|
+
onConnectionStateChange(callback) {
|
|
968
|
+
return this.transport.onConnectionStateChange(callback);
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Create the chat realtime helpers.
|
|
972
|
+
*/
|
|
973
|
+
createChatNamespace() {
|
|
974
|
+
return {
|
|
975
|
+
joinRoom: (channelId) => {
|
|
976
|
+
const channelName = this.toChatRoom(channelId);
|
|
977
|
+
return this.join(channelName);
|
|
978
|
+
},
|
|
979
|
+
leaveRoom: (channelId) => {
|
|
980
|
+
this.leave(this.toChatRoom(channelId));
|
|
981
|
+
},
|
|
982
|
+
onMessage: (channelId, callback) => this.attachChatListener(channelId, ".SendPublicChatMessage", callback),
|
|
983
|
+
onMessageUpdated: (channelId, callback) => this.attachChatListener(channelId, ".chat.message.updated", callback),
|
|
984
|
+
onMessageDeleted: (channelId, callback) => this.attachChatListener(channelId, ".chat.message.deleted", callback)
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Attach a chat listener to the channel room.
|
|
989
|
+
*/
|
|
990
|
+
attachChatListener(channelId, event, callback) {
|
|
991
|
+
const channel = this.join(this.toChatRoom(channelId));
|
|
992
|
+
channel.listen(event, callback);
|
|
993
|
+
return () => {
|
|
994
|
+
channel.stopListening(event, callback);
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Build the chat room name for a channel id.
|
|
999
|
+
*/
|
|
1000
|
+
toChatRoom(channelId) {
|
|
1001
|
+
return `chat-public.${String(channelId)}`;
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
var createRealtimeClient = (options) => {
|
|
1005
|
+
if (!options) {
|
|
1006
|
+
return new RealtimeNamespace(new NoopRealtimeTransport());
|
|
1007
|
+
}
|
|
1008
|
+
try {
|
|
1009
|
+
return new RealtimeNamespace(new PusherRealtimeTransport(options));
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
if (error instanceof SDKError) {
|
|
1012
|
+
throw error;
|
|
1013
|
+
}
|
|
1014
|
+
const message = error instanceof Error ? error.message : "Unknown realtime error";
|
|
1015
|
+
throw createSdkError(`Failed to initialize realtime client: ${message}`);
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
export {
|
|
1019
|
+
createRealtimeClient
|
|
1020
|
+
};
|
|
1021
|
+
//# sourceMappingURL=realtime.mjs.map
|