@palbase/web 1.6.2 → 1.7.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.
@@ -1,7 +1,7 @@
1
- import { v as PalbeConfig, N as PalbeRuntime } from './analytics-facade-ATGUv2-f.cjs';
2
- export { Q as buildRuntime } from './analytics-facade-ATGUv2-f.cjs';
1
+ import { v as PalbeConfig, T as PalbeRuntime } from './analytics-facade-9GPSKnVG.cjs';
2
+ export { V as buildRuntime } from './analytics-facade-9GPSKnVG.cjs';
3
3
  import { B as BackendError } from './errors-fDoNdTrJ.cjs';
4
- export { P as PB, c as createBoundClient } from './pb-VzJvX7Gg.cjs';
4
+ export { P as PB, c as createBoundClient } from './pb-D4HyUbpb.cjs';
5
5
  import 'livekit-client';
6
6
  import './storage-BPaeSG8K.cjs';
7
7
  import './pooled-flags-Bwq4usn0.js';
@@ -1,7 +1,7 @@
1
- import { v as PalbeConfig, N as PalbeRuntime } from './analytics-facade-DhcTP_kw.js';
2
- export { Q as buildRuntime } from './analytics-facade-DhcTP_kw.js';
1
+ import { v as PalbeConfig, T as PalbeRuntime } from './analytics-facade-CQJ3b-zB.js';
2
+ export { V as buildRuntime } from './analytics-facade-CQJ3b-zB.js';
3
3
  import { B as BackendError } from './errors-fDoNdTrJ.js';
4
- export { P as PB, c as createBoundClient } from './pb-TAUNVyT6.js';
4
+ export { P as PB, c as createBoundClient } from './pb-BvfCJZux.js';
5
5
  import 'livekit-client';
6
6
  import './storage-BPaeSG8K.js';
7
7
  import './pooled-flags-Bwq4usn0.js';
package/dist/internal.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  createBoundClient,
7
7
  getRuntime,
8
8
  onConfigured
9
- } from "./chunk-XQZ53URR.js";
9
+ } from "./chunk-QRO632M7.js";
10
10
  export {
11
11
  __configure,
12
12
  __registerNamespaces,
@@ -2706,6 +2706,10 @@ var MessagingPaths = {
2706
2706
  groupMessages: (displayId) => `${GROUPS}/${seg(displayId)}/messages`,
2707
2707
  groupCommits: (displayId) => `${GROUPS}/${seg(displayId)}/commits`,
2708
2708
  groupRead: (displayId) => `${GROUPS}/${seg(displayId)}/read`,
2709
+ // Server-metadata cluster: the per-(user,group) notify scope (mute toggle, GET/PUT)
2710
+ // + the caller's own unread view (GET). {gid} is the grp_ display_id (M3 #7).
2711
+ groupNotify: (displayId) => `${GROUPS}/${seg(displayId)}/notify`,
2712
+ groupUnread: (displayId) => `${GROUPS}/${seg(displayId)}/unread`,
2709
2713
  deviceWelcomes: (deviceId) => `${DEVICES}/${seg(deviceId)}/welcomes`,
2710
2714
  deviceQueue: (deviceId) => `${DEVICES}/${seg(deviceId)}/queue`,
2711
2715
  deviceQueueAck: (deviceId) => `${DEVICES}/${seg(deviceId)}/queue/ack`,
@@ -4284,6 +4288,18 @@ var Chat = class {
4284
4288
  lastSeenAt: ts ? new Date(ts * 1e3) : null
4285
4289
  });
4286
4290
  this.emit();
4291
+ } else if (event === "delivered" || event === "read") {
4292
+ const seq = typeof payload.up_to_server_seq === "number" ? payload.up_to_server_seq : null;
4293
+ if (seq === null) return;
4294
+ let changed = false;
4295
+ this.messageList = this.messageList.map((m) => {
4296
+ if (m.direction !== "outgoing" || m.serverSeq > seq) return m;
4297
+ const cur = event === "delivered" ? m.deliveredUpTo ?? -1 : m.readUpTo ?? -1;
4298
+ if (seq <= cur) return m;
4299
+ changed = true;
4300
+ return event === "delivered" ? { ...m, deliveredUpTo: seq } : { ...m, readUpTo: seq };
4301
+ });
4302
+ if (changed) this.emit();
4287
4303
  }
4288
4304
  }
