spectrum-ts 1.1.0 → 1.1.2

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.
@@ -1,4 +1,4 @@
1
- import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-DJQLFwWW.js';
1
+ import { d as Platform, c as PlatformDef, P as ProviderMessage, M as Message } from '../../types-GhOtIIqj.js';
2
2
  import z__default from 'zod';
3
3
  import 'hotscript';
4
4
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  asVoice
3
- } from "../../chunk-7Q7KJKGL.js";
3
+ } from "../../chunk-QZ5DJ7VR.js";
4
4
  import {
5
5
  UnsupportedError,
6
6
  asAttachment,
@@ -10,7 +10,7 @@ import {
10
10
  fromVCard,
11
11
  reactionSchema,
12
12
  toVCard
13
- } from "../../chunk-XMAI2AAN.js";
13
+ } from "../../chunk-5GQ2OMFY.js";
14
14
 
15
15
  // src/providers/terminal/index.ts
16
16
  import { spawn } from "child_process";
@@ -601,6 +601,14 @@ function parseTimestamp(s) {
601
601
  const t = Date.parse(s);
602
602
  return Number.isNaN(t) ? /* @__PURE__ */ new Date() : new Date(t);
603
603
  }
604
+ function buildOutboundRecord(result, content, spaceId) {
605
+ return {
606
+ id: result.id,
607
+ content,
608
+ space: { id: spaceId },
609
+ timestamp: parseTimestamp(result.timestamp)
610
+ };
611
+ }
604
612
  function reactionTargetFromProtocol(reaction) {
605
613
  const target = {
606
614
  id: reaction.messageId,
@@ -810,7 +818,7 @@ var terminal = definePlatform("terminal", {
810
818
  "send",
811
819
  { spaceId: space.id, content: proto }
812
820
  );
813
- return { id: result.id, timestamp: parseTimestamp(result.timestamp) };
821
+ return buildOutboundRecord(result, content, space.id);
814
822
  },
815
823
  startTyping: async ({ client, space }) => {
816
824
  const c = client;
@@ -835,7 +843,7 @@ var terminal = definePlatform("terminal", {
835
843
  "replyToMessage",
836
844
  { spaceId: space.id, messageId, content: proto }
837
845
  );
838
- return { id: result.id, timestamp: parseTimestamp(result.timestamp) };
846
+ return buildOutboundRecord(result, content, space.id);
839
847
  }
840
848
  }
841
849
  });
@@ -1,8 +1,7 @@
1
- import { M as ManagedStream } from '../../stream-B55k7W8-.js';
1
+ import { o as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage, i as ManagedStream } from '../../types-GhOtIIqj.js';
2
2
  import { WhatsAppClient } from '@photon-ai/whatsapp-business';
3
3
  import * as z from 'zod';
4
4
  import z__default from 'zod';
5
- import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DJQLFwWW.js';
6
5
  import * as zod_v4_core from 'zod/v4/core';
7
6
  import 'hotscript';
8
7
 
@@ -3,7 +3,7 @@ import {
3
3
  cloud,
4
4
  mergeStreams,
5
5
  stream
6
- } from "../../chunk-PXX7ISZ6.js";
6
+ } from "../../chunk-FF2R4EP3.js";
7
7
  import {
8
8
  UnsupportedError,
9
9
  asAttachment,
@@ -12,7 +12,7 @@ import {
12
12
  asReaction,
13
13
  asText,
14
14
  definePlatform
15
- } from "../../chunk-XMAI2AAN.js";
15
+ } from "../../chunk-5GQ2OMFY.js";
16
16
 
17
17
  // src/providers/whatsapp-business/index.ts
18
18
  import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
@@ -266,8 +266,11 @@ var primary = (clients) => {
266
266
  }
267
267
  return client;
268
268
  };
