spectrum-ts 1.18.0 → 3.0.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.
Files changed (38) hide show
  1. package/README.md +11 -1
  2. package/dist/{attachment-DfWSZS5L.d.ts → attachment-WePAHfcH.d.ts} +1 -1
  3. package/dist/{authoring-C9uDdZ2F.d.ts → authoring-DDh3muGT.d.ts} +61 -26
  4. package/dist/authoring.d.ts +3 -3
  5. package/dist/authoring.js +8 -5
  6. package/dist/chunk-34FQGGD7.js +34 -0
  7. package/dist/chunk-3GEJYGZK.js +84 -0
  8. package/dist/{chunk-MC6ZKFSG.js → chunk-5XEFJBN2.js} +25 -103
  9. package/dist/{chunk-QGJFZMD5.js → chunk-6UZFVXQF.js} +17 -101
  10. package/dist/{chunk-NNY6LMSC.js → chunk-77U6SH5A.js} +1 -1
  11. package/dist/{chunk-YN6WOTBF.js → chunk-AYCMTRVC.js} +622 -79
  12. package/dist/{chunk-JQN6CRSC.js → chunk-CHY5YLLV.js} +11 -40
  13. package/dist/{chunk-5BKZJMZV.js → chunk-EZ5SNNFS.js} +79 -38
  14. package/dist/{chunk-3OTECDNH.js → chunk-FULEQIRQ.js} +31 -23
  15. package/dist/{chunk-2ILTJC35.js → chunk-LQMDV75O.js} +205 -11
  16. package/dist/{chunk-IPOFBAIM.js → chunk-LX437ZTY.js} +439 -154
  17. package/dist/chunk-MHGCPC2V.js +35 -0
  18. package/dist/chunk-NZ5WCMTY.js +91 -0
  19. package/dist/chunk-TXRWKSNH.js +927 -0
  20. package/dist/{chunk-5TIF3FIE.js → chunk-UXJ5OO6P.js} +16 -14
  21. package/dist/index.d.ts +125 -129
  22. package/dist/index.js +180 -73
  23. package/dist/manifest.json +6 -0
  24. package/dist/providers/imessage/index.d.ts +6 -14
  25. package/dist/providers/imessage/index.js +9 -6
  26. package/dist/providers/index.d.ts +5 -2
  27. package/dist/providers/index.js +18 -10
  28. package/dist/providers/slack/index.d.ts +1 -2
  29. package/dist/providers/slack/index.js +5 -4
  30. package/dist/providers/telegram/index.d.ts +45 -0
  31. package/dist/providers/telegram/index.js +13 -0
  32. package/dist/providers/terminal/index.d.ts +18 -422
  33. package/dist/providers/terminal/index.js +7 -5
  34. package/dist/providers/whatsapp-business/index.d.ts +1 -1
  35. package/dist/providers/whatsapp-business/index.js +7 -5
  36. package/dist/types-BujGKBin.d.ts +82 -0
  37. package/dist/{types-DcQ5a7PK.d.ts → types-YqCNUDIt.d.ts} +204 -26
  38. package/package.json +3 -1
@@ -3,23 +3,25 @@ import {
3
3
  asPollOption
4
4
  } from "./chunk-2D27WW5B.js";
5
5
  import {
6
- cloud,
7
- mergeStreams,
8
- stream
9
- } from "./chunk-MC6ZKFSG.js";
6
+ cloud
7
+ } from "./chunk-3GEJYGZK.js";
10
8
  import {
11
9
  asContact
12
- } from "./chunk-QGJFZMD5.js";
10
+ } from "./chunk-NZ5WCMTY.js";
11
+ import {
12
+ mergeStreams,
13
+ stream
14
+ } from "./chunk-5XEFJBN2.js";
13
15
  import {
14
16
  UnsupportedError,
15
17
  definePlatform
16
- } from "./chunk-IPOFBAIM.js";
18
+ } from "./chunk-LX437ZTY.js";
17
19
  import {
18
20
  asAttachment,
19
21
  asCustom,
20
22
  asReaction,
21
23
  asText
22
- } from "./chunk-2ILTJC35.js";
24
+ } from "./chunk-LQMDV75O.js";
23
25
 
