@ttt-productions/chat-react 0.12.11 → 0.12.13
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/context/ChatAttachmentMediaContext.d.ts +22 -9
- package/dist/context/ChatAttachmentMediaContext.d.ts.map +1 -1
- package/dist/context/ChatAttachmentMediaContext.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/realtime/channel-client.d.ts +46 -0
- package/dist/realtime/channel-client.d.ts.map +1 -1
- package/dist/realtime/channel-client.js +294 -21
- package/dist/realtime/channel-client.js.map +1 -1
- package/dist/realtime/diagnostics.d.ts +76 -0
- package/dist/realtime/diagnostics.d.ts.map +1 -0
- package/dist/realtime/diagnostics.js +111 -0
- package/dist/realtime/diagnostics.js.map +1 -0
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +1 -0
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/transport.d.ts +9 -0
- package/dist/realtime/transport.d.ts.map +1 -1
- package/dist/realtime/transport.js +1 -0
- package/dist/realtime/transport.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/realtime/diagnostics.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,8EAA8E;AAC9E,iFAAiF;AACjF,oEAAoE;AACpE,EAAE;AACF,uCAAuC;AACvC,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,2DAA2D;AAC3D,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAoB9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,gFAAgF;IAChF,eAAe,EAAE,6BAA6B;IAC9C,8EAA8E;IAC9E,YAAY,EAAE,0BAA0B;IACxC,0EAA0E;IAC1E,WAAW,EAAE,yBAAyB;IACtC,+EAA+E;IAC/E,YAAY,EAAE,0BAA0B;IACxC,8EAA8E;IAC9E,mBAAmB,EAAE,iCAAiC;IACtD,wCAAwC;IACxC,cAAc,EAAE,4BAA4B;IAC5C,qEAAqE;IACrE,aAAa,EAAE,2BAA2B;IAC1C,8EAA8E;IAC9E,mBAAmB,EAAE,iCAAiC;IACtD,wFAAwF;IACxF,aAAa,EAAE,2BAA2B;IAC1C,gDAAgD;IAChD,aAAa,EAAE,2BAA2B;IAC1C,mFAAmF;IACnF,qBAAqB,EAAE,mCAAmC;IAC1D,yFAAyF;IACzF,gBAAgB,EAAE,8BAA8B;IAChD,qDAAqD;IACrD,eAAe,EAAE,6BAA6B;IAC9C,mEAAmE;IACnE,YAAY,EAAE,0BAA0B;IACxC,6DAA6D;IAC7D,eAAe,EAAE,6BAA6B;IAC9C,qDAAqD;IACrD,QAAQ,EAAE,sBAAsB;IAChC,kFAAkF;IAClF,aAAa,EAAE,2BAA2B;IAC1C,gFAAgF;IAChF,UAAU,EAAE,wBAAwB;IACpC,gEAAgE;IAChE,WAAW,EAAE,yBAAyB;IACtC,iDAAiD;IACjD,WAAW,EAAE,yBAAyB;CAC9B,CAAC;AAKX,8FAA8F;AAC9F,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAgB,GAA8B,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IAClE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO;IAClF,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAA+C;IAE/C,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC;IACzD,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,8EAA8E;QAC9E,qEAAqE;QACrE,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,sDAAsD;QACxD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// OPT-IN structured client diagnostics for the realtime chat transport.\n//\n// The E2E/browser harness can already capture the raw WebSocket frames; what it\n// cannot see is what the CLIENT DECIDED about them — which frame it applied,\n// which it dropped and why, what resume cursor it sent, whether an attachment\n// row mutated in place, and whether a send was reconciled or failed. This module\n// is that missing half: a bounded, structured, opt-in decision log.\n//\n// Rules this module exists to enforce:\n// - OFF BY DEFAULT and zero behavior change. When the option is absent the\n// factory returns `null`, every call site is `this.diag?.(...)`, and JS\n// optional-call short-circuiting means the payload object is never even\n// constructed. The cost when off is one nullish check.\n// - NEVER user content. Ids, seqs, states, counts, codes, booleans only —\n// never message text, captions, filenames, URLs, tokens, or previews.\n// - STABLE event names (`chat_client_*`) suitable for log queries and later\n// alert metrics; one line per DECISION, never per render or per heartbeat.\n// - A diagnostics sink can never break the client: every emit is wrapped, so a\n// throwing sink is swallowed rather than turned into a transport failure.\n\n/**\n * A structured diagnostic sink. `event` is one of the stable\n * {@link CHAT_CLIENT_DIAGNOSTIC_EVENTS} names; `data` is a compact, content-free\n * payload (ids/seqs/states/counts/codes only). Supplying a sink lets the app\n * route entries into its own logger; `true` uses the console.debug default.\n */\nexport type ChatClientDiagnosticsSink = (event: string, data: Record<string, unknown>) => void;\n\n/**\n * The additive `diagnostics` config value: `false`/absent = off (the default and\n * the only production posture), `true` = the single-line `console.debug` sink,\n * or a custom {@link ChatClientDiagnosticsSink}.\n */\nexport type ChatClientDiagnosticsOption = boolean | ChatClientDiagnosticsSink;\n\n/** The bound emitter, or `null` when diagnostics are off (the zero-overhead path). */\nexport type ChatClientDiagnosticsEmitter = ChatClientDiagnosticsSink | null;\n\n/**\n * Stable event names. These are a QUERY CONTRACT — Cloud Logging filters, E2E\n * console greps, and any later alert metric key on them, so a name is added or\n * retired deliberately, never renamed in place.\n */\nexport const CHAT_CLIENT_DIAGNOSTIC_EVENTS = {\n /** A socket open is being attempted (per attempt, with the reconnect cause). */\n CONNECT_ATTEMPT: 'chat_client_connect_attempt',\n /** The grant mint failed before a socket existed (terminal vs. retryable). */\n GRANT_FAILED: 'chat_client_grant_failed',\n /** The socket reached OPEN (the point the resume cursor is sent from). */\n SOCKET_OPEN: 'chat_client_socket_open',\n /** The socket closed, with the code and what the client decided to do next. */\n SOCKET_CLOSE: 'chat_client_socket_close',\n /** A reconnect was scheduled (`delayMs`) or given up on (`delayMs: null`). */\n RECONNECT_SCHEDULED: 'chat_client_reconnect_scheduled',\n /** The resume cursor sent to the DO. */\n RESUME_REQUEST: 'chat_client_resume_request',\n /** The DO's snapshot answer + how the cursor moved because of it. */\n RESUME_RESULT: 'chat_client_resume_result',\n /** A `resync: true` snapshot dropped the local tail (removal, not upsert). */\n RESYNC_DROPPED_TAIL: 'chat_client_resync_dropped_tail',\n /** A frame was applied to UI state (insert / replace-by-seq / optimistic reconcile). */\n FRAME_APPLIED: 'chat_client_frame_applied',\n /** A frame was NOT applied, with the reason. */\n FRAME_DROPPED: 'chat_client_frame_dropped',\n /** An attachment lifecycle change AS SEEN BY THE CLIENT: seq, old -> new state. */\n ATTACHMENT_TRANSITION: 'chat_client_attachment_transition',\n /** A moderation revision overlay was recorded (and whether a loaded row re-rendered). */\n REVISION_APPLIED: 'chat_client_revision_applied',\n /** A history page was requested (cursor + limit). */\n HISTORY_REQUEST: 'chat_client_history_request',\n /** A history page was applied: size, seq range, cursor advance. */\n HISTORY_PAGE: 'chat_client_history_page',\n /** An optimistic send was rendered and its frame written. */\n SEND_OPTIMISTIC: 'chat_client_send_optimistic',\n /** A send was acked by the server (seq assigned). */\n SEND_ACK: 'chat_client_send_ack',\n /** A correlated `send-rejected` (or its legacy uncorrelated form) was handled. */\n SEND_REJECTED: 'chat_client_send_rejected',\n /** A send was re-emitted (reconnect resume / scheduled hint / manual retry). */\n SEND_RETRY: 'chat_client_send_retry',\n /** A send reached its visible failed state, with the reason. */\n SEND_FAILED: 'chat_client_send_failed',\n /** An uncorrelated server `error` frame code. */\n ERROR_FRAME: 'chat_client_error_frame',\n} as const;\n\nexport type ChatClientDiagnosticEventName =\n (typeof CHAT_CLIENT_DIAGNOSTIC_EVENTS)[keyof typeof CHAT_CLIENT_DIAGNOSTIC_EVENTS];\n\n/** Max length of a server-supplied label (frame type, error code) we echo into a log line. */\nconst MAX_LABEL_LEN = 48;\n\n/**\n * Clamp a server-supplied label before it enters a log line. Frame types and\n * error codes are protocol tokens, not user content, but they arrive from the\n * wire — bound them so a hostile/buggy peer cannot emit an unbounded line.\n */\nexport function safeDiagnosticLabel(raw: unknown): string {\n if (typeof raw !== 'string') return 'unknown';\n const trimmed = raw.slice(0, MAX_LABEL_LEN);\n return trimmed.length > 0 ? trimmed : 'unknown';\n}\n\n/**\n * The default sink: ONE `console.debug` line per decision, shaped\n * `chat_client_<event> {\"compact\":\"json\"}` so a browser console capture or a log\n * query can filter on the stable prefix and parse the payload without a\n * multi-line join.\n */\nconst consoleDebugSink: ChatClientDiagnosticsSink = (event, data) => {\n if (typeof console === 'undefined' || typeof console.debug !== 'function') return;\n console.debug(`${event} ${JSON.stringify(data)}`);\n};\n\n/**\n * Build the emitter for a `diagnostics` config value. Returns `null` when\n * diagnostics are off so call sites can use `this.diag?.(...)` — with optional\n * call syntax the argument object is not constructed at all on the off path.\n */\nexport function createDiagnosticsEmitter(\n option: ChatClientDiagnosticsOption | undefined,\n): ChatClientDiagnosticsEmitter {\n if (option == null || option === false) return null;\n const sink = option === true ? consoleDebugSink : option;\n return (event, data) => {\n // Diagnostics observe; they must never alter transport behavior — a sink that\n // throws (or a payload that cannot be serialized) is swallowed here.\n try {\n sink(event, data);\n } catch {\n /* diagnostics are never allowed to fail the client */\n }\n };\n}\n"]}
|
package/dist/realtime/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export type { GrantProvider, TransportTimers, RealtimeStatus } from './shared.js
|
|
|
6
6
|
export { defaultTimers, ChatAccessDeniedError, isChatAccessDeniedError, HEARTBEAT_MS, TYPING_COALESCE_MS, HISTORY_PAGE_MAX, } from './shared.js';
|
|
7
7
|
export { wireRowToMessage, optimisticMessage, seqToMessageId, applyModerationOverlay, overlayFromRow, MODERATION_REDACTED_TEXT, } from './map.js';
|
|
8
8
|
export type { ModerationOverlay } from './map.js';
|
|
9
|
+
export { CHAT_CLIENT_DIAGNOSTIC_EVENTS } from './diagnostics.js';
|
|
10
|
+
export type { ChatClientDiagnosticsOption, ChatClientDiagnosticsSink, ChatClientDiagnosticEventName, } from './diagnostics.js';
|
|
9
11
|
export { ChannelClient } from './channel-client.js';
|
|
10
12
|
export type { ChannelClientState, ChannelClientConfig } from './channel-client.js';
|
|
11
13
|
export { InboxClient } from './inbox-client.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAElF,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,YAAY,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,YAAY,EACV,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAElF,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,YAAY,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC"}
|
package/dist/realtime/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { CHAT_SUBPROTOCOL, CHAT_WIRE_VERSION, CHAT_CLOSE_CODES, CLIENT_FRAME, SE
|
|
|
7
7
|
export { browserSocketFactory } from './socket.js';
|
|
8
8
|
export { defaultTimers, ChatAccessDeniedError, isChatAccessDeniedError, HEARTBEAT_MS, TYPING_COALESCE_MS, HISTORY_PAGE_MAX, } from './shared.js';
|
|
9
9
|
export { wireRowToMessage, optimisticMessage, seqToMessageId, applyModerationOverlay, overlayFromRow, MODERATION_REDACTED_TEXT, } from './map.js';
|
|
10
|
+
export { CHAT_CLIENT_DIAGNOSTIC_EVENTS } from './diagnostics.js';
|
|
10
11
|
export { ChannelClient } from './channel-client.js';
|
|
11
12
|
export { InboxClient } from './inbox-client.js';
|
|
12
13
|
export { createRealtimeChatClient, createInboxClient, } from './transport.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,sEAAsE;AACtE,uEAAuE;AACvE,mCAAmC;AAEnC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC;AAanB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["// The realtime (Cloudflare Durable Object) chat transport — the client half of\n// the chat Worker wire protocol (Contract A connection + Contract C wire). The\n// FIRESTORE transport stays the unchanged default; this is opt-in via\n// `ChatCoreConfig.transport === 'realtime'` + a `realtime.client` from\n// `createRealtimeChatClient(...)`.\n\nexport {\n CHAT_SUBPROTOCOL,\n CHAT_WIRE_VERSION,\n CHAT_CLOSE_CODES,\n CLIENT_FRAME,\n SERVER_FRAME,\n buildFrame,\n parseFrame,\n isInboxSnapshot,\n} from './wire.js';\nexport type {\n ChannelRefTuple,\n ChatCloseCode,\n WireMessageRow,\n WireChannelSnapshot,\n WireInboxSnapshot,\n WireRegistryEntry,\n ServerFrame,\n RevisionKind,\n} from './wire.js';\n\nexport type { RealtimeSocket, SocketFactory, SocketHandlers } from './socket.js';\nexport { browserSocketFactory } from './socket.js';\n\nexport type { GrantProvider, TransportTimers, RealtimeStatus } from './shared.js';\nexport {\n defaultTimers,\n ChatAccessDeniedError,\n isChatAccessDeniedError,\n HEARTBEAT_MS,\n TYPING_COALESCE_MS,\n HISTORY_PAGE_MAX,\n} from './shared.js';\n\nexport {\n wireRowToMessage,\n optimisticMessage,\n seqToMessageId,\n applyModerationOverlay,\n overlayFromRow,\n MODERATION_REDACTED_TEXT,\n} from './map.js';\nexport type { ModerationOverlay } from './map.js';\n\nexport { ChannelClient } from './channel-client.js';\nexport type { ChannelClientState, ChannelClientConfig } from './channel-client.js';\nexport { InboxClient } from './inbox-client.js';\nexport type { InboxClientState, InboxClientConfig } from './inbox-client.js';\n\nexport {\n createRealtimeChatClient,\n createInboxClient,\n} from './transport.js';\nexport type { RealtimeChatClient, RealtimeTransportConfig } from './transport.js';\n\nexport { useRealtimeChatMessages } from './useRealtimeChatMessages.js';\nexport type { UseRealtimeChatMessagesResult } from './useRealtimeChatMessages.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,sEAAsE;AACtE,uEAAuE;AACvE,mCAAmC;AAEnC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC;AAanB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAOjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["// The realtime (Cloudflare Durable Object) chat transport — the client half of\n// the chat Worker wire protocol (Contract A connection + Contract C wire). The\n// FIRESTORE transport stays the unchanged default; this is opt-in via\n// `ChatCoreConfig.transport === 'realtime'` + a `realtime.client` from\n// `createRealtimeChatClient(...)`.\n\nexport {\n CHAT_SUBPROTOCOL,\n CHAT_WIRE_VERSION,\n CHAT_CLOSE_CODES,\n CLIENT_FRAME,\n SERVER_FRAME,\n buildFrame,\n parseFrame,\n isInboxSnapshot,\n} from './wire.js';\nexport type {\n ChannelRefTuple,\n ChatCloseCode,\n WireMessageRow,\n WireChannelSnapshot,\n WireInboxSnapshot,\n WireRegistryEntry,\n ServerFrame,\n RevisionKind,\n} from './wire.js';\n\nexport type { RealtimeSocket, SocketFactory, SocketHandlers } from './socket.js';\nexport { browserSocketFactory } from './socket.js';\n\nexport type { GrantProvider, TransportTimers, RealtimeStatus } from './shared.js';\nexport {\n defaultTimers,\n ChatAccessDeniedError,\n isChatAccessDeniedError,\n HEARTBEAT_MS,\n TYPING_COALESCE_MS,\n HISTORY_PAGE_MAX,\n} from './shared.js';\n\nexport {\n wireRowToMessage,\n optimisticMessage,\n seqToMessageId,\n applyModerationOverlay,\n overlayFromRow,\n MODERATION_REDACTED_TEXT,\n} from './map.js';\nexport type { ModerationOverlay } from './map.js';\n\nexport { CHAT_CLIENT_DIAGNOSTIC_EVENTS } from './diagnostics.js';\nexport type {\n ChatClientDiagnosticsOption,\n ChatClientDiagnosticsSink,\n ChatClientDiagnosticEventName,\n} from './diagnostics.js';\n\nexport { ChannelClient } from './channel-client.js';\nexport type { ChannelClientState, ChannelClientConfig } from './channel-client.js';\nexport { InboxClient } from './inbox-client.js';\nexport type { InboxClientState, InboxClientConfig } from './inbox-client.js';\n\nexport {\n createRealtimeChatClient,\n createInboxClient,\n} from './transport.js';\nexport type { RealtimeChatClient, RealtimeTransportConfig } from './transport.js';\n\nexport { useRealtimeChatMessages } from './useRealtimeChatMessages.js';\nexport type { UseRealtimeChatMessagesResult } from './useRealtimeChatMessages.js';\n"]}
|
|
@@ -2,6 +2,7 @@ import { ChannelClient, type ChannelClientConfig, type ChannelClientState } from
|
|
|
2
2
|
import { InboxClient, type InboxClientConfig, type InboxClientState } from './inbox-client.js';
|
|
3
3
|
import { type SocketFactory } from './socket.js';
|
|
4
4
|
import type { GrantProvider, TransportTimers } from './shared.js';
|
|
5
|
+
import type { ChatClientDiagnosticsOption } from './diagnostics.js';
|
|
5
6
|
import type { ChannelRefTuple } from './wire.js';
|
|
6
7
|
/**
|
|
7
8
|
* Everything the channel transport needs. The app supplies `grantProvider`
|
|
@@ -17,6 +18,14 @@ export interface RealtimeTransportConfig {
|
|
|
17
18
|
socketFactory?: SocketFactory;
|
|
18
19
|
timers?: TransportTimers;
|
|
19
20
|
reconnect?: ChannelClientConfig['reconnect'];
|
|
21
|
+
/**
|
|
22
|
+
* OPT-IN structured client diagnostics, forwarded to the ChannelClient. Absent
|
|
23
|
+
* or `false` (the default) changes nothing and costs one nullish check; `true`
|
|
24
|
+
* emits one single-line `console.debug` entry per client DECISION with a stable
|
|
25
|
+
* `chat_client_*` event name; a function routes those entries into the app's own
|
|
26
|
+
* logger. Content-free by construction (ids/seqs/states/counts/codes only).
|
|
27
|
+
*/
|
|
28
|
+
diagnostics?: ChatClientDiagnosticsOption;
|
|
20
29
|
}
|
|
21
30
|
/**
|
|
22
31
|
* The opaque realtime client handle stored on `ChatRealtimeTransportConfig.client`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/realtime/transport.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACvG,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/realtime/transport.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACvG,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,2BAA2B,CAAC;CAC3C;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,uEAAuE;IACvE,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,IAAI,kBAAkB,CAAC;IAC/B,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC5D;AAED,4FAA4F;AAC5F,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,uBAAuB,GAAG,kBAAkB,CAqB5F;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAC5C,GAAG,WAAW,CASd;AAED,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/realtime/transport.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6DAA6D;AAC7D,gFAAgF;AAChF,2EAA2E;AAC3E,oFAAoF;AACpF,EAAE;AACF,sEAAsE;AACtE,+EAA+E;AAC/E,kFAAkF;AAClF,mFAAmF;AACnF,sDAAsD;AAEtD,OAAO,EAAE,aAAa,EAAqD,MAAM,qBAAqB,CAAC;AACvG,OAAO,EAAE,WAAW,EAAiD,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAsB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/realtime/transport.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6DAA6D;AAC7D,gFAAgF;AAChF,2EAA2E;AAC3E,oFAAoF;AACpF,EAAE;AACF,sEAAsE;AACtE,+EAA+E;AAC/E,kFAAkF;AAClF,mFAAmF;AACnF,sDAAsD;AAEtD,OAAO,EAAE,aAAa,EAAqD,MAAM,qBAAqB,CAAC;AACvG,OAAO,EAAE,WAAW,EAAiD,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAsB,MAAM,aAAa,CAAC;AA6CvE,4FAA4F;AAC5F,MAAM,UAAU,wBAAwB,CAAC,MAA+B;IACtE,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,oBAAoB;QAC3D,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;QAChC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE;QAC5B,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,MAOjC;IACC,OAAO,IAAI,WAAW,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,oBAAoB;QAC3D,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;AACL,CAAC","sourcesContent":["// The realtime transport HANDLE the chat-react config carries on the `realtime`\n// transport (`ChatRealtimeTransportConfig.client`). It owns:\n// - a ChannelClient for the active thread (send/read/typing/presence/history)\n// - the grant-mint wiring (channel scope) via the injected grantProvider\n// - auth-user-switch teardown (close every socket before connecting as a new uid)\n//\n// The INBOX socket is created SEPARATELY (one per user, app-wide) via\n// `createInboxClient` — it is not tied to a single thread, so the app owns its\n// lifetime (mount it once at the dock, not per ChatShell). This keeps the channel\n// transport (per-thread) and the inbox transport (per-user) cleanly split, exactly\n// as the worker splits Channel DOs from the Inbox DO.\n\nimport { ChannelClient, type ChannelClientConfig, type ChannelClientState } from './channel-client.js';\nimport { InboxClient, type InboxClientConfig, type InboxClientState } from './inbox-client.js';\nimport { browserSocketFactory, type SocketFactory } from './socket.js';\nimport type { GrantProvider, TransportTimers } from './shared.js';\nimport type { ChatClientDiagnosticsOption } from './diagnostics.js';\nimport type { ChannelRefTuple } from './wire.js';\n\n/**\n * Everything the channel transport needs. The app supplies `grantProvider`\n * (its `mintChatGrant` callable, channel scope) + `endpoint`; `socketFactory`\n * defaults to the real browser WebSocket and is overridden in tests.\n */\nexport interface RealtimeTransportConfig {\n endpoint: string;\n channelRef: ChannelRefTuple;\n threadId: string;\n currentUserId: string;\n grantProvider: GrantProvider;\n socketFactory?: SocketFactory;\n timers?: TransportTimers;\n reconnect?: ChannelClientConfig['reconnect'];\n /**\n * OPT-IN structured client diagnostics, forwarded to the ChannelClient. Absent\n * or `false` (the default) changes nothing and costs one nullish check; `true`\n * emits one single-line `console.debug` entry per client DECISION with a stable\n * `chat_client_*` event name; a function routes those entries into the app's own\n * logger. Content-free by construction (ids/seqs/states/counts/codes only).\n */\n diagnostics?: ChatClientDiagnosticsOption;\n}\n\n/**\n * The opaque realtime client handle stored on `ChatRealtimeTransportConfig.client`.\n * The UI hook (`useRealtimeChatMessages`) drives it; the UI never reaches into the\n * socket directly.\n */\nexport interface RealtimeChatClient {\n readonly channel: ChannelClient;\n readonly channelRef: ChannelRefTuple;\n readonly currentUserId: string;\n connect(): Promise<void>;\n /** Tear down every socket (auth-user switch / unmount). Idempotent. */\n close(): void;\n getState(): ChannelClientState;\n subscribe(fn: (s: ChannelClientState) => void): () => void;\n}\n\n/** Create the per-thread realtime client (the value placed on `config.realtime.client`). */\nexport function createRealtimeChatClient(config: RealtimeTransportConfig): RealtimeChatClient {\n const channel = new ChannelClient({\n endpoint: config.endpoint,\n threadId: config.threadId,\n currentUserId: config.currentUserId,\n grantProvider: config.grantProvider,\n socketFactory: config.socketFactory ?? browserSocketFactory,\n timers: config.timers,\n reconnect: config.reconnect,\n diagnostics: config.diagnostics,\n });\n\n return {\n channel,\n channelRef: config.channelRef,\n currentUserId: config.currentUserId,\n connect: () => channel.connect(),\n close: () => channel.close(),\n getState: () => channel.getState(),\n subscribe: (fn) => channel.subscribe(fn),\n };\n}\n\n/** Create the per-USER inbox client (mount once at the dock; not per-thread). */\nexport function createInboxClient(config: {\n endpoint: string;\n currentUserId: string;\n grantProvider: GrantProvider;\n socketFactory?: SocketFactory;\n timers?: TransportTimers;\n reconnect?: InboxClientConfig['reconnect'];\n}): InboxClient {\n return new InboxClient({\n endpoint: config.endpoint,\n currentUserId: config.currentUserId,\n grantProvider: config.grantProvider,\n socketFactory: config.socketFactory ?? browserSocketFactory,\n timers: config.timers,\n reconnect: config.reconnect,\n });\n}\n\nexport type { ChannelClientState, InboxClientState };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttt-productions/chat-react",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.13",
|
|
4
4
|
"description": "Chat React UI, hooks, and Firebase-client adapter for TTT Productions apps (realtime newest window + infinite older pagination)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"@ttt-productions/ui-core": "^0.11.10",
|
|
68
68
|
"@ttt-productions/file-input": "^0.11.6",
|
|
69
69
|
"@ttt-productions/upload-ui": "^0.7.5",
|
|
70
|
-
"@ttt-productions/media-viewer": "^0.10.
|
|
70
|
+
"@ttt-productions/media-viewer": "^0.10.6",
|
|
71
71
|
"@ttt-productions/mobile-core": "^0.9.1",
|
|
72
|
-
"@ttt-productions/firebase-helpers": "^0.12.
|
|
72
|
+
"@ttt-productions/firebase-helpers": "^0.12.3"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@ttt-productions/query-core": "^0.14.1",
|