@palbase/web 1.6.2 → 1.8.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/{analytics-facade-DhcTP_kw.d.ts → analytics-facade-CgURkjpP.d.ts} +236 -2
- package/dist/{analytics-facade-ATGUv2-f.d.cts → analytics-facade-DfJ420F5.d.cts} +236 -2
- package/dist/{chunk-XQZ53URR.js → chunk-AWVNDAMG.js} +690 -18
- package/dist/chunk-AWVNDAMG.js.map +1 -0
- package/dist/index.cjs +158 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/internal.cjs +689 -17
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.js +1 -1
- package/dist/next/client.cjs +679 -14
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.js +1 -1
- package/dist/next/index.cjs +685 -14
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +2 -2
- package/dist/next/index.d.ts +2 -2
- package/dist/next/index.js +1 -1
- package/dist/{pb-VzJvX7Gg.d.cts → pb-BwQwp411.d.cts} +9 -1
- package/dist/{pb-TAUNVyT6.d.ts → pb-C1v9ErPy.d.ts} +9 -1
- package/dist/react/index.cjs +69 -13
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-XQZ53URR.js.map +0 -1
|
@@ -622,6 +622,16 @@ interface PalbeConfig {
|
|
|
622
622
|
apiKey: string;
|
|
623
623
|
/** Informational — url+apiKey are already branch-specific (endpointRef embeds the branch slug); gen bakes all three consistently. */
|
|
624
624
|
branch?: string;
|
|
625
|
+
/**
|
|
626
|
+
* F2 app-registration: the registered app `identifier` from
|
|
627
|
+
* `palbase-config.json` — for web this is the declared ORIGIN (e.g.
|
|
628
|
+
* `https://app.example.com`). When non-empty, `configure` REFUSES to build the
|
|
629
|
+
* runtime if `window.location.origin` does not match (SDK-REFUSES), and the
|
|
630
|
+
* value rides on `X-Palbase-Bundle` on EVERY request so the Kong gate can match
|
|
631
|
+
* it (the IDENTICAL header + value the iOS SDK sends). Empty/absent → legacy /
|
|
632
|
+
* tooling: no guard, no header.
|
|
633
|
+
*/
|
|
634
|
+
identifier?: string;
|
|
625
635
|
oauth?: PalbeOAuthConfig;
|
|
626
636
|
/** Refresh-token persistence. Default: endpoint-scoped localStorage in browsers, memory elsewhere. */
|
|
627
637
|
storage?: SessionStorageAdapter;
|
|
@@ -825,6 +835,49 @@ interface ChatMessage {
|
|
|
825
835
|
* Mirrors iOS `ChatMessage.effectiveExpiry` (which it derives from).
|
|
826
836
|
*/
|
|
827
837
|
readonly expiresAt: Date | null;
|
|
838
|
+
/**
|
|
839
|
+
* Server-metadata cluster — the double-tick DELIVERED watermark on THIS user's OWN
|
|
840
|
+
* (`direction === 'outgoing'`) messages, FOLDED TO USER-LEVEL. The wire carries the
|
|
841
|
+
* acking device_id; the SDK folds across a peer's devices and across peers to ONE
|
|
842
|
+
* user-level server_seq (MONOTONIC max — a stale lower incoming tick NEVER lowers it).
|
|
843
|
+
* A per-message tick is "is `message.serverSeq <= deliveredUpTo`?". Absent (`undefined`)
|
|
844
|
+
* until a `delivered` conv event covers this message; never set on an incoming message.
|
|
845
|
+
* Mirrors iOS `Chat.deliveredUpTo` (a chat-level scalar there; per-message here).
|
|
846
|
+
*/
|
|
847
|
+
readonly deliveredUpTo?: number;
|
|
848
|
+
/**
|
|
849
|
+
* Server-metadata cluster — the double-tick READ watermark on THIS user's OWN
|
|
850
|
+
* (`direction === 'outgoing'`) messages, FOLDED TO USER-LEVEL + MONOTONIC max (same
|
|
851
|
+
* fold as `deliveredUpTo`). Set by a `read` conv event. Read STAYS gated by the peer's
|
|
852
|
+
* `share_receipts` server-side (the broadcast simply never arrives when muted); the
|
|
853
|
+
* client fold is identical to delivered. Mirrors iOS `Chat.readUpTo`.
|
|
854
|
+
*/
|
|
855
|
+
readonly readUpTo?: number;
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* The per-(user, group) notify scope (the server-metadata MUTE toggle). `'all'`
|
|
859
|
+
* (default, absent row) fires the push wake; `'none'` (muted) suppresses it. The raw
|
|
860
|
+
* wire value is the snake-free `"all"`/`"none"` string. An unknown/garbage server value
|
|
861
|
+
* maps to `'all'` at the surface — fail-OPEN, never silently mutes (mirrors iOS
|
|
862
|
+
* `NotifyScope`). The server stores this opaque enum and stays MLS-blind (no content).
|
|
863
|
+
*/
|
|
864
|
+
type NotifyScope = 'all' | 'none';
|
|
865
|
+
/**
|
|
866
|
+
* The caller's OWN unread view (the `GET /v1/messaging/groups/{gid}/unread` response).
|
|
867
|
+
* Every field is an OPAQUE server-metadata integer (no message content): the group's max
|
|
868
|
+
* server_seq, this caller's read + delivered cursors, and the server-derived unread
|
|
869
|
+
* count. The camelCase mirror of the snake_case wire (`group_max_seq` → `groupMaxSeq`,
|
|
870
|
+
* etc). Mirrors iOS `UnreadView`.
|
|
871
|
+
*/
|
|
872
|
+
interface UnreadView {
|
|
873
|
+
/** The highest server_seq the group has reached (the newest message's seq). */
|
|
874
|
+
readonly groupMaxSeq: number;
|
|
875
|
+
/** The furthest server_seq THIS caller has marked read. */
|
|
876
|
+
readonly lastReadSeq: number;
|
|
877
|
+
/** The furthest server_seq THIS caller's devices have acked delivered. */
|
|
878
|
+
readonly deliveredSeq: number;
|
|
879
|
+
/** The server-derived unread count for this caller (clamped `>= 0` at the surface). */
|
|
880
|
+
readonly unreadCount: number;
|
|
828
881
|
}
|
|
829
882
|
/** The receipt from a send — the server's monotonic sequence + accepted epoch. */
|
|
830
883
|
interface SentReceipt {
|
|
@@ -1001,7 +1054,12 @@ interface ChatBackend {
|
|
|
1001
1054
|
registerActive(group: MessagingGroup): void;
|
|
1002
1055
|
setTyping(group: MessagingGroup, isTyping: boolean): void;
|
|
1003
1056
|
markRead(group: MessagingGroup, upToServerSeq: number): Promise<void>;
|
|
1004
|
-
/**
|
|
1057
|
+
/** Server-metadata cluster: set/get the per-(user,group) notify scope (mute) and
|
|
1058
|
+
* fetch the caller's own unread view. The server stays MLS-blind (opaque metadata). */
|
|
1059
|
+
setNotifyScope(group: MessagingGroup, scope: NotifyScope): Promise<NotifyScope>;
|
|
1060
|
+
getNotifyScope(group: MessagingGroup): Promise<NotifyScope>;
|
|
1061
|
+
unread(group: MessagingGroup): Promise<UnreadView>;
|
|
1062
|
+
/** Subscribe live message + conv (presence/typing/read/delivered) for an active group. */
|
|
1005
1063
|
subscribeLive(group: MessagingGroup, chat: Chat): Unsubscribe$1;
|
|
1006
1064
|
/** Resolve a sender device id → its owning user id (for senderUserId). */
|
|
1007
1065
|
userIdForDevice(group: MessagingGroup, deviceId: string): Promise<string | null>;
|
|
@@ -1306,6 +1364,20 @@ declare class Chat {
|
|
|
1306
1364
|
leave(): Promise<void>;
|
|
1307
1365
|
setTyping(isTyping: boolean): void;
|
|
1308
1366
|
markRead(message: ChatMessage): Promise<void>;
|
|
1367
|
+
/** Set this chat's notify scope (the mute toggle). `'none'` mutes the push wake;
|
|
1368
|
+
* `'all'` unmutes (the default). Materializes a draft first (the scope is a
|
|
1369
|
+
* per-(user,group) server row), PUTs `/notify`, and returns the server-echoed scope.
|
|
1370
|
+
* Mirrors iOS `Chat.setNotifyScope`. */
|
|
1371
|
+
setNotifyScope(scope: NotifyScope): Promise<NotifyScope>;
|
|
1372
|
+
/** Refresh + return this chat's notify scope from the server (fail-OPEN to `'all'`).
|
|
1373
|
+
* Returns `'all'` for a draft chat (no server row yet). */
|
|
1374
|
+
getNotifyScope(): Promise<NotifyScope>;
|
|
1375
|
+
/** Fetch the caller's authoritative SERVER unread count (opaque server metadata).
|
|
1376
|
+
* Returns the clamped count (`max(0, …)`); `0` for a draft chat. The local computed
|
|
1377
|
+
* `unreadCount` getter stays the instant, offline best-effort badge — this is the
|
|
1378
|
+
* canonical count on demand. Named distinctly so it does not shadow the observable
|
|
1379
|
+
* `unreadCount` snapshot getter. Mirrors iOS `Chat.refreshUnread`. */
|
|
1380
|
+
unreadCountFromServer(): Promise<number>;
|
|
1309
1381
|
/** Add an emoji reaction to a message. No-op if the message isn't reactable
|
|
1310
1382
|
* (empty clientMsgId — a legacy/system row). The reaction folds locally with
|
|
1311
1383
|
* the server receipt's `(epoch, serverSeq)` so the target's tally updates
|
|
@@ -1374,6 +1446,153 @@ declare class PalbeMessaging {
|
|
|
1374
1446
|
onChatsChange(cb: () => void): Unsubscribe$1;
|
|
1375
1447
|
}
|
|
1376
1448
|
|
|
1449
|
+
/** The Faz-1 trace kinds plus the Faz-1.5 web-vital family. */
|
|
1450
|
+
type PerfTraceType = 'network' | 'app_start' | 'custom' | 'web_vital';
|
|
1451
|
+
/**
|
|
1452
|
+
* One perf measurement, shaped EXACTLY as the ingest wire expects. Keys are
|
|
1453
|
+
* snake_case to match the Go decode tags — do not rename to camelCase.
|
|
1454
|
+
*/
|
|
1455
|
+
interface PerfItem {
|
|
1456
|
+
/** Client-generated UUIDv7 — server dedup key. */
|
|
1457
|
+
row_id: string;
|
|
1458
|
+
trace_type: PerfTraceType;
|
|
1459
|
+
name: string;
|
|
1460
|
+
/** Duration in milliseconds. */
|
|
1461
|
+
value: number;
|
|
1462
|
+
counters?: Record<string, number>;
|
|
1463
|
+
attrs?: Record<string, string>;
|
|
1464
|
+
request_id?: string;
|
|
1465
|
+
/** Unix milliseconds. */
|
|
1466
|
+
timestamp: number;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* Bounded FIFO perf-item queue. `enqueue` appends and evicts the oldest on
|
|
1471
|
+
* overflow; `drainAll` returns everything (oldest-first) and clears the store;
|
|
1472
|
+
* `count` is the current depth; `dropped` is the cumulative eviction counter.
|
|
1473
|
+
*
|
|
1474
|
+
* When `localStorage` is present the queue is read-through / write-through to a
|
|
1475
|
+
* fixed key, so a fresh instance after a reload sees the persisted items. With
|
|
1476
|
+
* no `localStorage` it is purely in-memory.
|
|
1477
|
+
*/
|
|
1478
|
+
declare class PerfOfflineQueue {
|
|
1479
|
+
private items;
|
|
1480
|
+
private _dropped;
|
|
1481
|
+
private readonly maxItems;
|
|
1482
|
+
constructor(maxItems?: number);
|
|
1483
|
+
/** Append items; FIFO-evict the oldest when over `maxItems`. */
|
|
1484
|
+
enqueue(items: PerfItem[]): void;
|
|
1485
|
+
/** Return all queued items (oldest-first) and clear the queue + store. */
|
|
1486
|
+
drainAll(): PerfItem[];
|
|
1487
|
+
/** Current queue depth. */
|
|
1488
|
+
get count(): number;
|
|
1489
|
+
/** Cumulative count of FIFO-evicted items (a `dropped` metric, not silent). */
|
|
1490
|
+
get dropped(): number;
|
|
1491
|
+
/** Drop the oldest items until at most `maxItems` remain, counting each. */
|
|
1492
|
+
private trim;
|
|
1493
|
+
private persist;
|
|
1494
|
+
private clearStore;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* The mutable PalPerf state shared between the facade and the network hook.
|
|
1499
|
+
* `testDevice` is signalled to the server via the `X-Palbase-Test-Device: 1`
|
|
1500
|
+
* request header (server-authoritative tagging — the SDK only flips the bit).
|
|
1501
|
+
*/
|
|
1502
|
+
declare class PerfState {
|
|
1503
|
+
/** Pending, un-flushed perf items (FIFO). */
|
|
1504
|
+
readonly buffer: PerfItem[];
|
|
1505
|
+
/** When true, every flush carries `X-Palbase-Test-Device: 1`. */
|
|
1506
|
+
testDevice: boolean;
|
|
1507
|
+
enqueue(item: PerfItem): void;
|
|
1508
|
+
/** Detach up to `MAX_PERF_BATCH` items for one POST (FIFO order preserved). */
|
|
1509
|
+
take(limit?: number): PerfItem[];
|
|
1510
|
+
get size(): number;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* A running custom trace. `putAttribute`/`incrementMetric` accumulate metadata;
|
|
1515
|
+
* `stop()` records ONE `custom` PerfItem whose `value` is the elapsed
|
|
1516
|
+
* milliseconds since `startTrace`. Idempotent: a second `stop()` is a no-op.
|
|
1517
|
+
*/
|
|
1518
|
+
declare class PerfTrace {
|
|
1519
|
+
private readonly name;
|
|
1520
|
+
private readonly onStop;
|
|
1521
|
+
private readonly attrs;
|
|
1522
|
+
private readonly counters;
|
|
1523
|
+
private readonly startedAt;
|
|
1524
|
+
private stopped;
|
|
1525
|
+
constructor(name: string, onStop: (item: PerfItem) => void);
|
|
1526
|
+
putAttribute(key: string, value: string): void;
|
|
1527
|
+
incrementMetric(name: string, by?: number): void;
|
|
1528
|
+
stop(): void;
|
|
1529
|
+
}
|
|
1530
|
+
declare class PalbePerf {
|
|
1531
|
+
private readonly rt;
|
|
1532
|
+
private readonly state;
|
|
1533
|
+
/** Durable offline buffer for failed flushes (persist-on-fail). Browser →
|
|
1534
|
+
* localStorage-backed; server → in-memory. */
|
|
1535
|
+
private readonly queue;
|
|
1536
|
+
private flushTimer;
|
|
1537
|
+
/** Browser → buffer + size/timer flush. Server (no document) → immediate
|
|
1538
|
+
* per-item flush, zero timers (nothing leaks into RSC/route handlers). */
|
|
1539
|
+
private readonly browser;
|
|
1540
|
+
/** Bound `online` handler so it can be removed on `dispose()` (no leak). */
|
|
1541
|
+
private readonly onOnline;
|
|
1542
|
+
/** Server-controlled client-side sample rate (0..100). 100 until the config
|
|
1543
|
+
* client fetches `/v1/analytics/perf/config` — the SDK obeys this ceiling and
|
|
1544
|
+
* never raises its own rate (invariant 3). `record` drops an item whose
|
|
1545
|
+
* deterministic `row_id` bucket is >= this pct, mirroring the server's
|
|
1546
|
+
* `SampleDecision` so client + server keep the SAME rows. */
|
|
1547
|
+
private samplePct;
|
|
1548
|
+
constructor(rt: PalbeRuntime, state?: PerfState,
|
|
1549
|
+
/** Durable offline buffer for failed flushes (persist-on-fail). Browser →
|
|
1550
|
+
* localStorage-backed; server → in-memory. */
|
|
1551
|
+
queue?: PerfOfflineQueue);
|
|
1552
|
+
/** Remove the `online` listener. Called when the runtime is replaced so the
|
|
1553
|
+
* handler does not outlive this facade. No-op outside the browser. */
|
|
1554
|
+
dispose(): void;
|
|
1555
|
+
/** Mark (or unmark) this client's traffic as test — the server tags the rows
|
|
1556
|
+
* when the `X-Palbase-Test-Device: 1` header rides along on flush. */
|
|
1557
|
+
setTestDevice(on: boolean): void;
|
|
1558
|
+
/** Apply the server-resolved client-side sample rate (0..100), clamped. Called
|
|
1559
|
+
* by `PerfConfigClient` after fetching `/v1/analytics/perf/config`. The SDK
|
|
1560
|
+
* OBEYS this value — it is a ceiling, never raised locally. */
|
|
1561
|
+
setSamplePct(pct: number): void;
|
|
1562
|
+
/** Pending (un-flushed) buffer depth. Test-only visibility into the buffer so
|
|
1563
|
+
* the remote-sampling tests can assert how many items were sampled in. */
|
|
1564
|
+
get bufferSizeForTest(): number;
|
|
1565
|
+
/** Opt-in: wrap the global `fetch` so every app-level request is recorded as a
|
|
1566
|
+
* redacted `network` perf item (the `/v1/analytics/*` ingest paths are
|
|
1567
|
+
* self-excluded). OFF by default — swizzling a global is a page-wide side
|
|
1568
|
+
* effect. Returns an `uninstall` that restores the original `fetch`. */
|
|
1569
|
+
enableFetchCapture(): () => void;
|
|
1570
|
+
/** Start a custom trace; the returned handle records a `custom` item on
|
|
1571
|
+
* `.stop()`. */
|
|
1572
|
+
startTrace(name: string): PerfTrace;
|
|
1573
|
+
/** Buffer one perf item. In the browser, flush on size/timer; on the server
|
|
1574
|
+
* flush immediately (no timers). Never throws.
|
|
1575
|
+
*
|
|
1576
|
+
* Client-side remote sampling: an item whose deterministic `row_id` bucket is
|
|
1577
|
+
* NOT below the server-controlled `samplePct` is dropped before buffering —
|
|
1578
|
+
* the SAME FNV-1a-mod-100 decision the server applies at ingest, so the two
|
|
1579
|
+
* keep identical rows and the SDK saves the upload (defense-in-depth: the
|
|
1580
|
+
* server re-samples authoritatively). */
|
|
1581
|
+
record(item: PerfItem): void;
|
|
1582
|
+
/** Buffer a network trace — called by `request.ts` around `rt.http.request`
|
|
1583
|
+
* (the analytics ingest path is excluded by the caller to avoid recursion). */
|
|
1584
|
+
recordNetwork(method: string, url: string, status: number, durationMs: number, requestId?: string): void;
|
|
1585
|
+
/** Drain the offline queue (oldest-first) and the live buffer to
|
|
1586
|
+
* `/v1/analytics/perf` (≤100 items per request, sequential). Resolves when
|
|
1587
|
+
* delivery finished; NEVER rejects. A failed slice is NOT dropped — it goes
|
|
1588
|
+
* to the offline queue (persist-on-fail) so the next flush (size/timer or the
|
|
1589
|
+
* `online` reconnect event) retries it. Items keep their original `row_id`,
|
|
1590
|
+
* so a redelivery dedups server-side (ReplacingMergeTree). */
|
|
1591
|
+
flush(): Promise<void>;
|
|
1592
|
+
private startTimer;
|
|
1593
|
+
private cancelTimer;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1377
1596
|
/**
|
|
1378
1597
|
* The connection state of the shared realtime WebSocket (iOS enum parity), plus
|
|
1379
1598
|
* `'error'` — surfaced when a channel could not be recovered after a
|
|
@@ -1471,6 +1690,14 @@ declare class PalbeRealtime {
|
|
|
1471
1690
|
|
|
1472
1691
|
interface PalbeRuntime {
|
|
1473
1692
|
config: PalbeConfig;
|
|
1693
|
+
/**
|
|
1694
|
+
* F2 app-registration: the registered app `identifier` (web ORIGIN) stashed at
|
|
1695
|
+
* configure. Rides on `X-Palbase-Bundle` on EVERY request (request.ts) so the
|
|
1696
|
+
* Kong gate can match it. Empty string when the binding is unconfigured/tooling
|
|
1697
|
+
* (no header is sent). Origin-match is enforced in `buildRuntime` BEFORE this
|
|
1698
|
+
* runtime is returned — a mismatch throws there and no runtime is built.
|
|
1699
|
+
*/
|
|
1700
|
+
appIdentifier: string;
|
|
1474
1701
|
http: HttpClient$1;
|
|
1475
1702
|
tokenManager: TokenManager$1;
|
|
1476
1703
|
authClient: AuthClient;
|
|
@@ -1480,6 +1707,13 @@ interface PalbeRuntime {
|
|
|
1480
1707
|
analytics: PalbeAnalytics;
|
|
1481
1708
|
calls: PalbeCalls;
|
|
1482
1709
|
messaging: PalbeMessaging;
|
|
1710
|
+
/**
|
|
1711
|
+
* PalPerf surface. EAGER (like analytics identity): `request.ts` records a
|
|
1712
|
+
* `network` trace around EVERY SDK fetch, so the facade must exist from the
|
|
1713
|
+
* first request — never lazy. The buffer/timer it owns is inert until the
|
|
1714
|
+
* first item is recorded.
|
|
1715
|
+
*/
|
|
1716
|
+
perf: PalbePerf;
|
|
1483
1717
|
storage: SessionStorageAdapter;
|
|
1484
1718
|
/**
|
|
1485
1719
|
* Destroy the realtime facade if it was already constructed (no-op otherwise).
|
|
@@ -1731,4 +1965,4 @@ declare class PalbeAnalytics {
|
|
|
1731
1965
|
private post;
|
|
1732
1966
|
}
|
|
1733
1967
|
|
|
1734
|
-
export { type AnalyticsProperties as A, type PresenceState as B, Call as C, type RealtimeConnectionState as D, type RealtimeHandler as E, type FlagsView as F, type RealtimePayload as G, type RealtimeStatus as H, type RealtimeStatusSnapshot as I, type RealtimeSubscription as J, type ResolvedMention as K, type ResolvedReply as L, type MagicLinkResult as M, type
|
|
1968
|
+
export { type AnalyticsProperties as A, type PresenceState as B, Call as C, type RealtimeConnectionState as D, type RealtimeHandler as E, type FlagsView as F, type RealtimePayload as G, type RealtimeStatus as H, type RealtimeStatusSnapshot as I, type RealtimeSubscription as J, type ResolvedMention as K, type ResolvedReply as L, type MagicLinkResult as M, type NotifyScope as N, type OAuthExchangeResult as O, PalbeAnalytics as P, type Unsubscribe as Q, RealtimeChannel as R, type SentReceipt as S, type PalbeRuntime as T, type UnreadView as U, buildRuntime as V, PalbePerf as W, type AuthChangeEvent as a, type AuthState as b, type AuthSuccess as c, type AuthUser as d, type CallChangeCallback as e, type CallParticipant as f, type CallState as g, Chat as h, type ChatBackend as i, type ChatDraft as j, type ChatKind as k, type ChatMember as l, type ChatMessage as m, type ChatMessageKind as n, type ChatRole as o, type ChatState as p, type CommsPrefs as q, type MentionRange as r, type MessageDirection as s, PalbeAuth as t, PalbeCalls as u, type PalbeConfig as v, PalbeFlags as w, PalbeMessaging as x, type PalbeOAuthConfig as y, PalbeRealtime as z };
|
|
@@ -622,6 +622,16 @@ interface PalbeConfig {
|
|
|
622
622
|
apiKey: string;
|
|
623
623
|
/** Informational — url+apiKey are already branch-specific (endpointRef embeds the branch slug); gen bakes all three consistently. */
|
|
624
624
|
branch?: string;
|
|
625
|
+
/**
|
|
626
|
+
* F2 app-registration: the registered app `identifier` from
|
|
627
|
+
* `palbase-config.json` — for web this is the declared ORIGIN (e.g.
|
|
628
|
+
* `https://app.example.com`). When non-empty, `configure` REFUSES to build the
|
|
629
|
+
* runtime if `window.location.origin` does not match (SDK-REFUSES), and the
|
|
630
|
+
* value rides on `X-Palbase-Bundle` on EVERY request so the Kong gate can match
|
|
631
|
+
* it (the IDENTICAL header + value the iOS SDK sends). Empty/absent → legacy /
|
|
632
|
+
* tooling: no guard, no header.
|
|
633
|
+
*/
|
|
634
|
+
identifier?: string;
|
|
625
635
|
oauth?: PalbeOAuthConfig;
|
|
626
636
|
/** Refresh-token persistence. Default: endpoint-scoped localStorage in browsers, memory elsewhere. */
|
|
627
637
|
storage?: SessionStorageAdapter;
|
|
@@ -825,6 +835,49 @@ interface ChatMessage {
|
|
|
825
835
|
* Mirrors iOS `ChatMessage.effectiveExpiry` (which it derives from).
|
|
826
836
|
*/
|
|
827
837
|
readonly expiresAt: Date | null;
|
|
838
|
+
/**
|
|
839
|
+
* Server-metadata cluster — the double-tick DELIVERED watermark on THIS user's OWN
|
|
840
|
+
* (`direction === 'outgoing'`) messages, FOLDED TO USER-LEVEL. The wire carries the
|
|
841
|
+
* acking device_id; the SDK folds across a peer's devices and across peers to ONE
|
|
842
|
+
* user-level server_seq (MONOTONIC max — a stale lower incoming tick NEVER lowers it).
|
|
843
|
+
* A per-message tick is "is `message.serverSeq <= deliveredUpTo`?". Absent (`undefined`)
|
|
844
|
+
* until a `delivered` conv event covers this message; never set on an incoming message.
|
|
845
|
+
* Mirrors iOS `Chat.deliveredUpTo` (a chat-level scalar there; per-message here).
|
|
846
|
+
*/
|
|
847
|
+
readonly deliveredUpTo?: number;
|
|
848
|
+
/**
|
|
849
|
+
* Server-metadata cluster — the double-tick READ watermark on THIS user's OWN
|
|
850
|
+
* (`direction === 'outgoing'`) messages, FOLDED TO USER-LEVEL + MONOTONIC max (same
|
|
851
|
+
* fold as `deliveredUpTo`). Set by a `read` conv event. Read STAYS gated by the peer's
|
|
852
|
+
* `share_receipts` server-side (the broadcast simply never arrives when muted); the
|
|
853
|
+
* client fold is identical to delivered. Mirrors iOS `Chat.readUpTo`.
|
|
854
|
+
*/
|
|
855
|
+
readonly readUpTo?: number;
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* The per-(user, group) notify scope (the server-metadata MUTE toggle). `'all'`
|
|
859
|
+
* (default, absent row) fires the push wake; `'none'` (muted) suppresses it. The raw
|
|
860
|
+
* wire value is the snake-free `"all"`/`"none"` string. An unknown/garbage server value
|
|
861
|
+
* maps to `'all'` at the surface — fail-OPEN, never silently mutes (mirrors iOS
|
|
862
|
+
* `NotifyScope`). The server stores this opaque enum and stays MLS-blind (no content).
|
|
863
|
+
*/
|
|
864
|
+
type NotifyScope = 'all' | 'none';
|
|
865
|
+
/**
|
|
866
|
+
* The caller's OWN unread view (the `GET /v1/messaging/groups/{gid}/unread` response).
|
|
867
|
+
* Every field is an OPAQUE server-metadata integer (no message content): the group's max
|
|
868
|
+
* server_seq, this caller's read + delivered cursors, and the server-derived unread
|
|
869
|
+
* count. The camelCase mirror of the snake_case wire (`group_max_seq` → `groupMaxSeq`,
|
|
870
|
+
* etc). Mirrors iOS `UnreadView`.
|
|
871
|
+
*/
|
|
872
|
+
interface UnreadView {
|
|
873
|
+
/** The highest server_seq the group has reached (the newest message's seq). */
|
|
874
|
+
readonly groupMaxSeq: number;
|
|
875
|
+
/** The furthest server_seq THIS caller has marked read. */
|
|
876
|
+
readonly lastReadSeq: number;
|
|
877
|
+
/** The furthest server_seq THIS caller's devices have acked delivered. */
|
|
878
|
+
readonly deliveredSeq: number;
|
|
879
|
+
/** The server-derived unread count for this caller (clamped `>= 0` at the surface). */
|
|
880
|
+
readonly unreadCount: number;
|
|
828
881
|
}
|
|
829
882
|
/** The receipt from a send — the server's monotonic sequence + accepted epoch. */
|
|
830
883
|
interface SentReceipt {
|
|
@@ -1001,7 +1054,12 @@ interface ChatBackend {
|
|
|
1001
1054
|
registerActive(group: MessagingGroup): void;
|
|
1002
1055
|
setTyping(group: MessagingGroup, isTyping: boolean): void;
|
|
1003
1056
|
markRead(group: MessagingGroup, upToServerSeq: number): Promise<void>;
|
|
1004
|
-
/**
|
|
1057
|
+
/** Server-metadata cluster: set/get the per-(user,group) notify scope (mute) and
|
|
1058
|
+
* fetch the caller's own unread view. The server stays MLS-blind (opaque metadata). */
|
|
1059
|
+
setNotifyScope(group: MessagingGroup, scope: NotifyScope): Promise<NotifyScope>;
|
|
1060
|
+
getNotifyScope(group: MessagingGroup): Promise<NotifyScope>;
|
|
1061
|
+
unread(group: MessagingGroup): Promise<UnreadView>;
|
|
1062
|
+
/** Subscribe live message + conv (presence/typing/read/delivered) for an active group. */
|
|
1005
1063
|
subscribeLive(group: MessagingGroup, chat: Chat): Unsubscribe$1;
|
|
1006
1064
|
/** Resolve a sender device id → its owning user id (for senderUserId). */
|
|
1007
1065
|
userIdForDevice(group: MessagingGroup, deviceId: string): Promise<string | null>;
|
|
@@ -1306,6 +1364,20 @@ declare class Chat {
|
|
|
1306
1364
|
leave(): Promise<void>;
|
|
1307
1365
|
setTyping(isTyping: boolean): void;
|
|
1308
1366
|
markRead(message: ChatMessage): Promise<void>;
|
|
1367
|
+
/** Set this chat's notify scope (the mute toggle). `'none'` mutes the push wake;
|
|
1368
|
+
* `'all'` unmutes (the default). Materializes a draft first (the scope is a
|
|
1369
|
+
* per-(user,group) server row), PUTs `/notify`, and returns the server-echoed scope.
|
|
1370
|
+
* Mirrors iOS `Chat.setNotifyScope`. */
|
|
1371
|
+
setNotifyScope(scope: NotifyScope): Promise<NotifyScope>;
|
|
1372
|
+
/** Refresh + return this chat's notify scope from the server (fail-OPEN to `'all'`).
|
|
1373
|
+
* Returns `'all'` for a draft chat (no server row yet). */
|
|
1374
|
+
getNotifyScope(): Promise<NotifyScope>;
|
|
1375
|
+
/** Fetch the caller's authoritative SERVER unread count (opaque server metadata).
|
|
1376
|
+
* Returns the clamped count (`max(0, …)`); `0` for a draft chat. The local computed
|
|
1377
|
+
* `unreadCount` getter stays the instant, offline best-effort badge — this is the
|
|
1378
|
+
* canonical count on demand. Named distinctly so it does not shadow the observable
|
|
1379
|
+
* `unreadCount` snapshot getter. Mirrors iOS `Chat.refreshUnread`. */
|
|
1380
|
+
unreadCountFromServer(): Promise<number>;
|
|
1309
1381
|
/** Add an emoji reaction to a message. No-op if the message isn't reactable
|
|
1310
1382
|
* (empty clientMsgId — a legacy/system row). The reaction folds locally with
|
|
1311
1383
|
* the server receipt's `(epoch, serverSeq)` so the target's tally updates
|
|
@@ -1374,6 +1446,153 @@ declare class PalbeMessaging {
|
|
|
1374
1446
|
onChatsChange(cb: () => void): Unsubscribe$1;
|
|
1375
1447
|
}
|
|
1376
1448
|
|
|
1449
|
+
/** The Faz-1 trace kinds plus the Faz-1.5 web-vital family. */
|
|
1450
|
+
type PerfTraceType = 'network' | 'app_start' | 'custom' | 'web_vital';
|
|
1451
|
+
/**
|
|
1452
|
+
* One perf measurement, shaped EXACTLY as the ingest wire expects. Keys are
|
|
1453
|
+
* snake_case to match the Go decode tags — do not rename to camelCase.
|
|
1454
|
+
*/
|
|
1455
|
+
interface PerfItem {
|
|
1456
|
+
/** Client-generated UUIDv7 — server dedup key. */
|
|
1457
|
+
row_id: string;
|
|
1458
|
+
trace_type: PerfTraceType;
|
|
1459
|
+
name: string;
|
|
1460
|
+
/** Duration in milliseconds. */
|
|
1461
|
+
value: number;
|
|
1462
|
+
counters?: Record<string, number>;
|
|
1463
|
+
attrs?: Record<string, string>;
|
|
1464
|
+
request_id?: string;
|
|
1465
|
+
/** Unix milliseconds. */
|
|
1466
|
+
timestamp: number;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* Bounded FIFO perf-item queue. `enqueue` appends and evicts the oldest on
|
|
1471
|
+
* overflow; `drainAll` returns everything (oldest-first) and clears the store;
|
|
1472
|
+
* `count` is the current depth; `dropped` is the cumulative eviction counter.
|
|
1473
|
+
*
|
|
1474
|
+
* When `localStorage` is present the queue is read-through / write-through to a
|
|
1475
|
+
* fixed key, so a fresh instance after a reload sees the persisted items. With
|
|
1476
|
+
* no `localStorage` it is purely in-memory.
|
|
1477
|
+
*/
|
|
1478
|
+
declare class PerfOfflineQueue {
|
|
1479
|
+
private items;
|
|
1480
|
+
private _dropped;
|
|
1481
|
+
private readonly maxItems;
|
|
1482
|
+
constructor(maxItems?: number);
|
|
1483
|
+
/** Append items; FIFO-evict the oldest when over `maxItems`. */
|
|
1484
|
+
enqueue(items: PerfItem[]): void;
|
|
1485
|
+
/** Return all queued items (oldest-first) and clear the queue + store. */
|
|
1486
|
+
drainAll(): PerfItem[];
|
|
1487
|
+
/** Current queue depth. */
|
|
1488
|
+
get count(): number;
|
|
1489
|
+
/** Cumulative count of FIFO-evicted items (a `dropped` metric, not silent). */
|
|
1490
|
+
get dropped(): number;
|
|
1491
|
+
/** Drop the oldest items until at most `maxItems` remain, counting each. */
|
|
1492
|
+
private trim;
|
|
1493
|
+
private persist;
|
|
1494
|
+
private clearStore;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* The mutable PalPerf state shared between the facade and the network hook.
|
|
1499
|
+
* `testDevice` is signalled to the server via the `X-Palbase-Test-Device: 1`
|
|
1500
|
+
* request header (server-authoritative tagging — the SDK only flips the bit).
|
|
1501
|
+
*/
|
|
1502
|
+
declare class PerfState {
|
|
1503
|
+
/** Pending, un-flushed perf items (FIFO). */
|
|
1504
|
+
readonly buffer: PerfItem[];
|
|
1505
|
+
/** When true, every flush carries `X-Palbase-Test-Device: 1`. */
|
|
1506
|
+
testDevice: boolean;
|
|
1507
|
+
enqueue(item: PerfItem): void;
|
|
1508
|
+
/** Detach up to `MAX_PERF_BATCH` items for one POST (FIFO order preserved). */
|
|
1509
|
+
take(limit?: number): PerfItem[];
|
|
1510
|
+
get size(): number;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* A running custom trace. `putAttribute`/`incrementMetric` accumulate metadata;
|
|
1515
|
+
* `stop()` records ONE `custom` PerfItem whose `value` is the elapsed
|
|
1516
|
+
* milliseconds since `startTrace`. Idempotent: a second `stop()` is a no-op.
|
|
1517
|
+
*/
|
|
1518
|
+
declare class PerfTrace {
|
|
1519
|
+
private readonly name;
|
|
1520
|
+
private readonly onStop;
|
|
1521
|
+
private readonly attrs;
|
|
1522
|
+
private readonly counters;
|
|
1523
|
+
private readonly startedAt;
|
|
1524
|
+
private stopped;
|
|
1525
|
+
constructor(name: string, onStop: (item: PerfItem) => void);
|
|
1526
|
+
putAttribute(key: string, value: string): void;
|
|
1527
|
+
incrementMetric(name: string, by?: number): void;
|
|
1528
|
+
stop(): void;
|
|
1529
|
+
}
|
|
1530
|
+
declare class PalbePerf {
|
|
1531
|
+
private readonly rt;
|
|
1532
|
+
private readonly state;
|
|
1533
|
+
/** Durable offline buffer for failed flushes (persist-on-fail). Browser →
|
|
1534
|
+
* localStorage-backed; server → in-memory. */
|
|
1535
|
+
private readonly queue;
|
|
1536
|
+
private flushTimer;
|
|
1537
|
+
/** Browser → buffer + size/timer flush. Server (no document) → immediate
|
|
1538
|
+
* per-item flush, zero timers (nothing leaks into RSC/route handlers). */
|
|
1539
|
+
private readonly browser;
|
|
1540
|
+
/** Bound `online` handler so it can be removed on `dispose()` (no leak). */
|
|
1541
|
+
private readonly onOnline;
|
|
1542
|
+
/** Server-controlled client-side sample rate (0..100). 100 until the config
|
|
1543
|
+
* client fetches `/v1/analytics/perf/config` — the SDK obeys this ceiling and
|
|
1544
|
+
* never raises its own rate (invariant 3). `record` drops an item whose
|
|
1545
|
+
* deterministic `row_id` bucket is >= this pct, mirroring the server's
|
|
1546
|
+
* `SampleDecision` so client + server keep the SAME rows. */
|
|
1547
|
+
private samplePct;
|
|
1548
|
+
constructor(rt: PalbeRuntime, state?: PerfState,
|
|
1549
|
+
/** Durable offline buffer for failed flushes (persist-on-fail). Browser →
|
|
1550
|
+
* localStorage-backed; server → in-memory. */
|
|
1551
|
+
queue?: PerfOfflineQueue);
|
|
1552
|
+
/** Remove the `online` listener. Called when the runtime is replaced so the
|
|
1553
|
+
* handler does not outlive this facade. No-op outside the browser. */
|
|
1554
|
+
dispose(): void;
|
|
1555
|
+
/** Mark (or unmark) this client's traffic as test — the server tags the rows
|
|
1556
|
+
* when the `X-Palbase-Test-Device: 1` header rides along on flush. */
|
|
1557
|
+
setTestDevice(on: boolean): void;
|
|
1558
|
+
/** Apply the server-resolved client-side sample rate (0..100), clamped. Called
|
|
1559
|
+
* by `PerfConfigClient` after fetching `/v1/analytics/perf/config`. The SDK
|
|
1560
|
+
* OBEYS this value — it is a ceiling, never raised locally. */
|
|
1561
|
+
setSamplePct(pct: number): void;
|
|
1562
|
+
/** Pending (un-flushed) buffer depth. Test-only visibility into the buffer so
|
|
1563
|
+
* the remote-sampling tests can assert how many items were sampled in. */
|
|
1564
|
+
get bufferSizeForTest(): number;
|
|
1565
|
+
/** Opt-in: wrap the global `fetch` so every app-level request is recorded as a
|
|
1566
|
+
* redacted `network` perf item (the `/v1/analytics/*` ingest paths are
|
|
1567
|
+
* self-excluded). OFF by default — swizzling a global is a page-wide side
|
|
1568
|
+
* effect. Returns an `uninstall` that restores the original `fetch`. */
|
|
1569
|
+
enableFetchCapture(): () => void;
|
|
1570
|
+
/** Start a custom trace; the returned handle records a `custom` item on
|
|
1571
|
+
* `.stop()`. */
|
|
1572
|
+
startTrace(name: string): PerfTrace;
|
|
1573
|
+
/** Buffer one perf item. In the browser, flush on size/timer; on the server
|
|
1574
|
+
* flush immediately (no timers). Never throws.
|
|
1575
|
+
*
|
|
1576
|
+
* Client-side remote sampling: an item whose deterministic `row_id` bucket is
|
|
1577
|
+
* NOT below the server-controlled `samplePct` is dropped before buffering —
|
|
1578
|
+
* the SAME FNV-1a-mod-100 decision the server applies at ingest, so the two
|
|
1579
|
+
* keep identical rows and the SDK saves the upload (defense-in-depth: the
|
|
1580
|
+
* server re-samples authoritatively). */
|
|
1581
|
+
record(item: PerfItem): void;
|
|
1582
|
+
/** Buffer a network trace — called by `request.ts` around `rt.http.request`
|
|
1583
|
+
* (the analytics ingest path is excluded by the caller to avoid recursion). */
|
|
1584
|
+
recordNetwork(method: string, url: string, status: number, durationMs: number, requestId?: string): void;
|
|
1585
|
+
/** Drain the offline queue (oldest-first) and the live buffer to
|
|
1586
|
+
* `/v1/analytics/perf` (≤100 items per request, sequential). Resolves when
|
|
1587
|
+
* delivery finished; NEVER rejects. A failed slice is NOT dropped — it goes
|
|
1588
|
+
* to the offline queue (persist-on-fail) so the next flush (size/timer or the
|
|
1589
|
+
* `online` reconnect event) retries it. Items keep their original `row_id`,
|
|
1590
|
+
* so a redelivery dedups server-side (ReplacingMergeTree). */
|
|
1591
|
+
flush(): Promise<void>;
|
|
1592
|
+
private startTimer;
|
|
1593
|
+
private cancelTimer;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1377
1596
|
/**
|
|
1378
1597
|
* The connection state of the shared realtime WebSocket (iOS enum parity), plus
|
|
1379
1598
|
* `'error'` — surfaced when a channel could not be recovered after a
|
|
@@ -1471,6 +1690,14 @@ declare class PalbeRealtime {
|
|
|
1471
1690
|
|
|
1472
1691
|
interface PalbeRuntime {
|
|
1473
1692
|
config: PalbeConfig;
|
|
1693
|
+
/**
|
|
1694
|
+
* F2 app-registration: the registered app `identifier` (web ORIGIN) stashed at
|
|
1695
|
+
* configure. Rides on `X-Palbase-Bundle` on EVERY request (request.ts) so the
|
|
1696
|
+
* Kong gate can match it. Empty string when the binding is unconfigured/tooling
|
|
1697
|
+
* (no header is sent). Origin-match is enforced in `buildRuntime` BEFORE this
|
|
1698
|
+
* runtime is returned — a mismatch throws there and no runtime is built.
|
|
1699
|
+
*/
|
|
1700
|
+
appIdentifier: string;
|
|
1474
1701
|
http: HttpClient$1;
|
|
1475
1702
|
tokenManager: TokenManager$1;
|
|
1476
1703
|
authClient: AuthClient;
|
|
@@ -1480,6 +1707,13 @@ interface PalbeRuntime {
|
|
|
1480
1707
|
analytics: PalbeAnalytics;
|
|
1481
1708
|
calls: PalbeCalls;
|
|
1482
1709
|
messaging: PalbeMessaging;
|
|
1710
|
+
/**
|
|
1711
|
+
* PalPerf surface. EAGER (like analytics identity): `request.ts` records a
|
|
1712
|
+
* `network` trace around EVERY SDK fetch, so the facade must exist from the
|
|
1713
|
+
* first request — never lazy. The buffer/timer it owns is inert until the
|
|
1714
|
+
* first item is recorded.
|
|
1715
|
+
*/
|
|
1716
|
+
perf: PalbePerf;
|
|
1483
1717
|
storage: SessionStorageAdapter;
|
|
1484
1718
|
/**
|
|
1485
1719
|
* Destroy the realtime facade if it was already constructed (no-op otherwise).
|
|
@@ -1731,4 +1965,4 @@ declare class PalbeAnalytics {
|
|
|
1731
1965
|
private post;
|
|
1732
1966
|
}
|
|
1733
1967
|
|
|
1734
|
-
export { type AnalyticsProperties as A, type PresenceState as B, Call as C, type RealtimeConnectionState as D, type RealtimeHandler as E, type FlagsView as F, type RealtimePayload as G, type RealtimeStatus as H, type RealtimeStatusSnapshot as I, type RealtimeSubscription as J, type ResolvedMention as K, type ResolvedReply as L, type MagicLinkResult as M, type
|
|
1968
|
+
export { type AnalyticsProperties as A, type PresenceState as B, Call as C, type RealtimeConnectionState as D, type RealtimeHandler as E, type FlagsView as F, type RealtimePayload as G, type RealtimeStatus as H, type RealtimeStatusSnapshot as I, type RealtimeSubscription as J, type ResolvedMention as K, type ResolvedReply as L, type MagicLinkResult as M, type NotifyScope as N, type OAuthExchangeResult as O, PalbeAnalytics as P, type Unsubscribe as Q, RealtimeChannel as R, type SentReceipt as S, type PalbeRuntime as T, type UnreadView as U, buildRuntime as V, PalbePerf as W, type AuthChangeEvent as a, type AuthState as b, type AuthSuccess as c, type AuthUser as d, type CallChangeCallback as e, type CallParticipant as f, type CallState as g, Chat as h, type ChatBackend as i, type ChatDraft as j, type ChatKind as k, type ChatMember as l, type ChatMessage as m, type ChatMessageKind as n, type ChatRole as o, type ChatState as p, type CommsPrefs as q, type MentionRange as r, type MessageDirection as s, PalbeAuth as t, PalbeCalls as u, type PalbeConfig as v, PalbeFlags as w, PalbeMessaging as x, type PalbeOAuthConfig as y, PalbeRealtime as z };
|