@spectrum-ts/imessage 9.1.0 → 9.3.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/index.d.ts CHANGED
@@ -141,6 +141,7 @@ declare const customizedMiniAppSchema: z.ZodObject<{
141
141
  imageSubtitle: z.ZodOptional<z.ZodString>;
142
142
  summary: z.ZodOptional<z.ZodString>;
143
143
  }, z.core.$strip>;
144
+ live: z.ZodOptional<z.ZodBoolean>;
144
145
  teamId: z.ZodString;
145
146
  url: z.ZodURL;
146
147
  }, z.core.$strip>;
@@ -155,7 +156,8 @@ type CustomizedMiniAppInput = Omit<CustomizedMiniApp, "type" | "__platform">;
155
156
  * the recipient taps the card; the server constructs the matching
156
157
  * `MSMessageExtensionBalloonPlugin` plugin id from these values. `appStoreId`
157
158
  * is optional and only points recipients without the extension at its App
158
- * Store entry.
159
+ * Store entry. `live` is optional; when omitted, the remote server keeps the
160
+ * static layout preview visible.
159
161
  *
160
162
  * `space.send(customizedMiniApp(...))` is the canonical form.
161
163
  *
@@ -193,8 +195,25 @@ declare const spaceSchema: z.ZodObject<{
193
195
  }>;
194
196
  phone: z.ZodString;
195
197
  }, z.core.$strip>;
198
+ declare const miniAppCardSessionSchema: z.ZodObject<{
199
+ chatGuid: z.ZodString;
200
+ messageGuid: z.ZodString;
201
+ sessionId: z.ZodString;
202
+ targetMessageGuid: z.ZodString;
203
+ }, z.core.$strip>;
204
+ /**
205
+ * iMessage-specific per-message metadata surfaced on `IMessageMessage`.
206
+ * - `partIndex`: ordered part index within a multi-part message. Text and
207
+ * attachment parts both consume an index (0 for bare or single-part
208
+ * messages; 0..N-1 for a group's sub-items).
209
+ * - `parentId`: guid of the parent message for a group sub-item. Undefined
210
+ * when the message itself is the parent.
211
+ * - `miniAppCardSession`: stable handle returned by mini-app card sends and
212
+ * updates. It is required to update the card in place later.
213
+ */
196
214
  type IMessageMessage = SchemaMessage<typeof userSchema, typeof spaceSchema> & {
197
215
  direction?: "inbound" | "outbound";
216
+ miniAppCardSession?: z.infer<typeof miniAppCardSessionSchema>;
198
217
  partIndex?: number;
199
218
  parentId?: string;
200
219
  };