4289
4305
  kindOf(incoming) {
@@ -4532,6 +4548,31 @@ var Chat = class {
4532
4548
  this.readWatermark = Math.max(this.readWatermark, message.serverSeq);
4533
4549
  this.emit();
4534
4550
  }
4551
+ // ── Server-metadata cluster: notify scope (mute) + server unread ──
4552
+ /** Set this chat's notify scope (the mute toggle). `'none'` mutes the push wake;
4553
+ * `'all'` unmutes (the default). Materializes a draft first (the scope is a
4554
+ * per-(user,group) server row), PUTs `/notify`, and returns the server-echoed scope.
4555
+ * Mirrors iOS `Chat.setNotifyScope`. */
4556
+ async setNotifyScope(scope) {
4557
+ const group = await this.materializeIfNeeded();
4558
+ return this.backend.setNotifyScope(group, scope);
4559
+ }
4560
+ /** Refresh + return this chat's notify scope from the server (fail-OPEN to `'all'`).
4561
+ * Returns `'all'` for a draft chat (no server row yet). */
4562
+ async getNotifyScope() {
4563
+ if (!this._group) return "all";
4564
+ return this.backend.getNotifyScope(this._group);
4565
+ }
4566
+ /** Fetch the caller's authoritative SERVER unread count (opaque server metadata).
4567
+ * Returns the clamped count (`max(0, …)`); `0` for a draft chat. The local computed
4568
+ * `unreadCount` getter stays the instant, offline best-effort badge — this is the
4569
+ * canonical count on demand. Named distinctly so it does not shadow the observable
4570
+ * `unreadCount` snapshot getter. Mirrors iOS `Chat.refreshUnread`. */
4571
+ async unreadCountFromServer() {
4572
+ if (!this._group) return 0;
4573
+ const v = await this.backend.unread(this._group);
4574
+ return Math.max(0, v.unreadCount);
4575
+ }
4535
4576
  // ── Reactions ──
4536
4577
  /** Add an emoji reaction to a message. No-op if the message isn't reactable
4537
4578
  * (empty clientMsgId — a legacy/system row). The reaction folds locally with
@@ -4970,7 +5011,7 @@ var MessageDeliverySource = class {
4970
5011
  if (this.observed.has(group.displayId)) return;
4971
5012
  try {
4972
5013
  const channel = this.rt.realtime.channel(`messaging:conv:${group.rfcGroupId}`);
4973
- const subs = ["presence", "typing", "read"].map(
5014
+ const subs = ["presence", "typing", "read", "delivered"].map(
4974
5015
  (ev) => channel.on(ev, (payload) => {
4975
5016
  this.hub.emitConv(group.displayId, { event: ev, payload });
4976
5017
  })
@@ -5010,6 +5051,40 @@ var MessageDeliverySource = class {
5010
5051
  body: { read_seq: upToServerSeq, read_epoch: group.currentEpoch, is_private: false }
5011
5052
  });
5012
5053
  }
5054
+ // ── Server-metadata cluster: notify scope (mute) + unread (HTTP) ──
5055
+ /** PUT `/v1/messaging/groups/{gid}/notify` — set the caller's per-(user,group) notify
5056
+ * scope (`'all'`|`'none'`). The server stores the opaque enum verbatim and stays blind.
5057
+ * Returns the server-echoed scope (fail-OPEN to `'all'` on an unknown value). */
5058
+ async setNotifyScope(group, scope) {
5059
+ const res = await palbeRequest(
5060
+ this.rt,
5061
+ "PUT",
5062
+ MessagingPaths.groupNotify(group.displayId),
5063
+ { body: { notify_scope: scope } }
5064
+ );
5065
+ return res.notify_scope === "none" ? "none" : "all";
5066
+ }
5067
+ /** GET `/v1/messaging/groups/{gid}/notify` — the caller's notify scope. An absent
5068
+ * server row / unknown value reads as `'all'` (fail-OPEN — never silently mutes). */
5069
+ async getNotifyScope(group) {
5070
+ const res = await palbeRequest(
5071
+ this.rt,
5072
+ "GET",
5073
+ MessagingPaths.groupNotify(group.displayId)
5074
+ );
5075
+ return res.notify_scope === "none" ? "none" : "all";
5076
+ }
5077
+ /** GET `/v1/messaging/groups/{gid}/unread` — the caller's OWN unread view (opaque
5078
+ * server metadata). Maps the snake_case wire → the camelCase `UnreadView`. */
5079
+ async unread(group) {
5080
+ const res = await palbeRequest(this.rt, "GET", MessagingPaths.groupUnread(group.displayId));
5081
+ return {
5082
+ groupMaxSeq: res.group_max_seq,
5083
+ lastReadSeq: res.last_read_seq,
5084
+ deliveredSeq: res.delivered_seq,
5085
+ unreadCount: res.unread_count
5086
+ };
5087
+ }
5013
5088
  };
5014
5089
  function isOwnEchoOrConsumed(e) {
5015
5090
  const msg = e instanceof Error ? e.message : String(e);
@@ -7167,6 +7242,19 @@ var MessagingCoordinator = class {
7167
7242
  const r = await this.resolve();
7168
7243
  await r.source.markRead(group, upToServerSeq);
7169
7244
  }
7245
+ // ── Server-metadata cluster: notify scope (mute) + unread ──
7246
+ async setNotifyScope(group, scope) {
7247
+ const r = await this.resolve();
7248
+ return r.source.setNotifyScope(group, scope);
7249
+ }
7250
+ async getNotifyScope(group) {
7251
+ const r = await this.resolve();
7252
+ return r.source.getNotifyScope(group);
7253
+ }
7254
+ async unread(group) {
7255
+ const r = await this.resolve();
7256
+ return r.source.unread(group);
7257
+ }
7170
7258
  subscribeLive(group, chat) {
7171
7259
  let offMsg = null;
7172
7260
  let offConv = null;
@@ -8106,7 +8194,7 @@ function defaultSessionStorage(key) {
8106
8194
  }
8107
8195
 
8108
8196
  // src/version.ts
8109
- var VERSION = "1.6.2";
8197
+ var VERSION = "1.7.0";
8110
8198
 
8111
8199
  // src/runtime.ts
8112
8200
  function buildRuntime(config) {