269
- var toSendResult = (result) => ({
270
- id: result.messageId
269
+ var toRecord = (result, spaceId, content) => ({
270
+ id: result.messageId,
271
+ content,
272
+ space: { id: spaceId },
273
+ timestamp: /* @__PURE__ */ new Date()
271
274
  });
272
275
  var MAX_POLL_CACHE_SIZE = 1e3;
273
276
  var OPTION_ID_PREFIX = "opt_";
@@ -622,8 +625,10 @@ var send = async (clients, spaceId, content) => {
622
625
  const client = primary(clients);
623
626
  switch (content.type) {
624
627
  case "text":
625
- return toSendResult(
626
- await client.messages.send({ to: spaceId, text: content.text })
628
+ return toRecord(
629
+ await client.messages.send({ to: spaceId, text: content.text }),
630
+ spaceId,
631
+ content
627
632
  );
628
633
  case "attachment": {
629
634
  const { mediaId } = await client.media.upload({
@@ -633,19 +638,23 @@ var send = async (clients, spaceId, content) => {
633
638
  });
634
639
  const mediaType = mimeToMediaType(content.mimeType);
635
640
  const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
636
- return toSendResult(
641
+ return toRecord(
637
642
  await client.messages.send({
638
643
  to: spaceId,
639
644
  [mediaType]: mediaPayload
640
- })
645
+ }),
646
+ spaceId,
647
+ content
641
648
  );
642
649
  }
643
650
  case "contact":
644
- return toSendResult(
651
+ return toRecord(
645
652
  await client.messages.send({
646
653
  to: spaceId,
647
654
  contacts: [contactToWa(content)]
648
- })
655
+ }),
656
+ spaceId,
657
+ content
649
658
  );
650
659
  case "voice": {
651
660
  const { mediaId } = await client.media.upload({
@@ -653,11 +662,13 @@ var send = async (clients, spaceId, content) => {
653
662
  mimeType: content.mimeType,
654
663
  filename: voiceFilename(content)
655
664
  });
656
- return toSendResult(
665
+ return toRecord(
657
666
  await client.messages.send({
658
667
  to: spaceId,
659
668
  audio: { id: mediaId }
660
- })
669
+ }),
670
+ spaceId,
671
+ content
661
672
  );
662
673
  }
663
674
  case "poll": {
@@ -666,7 +677,7 @@ var send = async (clients, spaceId, content) => {
666
677
  interactive: pollToInteractive(content)
667
678
  });
668
679
  cachePoll(client, result.messageId, content);
669
- return toSendResult(result);
680
+ return toRecord(result, spaceId, content);
670
681
  }
671
682
  default:
672
683
  throw UnsupportedError.content(content.type);
@@ -682,12 +693,14 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
682
693
  const client = primary(clients);
683
694
  switch (content.type) {
684
695
  case "text":
685
- return toSendResult(
696
+ return toRecord(
686
697
  await client.messages.send({
687
698
  to: spaceId,
688
699
  replyTo: messageId,
689
700
  text: content.text
690
- })
701
+ }),
702
+ spaceId,
703
+ content
691
704
  );
692
705
  case "attachment": {
693
706
  const { mediaId } = await client.media.upload({
@@ -697,21 +710,25 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
697
710
  });
698
711
  const mediaType = mimeToMediaType(content.mimeType);
699
712
  const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
700
- return toSendResult(
713
+ return toRecord(
701
714
  await client.messages.send({
702
715
  to: spaceId,
703
716
  replyTo: messageId,
704
717
  [mediaType]: mediaPayload
705
- })
718
+ }),
719
+ spaceId,
720
+ content
706
721
  );
707
722
  }
708
723
  case "contact":
709
- return toSendResult(
724
+ return toRecord(
710
725
  await client.messages.send({
711
726
  to: spaceId,
712
727
  replyTo: messageId,
713
728
  contacts: [contactToWa(content)]
714
- })
729
+ }),
730
+ spaceId,
731
+ content
715
732
  );
716
733
  case "voice": {
717
734
  const { mediaId } = await client.media.upload({
@@ -719,12 +736,14 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
719
736
  mimeType: content.mimeType,
720
737
  filename: voiceFilename(content)
721
738
  });
722
- return toSendResult(
739
+ return toRecord(
723
740
  await client.messages.send({
724
741
  to: spaceId,
725
742
  replyTo: messageId,
726
743
  audio: { id: mediaId }
727
- })
744
+ }),
745
+ spaceId,
746
+ content
728
747
  );
729
748
  }
730
749
  case "poll": {
@@ -734,7 +753,7 @@ var replyToMessage = async (clients, spaceId, messageId, content) => {
734
753
  interactive: pollToInteractive(content)
735
754
  });
736
755
  cachePoll(client, result.messageId, content);
737
- return toSendResult(result);
756
+ return toRecord(result, spaceId, content);
738
757
  }
739
758
  default:
740
759
  throw UnsupportedError.content(content.type);
@@ -166,6 +166,18 @@ interface OutboundMessage<TPlatform extends string = string, TSender extends Use
166
166
  }
167
167
  type Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> = InboundMessage<TPlatform, TSender, TSpace> | OutboundMessage<TPlatform, TSender, TSpace>;
168
168
 
