@aurabase/realtime 0.5.0 → 0.5.1

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/index.cjs CHANGED
@@ -272,10 +272,12 @@ var AuraChannel = class {
272
272
  constructor(name, projectPrefix, options) {
273
273
  this.name = name;
274
274
  this._projectPrefix = projectPrefix;
275
- this._isPrivate = options?.private ?? false;
276
- this._broadcastAck = options?.broadcast?.ack ?? false;
277
- this._broadcastSelf = options?.broadcast?.self ?? false;
278
- this._presenceKey = options?.config?.presence?.key ?? "";
275
+ const bcast = options?.broadcast ?? options?.config?.broadcast;
276
+ const pres = options?.presence ?? options?.config?.presence;
277
+ this._isPrivate = Boolean(options?.private ?? options?.config?.private ?? false);
278
+ this._broadcastAck = Boolean(bcast?.ack ?? false);
279
+ this._broadcastSelf = Boolean(bcast?.self ?? false);
280
+ this._presenceKey = typeof pres?.key === "string" ? pres.key : "";
279
281
  }
280
282
  /** Génère un ref_id unique pour la corrélation request/response. */
281
283
  _nextRef() {
@@ -308,6 +310,7 @@ var AuraChannel = class {
308
310
  subscribe(callback, timeoutMs) {
309
311
  this._subscribeCallback = callback ?? null;
310
312
  this._subscribed = true;
313
+ this._serverState = "pending";
311
314
  this._closedEmitted = false;
312
315
  if (typeof timeoutMs === "number" && timeoutMs > 0) {
313
316
  this._subscribeTimeoutMs = timeoutMs;
@@ -694,14 +697,32 @@ var AuraChannel = class {
694
697
  }
695
698
  }
696
699
  }
697
- listener.callback(event);
700
+ const cdcPayload = payload && typeof payload === "object" ? payload : {};
701
+ if (cdcPayload.new === void 0 && cdcPayload.record !== void 0) {
702
+ cdcPayload.new = cdcPayload.record;
703
+ }
704
+ if (cdcPayload.old === void 0 && cdcPayload.old_record !== void 0) {
705
+ cdcPayload.old = cdcPayload.old_record;
706
+ }
707
+ if (cdcPayload.eventType === void 0 && cdcPayload.type !== void 0) {
708
+ cdcPayload.eventType = cdcPayload.type;
709
+ }
710
+ const enrichedEvent = Object.assign(Object.create(event), {
711
+ new: cdcPayload.record,
712
+ old: cdcPayload.old_record,
713
+ eventType: cdcPayload.type,
714
+ schema: cdcPayload.schema,
715
+ table: cdcPayload.table
716
+ });
717
+ listener.callback(enrichedEvent);
698
718
  }
699
719
  }
700
720
  } else if (listener.type === "broadcast") {
701
721
  if (eventType === "broadcast") {
702
722
  const filter = listener.filter;
703
- const payload = event.payload;
704
- if (!filter.event || payload.event === filter.event) {
723
+ const broadcastPayload = event.payload && typeof event.payload === "object" ? event.payload : void 0;
724
+ const broadcastEvent = broadcastPayload?.event;
725
+ if (!filter.event || filter.event === "*" || broadcastEvent === filter.event) {
705
726
  listener.callback(event);
706
727
  }
707
728
  }
@@ -926,6 +947,8 @@ var RealtimeService = class _RealtimeService {
926
947
  _tokenRefreshTimer = null;
927
948
  /** Dernier access_token propagé au serveur — évite les pushs redondants (propagation différentielle). */
928
949
  _lastSentToken = null;
950
+ /** Token d'authentification explicite passé à setAuth(), prioritaire sur authStore. */
951
+ _customAuthToken = null;
929
952
  /** Listeners d'erreurs de transport (handshake refusé, coupure, connexion morte). */
930
953
  _errorListeners = /* @__PURE__ */ new Set();
931
954
  /**
@@ -955,6 +978,10 @@ var RealtimeService = class _RealtimeService {
955
978
  get connectionState() {
956
979
  return this._state;
957
980
  }
981
+ /** Whether the WebSocket is currently connected. */
982
+ get isConnected() {
983
+ return this._state === "connected";
984
+ }
958
985
  /** Listen for connection state changes. */
959
986
  onStateChange(callback) {
960
987
  this._stateListeners.add(callback);
@@ -1019,17 +1046,15 @@ var RealtimeService = class _RealtimeService {
1019
1046
  }
1020
1047
  // ─── Préfixe de projet des canaux ───────────────────────────────────────
1021
1048
  /**
1022
- * Préfixe `"<project_id>:"` des noms de canaux sur le fil, `""` s'il est inconnu.
1049
+ * Préfixe de projet déduit du token courant (`<project_id>:`), vide si aucun token.
1023
1050
  *
1024
- * `aura-realtime` exige que tout canal commence par le `project_id` du TOKEN
1025
- * (`handlers/websocket.rs`, `expected_prefix` ; idem pour le broadcast HTTP,
1026
- * `handlers/broadcast.rs`). Le SDK ne porte plus d'identifiant de projet — le projet est
1027
- * celui de l'URL — mais le token de session, lui, porte ce claim : on le lit là, dans le
1028
- * même jeton que celui envoyé au serveur. Sans token (pas encore connecté), il n'y a rien
1051
+ * Utilisé pour normaliser les noms de canaux : le serveur (`aura-realtime`) attend
1052
+ * systématiquement `<project_id>:<canal>` sur le protocole WebSocket et REST, alors que
1053
+ * l'utilisateur passe généralement un nom court (`room-1`). Sans session, aucun préfixe
1029
1054
  * à préfixer ; la connexion WS échouerait de toute façon, le serveur exigeant un JWT.
1030
1055
  */
1031
1056
  _projectPrefix() {
1032
- const token = this.client.authStore.token;
1057
+ const token = this._customAuthToken ?? this.client.authStore.token;
1033
1058
  if (!token) return "";
1034
1059
  const pid = getTokenProjectId(token);
1035
1060
  return pid ? `${pid}:` : "";
@@ -1047,7 +1072,7 @@ var RealtimeService = class _RealtimeService {
1047
1072
  }
1048
1073
  this._intentionalClose = false;
1049
1074
  this._setState("connecting");
1050
- const token = this.client.authStore.token;
1075
+ const token = this._customAuthToken ?? this.client.authStore.token;
1051
1076
  const params = new URLSearchParams();
1052
1077
  if (token) params.set("token", token);
1053
1078
  if (this.client.apiKey) params.set("apikey", this.client.apiKey);
@@ -1066,6 +1091,9 @@ var RealtimeService = class _RealtimeService {
1066
1091
  opened = true;
1067
1092
  this._reconnectAttempts = 0;
1068
1093
  this._setState("connected");
1094
+ if (this._customAuthToken && this._customAuthToken !== this._lastSentToken) {
1095
+ this.refreshToken(this._customAuthToken);
1096
+ }
1069
1097
  this._awaitingPong = false;
1070
1098
  this._lastServerMessageAt = Date.now();
1071
1099
  this._heartbeat.start(() => this._heartbeatTick(ws), HEARTBEAT_INTERVAL_MS);
@@ -1291,7 +1319,11 @@ var RealtimeService = class _RealtimeService {
1291
1319
  */
1292
1320
  setAuth(token) {
1293
1321
  const resolved = token ?? this.client.authStore.token;
1294
- if (resolved == null) return;
1322
+ this._customAuthToken = resolved ?? null;
1323
+ if (resolved == null) {
1324
+ this._lastSentToken = null;
1325
+ return;
1326
+ }
1295
1327
  this.refreshToken(resolved);
1296
1328
  }
1297
1329
  /**
@@ -1469,8 +1501,9 @@ var RealtimeService = class _RealtimeService {
1469
1501
  }
1470
1502
  return ch;
1471
1503
  }
1472
- /** Remove a channel. */
1473
- removeChannel(name) {
1504
+ /** Remove a channel by name or by AuraChannel instance. */
1505
+ removeChannel(channel) {
1506
+ const name = typeof channel === "string" ? channel : channel.name;
1474
1507
  const ch = this._channels.get(name);
1475
1508
  if (ch) {
1476
1509
  ch.unsubscribe();
@@ -1500,8 +1533,17 @@ var RealtimeService = class _RealtimeService {
1500
1533
  ch._onMessage(msg);
1501
1534
  return;
1502
1535
  }
1536
+ if (channelFull.includes(":")) {
1537
+ const colonIdx = channelFull.indexOf(":");
1538
+ const relativeName = channelFull.slice(colonIdx + 1);
1539
+ const relCh = this._channels.get(relativeName);
1540
+ if (relCh) {
1541
+ relCh._onMessage(msg);
1542
+ return;
1543
+ }
1544
+ }
1503
1545
  for (const [, channel] of this._channels) {
1504
- if (channel.fullName === channelFull || channelFull.startsWith(channel.fullName + ":")) {
1546
+ if (channel.fullName === channelFull || channel.name === channelFull || channelFull.startsWith(channel.fullName + ":") || channelFull.endsWith(`:${channel.name}`)) {
1505
1547
  channel._onMessage(msg);
1506
1548
  return;
1507
1549
  }
package/dist/index.d.cts CHANGED
@@ -1,10 +1,17 @@
1
- import { ChannelConfig, PostgresChangesFilter, RealtimeEvent, BroadcastFilter, PresenceFilter, PresenceState, SubscribeCallback, BroadcastPayload, BroadcastSendStatus, ServerMessage, RealtimeListenType, AuraClientLike, AuraResponse } from '@aurabase/core';
1
+ import { ChannelConfig, PostgresChangesFilter, RealtimeEvent, BroadcastFilter, PresenceFilter, PresenceState, SubscribeCallback, BroadcastPayload, BroadcastSendStatus, ServerMessage, AuraClientLike, AuraResponse } from '@aurabase/core';
2
2
 
3
- type ListenerCallback = (payload: RealtimeEvent | Record<string, unknown>) => void;
4
3
  type ListenerEntry = {
5
- type: RealtimeListenType;
6
- filter: PostgresChangesFilter | BroadcastFilter | PresenceFilter;
7
- callback: ListenerCallback;
4
+ type: 'postgres_changes';
5
+ filter: PostgresChangesFilter;
6
+ callback: (payload: RealtimeEvent) => void;
7
+ } | {
8
+ type: 'broadcast';
9
+ filter: BroadcastFilter;
10
+ callback: (payload: RealtimeEvent) => void;
11
+ } | {
12
+ type: 'presence';
13
+ filter: PresenceFilter;
14
+ callback: (payload: PresenceState | RealtimeEvent | Record<string, unknown>) => void;
8
15
  };
9
16
  /**
10
17
  * Fonction d'émission fournie par `RealtimeService`.
@@ -379,6 +386,8 @@ declare class RealtimeService {
379
386
  private _tokenRefreshTimer;
380
387
  /** Dernier access_token propagé au serveur — évite les pushs redondants (propagation différentielle). */
381
388
  private _lastSentToken;
389
+ /** Token d'authentification explicite passé à setAuth(), prioritaire sur authStore. */
390
+ private _customAuthToken;
382
391
  /** Listeners d'erreurs de transport (handshake refusé, coupure, connexion morte). */
383
392
  private _errorListeners;
384
393
  /**
@@ -404,6 +413,8 @@ declare class RealtimeService {
404
413
  constructor(client: AuraClientLike);
405
414
  /** Current connection state. */
406
415
  get connectionState(): ConnectionState;
416
+ /** Whether the WebSocket is currently connected. */
417
+ get isConnected(): boolean;
407
418
  /** Listen for connection state changes. */
408
419
  onStateChange(callback: (state: ConnectionState) => void): () => void;
409
420
  private _setState;
@@ -438,13 +449,11 @@ declare class RealtimeService {
438
449
  */
439
450
  private _emitError;
440
451
  /**
441
- * Préfixe `"<project_id>:"` des noms de canaux sur le fil, `""` s'il est inconnu.
452
+ * Préfixe de projet déduit du token courant (`<project_id>:`), vide si aucun token.
442
453
  *
443
- * `aura-realtime` exige que tout canal commence par le `project_id` du TOKEN
444
- * (`handlers/websocket.rs`, `expected_prefix` ; idem pour le broadcast HTTP,
445
- * `handlers/broadcast.rs`). Le SDK ne porte plus d'identifiant de projet — le projet est
446
- * celui de l'URL — mais le token de session, lui, porte ce claim : on le lit là, dans le
447
- * même jeton que celui envoyé au serveur. Sans token (pas encore connecté), il n'y a rien
454
+ * Utilisé pour normaliser les noms de canaux : le serveur (`aura-realtime`) attend
455
+ * systématiquement `<project_id>:<canal>` sur le protocole WebSocket et REST, alors que
456
+ * l'utilisateur passe généralement un nom court (`room-1`). Sans session, aucun préfixe
448
457
  * à préfixer ; la connexion WS échouerait de toute façon, le serveur exigeant un JWT.
449
458
  */
450
459
  private _projectPrefix;
@@ -609,8 +618,8 @@ declare class RealtimeService {
609
618
  * ```
610
619
  */
611
620
  channel(name: string, options?: ChannelConfig): AuraChannel;
612
- /** Remove a channel. */
613
- removeChannel(name: string): void;
621
+ /** Remove a channel by name or by AuraChannel instance. */
622
+ removeChannel(channel: string | AuraChannel): void;
614
623
  /** List active channels. */
615
624
  getChannels(): AuraChannel[];
616
625
  /** Remove all channels and subscriptions. */
package/dist/index.d.ts CHANGED
@@ -1,10 +1,17 @@
1
- import { ChannelConfig, PostgresChangesFilter, RealtimeEvent, BroadcastFilter, PresenceFilter, PresenceState, SubscribeCallback, BroadcastPayload, BroadcastSendStatus, ServerMessage, RealtimeListenType, AuraClientLike, AuraResponse } from '@aurabase/core';
1
+ import { ChannelConfig, PostgresChangesFilter, RealtimeEvent, BroadcastFilter, PresenceFilter, PresenceState, SubscribeCallback, BroadcastPayload, BroadcastSendStatus, ServerMessage, AuraClientLike, AuraResponse } from '@aurabase/core';
2
2
 
3
- type ListenerCallback = (payload: RealtimeEvent | Record<string, unknown>) => void;
4
3
  type ListenerEntry = {
5
- type: RealtimeListenType;
6
- filter: PostgresChangesFilter | BroadcastFilter | PresenceFilter;
7
- callback: ListenerCallback;
4
+ type: 'postgres_changes';
5
+ filter: PostgresChangesFilter;
6
+ callback: (payload: RealtimeEvent) => void;
7
+ } | {
8
+ type: 'broadcast';
9
+ filter: BroadcastFilter;
10
+ callback: (payload: RealtimeEvent) => void;
11
+ } | {
12
+ type: 'presence';
13
+ filter: PresenceFilter;
14
+ callback: (payload: PresenceState | RealtimeEvent | Record<string, unknown>) => void;
8
15
  };
9
16
  /**
10
17
  * Fonction d'émission fournie par `RealtimeService`.
@@ -379,6 +386,8 @@ declare class RealtimeService {
379
386
  private _tokenRefreshTimer;
380
387
  /** Dernier access_token propagé au serveur — évite les pushs redondants (propagation différentielle). */
381
388
  private _lastSentToken;
389
+ /** Token d'authentification explicite passé à setAuth(), prioritaire sur authStore. */
390
+ private _customAuthToken;
382
391
  /** Listeners d'erreurs de transport (handshake refusé, coupure, connexion morte). */
383
392
  private _errorListeners;
384
393
  /**
@@ -404,6 +413,8 @@ declare class RealtimeService {
404
413
  constructor(client: AuraClientLike);
405
414
  /** Current connection state. */
406
415
  get connectionState(): ConnectionState;
416
+ /** Whether the WebSocket is currently connected. */
417
+ get isConnected(): boolean;
407
418
  /** Listen for connection state changes. */
408
419
  onStateChange(callback: (state: ConnectionState) => void): () => void;
409
420
  private _setState;
@@ -438,13 +449,11 @@ declare class RealtimeService {
438
449
  */
439
450
  private _emitError;
440
451
  /**
441
- * Préfixe `"<project_id>:"` des noms de canaux sur le fil, `""` s'il est inconnu.
452
+ * Préfixe de projet déduit du token courant (`<project_id>:`), vide si aucun token.
442
453
  *
443
- * `aura-realtime` exige que tout canal commence par le `project_id` du TOKEN
444
- * (`handlers/websocket.rs`, `expected_prefix` ; idem pour le broadcast HTTP,
445
- * `handlers/broadcast.rs`). Le SDK ne porte plus d'identifiant de projet — le projet est
446
- * celui de l'URL — mais le token de session, lui, porte ce claim : on le lit là, dans le
447
- * même jeton que celui envoyé au serveur. Sans token (pas encore connecté), il n'y a rien
454
+ * Utilisé pour normaliser les noms de canaux : le serveur (`aura-realtime`) attend
455
+ * systématiquement `<project_id>:<canal>` sur le protocole WebSocket et REST, alors que
456
+ * l'utilisateur passe généralement un nom court (`room-1`). Sans session, aucun préfixe
448
457
  * à préfixer ; la connexion WS échouerait de toute façon, le serveur exigeant un JWT.
449
458
  */
450
459
  private _projectPrefix;
@@ -609,8 +618,8 @@ declare class RealtimeService {
609
618
  * ```
610
619
  */
611
620
  channel(name: string, options?: ChannelConfig): AuraChannel;
612
- /** Remove a channel. */
613
- removeChannel(name: string): void;
621
+ /** Remove a channel by name or by AuraChannel instance. */
622
+ removeChannel(channel: string | AuraChannel): void;
614
623
  /** List active channels. */
615
624
  getChannels(): AuraChannel[];
616
625
  /** Remove all channels and subscriptions. */
package/dist/index.js CHANGED
@@ -270,10 +270,12 @@ var AuraChannel = class {
270
270
  constructor(name, projectPrefix, options) {
271
271
  this.name = name;
272
272
  this._projectPrefix = projectPrefix;
273
- this._isPrivate = options?.private ?? false;
274
- this._broadcastAck = options?.broadcast?.ack ?? false;
275
- this._broadcastSelf = options?.broadcast?.self ?? false;
276
- this._presenceKey = options?.config?.presence?.key ?? "";
273
+ const bcast = options?.broadcast ?? options?.config?.broadcast;
274
+ const pres = options?.presence ?? options?.config?.presence;
275
+ this._isPrivate = Boolean(options?.private ?? options?.config?.private ?? false);
276
+ this._broadcastAck = Boolean(bcast?.ack ?? false);
277
+ this._broadcastSelf = Boolean(bcast?.self ?? false);
278
+ this._presenceKey = typeof pres?.key === "string" ? pres.key : "";
277
279
  }
278
280
  /** Génère un ref_id unique pour la corrélation request/response. */
279
281
  _nextRef() {
@@ -306,6 +308,7 @@ var AuraChannel = class {
306
308
  subscribe(callback, timeoutMs) {
307
309
  this._subscribeCallback = callback ?? null;
308
310
  this._subscribed = true;
311
+ this._serverState = "pending";
309
312
  this._closedEmitted = false;
310
313
  if (typeof timeoutMs === "number" && timeoutMs > 0) {
311
314
  this._subscribeTimeoutMs = timeoutMs;
@@ -692,14 +695,32 @@ var AuraChannel = class {
692
695
  }
693
696
  }
694
697
  }
695
- listener.callback(event);
698
+ const cdcPayload = payload && typeof payload === "object" ? payload : {};
699
+ if (cdcPayload.new === void 0 && cdcPayload.record !== void 0) {
700
+ cdcPayload.new = cdcPayload.record;
701
+ }
702
+ if (cdcPayload.old === void 0 && cdcPayload.old_record !== void 0) {
703
+ cdcPayload.old = cdcPayload.old_record;
704
+ }
705
+ if (cdcPayload.eventType === void 0 && cdcPayload.type !== void 0) {
706
+ cdcPayload.eventType = cdcPayload.type;
707
+ }
708
+ const enrichedEvent = Object.assign(Object.create(event), {
709
+ new: cdcPayload.record,
710
+ old: cdcPayload.old_record,
711
+ eventType: cdcPayload.type,
712
+ schema: cdcPayload.schema,
713
+ table: cdcPayload.table
714
+ });
715
+ listener.callback(enrichedEvent);
696
716
  }
697
717
  }
698
718
  } else if (listener.type === "broadcast") {
699
719
  if (eventType === "broadcast") {
700
720
  const filter = listener.filter;
701
- const payload = event.payload;
702
- if (!filter.event || payload.event === filter.event) {
721
+ const broadcastPayload = event.payload && typeof event.payload === "object" ? event.payload : void 0;
722
+ const broadcastEvent = broadcastPayload?.event;
723
+ if (!filter.event || filter.event === "*" || broadcastEvent === filter.event) {
703
724
  listener.callback(event);
704
725
  }
705
726
  }
@@ -924,6 +945,8 @@ var RealtimeService = class _RealtimeService {
924
945
  _tokenRefreshTimer = null;
925
946
  /** Dernier access_token propagé au serveur — évite les pushs redondants (propagation différentielle). */
926
947
  _lastSentToken = null;
948
+ /** Token d'authentification explicite passé à setAuth(), prioritaire sur authStore. */
949
+ _customAuthToken = null;
927
950
  /** Listeners d'erreurs de transport (handshake refusé, coupure, connexion morte). */
928
951
  _errorListeners = /* @__PURE__ */ new Set();
929
952
  /**
@@ -953,6 +976,10 @@ var RealtimeService = class _RealtimeService {
953
976
  get connectionState() {
954
977
  return this._state;
955
978
  }
979
+ /** Whether the WebSocket is currently connected. */
980
+ get isConnected() {
981
+ return this._state === "connected";
982
+ }
956
983
  /** Listen for connection state changes. */
957
984
  onStateChange(callback) {
958
985
  this._stateListeners.add(callback);
@@ -1017,17 +1044,15 @@ var RealtimeService = class _RealtimeService {
1017
1044
  }
1018
1045
  // ─── Préfixe de projet des canaux ───────────────────────────────────────
1019
1046
  /**
1020
- * Préfixe `"<project_id>:"` des noms de canaux sur le fil, `""` s'il est inconnu.
1047
+ * Préfixe de projet déduit du token courant (`<project_id>:`), vide si aucun token.
1021
1048
  *
1022
- * `aura-realtime` exige que tout canal commence par le `project_id` du TOKEN
1023
- * (`handlers/websocket.rs`, `expected_prefix` ; idem pour le broadcast HTTP,
1024
- * `handlers/broadcast.rs`). Le SDK ne porte plus d'identifiant de projet — le projet est
1025
- * celui de l'URL — mais le token de session, lui, porte ce claim : on le lit là, dans le
1026
- * même jeton que celui envoyé au serveur. Sans token (pas encore connecté), il n'y a rien
1049
+ * Utilisé pour normaliser les noms de canaux : le serveur (`aura-realtime`) attend
1050
+ * systématiquement `<project_id>:<canal>` sur le protocole WebSocket et REST, alors que
1051
+ * l'utilisateur passe généralement un nom court (`room-1`). Sans session, aucun préfixe
1027
1052
  * à préfixer ; la connexion WS échouerait de toute façon, le serveur exigeant un JWT.
1028
1053
  */
1029
1054
  _projectPrefix() {
1030
- const token = this.client.authStore.token;
1055
+ const token = this._customAuthToken ?? this.client.authStore.token;
1031
1056
  if (!token) return "";
1032
1057
  const pid = getTokenProjectId(token);
1033
1058
  return pid ? `${pid}:` : "";
@@ -1045,7 +1070,7 @@ var RealtimeService = class _RealtimeService {
1045
1070
  }
1046
1071
  this._intentionalClose = false;
1047
1072
  this._setState("connecting");
1048
- const token = this.client.authStore.token;
1073
+ const token = this._customAuthToken ?? this.client.authStore.token;
1049
1074
  const params = new URLSearchParams();
1050
1075
  if (token) params.set("token", token);
1051
1076
  if (this.client.apiKey) params.set("apikey", this.client.apiKey);
@@ -1064,6 +1089,9 @@ var RealtimeService = class _RealtimeService {
1064
1089
  opened = true;
1065
1090
  this._reconnectAttempts = 0;
1066
1091
  this._setState("connected");
1092
+ if (this._customAuthToken && this._customAuthToken !== this._lastSentToken) {
1093
+ this.refreshToken(this._customAuthToken);
1094
+ }
1067
1095
  this._awaitingPong = false;
1068
1096
  this._lastServerMessageAt = Date.now();
1069
1097
  this._heartbeat.start(() => this._heartbeatTick(ws), HEARTBEAT_INTERVAL_MS);
@@ -1289,7 +1317,11 @@ var RealtimeService = class _RealtimeService {
1289
1317
  */
1290
1318
  setAuth(token) {
1291
1319
  const resolved = token ?? this.client.authStore.token;
1292
- if (resolved == null) return;
1320
+ this._customAuthToken = resolved ?? null;
1321
+ if (resolved == null) {
1322
+ this._lastSentToken = null;
1323
+ return;
1324
+ }
1293
1325
  this.refreshToken(resolved);
1294
1326
  }
1295
1327
  /**
@@ -1467,8 +1499,9 @@ var RealtimeService = class _RealtimeService {
1467
1499
  }
1468
1500
  return ch;
1469
1501
  }
1470
- /** Remove a channel. */
1471
- removeChannel(name) {
1502
+ /** Remove a channel by name or by AuraChannel instance. */
1503
+ removeChannel(channel) {
1504
+ const name = typeof channel === "string" ? channel : channel.name;
1472
1505
  const ch = this._channels.get(name);
1473
1506
  if (ch) {
1474
1507
  ch.unsubscribe();
@@ -1498,8 +1531,17 @@ var RealtimeService = class _RealtimeService {
1498
1531
  ch._onMessage(msg);
1499
1532
  return;
1500
1533
  }
1534
+ if (channelFull.includes(":")) {
1535
+ const colonIdx = channelFull.indexOf(":");
1536
+ const relativeName = channelFull.slice(colonIdx + 1);
1537
+ const relCh = this._channels.get(relativeName);
1538
+ if (relCh) {
1539
+ relCh._onMessage(msg);
1540
+ return;
1541
+ }
1542
+ }
1501
1543
  for (const [, channel] of this._channels) {
1502
- if (channel.fullName === channelFull || channelFull.startsWith(channel.fullName + ":")) {
1544
+ if (channel.fullName === channelFull || channel.name === channelFull || channelFull.startsWith(channel.fullName + ":") || channelFull.endsWith(`:${channel.name}`)) {
1503
1545
  channel._onMessage(msg);
1504
1546
  return;
1505
1547
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurabase/realtime",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Service temps réel du SDK Aurabase (postgres_changes, broadcast, presence)",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -34,7 +34,7 @@
34
34
  "url": "git+https://github.com/daylami555/aurabase.git",
35
35
  "directory": "aurabase-js/packages/realtime"
36
36
  },
37
- "homepage": "https://github.com/daylami555/aurabase/tree/main/aurabase-js/packages/realtime#readme",
37
+ "homepage": "https://aurabase.cloud",
38
38
  "bugs": {
39
39
  "url": "https://github.com/daylami555/aurabase/issues"
40
40
  },
@@ -44,19 +44,20 @@
44
44
  "sdk",
45
45
  "realtime"
46
46
  ],
47
- "dependencies": {
48
- "@aurabase/core": "0.5.0"
49
- },
50
- "devDependencies": {
51
- "@types/node": "20.14.15",
52
- "tsup": "^8.0.0",
53
- "typescript": "^5.5.0",
54
- "vitest": "^4.1.6"
55
- },
56
47
  "scripts": {
57
48
  "build": "tsup",
58
49
  "test": "vitest run --passWithNoTests",
59
50
  "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
51
+ "prepack": "pnpm build",
60
52
  "typecheck:tests": "tsc --noEmit -p tsconfig.test.json"
53
+ },
54
+ "dependencies": {
55
+ "@aurabase/core": "workspace:*"
56
+ },
57
+ "devDependencies": {
58
+ "@types/node": "catalog:",
59
+ "tsup": "catalog:",
60
+ "typescript": "catalog:",
61
+ "vitest": "catalog:"
61
62
  }
62
- }
63
+ }