Skip to content

Commit 6622de2

Browse files
Merge pull request #15 from photon-hq/docs/update-spectrum-ts-v1.3.0
docs: update spectrum-ts documentation for v1.3.0
2 parents 7fcfa11 + 24b2de2 commit 6622de2

5 files changed

Lines changed: 261 additions & 25 deletions

File tree

docs-src/spectrum-ts/custom-events-and-lifecycle.mdx.vel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Use the flat form on `app` when you want a merged feed across platforms; use the
4242
await app.stop();
4343
```
4444

45-
This closes the merged message stream, drains and disposes every custom event stream, and tears down every platform client via its `lifecycle.destroyClient` hook. It's idempotent — calling `stop()` twice is safe.
45+
This closes the merged message stream, drains and disposes every custom event stream, and tears down every platform client via its `lifecycle.destroyClient` hook (if one is defined). It's idempotent — calling `stop()` twice is safe.
4646

4747
### Signal handling
4848

docs-src/spectrum-ts/custom-platforms.mdx.vel

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const myPlatform = definePlatform("my-platform", {
4646

4747
// Client lifecycle
4848
lifecycle: {
49-
createClient: async ({ config }) => new MyPlatformClient(config.apiKey),
49+
createClient: async ({ config, store }) => new MyPlatformClient(config.apiKey),
5050
destroyClient: async ({ client }) => { await client.disconnect(); },
5151
},
5252

@@ -93,8 +93,8 @@ export const myPlatform = definePlatform("my-platform", {
9393
| `space.resolve` | Yes | Resolves or creates a conversation. Receives an array of users plus optional params. |
9494
| `space.schema` | No | Optional Zod schema for the resolved space. |
9595
| `space.params` | No | Zod schema for additional space creation parameters — surfaces as the second arg to `platform(app).space()`. |
96-
| `lifecycle.createClient` | Yes | Creates the platform client. Receives `config`, `projectId`, `projectSecret` (both may be `undefined`). |
97-
| `lifecycle.destroyClient` | Yes | Tears down the client on shutdown. |
96+
| `lifecycle.createClient` | Yes | Creates the platform client. Receives `config`, `projectId`, `projectSecret` (both may be `undefined`), and `store`. |
97+
| `lifecycle.destroyClient` | No | Tears down the client on shutdown. Omit if no cleanup is needed. |
9898
| `events.messages` | Yes | Async generator that yields incoming messages. |
9999
| `events.[custom]` | No | Additional async generators for platform-specific events — exposed on `app.[eventName]`. |
100100
| `actions.send` | Yes | Sends a single content item to a space. Invoked once per item when multiple are passed. |
@@ -107,7 +107,7 @@ export const myPlatform = definePlatform("my-platform", {
107107

108108
## Event producers
109109

110-
Every event generator receives `{ client, config }` and returns an `AsyncIterable`. The signature is <TypeTooltip name="EventProducer" type={`{{ ep.signature }}`} />.
110+
Every event generator receives `{ client, config, store }` and returns an `AsyncIterable`. The signature is <TypeTooltip name="EventProducer" type={`{{ ep.signature }}`} />.
111111

112112
```ts
113113
events: {

docs-src/spectrum-ts/providers/imessage.mdx.vel

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: "Receive and send iMessage across local, cloud, and dedicated modes
77
import { imessage } from "spectrum-ts/providers/imessage";
88
```
99

10-
The iMessage provider supports three connection modes — local, cloud, and dedicated — and exposes iMessage-specific features (tapbacks, DM vs group spaces) through [platform narrowing](/spectrum-ts/platform-narrowing).
10+
The iMessage provider supports three connection modes — local, cloud, and dedicated — and exposes iMessage-specific features (tapbacks, DM vs group spaces, per-phone routing) through [platform narrowing](/spectrum-ts/platform-narrowing).
1111

1212
## Connection modes
1313

@@ -41,18 +41,18 @@ The iMessage provider supports three connection modes — local, cloud, and dedi
4141
</Note>
4242
</Tab>
4343
<Tab title="Dedicated">
44-
Connect directly to one or more iMessage gRPC endpoints with your own tokens — use this when you're running your own iMessage relay and want to skip cloud auth:
44+
Connect directly to one or more iMessage gRPC endpoints with your own tokens — use this when you're running your own iMessage relay and want to skip cloud auth. Each entry must include the `phone` number the instance serves, so Spectrum can route messages through the right number:
4545

4646
```ts
4747
imessage.config({
4848
clients: [
49-
{ address: "instance-1.example.com:443", token: "your-token" },
50-
{ address: "instance-2.example.com:443", token: "your-token" },
49+
{ address: "instance-1.example.com:443", token: "your-token", phone: "+15551111111" },
50+
{ address: "instance-2.example.com:443", token: "your-token", phone: "+15552222222" },
5151
],
5252
});
5353
```
5454

55-
Multiple clients load-balance across instances.
55+
Multiple clients route messages based on the phone number associated with each space.
5656
</Tab>
5757
</Tabs>
5858

@@ -66,6 +66,7 @@ Cloud mode routes your messages through phone numbers ("lines") provisioned by S
6666
| **Business** | **Dedicated.** All of your end users text the same number, which belongs to your project. | A normal iMessage, always from the same number. |
6767

6868
End-user delivery is identical in both modes; the distinction is which number sends.
69+
Cloud mode routes your messages through dedicated phone numbers ("lines") provisioned by Spectrum. Each project gets one or more dedicated lines, and all your end users text the same number(s).
6970

7071
### Auto-scale
7172

@@ -77,12 +78,13 @@ When traffic to a dedicated line approaches its per-line capacity, Spectrum can
7778

7879
## Space types
7980

80-
iMessage spaces carry a `type` field — `"dm"` or `"group"` — accessible through narrowing:
81+
iMessage spaces carry a `type` field — `"dm"` or `"group"` — and a `phone` field indicating which phone number the conversation is routed through. Both are accessible through narrowing:
8182

8283
```ts
8384
for await (const [space, message] of app.messages) {
8485
if (message.platform !== "iMessage") continue;
8586
const im = imessage(space);
87+
console.log(im.phone); // the phone number handling this conversation
8688
if (im.type === "group") {
8789
// group chat logic
8890
}
@@ -109,6 +111,16 @@ await group.send("Welcome to the group.");
109111

110112
Space creation requires cloud or dedicated mode. In local mode `space()` throws — the local Messages database doesn't expose chat creation.
111113

114+
### Per-phone routing
115+
116+
If your account has multiple phone numbers, you can pin a conversation to a specific line by passing `phone` as a space parameter:
117+
118+
```ts
119+
const dm = await im.space(alice, { phone: "+15559999999" });
120+
```
121+
122+
When omitted, Spectrum picks a phone at random from the available lines. All subsequent actions on that space — sending, typing, replies, edits, reactions, and lookups — route through the chosen number.
123+
112124
## Tapback constants
113125

114126
iMessage uses a fixed set of tapback reactions. The `imessage` object exposes them as constants:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"eslint-plugin-format": "^2.0.1",
2828
"husky": "^9.1.7",
2929
"oxfmt": "^0.44.0",
30-
"spectrum-ts": "^0.3.0",
30+
"spectrum-ts": "1.2.1",
3131
"tsx": "^4.21.0",
3232
"typescript": "^5.9.3"
3333
}

0 commit comments

Comments
 (0)