@marktiderman/genesis-chat 0.1.1 → 0.2.1
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 +379 -13
- package/dist/chunk-A4YJX7KT.js +544 -0
- package/dist/chunk-A4YJX7KT.js.map +1 -0
- package/dist/chunk-AZS3HNLM.js +30 -0
- package/dist/chunk-AZS3HNLM.js.map +1 -0
- package/dist/chunk-BJCE5O7V.js +70 -0
- package/dist/chunk-BJCE5O7V.js.map +1 -0
- package/dist/chunk-GBJ3YI4E.js +966 -0
- package/dist/chunk-GBJ3YI4E.js.map +1 -0
- package/dist/chunk-JU2FAPBI.js +609 -0
- package/dist/chunk-JU2FAPBI.js.map +1 -0
- package/dist/chunk-VEPZROQB.js +187 -0
- package/dist/chunk-VEPZROQB.js.map +1 -0
- package/dist/{client-BtdALFCx.d.ts → client-DUIG1hum.d.ts} +187 -11
- package/dist/index.d.ts +78 -163
- package/dist/index.js +3 -2
- package/dist/native.d.ts +1939 -1
- package/dist/native.js +5023 -0
- package/dist/native.js.map +1 -1
- package/dist/outbox-B9NAWQ58.d.ts +219 -0
- package/dist/push.d.ts +206 -0
- package/dist/push.js +3 -0
- package/dist/push.js.map +1 -0
- package/dist/react.d.ts +176 -7
- package/dist/react.js +3 -3
- package/dist/server.d.ts +551 -21
- package/dist/server.js +976 -34
- package/dist/server.js.map +1 -1
- package/dist/thread-oPra7pkW.d.ts +57 -0
- package/dist/web.d.ts +335 -12
- package/dist/web.js +1784 -64
- package/dist/web.js.map +1 -1
- package/migrations/0002_genesis_chat_coaching.sql +934 -0
- package/migrations/0003_genesis_chat_search_threads.sql +85 -0
- package/migrations/tests/0002_genesis_chat_coaching.test.sql +269 -0
- package/migrations/tests/0003_genesis_chat_search_threads.test.sql +50 -0
- package/package.json +78 -6
- package/src/__tests__/coaching-core.test.ts +334 -0
- package/src/__tests__/coaching-react.test.tsx +319 -0
- package/src/__tests__/coaching-web.test.tsx +521 -0
- package/src/__tests__/core.test.ts +91 -0
- package/src/__tests__/fake-xhr.ts +54 -0
- package/src/__tests__/outbox-hosted.test.ts +269 -0
- package/src/__tests__/outbox.test.ts +122 -0
- package/src/__tests__/realtime.test.ts +70 -0
- package/src/__tests__/review-279.test.ts +41 -0
- package/src/__tests__/review-fixes-core.test.ts +193 -0
- package/src/__tests__/review-fixes-web.test.tsx +405 -0
- package/src/__tests__/server-effects.test.ts +158 -0
- package/src/__tests__/server-fake-video.test.ts +81 -0
- package/src/__tests__/server-fakes.ts +96 -0
- package/src/__tests__/server-integrations.test.ts +247 -0
- package/src/__tests__/server-providers.test.ts +246 -0
- package/src/__tests__/server-runner.test.ts +277 -0
- package/src/__tests__/server-safety.test.ts +303 -0
- package/src/__tests__/web-markdown.test.tsx +88 -0
- package/src/__tests__/web.test.tsx +349 -0
- package/src/core/availability.ts +223 -0
- package/src/core/client.ts +783 -0
- package/src/core/extras.ts +106 -0
- package/src/core/media.ts +144 -0
- package/src/core/outbox.ts +635 -0
- package/src/core/thread.ts +171 -0
- package/src/core/transfer.ts +71 -0
- package/src/core/types.ts +328 -0
- package/src/index.ts +14 -0
- package/src/native/__tests__/auto-retry.test.tsx +128 -0
- package/src/native/__tests__/composer-mic-lock.test.tsx +115 -0
- package/src/native/__tests__/composer-state.test.ts +188 -0
- package/src/native/__tests__/composer.test.tsx +133 -0
- package/src/native/__tests__/emoji.test.tsx +254 -0
- package/src/native/__tests__/inbox-screen.test.tsx +48 -0
- package/src/native/__tests__/message-bubble.test.tsx +127 -0
- package/src/native/__tests__/organise-logic.test.ts +164 -0
- package/src/native/__tests__/organise-screens.test.tsx +424 -0
- package/src/native/__tests__/photo-viewer.test.tsx +226 -0
- package/src/native/__tests__/push-payload.test.ts +66 -0
- package/src/native/__tests__/push.test.ts +209 -0
- package/src/native/__tests__/recorder-machine.test.ts +96 -0
- package/src/native/__tests__/rows-actions.test.ts +76 -0
- package/src/native/__tests__/thread-layout.test.ts +41 -0
- package/src/native/__tests__/thread-screen.test.tsx +116 -0
- package/src/native/__tests__/tus.test.ts +154 -0
- package/src/native/__tests__/use-voice-recorder.test.tsx +316 -0
- package/src/native/__tests__/video-media.test.tsx +498 -0
- package/src/native/__tests__/video-recorder-state.test.ts +87 -0
- package/src/native/__tests__/video-upload.test.ts +227 -0
- package/src/native/access-error.tsx +31 -0
- package/src/native/actions.ts +42 -0
- package/src/native/attachment-cards.tsx +132 -0
- package/src/native/auto-retry.ts +69 -0
- package/src/native/availability.tsx +376 -0
- package/src/native/broadcast-sheet.tsx +193 -0
- package/src/native/composer-state.ts +302 -0
- package/src/native/composer.tsx +453 -0
- package/src/native/context.tsx +70 -0
- package/src/native/copy.ts +296 -0
- package/src/native/emoji-data.ts +21 -0
- package/src/native/emoji-picker.tsx +229 -0
- package/src/native/emoji.ts +118 -0
- package/src/native/icon-button.tsx +40 -0
- package/src/native/inbox-screen.tsx +122 -0
- package/src/native/index.ts +184 -0
- package/src/native/link-preview.tsx +104 -0
- package/src/native/media-colors.ts +15 -0
- package/src/native/media.tsx +187 -0
- package/src/native/message-actions-sheet.tsx +126 -0
- package/src/native/message-bubble.tsx +366 -0
- package/src/native/moderation.tsx +42 -0
- package/src/native/modules.ts +277 -0
- package/src/native/organise-copy.ts +195 -0
- package/src/native/photo-viewer.tsx +531 -0
- package/src/native/push.ts +375 -0
- package/src/native/recorder-machine.ts +176 -0
- package/src/native/rows.ts +81 -0
- package/src/native/schedule-sheet.tsx +328 -0
- package/src/native/search-screen.tsx +189 -0
- package/src/native/stack-options.ts +36 -0
- package/src/native/start-sheet.tsx +87 -0
- package/src/native/thread-screen.tsx +647 -0
- package/src/native/topics.tsx +234 -0
- package/src/native/tus.ts +282 -0
- package/src/native/use-composer.ts +71 -0
- package/src/native/use-jump.ts +91 -0
- package/src/native/use-voice-recorder.ts +234 -0
- package/src/native/video-player.tsx +410 -0
- package/src/native/video-recorder-state.ts +140 -0
- package/src/native/video-recorder.tsx +274 -0
- package/src/native/video-upload-tray.tsx +77 -0
- package/src/native/video-upload.ts +432 -0
- package/src/native/voice-player.tsx +301 -0
- package/src/react/index.tsx +894 -0
- package/src/react/previews.ts +51 -0
- package/src/server/assistant.ts +235 -0
- package/src/server/crypto.ts +86 -0
- package/src/server/expo.ts +119 -0
- package/src/server/fake-video.ts +171 -0
- package/src/server/handler.ts +32 -0
- package/src/server/index.ts +58 -0
- package/src/server/moderation.ts +155 -0
- package/src/server/mux.ts +290 -0
- package/src/server/notifications.ts +130 -0
- package/src/server/runner.ts +468 -0
- package/src/server/transcribers.ts +111 -0
- package/src/server/types.ts +171 -0
- package/src/server/unfurl.ts +480 -0
- package/src/server/upload.ts +158 -0
- package/src/web/attachments.tsx +379 -0
- package/src/web/availability.tsx +299 -0
- package/src/web/broadcast.tsx +166 -0
- package/src/web/bubble.tsx +585 -0
- package/src/web/cards.tsx +136 -0
- package/src/web/composer.tsx +571 -0
- package/src/web/emoji-picker.tsx +84 -0
- package/src/web/error-boundary.tsx +33 -0
- package/src/web/format.ts +55 -0
- package/src/web/inbox.tsx +196 -0
- package/src/web/index.ts +75 -0
- package/src/web/markdown.tsx +245 -0
- package/src/web/memory-client.ts +714 -0
- package/src/web/panel.tsx +135 -0
- package/src/web/schedule.tsx +204 -0
- package/src/web/search.tsx +129 -0
- package/src/web/thread-context.ts +64 -0
- package/src/web/thread.tsx +830 -0
- package/src/web/topics.tsx +160 -0
- package/src/web/use-voice-recorder.ts +264 -0
- package/src/web/video.tsx +516 -0
- package/src/web/voice-note.tsx +197 -0
- package/dist/chunk-27UTR5FW.js +0 -322
- package/dist/chunk-27UTR5FW.js.map +0 -1
- package/dist/chunk-JQXZUEEL.js +0 -525
- package/dist/chunk-JQXZUEEL.js.map +0 -1
- package/dist/chunk-SAY24E6V.js +0 -309
- package/dist/chunk-SAY24E6V.js.map +0 -1
|
@@ -2,7 +2,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @feat:chat
|
|
5
|
-
* The chat contract: what the genesis_chat schema (
|
|
5
|
+
* The chat contract: what the genesis_chat schema (migrations 0001 and 0002) stores, in
|
|
6
6
|
* the app's words. Everything here is plain data, shared by web, native and
|
|
7
7
|
* the server.
|
|
8
8
|
*/
|
|
@@ -64,6 +64,11 @@ interface ChatMessage {
|
|
|
64
64
|
createdAt: string;
|
|
65
65
|
editedAt: string | null;
|
|
66
66
|
deletedAt: string | null;
|
|
67
|
+
/**
|
|
68
|
+
* What moderation said (migration 0002): `hidden` messages reach only their sender and the
|
|
69
|
+
* conversation's observers; `flagged` ones are visible to everyone and reported to observers.
|
|
70
|
+
*/
|
|
71
|
+
moderation?: "flagged" | "hidden" | null;
|
|
67
72
|
attachments: ChatAttachment[];
|
|
68
73
|
reactions: ChatReaction[];
|
|
69
74
|
}
|
|
@@ -174,6 +179,8 @@ interface PendingMessage {
|
|
|
174
179
|
createdAt: string;
|
|
175
180
|
status: "sending" | "failed";
|
|
176
181
|
error?: string;
|
|
182
|
+
/** The server refused it (not allowed, bad data): only a manual retry sends it again. */
|
|
183
|
+
permanent?: boolean;
|
|
177
184
|
/** Local previews for files still uploading (object URLs or file URIs). */
|
|
178
185
|
previews?: Record<number, string>;
|
|
179
186
|
/** What each file is, in order, so a pending bubble can draw it (a voice note's duration and waveform, a file's name). */
|
|
@@ -186,6 +193,20 @@ interface PendingFile {
|
|
|
186
193
|
meta?: Partial<AttachmentInput>;
|
|
187
194
|
/** Not kept between launches (bytes with nowhere to save them): attach it again. */
|
|
188
195
|
lost?: boolean;
|
|
196
|
+
/** How much of it has uploaded, 0 to 1, once the upload reports progress. */
|
|
197
|
+
progress?: number;
|
|
198
|
+
/** Going to the hosted video provider (Mux, Cloudflare) rather than storage. */
|
|
199
|
+
hosted?: boolean;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* A hosted video upload that has started: the provider's upload id, sent with the message as
|
|
203
|
+
* `{ provider, providerId, status: "pending" }` while the bytes still go up. The provider's
|
|
204
|
+
* webhook marks the attachment ready.
|
|
205
|
+
*/
|
|
206
|
+
interface HostedAttachment {
|
|
207
|
+
provider: "mux" | "cloudflare";
|
|
208
|
+
providerId: string;
|
|
209
|
+
status: "pending";
|
|
189
210
|
}
|
|
190
211
|
/** A live hint from Realtime: something changed; fetch to see what. */
|
|
191
212
|
type ChatSignal = {
|
|
@@ -215,10 +236,101 @@ interface ChatActivity {
|
|
|
215
236
|
activity: "typing" | "recording-voice" | "recording-video";
|
|
216
237
|
at: number;
|
|
217
238
|
}
|
|
239
|
+
/** A named sub-thread of a conversation (a cohort's lesson threads). Messages join one through `topic`. */
|
|
240
|
+
interface ChatTopic {
|
|
241
|
+
conversationId: string;
|
|
242
|
+
/** The key messages carry in `topic`. */
|
|
243
|
+
topic: string;
|
|
244
|
+
title: string;
|
|
245
|
+
position: number;
|
|
246
|
+
/** Set when closed: only owners, admins and observers post in it then. */
|
|
247
|
+
closedAt: string | null;
|
|
248
|
+
createdBy: string | null;
|
|
249
|
+
createdAt: string;
|
|
250
|
+
}
|
|
251
|
+
/** What `setTopic` changes; anything left out keeps its value (a new topic's title is its key). */
|
|
252
|
+
interface TopicInput {
|
|
253
|
+
title?: string;
|
|
254
|
+
position?: number;
|
|
255
|
+
closed?: boolean;
|
|
256
|
+
}
|
|
257
|
+
/** A message to send later, as its sender. Only its sender reads it. */
|
|
258
|
+
interface ScheduledMessage {
|
|
259
|
+
id: string;
|
|
260
|
+
conversationId: string;
|
|
261
|
+
clientId: string;
|
|
262
|
+
body: string;
|
|
263
|
+
attachments: AttachmentInput[];
|
|
264
|
+
replyToId: string | null;
|
|
265
|
+
topic: string | null;
|
|
266
|
+
mentions: string[];
|
|
267
|
+
silent: boolean;
|
|
268
|
+
sendAt: string;
|
|
269
|
+
sentMessageId: string | null;
|
|
270
|
+
cancelledAt: string | null;
|
|
271
|
+
/** Why it couldn't be sent when due (the sender left the conversation, say). */
|
|
272
|
+
error: string | null;
|
|
273
|
+
createdAt: string;
|
|
274
|
+
status: "scheduled" | "sent" | "cancelled" | "failed";
|
|
275
|
+
}
|
|
276
|
+
/** Between a minute and a year ahead. Files in `attachments` are uploaded first, as for `send`. */
|
|
277
|
+
interface ScheduleInput extends Omit<SendInput, "threadRootId" | "visibility"> {
|
|
278
|
+
sendAt: string | Date;
|
|
279
|
+
}
|
|
280
|
+
type Weekday = "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun";
|
|
281
|
+
/** Working hours per weekday as `[["09:00","17:00"]]`, 24-hour local times; a missing day is not working. An end at or before its start runs past midnight. */
|
|
282
|
+
type WorkingHours = Partial<Record<Weekday, [string, string][]>>;
|
|
283
|
+
/** A person's away message and working hours. */
|
|
284
|
+
interface ChatAvailability {
|
|
285
|
+
userId: string;
|
|
286
|
+
awayMessage: string | null;
|
|
287
|
+
/** Away until then; with an away message and no date, away until they clear it. */
|
|
288
|
+
awayUntil: string | null;
|
|
289
|
+
/** An IANA zone (`America/New_York`); hours are read in it. */
|
|
290
|
+
timeZone: string | null;
|
|
291
|
+
hours: WorkingHours | null;
|
|
292
|
+
}
|
|
293
|
+
type AvailabilityInput = Partial<Omit<ChatAvailability, "userId">>;
|
|
294
|
+
/** One search result. `snippet` marks the matched words with « and » (the text's own « and » arrive as ‹ and ›, so marks are always real). */
|
|
295
|
+
interface ChatSearchHit {
|
|
296
|
+
messageId: string;
|
|
297
|
+
conversationId: string;
|
|
298
|
+
seq: number;
|
|
299
|
+
senderId: string | null;
|
|
300
|
+
createdAt: string;
|
|
301
|
+
snippet: string;
|
|
302
|
+
/** Found in a voice note's or video's transcript, not the text. */
|
|
303
|
+
inTranscript: boolean;
|
|
304
|
+
/** The thread the message is a reply in (open that thread to show it); null on the main timeline. */
|
|
305
|
+
threadRootId: string | null;
|
|
306
|
+
}
|
|
307
|
+
/** Open Graph data for a link (fetched by the server's runner). Plain text: never render it as HTML. */
|
|
308
|
+
interface ChatLinkPreview {
|
|
309
|
+
url: string;
|
|
310
|
+
status: "ok" | "failed" | "blocked";
|
|
311
|
+
title: string | null;
|
|
312
|
+
description: string | null;
|
|
313
|
+
/** Always https when present. */
|
|
314
|
+
imageUrl: string | null;
|
|
315
|
+
siteName: string | null;
|
|
316
|
+
fetchedAt: string;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
type UploadProgress = (sent: number, total: number) => void;
|
|
320
|
+
interface SendBytesOptions {
|
|
321
|
+
method?: "PUT" | "POST";
|
|
322
|
+
headers?: Record<string, string>;
|
|
323
|
+
signal?: AbortSignal;
|
|
324
|
+
onProgress?: UploadProgress;
|
|
325
|
+
/** For tests and runtimes without XMLHttpRequest. */
|
|
326
|
+
fetch?: typeof fetch;
|
|
327
|
+
}
|
|
328
|
+
/** Sends `body` to `url`; resolves with the response text, throws a ChatError on a non-2xx answer. */
|
|
329
|
+
declare function sendBytes(url: string, body: Blob | ArrayBuffer, opts?: SendBytesOptions): Promise<string>;
|
|
218
330
|
|
|
219
331
|
/**
|
|
220
332
|
* @feat:chat
|
|
221
|
-
* The chat client: the app's own Supabase (
|
|
333
|
+
* The chat client: the app's own Supabase (migrations 0001 and 0002, the genesis_chat
|
|
222
334
|
* schema) under row level security. Reads are table selects; every write is a
|
|
223
335
|
* genesis_chat function. Live updates are hints on private Realtime topics,
|
|
224
336
|
* after which the client fetches again, so nothing is trusted from the wire.
|
|
@@ -239,10 +351,21 @@ declare class ChatError extends Error {
|
|
|
239
351
|
get rateLimited(): boolean;
|
|
240
352
|
/** Worth trying again: the network, not the database, said no. */
|
|
241
353
|
get transient(): boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Sending it again won't help: the database refused what was sent (not allowed 42501, bad
|
|
356
|
+
* data 22xxx such as 22023, a conflict 23xxx such as 23505, another refusal 42xxx, or a
|
|
357
|
+
* function's own `raise` P0001). A person may still retry by hand; nothing retries it alone.
|
|
358
|
+
*/
|
|
359
|
+
get permanent(): boolean;
|
|
242
360
|
}
|
|
243
361
|
type Row = Record<string, unknown>;
|
|
244
362
|
declare function toAttachment(r: Row): ChatAttachment;
|
|
245
363
|
declare function toMessage(r: Row): ChatMessage;
|
|
364
|
+
declare function toTopic(r: Row): ChatTopic;
|
|
365
|
+
declare function toScheduled(r: Row): ScheduledMessage;
|
|
366
|
+
declare function toAvailability(r: Row): ChatAvailability;
|
|
367
|
+
declare function toSearchHit(r: Row): ChatSearchHit;
|
|
368
|
+
declare function toLinkPreview(r: Row): ChatLinkPreview;
|
|
246
369
|
interface MessagePage {
|
|
247
370
|
messages: ChatMessage[];
|
|
248
371
|
/** More, older messages exist before the first one. */
|
|
@@ -255,14 +378,25 @@ interface ChatClientOptions {
|
|
|
255
378
|
interface Subscription {
|
|
256
379
|
unsubscribe(): void;
|
|
257
380
|
}
|
|
381
|
+
interface ConversationHandlers {
|
|
382
|
+
onSignal: (s: ChatSignal) => void;
|
|
383
|
+
onActivity?: (a: ChatActivity) => void;
|
|
384
|
+
/** Every join, the first included: catch up on what arrived before the channel was live. */
|
|
385
|
+
onJoin?: () => void;
|
|
386
|
+
/** Re-joins only. Prefer `onJoin`. */
|
|
387
|
+
onReconnect?: () => void;
|
|
388
|
+
}
|
|
258
389
|
interface ConversationChannel extends Subscription {
|
|
259
390
|
/** Tell the others you are typing or recording (throttle to once every 3 seconds). */
|
|
260
391
|
signal(activity: ChatActivity["activity"]): void;
|
|
261
392
|
}
|
|
262
393
|
declare function createChatClient(supabase: ChatSupabase, options?: ChatClientOptions): {
|
|
263
394
|
supabase: ChatSupabase;
|
|
395
|
+
/** Your conversations: one `kind`, several `kinds`, or all but `excludeKinds` (e.g. Messages without `support`). */
|
|
264
396
|
inbox(opts?: {
|
|
265
397
|
kind?: string;
|
|
398
|
+
kinds?: string[];
|
|
399
|
+
excludeKinds?: string[];
|
|
266
400
|
archived?: boolean;
|
|
267
401
|
limit?: number;
|
|
268
402
|
before?: string;
|
|
@@ -272,7 +406,10 @@ declare function createChatClient(supabase: ChatSupabase, options?: ChatClientOp
|
|
|
272
406
|
limit?: number;
|
|
273
407
|
before?: string;
|
|
274
408
|
}): Promise<Row[]>;
|
|
275
|
-
|
|
409
|
+
/** Unread across your conversations (for a badge), leaving out `excludeKinds` to match an inbox that does. */
|
|
410
|
+
unreadTotal(opts?: {
|
|
411
|
+
excludeKinds?: string[];
|
|
412
|
+
}): Promise<number>;
|
|
276
413
|
conversation(id: string): Promise<ChatConversation | null>;
|
|
277
414
|
/** A kind's rules (how many members, who posts, threads), for what the UI offers. */
|
|
278
415
|
kind(kind: string): Promise<ChatKindRules | null>;
|
|
@@ -320,30 +457,69 @@ declare function createChatClient(supabase: ChatSupabase, options?: ChatClientOp
|
|
|
320
457
|
pins(conversationId: string): Promise<string[]>;
|
|
321
458
|
save(messageId: string, on?: boolean, note?: string): Promise<void>;
|
|
322
459
|
report(messageId: string, reason: "spam" | "harassment" | "safety" | "other", note?: string): Promise<string>;
|
|
460
|
+
/** A conversation's topics, in order (position, then key). */
|
|
461
|
+
topics(conversationId: string): Promise<ChatTopic[]>;
|
|
462
|
+
/** Adds a topic, or renames, reorders, closes (`closed: true`) or reopens it. Owners and admins. */
|
|
463
|
+
setTopic(conversationId: string, topic: string, input?: TopicInput): Promise<void>;
|
|
464
|
+
/** Schedules a message (a minute to a year ahead) and returns its id. Safe to retry with the same clientId. */
|
|
465
|
+
schedule(input: ScheduleInput): Promise<string>;
|
|
466
|
+
/** Your messages still waiting to go (and ones that failed when due), soonest first; in one conversation or all. */
|
|
467
|
+
scheduled(conversationId?: string): Promise<ScheduledMessage[]>;
|
|
468
|
+
cancelScheduled(id: string): Promise<void>;
|
|
469
|
+
/** The away message and hours of a conversation's members who set them (not observers). */
|
|
470
|
+
availabilityFor(conversationId: string): Promise<ChatAvailability[]>;
|
|
471
|
+
/** Your own away message and hours, or null when never set. */
|
|
472
|
+
myAvailability(): Promise<ChatAvailability | null>;
|
|
473
|
+
/** Replaces your away message and hours (a field left out is cleared). */
|
|
474
|
+
setAvailability(input: AvailabilityInput): Promise<void>;
|
|
475
|
+
/**
|
|
476
|
+
* Sends one text message into each of these conversations where you may post (a coach to
|
|
477
|
+
* each client's direct conversation), so replies come back privately. Text only. Safe to
|
|
478
|
+
* retry with the same clientId. Returns the ids of the messages sent.
|
|
479
|
+
*/
|
|
480
|
+
broadcast(conversationIds: string[], clientId: string, body: string, opts?: {
|
|
481
|
+
silent?: boolean;
|
|
482
|
+
}): Promise<string[]>;
|
|
483
|
+
/** Messages (and transcripts) you can read that match, newest first: in one conversation or all of yours. Two characters at least. */
|
|
484
|
+
search(query: string, conversationId?: string | null, opts?: {
|
|
485
|
+
limit?: number;
|
|
486
|
+
}): Promise<ChatSearchHit[]>;
|
|
487
|
+
/**
|
|
488
|
+
* The previews the server has fetched for the links in these messages, by message id (only
|
|
489
|
+
* `ok` ones; links not fetched yet are left out). Read through link_previews_for, one call
|
|
490
|
+
* per message (up to 6 at once), which answers only for messages you can read: the preview
|
|
491
|
+
* table itself is closed, since a URL can carry a secret.
|
|
492
|
+
*/
|
|
493
|
+
linkPreviewsFor(messageIds: string[]): Promise<Record<string, ChatLinkPreview[]>>;
|
|
323
494
|
/**
|
|
324
495
|
* Uploads a file into the conversation's folder for the signed-in person and
|
|
325
496
|
* returns its path, ready to attach. Resumable for big files is the native
|
|
326
497
|
* renderer's job (Supabase TUS); this is the plain upload.
|
|
498
|
+
*
|
|
499
|
+
* With `onProgress(sent, total)`, where XMLHttpRequest exists (browsers, React Native), the
|
|
500
|
+
* bytes go to a signed upload URL (`createSignedUploadUrl`, which checks the same storage
|
|
501
|
+
* policy as a plain upload) through XMLHttpRequest, which reports progress; elsewhere the
|
|
502
|
+
* plain upload runs and reports once, at the end. `signal` cancels it.
|
|
327
503
|
*/
|
|
328
504
|
upload(conversationId: string, userId: string, file: Blob | ArrayBuffer, opts: {
|
|
329
505
|
name: string;
|
|
330
506
|
contentType: string;
|
|
331
507
|
id?: string;
|
|
508
|
+
onProgress?: UploadProgress;
|
|
509
|
+
signal?: AbortSignal;
|
|
332
510
|
}): Promise<string>;
|
|
333
511
|
/** Signed links for files, cached until shortly before they expire. */
|
|
334
512
|
fileUrls(paths: string[]): Promise<Record<string, string>>;
|
|
335
513
|
/** Your inbox's live hints (a new message anywhere you are, a membership change). */
|
|
336
514
|
subscribeInbox(userId: string, onSignal: (s: ChatSignal) => void): Subscription;
|
|
337
515
|
/**
|
|
338
|
-
* A conversation's live hints, plus who is typing or recording. `
|
|
339
|
-
*
|
|
516
|
+
* A conversation's live hints, plus who is typing or recording. `onJoin` runs every
|
|
517
|
+
* time the channel joins, the first time included: the moment to fetch what arrived
|
|
518
|
+
* before the subscription was live. `onReconnect` (kept for older callers) runs on
|
|
519
|
+
* re-joins only.
|
|
340
520
|
*/
|
|
341
|
-
subscribeConversation(conversationId: string, me: string, handlers:
|
|
342
|
-
onSignal: (s: ChatSignal) => void;
|
|
343
|
-
onActivity?: (a: ChatActivity) => void;
|
|
344
|
-
onReconnect?: () => void;
|
|
345
|
-
}): ConversationChannel;
|
|
521
|
+
subscribeConversation(conversationId: string, me: string, handlers: ConversationHandlers): ConversationChannel;
|
|
346
522
|
};
|
|
347
523
|
type ChatClient = ReturnType<typeof createChatClient>;
|
|
348
524
|
|
|
349
|
-
export { type
|
|
525
|
+
export { type AttachmentInput as A, type PendingMessage as B, type ChatAvailability as C, type ScheduledMessage as D, type SendBytesOptions as E, type SendInput as F, type Subscription as G, type HostedAttachment as H, conversationTopic as I, createChatClient as J, sendBytes as K, toAttachment as L, type MessagePage as M, toAvailability as N, toLinkPreview as O, type PendingFile as P, toMessage as Q, toScheduled as R, type ScheduleInput as S, type TopicInput as T, type UploadProgress as U, toSearchHit as V, type Weekday as W, toTopic as X, userTopic as Y, type WorkingHours as a, type AttachmentKind as b, type AttachmentProvider as c, type AvailabilityInput as d, CHAT_BUCKET as e, CHAT_SCHEMA as f, type ChatActivity as g, type ChatAttachment as h, type ChatClient as i, type ChatClientOptions as j, type ChatConversation as k, ChatError as l, type ChatInboxItem as m, type ChatKindRules as n, type ChatLinkPreview as o, type ChatMember as p, type ChatMessage as q, type ChatPreview as r, type ChatReaction as s, type ChatRole as t, type ChatSearchHit as u, type ChatSignal as v, type ChatSupabase as w, type ChatTopic as x, type ConversationChannel as y, type ConversationHandlers as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,185 +1,100 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { W as Weekday, C as ChatAvailability, a as WorkingHours } from './client-DUIG1hum.js';
|
|
2
|
+
export { A as AttachmentInput, b as AttachmentKind, c as AttachmentProvider, d as AvailabilityInput, e as CHAT_BUCKET, f as CHAT_SCHEMA, g as ChatActivity, h as ChatAttachment, i as ChatClient, j as ChatClientOptions, k as ChatConversation, l as ChatError, m as ChatInboxItem, n as ChatKindRules, o as ChatLinkPreview, p as ChatMember, q as ChatMessage, r as ChatPreview, s as ChatReaction, t as ChatRole, u as ChatSearchHit, v as ChatSignal, w as ChatSupabase, x as ChatTopic, y as ConversationChannel, z as ConversationHandlers, H as HostedAttachment, M as MessagePage, P as PendingFile, B as PendingMessage, S as ScheduleInput, D as ScheduledMessage, E as SendBytesOptions, F as SendInput, G as Subscription, T as TopicInput, U as UploadProgress, I as conversationTopic, J as createChatClient, K as sendBytes, L as toAttachment, N as toAvailability, O as toLinkPreview, Q as toMessage, R as toScheduled, V as toSearchHit, X as toTopic, Y as userTopic } from './client-DUIG1hum.js';
|
|
3
|
+
export { A as ALLOWED_EXTENSIONS, C as CHAT_LIMITS, H as HostedUpload, a as HostedUploadOptions, b as HostedUploadRecord, c as HostedUploadStart, L as LocalFile, O as Outbox, d as OutboxOptions, e as OutboxStore, P as PLAYBACK_RATES, Q as QueuedMessage, S as StorageUpload, f as attachmentKindFor, g as createOutbox, h as fileExtension, i as formatDuration, j as isAllowedExtension, m as memoryOutboxStore, n as nextPlaybackRate, r as randomId, k as recordingLimitMs, l as releaseObjectUrl, w as waveformFromMetering, o as waveformPeaks } from './outbox-B9NAWQ58.js';
|
|
4
|
+
export { R as ReactionSummary, T as ThreadItem, a as activityLine, c as currentActivity, d as dayLabel, f as firstUnreadId, i as itemSender, b as itemTime, m as mergeThread, p as parseMentions, e as previewText, s as sameDay, g as startsDay, h as startsGroup, j as summarizeReactions, t as throttle, u as upsertMessages } from './thread-oPra7pkW.js';
|
|
3
5
|
import '@supabase/supabase-js';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* @feat:chat
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* Availability, the same on every platform: is someone inside their working hours (read in
|
|
10
|
+
* their own time zone), are they away, and the one line a thread shows about it ("Mark
|
|
11
|
+
* replies Mon–Fri, 9–5 (Eastern)", "Away until Monday: Back Monday"). Pure: `now` is passed
|
|
12
|
+
* in, and time zones come from Intl.
|
|
10
13
|
*/
|
|
11
14
|
|
|
15
|
+
declare const WEEKDAYS: readonly Weekday[];
|
|
16
|
+
/** "09:30" → 570; a bad value (anything but such a string) → null. "24:00" is allowed as the end of a day. */
|
|
17
|
+
declare function minutesOf(hhmm: unknown): number | null;
|
|
18
|
+
/** At most this many ranges a day, as the database allows. */
|
|
19
|
+
declare const MAX_RANGES_PER_DAY = 4;
|
|
12
20
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
21
|
+
* Working hours as they may safely be read: only mon..sun, each an array of `["HH:MM", "HH:MM"]`
|
|
22
|
+
* string pairs (at most four a day); every other day, range or value is dropped. Null when
|
|
23
|
+
* nothing is left. Hours come from other people, so they are never trusted as typed.
|
|
16
24
|
*/
|
|
17
|
-
declare function
|
|
18
|
-
/**
|
|
19
|
-
declare
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
declare function isAllowedExtension(ext: string): boolean;
|
|
23
|
-
/** What an upload becomes in a message. */
|
|
24
|
-
declare function attachmentKindFor(contentType: string, opts?: {
|
|
25
|
-
recordedVoice?: boolean;
|
|
26
|
-
}): AttachmentKind;
|
|
27
|
-
/** Default limits (decision 5): an app may lower them, not raise them past the bucket's 100 MB. */
|
|
28
|
-
declare const CHAT_LIMITS: {
|
|
29
|
-
/** Voice notes and videos, for members. */
|
|
30
|
-
readonly recordingMs: number;
|
|
31
|
-
/** For owners, admins and observers (coaches, staff). */
|
|
32
|
-
readonly staffRecordingMs: number;
|
|
33
|
-
readonly fileBytes: number;
|
|
34
|
-
readonly videoBytes: number;
|
|
35
|
-
readonly attachmentsPerMessage: 20;
|
|
36
|
-
readonly bodyChars: 10000;
|
|
25
|
+
declare function normalizeHours(raw: unknown): WorkingHours | null;
|
|
26
|
+
/** The weekday and minute of the day at `now` in `timeZone` (the device's zone when null or unknown). */
|
|
27
|
+
declare function localClock(now: Date, timeZone?: string | null): {
|
|
28
|
+
day: Weekday;
|
|
29
|
+
minutes: number;
|
|
37
30
|
};
|
|
38
|
-
/** The longest recording this role may make. */
|
|
39
|
-
declare function recordingLimitMs(role: string | null | undefined): number;
|
|
40
31
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
32
|
+
* Is `now` inside these working hours, read in `timeZone`? No hours set means always.
|
|
33
|
+
* A range whose end is at or before its start runs overnight into the next day
|
|
34
|
+
* (`fri: [["22:00","02:00"]]` covers Friday 22:00 to Saturday 02:00).
|
|
44
35
|
*/
|
|
45
|
-
declare function
|
|
36
|
+
declare function isWithinWorkingHours(raw: WorkingHours | null | undefined, timeZone: string | null | undefined, now?: Date): boolean;
|
|
37
|
+
/** Away now: an away message with no end date, or an end date still ahead. */
|
|
38
|
+
declare function isAway(a: Pick<ChatAvailability, "awayMessage" | "awayUntil"> | null | undefined, now?: Date): boolean;
|
|
39
|
+
/** "Mon–Fri, 9–5", "Mon–Thu, 9–5; Fri, 9–1". Days with the same hours are grouped. Empty when none. */
|
|
40
|
+
declare function hoursSummary(raw: WorkingHours | null | undefined): string;
|
|
41
|
+
/** "Eastern" for America/New_York (the zone's generic name, less " Time"); the city when Intl has no name. */
|
|
42
|
+
declare function timeZoneLabel(timeZone: string | null | undefined, locale?: string): string;
|
|
43
|
+
/** "3:00 PM" today, "Monday" within the week, else "12 Mar". */
|
|
44
|
+
declare function untilLabel(iso: string, now?: Date, locale?: string, timeZone?: string | null): string;
|
|
45
|
+
interface AwayLineOptions {
|
|
46
|
+
now?: Date;
|
|
47
|
+
locale?: string;
|
|
48
|
+
/** Show the hours line even inside working hours (a profile, not a banner). */
|
|
49
|
+
always?: boolean;
|
|
50
|
+
}
|
|
46
51
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
52
|
+
* The line a thread shows about someone, or null when they are around:
|
|
53
|
+
* - away with a date: "Away until Monday: Back Monday" (the away message after the colon);
|
|
54
|
+
* - away with no date: "Mark is away: On a retreat";
|
|
55
|
+
* - outside working hours: "Mark replies Mon–Fri, 9–5 (Eastern)".
|
|
49
56
|
*/
|
|
50
|
-
declare function
|
|
51
|
-
/**
|
|
52
|
-
declare function
|
|
53
|
-
/** Playback speeds offered for voice and video (free for everyone, decision 5). */
|
|
54
|
-
declare const PLAYBACK_RATES: readonly [1, 1.5, 2];
|
|
55
|
-
declare function nextPlaybackRate(rate: number): number;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* @feat:chat
|
|
59
|
-
* Pure thread logic, the same on every platform: merging the server's messages
|
|
60
|
-
* with ones still on their way, grouping a run of messages from one sender,
|
|
61
|
-
* day dividers, the unread line, reactions by emoji, and the typing line.
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
type ThreadItem = {
|
|
65
|
-
type: "message";
|
|
66
|
-
message: ChatMessage;
|
|
67
|
-
pending?: undefined;
|
|
68
|
-
} | {
|
|
69
|
-
type: "pending";
|
|
70
|
-
pending: PendingMessage;
|
|
71
|
-
message?: undefined;
|
|
72
|
-
};
|
|
57
|
+
declare function awayLine(a: ChatAvailability | null | undefined, name: string, opts?: AwayLineOptions): string | null;
|
|
58
|
+
/** "Sam", "Sam and Lee", "Sam, Lee and 3 others": at most two names. */
|
|
59
|
+
declare function namesLine(names: string[]): string;
|
|
73
60
|
/**
|
|
74
|
-
* The
|
|
75
|
-
*
|
|
76
|
-
*
|
|
61
|
+
* The line for several people (a group's members): one person's full `awayLine`, or for more
|
|
62
|
+
* "Sam and Lee are away", "Sam, Lee and 2 others are outside their hours", or "… are away or
|
|
63
|
+
* outside their hours" when it's a mix. Null when everyone is around.
|
|
77
64
|
*/
|
|
78
|
-
declare function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
declare function itemTime(item: ThreadItem): string;
|
|
83
|
-
/** Runs of one sender within five minutes share a header (name, avatar). */
|
|
84
|
-
declare function startsGroup(items: ThreadItem[], index: number, gapMs?: number): boolean;
|
|
85
|
-
declare function sameDay(a: string, b: string): boolean;
|
|
86
|
-
/** A day divider goes before this item. */
|
|
87
|
-
declare function startsDay(items: ThreadItem[], index: number): boolean;
|
|
88
|
-
/** "Today", "Yesterday", "Monday", or "12 Mar 2026". */
|
|
89
|
-
declare function dayLabel(iso: string, now?: Date, locale?: string): string;
|
|
90
|
-
/** The first message after what you had read, from someone else: where "New" goes. */
|
|
91
|
-
declare function firstUnreadId(messages: ChatMessage[], lastReadSeq: number, me: string): string | null;
|
|
92
|
-
interface ReactionSummary {
|
|
93
|
-
emoji: string;
|
|
94
|
-
count: number;
|
|
95
|
-
mine: boolean;
|
|
96
|
-
userIds: string[];
|
|
97
|
-
}
|
|
98
|
-
/** Reactions by emoji, most first, then in first-used order. */
|
|
99
|
-
declare function summarizeReactions(message: ChatMessage, me: string): ReactionSummary[];
|
|
100
|
-
/** Who is doing what now: activity older than six seconds has stopped. */
|
|
101
|
-
declare function currentActivity(activity: ChatActivity[], now?: number, staleMs?: number): ChatActivity[];
|
|
102
|
-
/** "Sam is typing…", "Sam and Lee are typing…", "Sam is recording a voice message…". */
|
|
103
|
-
declare function activityLine(activity: ChatActivity[], nameOf: (userId: string) => string): string | null;
|
|
104
|
-
/** Sends activity at most once every `everyMs`. */
|
|
105
|
-
declare function throttle(fn: () => void, everyMs?: number): () => void;
|
|
106
|
-
/** The ids @mentioned in markdown written as `@[Name](user:<uuid>)`. */
|
|
107
|
-
declare function parseMentions(body: string): string[];
|
|
108
|
-
/** A one-line preview: text, or what was attached. */
|
|
109
|
-
declare function previewText(body: string, attachment: string | null | undefined, deleted?: boolean): string;
|
|
65
|
+
declare function awaySummary(people: {
|
|
66
|
+
availability: ChatAvailability | null | undefined;
|
|
67
|
+
name: string;
|
|
68
|
+
}[], opts?: AwayLineOptions): string | null;
|
|
110
69
|
|
|
111
70
|
/**
|
|
112
71
|
* @feat:chat
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* localStorage on web, MMKV or SQLite on native), behind OutboxStore.
|
|
72
|
+
* Small pure helpers for migration 0002's features, shared by every platform: the links a
|
|
73
|
+
* message's text carries (the same rule the database uses to queue previews), https checks
|
|
74
|
+
* for preview images, search snippets split at their « » marks, scheduling quick picks, and
|
|
75
|
+
* topic keys.
|
|
118
76
|
*/
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
/** A preview to show while it uploads (an object URL, a file URI). */
|
|
127
|
-
previewUrl?: string;
|
|
128
|
-
/** Known up front: a voice note's duration and waveform, a photo's size. */
|
|
129
|
-
meta?: Partial<Omit<AttachmentInput, "path" | "kind">> & {
|
|
130
|
-
kind?: AttachmentInput["kind"];
|
|
131
|
-
};
|
|
77
|
+
/** The https links in a message's text that get a preview, at most three, as genesis_chat.message_links finds them. */
|
|
78
|
+
declare function extractLinks(body: string, max?: number): string[];
|
|
79
|
+
/** An absolute https URL with a host: the only kind a preview image may load from. */
|
|
80
|
+
declare function isHttpsUrl(url: string | null | undefined): url is string;
|
|
81
|
+
interface SnippetPart {
|
|
82
|
+
text: string;
|
|
83
|
+
match: boolean;
|
|
132
84
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
lostFiles?: number;
|
|
139
|
-
attempts: number;
|
|
85
|
+
/** "a «word» here" → [{a }, {word, match}, { here}]. Unbalanced marks are kept as text. */
|
|
86
|
+
declare function snippetParts(snippet: string): SnippetPart[];
|
|
87
|
+
interface QuickPick {
|
|
88
|
+
label: string;
|
|
89
|
+
at: Date;
|
|
140
90
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
store?: OutboxStore;
|
|
150
|
-
/** Reads a native file URI into bytes for upload. */
|
|
151
|
-
readFile?: (uri: string) => Promise<Blob | ArrayBuffer>;
|
|
152
|
-
/** Upload hook, e.g. resumable uploads on native. Defaults to client.upload. */
|
|
153
|
-
upload?: (conversationId: string, file: LocalFile) => Promise<string>;
|
|
154
|
-
/** Called with every change, for the UI. */
|
|
155
|
-
onChange?: (queue: QueuedMessage[]) => void;
|
|
156
|
-
/** Called when a message lands. */
|
|
157
|
-
onSent?: (message: ChatMessage, clientId: string) => void;
|
|
158
|
-
/** Makes client ids. Default: a random UUID (works where crypto.randomUUID is missing). */
|
|
159
|
-
newId?: () => string;
|
|
160
|
-
/**
|
|
161
|
-
* Keeps a file held as bytes (a pasted image, a recording) between launches: write it
|
|
162
|
-
* somewhere and return a URI `readFile` can read (native: the app's cache directory).
|
|
163
|
-
* Without it, such a file isn't saved, and after a relaunch its message asks for it again.
|
|
164
|
-
*/
|
|
165
|
-
persistFile?: (file: LocalFile) => Promise<string>;
|
|
166
|
-
}
|
|
167
|
-
declare function createOutbox(opts: OutboxOptions): {
|
|
168
|
-
/** Queues a message; it shows at once and sends in order. Returns its clientId. */
|
|
169
|
-
send(input: Omit<SendInput, "clientId"> & {
|
|
170
|
-
clientId?: string;
|
|
171
|
-
}, files?: LocalFile[]): Promise<string>;
|
|
172
|
-
retry(clientId: string): Promise<void>;
|
|
173
|
-
/** Gives a message whose files were lost on a relaunch its files again, and sends it. */
|
|
174
|
-
reattach(clientId: string, files: LocalFile[]): Promise<void>;
|
|
175
|
-
/** Retries every failed message (after the connection comes back). */
|
|
176
|
-
retryAll(): Promise<void>;
|
|
177
|
-
discard(clientId: string): Promise<void>;
|
|
178
|
-
pending(conversationId?: string): PendingMessage[];
|
|
179
|
-
/** A new client id, made the way this outbox makes them. */
|
|
180
|
-
newId: typeof randomId;
|
|
181
|
-
load: () => Promise<void>;
|
|
182
|
-
};
|
|
183
|
-
type Outbox = ReturnType<typeof createOutbox>;
|
|
91
|
+
/** "Tomorrow, 9:00 AM" and "Monday, 9:00 AM" (the next Monday after tomorrow; one pick when they're the same day). */
|
|
92
|
+
declare function scheduleQuickPicks(now?: Date, locale?: string): QuickPick[];
|
|
93
|
+
/** When a scheduled message goes: "Tomorrow, 9:00 AM", "Mon 12 Oct, 9:00 AM". */
|
|
94
|
+
declare function scheduleLabel(iso: string | Date, now?: Date, locale?: string): string;
|
|
95
|
+
/** The send time the database accepts: at least a minute and at most a year ahead. */
|
|
96
|
+
declare function isSchedulable(at: Date, now?: Date): boolean;
|
|
97
|
+
/** A topic's key from its title: "Week 1: Habits" → "week-1-habits" (at most 120 characters). */
|
|
98
|
+
declare function topicKey(title: string): string;
|
|
184
99
|
|
|
185
|
-
export {
|
|
100
|
+
export { type AwayLineOptions, ChatAvailability, MAX_RANGES_PER_DAY, type QuickPick, type SnippetPart, WEEKDAYS, Weekday, WorkingHours, awayLine, awaySummary, extractLinks, hoursSummary, isAway, isHttpsUrl, isSchedulable, isWithinWorkingHours, localClock, minutesOf, namesLine, normalizeHours, scheduleLabel, scheduleQuickPicks, snippetParts, timeZoneLabel, topicKey, untilLabel };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { extractLinks, isHttpsUrl, isSchedulable, scheduleLabel, scheduleQuickPicks, snippetParts, topicKey } from './chunk-BJCE5O7V.js';
|
|
2
|
+
export { activityLine, createOutbox, currentActivity, dayLabel, firstUnreadId, itemSender, itemTime, memoryOutboxStore, mergeThread, parseMentions, previewText, releaseObjectUrl, sameDay, startsDay, startsGroup, summarizeReactions, throttle, upsertMessages } from './chunk-A4YJX7KT.js';
|
|
3
|
+
export { ALLOWED_EXTENSIONS, CHAT_BUCKET, CHAT_LIMITS, CHAT_SCHEMA, ChatError, MAX_RANGES_PER_DAY, PLAYBACK_RATES, WEEKDAYS, attachmentKindFor, awayLine, awaySummary, conversationTopic, createChatClient, fileExtension, formatDuration, hoursSummary, isAllowedExtension, isAway, isWithinWorkingHours, localClock, minutesOf, namesLine, nextPlaybackRate, normalizeHours, randomId, recordingLimitMs, sendBytes, timeZoneLabel, toAttachment, toAvailability, toLinkPreview, toMessage, toScheduled, toSearchHit, toTopic, untilLabel, userTopic, waveformFromMetering, waveformPeaks } from './chunk-GBJ3YI4E.js';
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
|
4
5
|
//# sourceMappingURL=index.js.map
|