@@ -238,6 +257,12 @@ declare const imessage: import("@spectrum-ts/core").Platform<import("@spectrum-t
238
257
  type: "dm" | "group";
239
258
  phone: string;
240
259
  }, import("zod").ZodObject<{
260
+ miniAppCardSession: import("zod").ZodOptional<import("zod").ZodObject<{
261
+ chatGuid: import("zod").ZodString;
262
+ messageGuid: import("zod").ZodString;
263
+ sessionId: import("zod").ZodString;
264
+ targetMessageGuid: import("zod").ZodString;
265
+ }, import("zod/v4/core").$strip>>;
241
266
  partIndex: import("zod").ZodOptional<import("zod").ZodNumber>;
242
267
  parentId: import("zod").ZodOptional<import("zod").ZodString>;
243
268
  }, import("zod/v4/core").$strip>, IMessageMessage, undefined, {
package/dist/index.js CHANGED
@@ -124,6 +124,7 @@ const customizedMiniAppSchema = z.object({
124
124
  appStoreId: z.number().int().positive().optional(),
125
125
  extensionBundleId: z.string().nonempty(),
126
126
  layout: layoutSchema,
127
+ live: z.boolean().optional(),
127
128
  teamId: z.string(),
128
129
  url: z.url()
129
130
  });
@@ -141,7 +142,8 @@ const asCustomizedMiniApp = (input) => customizedMiniAppSchema.parse({
141
142
  * the recipient taps the card; the server constructs the matching
142
143
  * `MSMessageExtensionBalloonPlugin` plugin id from these values. `appStoreId`
143
144
  * is optional and only points recipients without the extension at its App
144
- * Store entry.
145
+ * Store entry. `live` is optional; when omitted, the remote server keeps the
146
+ * static layout preview visible.
145
147
  *
146
148
  * `space.send(customizedMiniApp(...))` is the canonical form.
147
149
  *
@@ -202,6 +204,12 @@ const spaceSchema = z.object({
202
204
  phone: z.string()
203
205
  });
204
206
  const spaceParamsSchema = z.object({ phone: z.string().optional() });
207
+ const miniAppCardSessionSchema = z.object({
208
+ chatGuid: z.string(),
209
+ messageGuid: z.string(),
210
+ sessionId: z.string(),
211
+ targetMessageGuid: z.string()
212
+ });
205
213
  /**
206
214
  * iMessage-specific per-message metadata surfaced on `IMessageMessage`.
207
215
  * - `partIndex`: ordered part index within a multi-part message. Text and
@@ -209,8 +217,11 @@ const spaceParamsSchema = z.object({ phone: z.string().optional() });
209
217
  * messages; 0..N-1 for a group's sub-items).
210
218
  * - `parentId`: guid of the parent message for a group sub-item. Undefined
211
219
  * when the message itself is the parent.
220
+ * - `miniAppCardSession`: stable handle returned by mini-app card sends and
221
+ * updates. It is required to update the card in place later.
212
222
  */
213
223
  const messageSchema = z.object({
224
+ miniAppCardSession: miniAppCardSessionSchema.optional(),
214
225
  partIndex: z.number().int().nonnegative().optional(),
215
226
  parentId: z.string().optional()
216
227
  });
@@ -789,6 +800,14 @@ const shareContactCard$1 = async (remote, spaceId) => {
789
800
  };
790
801
  //#endregion
791
802
  //#region src/remote/customized-mini-app.ts
803
+ const toProviderRecord = (result, content, spaceId) => ({
804
+ id: result.guid,
805
+ content,
806
+ direction: "outbound",
807
+ miniAppCardSession: result.miniAppCardSession,
808
+ space: { id: spaceId },
809
+ timestamp: result.dateCreated
810
+ });
792
811
  /**
793
812
  * Send a `CustomizedMiniApp` card to a remote iMessage chat.
794
813
  *
@@ -800,14 +819,10 @@ const shareContactCard$1 = async (remote, spaceId) => {
800
819
  */
801
820
  const sendCustomizedMiniApp$1 = async (remote, spaceId, content) => {
802
821
  const chat = toChatGuid(spaceId);
803
- const message = await remote.messages.sendCustomizedMiniApp(chat, content);
804
- return {
805
- id: message.guid,
806
- content,
807
- direction: "outbound",
808
- space: { id: spaceId },
809
- timestamp: message.dateCreated
810
- };
822
+ return toProviderRecord(await remote.messages.sendCustomizedMiniApp(chat, content), content, spaceId);
823
+ };
824
+ const updateCustomizedMiniApp$1 = async (remote, spaceId, session, content) => {
825
+ return toProviderRecord(await remote.messages.updateCustomizedMiniApp(session, content), content, spaceId);
811
826
  };
812
827
  //#endregion
813
828
  //#region src/remote/attachments.ts
@@ -2163,6 +2178,7 @@ const stopTyping$1 = async (remote, spaceId) => {
2163
2178
  const messages = (clients, projectConfig) => messages$1(clients, projectConfig);
2164
2179
  const setBackground = async (remote, spaceId, content) => setBackground$1(remote, spaceId, content);
2165
2180
  const sendCustomizedMiniApp = async (remote, spaceId, content) => sendCustomizedMiniApp$1(remote, spaceId, content);
2181
+ const updateCustomizedMiniApp = async (remote, spaceId, session, content) => updateCustomizedMiniApp$1(remote, spaceId, session, content);
2166
2182
  const setDisplayName = async (remote, spaceId, content) => setDisplayName$1(remote, spaceId, content);
2167
2183
  const getDisplayName = async (remote, spaceId) => getDisplayName$1(remote, spaceId);
2168
2184
  const addParticipants = async (remote, spaceId, content) => addParticipants$1(remote, spaceId, content);
@@ -2208,13 +2224,14 @@ const SPECTRUM_MINI_APP = {
2208
2224
  };
2209
2225
  /**
2210
2226
  * Build the iMessage mini-app card for an `app` content: Spectrum's fixed
2211
- * identity plus the per-message `url` and the `layout` already derived from the
2212
- * URL's link metadata.
2227
+ * identity plus the per-message `url`, optional live-rendering hint, and the
2228
+ * `layout` already derived from the URL's link metadata.
2213
2229
  */
2214
- const toSpectrumMiniApp = (url, layout) => asCustomizedMiniApp({
2230
+ const toSpectrumMiniApp = (url, layout, live) => asCustomizedMiniApp({
2215
2231
  ...SPECTRUM_MINI_APP,
2216
2232
  url,
2217
- layout
2233
+ layout,
2234
+ ...live === void 0 ? {} : { live }
2218
2235
  });
2219
2236
  //#endregion
2220
2237
  //#region src/remote/client.ts
@@ -2259,6 +2276,25 @@ const cacheRemoteOutbound = (remote, space, record) => {
2259
2276
  };
2260
2277
  const handleEdit = async (client, space, content) => {
2261
2278
  if (isLocal(client)) throw UnsupportedError.action("edit", "iMessage (local mode)");
2279
+ const miniAppCardSession = content.target.miniAppCardSession;
2280
+ const updateMiniAppCardSession = (record) => {
2281
+ const nextSession = record?.miniAppCardSession;
2282
+ if (nextSession) content.target.miniAppCardSession = nextSession;
2283
+ };
2284
+ if (content.content.type === "app") {
2285
+ if (!miniAppCardSession) throw UnsupportedError.content("edit", "iMessage", "mini app card edits require a miniAppCardSession from the original send");
2286
+ const url = await content.content.url();
2287
+ const layout = await content.content.layout();
2288
+ const remote = clientForPhone(client, space.phone);
2289
+ updateMiniAppCardSession(cacheRemoteOutbound(remote, space, await updateCustomizedMiniApp(remote, space.id, miniAppCardSession, toSpectrumMiniApp(url, layout, content.content.live))));
2290
+ return;
2291
+ }
2292
+ if (isCustomizedMiniApp(content.content)) {
2293
+ if (!miniAppCardSession) throw UnsupportedError.content("edit", "iMessage", "customized mini app card edits require a miniAppCardSession from the original send");
2294
+ const remote = clientForPhone(client, space.phone);
2295
+ updateMiniAppCardSession(cacheRemoteOutbound(remote, space, await updateCustomizedMiniApp(remote, space.id, miniAppCardSession, content.content)));
2296
+ return;
2297
+ }
2262
2298
  if (content.content.type !== "text") throw UnsupportedError.content("edit", "iMessage", `only text content can be edited (got "${content.content.type}")`);
2263
2299
  await editMessage(clientForPhone(client, space.phone), space.id, content.target.id, content.content);
2264
2300
  };
@@ -2298,7 +2334,7 @@ const handleApp = async (client, space, content) => {
2298
2334
  if (isLocal(client)) return await send$2(client, space.id, await text(url).build());
2299
2335
  const layout = await content.layout();
2300
2336
  const remote = clientForPhone(client, space.phone);
2301
- return cacheRemoteOutbound(remote, space, await sendCustomizedMiniApp(remote, space.id, toSpectrumMiniApp(url, layout)));
2337
+ return cacheRemoteOutbound(remote, space, await sendCustomizedMiniApp(remote, space.id, toSpectrumMiniApp(url, layout, content.live)));
2302
2338
  };
2303
2339
  const handleRead = async (client, space) => {
2304
2340
  if (isLocal(client)) throw UnsupportedError.action("read", "iMessage (local mode)", "marking chats as read requires remote iMessage");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-ts/imessage",
3
- "version": "9.1.0",
3
+ "version": "9.3.0",
4
4
  "description": "iMessage provider for spectrum-ts — local and remote (advanced) modes.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,7 +31,7 @@
31
31
  "label": "iMessage"
32
32
  },
33
33
  "dependencies": {
34
- "@photon-ai/advanced-imessage": "^0.12.0",
34
+ "@photon-ai/advanced-imessage": "^1.0.0",
35
35
  "@photon-ai/imessage-kit": "^3.0.0",
36
36
  "@photon-ai/otel": "^3.1.0",
37
37
  "lru-cache": "^11.0.0",