@ai-matrx/messaging 0.10.5 → 0.11.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/CHANGELOG.md +51 -0
- package/README.md +33 -0
- package/dist/index.cjs +98 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -1
- package/dist/index.d.ts +101 -1
- package/dist/index.js +98 -11
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +145 -14
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +126 -1
- package/dist/react.d.ts +126 -1
- package/dist/react.js +145 -14
- package/dist/react.js.map +1 -1
- package/dist/styles.css +7 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -137,6 +137,39 @@ interface Message {
|
|
|
137
137
|
/** Set only while this message is in the outbox and its last send failed. */
|
|
138
138
|
readonly failureReason?: string | undefined;
|
|
139
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* THE ARCHIVED-ITEMS LAW's three states (Arman, 2026-09-09 —
|
|
142
|
+
* `common-docs/policies/archived-items.md`):
|
|
143
|
+
*
|
|
144
|
+
* > "everything should have an archive filter, and the default should always
|
|
145
|
+
* > hide archived, but seeing archived items should be one or two clicks
|
|
146
|
+
* > away … this is a system wide decision for every single item everywhere in
|
|
147
|
+
* > our system, for every single table and every single page."
|
|
148
|
+
*
|
|
149
|
+
* | value | what the list shows |
|
|
150
|
+
* |------------|--------------------------|
|
|
151
|
+
* | `active` | only un-archived rows |
|
|
152
|
+
* | `archived` | only archived rows |
|
|
153
|
+
* | `all` | every row |
|
|
154
|
+
*
|
|
155
|
+
* The same three words the rest of the platform uses — `ArchivedFilter` in
|
|
156
|
+
* matrx-frontend's `lib/entity-list`, `p_archived` on the `agx_*`/`wfx_*` and
|
|
157
|
+
* DM list RPCs, `ArchiveFilter` in `@ai-matrx/design-system`. A person meets
|
|
158
|
+
* ONE control, not one per app.
|
|
159
|
+
*
|
|
160
|
+
* 🚨 Three states, never a boolean. A boolean cannot say "archived only",
|
|
161
|
+
* which is exactly the view someone looking for a conversation they archived
|
|
162
|
+
* last month needs.
|
|
163
|
+
*/
|
|
164
|
+
type MessagingArchiveFilter = "active" | "archived" | "all";
|
|
165
|
+
/** The platform default: a list hides archived rows until asked. */
|
|
166
|
+
declare const DEFAULT_MESSAGING_ARCHIVE_FILTER: MessagingArchiveFilter;
|
|
167
|
+
/**
|
|
168
|
+
* Narrow an untrusted value (a stored preference, a URL param, a host knob) to
|
|
169
|
+
* the tri-state. Anything unrecognised falls back to the default rather than
|
|
170
|
+
* silently widening a list to archived conversations.
|
|
171
|
+
*/
|
|
172
|
+
declare function toMessagingArchiveFilter(value: unknown, fallback?: MessagingArchiveFilter): MessagingArchiveFilter;
|
|
140
173
|
interface ConversationSummary {
|
|
141
174
|
readonly conversation: Conversation;
|
|
142
175
|
readonly participants: readonly UserSummary[];
|
|
@@ -770,7 +803,30 @@ interface MessagingRepository {
|
|
|
770
803
|
listConversations(args?: {
|
|
771
804
|
limit?: number;
|
|
772
805
|
cursor?: ConversationCursor | null;
|
|
806
|
+
/**
|
|
807
|
+
* THE ARCHIVED-ITEMS LAW. Omitted means `active` — archived conversations
|
|
808
|
+
* are hidden until a caller asks for them. This is a REQUEST to the reader
|
|
809
|
+
* (the RPC's `p_archived`), never a client-side sieve, so `hasMore` and the
|
|
810
|
+
* cursor describe the rows the caller actually asked for.
|
|
811
|
+
*/
|
|
812
|
+
archived?: MessagingArchiveFilter;
|
|
773
813
|
}): Promise<Page<ConversationSummary, ConversationCursor>>;
|
|
814
|
+
/**
|
|
815
|
+
* How many ARCHIVED conversations the caller has — the number a reveal
|
|
816
|
+
* control prints ("Archived (12)").
|
|
817
|
+
*
|
|
818
|
+
* 🚨 It is capped, and it says so. A count is read by listing archived rows
|
|
819
|
+
* up to `limit`; if that many come back the result is `exact: false` and the
|
|
820
|
+
* UI must render "12+", never a confident "12". A screen never lies: a cap
|
|
821
|
+
* silently presented as a total is the same defect as a badge counting rows
|
|
822
|
+
* the list hides.
|
|
823
|
+
*/
|
|
824
|
+
countArchivedConversations(args?: {
|
|
825
|
+
limit?: number;
|
|
826
|
+
}): Promise<{
|
|
827
|
+
count: number;
|
|
828
|
+
exact: boolean;
|
|
829
|
+
}>;
|
|
774
830
|
getConversation(id: ConversationId): Promise<Conversation>;
|
|
775
831
|
listMessages(conversationId: ConversationId, args?: {
|
|
776
832
|
limit?: number;
|
|
@@ -857,11 +913,38 @@ interface MessagingSnapshot {
|
|
|
857
913
|
readonly activeConversationId: ConversationId | null;
|
|
858
914
|
/** Conversations WITH unread, not total unread messages (the origin's semantics). */
|
|
859
915
|
readonly totalUnreadConversations: number;
|
|
916
|
+
/**
|
|
917
|
+
* THE ARCHIVED-ITEMS LAW's state for this inbox. `conversations` above is
|
|
918
|
+
* ALWAYS the rows this filter asked the server for — never a superset a
|
|
919
|
+
* surface is expected to sieve, so counts and pagination cannot disagree
|
|
920
|
+
* with what renders.
|
|
921
|
+
*/
|
|
922
|
+
readonly archiveFilter: MessagingArchiveFilter;
|
|
923
|
+
/**
|
|
924
|
+
* How many archived conversations exist, for the reveal control's label, or
|
|
925
|
+
* `null` before the first count lands. `exact: false` means the count hit its
|
|
926
|
+
* cap and the label must read "N+" — a capped number shown as a total is the
|
|
927
|
+
* same lie as a badge counting hidden rows.
|
|
928
|
+
*/
|
|
929
|
+
readonly archivedCount: {
|
|
930
|
+
readonly count: number;
|
|
931
|
+
readonly exact: boolean;
|
|
932
|
+
} | null;
|
|
860
933
|
}
|
|
861
934
|
interface MessagingStore {
|
|
862
935
|
snapshot(): MessagingSnapshot;
|
|
863
936
|
subscribe(listener: (snapshot: MessagingSnapshot) => void): () => void;
|
|
864
937
|
setConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
|
|
938
|
+
/**
|
|
939
|
+
* Switch the archive axis. Clears the list and marks it UNLOADED: the rows
|
|
940
|
+
* on screen belong to the old filter, and leaving them there while the new
|
|
941
|
+
* page is in flight shows active conversations under an "Archived" heading.
|
|
942
|
+
*/
|
|
943
|
+
setArchiveFilter(next: MessagingArchiveFilter): void;
|
|
944
|
+
setArchivedCount(value: {
|
|
945
|
+
count: number;
|
|
946
|
+
exact: boolean;
|
|
947
|
+
} | null): void;
|
|
865
948
|
appendConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
|
|
866
949
|
upsertConversation(item: ConversationSummary): void;
|
|
867
950
|
removeConversation(id: ConversationId): void;
|
|
@@ -936,6 +1019,15 @@ interface MessagingEngineOptions {
|
|
|
936
1019
|
onIncoming?: ((message: Message) => void) | undefined;
|
|
937
1020
|
conversationPageSize?: number | undefined;
|
|
938
1021
|
messagePageSize?: number | undefined;
|
|
1022
|
+
/**
|
|
1023
|
+
* 🚨 OPINIONS BECOME KNOBS. THE ARCHIVED-ITEMS LAW's clause 6 says the
|
|
1024
|
+
* filter's initial state is an org/user-configurable setting, not code
|
|
1025
|
+
* taste. The PLATFORM default is `active` (hide archived) and a host that
|
|
1026
|
+
* passes nothing gets exactly that; a host wires this to whatever its own
|
|
1027
|
+
* setting resolves to. The person can always change it from the control on
|
|
1028
|
+
* the list.
|
|
1029
|
+
*/
|
|
1030
|
+
archiveFilter?: MessagingArchiveFilter | undefined;
|
|
939
1031
|
}
|
|
940
1032
|
interface MessagingEngine {
|
|
941
1033
|
readonly store: MessagingStore;
|
|
@@ -944,6 +1036,14 @@ interface MessagingEngine {
|
|
|
944
1036
|
/** Load page one of the inbox and start the inbox channel. */
|
|
945
1037
|
start(): Promise<void>;
|
|
946
1038
|
loadMoreConversations(): Promise<void>;
|
|
1039
|
+
/**
|
|
1040
|
+
* THE ARCHIVED-ITEMS LAW's control. Re-reads page one under the new state
|
|
1041
|
+
* (the filter is a REQUEST to the server, never a client-side sieve) and
|
|
1042
|
+
* refreshes the archived count the reveal label prints.
|
|
1043
|
+
*/
|
|
1044
|
+
setArchiveFilter(next: MessagingArchiveFilter): Promise<void>;
|
|
1045
|
+
/** Re-read how many archived conversations exist, for the reveal's label. */
|
|
1046
|
+
refreshArchivedCount(): Promise<void>;
|
|
947
1047
|
/** Open a conversation: load its thread and subscribe to its channel. */
|
|
948
1048
|
openConversation(id: ConversationId): Promise<void>;
|
|
949
1049
|
closeConversation(id: ConversationId): void;
|
|
@@ -1119,4 +1219,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1119
1219
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1120
1220
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1121
1221
|
|
|
1122
|
-
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, unreadCutoff };
|
|
1222
|
+
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, DEFAULT_MESSAGING_ARCHIVE_FILTER, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingArchiveFilter, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff };
|
package/dist/index.d.ts
CHANGED
|
@@ -137,6 +137,39 @@ interface Message {
|
|
|
137
137
|
/** Set only while this message is in the outbox and its last send failed. */
|
|
138
138
|
readonly failureReason?: string | undefined;
|
|
139
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* THE ARCHIVED-ITEMS LAW's three states (Arman, 2026-09-09 —
|
|
142
|
+
* `common-docs/policies/archived-items.md`):
|
|
143
|
+
*
|
|
144
|
+
* > "everything should have an archive filter, and the default should always
|
|
145
|
+
* > hide archived, but seeing archived items should be one or two clicks
|
|
146
|
+
* > away … this is a system wide decision for every single item everywhere in
|
|
147
|
+
* > our system, for every single table and every single page."
|
|
148
|
+
*
|
|
149
|
+
* | value | what the list shows |
|
|
150
|
+
* |------------|--------------------------|
|
|
151
|
+
* | `active` | only un-archived rows |
|
|
152
|
+
* | `archived` | only archived rows |
|
|
153
|
+
* | `all` | every row |
|
|
154
|
+
*
|
|
155
|
+
* The same three words the rest of the platform uses — `ArchivedFilter` in
|
|
156
|
+
* matrx-frontend's `lib/entity-list`, `p_archived` on the `agx_*`/`wfx_*` and
|
|
157
|
+
* DM list RPCs, `ArchiveFilter` in `@ai-matrx/design-system`. A person meets
|
|
158
|
+
* ONE control, not one per app.
|
|
159
|
+
*
|
|
160
|
+
* 🚨 Three states, never a boolean. A boolean cannot say "archived only",
|
|
161
|
+
* which is exactly the view someone looking for a conversation they archived
|
|
162
|
+
* last month needs.
|
|
163
|
+
*/
|
|
164
|
+
type MessagingArchiveFilter = "active" | "archived" | "all";
|
|
165
|
+
/** The platform default: a list hides archived rows until asked. */
|
|
166
|
+
declare const DEFAULT_MESSAGING_ARCHIVE_FILTER: MessagingArchiveFilter;
|
|
167
|
+
/**
|
|
168
|
+
* Narrow an untrusted value (a stored preference, a URL param, a host knob) to
|
|
169
|
+
* the tri-state. Anything unrecognised falls back to the default rather than
|
|
170
|
+
* silently widening a list to archived conversations.
|
|
171
|
+
*/
|
|
172
|
+
declare function toMessagingArchiveFilter(value: unknown, fallback?: MessagingArchiveFilter): MessagingArchiveFilter;
|
|
140
173
|
interface ConversationSummary {
|
|
141
174
|
readonly conversation: Conversation;
|
|
142
175
|
readonly participants: readonly UserSummary[];
|
|
@@ -770,7 +803,30 @@ interface MessagingRepository {
|
|
|
770
803
|
listConversations(args?: {
|
|
771
804
|
limit?: number;
|
|
772
805
|
cursor?: ConversationCursor | null;
|
|
806
|
+
/**
|
|
807
|
+
* THE ARCHIVED-ITEMS LAW. Omitted means `active` — archived conversations
|
|
808
|
+
* are hidden until a caller asks for them. This is a REQUEST to the reader
|
|
809
|
+
* (the RPC's `p_archived`), never a client-side sieve, so `hasMore` and the
|
|
810
|
+
* cursor describe the rows the caller actually asked for.
|
|
811
|
+
*/
|
|
812
|
+
archived?: MessagingArchiveFilter;
|
|
773
813
|
}): Promise<Page<ConversationSummary, ConversationCursor>>;
|
|
814
|
+
/**
|
|
815
|
+
* How many ARCHIVED conversations the caller has — the number a reveal
|
|
816
|
+
* control prints ("Archived (12)").
|
|
817
|
+
*
|
|
818
|
+
* 🚨 It is capped, and it says so. A count is read by listing archived rows
|
|
819
|
+
* up to `limit`; if that many come back the result is `exact: false` and the
|
|
820
|
+
* UI must render "12+", never a confident "12". A screen never lies: a cap
|
|
821
|
+
* silently presented as a total is the same defect as a badge counting rows
|
|
822
|
+
* the list hides.
|
|
823
|
+
*/
|
|
824
|
+
countArchivedConversations(args?: {
|
|
825
|
+
limit?: number;
|
|
826
|
+
}): Promise<{
|
|
827
|
+
count: number;
|
|
828
|
+
exact: boolean;
|
|
829
|
+
}>;
|
|
774
830
|
getConversation(id: ConversationId): Promise<Conversation>;
|
|
775
831
|
listMessages(conversationId: ConversationId, args?: {
|
|
776
832
|
limit?: number;
|
|
@@ -857,11 +913,38 @@ interface MessagingSnapshot {
|
|
|
857
913
|
readonly activeConversationId: ConversationId | null;
|
|
858
914
|
/** Conversations WITH unread, not total unread messages (the origin's semantics). */
|
|
859
915
|
readonly totalUnreadConversations: number;
|
|
916
|
+
/**
|
|
917
|
+
* THE ARCHIVED-ITEMS LAW's state for this inbox. `conversations` above is
|
|
918
|
+
* ALWAYS the rows this filter asked the server for — never a superset a
|
|
919
|
+
* surface is expected to sieve, so counts and pagination cannot disagree
|
|
920
|
+
* with what renders.
|
|
921
|
+
*/
|
|
922
|
+
readonly archiveFilter: MessagingArchiveFilter;
|
|
923
|
+
/**
|
|
924
|
+
* How many archived conversations exist, for the reveal control's label, or
|
|
925
|
+
* `null` before the first count lands. `exact: false` means the count hit its
|
|
926
|
+
* cap and the label must read "N+" — a capped number shown as a total is the
|
|
927
|
+
* same lie as a badge counting hidden rows.
|
|
928
|
+
*/
|
|
929
|
+
readonly archivedCount: {
|
|
930
|
+
readonly count: number;
|
|
931
|
+
readonly exact: boolean;
|
|
932
|
+
} | null;
|
|
860
933
|
}
|
|
861
934
|
interface MessagingStore {
|
|
862
935
|
snapshot(): MessagingSnapshot;
|
|
863
936
|
subscribe(listener: (snapshot: MessagingSnapshot) => void): () => void;
|
|
864
937
|
setConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
|
|
938
|
+
/**
|
|
939
|
+
* Switch the archive axis. Clears the list and marks it UNLOADED: the rows
|
|
940
|
+
* on screen belong to the old filter, and leaving them there while the new
|
|
941
|
+
* page is in flight shows active conversations under an "Archived" heading.
|
|
942
|
+
*/
|
|
943
|
+
setArchiveFilter(next: MessagingArchiveFilter): void;
|
|
944
|
+
setArchivedCount(value: {
|
|
945
|
+
count: number;
|
|
946
|
+
exact: boolean;
|
|
947
|
+
} | null): void;
|
|
865
948
|
appendConversations(items: readonly ConversationSummary[], hasMore: boolean): void;
|
|
866
949
|
upsertConversation(item: ConversationSummary): void;
|
|
867
950
|
removeConversation(id: ConversationId): void;
|
|
@@ -936,6 +1019,15 @@ interface MessagingEngineOptions {
|
|
|
936
1019
|
onIncoming?: ((message: Message) => void) | undefined;
|
|
937
1020
|
conversationPageSize?: number | undefined;
|
|
938
1021
|
messagePageSize?: number | undefined;
|
|
1022
|
+
/**
|
|
1023
|
+
* 🚨 OPINIONS BECOME KNOBS. THE ARCHIVED-ITEMS LAW's clause 6 says the
|
|
1024
|
+
* filter's initial state is an org/user-configurable setting, not code
|
|
1025
|
+
* taste. The PLATFORM default is `active` (hide archived) and a host that
|
|
1026
|
+
* passes nothing gets exactly that; a host wires this to whatever its own
|
|
1027
|
+
* setting resolves to. The person can always change it from the control on
|
|
1028
|
+
* the list.
|
|
1029
|
+
*/
|
|
1030
|
+
archiveFilter?: MessagingArchiveFilter | undefined;
|
|
939
1031
|
}
|
|
940
1032
|
interface MessagingEngine {
|
|
941
1033
|
readonly store: MessagingStore;
|
|
@@ -944,6 +1036,14 @@ interface MessagingEngine {
|
|
|
944
1036
|
/** Load page one of the inbox and start the inbox channel. */
|
|
945
1037
|
start(): Promise<void>;
|
|
946
1038
|
loadMoreConversations(): Promise<void>;
|
|
1039
|
+
/**
|
|
1040
|
+
* THE ARCHIVED-ITEMS LAW's control. Re-reads page one under the new state
|
|
1041
|
+
* (the filter is a REQUEST to the server, never a client-side sieve) and
|
|
1042
|
+
* refreshes the archived count the reveal label prints.
|
|
1043
|
+
*/
|
|
1044
|
+
setArchiveFilter(next: MessagingArchiveFilter): Promise<void>;
|
|
1045
|
+
/** Re-read how many archived conversations exist, for the reveal's label. */
|
|
1046
|
+
refreshArchivedCount(): Promise<void>;
|
|
947
1047
|
/** Open a conversation: load its thread and subscribe to its channel. */
|
|
948
1048
|
openConversation(id: ConversationId): Promise<void>;
|
|
949
1049
|
closeConversation(id: ConversationId): void;
|
|
@@ -1119,4 +1219,4 @@ declare function summarizeText(content: string, maxLength?: number): string;
|
|
|
1119
1219
|
/** Serialize picked references into a fence the platform's other readers accept. */
|
|
1120
1220
|
declare function composeFence(references: readonly MatrxReference[]): string;
|
|
1121
1221
|
|
|
1122
|
-
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, unreadCutoff };
|
|
1222
|
+
export { type ActionChoice, type ActionContext, type ActionHandler, type ActionOutcome, type ActionReceipt, type ActionRegistry, type ActorPresentation, type AiCallArgs, type AiCapability, type AiResult, type Attachment, type ClientMessageId, type Conversation, type ConversationCursor, type ConversationId, type ConversationSummary, type ConversationThread, type ConversationType, DEFAULT_MESSAGING_ARCHIVE_FILTER, type DeliveryState, type DraftMessage, type EngineDiagnostic, type JsonObject, type JsonValue, MESSAGING_EVENTS, MESSAGING_RPC_SCHEMA, MESSAGING_SCHEMA, type MatrxReference, type Message, type MessageAction, type MessageCursor, type MessageGroup, type MessageId, type MessageKind, type MessagingAgentIdentity, type MessagingAgents, type MessagingAi, type MessagingAiOptions, type MessagingArchiveFilter, type MessagingEngine, type MessagingEngineOptions, MessagingError, type MessagingErrorCode, type MessagingIdentity, type MessagingRepository, type MessagingSnapshot, type MessagingStore, type MessagingSupabaseClient, type MessagingSupabaseInternal, type OrganizationId, type Outbox, type OutboxEntry, type OutboxOptions, type OutboxStorage, type Page, type Participant, type ParticipantRole, type PostgrestFilterLike, type PostgrestLikeResponse, type PostgrestTableLike, RPCS, type ReadCache, type ReadCacheOptions, type RepositoryOptions, type SchemaLike, type SessionResolver, type SupabaseLike, TABLES, type TextSegment, type UserId, type UserSummary, asClientMessageId, asConversationId, asMessageId, asOrganizationId, asUserId, composeFence, conversationTopic, createActionRegistry, createMemoryOutboxStorage, createMessagingAi, createMessagingEngine, createMessagingRepository, createMessagingStore, createOutbox, createReadCache, createWebOutboxStorage, effectiveActorKey, extractReferences, formatConversationTime, formatDateSeparator, formatLastSeen, formatMessageTime, formatTypists, groupMessages, inboxTopic, invalidResponse, isSameDay, messagingClientId, normalizeMessagingError, optimisticMessage, participantNames, projectConversationSummary, projectMessage, projectMessageAction, projectParticipantRole, projectUserSummary, resolveActor, splitText, summarizeText, toMessagingArchiveFilter, unreadCutoff };
|
package/dist/index.js
CHANGED
|
@@ -920,6 +920,17 @@ function projectConversationSummary(row, viewerId, fallbackOrganizationId) {
|
|
|
920
920
|
};
|
|
921
921
|
}
|
|
922
922
|
|
|
923
|
+
// src/core/types.ts
|
|
924
|
+
var asConversationId = (value) => value;
|
|
925
|
+
var asMessageId = (value) => value;
|
|
926
|
+
var asUserId = (value) => value;
|
|
927
|
+
var asOrganizationId = (value) => value;
|
|
928
|
+
var asClientMessageId = (value) => value;
|
|
929
|
+
var DEFAULT_MESSAGING_ARCHIVE_FILTER = "active";
|
|
930
|
+
function toMessagingArchiveFilter(value, fallback = DEFAULT_MESSAGING_ARCHIVE_FILTER) {
|
|
931
|
+
return value === "active" || value === "archived" || value === "all" ? value : fallback;
|
|
932
|
+
}
|
|
933
|
+
|
|
923
934
|
// src/core/store.ts
|
|
924
935
|
function timeOf(message) {
|
|
925
936
|
const stamp = message.editedAt ?? message.createdAt;
|
|
@@ -950,6 +961,8 @@ function createMessagingStore() {
|
|
|
950
961
|
let conversations = [];
|
|
951
962
|
let hasMoreConversations = false;
|
|
952
963
|
let hasLoadedConversations = false;
|
|
964
|
+
let archiveFilter = DEFAULT_MESSAGING_ARCHIVE_FILTER;
|
|
965
|
+
let archivedCount = null;
|
|
953
966
|
let threads = /* @__PURE__ */ new Map();
|
|
954
967
|
let activeConversationId = null;
|
|
955
968
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -962,7 +975,9 @@ function createMessagingStore() {
|
|
|
962
975
|
hasLoadedConversations,
|
|
963
976
|
threads,
|
|
964
977
|
activeConversationId,
|
|
965
|
-
totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length
|
|
978
|
+
totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length,
|
|
979
|
+
archiveFilter,
|
|
980
|
+
archivedCount
|
|
966
981
|
};
|
|
967
982
|
return cached;
|
|
968
983
|
}
|
|
@@ -1009,6 +1024,18 @@ function createMessagingStore() {
|
|
|
1009
1024
|
hasLoadedConversations = true;
|
|
1010
1025
|
emit();
|
|
1011
1026
|
},
|
|
1027
|
+
setArchiveFilter(next) {
|
|
1028
|
+
if (next === archiveFilter) return;
|
|
1029
|
+
archiveFilter = next;
|
|
1030
|
+
conversations = [];
|
|
1031
|
+
hasMoreConversations = false;
|
|
1032
|
+
hasLoadedConversations = false;
|
|
1033
|
+
emit();
|
|
1034
|
+
},
|
|
1035
|
+
setArchivedCount(value) {
|
|
1036
|
+
archivedCount = value;
|
|
1037
|
+
emit();
|
|
1038
|
+
},
|
|
1012
1039
|
appendConversations(items, hasMore) {
|
|
1013
1040
|
const byId = new Map(conversations.map((item) => [item.conversation.id, item]));
|
|
1014
1041
|
items.forEach((item) => byId.set(item.conversation.id, item));
|
|
@@ -1215,11 +1242,20 @@ function createMessagingEngine(options) {
|
|
|
1215
1242
|
}
|
|
1216
1243
|
async function reloadInbox() {
|
|
1217
1244
|
if (disposed) return;
|
|
1218
|
-
const page = await repository.listConversations({
|
|
1245
|
+
const page = await repository.listConversations({
|
|
1246
|
+
limit: conversationPageSize,
|
|
1247
|
+
archived: store.snapshot().archiveFilter
|
|
1248
|
+
});
|
|
1219
1249
|
if (disposed) return;
|
|
1220
1250
|
conversationCursor = page.nextCursor;
|
|
1221
1251
|
store.setConversations(page.items, page.hasMore);
|
|
1222
1252
|
}
|
|
1253
|
+
async function reloadArchivedCount() {
|
|
1254
|
+
if (disposed) return;
|
|
1255
|
+
const value = await repository.countArchivedConversations();
|
|
1256
|
+
if (disposed) return;
|
|
1257
|
+
store.setArchivedCount(value);
|
|
1258
|
+
}
|
|
1223
1259
|
async function backfillConversation(id) {
|
|
1224
1260
|
const thread = store.snapshot().threads.get(id);
|
|
1225
1261
|
const since = thread?.latestAt ?? null;
|
|
@@ -1246,7 +1282,13 @@ function createMessagingEngine(options) {
|
|
|
1246
1282
|
outbox,
|
|
1247
1283
|
identity,
|
|
1248
1284
|
async start() {
|
|
1285
|
+
if (options.archiveFilter !== void 0) {
|
|
1286
|
+
store.setArchiveFilter(options.archiveFilter);
|
|
1287
|
+
}
|
|
1249
1288
|
await reloadInbox();
|
|
1289
|
+
void reloadArchivedCount().catch(
|
|
1290
|
+
(error) => reportError(error, "refreshArchivedCount")
|
|
1291
|
+
);
|
|
1250
1292
|
if (disposed || inboxChannel !== null) return;
|
|
1251
1293
|
inboxChannel = manager.open({
|
|
1252
1294
|
topic: inboxTopic(identity.userId),
|
|
@@ -1288,12 +1330,33 @@ function createMessagingEngine(options) {
|
|
|
1288
1330
|
}
|
|
1289
1331
|
});
|
|
1290
1332
|
},
|
|
1333
|
+
async setArchiveFilter(next) {
|
|
1334
|
+
if (next === store.snapshot().archiveFilter) return;
|
|
1335
|
+
store.setArchiveFilter(next);
|
|
1336
|
+
conversationCursor = null;
|
|
1337
|
+
try {
|
|
1338
|
+
await reloadInbox();
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
reportError(error, "setArchiveFilter");
|
|
1341
|
+
}
|
|
1342
|
+
await reloadArchivedCount().catch(
|
|
1343
|
+
(error) => reportError(error, "refreshArchivedCount")
|
|
1344
|
+
);
|
|
1345
|
+
},
|
|
1346
|
+
async refreshArchivedCount() {
|
|
1347
|
+
try {
|
|
1348
|
+
await reloadArchivedCount();
|
|
1349
|
+
} catch (error) {
|
|
1350
|
+
reportError(error, "refreshArchivedCount");
|
|
1351
|
+
}
|
|
1352
|
+
},
|
|
1291
1353
|
async loadMoreConversations() {
|
|
1292
1354
|
if (conversationCursor === null) return;
|
|
1293
1355
|
try {
|
|
1294
1356
|
const page = await repository.listConversations({
|
|
1295
1357
|
limit: conversationPageSize,
|
|
1296
|
-
cursor: conversationCursor
|
|
1358
|
+
cursor: conversationCursor,
|
|
1359
|
+
archived: store.snapshot().archiveFilter
|
|
1297
1360
|
});
|
|
1298
1361
|
conversationCursor = page.nextCursor;
|
|
1299
1362
|
store.appendConversations(page.items, page.hasMore);
|
|
@@ -1602,6 +1665,7 @@ function createMessagingRepository(options) {
|
|
|
1602
1665
|
identity,
|
|
1603
1666
|
async listConversations(args = {}) {
|
|
1604
1667
|
const limit = args.limit ?? 30;
|
|
1668
|
+
const archived = args.archived ?? DEFAULT_MESSAGING_ARCHIVE_FILTER;
|
|
1605
1669
|
const operation = "listConversations";
|
|
1606
1670
|
const rows = await withSessionRetry(
|
|
1607
1671
|
operation,
|
|
@@ -1611,7 +1675,12 @@ function createMessagingRepository(options) {
|
|
|
1611
1675
|
p_user_id: identity.userId,
|
|
1612
1676
|
p_limit: limit + 1,
|
|
1613
1677
|
p_before_sort_at: args.cursor?.beforeSortAt ?? null,
|
|
1614
|
-
p_before_conversation_id: args.cursor?.beforeConversationId ?? null
|
|
1678
|
+
p_before_conversation_id: args.cursor?.beforeConversationId ?? null,
|
|
1679
|
+
// THE ARCHIVED-ITEMS LAW, SERVER-side. `get_dm_conversations_with_details`
|
|
1680
|
+
// used to hardcode `is_archived IS FALSE` with no parameter at all,
|
|
1681
|
+
// so an archived conversation was not hidden — it was unreachable.
|
|
1682
|
+
// The RPC gained `p_archived` on 2026-09-09 (register row R1).
|
|
1683
|
+
p_archived: archived
|
|
1615
1684
|
},
|
|
1616
1685
|
operation
|
|
1617
1686
|
)
|
|
@@ -1631,6 +1700,29 @@ function createMessagingRepository(options) {
|
|
|
1631
1700
|
nextCursor: hasMore && last !== void 0 ? { beforeSortAt: last.sortAt, beforeConversationId: last.conversation.id } : null
|
|
1632
1701
|
};
|
|
1633
1702
|
},
|
|
1703
|
+
async countArchivedConversations(args = {}) {
|
|
1704
|
+
const limit = args.limit ?? 100;
|
|
1705
|
+
const operation = "countArchivedConversations";
|
|
1706
|
+
const rows = await withSessionRetry(
|
|
1707
|
+
operation,
|
|
1708
|
+
() => rpc(
|
|
1709
|
+
RPCS.conversationsWithDetails,
|
|
1710
|
+
{
|
|
1711
|
+
p_user_id: identity.userId,
|
|
1712
|
+
p_limit: limit + 1,
|
|
1713
|
+
p_before_sort_at: null,
|
|
1714
|
+
p_before_conversation_id: null,
|
|
1715
|
+
p_archived: "archived"
|
|
1716
|
+
},
|
|
1717
|
+
operation
|
|
1718
|
+
)
|
|
1719
|
+
);
|
|
1720
|
+
if (rows !== null && !Array.isArray(rows)) {
|
|
1721
|
+
throw invalidResponse(operation, `${RPCS.conversationsWithDetails} did not return rows`);
|
|
1722
|
+
}
|
|
1723
|
+
const found = (rows ?? []).length;
|
|
1724
|
+
return found > limit ? { count: limit, exact: false } : { count: found, exact: true };
|
|
1725
|
+
},
|
|
1634
1726
|
async getConversation(id) {
|
|
1635
1727
|
const operation = "getConversation";
|
|
1636
1728
|
const { data, error } = await withSessionRetry(
|
|
@@ -1864,14 +1956,8 @@ function createMessagingRepository(options) {
|
|
|
1864
1956
|
};
|
|
1865
1957
|
return repository;
|
|
1866
1958
|
}
|
|
1867
|
-
|
|
1868
|
-
// src/core/types.ts
|
|
1869
|
-
var asConversationId = (value) => value;
|
|
1870
|
-
var asMessageId = (value) => value;
|
|
1871
|
-
var asUserId = (value) => value;
|
|
1872
|
-
var asOrganizationId = (value) => value;
|
|
1873
|
-
var asClientMessageId = (value) => value;
|
|
1874
1959
|
export {
|
|
1960
|
+
DEFAULT_MESSAGING_ARCHIVE_FILTER,
|
|
1875
1961
|
MESSAGING_EVENTS,
|
|
1876
1962
|
MESSAGING_RPC_SCHEMA,
|
|
1877
1963
|
MESSAGING_SCHEMA,
|
|
@@ -1917,6 +2003,7 @@ export {
|
|
|
1917
2003
|
resolveActor,
|
|
1918
2004
|
splitText,
|
|
1919
2005
|
summarizeText,
|
|
2006
|
+
toMessagingArchiveFilter,
|
|
1920
2007
|
unreadCutoff
|
|
1921
2008
|
};
|
|
1922
2009
|
//# sourceMappingURL=index.js.map
|