169
+ interface ManagedStream<T> extends AsyncIterable<T> {
170
+ close(): Promise<void>;
171
+ }
172
+ type StreamCleanup = void | (() => void | Promise<void>);
173
+ declare function stream<T>(setup: (emit: (value: T) => Promise<void>, end: (error?: unknown) => void) => StreamCleanup | Promise<StreamCleanup>): ManagedStream<T>;
174
+ declare function mergeStreams<T>(streams: readonly ManagedStream<T>[]): ManagedStream<T>;
175
+ interface Broadcaster<T> {
176
+ close(): Promise<void>;
177
+ subscribe(): ManagedStream<T>;
178
+ }
179
+ declare function broadcast<T>(source: ManagedStream<T>): Broadcaster<T>;
180
+
169
181
  type ResolvedSpace = Pick<Space, "id">;
170
182
  type SpaceRef = Pick<Space, "id" | "__platform">;
171
183
  type ResolvedUser = Pick<User, "id">;
@@ -187,19 +199,28 @@ type ProviderMessage<TSender extends ResolvedUser = ResolvedUser, TSpace extends
187
199
  space: TSpace;
188
200
  timestamp?: Date;
189
201
  } & TExtra;
190
- interface SendResult<TSender extends ResolvedUser = ResolvedUser> {
191
- /**
192
- * Per-item send receipts returned when the dispatched content was a
193
- * `group`. Providers that iterate native sends to emulate a group
194
- * (e.g. iMessage) populate this so the platform build layer can
195
- * replace the outbound group's placeholder items with real Messages
196
- * that carry each item's own id.
197
- */
198
- groupMembers?: SendResult<TSender>[];
202
+ /**
203
+ * A message a provider produced — used for both inbound (`events.messages`,
204
+ * `getMessage`) and outbound (`send`, `replyToMessage`) flows. Providers
205
+ * return their native record shape (including platform extras like
206
+ * `partIndex`/`parentId` for iMessage) and the platform `wrapProviderMessage`
207
+ * pipeline turns it into a fully-built Message.
208
+ *
209
+ * `sender` is optional because outbound sends often can't synthesize one
210
+ * (the SDK doesn't surface the bot's own handle); inbound providers are
211
+ * expected to populate it.
212
+ */
213
+ type ProviderMessageRecord = {
199
214
  id: string;
200
- sender?: TSender;
215
+ content: Content;
216
+ sender?: {
217
+ id: string;
218
+ } & Record<string, unknown>;
219
+ space: {
220
+ id: string;
221
+ } & Record<string, unknown>;
201
222
  timestamp?: Date;
202
- }
223
+ } & Record<string, unknown>;
203
224
  type MergeSchema<TSchema extends z__default.ZodType | undefined, TBase extends object> = TSchema extends z__default.ZodType ? string extends keyof z__default.infer<TSchema> ? TBase : Omit<z__default.infer<TSchema>, keyof TBase> & TBase : TBase;
204
225
  type SchemaMessage<TUserSchema extends z__default.ZodType | undefined = undefined, TSpaceSchema extends z__default.ZodType | undefined = undefined> = ProviderMessage<MergeSchema<TUserSchema, ResolvedUser>, MergeSchema<TSpaceSchema, ResolvedSpace>>;
205
226
  type InferEventPayload<T> = T extends (ctx: never) => AsyncIterable<infer P> ? P : never;
@@ -215,7 +236,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
215
236
  content: Content;
216
237
  client: _Client;
217
238
  config: z__default.infer<_ConfigSchema>;
