@mitway/sdk 0.2.4 → 0.3.0

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
@@ -893,6 +893,11 @@ var Database = class {
893
893
  // src/modules/realtime.ts
894
894
  var import_socket = require("socket.io-client");
895
895
  var PRESENCE_HEARTBEAT_MS = 2e4;
896
+ function makeChannelError(code, message) {
897
+ const err = new Error(message);
898
+ err.code = code;
899
+ return err;
900
+ }
896
901
  var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
897
902
  var RealtimeChannel = class {
898
903
  constructor(topic, realtime, options = {}) {
@@ -963,12 +968,19 @@ var RealtimeChannel = class {
963
968
  this.statusCallback?.("SUBSCRIBED");
964
969
  } catch (err) {
965
970
  this.state = "errored";
966
- this.statusCallback?.("CHANNEL_ERROR", {
967
- code: "REJOIN_FAILED",
968
- message: err instanceof Error ? err.message : String(err)
969
- });
971
+ this.statusCallback?.(
972
+ "CHANNEL_ERROR",
973
+ makeChannelError("REJOIN_FAILED", err instanceof Error ? err.message : String(err))
974
+ );
970
975
  }
971
976
  }
977
+ // ── implementation signature (not in public type surface).
978
+ // The callback type is intentionally broad: each overload above pins a
979
+ // specific payload shape, but TypeScript overload resolution needs the
980
+ // implementation to accept the union of every narrow callback without
981
+ // the contravariance conflict (TS2394). `any` is the standard escape
982
+ // hatch for this exact pattern and is confined to this one line — the
983
+ // public surface users see is strictly typed via the overloads.
972
984
  on(type, filter, callback) {
973
985
  if (type === "postgres_changes") {
974
986
  this.bindings.push({
@@ -1070,18 +1082,18 @@ var RealtimeChannel = class {
1070
1082
  } catch (err) {
1071
1083
  this.state = "errored";
1072
1084
  const message = err instanceof Error ? err.message : String(err);
1073
- this.statusCallback?.("CHANNEL_ERROR", {
1074
- code: "SUBSCRIBE_FAILED",
1075
- message
1076
- });
1085
+ this.statusCallback?.(
1086
+ "CHANNEL_ERROR",
1087
+ makeChannelError("SUBSCRIBE_FAILED", message)
1088
+ );
1077
1089
  }
1078
1090
  },
1079
1091
  (err) => {
1080
1092
  this.state = "errored";
1081
- this.statusCallback?.("CHANNEL_ERROR", {
1082
- code: "CONNECT_FAILED",
1083
- message: err.message
1084
- });
1093
+ this.statusCallback?.(
1094
+ "CHANNEL_ERROR",
1095
+ makeChannelError("CONNECT_FAILED", err.message)
1096
+ );
1085
1097
  }
1086
1098
  );
1087
1099
  return this;
@@ -1134,6 +1146,12 @@ var RealtimeChannel = class {
1134
1146
  * events, write to your own application table and enable
1135
1147
  * `postgres_changes` on it; the SDK will surface the INSERT as a
1136
1148
  * `postgres_changes` event without a separate channel.send call.
1149
+ *
1150
+ * The returned promise always resolves with the server ack, so callers
1151
+ * can `await channel.send(...)` to confirm delivery + get the server-
1152
+ * assigned `message_id`. There's no performance cost — Socket.IO piggy-
1153
+ * backs the ack on the same frame. Callers that don't need it just
1154
+ * don't await.
1137
1155
  */
1138
1156
  async send(args) {
1139
1157
  if (args.type !== "broadcast") {
@@ -1160,9 +1178,7 @@ var RealtimeChannel = class {
1160
1178
  if (!socket) {
1161
1179
  throw new MitwayBaasError("Socket not connected", 503, "NOT_CONNECTED");
1162
1180
  }
1163
- const broadcastCfg = this.options.config?.broadcast;
1164
- const wantAck = broadcastCfg?.ack === true;
1165
- const self = broadcastCfg?.self;
1181
+ const self = this.options.config?.broadcast?.self;
1166
1182
  const wirePayload = {
1167
1183
  channel: this.topic,
1168
1184
  event: args.event,
@@ -1171,10 +1187,6 @@ var RealtimeChannel = class {
1171
1187
  if (self === false) {
1172
1188
  wirePayload.self = false;
1173
1189
  }
1174
- if (!wantAck) {
1175
- socket.emit("realtime:publish", wirePayload);
1176
- return;
1177
- }
1178
1190
  return await new Promise((resolve) => {
1179
1191
  socket.emit(
1180
1192
  "realtime:publish",
@@ -1215,7 +1227,7 @@ var RealtimeChannel = class {
1215
1227
  if (!b.subscriptionId || !pcEvent.ids.includes(b.subscriptionId)) {
1216
1228
  continue;
1217
1229
  }
1218
- const matchesEvent = b.filter.event === "*" || b.filter.event === pcEvent.data.type;
1230
+ const matchesEvent = b.filter.event === "*" || b.filter.event === pcEvent.data.eventType;
1219
1231
  if (!matchesEvent) {
1220
1232
  continue;
1221
1233
  }
@@ -1274,7 +1286,13 @@ var RealtimeChannel = class {
1274
1286
  continue;
1275
1287
  }
1276
1288
  try {
1277
- b.callback(payload);
1289
+ if (payload.event === "sync") {
1290
+ b.callback();
1291
+ } else if (payload.event === "join") {
1292
+ b.callback(payload);
1293
+ } else {
1294
+ b.callback(payload);
1295
+ }
1278
1296
  } catch {
1279
1297
  }
1280
1298
  }
@@ -1293,7 +1311,7 @@ var RealtimeChannel = class {
1293
1311
  "realtime:subscribe",
1294
1312
  { channel: this.topic, private: this.isPrivate },
1295
1313
  (ack) => {
1296
- if (ack.ok) {
1314
+ if (ack.status === "ok") {
1297
1315
  resolve();
1298
1316
  } else {
1299
1317
  reject(new Error(ack.error?.message ?? "subscribe failed"));
@@ -1317,7 +1335,7 @@ var RealtimeChannel = class {
1317
1335
  filter: b.filter.filter
1318
1336
  },
1319
1337
  (ack) => {
1320
- if (ack.ok && ack.subscription_id) {
1338
+ if (ack.status === "ok" && ack.subscription_id) {
1321
1339
  b.subscriptionId = ack.subscription_id;
1322
1340
  resolve();
1323
1341
  } else {
@@ -1363,13 +1381,14 @@ var Realtime = class {
1363
1381
  * The optional `opts` argument lets the caller configure the channel:
1364
1382
  * * `config.private` — enable subscribe-side authorization against
1365
1383
  * `realtime.authorize_subscribe(...)` on the tenant DB.
1366
- * * `config.broadcast.ack` — `channel.send()` resolves with the
1367
- * server's ack (message_id) instead of fire-and-forget.
1368
1384
  * * `config.broadcast.self` — `false` excludes the sender from the
1369
1385
  * fan-out (defaults to `true`).
1370
1386
  * * `config.presence.key` — stable presence key to group multiple
1371
1387
  * tabs of the same user under one entry.
1372
1388
  *
1389
+ * `channel.send()` always resolves with the server ack (see its own
1390
+ * docstring); there is no separate opt-in needed.
1391
+ *
1373
1392
  * Options are locked in when the channel is first created; subsequent
1374
1393
  * `.channel('same')` calls with different opts are ignored. Pass a
1375
1394
  * different topic to get a different-configured channel.