spectrum-ts 1.17.1 → 2.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.
- package/README.md +11 -1
- package/dist/{attachment-DfWSZS5L.d.ts → attachment-B4nSrKVd.d.ts} +1 -1
- package/dist/{authoring-C9uDdZ2F.d.ts → authoring-BjE5BvlO.d.ts} +2 -2
- package/dist/authoring.d.ts +3 -3
- package/dist/authoring.js +6 -3
- package/dist/chunk-34FQGGD7.js +34 -0
- package/dist/chunk-3B4QH4JG.js +35 -0
- package/dist/chunk-3GEJYGZK.js +84 -0
- package/dist/chunk-5LT5J3NR.js +695 -0
- package/dist/{chunk-MC6ZKFSG.js → chunk-5XEFJBN2.js} +25 -103
- package/dist/{chunk-JQN6CRSC.js → chunk-6BI4PFTP.js} +10 -39
- package/dist/{chunk-QGJFZMD5.js → chunk-6UZFVXQF.js} +17 -101
- package/dist/{chunk-YJMPSD3S.js → chunk-ATNAE7OR.js} +196 -47
- package/dist/{chunk-IPOFBAIM.js → chunk-NGC4DJIX.js} +23 -19
- package/dist/{chunk-5TIF3FIE.js → chunk-Q537JPTG.js} +8 -6
- package/dist/{chunk-5BKZJMZV.js → chunk-U3LXXT3W.js} +61 -32
- package/dist/chunk-U7AWXDH6.js +91 -0
- package/dist/{chunk-3OTECDNH.js → chunk-WXY5QP3M.js} +5 -3
- package/dist/index.d.ts +71 -126
- package/dist/index.js +350 -90
- package/dist/manifest.json +6 -0
- package/dist/providers/imessage/index.d.ts +75 -3
- package/dist/providers/imessage/index.js +10 -5
- package/dist/providers/index.d.ts +5 -2
- package/dist/providers/index.js +16 -8
- package/dist/providers/slack/index.d.ts +1 -1
- package/dist/providers/slack/index.js +4 -3
- package/dist/providers/telegram/index.d.ts +47 -0
- package/dist/providers/telegram/index.js +13 -0
- package/dist/providers/terminal/index.d.ts +17 -419
- package/dist/providers/terminal/index.js +5 -3
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +6 -4
- package/dist/types-BD0-kKyv.d.ts +82 -0
- package/dist/{types-DcQ5a7PK.d.ts → types-Bje8aq1k.d.ts} +34 -4
- package/package.json +3 -2
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
asRichlink
|
|
4
|
+
} from "./chunk-6BI4PFTP.js";
|
|
2
5
|
import {
|
|
3
6
|
asGroup,
|
|
4
|
-
asRichlink,
|
|
5
7
|
groupSchema
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3B4QH4JG.js";
|
|
7
9
|
import {
|
|
8
10
|
asPoll,
|
|
9
11
|
asPollOption
|
|
10
12
|
} from "./chunk-2D27WW5B.js";
|
|
11
13
|
import {
|
|
12
|
-
cloud
|
|
14
|
+
cloud
|
|
15
|
+
} from "./chunk-3GEJYGZK.js";
|
|
16
|
+
import {
|
|
17
|
+
asContact
|
|
18
|
+
} from "./chunk-U7AWXDH6.js";
|
|
19
|
+
import {
|
|
13
20
|
mergeStreams,
|
|
14
21
|
stream
|
|
15
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-5XEFJBN2.js";
|
|
16
23
|
import {
|
|
17
|
-
asContact,
|
|
18
24
|
fromVCard,
|
|
19
25
|
toVCard
|
|
20
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-6UZFVXQF.js";
|
|
21
27
|
import {
|
|
22
28
|
UnsupportedError,
|
|
23
29
|
buildPhotoAction,
|
|
24
30
|
definePlatform,
|
|
25
31
|
photoActionSchema
|
|
26
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-NGC4DJIX.js";
|
|
27
33
|
import {
|
|
28
34
|
asAttachment,
|
|
29
35
|
asCustom,
|
|
@@ -60,21 +66,79 @@ function background(input, options) {
|
|
|
60
66
|
};
|
|
61
67
|
}
|
|
62
68
|
|
|
69
|
+
// src/providers/imessage/content/customized-mini-app.ts
|
|
70
|
+
import z2 from "zod";
|
|
71
|
+
var layoutSchema = z2.object({
|
|
72
|
+
caption: z2.string().nonempty().optional(),
|
|
73
|
+
subcaption: z2.string().nonempty().optional(),
|
|
74
|
+
trailingCaption: z2.string().nonempty().optional(),
|
|
75
|
+
trailingSubcaption: z2.string().nonempty().optional(),
|
|
76
|
+
image: z2.instanceof(Uint8Array).optional(),
|
|
77
|
+
imageTitle: z2.string().nonempty().optional(),
|
|
78
|
+
imageSubtitle: z2.string().nonempty().optional(),
|
|
79
|
+
summary: z2.string().nonempty().optional()
|
|
80
|
+
}).refine(
|
|
81
|
+
(layout) => layout.caption !== void 0 || layout.subcaption !== void 0 || layout.trailingCaption !== void 0 || layout.trailingSubcaption !== void 0 || layout.image !== void 0,
|
|
82
|
+
{
|
|
83
|
+
message: "layout must set at least one of caption, subcaption, trailingCaption, trailingSubcaption, image"
|
|
84
|
+
}
|
|
85
|
+
).refine(
|
|
86
|
+
(layout) => layout.image === void 0 === (layout.imageTitle === void 0),
|
|
87
|
+
{
|
|
88
|
+
message: "layout.image and layout.imageTitle must be set together",
|
|
89
|
+
path: ["imageTitle"]
|
|
90
|
+
}
|
|
91
|
+
).refine(
|
|
92
|
+
(layout) => layout.imageSubtitle === void 0 || layout.image !== void 0,
|
|
93
|
+
{
|
|
94
|
+
message: "layout.imageSubtitle requires layout.image",
|
|
95
|
+
path: ["imageSubtitle"]
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
var customizedMiniAppSchema = z2.object({
|
|
99
|
+
type: z2.literal("customized-mini-app"),
|
|
100
|
+
__platform: z2.literal("iMessage"),
|
|
101
|
+
// Display name of the owning app, shown by Messages fallback UI.
|
|
102
|
+
appName: z2.string().nonempty(),
|
|
103
|
+
// Apple App Store numeric id of the owning app. Positive when set; omit to
|
|
104
|
+
// send a card whose extension is not published on the App Store.
|
|
105
|
+
appStoreId: z2.number().int().positive().optional(),
|
|
106
|
+
// Bundle identifier of the iMessage extension target.
|
|
107
|
+
extensionBundleId: z2.string().nonempty(),
|
|
108
|
+
// Visible card layout.
|
|
109
|
+
layout: layoutSchema,
|
|
110
|
+
// 10-character uppercase alphanumeric Apple Team ID.
|
|
111
|
+
teamId: z2.string(),
|
|
112
|
+
// Absolute URL delivered to the installed extension on tap.
|
|
113
|
+
url: z2.url()
|
|
114
|
+
});
|
|
115
|
+
var isCustomizedMiniApp = (v) => customizedMiniAppSchema.safeParse(v).success;
|
|
116
|
+
var asCustomizedMiniApp = (input) => customizedMiniAppSchema.parse({
|
|
117
|
+
type: "customized-mini-app",
|
|
118
|
+
__platform: "iMessage",
|
|
119
|
+
...input
|
|
120
|
+
});
|
|
121
|
+
function customizedMiniApp(input) {
|
|
122
|
+
return {
|
|
123
|
+
build: async () => asCustomizedMiniApp(input)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
63
127
|
// src/providers/imessage/content/effect.ts
|
|
64
128
|
import {
|
|
65
129
|
MessageEffect
|
|
66
130
|
} from "@photon-ai/advanced-imessage";
|
|
67
131
|
|
|
68
132
|
// src/content/effect.ts
|
|
69
|
-
import
|
|
70
|
-
var effectInnerSchema =
|
|
133
|
+
import z3 from "zod";
|
|
134
|
+
var effectInnerSchema = z3.discriminatedUnion("type", [
|
|
71
135
|
textSchema,
|
|
72
136
|
attachmentSchema
|
|
73
137
|
]);
|
|
74
|
-
var messageEffectSchema =
|
|
75
|
-
type:
|
|
138
|
+
var messageEffectSchema = z3.object({
|
|
139
|
+
type: z3.literal("effect"),
|
|
76
140
|
content: effectInnerSchema,
|
|
77
|
-
effect:
|
|
141
|
+
effect: z3.string().nonempty()
|
|
78
142
|
});
|
|
79
143
|
|
|
80
144
|
// src/providers/imessage/content/effect.ts
|
|
@@ -104,13 +168,13 @@ function effect(input, messageEffect) {
|
|
|
104
168
|
}
|
|
105
169
|
|
|
106
170
|
// src/providers/imessage/content/read.ts
|
|
107
|
-
import
|
|
171
|
+
import z4 from "zod";
|
|
108
172
|
var isMessage = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
109
|
-
var readSchema =
|
|
110
|
-
type:
|
|
111
|
-
__platform:
|
|
112
|
-
__fireAndForget:
|
|
113
|
-
target:
|
|
173
|
+
var readSchema = z4.object({
|
|
174
|
+
type: z4.literal("read"),
|
|
175
|
+
__platform: z4.literal("iMessage"),
|
|
176
|
+
__fireAndForget: z4.literal(true),
|
|
177
|
+
target: z4.custom(isMessage, {
|
|
114
178
|
message: "read target must be a Message"
|
|
115
179
|
})
|
|
116
180
|
});
|
|
@@ -138,33 +202,33 @@ import { createClient } from "@photon-ai/advanced-imessage";
|
|
|
138
202
|
|
|
139
203
|
// src/providers/imessage/types.ts
|
|
140
204
|
import { IMessageSDK } from "@photon-ai/imessage-kit";
|
|
141
|
-
import
|
|
205
|
+
import z5 from "zod";
|
|
142
206
|
var SHARED_PHONE = "shared";
|
|
143
207
|
var isLocal = (client) => client instanceof IMessageSDK;
|
|
144
|
-
var clientEntry =
|
|
145
|
-
address:
|
|
146
|
-
token:
|
|
147
|
-
phone:
|
|
208
|
+
var clientEntry = z5.object({
|
|
209
|
+
address: z5.string(),
|
|
210
|
+
token: z5.string(),
|
|
211
|
+
phone: z5.string()
|
|
148
212
|
});
|
|
149
|
-
var configSchema =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
local:
|
|
153
|
-
clients: clientEntry.or(
|
|
213
|
+
var configSchema = z5.union([
|
|
214
|
+
z5.object({ local: z5.literal(true) }),
|
|
215
|
+
z5.object({
|
|
216
|
+
local: z5.literal(false).optional().default(false),
|
|
217
|
+
clients: clientEntry.or(z5.array(clientEntry)).optional()
|
|
154
218
|
})
|
|
155
219
|
]);
|
|
156
|
-
var userSchema =
|
|
157
|
-
var spaceSchema =
|
|
158
|
-
id:
|
|
159
|
-
type:
|
|
160
|
-
phone:
|
|
220
|
+
var userSchema = z5.object({});
|
|
221
|
+
var spaceSchema = z5.object({
|
|
222
|
+
id: z5.string(),
|
|
223
|
+
type: z5.enum(["dm", "group"]),
|
|
224
|
+
phone: z5.string()
|
|
161
225
|
});
|
|
162
|
-
var spaceParamsSchema =
|
|
163
|
-
phone:
|
|
226
|
+
var spaceParamsSchema = z5.object({
|
|
227
|
+
phone: z5.string().optional()
|
|
164
228
|
});
|
|
165
|
-
var messageSchema =
|
|
166
|
-
partIndex:
|
|
167
|
-
parentId:
|
|
229
|
+
var messageSchema = z5.object({
|
|
230
|
+
partIndex: z5.number().int().nonnegative().optional(),
|
|
231
|
+
parentId: z5.string().optional()
|
|
168
232
|
});
|
|
169
233
|
|
|
170
234
|
// src/providers/imessage/auth.ts
|
|
@@ -549,6 +613,18 @@ var setBackground = async (remote, spaceId, content) => {
|
|
|
549
613
|
);
|
|
550
614
|
};
|
|
551
615
|
|
|
616
|
+
// src/providers/imessage/remote/customized-mini-app.ts
|
|
617
|
+
var sendCustomizedMiniApp = async (remote, spaceId, content) => {
|
|
618
|
+
const chat = toChatGuid(spaceId);
|
|
619
|
+
const message = await remote.messages.sendCustomizedMiniApp(chat, content);
|
|
620
|
+
return {
|
|
621
|
+
id: message.guid,
|
|
622
|
+
content,
|
|
623
|
+
space: { id: spaceId },
|
|
624
|
+
timestamp: message.dateCreated
|
|
625
|
+
};
|
|
626
|
+
};
|
|
627
|
+
|
|
552
628
|
// src/providers/imessage/remote/inbound.ts
|
|
553
629
|
import {
|
|
554
630
|
NotFoundError as NotFoundError2
|
|
@@ -910,7 +986,6 @@ var getMessage3 = async (remote, spaceId, msgId, phone) => {
|
|
|
910
986
|
if (childRef) {
|
|
911
987
|
try {
|
|
912
988
|
const fetched = await remote.messages.get(
|
|
913
|
-
toChatGuid(spaceId),
|
|
914
989
|
toMessageGuid(childRef.parentGuid)
|
|
915
990
|
);
|
|
916
991
|
const parent = await rebuildFromAppleMessage(
|
|
@@ -933,10 +1008,7 @@ var getMessage3 = async (remote, spaceId, msgId, phone) => {
|
|
|
933
1008
|
}
|
|
934
1009
|
}
|
|
935
1010
|
try {
|
|
936
|
-
const fetched = await remote.messages.get(
|
|
937
|
-
toChatGuid(spaceId),
|
|
938
|
-
toMessageGuid(msgId)
|
|
939
|
-
);
|
|
1011
|
+
const fetched = await remote.messages.get(toMessageGuid(msgId));
|
|
940
1012
|
const rebuilt = await rebuildFromAppleMessage(
|
|
941
1013
|
remote,
|
|
942
1014
|
fetched,
|
|
@@ -975,10 +1047,7 @@ var resolveReactionTarget = async (client, cache, chat, targetGuid, partIndex, p
|
|
|
975
1047
|
let candidate = cache.get(targetGuid);
|
|
976
1048
|
if (!candidate) {
|
|
977
1049
|
try {
|
|
978
|
-
const fetched = await client.messages.get(
|
|
979
|
-
toChatGuid(chat),
|
|
980
|
-
toMessageGuid(targetGuid)
|
|
981
|
-
);
|
|
1050
|
+
const fetched = await client.messages.get(toMessageGuid(targetGuid));
|
|
982
1051
|
candidate = await rebuildFromAppleMessage(client, fetched, phone, chat);
|
|
983
1052
|
cacheMessage(cache, candidate);
|
|
984
1053
|
} catch {
|
|
@@ -1976,6 +2045,55 @@ var messages3 = (clients, projectConfig) => {
|
|
|
1976
2045
|
);
|
|
1977
2046
|
};
|
|
1978
2047
|
|
|
2048
|
+
// src/providers/imessage/remote/stream-text.ts
|
|
2049
|
+
var INITIAL_THROTTLE_MS = 1e3;
|
|
2050
|
+
var BACKOFF_FACTOR = 2;
|
|
2051
|
+
var MAX_EDITS = 5;
|
|
2052
|
+
var sendStreamText = async (remote, spaceId, content) => {
|
|
2053
|
+
const chat = toChatGuid(spaceId);
|
|
2054
|
+
let sent;
|
|
2055
|
+
let full = "";
|
|
2056
|
+
let lastSentText = "";
|
|
2057
|
+
let lastEditAt = 0;
|
|
2058
|
+
let editCount = 0;
|
|
2059
|
+
const flushEdit = async (text2) => {
|
|
2060
|
+
if (!sent || text2 === lastSentText) {
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
await remote.messages.edit(chat, toMessageGuid(sent.guid), text2);
|
|
2064
|
+
lastSentText = text2;
|
|
2065
|
+
lastEditAt = Date.now();
|
|
2066
|
+
editCount += 1;
|
|
2067
|
+
};
|
|
2068
|
+
for await (const delta of content.stream()) {
|
|
2069
|
+
full += delta;
|
|
2070
|
+
if (!sent) {
|
|
2071
|
+
sent = await remote.messages.sendText(chat, full);
|
|
2072
|
+
lastSentText = full;
|
|
2073
|
+
lastEditAt = Date.now();
|
|
2074
|
+
continue;
|
|
2075
|
+
}
|
|
2076
|
+
const hasBudgetForInterimEdit = editCount < MAX_EDITS - 1;
|
|
2077
|
+
const requiredGap = INITIAL_THROTTLE_MS * BACKOFF_FACTOR ** editCount;
|
|
2078
|
+
if (hasBudgetForInterimEdit && Date.now() - lastEditAt >= requiredGap) {
|
|
2079
|
+
await flushEdit(full);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
if (!sent) {
|
|
2083
|
+
throw unsupportedRemoteContent(
|
|
2084
|
+
"streamText",
|
|
2085
|
+
"stream produced no text \u2014 nothing to send"
|
|
2086
|
+
);
|
|
2087
|
+
}
|
|
2088
|
+
await flushEdit(full);
|
|
2089
|
+
return {
|
|
2090
|
+
id: sent.guid,
|
|
2091
|
+
content: asText(full),
|
|
2092
|
+
space: { id: spaceId },
|
|
2093
|
+
timestamp: sent.dateCreated
|
|
2094
|
+
};
|
|
2095
|
+
};
|
|
2096
|
+
|
|
1979
2097
|
// src/providers/imessage/remote/typing.ts
|
|
1980
2098
|
var startTyping = async (remote, spaceId) => {
|
|
1981
2099
|
await remote.chats.setTyping(toChatGuid(spaceId), true);
|
|
@@ -1987,6 +2105,7 @@ var stopTyping = async (remote, spaceId) => {
|
|
|
1987
2105
|
// src/providers/imessage/remote/api.ts
|
|
1988
2106
|
var messages4 = (clients, projectConfig) => messages3(clients, projectConfig);
|
|
1989
2107
|
var setBackground2 = async (remote, spaceId, content) => setBackground(remote, spaceId, content);
|
|
2108
|
+
var sendCustomizedMiniApp2 = async (remote, spaceId, content) => sendCustomizedMiniApp(remote, spaceId, content);
|
|
1990
2109
|
var setDisplayName2 = async (remote, spaceId, content) => setDisplayName(remote, spaceId, content);
|
|
1991
2110
|
var setIcon2 = async (remote, spaceId, content) => setIcon(remote, spaceId, content);
|
|
1992
2111
|
var markRead2 = async (remote, spaceId) => {
|
|
@@ -1999,6 +2118,7 @@ var stopTyping2 = async (remote, spaceId) => {
|
|
|
1999
2118
|
await stopTyping(remote, spaceId);
|
|
2000
2119
|
};
|
|
2001
2120
|
var send4 = async (remote, spaceId, content) => send3(remote, spaceId, content);
|
|
2121
|
+
var sendStreamText2 = async (remote, spaceId, content) => sendStreamText(remote, spaceId, content);
|
|
2002
2122
|
var replyToMessage2 = async (remote, spaceId, msgId, content) => replyToMessage(remote, spaceId, msgId, content);
|
|
2003
2123
|
var editMessage2 = async (remote, spaceId, msgId, content) => editMessage(remote, spaceId, msgId, content);
|
|
2004
2124
|
var reactToMessage2 = async (remote, spaceId, target, reaction) => {
|
|
@@ -2056,6 +2176,17 @@ var handleEdit = async (client, space, content) => {
|
|
|
2056
2176
|
const remote = clientForPhone(client, space.phone);
|
|
2057
2177
|
await editMessage2(remote, space.id, content.target.id, content.content);
|
|
2058
2178
|
};
|
|
2179
|
+
var handleStreamText = async (client, space, content) => {
|
|
2180
|
+
if (isLocal(client)) {
|
|
2181
|
+
throw UnsupportedError.action(
|
|
2182
|
+
"streamText",
|
|
2183
|
+
"iMessage (local mode)",
|
|
2184
|
+
"streaming text responses require remote iMessage"
|
|
2185
|
+
);
|
|
2186
|
+
}
|
|
2187
|
+
const remote = clientForPhone(client, space.phone);
|
|
2188
|
+
return await sendStreamText2(remote, space.id, content);
|
|
2189
|
+
};
|
|
2059
2190
|
var handleBackground = async (client, space, content) => {
|
|
2060
2191
|
if (isLocal(client)) {
|
|
2061
2192
|
throw UnsupportedError.action(
|
|
@@ -2067,6 +2198,17 @@ var handleBackground = async (client, space, content) => {
|
|
|
2067
2198
|
const remote = clientForPhone(client, space.phone);
|
|
2068
2199
|
await setBackground2(remote, space.id, content);
|
|
2069
2200
|
};
|
|
2201
|
+
var handleCustomizedMiniApp = async (client, space, content) => {
|
|
2202
|
+
if (isLocal(client)) {
|
|
2203
|
+
throw UnsupportedError.action(
|
|
2204
|
+
"customized-mini-app",
|
|
2205
|
+
"iMessage (local mode)",
|
|
2206
|
+
"mini app cards require remote iMessage"
|
|
2207
|
+
);
|
|
2208
|
+
}
|
|
2209
|
+
const remote = clientForPhone(client, space.phone);
|
|
2210
|
+
return await sendCustomizedMiniApp2(remote, space.id, content);
|
|
2211
|
+
};
|
|
2070
2212
|
var handleRead = async (client, space) => {
|
|
2071
2213
|
if (isLocal(client)) {
|
|
2072
2214
|
throw UnsupportedError.action(
|
|
@@ -2275,6 +2417,9 @@ var imessage = definePlatform("iMessage", {
|
|
|
2275
2417
|
await handleEdit(client, space, content);
|
|
2276
2418
|
return;
|
|
2277
2419
|
}
|
|
2420
|
+
if (content.type === "streamText") {
|
|
2421
|
+
return await handleStreamText(client, space, content);
|
|
2422
|
+
}
|
|
2278
2423
|
if (content.type === "rename") {
|
|
2279
2424
|
await handleRename(client, space, content);
|
|
2280
2425
|
return;
|
|
@@ -2291,6 +2436,9 @@ var imessage = definePlatform("iMessage", {
|
|
|
2291
2436
|
await handleRead(client, space);
|
|
2292
2437
|
return;
|
|
2293
2438
|
}
|
|
2439
|
+
if (isCustomizedMiniApp(content)) {
|
|
2440
|
+
return await handleCustomizedMiniApp(client, space, content);
|
|
2441
|
+
}
|
|
2294
2442
|
if (isLocal(client)) {
|
|
2295
2443
|
return await send2(client, space.id, content);
|
|
2296
2444
|
}
|
|
@@ -2351,6 +2499,7 @@ var imessage = definePlatform("iMessage", {
|
|
|
2351
2499
|
|
|
2352
2500
|
export {
|
|
2353
2501
|
background,
|
|
2502
|
+
customizedMiniApp,
|
|
2354
2503
|
effect,
|
|
2355
2504
|
read,
|
|
2356
2505
|
imessage
|
|
@@ -216,7 +216,7 @@ var UnsupportedError = class _UnsupportedError extends Error {
|
|
|
216
216
|
};
|
|
217
217
|
|
|
218
218
|
// src/platform/define.ts
|
|
219
|
-
import { withSpan as withSpan2 } from "@photon-ai/otel";
|
|
219
|
+
import { createLogger as createLogger2, withSpan as withSpan2 } from "@photon-ai/otel";
|
|
220
220
|
|
|
221
221
|
// src/utils/identifier.ts
|
|
222
222
|
import { sanitizeEmail, sanitizePhone } from "@photon-ai/otel";
|
|
@@ -747,6 +747,7 @@ function buildMessage(params) {
|
|
|
747
747
|
}
|
|
748
748
|
|
|
749
749
|
// src/platform/define.ts
|
|
750
|
+
var platformLog2 = createLogger2("spectrum.platform");
|
|
750
751
|
function classifySpaceIdentifier(args) {
|
|
751
752
|
const stringArgs = args.filter((a) => typeof a === "string");
|
|
752
753
|
if (stringArgs.length > 1) {
|
|
@@ -910,13 +911,20 @@ function createPlatformInstance(def, runtime) {
|
|
|
910
911
|
const eventProperties = {};
|
|
911
912
|
const customEvents = def.events ?? {};
|
|
912
913
|
for (const eventName of Object.keys(customEvents)) {
|
|
913
|
-
const
|
|
914
|
-
if (
|
|
914
|
+
const declared = customEvents[eventName];
|
|
915
|
+
if (typeof declared === "function") {
|
|
916
|
+
const producer = declared;
|
|
915
917
|
eventProperties[eventName] = producer({
|
|
916
918
|
client: runtime.client,
|
|
917
919
|
config: runtime.config,
|
|
920
|
+
projectConfig: runtime.projectConfig,
|
|
918
921
|
store: runtime.store
|
|
919
922
|
});
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
const fusorEvents = runtime.subscribeEvent?.(eventName);
|
|
926
|
+
if (fusorEvents) {
|
|
927
|
+
eventProperties[eventName] = fusorEvents;
|
|
920
928
|
}
|
|
921
929
|
}
|
|
922
930
|
let messagesIterable;
|
|
@@ -948,8 +956,9 @@ function createPlatformInstance(def, runtime) {
|
|
|
948
956
|
eventProperties
|
|
949
957
|
);
|
|
950
958
|
}
|
|
951
|
-
function definePlatform(name,
|
|
952
|
-
const
|
|
959
|
+
function definePlatform(name, rawDef) {
|
|
960
|
+
const def = rawDef;
|
|
961
|
+
const fullDef = { ...def, name };
|
|
953
962
|
const platformCache = /* @__PURE__ */ new WeakMap();
|
|
954
963
|
const narrowSpectrum = (spectrum) => {
|
|
955
964
|
const cached = platformCache.get(spectrum);
|
|
@@ -969,17 +978,19 @@ function definePlatform(name, def) {
|
|
|
969
978
|
};
|
|
970
979
|
const narrowSpace = (input) => {
|
|
971
980
|
if (input.__platform !== name) {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
981
|
+
platformLog2.warn("space platform mismatch; narrowing skipped", {
|
|
982
|
+
expected: name,
|
|
983
|
+
actual: input.__platform
|
|
984
|
+
});
|
|
975
985
|
}
|
|
976
986
|
return input;
|
|
977
987
|
};
|
|
978
988
|
const narrowMessage = (input) => {
|
|
979
989
|
if (input.platform !== name) {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
990
|
+
platformLog2.warn("message platform mismatch; narrowing skipped", {
|
|
991
|
+
expected: name,
|
|
992
|
+
actual: input.platform
|
|
993
|
+
});
|
|
983
994
|
}
|
|
984
995
|
return input;
|
|
985
996
|
};
|
|
@@ -1022,12 +1033,6 @@ function definePlatform(name, def) {
|
|
|
1022
1033
|
}
|
|
1023
1034
|
return narrower;
|
|
1024
1035
|
}
|
|
1025
|
-
function defineFusorPlatform(name, def) {
|
|
1026
|
-
return definePlatform(
|
|
1027
|
-
name,
|
|
1028
|
-
def
|
|
1029
|
-
);
|
|
1030
|
-
}
|
|
1031
1036
|
|
|
1032
1037
|
export {
|
|
1033
1038
|
photoActionSchema,
|
|
@@ -1042,6 +1047,5 @@ export {
|
|
|
1042
1047
|
senderAttrs,
|
|
1043
1048
|
wrapProviderMessage,
|
|
1044
1049
|
buildSpace,
|
|
1045
|
-
definePlatform
|
|
1046
|
-
defineFusorPlatform
|
|
1050
|
+
definePlatform
|
|
1047
1051
|
};
|
|
@@ -3,17 +3,19 @@ import {
|
|
|
3
3
|
asPollOption
|
|
4
4
|
} from "./chunk-2D27WW5B.js";
|
|
5
5
|
import {
|
|
6
|
-
cloud
|
|
7
|
-
|
|
8
|
-
stream
|
|
9
|
-
} from "./chunk-MC6ZKFSG.js";
|
|
6
|
+
cloud
|
|
7
|
+
} from "./chunk-3GEJYGZK.js";
|
|
10
8
|
import {
|
|
11
9
|
asContact
|
|
12
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-U7AWXDH6.js";
|
|
11
|
+
import {
|
|
12
|
+
mergeStreams,
|
|
13
|
+
stream
|
|
14
|
+
} from "./chunk-5XEFJBN2.js";
|
|
13
15
|
import {
|
|
14
16
|
UnsupportedError,
|
|
15
17
|
definePlatform
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NGC4DJIX.js";
|
|
17
19
|
import {
|
|
18
20
|
asAttachment,
|
|
19
21
|
asCustom,
|
|
@@ -3,14 +3,19 @@ import {
|
|
|
3
3
|
asVoice
|
|
4
4
|
} from "./chunk-NNY6LMSC.js";
|
|
5
5
|
import {
|
|
6
|
-
asContact
|
|
6
|
+
asContact
|
|
7
|
+
} from "./chunk-U7AWXDH6.js";
|
|
8
|
+
import {
|
|
9
|
+
stream
|
|
10
|
+
} from "./chunk-5XEFJBN2.js";
|
|
11
|
+
import {
|
|
7
12
|
fromVCard,
|
|
8
13
|
toVCard
|
|
9
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-6UZFVXQF.js";
|
|
10
15
|
import {
|
|
11
16
|
UnsupportedError,
|
|
12
17
|
definePlatform
|
|
13
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NGC4DJIX.js";
|
|
14
19
|
import {
|
|
15
20
|
asAttachment,
|
|
16
21
|
asCustom,
|
|
@@ -694,7 +699,7 @@ function protocolToSpectrum(p) {
|
|
|
694
699
|
}
|
|
695
700
|
return cached;
|
|
696
701
|
};
|
|
697
|
-
const
|
|
702
|
+
const stream2 = async () => {
|
|
698
703
|
if (path) {
|
|
699
704
|
const [{ createReadStream }, { Readable }] = await Promise.all([
|
|
700
705
|
import("fs"),
|
|
@@ -718,7 +723,7 @@ function protocolToSpectrum(p) {
|
|
|
718
723
|
mimeType: p.mimeType,
|
|
719
724
|
size: p.size,
|
|
720
725
|
read: readBytes,
|
|
721
|
-
stream
|
|
726
|
+
stream: stream2
|
|
722
727
|
});
|
|
723
728
|
}
|
|
724
729
|
return asVoice({
|
|
@@ -726,7 +731,7 @@ function protocolToSpectrum(p) {
|
|
|
726
731
|
mimeType: p.mimeType,
|
|
727
732
|
size: p.size,
|
|
728
733
|
read: readBytes,
|
|
729
|
-
stream
|
|
734
|
+
stream: stream2
|
|
730
735
|
});
|
|
731
736
|
}
|
|
732
737
|
if (p.type === "contact") {
|
|
@@ -784,33 +789,57 @@ var terminal = definePlatform("Terminal", {
|
|
|
784
789
|
return { id };
|
|
785
790
|
}
|
|
786
791
|
},
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
792
|
+
// Return a ManagedStream (not a native async generator): a native generator
|
|
793
|
+
// parked on an in-flight `client.events.next()` cannot be force-cancelled —
|
|
794
|
+
// a `.return()` queues behind the pending `next()` and never reaches the
|
|
795
|
+
// event queue, which would deadlock `Spectrum.stop()`. Driving the queue with
|
|
796
|
+
// an explicit pump lets cleanup call the queue iterator's `return()` directly
|
|
797
|
+
// (synchronous close + drain), so the stream tears down promptly on stop()
|
|
798
|
+
// without waiting for destroyClient.
|
|
799
|
+
messages({ client }) {
|
|
800
|
+
return stream((emit, end) => {
|
|
801
|
+
const iterator = client.events[Symbol.asyncIterator]();
|
|
802
|
+
const pump = (async () => {
|
|
803
|
+
try {
|
|
804
|
+
let result = await iterator.next();
|
|
805
|
+
while (!result.done) {
|
|
806
|
+
const evt = result.value;
|
|
807
|
+
if (evt.kind === "message") {
|
|
808
|
+
const msg = evt.value;
|
|
809
|
+
client.knownChats.add(msg.spaceId);
|
|
810
|
+
await emit({
|
|
811
|
+
id: msg.id,
|
|
812
|
+
content: protocolToSpectrum(msg.content),
|
|
813
|
+
sender: { id: msg.senderId },
|
|
814
|
+
space: { id: msg.spaceId },
|
|
815
|
+
timestamp: parseTimestamp(msg.timestamp),
|
|
816
|
+
// replyTo is a terminal-specific extra — agents inspect via a
|
|
817
|
+
// cast until Spectrum's message model grows first-class support.
|
|
818
|
+
...msg.replyTo ? { replyTo: msg.replyTo } : {}
|
|
819
|
+
});
|
|
820
|
+
} else {
|
|
821
|
+
const r = evt.value;
|
|
822
|
+
client.knownChats.add(r.spaceId);
|
|
823
|
+
await emit({
|
|
824
|
+
id: `reaction:${r.messageId}:${r.reaction}:${r.timestamp}`,
|
|
825
|
+
content: reactionContentFromProtocol(r),
|
|
826
|
+
sender: { id: r.senderId },
|
|
827
|
+
space: { id: r.spaceId },
|
|
828
|
+
timestamp: parseTimestamp(r.timestamp)
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
result = await iterator.next();
|
|
832
|
+
}
|
|
833
|
+
end();
|
|
834
|
+
} catch (error) {
|
|
835
|
+
end(error);
|
|
836
|
+
}
|
|
837
|
+
})();
|
|
838
|
+
return async () => {
|
|
839
|
+
await iterator.return?.();
|
|
840
|
+
await pump.catch(() => void 0);
|
|
812
841
|
};
|
|
813
|
-
}
|
|
842
|
+
});
|
|
814
843
|
},
|
|
815
844
|
send: async ({ client, content, space }) => {
|
|
816
845
|
if (content.type === "reply") {
|