spectrum-ts 1.7.2 → 1.8.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/dist/{chunk-VO43HJ5B.js → chunk-5NHNMN4H.js} +1 -1
- package/dist/{chunk-2SB6VN7J.js → chunk-N3ZKMTSG.js} +2 -2
- package/dist/{chunk-ZDNX3S3H.js → chunk-OM5VSKWD.js} +2 -2
- package/dist/{chunk-ET42EGIA.js → chunk-OR3VGVML.js} +1 -1
- package/dist/{chunk-VVXMZYDH.js → chunk-TN54TDTQ.js} +1 -1
- package/dist/{chunk-JWWIFSI7.js → chunk-XZSBR26X.js} +261 -89
- package/dist/index.d.ts +2 -0
- package/dist/index.js +152 -59
- package/dist/providers/imessage/index.js +3 -3
- package/dist/providers/index.js +6 -6
- package/dist/providers/terminal/index.js +3 -3
- package/dist/providers/whatsapp-business/index.js +2 -2
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
asVoice
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TN54TDTQ.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-
|
|
13
|
+
} from "./chunk-XZSBR26X.js";
|
|
14
14
|
|
|
15
15
|
// src/providers/terminal/index.ts
|
|
16
16
|
import { spawn } from "child_process";
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
asGroup,
|
|
3
3
|
asRichlink,
|
|
4
4
|
groupSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-5NHNMN4H.js";
|
|
6
6
|
import {
|
|
7
7
|
asPoll,
|
|
8
8
|
asPollOption,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
text,
|
|
25
25
|
textSchema,
|
|
26
26
|
toVCard
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-XZSBR26X.js";
|
|
28
28
|
|
|
29
29
|
// src/providers/imessage/index.ts
|
|
30
30
|
import { createClient as createClient2, MessageEffect as MessageEffect2 } from "@photon-ai/advanced-imessage";
|
|
@@ -710,7 +710,125 @@ var UnsupportedError = class _UnsupportedError extends Error {
|
|
|
710
710
|
}
|
|
711
711
|
};
|
|
712
712
|
|
|
713
|
+
// src/platform/define.ts
|
|
714
|
+
import { withSpan as withSpan2 } from "@photon-ai/otel";
|
|
715
|
+
|
|
716
|
+
// src/utils/identifier.ts
|
|
717
|
+
import { sanitizeEmail, sanitizePhone } from "@photon-ai/otel";
|
|
718
|
+
var PHONE_LIKE = /^\+?[\d\s()\-.]{7,}$/;
|
|
719
|
+
var EMAIL_LIKE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
720
|
+
function classifyIdentifier(s) {
|
|
721
|
+
if (EMAIL_LIKE.test(s)) {
|
|
722
|
+
return { kind: "email", identifier: sanitizeEmail(s) };
|
|
723
|
+
}
|
|
724
|
+
if (PHONE_LIKE.test(s) && s.replace(/\D/g, "").length >= 7) {
|
|
725
|
+
return { kind: "phone", identifier: sanitizePhone(s) };
|
|
726
|
+
}
|
|
727
|
+
return { kind: "unknown", identifier: s };
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// src/platform/build.ts
|
|
731
|
+
import { createLogger, withSpan } from "@photon-ai/otel";
|
|
732
|
+
|
|
733
|
+
// src/utils/telemetry.ts
|
|
734
|
+
var targetId = (target) => {
|
|
735
|
+
const id = target?.id;
|
|
736
|
+
return typeof id === "string" ? id : void 0;
|
|
737
|
+
};
|
|
738
|
+
var targetType = (target) => {
|
|
739
|
+
const type = target?.content?.type;
|
|
740
|
+
return typeof type === "string" ? type : void 0;
|
|
741
|
+
};
|
|
742
|
+
var replyOrEditAttrs = (content) => {
|
|
743
|
+
const target = content.target;
|
|
744
|
+
const inner = content.content;
|
|
745
|
+
const innerType = inner?.type;
|
|
746
|
+
return {
|
|
747
|
+
"spectrum.message.content.target.id": targetId(target),
|
|
748
|
+
"spectrum.message.content.target.type": targetType(target),
|
|
749
|
+
"spectrum.message.content.inner.type": typeof innerType === "string" ? innerType : void 0
|
|
750
|
+
};
|
|
751
|
+
};
|
|
752
|
+
var reactionAttrs = (content) => {
|
|
753
|
+
const target = content.target;
|
|
754
|
+
const emoji = content.emoji;
|
|
755
|
+
return {
|
|
756
|
+
"spectrum.message.content.target.id": targetId(target),
|
|
757
|
+
"spectrum.message.content.reaction.emoji": typeof emoji === "string" ? emoji : void 0
|
|
758
|
+
};
|
|
759
|
+
};
|
|
760
|
+
var groupAttrs = (content) => {
|
|
761
|
+
const items = content.items;
|
|
762
|
+
if (!Array.isArray(items)) {
|
|
763
|
+
return {};
|
|
764
|
+
}
|
|
765
|
+
const types = items.map((item) => {
|
|
766
|
+
const itemType = item?.content?.type;
|
|
767
|
+
return typeof itemType === "string" ? itemType : void 0;
|
|
768
|
+
}).filter((t) => t !== void 0);
|
|
769
|
+
return {
|
|
770
|
+
"spectrum.message.content.items.count": items.length,
|
|
771
|
+
"spectrum.message.content.items.types": types.length > 0 ? types.join(",") : void 0
|
|
772
|
+
};
|
|
773
|
+
};
|
|
774
|
+
var typingAttrs = (content) => {
|
|
775
|
+
const state = content.state;
|
|
776
|
+
return {
|
|
777
|
+
"spectrum.message.content.typing.state": typeof state === "string" ? state : void 0
|
|
778
|
+
};
|
|
779
|
+
};
|
|
780
|
+
var attachmentAttrs = (content) => {
|
|
781
|
+
const mime = content.mimeType;
|
|
782
|
+
const size = content.size;
|
|
783
|
+
return {
|
|
784
|
+
"spectrum.message.content.attachment.mime": typeof mime === "string" ? mime : void 0,
|
|
785
|
+
"spectrum.message.content.attachment.size": typeof size === "number" ? size : void 0
|
|
786
|
+
};
|
|
787
|
+
};
|
|
788
|
+
var voiceAttrs = (content) => {
|
|
789
|
+
const mime = content.mimeType;
|
|
790
|
+
const duration = content.duration;
|
|
791
|
+
const size = content.size;
|
|
792
|
+
return {
|
|
793
|
+
"spectrum.message.content.voice.mime": typeof mime === "string" ? mime : void 0,
|
|
794
|
+
"spectrum.message.content.voice.duration": typeof duration === "number" ? duration : void 0,
|
|
795
|
+
"spectrum.message.content.voice.size": typeof size === "number" ? size : void 0
|
|
796
|
+
};
|
|
797
|
+
};
|
|
798
|
+
var CONTENT_ATTR_HANDLERS = {
|
|
799
|
+
reply: replyOrEditAttrs,
|
|
800
|
+
edit: replyOrEditAttrs,
|
|
801
|
+
reaction: reactionAttrs,
|
|
802
|
+
group: groupAttrs,
|
|
803
|
+
typing: typingAttrs,
|
|
804
|
+
attachment: attachmentAttrs,
|
|
805
|
+
voice: voiceAttrs
|
|
806
|
+
};
|
|
807
|
+
function contentAttrs(content) {
|
|
808
|
+
const type = content?.type;
|
|
809
|
+
if (!(content && type)) {
|
|
810
|
+
return { "spectrum.message.content.type": void 0 };
|
|
811
|
+
}
|
|
812
|
+
const handler = CONTENT_ATTR_HANDLERS[type];
|
|
813
|
+
return {
|
|
814
|
+
"spectrum.message.content.type": type,
|
|
815
|
+
...handler ? handler(content) : {}
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function senderAttrs(sender) {
|
|
819
|
+
const id = sender?.id;
|
|
820
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
821
|
+
return {};
|
|
822
|
+
}
|
|
823
|
+
const { kind, identifier } = classifyIdentifier(id);
|
|
824
|
+
return {
|
|
825
|
+
"spectrum.message.sender.id": identifier,
|
|
826
|
+
"spectrum.message.sender.kind": kind
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
|
|
713
830
|
// src/platform/build.ts
|
|
831
|
+
var platformLog = createLogger("spectrum.platform");
|
|
714
832
|
var ANSI_YELLOW = "\x1B[33m";
|
|
715
833
|
var ANSI_RESET = "\x1B[0m";
|
|
716
834
|
var supportsAnsiColor = () => {
|
|
@@ -752,9 +870,14 @@ var warnUnsupported = (err, fallbackPlatform) => {
|
|
|
752
870
|
const platform = err.platform ?? fallbackPlatform;
|
|
753
871
|
const subject = err.kind === "content" ? `content type "${err.contentType ?? "unknown"}"` : `action "${err.action ?? "unknown"}"`;
|
|
754
872
|
const detail = err.detail ? `: ${err.detail}` : "";
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
873
|
+
platformLog.warn(
|
|
874
|
+
`${platform} does not support ${subject}${detail}; skipping.`,
|
|
875
|
+
{
|
|
876
|
+
"spectrum.provider": platform,
|
|
877
|
+
"spectrum.unsupported.kind": err.kind,
|
|
878
|
+
"spectrum.unsupported.content_type": err.contentType,
|
|
879
|
+
"spectrum.unsupported.action": err.action
|
|
880
|
+
}
|
|
758
881
|
);
|
|
759
882
|
};
|
|
760
883
|
var contentPlatform = (content) => {
|
|
@@ -879,38 +1002,49 @@ function buildSpace(params) {
|
|
|
879
1002
|
const { spaceRef, extras, actionCtx, definition, client, config, store } = params;
|
|
880
1003
|
let space;
|
|
881
1004
|
async function dispatchSend(item) {
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1005
|
+
return withSpan(
|
|
1006
|
+
"spectrum.message.send",
|
|
1007
|
+
{
|
|
1008
|
+
"spectrum.provider": definition.name,
|
|
1009
|
+
"spectrum.space.id": spaceRef.id,
|
|
1010
|
+
"spectrum.message.fire_and_forget": isFireAndForget(item),
|
|
1011
|
+
...contentAttrs(item)
|
|
1012
|
+
},
|
|
1013
|
+
async () => {
|
|
1014
|
+
let raw;
|
|
1015
|
+
try {
|
|
1016
|
+
const platformError = unsupportedPlatformContentError(
|
|
1017
|
+
item,
|
|
1018
|
+
definition.name
|
|
1019
|
+
);
|
|
1020
|
+
if (platformError) {
|
|
1021
|
+
throw platformError;
|
|
1022
|
+
}
|
|
1023
|
+
raw = await definition.send({
|
|
1024
|
+
...actionCtx,
|
|
1025
|
+
content: item
|
|
1026
|
+
});
|
|
1027
|
+
} catch (err) {
|
|
1028
|
+
if (err instanceof UnsupportedError) {
|
|
1029
|
+
warnUnsupported(err, definition.name);
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
throw err;
|
|
1033
|
+
}
|
|
1034
|
+
if (!raw?.id) {
|
|
1035
|
+
if (isFireAndForget(item)) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
throw new Error(
|
|
1039
|
+
`Platform "${definition.name}" send did not return a message id`
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
return wrapProviderMessage(
|
|
1043
|
+
raw,
|
|
1044
|
+
{ client, config, definition, space, spaceRef, store },
|
|
1045
|
+
"outbound"
|
|
1046
|
+
);
|
|
905
1047
|
}
|
|
906
|
-
throw new Error(
|
|
907
|
-
`Platform "${definition.name}" send did not return a message id`
|
|
908
|
-
);
|
|
909
|
-
}
|
|
910
|
-
return wrapProviderMessage(
|
|
911
|
-
raw,
|
|
912
|
-
{ client, config, definition, space, spaceRef, store },
|
|
913
|
-
"outbound"
|
|
914
1048
|
);
|
|
915
1049
|
}
|
|
916
1050
|
async function sendImpl(...content) {
|
|
@@ -936,29 +1070,39 @@ function buildSpace(params) {
|
|
|
936
1070
|
);
|
|
937
1071
|
return;
|
|
938
1072
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1073
|
+
return withSpan(
|
|
1074
|
+
"spectrum.message.get",
|
|
1075
|
+
{
|
|
1076
|
+
"spectrum.provider": definition.name,
|
|
1077
|
+
"spectrum.space.id": spaceRef.id,
|
|
1078
|
+
"spectrum.message.id": id
|
|
1079
|
+
},
|
|
1080
|
+
async () => {
|
|
1081
|
+
let raw;
|
|
1082
|
+
try {
|
|
1083
|
+
raw = await getMessage({
|
|
1084
|
+
space: spaceRef,
|
|
1085
|
+
messageId: id,
|
|
1086
|
+
client,
|
|
1087
|
+
config,
|
|
1088
|
+
store
|
|
1089
|
+
});
|
|
1090
|
+
} catch (err) {
|
|
1091
|
+
if (err instanceof UnsupportedError) {
|
|
1092
|
+
warnUnsupported(err, definition.name);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
throw err;
|
|
1096
|
+
}
|
|
1097
|
+
if (!raw) {
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
return wrapProviderMessage(
|
|
1101
|
+
raw,
|
|
1102
|
+
{ client, config, definition, space, spaceRef, store },
|
|
1103
|
+
"inbound"
|
|
1104
|
+
);
|
|
952
1105
|
}
|
|
953
|
-
throw err;
|
|
954
|
-
}
|
|
955
|
-
if (!raw) {
|
|
956
|
-
return;
|
|
957
|
-
}
|
|
958
|
-
return wrapProviderMessage(
|
|
959
|
-
raw,
|
|
960
|
-
{ client, config, definition, space, spaceRef, store },
|
|
961
|
-
"inbound"
|
|
962
1106
|
);
|
|
963
1107
|
}
|
|
964
1108
|
const platformActions = {};
|
|
@@ -1057,6 +1201,21 @@ function buildMessage(params) {
|
|
|
1057
1201
|
}
|
|
1058
1202
|
|
|
1059
1203
|
// src/platform/define.ts
|
|
1204
|
+
function classifySpaceIdentifier(args) {
|
|
1205
|
+
const stringArgs = args.filter((a) => typeof a === "string");
|
|
1206
|
+
if (stringArgs.length > 1) {
|
|
1207
|
+
return { kind: "group" };
|
|
1208
|
+
}
|
|
1209
|
+
const s = stringArgs[0];
|
|
1210
|
+
if (!s) {
|
|
1211
|
+
return { kind: "unknown" };
|
|
1212
|
+
}
|
|
1213
|
+
const { kind, identifier } = classifyIdentifier(s);
|
|
1214
|
+
if (kind === "unknown") {
|
|
1215
|
+
return { kind: "unknown" };
|
|
1216
|
+
}
|
|
1217
|
+
return { kind, identifier };
|
|
1218
|
+
}
|
|
1060
1219
|
function createPlatformInstance(def, runtime) {
|
|
1061
1220
|
const isPlatformUser = (value) => typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
1062
1221
|
const resolveUserID = async (userID) => {
|
|
@@ -1126,39 +1285,50 @@ function createPlatformInstance(def, runtime) {
|
|
|
1126
1285
|
};
|
|
1127
1286
|
},
|
|
1128
1287
|
async space(...args) {
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1288
|
+
const { kind, identifier } = classifySpaceIdentifier(args);
|
|
1289
|
+
return withSpan2(
|
|
1290
|
+
"spectrum.space.resolve",
|
|
1291
|
+
{
|
|
1292
|
+
"spectrum.provider": def.name,
|
|
1293
|
+
"spectrum.space.identifier_kind": kind,
|
|
1294
|
+
"spectrum.space.identifier": identifier
|
|
1295
|
+
},
|
|
1296
|
+
async () => {
|
|
1297
|
+
const convertedArgs = await resolveStringUsers(args);
|
|
1298
|
+
const { users, params } = normalizeSpaceArgs(convertedArgs);
|
|
1299
|
+
let parsedParams = params;
|
|
1300
|
+
if (params !== void 0 && def.space.params) {
|
|
1301
|
+
parsedParams = def.space.params.parse(params);
|
|
1302
|
+
}
|
|
1303
|
+
const resolved = await def.space.resolve({
|
|
1304
|
+
input: { users, params: parsedParams },
|
|
1305
|
+
client: runtime.client,
|
|
1306
|
+
config: runtime.config,
|
|
1307
|
+
store: runtime.store
|
|
1308
|
+
});
|
|
1309
|
+
const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
|
|
1310
|
+
const spaceRef = {
|
|
1311
|
+
...parsedSpace,
|
|
1312
|
+
id: parsedSpace.id,
|
|
1313
|
+
__platform: def.name
|
|
1314
|
+
};
|
|
1315
|
+
const actionCtx = {
|
|
1316
|
+
space: spaceRef,
|
|
1317
|
+
client: runtime.client,
|
|
1318
|
+
config: runtime.config,
|
|
1319
|
+
store: runtime.store
|
|
1320
|
+
};
|
|
1321
|
+
return buildSpace({
|
|
1322
|
+
spaceRef,
|
|
1323
|
+
extras: parsedSpace,
|
|
1324
|
+
actionCtx,
|
|
1325
|
+
definition: def,
|
|
1326
|
+
client: runtime.client,
|
|
1327
|
+
config: runtime.config,
|
|
1328
|
+
store: runtime.store
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
);
|
|
1162
1332
|
}
|
|
1163
1333
|
};
|
|
1164
1334
|
const eventProperties = {};
|
|
@@ -1282,6 +1452,8 @@ export {
|
|
|
1282
1452
|
reply,
|
|
1283
1453
|
typing,
|
|
1284
1454
|
UnsupportedError,
|
|
1455
|
+
contentAttrs,
|
|
1456
|
+
senderAttrs,
|
|
1285
1457
|
wrapProviderMessage,
|
|
1286
1458
|
buildSpace,
|
|
1287
1459
|
definePlatform
|
package/dist/index.d.ts
CHANGED
|
@@ -2739,11 +2739,13 @@ declare function Spectrum<const Providers extends PlatformProviderConfig[]>(opti
|
|
|
2739
2739
|
projectSecret: string;
|
|
2740
2740
|
providers: [...Providers];
|
|
2741
2741
|
options?: SpectrumOptions;
|
|
2742
|
+
telemetry?: boolean;
|
|
2742
2743
|
} | {
|
|
2743
2744
|
projectId?: never;
|
|
2744
2745
|
projectSecret?: never;
|
|
2745
2746
|
providers: [...Providers];
|
|
2746
2747
|
options?: SpectrumOptions;
|
|
2748
|
+
telemetry?: boolean;
|
|
2747
2749
|
}): Promise<SpectrumInstance<Providers>>;
|
|
2748
2750
|
|
|
2749
2751
|
type SubscriptionStatus = "active" | "canceled" | "past_due";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
group,
|
|
3
3
|
richlink
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5NHNMN4H.js";
|
|
5
5
|
import {
|
|
6
6
|
voice
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TN54TDTQ.js";
|
|
8
8
|
import {
|
|
9
9
|
SpectrumCloudError,
|
|
10
10
|
broadcast,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
attachment,
|
|
20
20
|
buildSpace,
|
|
21
21
|
contact,
|
|
22
|
+
contentAttrs,
|
|
22
23
|
custom,
|
|
23
24
|
definePlatform,
|
|
24
25
|
edit,
|
|
@@ -26,11 +27,12 @@ import {
|
|
|
26
27
|
reaction,
|
|
27
28
|
reply,
|
|
28
29
|
resolveContents,
|
|
30
|
+
senderAttrs,
|
|
29
31
|
text,
|
|
30
32
|
toVCard,
|
|
31
33
|
typing,
|
|
32
34
|
wrapProviderMessage
|
|
33
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-XZSBR26X.js";
|
|
34
36
|
|
|
35
37
|
// src/emoji/generated.ts
|
|
36
38
|
var GeneratedEmoji = {
|
|
@@ -1962,6 +1964,11 @@ var aliases = {
|
|
|
1962
1964
|
var Emoji = { ...GeneratedEmoji, ...aliases };
|
|
1963
1965
|
|
|
1964
1966
|
// src/spectrum.ts
|
|
1967
|
+
import {
|
|
1968
|
+
createLogger,
|
|
1969
|
+
setupOtel,
|
|
1970
|
+
withSpan
|
|
1971
|
+
} from "@photon-ai/otel";
|
|
1965
1972
|
import z from "zod";
|
|
1966
1973
|
|
|
1967
1974
|
// src/utils/store.ts
|
|
@@ -2019,7 +2026,12 @@ function createStore() {
|
|
|
2019
2026
|
};
|
|
2020
2027
|
}
|
|
2021
2028
|
|
|
2029
|
+
// src/version.ts
|
|
2030
|
+
var SPECTRUM_SDK_VERSION = "1.8.0";
|
|
2031
|
+
|
|
2022
2032
|
// src/spectrum.ts
|
|
2033
|
+
var PHOTON_OTEL_ENDPOINT = "https://otlp.photon.codes";
|
|
2034
|
+
var lifecycleLog = createLogger("spectrum.lifecycle");
|
|
2023
2035
|
var ignoreCleanupError = () => void 0;
|
|
2024
2036
|
var spectrumOptionsSchema = z.object({
|
|
2025
2037
|
flattenGroups: z.boolean().optional()
|
|
@@ -2029,24 +2041,46 @@ var spectrumConfigSchema = z.union([
|
|
|
2029
2041
|
projectId: z.string().min(1),
|
|
2030
2042
|
projectSecret: z.string().min(1),
|
|
2031
2043
|
providers: z.array(z.custom()),
|
|
2032
|
-
options: spectrumOptionsSchema
|
|
2044
|
+
options: spectrumOptionsSchema,
|
|
2045
|
+
telemetry: z.boolean().optional()
|
|
2033
2046
|
}),
|
|
2034
2047
|
z.object({
|
|
2035
2048
|
projectId: z.undefined().optional(),
|
|
2036
2049
|
projectSecret: z.undefined().optional(),
|
|
2037
2050
|
providers: z.array(z.custom()),
|
|
2038
|
-
options: spectrumOptionsSchema
|
|
2051
|
+
options: spectrumOptionsSchema,
|
|
2052
|
+
telemetry: z.boolean().optional()
|
|
2039
2053
|
})
|
|
2040
2054
|
]);
|
|
2055
|
+
function bootstrapTelemetry(opts) {
|
|
2056
|
+
const headers = {};
|
|
2057
|
+
if (opts.projectId && opts.projectSecret) {
|
|
2058
|
+
const credential = `${opts.projectId}:${opts.projectSecret}`;
|
|
2059
|
+
headers.Authorization = `Basic ${btoa(credential)}`;
|
|
2060
|
+
}
|
|
2061
|
+
const resourceAttributes = {};
|
|
2062
|
+
if (opts.projectId) {
|
|
2063
|
+
resourceAttributes["spectrum.project_id"] = opts.projectId;
|
|
2064
|
+
}
|
|
2065
|
+
return setupOtel({
|
|
2066
|
+
serviceName: "spectrum-ts",
|
|
2067
|
+
serviceVersion: SPECTRUM_SDK_VERSION,
|
|
2068
|
+
endpoint: PHOTON_OTEL_ENDPOINT,
|
|
2069
|
+
headers,
|
|
2070
|
+
resourceAttributes
|
|
2071
|
+
});
|
|
2072
|
+
}
|
|
2041
2073
|
async function Spectrum(options) {
|
|
2042
2074
|
spectrumConfigSchema.parse(options);
|
|
2043
2075
|
const {
|
|
2044
2076
|
projectId,
|
|
2045
2077
|
projectSecret,
|
|
2046
2078
|
providers,
|
|
2047
|
-
options: runtimeOptions
|
|
2079
|
+
options: runtimeOptions,
|
|
2080
|
+
telemetry
|
|
2048
2081
|
} = options;
|
|
2049
2082
|
const flattenGroups = runtimeOptions?.flattenGroups ?? false;
|
|
2083
|
+
const otelHandle = telemetry ? bootstrapTelemetry({ projectId, projectSecret }) : void 0;
|
|
2050
2084
|
const platformStates = /* @__PURE__ */ new Map();
|
|
2051
2085
|
const messageBroadcasters = /* @__PURE__ */ new Map();
|
|
2052
2086
|
const customEventStreams = /* @__PURE__ */ new Map();
|
|
@@ -2079,32 +2113,46 @@ async function Spectrum(options) {
|
|
|
2079
2113
|
});
|
|
2080
2114
|
const bindSend = async function* () {
|
|
2081
2115
|
for await (const msg of raw) {
|
|
2082
|
-
const
|
|
2083
|
-
|
|
2084
|
-
__platform: definition.name
|
|
2085
|
-
};
|
|
2086
|
-
const actionCtx = { space: spaceRef, client, config, store };
|
|
2087
|
-
const space = buildSpace({
|
|
2088
|
-
spaceRef,
|
|
2089
|
-
extras: {},
|
|
2090
|
-
actionCtx,
|
|
2091
|
-
definition,
|
|
2092
|
-
client,
|
|
2093
|
-
config,
|
|
2094
|
-
store
|
|
2095
|
-
});
|
|
2096
|
-
const normalizedMessage = wrapProviderMessage(
|
|
2097
|
-
msg,
|
|
2116
|
+
const built = await withSpan(
|
|
2117
|
+
"spectrum.message.receive",
|
|
2098
2118
|
{
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
store
|
|
2119
|
+
"spectrum.provider": definition.name,
|
|
2120
|
+
"spectrum.message.id": msg.id,
|
|
2121
|
+
"spectrum.space.id": msg.space?.id,
|
|
2122
|
+
...contentAttrs(msg.content),
|
|
2123
|
+
...senderAttrs(msg.sender)
|
|
2105
2124
|
},
|
|
2106
|
-
|
|
2125
|
+
() => {
|
|
2126
|
+
const spaceRef = {
|
|
2127
|
+
...msg.space,
|
|
2128
|
+
__platform: definition.name
|
|
2129
|
+
};
|
|
2130
|
+
const actionCtx = { space: spaceRef, client, config, store };
|
|
2131
|
+
const space2 = buildSpace({
|
|
2132
|
+
spaceRef,
|
|
2133
|
+
extras: {},
|
|
2134
|
+
actionCtx,
|
|
2135
|
+
definition,
|
|
2136
|
+
client,
|
|
2137
|
+
config,
|
|
2138
|
+
store
|
|
2139
|
+
});
|
|
2140
|
+
const normalizedMessage2 = wrapProviderMessage(
|
|
2141
|
+
msg,
|
|
2142
|
+
{
|
|
2143
|
+
client,
|
|
2144
|
+
config,
|
|
2145
|
+
definition,
|
|
2146
|
+
space: space2,
|
|
2147
|
+
spaceRef,
|
|
2148
|
+
store
|
|
2149
|
+
},
|
|
2150
|
+
"inbound"
|
|
2151
|
+
);
|
|
2152
|
+
return { space: space2, normalizedMessage: normalizedMessage2 };
|
|
2153
|
+
}
|
|
2107
2154
|
);
|
|
2155
|
+
const { space, normalizedMessage } = built;
|
|
2108
2156
|
if (flattenGroups && normalizedMessage.content.type === "group") {
|
|
2109
2157
|
for (const item of normalizedMessage.content.items) {
|
|
2110
2158
|
yield [space, item];
|
|
@@ -2130,28 +2178,49 @@ async function Spectrum(options) {
|
|
|
2130
2178
|
}
|
|
2131
2179
|
return broadcaster;
|
|
2132
2180
|
};
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2181
|
+
await withSpan(
|
|
2182
|
+
"spectrum.init",
|
|
2183
|
+
{
|
|
2184
|
+
"spectrum.provider_count": providers.length,
|
|
2185
|
+
"spectrum.flatten_groups": flattenGroups
|
|
2186
|
+
},
|
|
2187
|
+
async () => {
|
|
2188
|
+
for (const provider of providers) {
|
|
2189
|
+
const providerConfig = provider;
|
|
2190
|
+
const def = providerConfig.__definition;
|
|
2191
|
+
const userConfig = def.config.parse(providerConfig.config);
|
|
2192
|
+
const store = createStore();
|
|
2193
|
+
const client = await withSpan(
|
|
2194
|
+
"spectrum.provider.create_client",
|
|
2195
|
+
{
|
|
2196
|
+
"spectrum.provider": def.name
|
|
2197
|
+
},
|
|
2198
|
+
() => def.lifecycle.createClient({
|
|
2199
|
+
config: userConfig,
|
|
2200
|
+
projectId,
|
|
2201
|
+
projectSecret,
|
|
2202
|
+
store
|
|
2203
|
+
})
|
|
2204
|
+
);
|
|
2205
|
+
const state = {
|
|
2206
|
+
client,
|
|
2207
|
+
config: userConfig,
|
|
2208
|
+
definition: def,
|
|
2209
|
+
store
|
|
2210
|
+
};
|
|
2211
|
+
platformStates.set(def.name, {
|
|
2212
|
+
...state,
|
|
2213
|
+
subscribeMessages: () => getOrCreateMessageBroadcast(state).subscribe()
|
|
2214
|
+
});
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
);
|
|
2218
|
+
const providerNames = providers.map((p) => p.__definition.name).join(",");
|
|
2219
|
+
lifecycleLog.info("Spectrum started", {
|
|
2220
|
+
providerCount: providers.length,
|
|
2221
|
+
providers: providerNames,
|
|
2222
|
+
telemetry: telemetry === true
|
|
2223
|
+
});
|
|
2155
2224
|
const createMessagesStream = () => stream((emit, end) => {
|
|
2156
2225
|
const merged = mergeStreams(
|
|
2157
2226
|
Array.from(
|
|
@@ -2185,7 +2254,15 @@ async function Spectrum(options) {
|
|
|
2185
2254
|
const providerEvents = producer({ client, config, store });
|
|
2186
2255
|
const annotatePlatform = async function* () {
|
|
2187
2256
|
for await (const value of providerEvents) {
|
|
2188
|
-
|
|
2257
|
+
const annotated = await withSpan(
|
|
2258
|
+
"spectrum.event",
|
|
2259
|
+
{
|
|
2260
|
+
"spectrum.provider": definition.name,
|
|
2261
|
+
"spectrum.event.name": eventName
|
|
2262
|
+
},
|
|
2263
|
+
() => ({ ...value, platform: definition.name })
|
|
2264
|
+
);
|
|
2265
|
+
yield annotated;
|
|
2189
2266
|
}
|
|
2190
2267
|
};
|
|
2191
2268
|
providerStreams.push(adaptIterable(annotatePlatform()));
|
|
@@ -2226,17 +2303,33 @@ async function Spectrum(options) {
|
|
|
2226
2303
|
process.off("SIGINT", handleSignal);
|
|
2227
2304
|
process.off("SIGTERM", handleSignal);
|
|
2228
2305
|
await Promise.allSettled(streamShutdowns);
|
|
2229
|
-
const clientShutdowns =
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
}
|
|
2235
|
-
|
|
2306
|
+
const clientShutdowns = [];
|
|
2307
|
+
for (const state of platformStates.values()) {
|
|
2308
|
+
const destroy = state.definition.lifecycle.destroyClient;
|
|
2309
|
+
if (!destroy) {
|
|
2310
|
+
continue;
|
|
2311
|
+
}
|
|
2312
|
+
clientShutdowns.push(
|
|
2313
|
+
withSpan(
|
|
2314
|
+
"spectrum.provider.destroy_client",
|
|
2315
|
+
{
|
|
2316
|
+
"spectrum.provider": state.definition.name
|
|
2317
|
+
},
|
|
2318
|
+
() => destroy({
|
|
2319
|
+
client: state.client,
|
|
2320
|
+
store: state.store
|
|
2321
|
+
})
|
|
2322
|
+
)
|
|
2323
|
+
);
|
|
2324
|
+
}
|
|
2236
2325
|
await Promise.allSettled(clientShutdowns);
|
|
2237
2326
|
customEventStreams.clear();
|
|
2238
2327
|
messageBroadcasters.clear();
|
|
2239
2328
|
platformStates.clear();
|
|
2329
|
+
lifecycleLog.info("Spectrum stopped", { providers: providerNames });
|
|
2330
|
+
if (otelHandle) {
|
|
2331
|
+
await otelHandle.shutdown();
|
|
2332
|
+
}
|
|
2240
2333
|
};
|
|
2241
2334
|
const handleSignal = () => {
|
|
2242
2335
|
setTimeout(() => process.exit(1), 3e3).unref();
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
background,
|
|
3
3
|
effect,
|
|
4
4
|
imessage
|
|
5
|
-
} from "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
5
|
+
} from "../../chunk-OM5VSKWD.js";
|
|
6
|
+
import "../../chunk-5NHNMN4H.js";
|
|
7
7
|
import "../../chunk-HWADNTQF.js";
|
|
8
|
-
import "../../chunk-
|
|
8
|
+
import "../../chunk-XZSBR26X.js";
|
|
9
9
|
export {
|
|
10
10
|
background,
|
|
11
11
|
effect,
|
package/dist/providers/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
imessage
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-OM5VSKWD.js";
|
|
4
|
+
import "../chunk-5NHNMN4H.js";
|
|
5
5
|
import {
|
|
6
6
|
terminal
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-N3ZKMTSG.js";
|
|
8
|
+
import "../chunk-TN54TDTQ.js";
|
|
9
9
|
import {
|
|
10
10
|
whatsappBusiness
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-OR3VGVML.js";
|
|
12
12
|
import "../chunk-HWADNTQF.js";
|
|
13
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-XZSBR26X.js";
|
|
14
14
|
export {
|
|
15
15
|
imessage,
|
|
16
16
|
terminal,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
terminal
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-N3ZKMTSG.js";
|
|
4
|
+
import "../../chunk-TN54TDTQ.js";
|
|
5
|
+
import "../../chunk-XZSBR26X.js";
|
|
6
6
|
export {
|
|
7
7
|
terminal
|
|
8
8
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@photon-ai/advanced-imessage": "^0.7.0",
|
|
27
27
|
"@photon-ai/imessage-kit": "^3.0.0",
|
|
28
|
+
"@photon-ai/otel": "^0.1.1",
|
|
28
29
|
"@photon-ai/whatsapp-business": "^0.1.1",
|
|
29
30
|
"@repeaterjs/repeater": "^3.0.6",
|
|
30
31
|
"better-grpc": "^0.3.2",
|