@ttt-productions/chat-react 0.12.15 → 0.13.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/README.md +8 -8
- package/dist/hooks/useChatMessages.d.ts.map +1 -1
- package/dist/hooks/useChatMessages.js +0 -1
- package/dist/hooks/useChatMessages.js.map +1 -1
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/realtime/channel-client.d.ts +6 -13
- package/dist/realtime/channel-client.d.ts.map +1 -1
- package/dist/realtime/channel-client.js +7 -56
- package/dist/realtime/channel-client.js.map +1 -1
- package/dist/realtime/diagnostics.d.ts +0 -2
- package/dist/realtime/diagnostics.d.ts.map +1 -1
- package/dist/realtime/diagnostics.js +7 -5
- package/dist/realtime/diagnostics.js.map +1 -1
- package/dist/realtime/map.d.ts +4 -7
- package/dist/realtime/map.d.ts.map +1 -1
- package/dist/realtime/map.js +4 -41
- package/dist/realtime/map.js.map +1 -1
- package/dist/realtime/wire.d.ts +5 -5
- package/dist/realtime/wire.d.ts.map +1 -1
- package/dist/realtime/wire.js.map +1 -1
- package/dist/types.d.ts +0 -41
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/ChatShell.d.ts +2 -4
- package/dist/ui/ChatShell.d.ts.map +1 -1
- package/dist/ui/ChatShell.js +2 -13
- package/dist/ui/ChatShell.js.map +1 -1
- package/dist/ui/Composer.d.ts +5 -28
- package/dist/ui/Composer.d.ts.map +1 -1
- package/dist/ui/Composer.js +8 -104
- package/dist/ui/Composer.js.map +1 -1
- package/dist/ui/MessageItemDefault.d.ts +0 -5
- package/dist/ui/MessageItemDefault.d.ts.map +1 -1
- package/dist/ui/MessageItemDefault.js +6 -75
- package/dist/ui/MessageItemDefault.js.map +1 -1
- package/dist/ui/MessageList.d.ts +0 -3
- package/dist/ui/MessageList.d.ts.map +1 -1
- package/dist/ui/MessageList.js +2 -2
- package/dist/ui/MessageList.js.map +1 -1
- package/package.json +3 -6
- package/src/styles/chat.css +0 -139
- package/dist/context/ChatAttachmentMediaContext.d.ts +0 -37
- package/dist/context/ChatAttachmentMediaContext.d.ts.map +0 -1
- package/dist/context/ChatAttachmentMediaContext.js +0 -17
- package/dist/context/ChatAttachmentMediaContext.js.map +0 -1
- package/dist/context/ChatAttachmentUrlContext.d.ts +0 -25
- package/dist/context/ChatAttachmentUrlContext.d.ts.map +0 -1
- package/dist/context/ChatAttachmentUrlContext.js +0 -21
- package/dist/context/ChatAttachmentUrlContext.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# @ttt-productions/chat-react
|
|
2
2
|
|
|
3
3
|
Chat **React UI** for TTT Productions apps: chat shell, composer, message list,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
the generic mention autocomplete UI, the name-resolver context, and the
|
|
5
|
+
realtime-newest-window + infinite-older hooks. Chat is TEXT-only — a
|
|
6
|
+
conversation's files live in the consuming app's Conversation Files surface,
|
|
7
|
+
never in the message timeline.
|
|
6
8
|
|
|
7
9
|
Built on the pure [`@ttt-productions/chat-core`](../chat-core) package
|
|
8
10
|
(contracts, mention parser/serializer, grouping). A non-React consumer (a Cloud
|
|
@@ -12,9 +14,8 @@ in none of this frontend tree.
|
|
|
12
14
|
## Entry points
|
|
13
15
|
|
|
14
16
|
- `.` — React components, hooks, the Firebase-client adapter config types
|
|
15
|
-
(`ChatCoreConfig`, `
|
|
16
|
-
`
|
|
17
|
-
`RenderableMentionProvider`, `MentionResultRenderer`).
|
|
17
|
+
(`ChatCoreConfig`, `ChatMentionConfig`), and the React render types
|
|
18
|
+
(`MessageRenderer`, `RenderableMentionProvider`, `MentionResultRenderer`).
|
|
18
19
|
- `./styles` — chat CSS. Import once in your app layout:
|
|
19
20
|
`import "@ttt-productions/chat-react/styles";`
|
|
20
21
|
|
|
@@ -26,6 +27,5 @@ are optional peers — provided by the consuming app.
|
|
|
26
27
|
## Boundary
|
|
27
28
|
|
|
28
29
|
`chat-react` does not import `ttt-core`, does not hardcode TTT origins, and does
|
|
29
|
-
not build TTT storage paths
|
|
30
|
-
|
|
31
|
-
kinds, permissions, provider lists, routing, and search live in TTT code.
|
|
30
|
+
not build TTT storage paths — it runs no upload path at all. TTT mention kinds,
|
|
31
|
+
permissions, provider lists, routing, and search live in TTT code.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatMessages.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatMessages.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;
|
|
1
|
+
{"version":3,"file":"useChatMessages.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatMessages.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAwCF,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,qBAAqB,CAuF7E"}
|
|
@@ -29,7 +29,6 @@ function mapMsg(data, threadId) {
|
|
|
29
29
|
senderId: d.senderId,
|
|
30
30
|
text: d.text ?? "",
|
|
31
31
|
type: d.type,
|
|
32
|
-
attachment: d.attachment ?? undefined,
|
|
33
32
|
replyTo,
|
|
34
33
|
isSystemMessage: d.isSystemMessage ?? undefined,
|
|
35
34
|
// Moderation tombstone flag (backend-written) — carried through so renderers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatMessages.js","sourceRoot":"","sources":["../../src/hooks/useChatMessages.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAEpF,4CAA4C;AAC5C,MAAM,aAAa,GAAG,GAAG,CAAC;AAW1B,SAAS,MAAM,CACb,IAAmC,EACnC,QAAgB;IAEhB,MAAM,CAAC,GAAG,IAAW,CAAC;IAEtB,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAExC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oDAAoD,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5F,CAAC;IAED,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO;QACvB,CAAC,CAAC;YACE,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS;YAC9B,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE;YAClC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc;SACzC;QACH,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,EAAE;QAClB,QAAQ;QACR,SAAS,EAAE,SAAS,IAAI,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,
|
|
1
|
+
{"version":3,"file":"useChatMessages.js","sourceRoot":"","sources":["../../src/hooks/useChatMessages.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport type { DocumentData } from \"firebase/firestore\";\nimport { toMillis } from \"@ttt-productions/firebase-helpers\";\nimport { useFirestoreLiveInfinite } from \"@ttt-productions/query-core/react\";\nimport type { ChatMessageV1 } from \"@ttt-productions/chat-core\";\nimport type { ChatCoreConfig } from \"../types.js\";\nimport { canAccessThread } from \"./useChatThreadAccess.js\";\nimport { messagesColPath } from \"../firestore/queries.js\";\nimport { useOptionalChatNameResolver } from \"../context/ChatNameResolverContext.js\";\n\n// Safety limit to prevent memory exhaustion\nconst MAX_PAGE_SIZE = 100;\n\nexport type UseChatMessagesResult = {\n allowed: boolean;\n isInitialLoading: boolean;\n messages: ChatMessageV1[];\n fetchOlder: () => Promise<void>;\n hasOlder: boolean;\n isFetchingOlder: boolean;\n};\n\nfunction mapMsg(\n data: DocumentData & { id: string },\n threadId: string\n): ChatMessageV1 {\n const d = data as any;\n\n const createdAt = toMillis(d.createdAt);\n\n if (!createdAt) {\n console.error('[useChatMessages] Message missing valid createdAt:', data.id, d.createdAt);\n }\n\n // replyTo: the new shape uses senderId, not senderUsername. Tolerate older\n // docs that still have senderUsername — drop the name and keep what we can.\n const replyTo = d.replyTo\n ? {\n messageId: d.replyTo.messageId,\n senderId: d.replyTo.senderId ?? \"\",\n messagePreview: d.replyTo.messagePreview,\n }\n : undefined;\n\n return {\n messageId: data.id,\n threadId,\n createdAt: createdAt || 0,\n senderId: d.senderId,\n text: d.text ?? \"\",\n type: d.type,\n replyTo,\n isSystemMessage: d.isSystemMessage ?? undefined,\n // Moderation tombstone flag (backend-written) — carried through so renderers\n // can tombstone the content.\n hidden: d.hidden ?? undefined,\n meta: d.meta,\n };\n}\n\nexport function useChatMessages(config: ChatCoreConfig): UseChatMessagesResult {\n const {\n chatCollectionPath,\n messagesSubcollection = \"messages\",\n threadId,\n pageSize: requestedPageSize = 20,\n currentUserId,\n isAdmin,\n accessMode,\n threadAllowedUserIds,\n createdAtField = \"createdAt\",\n } = config;\n\n const pageSize = Math.min(requestedPageSize, MAX_PAGE_SIZE);\n\n if (requestedPageSize > MAX_PAGE_SIZE) {\n console.warn(\n `[useChatMessages] Requested pageSize ${requestedPageSize} exceeds maximum ${MAX_PAGE_SIZE}. Using ${MAX_PAGE_SIZE}.`\n );\n }\n\n const allowed = React.useMemo(\n () =>\n canAccessThread({\n accessMode,\n isAdmin,\n currentUserId,\n allowedUserIds: threadAllowedUserIds,\n }),\n [accessMode, isAdmin, currentUserId, threadAllowedUserIds]\n );\n\n // Stable key segment for the message collection path (string | string[]).\n const pathKey = React.useMemo(\n () =>\n JSON.stringify(\n Array.isArray(chatCollectionPath) ? chatCollectionPath : [chatCollectionPath]\n ),\n [chatCollectionPath]\n );\n\n // Slash-joined collection path for the generic hook (handles nested paths).\n const collectionPath = React.useMemo(\n () => messagesColPath(chatCollectionPath, threadId, messagesSubcollection).join(\"/\"),\n [chatCollectionPath, threadId, messagesSubcollection]\n );\n\n const { items, isInitialLoading, fetchOlder, hasOlder, isFetchingOlder } =\n useFirestoreLiveInfinite<ChatMessageV1>({\n collectionPath,\n queryKey: [\"chat-core\", \"messages\", pathKey, threadId, messagesSubcollection, pageSize],\n orderByField: createdAtField,\n pageSize,\n enabled: allowed,\n sort: \"asc\",\n select: (data) => mapMsg(data, threadId),\n getSortValue: (data) => toMillis(data.createdAt) ?? 0,\n });\n\n const messages = React.useMemo(() => (allowed ? items : []), [allowed, items]);\n\n // Pre-warm name cache for all visible senders (and reply-to senders).\n // Optional resolver: silent no-op if no provider is wrapped.\n const resolverCtx = useOptionalChatNameResolver();\n const senderIds = React.useMemo(() => {\n const set = new Set<string>();\n for (const m of messages) {\n set.add(m.senderId);\n if (m.replyTo?.senderId) set.add(m.replyTo.senderId);\n }\n return Array.from(set);\n }, [messages]);\n\n React.useEffect(() => {\n if (resolverCtx?.prewarm && senderIds.length > 0) {\n resolverCtx.prewarm(senderIds);\n }\n }, [resolverCtx, senderIds]);\n\n return {\n allowed,\n isInitialLoading: allowed ? isInitialLoading : false,\n messages,\n fetchOlder,\n hasOlder,\n isFetchingOlder,\n };\n}"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
export type { ChatCoreConfig, ChatTransportMode, ChatRealtimeTransportConfig,
|
|
2
|
-
export type { ChatAttachmentUrlResolver, ChatAttachmentUrlProviderProps, } from "./context/ChatAttachmentUrlContext.js";
|
|
3
|
-
export { ChatAttachmentUrlProvider, useChatAttachmentUrlResolver, } from "./context/ChatAttachmentUrlContext.js";
|
|
4
|
-
export type { ChatAttachmentMediaComponent, ChatAttachmentMediaProviderProps, } from "./context/ChatAttachmentMediaContext.js";
|
|
5
|
-
export { ChatAttachmentMediaProvider, useChatAttachmentMediaComponent, } from "./context/ChatAttachmentMediaContext.js";
|
|
1
|
+
export type { ChatCoreConfig, ChatTransportMode, ChatRealtimeTransportConfig, ChatMentionConfig, MessageRenderer, MessageRendererRegistry, RenderableMentionProvider, MentionResultRenderer, } from "./types.js";
|
|
6
2
|
export type { ChatNameResolverProviderProps } from "./context/ChatNameResolverContext.js";
|
|
7
3
|
export { ChatNameResolverProvider, useChatNameResolver, useOptionalChatNameResolver, useResolvedSenderName, } from "./context/ChatNameResolverContext.js";
|
|
8
4
|
export type { UseChatMessagesResult } from "./hooks/useChatMessages.js";
|
|
@@ -13,7 +9,7 @@ export type { RealtimeChatClient, RealtimeTransportConfig, ChatClientDiagnostics
|
|
|
13
9
|
export type { ChatShellProps } from "./ui/ChatShell.js";
|
|
14
10
|
export { ChatShell } from "./ui/ChatShell.js";
|
|
15
11
|
export { MessageList } from "./ui/MessageList.js";
|
|
16
|
-
export type { ComposerProps
|
|
12
|
+
export type { ComposerProps } from "./ui/Composer.js";
|
|
17
13
|
export { Composer } from "./ui/Composer.js";
|
|
18
14
|
export type { MessageItemDefaultProps } from "./ui/MessageItemDefault.js";
|
|
19
15
|
export { MessageItemDefault } from "./ui/MessageItemDefault.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,2BAA2B,EAC3B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,2BAA2B,EAC3B,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAE9C,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKjE,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,6BAA6B,EAC7B,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAU7B,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,YAAY,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,sBAAsB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,wCAAwC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { ChatAttachmentUrlProvider, useChatAttachmentUrlResolver, } from "./context/ChatAttachmentUrlContext.js";
|
|
3
|
-
export { ChatAttachmentMediaProvider, useChatAttachmentMediaComponent, } from "./context/ChatAttachmentMediaContext.js";
|
|
4
2
|
export { ChatNameResolverProvider, useChatNameResolver, useOptionalChatNameResolver, useResolvedSenderName, } from "./context/ChatNameResolverContext.js";
|
|
5
3
|
export { useChatMessages } from "./hooks/useChatMessages.js";
|
|
6
4
|
export { canAccessThread } from "./hooks/useChatThreadAccess.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAsBb,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,+EAA+E;AAC/E,kFAAkF;AAClF,oFAAoF;AACpF,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAkC7B,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAyB,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EACL,mBAAmB,GAEpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,sBAAsB,GAKvB,MAAM,wCAAwC,CAAC","sourcesContent":["\"use client\";\n\n// @ttt-productions/chat-react — chat React UI, hooks, the Firebase-client\n// adapter config types, and React render types. Depends on the pure\n// @ttt-productions/chat-core for contracts, parser, and grouping.\n//\n// Apps import chat CSS via \"@ttt-productions/chat-react/styles\".\n\n// React-coupled config + render types (previously on chat-core root).\nexport type {\n ChatCoreConfig,\n ChatTransportMode,\n ChatRealtimeTransportConfig,\n ChatMentionConfig,\n MessageRenderer,\n MessageRendererRegistry,\n RenderableMentionProvider,\n MentionResultRenderer,\n} from \"./types.js\";\n\n// Name-resolver context.\nexport type { ChatNameResolverProviderProps } from \"./context/ChatNameResolverContext.js\";\nexport {\n ChatNameResolverProvider,\n useChatNameResolver,\n useOptionalChatNameResolver,\n useResolvedSenderName,\n} from \"./context/ChatNameResolverContext.js\";\n\nexport type { UseChatMessagesResult } from \"./hooks/useChatMessages.js\";\nexport { useChatMessages } from \"./hooks/useChatMessages.js\";\nexport { canAccessThread } from \"./hooks/useChatThreadAccess.js\";\n\n// Realtime (Cloudflare Durable Object) transport — the client half of the chat\n// worker wire protocol. Opt-in via `ChatCoreConfig.transport === 'realtime'`; the\n// firestore transport stays the unchanged default. See docs/packages/chat-react.md.\nexport {\n createRealtimeChatClient,\n createInboxClient,\n ChannelClient,\n InboxClient,\n useRealtimeChatMessages,\n browserSocketFactory,\n ChatAccessDeniedError,\n isChatAccessDeniedError,\n CHAT_SUBPROTOCOL,\n CHAT_CLOSE_CODES,\n CLIENT_FRAME,\n SERVER_FRAME,\n buildFrame,\n parseFrame,\n CHAT_CLIENT_DIAGNOSTIC_EVENTS,\n} from \"./realtime/index.js\";\nexport type {\n RealtimeChatClient,\n RealtimeTransportConfig,\n ChatClientDiagnosticsOption,\n ChatClientDiagnosticsSink,\n ChatClientDiagnosticEventName,\n ChannelClientState,\n ChannelClientConfig,\n InboxClientState,\n InboxClientConfig,\n UseRealtimeChatMessagesResult,\n GrantProvider,\n TransportTimers,\n RealtimeStatus,\n RealtimeSocket,\n SocketFactory,\n SocketHandlers,\n ChannelRefTuple,\n WireMessageRow,\n WireInboxSnapshot,\n WireRegistryEntry,\n ServerFrame,\n} from \"./realtime/index.js\";\n\n// TODO (re-export when a consumer needs them): the moderation-overlay helpers\n// `RevisionKind`, `ModerationOverlay`, `applyModerationOverlay`, `overlayFromRow`,\n// and `MODERATION_REDACTED_TEXT` live in `./realtime` but are intentionally NOT\n// re-exported from this package root yet — the consuming app's renderer reads moderation\n// state off `message.meta` (the realtime client applies the overlay internally), so\n// nothing imports them from here today. Add them to the block above when a consumer\n// genuinely needs to apply the overlay directly. (Comment-only; rides the next publish.)\n\nexport type { ChatShellProps } from \"./ui/ChatShell.js\";\nexport { ChatShell } from \"./ui/ChatShell.js\";\nexport { MessageList } from \"./ui/MessageList.js\";\nexport type { ComposerProps } from \"./ui/Composer.js\";\nexport { Composer } from \"./ui/Composer.js\";\nexport type { MessageItemDefaultProps } from \"./ui/MessageItemDefault.js\";\nexport { MessageItemDefault } from \"./ui/MessageItemDefault.js\";\nexport { MessageActions, ThreadActions } from \"./ui/menus.js\";\nexport { MessageText, type MessageTextProps } from \"./mentions/MessageText.js\";\nexport {\n MentionAutocomplete,\n type MentionAutocompleteProps,\n} from \"./mentions/MentionAutocomplete.js\";\nexport {\n useMentionAutocomplete,\n type UseMentionAutocompleteArgs,\n type UseMentionAutocompleteResult,\n type AutocompleteState,\n type AutocompleteResultGroup,\n} from \"./mentions/use-mention-autocomplete.js\";\n"]}
|
|
@@ -246,17 +246,15 @@ export declare class ChannelClient {
|
|
|
246
246
|
* the decision the client made about it.
|
|
247
247
|
*
|
|
248
248
|
* Diagnostics bounding: a LIVE frame always emits one `chat_client_frame_applied`
|
|
249
|
-
* line; a DELTA row emits one only when it is materially interesting (carries
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* source, because an in-place attachment mutation is the exact event this
|
|
254
|
-
* instrumentation exists to prove.
|
|
249
|
+
* line; a DELTA row emits one only when it is materially interesting (carries a
|
|
250
|
+
* moderation kind, or reconciles one of our optimistic sends) — a 500-row backlog
|
|
251
|
+
* is otherwise summarized by `chat_client_resume_result` rather than spamming 500
|
|
252
|
+
* lines.
|
|
255
253
|
*/
|
|
256
254
|
private applyMessage;
|
|
257
255
|
/**
|
|
258
|
-
* The pre-merge view of a row's seq: whether we already hold that seq,
|
|
259
|
-
*
|
|
256
|
+
* The pre-merge view of a row's seq: whether we already hold that seq, and whether
|
|
257
|
+
* this row reconciles a live optimistic send.
|
|
260
258
|
* Diagnostics-only — never called when diagnostics are off.
|
|
261
259
|
*/
|
|
262
260
|
private priorRowFacts;
|
|
@@ -268,11 +266,6 @@ export declare class ChannelClient {
|
|
|
268
266
|
private mergeMessage;
|
|
269
267
|
private applyAck;
|
|
270
268
|
private applyHistoryPage;
|
|
271
|
-
/**
|
|
272
|
-
* A seq -> attachmentState map of the rows currently held (diagnostics-only, so a
|
|
273
|
-
* later in-place mutation can be reported as an explicit `old -> new` transition).
|
|
274
|
-
*/
|
|
275
|
-
private snapshotAttachmentStates;
|
|
276
269
|
private applyTyping;
|
|
277
270
|
private sendFrame;
|
|
278
271
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-client.d.ts","sourceRoot":"","sources":["../../src/realtime/channel-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"channel-client.d.ts","sourceRoot":"","sources":["../../src/realtime/channel-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -807,12 +807,10 @@ export class ChannelClient {
|
|
|
807
807
|
* the decision the client made about it.
|
|
808
808
|
*
|
|
809
809
|
* Diagnostics bounding: a LIVE frame always emits one `chat_client_frame_applied`
|
|
810
|
-
* line; a DELTA row emits one only when it is materially interesting (carries
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
* source, because an in-place attachment mutation is the exact event this
|
|
815
|
-
* instrumentation exists to prove.
|
|
810
|
+
* line; a DELTA row emits one only when it is materially interesting (carries a
|
|
811
|
+
* moderation kind, or reconciles one of our optimistic sends) — a 500-row backlog
|
|
812
|
+
* is otherwise summarized by `chat_client_resume_result` rather than spamming 500
|
|
813
|
+
* lines.
|
|
816
814
|
*/
|
|
817
815
|
applyMessage(row, source) {
|
|
818
816
|
if (!row || typeof row.seq !== 'number') {
|
|
@@ -828,18 +826,7 @@ export class ChannelClient {
|
|
|
828
826
|
this.resumeSeq = row.seq;
|
|
829
827
|
if (!this.diag || !prior)
|
|
830
828
|
return;
|
|
831
|
-
const
|
|
832
|
-
// Emit a transition for a real change only: first arrival of an attachment row
|
|
833
|
-
// (null -> pending) and every later in-place mutation (pending -> ready/failed).
|
|
834
|
-
if (attachmentState !== prior.attachmentState && (attachmentState != null || prior.hadRow)) {
|
|
835
|
-
this.diag(DIAG.ATTACHMENT_TRANSITION, {
|
|
836
|
-
seq: row.seq,
|
|
837
|
-
from: prior.attachmentState,
|
|
838
|
-
to: attachmentState,
|
|
839
|
-
source,
|
|
840
|
-
});
|
|
841
|
-
}
|
|
842
|
-
const notable = attachmentState != null || row.moderationKind != null || prior.reconciledOptimistic;
|
|
829
|
+
const notable = row.moderationKind != null || prior.reconciledOptimistic;
|
|
843
830
|
if (source === 'delta' && !notable)
|
|
844
831
|
return;
|
|
845
832
|
this.diag(DIAG.FRAME_APPLIED, {
|
|
@@ -847,7 +834,6 @@ export class ChannelClient {
|
|
|
847
834
|
source,
|
|
848
835
|
seq: row.seq,
|
|
849
836
|
hasClientMessageId: Boolean(row.clientMessageId),
|
|
850
|
-
attachmentState,
|
|
851
837
|
moderationKind: row.moderationKind ?? null,
|
|
852
838
|
op: prior.reconciledOptimistic ? 'optimistic-reconcile' : prior.hadRow ? 'replace-by-seq' : 'insert',
|
|
853
839
|
cursorBefore,
|
|
@@ -855,17 +841,15 @@ export class ChannelClient {
|
|
|
855
841
|
});
|
|
856
842
|
}
|
|
857
843
|
/**
|
|
858
|
-
* The pre-merge view of a row's seq: whether we already hold that seq,
|
|
859
|
-
*
|
|
844
|
+
* The pre-merge view of a row's seq: whether we already hold that seq, and whether
|
|
845
|
+
* this row reconciles a live optimistic send.
|
|
860
846
|
* Diagnostics-only — never called when diagnostics are off.
|
|
861
847
|
*/
|
|
862
848
|
priorRowFacts(row) {
|
|
863
849
|
const messageId = seqToMessageId(row.seq);
|
|
864
850
|
const existing = this.state.messages.find((m) => m.messageId === messageId);
|
|
865
|
-
const raw = existing?.meta?.attachmentState;
|
|
866
851
|
return {
|
|
867
852
|
hadRow: existing != null,
|
|
868
|
-
attachmentState: typeof raw === 'string' ? raw : null,
|
|
869
853
|
reconciledOptimistic: Boolean(row.clientMessageId &&
|
|
870
854
|
this.state.messages.some((m) => m.meta?.optimistic && m.meta?.clientMessageId === row.clientMessageId)),
|
|
871
855
|
};
|
|
@@ -923,11 +907,6 @@ export class ChannelClient {
|
|
|
923
907
|
}
|
|
924
908
|
applyHistoryPage(rows) {
|
|
925
909
|
const cursorBefore = this.resumeSeq;
|
|
926
|
-
// Pre-page attachment states for the seqs we already hold — a history page that
|
|
927
|
-
// carries a DIFFERENT state for a row we already rendered is an in-place mutation
|
|
928
|
-
// the client learned about by re-fetching, which is exactly the reveal path under
|
|
929
|
-
// investigation. Diagnostics-only, so only built when they are on.
|
|
930
|
-
const priorAttachment = this.diag ? this.snapshotAttachmentStates() : null;
|
|
931
910
|
const mapped = rows.map((r) => this.renderRow(r));
|
|
932
911
|
// Mirror mergeMessage's optimistic reconciliation: a history row carrying a
|
|
933
912
|
// clientMessageId we still hold as an optimistic placeholder IS that send (the
|
|
@@ -965,19 +944,6 @@ export class ChannelClient {
|
|
|
965
944
|
});
|
|
966
945
|
if (!this.diag)
|
|
967
946
|
return;
|
|
968
|
-
if (priorAttachment) {
|
|
969
|
-
for (const r of rows) {
|
|
970
|
-
if (typeof r.seq !== 'number')
|
|
971
|
-
continue;
|
|
972
|
-
const before = priorAttachment.get(r.seq);
|
|
973
|
-
if (before === undefined)
|
|
974
|
-
continue; // a row we did not hold — not a transition
|
|
975
|
-
const after = typeof r.attachmentState === 'string' ? r.attachmentState : null;
|
|
976
|
-
if (before !== after) {
|
|
977
|
-
this.diag(DIAG.ATTACHMENT_TRANSITION, { seq: r.seq, from: before, to: after, source: 'history' });
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
947
|
const seqs = rows.map((r) => r.seq).filter((s) => typeof s === 'number');
|
|
982
948
|
this.diag(DIAG.HISTORY_PAGE, {
|
|
983
949
|
count: rows.length,
|
|
@@ -990,21 +956,6 @@ export class ChannelClient {
|
|
|
990
956
|
total: merged.length,
|
|
991
957
|
});
|
|
992
958
|
}
|
|
993
|
-
/**
|
|
994
|
-
* A seq -> attachmentState map of the rows currently held (diagnostics-only, so a
|
|
995
|
-
* later in-place mutation can be reported as an explicit `old -> new` transition).
|
|
996
|
-
*/
|
|
997
|
-
snapshotAttachmentStates() {
|
|
998
|
-
const out = new Map();
|
|
999
|
-
for (const m of this.state.messages) {
|
|
1000
|
-
const seq = m.meta?.seq;
|
|
1001
|
-
if (typeof seq !== 'number')
|
|
1002
|
-
continue;
|
|
1003
|
-
const raw = m.meta?.attachmentState;
|
|
1004
|
-
out.set(seq, typeof raw === 'string' ? raw : null);
|
|
1005
|
-
}
|
|
1006
|
-
return out;
|
|
1007
|
-
}
|
|
1008
959
|
applyTyping(uid) {
|
|
1009
960
|
if (!uid || uid === this.config.currentUserId)
|
|
1010
961
|
return;
|