218
- }) => Promise<SendResult<_ResolvedUser>>;
239
+ }) => Promise<ProviderMessageRecord>;
219
240
  startTyping?: (_: {
220
241
  space: _ResolvedSpace & SpaceRef;
221
242
  client: _Client;
@@ -236,10 +257,11 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
236
257
  replyToMessage?: (_: {
237
258
  space: _ResolvedSpace & SpaceRef;
238
259
  messageId: string;
260
+ target: _MessageType;
239
261
  content: Content;
240
262
  client: _Client;
241
263
  config: z__default.infer<_ConfigSchema>;
242
- }) => Promise<SendResult<_ResolvedUser>>;
264
+ }) => Promise<ProviderMessageRecord>;
243
265
  editMessage?: (_: {
244
266
  space: _ResolvedSpace & SpaceRef;
245
267
  messageId: string;
@@ -297,11 +319,11 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
297
319
  }
298
320
  interface AnyPlatformDef {
299
321
  actions: {
300
- send: (_: any) => Promise<SendResult>;
322
+ send: (_: any) => Promise<ProviderMessageRecord>;
301
323
  startTyping?: (_: any) => Promise<void>;
302
324
  stopTyping?: (_: any) => Promise<void>;
303
325
  reactToMessage?: (_: any) => Promise<void>;
304
- replyToMessage?: (_: any) => Promise<SendResult>;
326
+ replyToMessage?: (_: any) => Promise<ProviderMessageRecord>;
305
327
  editMessage?: (_: any) => Promise<void>;
306
328
  getMessage?: (_: any) => Promise<any>;
307
329
  };
@@ -379,20 +401,27 @@ type SpaceVarargArgs<Def extends AnyPlatformDef> = [
379
401
  type SpaceArgs<Def extends AnyPlatformDef> = SpaceArrayArgs<Def> | SpaceVarargArgs<Def>;
380
402
  type PlatformSpace<Def extends AnyPlatformDef> = Omit<SpaceShapeOf<Def>, keyof Space> & Space;
381
403
  type PlatformMessage<Def extends AnyPlatformDef> = Omit<SchemaInfer<Def["message"]>, keyof Message> & Message<Def["name"], PlatformUser<Def>, PlatformSpace<Def>>;
404
+ type InboundPlatformMessage<Def extends AnyPlatformDef> = Omit<SchemaInfer<Def["message"]>, keyof InboundMessage> & InboundMessage<Def["name"], PlatformUser<Def>, PlatformSpace<Def>>;
382
405
  type PlatformUser<Def extends AnyPlatformDef> = Omit<ResolvedUserOf<Def>, keyof User> & User;
383
406
  type PlatformInstance<Def extends AnyPlatformDef> = {
407
+ readonly messages: AsyncIterable<[
408
+ PlatformSpace<Def>,
409
+ InboundPlatformMessage<Def>
410
+ ]>;
384
411
  space(...args: SpaceArgs<Def>): Promise<PlatformSpace<Def>>;
385
412
  user(userID: string): Promise<PlatformUser<Def>>;
386
413
  } & {
387
414
  [K in Exclude<keyof Def["events"], "messages" | symbol | number> as K extends ReservedNames ? never : K]: AsyncIterable<InferEventPayload<Def["events"][K]>>;
388
415
  };
416
+ interface PlatformRuntime {
417
+ client: unknown;
418
+ config: unknown;
419
+ definition: AnyPlatformDef;
420
+ subscribeMessages: () => ManagedStream<[Space, InboundMessage]>;
421
+ }
389
422
  interface SpectrumLike<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> {
390
423
  readonly __internal: {
391
- platforms: Map<string, {
392
- client: unknown;
393
- config: unknown;
394
- definition: AnyPlatformDef;
395
- }>;
424
+ platforms: Map<string, PlatformRuntime>;
396
425
  };
397
426
  readonly __providers: Providers;
398
427
  }
@@ -403,4 +432,4 @@ interface Platform<Def extends AnyPlatformDef> {
403
432
  (message: Message): PlatformMessage<Def>;
404
433
  }
405
434
 
406
- export type { AnyPlatformDef as A, ContentBuilder as C, EventProducer as E, InboundMessage as I, Message as M, OutboundMessage as O, ProviderMessage as P, SpectrumLike as S, User as U, ContentInput as a, Content as b, PlatformDef as c, Platform as d, PlatformProviderConfig as e, CustomEventStreams as f, Space as g, PlatformInstance as h, PlatformMessage as i, PlatformSpace as j, PlatformUser as k, SchemaMessage as l };
435
+ export { type AnyPlatformDef as A, type Broadcaster as B, type ContentBuilder as C, type EventProducer as E, type InboundMessage as I, type Message as M, type OutboundMessage as O, type ProviderMessage as P, type SpectrumLike as S, type User as U, type ContentInput as a, type Content as b, type PlatformDef as c, type Platform as d, type PlatformProviderConfig as e, type CustomEventStreams as f, type Space as g, type InboundPlatformMessage as h, type ManagedStream as i, type PlatformInstance as j, type PlatformMessage as k, type PlatformRuntime as l, type PlatformSpace as m, type PlatformUser as n, type SchemaMessage as o, broadcast as p, mergeStreams as q, stream as s };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -19,7 +19,7 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@photon-ai/advanced-imessage": "^0.5.1",
22
+ "@photon-ai/advanced-imessage": "^0.6.0",
23
23
  "@photon-ai/imessage-kit": "^3.0.0",
24
24
  "@photon-ai/whatsapp-business": "^0.1.1",
25
25
  "@repeaterjs/repeater": "^3.0.6",
@@ -1,8 +0,0 @@
1
- interface ManagedStream<T> extends AsyncIterable<T> {
2
- close(): Promise<void>;
3
- }
4
- type StreamCleanup = void | (() => void | Promise<void>);
5
- declare function stream<T>(setup: (emit: (value: T) => Promise<void>, end: (error?: unknown) => void) => StreamCleanup | Promise<StreamCleanup>): ManagedStream<T>;
6
- declare function mergeStreams<T>(streams: readonly ManagedStream<T>[]): ManagedStream<T>;
7
-
8
- export { type ManagedStream as M, mergeStreams as m, stream as s };