24
26
  // src/providers/whatsapp-business/index.ts
25
27
  import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
@@ -637,8 +639,7 @@ var send = async (clients, spaceId, content) => {
637
639
  );
638
640
  }
639
641
  if (content.type === "reaction") {
640
- await reactToMessage(clients, spaceId, content.target.id, content.emoji);
641
- return;
642
+ return await reactToMessage(clients, spaceId, content);
642
643
  }
643
644
  if (content.type === "typing") {
644
645
  return;
@@ -704,11 +705,12 @@ var send = async (clients, spaceId, content) => {
704
705
  throw UnsupportedError.content(content.type);
705
706
  }
706
707
  };
707
- var reactToMessage = async (clients, spaceId, messageId, reaction) => {
708
- await primary(clients).messages.send({
708
+ var reactToMessage = async (clients, spaceId, content) => {
709
+ const result = await primary(clients).messages.send({
709
710
  to: spaceId,
710
- reaction: { messageId, emoji: reaction }
711
+ reaction: { messageId: content.target.id, emoji: content.emoji }
711
712
  });
713
+ return toRecord(result, spaceId, content);
712
714
  };
713
715
  var replyToMessage = async (clients, spaceId, messageId, content) => {
714
716
  const client = primary(clients);
@@ -831,13 +833,13 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
831
833
  },
832
834
  space: {
833
835
  schema: spaceSchema,
834
- resolve: async ({ input }) => {
836
+ create: async ({ input }) => {
835
837
  if (input.users.length === 0) {
836
838
  throw new Error("WhatsApp space creation requires at least one user");
837
839
  }
838
840
  if (input.users.length > 1) {
839
841
  throw UnsupportedError.action(
840
- "createSpace",
842
+ "space.create",
841
843
  "WhatsApp Business",
842
844
  "only 1:1 conversations are supported"
843
845
  );
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- export { A as Attachment, a as AttachmentInput, b as attachment } from './attachment-DfWSZS5L.js';
1
+ export { A as Attachment, a as AttachmentInput, b as attachment } from './attachment-WePAHfcH.js';
2
2
  import z__default from 'zod';
3
3
  import { P as PhotoInput } from './photo-content-BJKnqgN-.js';
4
- import { C as ContentBuilder, M as Message, U as User, b as Space, c as ContentInput, e as Content, f as ProviderMessageRecord, g as SpaceActionFn, h as MessageActionFn, i as CreateClientContext, d as Store, P as Platform, a as PlatformDef, j as ProviderMessage, E as EventProducer, I as InstanceActionFn, k as PlatformProviderConfig, l as SpectrumLike, m as CustomEventStreams, A as AgentSender, n as ProjectData } from './types-DcQ5a7PK.js';
5
- export { o as AnyPlatformDef, B as Broadcaster, p as CloudPlatform, D as DedicatedTokenData, F as FusorTokenData, q as ImessageInfoData, r as ManagedStream, s as PlatformInstance, t as PlatformMessage, u as PlatformRuntime, v as PlatformSpace, w as PlatformStatus, x as PlatformUser, y as PlatformsData, z as ProjectProfile, S as SchemaMessage, G as SharedTokenData, H as SlackTeamMeta, J as SlackTokenData, K as SpectrumCloudError, L as SubscriptionData, N as SubscriptionStatus, T as TokenData, O as broadcast, Q as cloud, R as mergeStreams, V as stream } from './types-DcQ5a7PK.js';
6
- import { C as ContactInput, a as Contact } from './authoring-C9uDdZ2F.js';
7
- export { b as ContactAddress, c as ContactDetails, d as ContactEmail, e as ContactName, f as ContactOrg, g as ContactPhone, G as Group, P as Poll, h as PollChoice, i as PollChoiceInput, j as PollOption, R as Reaction, k as Richlink, V as Voice, l as contact, m as custom, n as group, o as option, p as poll, r as reaction, q as richlink, t as text, v as voice } from './authoring-C9uDdZ2F.js';
4
+ import { C as ContentBuilder, M as Message, U as User, e as Space, h as ContentInput, i as Content, g as ProviderMessage, E as EventProducer, j as SpaceActionFn, k as MessageActionFn, I as InstanceActionFn, l as CreateClientContext, c as Store, a as PlatformDef, P as Platform, m as PlatformProviderConfig, n as SpectrumLike, o as CustomEventStreams, A as AgentSender, b as ProjectData } from './types-YqCNUDIt.js';
5
+ export { p as AnyPlatformDef, B as Broadcaster, q as CloudPlatform, D as DedicatedTokenData, F as FusorTokenData, r as ImessageInfoData, s as ManagedStream, t as PlatformInstance, u as PlatformMessage, v as PlatformRuntime, w as PlatformSpace, x as PlatformStatus, y as PlatformUser, z as PlatformsData, G as ProjectProfile, R as Reaction, H as ReactionBuilder, S as SchemaMessage, J as SharedTokenData, K as SlackTeamMeta, L as SlackTokenData, N as SpaceNamespace, O as SpectrumCloudError, Q as SubscriptionData, T as SubscriptionStatus, V as TokenData, W as broadcast, X as cloud, Y as mergeStreams, Z as reaction, _ as stream } from './types-YqCNUDIt.js';
6
+ import { S as StreamTextSource, T as TextStreamOptions, C as ContactInput, a as Contact } from './authoring-DDh3muGT.js';
7
+ export { b as ContactAddress, c as ContactDetails, d as ContactEmail, e as ContactName, f as ContactOrg, g as ContactPhone, D as DeltaExtractor, G as Group, P as Poll, h as PollChoice, i as PollChoiceInput, j as PollOption, R as Richlink, k as StreamText, V as Voice, l as contact, m as custom, n as group, o as option, p as poll, r as richlink, t as text, v as voice } from './authoring-DDh3muGT.js';
8
+ import { a as FusorVerify, F as FusorClient, b as FusorMessages, W as WebhookHandler, c as WebhookRawRequest, d as WebhookRawResult } from './types-BujGKBin.js';
9
+ export { e as FusorEvent, f as FusorMessagesCtx, g as FusorMessagesReturn, h as FusorReply, i as FusorRespond, j as FusorVerifyRequest, k as fusorEvent, l as isFusorEvent } from './types-BujGKBin.js';
8
10
  import 'hotscript';
9
11
  import 'vcf';
10
12
 
@@ -65,7 +67,7 @@ declare function avatar(input: Buffer, options: {
65
67
  * (no new message id is produced; the existing message mutates in place).
66
68
  *
67
69
  * Edit cannot wrap `edit`, `reply`, `reaction`, `group`, `typing`, `rename`,
68
- * or `avatar` content.
70
+ * `avatar`, or `unsend` content.
69
71
  */
70
72
  declare const editSchema: z__default.ZodObject<{
71
73
  type: z__default.ZodLiteral<"edit">;
@@ -81,6 +83,9 @@ declare const editSchema: z__default.ZodObject<{
81
83
  } | {
82
84
  type: "text";
83
85
  text: string;
86
+ } | {
87
+ type: "markdown";
88
+ markdown: string;
84
89
  } | {
85
90
  type: "attachment";
86
91
  id: string;
@@ -89,6 +94,10 @@ declare const editSchema: z__default.ZodObject<{
89
94
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
90
95
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
91
96
  size?: number | undefined;
97
+ } | {
98
+ type: "streamText";
99
+ stream: () => AsyncIterable<string>;
100
+ format?: "markdown" | "plain" | undefined;
92
101
  } | {
93
102
  type: "custom";
94
103
  raw: unknown;
@@ -185,6 +194,9 @@ declare const editSchema: z__default.ZodObject<{
185
194
  content: {
186
195
  type: "text";
187
196
  text: string;
197
+ } | {
198
+ type: "markdown";
199
+ markdown: string;
188
200
  } | {
189
201
  type: "attachment";
190
202
  id: string;
@@ -213,6 +225,9 @@ declare const editSchema: z__default.ZodObject<{
213
225
  } | {
214
226
  type: "text";
215
227
  text: string;
228
+ } | {
229
+ type: "markdown";
230
+ markdown: string;
216
231
  } | {
217
232
  type: "attachment";
218
233
  id: string;
@@ -221,6 +236,10 @@ declare const editSchema: z__default.ZodObject<{
221
236
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
222
237
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
223
238
  size?: number | undefined;
239
+ } | {
240
+ type: "streamText";
241
+ stream: () => AsyncIterable<string>;
242
+ format?: "markdown" | "plain" | undefined;
224
243
  } | {
225
244
  type: "custom";
226
245
  raw: unknown;
@@ -317,6 +336,9 @@ declare const editSchema: z__default.ZodObject<{
317
336
  content: {
318
337
  type: "text";
319
338
  text: string;
339
+ } | {
340
+ type: "markdown";
341
+ markdown: string;
320
342
  } | {
321
343
  type: "attachment";
322
344
  id: string;
@@ -344,7 +366,38 @@ type Edit = z__default.infer<typeof editSchema>;
344
366
  * this with an inbound target throws at build time so the misuse surfaces
345
367
  * before the send pipeline runs.
346
368
  */
347
- declare function edit(content: ContentInput, target: Message): ContentBuilder;
369
+ declare function edit(content: ContentInput, target: Message | undefined): ContentBuilder;
370
+
371
+ /**
372
+ * Styled text written in standard markdown (CommonMark plus GFM tables and
373
+ * strikethrough). Outbound-only by design: inbound messages always surface as
374
+ * `text` content — no provider maps platform formatting back to markdown.
375
+ * Each platform renders the markdown to its native format (Telegram: HTML via
376
+ * `parse_mode`; remote iMessage: styled text via UTF-16 formatting ranges);
377
+ * platforms without native support receive readable plain text via the send
378
+ * pipeline's markdown fallback.
379
+ */
380
+ declare const markdownSchema: z__default.ZodObject<{
381
+ type: z__default.ZodLiteral<"markdown">;
382
+ markdown: z__default.ZodString;
383
+ }, z__default.core.$strip>;
384
+ type Markdown = z__default.infer<typeof markdownSchema>;
385
+ /**
386
+ * Send styled text written in standard markdown — a static string or a
387
+ * streaming LLM response.
388
+ *
389
+ * - `markdown("**hi**")` sends the markdown as one message.
390
+ * - `markdown(source)` marks a text stream as markdown: platforms with native
391
+ * support stream it styled (Telegram renders drafts and the final message
392
+ * via `parse_mode`), and everywhere else the accumulated text falls back
393
+ * through the markdown chain instead of surfacing raw `**` markers.
394
+ *
395
+ * Stream sources and options work exactly as in `text()` — any SDK streaming
396
+ * result or `AsyncIterable` / `ReadableStream`, with `options.extract` for
397
+ * unrecognized chunk shapes.
398
+ */
399
+ declare function markdown(source: string): ContentBuilder;
400
+ declare function markdown<T = unknown>(source: StreamTextSource<T>, options?: TextStreamOptions<T>): ContentBuilder;
348
401
 
349
402
  /**
350
403
  * Rename the current chat. Universal content — providers dispatch by
@@ -374,7 +427,7 @@ declare function rename(displayName: string): ContentBuilder;
374
427
  * `reply` like any other content type and route to a threaded send.
375
428
  *
376
429
  * Reply cannot wrap `reply`, `edit`, `reaction`, `group`, `typing`,
377
- * `rename`, or `avatar` content.
430
+ * `rename`, `avatar`, or `unsend` content.
378
431
  */
379
432
  declare const replySchema: z__default.ZodObject<{
380
433
  type: z__default.ZodLiteral<"reply">;
@@ -390,6 +443,9 @@ declare const replySchema: z__default.ZodObject<{
390
443
  } | {
391
444
  type: "text";
392
445
  text: string;
446
+ } | {
447
+ type: "markdown";
448
+ markdown: string;
393
449
  } | {
394
450
  type: "attachment";
395
451
  id: string;
@@ -398,6 +454,10 @@ declare const replySchema: z__default.ZodObject<{
398
454
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
399
455
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
400
456
  size?: number | undefined;
457
+ } | {
458
+ type: "streamText";
459
+ stream: () => AsyncIterable<string>;
460
+ format?: "markdown" | "plain" | undefined;
401
461
  } | {
402
462
  type: "custom";
403
463
  raw: unknown;
@@ -494,6 +554,9 @@ declare const replySchema: z__default.ZodObject<{
494
554
  content: {
495
555
  type: "text";
496
556
  text: string;
557
+ } | {
558
+ type: "markdown";
559
+ markdown: string;
497
560
  } | {
498
561
  type: "attachment";
499
562
  id: string;
@@ -522,6 +585,9 @@ declare const replySchema: z__default.ZodObject<{
522
585
  } | {
523
586
  type: "text";
524
587
  text: string;
588
+ } | {
589
+ type: "markdown";
590
+ markdown: string;
525
591
  } | {
526
592
  type: "attachment";
527
593
  id: string;
@@ -530,6 +596,10 @@ declare const replySchema: z__default.ZodObject<{
530
596
  read: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
531
597
  stream: z__default.core.$InferOuterFunctionType<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
532
598
  size?: number | undefined;
599
+ } | {
600
+ type: "streamText";
601
+ stream: () => AsyncIterable<string>;
602
+ format?: "markdown" | "plain" | undefined;
533
603
  } | {
534
604
  type: "custom";
535
605
  raw: unknown;
@@ -626,6 +696,9 @@ declare const replySchema: z__default.ZodObject<{
626
696
  content: {
627
697
  type: "text";
628
698
  text: string;
699
+ } | {
700
+ type: "markdown";
701
+ markdown: string;
629
702
  } | {
630
703
  type: "attachment";
631
704
  id: string;
@@ -646,13 +719,13 @@ declare const replySchema: z__default.ZodObject<{
646
719
  target: z__default.ZodCustom<Message<string, User, Space<unknown>>, Message<string, User, Space<unknown>>>;
647
720
  }, z__default.core.$strip>;
648
721
  type Reply = z__default.infer<typeof replySchema>;
649
- declare function reply(content: ContentInput, target: Message): ContentBuilder;
722
+ declare function reply(content: ContentInput, target: Message | undefined): ContentBuilder;
650
723
 
651
724
  declare const resolveContents: (items: readonly ContentInput[]) => Promise<Content[]>;
652
725
 
653
726
  /**
654
727
  * A `typing` content value carries a typing-indicator signal — either
655
- * `"start"` or `"stop"`. Like `reaction`, it's fire-and-forget: providers
728
+ * `"start"` or `"stop"`. Like `edit`, it's fire-and-forget: providers
656
729
  * dispatch on `content.type === "typing"` inside their `send()` action and
657
730
  * `space.send(typing(...))` resolves to `undefined`.
658
731
  *
@@ -677,6 +750,41 @@ type Typing = z__default.infer<typeof typingSchema>;
677
750
  */
678
751
  declare function typing(state?: "start" | "stop"): ContentBuilder;
679
752
 
753
+ /**
754
+ * An `unsend` retracts a previously-sent outbound message.
755
+ *
756
+ * `space.send(unsend(message))` is the canonical outbound API;
757
+ * `message.unsend()` and `space.unsend(message)` are sugar that delegate
758
+ * here. Unsends are fire-and-forget — providers handle them inside their
759
+ * `send` action and the resolved value is `undefined` (no new message id is
760
+ * produced; the existing message is retracted in place).
761
+ *
762
+ * Platform constraints surface from the provider at send time — e.g.
763
+ * iMessage enforces Apple's ~2-minute unsend window for regular messages
764
+ * (reaction removal is not time-limited), and a late or repeated unsend
765
+ * rejects with the provider's error. `space.getMessage(id)` results are
766
+ * wrapped as inbound, so a message cannot be unsent from a refetched id
767
+ * after a restart — keep the Message returned by `send` (same limitation
768
+ * as `edit`).
769
+ */
770
+ declare const unsendSchema: z__default.ZodObject<{
771
+ type: z__default.ZodLiteral<"unsend">;
772
+ target: z__default.ZodCustom<Message<string, User, Space<unknown>>, Message<string, User, Space<unknown>>>;
773
+ }, z__default.core.$strip>;
774
+ type Unsend = z__default.infer<typeof unsendSchema>;
775
+ /**
776
+ * Construct an `unsend` content value retracting `target`.
777
+ *
778
+ * Only outbound messages (those sent by the agent) can be unsent; calling
779
+ * this with an inbound target throws at build time so the misuse surfaces
780
+ * before the send pipeline runs.
781
+ *
782
+ * Accepts `Message | undefined` so `space.send` results chain without
783
+ * narrowing (`send` resolves `undefined` when a platform skips unsupported
784
+ * content); an undefined target throws at build time.
785
+ */
786
+ declare function unsend(target: Message | undefined): ContentBuilder;
787
+
680
788
  declare const Emoji: {
681
789
  readonly love: "❤️";
682
790
  readonly like: "👍";
@@ -2601,66 +2709,6 @@ declare const Emoji: {
2601
2709
  };
2602
2710
  type EmojiKey = keyof typeof Emoji;
2603
2711
 
2604
- interface FusorVerifyRequest {
2605
- headers: Record<string, string>;
2606
- method: string;
2607
- path: string;
2608
- rawBody: Uint8Array;
2609
- }
2610
- type FusorVerify<TPayload = unknown> = (req: FusorVerifyRequest) => TPayload | Promise<TPayload>;
2611
- interface FusorReply {
2612
- body?: string | Uint8Array;
2613
- headers?: Record<string, string>;
2614
- status?: number;
2615
- }
2616
- type FusorRespond = (reply: FusorReply) => void;
2617
- interface FusorMessagesCtx<TPayload> {
2618
- payload: TPayload;
2619
- respond: FusorRespond;
2620
- }
2621
- type FusorMessagesReturn = ProviderMessageRecord | ProviderMessageRecord[] | undefined;
2622
- type FusorMessages<TPayload> = (ctx: FusorMessagesCtx<TPayload>) => FusorMessagesReturn | Promise<FusorMessagesReturn>;
2623
- declare const FUSOR_BRAND: unique symbol;
2624
- interface FusorClient<TPayload = unknown> {
2625
- readonly platform: string;
2626
- readonly verify: FusorVerify<TPayload>;
2627
- readonly [FUSOR_BRAND]: true;
2628
- }
2629
- /**
2630
- * Request-scoped handler invoked once per inbound message that
2631
- * `spectrum.webhook()` resolves. Receives the same fully-built `[space,
2632
- * message]` pair that `spectrum.messages` yields.
2633
- *
2634
- * Runs **fire-and-forget**: it is dispatched after the HTTP response (the
2635
- * platform's `respond()` reply) has already been computed, so its outcome never
2636
- * affects the response, and a throw is caught + logged rather than surfaced —
2637
- * mirroring the body of a `for await (… of spectrum.messages)` loop.
2638
- *
2639
- * On a long-running server the event loop keeps the handler alive. On
2640
- * serverless/edge runtimes the function may be frozen once the response is
2641
- * returned, so keeping background work alive is the caller's responsibility —
2642
- * the usual pattern is to enqueue the work and process it in a separate worker.
2643
- */
2644
- type WebhookHandler = (space: Space, message: Message) => void | Promise<void>;
2645
- /**
2646
- * Raw webhook input for HTTP servers without Web `Request`/`Response` (Express,
2647
- * raw Node). `body` MUST be the exact bytes fusor POSTed — never a re-encoded
2648
- * JSON/text body — so the protobuf decode works. `headers` are accepted (so the
2649
- * natural `{ headers: req.headers, body: req.body }` shape keeps working) but are
2650
- * not read: inbound authenticity is established by the per-platform `verify()`,
2651
- * which reads the inner request reconstructed from the envelope.
2652
- */
2653
- interface WebhookRawRequest {
2654
- body: Uint8Array | ArrayBuffer;
2655
- headers?: Record<string, string>;
2656
- }
2657
- /** Raw webhook result, written back by the caller as the HTTP response. */
2658
- interface WebhookRawResult {
2659
- body: Uint8Array;
2660
- headers: Record<string, string>;
2661
- status: number;
2662
- }
2663
-
2664
2712
  declare function fusor<TPayload>(platform: string, verify: FusorVerify<TPayload>): FusorClient<TPayload>;
2665
2713
  declare function isFusorClient(value: unknown): value is FusorClient;
2666
2714
 
@@ -2682,12 +2730,13 @@ declare function definePlatform<_Name extends string, _ConfigSchema extends z__d
2682
2730
  } & Omit<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events, _SpaceActions, _MessageActions, _Actions>, "lifecycle" | "name"> & {
2683
2731
  static?: _Static;
2684
2732
  }): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events, _SpaceActions, _MessageActions, _Actions>> & Readonly<_Static>;
2685
- declare function defineFusorPlatform<_Name extends string, _ConfigSchema extends z__default.ZodType<object>, _UserSchema extends z__default.ZodType<object> | undefined, _SpaceSchema extends z__default.ZodType<object> | undefined, _SpaceParamsSchema extends z__default.ZodType<object> | undefined, _TPayload, _ResolvedUser extends {
2733
+ declare function definePlatform<_Name extends string, _ConfigSchema extends z__default.ZodType<object>, _UserSchema extends z__default.ZodType<object> | undefined, _SpaceSchema extends z__default.ZodType<object> | undefined, _SpaceParamsSchema extends z__default.ZodType<object> | undefined, _TPayload, _ResolvedUser extends {
2686
2734
  id: string;
2687
2735
  }, _ResolvedSpace extends {
2688
2736
  id: string;
2689
- }, _MessageSchema extends z__default.ZodType<object> | undefined = undefined, _Static extends Record<string, unknown> = Record<never, never>, _SpaceActions extends Record<string, SpaceActionFn> = Record<never, never>, _MessageActions extends Record<string, MessageActionFn> = Record<never, never>>(name: _Name, def: {
2690
- config: _ConfigSchema;
2737
+ }, _MessageSchema extends z__default.ZodType<object> | undefined = undefined, _FusorEvents extends (Record<string, z__default.ZodType<object>> & {
2738
+ messages?: never;
2739
+ }) | undefined = undefined, _Static extends Record<string, unknown> = Record<never, never>, _SpaceActions extends Record<string, SpaceActionFn> = Record<never, never>, _MessageActions extends Record<string, MessageActionFn> = Record<never, never>>(name: _Name, def: Omit<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, FusorClient<_TPayload>, _ResolvedUser, _ResolvedSpace, _MessageSchema, ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>>, _FusorEvents, _SpaceActions, _MessageActions>, "lifecycle" | "name" | "messages"> & {
2691
2740
  lifecycle: {
2692
2741
  createClient: (ctx: CreateClientContext<_ConfigSchema>) => Promise<FusorClient<_TPayload>>;
2693
2742
  destroyClient?: (ctx: {
@@ -2695,62 +2744,9 @@ declare function defineFusorPlatform<_Name extends string, _ConfigSchema extends
2695
2744
  store: Store;
2696
2745
  }) => Promise<void>;
2697
2746
  };
2698
- user: {
2699
- schema?: _UserSchema;
2700
- resolve: (_: {
2701
- input: {
2702
- userID: string;
2703
- };
2704
- client: FusorClient<_TPayload>;
2705
- config: z__default.infer<_ConfigSchema>;
2706
- store: Store;
2707
- }) => Promise<_ResolvedUser>;
2708
- };
2709
- space: {
2710
- schema?: _SpaceSchema;
2711
- params?: _SpaceParamsSchema;
2712
- resolve: (_: {
2713
- input: {
2714
- users: (_ResolvedUser & {
2715
- __platform: _Name;
2716
- })[];
2717
- params?: _SpaceParamsSchema extends z__default.ZodType<object> ? z__default.infer<_SpaceParamsSchema> : undefined;
2718
- };
2719
- client: FusorClient<_TPayload>;
2720
- config: z__default.infer<_ConfigSchema>;
2721
- store: Store;
2722
- }) => Promise<_ResolvedSpace>;
2723
- actions?: _SpaceActions;
2724
- };
2725
- message?: {
2726
- schema?: _MessageSchema;
2727
- actions?: _MessageActions;
2728
- };
2729
- messages: FusorMessages<_TPayload>;
2730
- send: (_: {
2731
- space: _ResolvedSpace & {
2732
- id: string;
2733
- __platform: _Name;
2734
- };
2735
- content: Content;
2736
- client: FusorClient<_TPayload>;
2737
- config: z__default.infer<_ConfigSchema>;
2738
- store: Store;
2739
- }) => Promise<ProviderMessageRecord | undefined>;
2740
- actions?: {
2741
- getMessage?: (_: {
2742
- space: _ResolvedSpace & {
2743
- id: string;
2744
- __platform: _Name;
2745
- };
2746
- messageId: string;
2747
- client: FusorClient<_TPayload>;
2748
- config: z__default.infer<_ConfigSchema>;
2749
- store: Store;
2750
- }) => Promise<unknown>;
2751
- };
2747
+ messages: FusorMessages<_TPayload, z__default.infer<_ConfigSchema>>;
2752
2748
  static?: _Static;
2753
- }): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, FusorClient<_TPayload>, _ResolvedUser, _ResolvedSpace, _MessageSchema, ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>>, undefined, _SpaceActions, _MessageActions>> & Readonly<_Static>;
2749
+ }): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, FusorClient<_TPayload>, _ResolvedUser, _ResolvedSpace, _MessageSchema, ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>>, _FusorEvents, _SpaceActions, _MessageActions>> & Readonly<_Static>;
2754
2750
 
2755
2751
  type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> = SpectrumLike<Providers> & CustomEventStreams<Providers> & {
2756
2752
  readonly messages: AsyncIterable<[Space, Message]>;
@@ -2837,4 +2833,4 @@ declare class UnsupportedError extends Error {
2837
2833
  declare const fromVCard: (vcf: string) => ContactInput;
2838
2834
  declare const toVCard: (contact: Contact) => Promise<string>;
2839
2835
 
2840
- export { AgentSender, type Avatar, type AvatarInput, Contact, ContactInput, Content, ContentBuilder, ContentInput, type Edit, Emoji, type EmojiKey, EventProducer, type FusorClient, type FusorMessages, type FusorMessagesCtx, type FusorMessagesReturn, type FusorReply, type FusorRespond, type FusorVerify, type FusorVerifyRequest, Message, Platform, PlatformDef, PlatformProviderConfig, ProjectData, ProviderMessage, type Rename, type Reply, Space, Spectrum, type SpectrumInstance, type Typing, UnsupportedError, type UnsupportedKind, User, type WebhookHandler, type WebhookRawRequest, type WebhookRawResult, avatar, defineFusorPlatform, definePlatform, edit, fromVCard, fusor, isFusorClient, rename, reply, resolveContents, toVCard, typing };
2836
+ export { AgentSender, type Avatar, type AvatarInput, Contact, ContactInput, Content, ContentBuilder, ContentInput, type Edit, Emoji, type EmojiKey, EventProducer, FusorClient, FusorMessages, FusorVerify, type Markdown, Message, Platform, PlatformDef, PlatformProviderConfig, ProjectData, ProviderMessage, type Rename, type Reply, Space, Spectrum, type SpectrumInstance, StreamTextSource, TextStreamOptions, type Typing, type Unsend, UnsupportedError, type UnsupportedKind, User, WebhookHandler, WebhookRawRequest, WebhookRawResult, avatar, definePlatform, edit, fromVCard, fusor, isFusorClient, markdown, rename, reply, resolveContents, toVCard, typing, unsend };