serverless-ircd 0.3.0 → 0.4.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/.github/workflows/ci.yml +2 -2
- package/.github/workflows/deploy-aws.yml +1 -3
- package/.github/workflows/deploy-cf-tcp.yml +87 -0
- package/.github/workflows/deploy-cf.yml +1 -1
- package/.node-version +1 -0
- package/.nvmrc +1 -0
- package/CHANGELOG.md +174 -18
- package/README.md +63 -30
- package/apps/aws-stack/README.md +2 -2
- package/apps/aws-stack/bin/aws.ts +7 -0
- package/apps/aws-stack/package.json +4 -4
- package/apps/aws-stack/src/aws-stack.ts +118 -6
- package/apps/aws-stack/tests/stack.test.ts +98 -3
- package/apps/cf-tcp-container/Dockerfile +69 -0
- package/apps/cf-tcp-container/package.json +34 -0
- package/apps/cf-tcp-container/src/config-loader.ts +145 -0
- package/apps/cf-tcp-container/src/container-do.ts +38 -0
- package/apps/cf-tcp-container/src/container-server.ts +363 -0
- package/apps/cf-tcp-container/src/main.ts +77 -0
- package/apps/cf-tcp-container/src/persistence.ts +144 -0
- package/apps/cf-tcp-container/src/worker.ts +41 -0
- package/apps/cf-tcp-container/terraform/provider.tf +24 -0
- package/apps/cf-tcp-container/terraform/spectrum.tf +81 -0
- package/apps/cf-tcp-container/tests/config-loader.test.ts +217 -0
- package/apps/cf-tcp-container/tests/container-server.test.ts +465 -0
- package/apps/cf-tcp-container/tests/persistence.test.ts +227 -0
- package/apps/cf-tcp-container/tests/tls-e2e.test.ts +275 -0
- package/apps/cf-tcp-container/tsconfig.build.json +17 -0
- package/apps/cf-tcp-container/tsconfig.test.json +15 -0
- package/apps/cf-tcp-container/vitest.config.ts +26 -0
- package/apps/cf-tcp-container/wrangler.toml +63 -0
- package/apps/cf-worker/package.json +1 -1
- package/apps/cf-worker/wrangler.test.toml +6 -0
- package/apps/cf-worker/wrangler.toml +28 -2
- package/apps/local-cli/package.json +1 -1
- package/apps/local-cli/src/config-loader.ts +10 -0
- package/apps/local-cli/src/server.ts +20 -3
- package/package.json +14 -10
- package/packages/aws-adapter/package.json +3 -3
- package/packages/aws-adapter/src/account-store.ts +1 -1
- package/packages/aws-adapter/src/admission.ts +74 -0
- package/packages/aws-adapter/src/aws-runtime.ts +6 -4
- package/packages/aws-adapter/src/config-loader.ts +32 -0
- package/packages/aws-adapter/src/dynamo-account-store.ts +35 -96
- package/packages/aws-adapter/src/handlers/connect.ts +64 -8
- package/packages/aws-adapter/src/handlers/default.ts +35 -2
- package/packages/aws-adapter/src/handlers/index.ts +69 -3
- package/packages/aws-adapter/src/handlers/nlb-stream.ts +481 -0
- package/packages/aws-adapter/src/handlers/ping-checker.ts +1 -1
- package/packages/aws-adapter/src/index.ts +6 -0
- package/packages/aws-adapter/tests/account-store-dynamo.test.ts +45 -34
- package/packages/aws-adapter/tests/account-store.test.ts +19 -20
- package/packages/aws-adapter/tests/admission.test.ts +70 -0
- package/packages/aws-adapter/tests/aws-harness.ts +13 -1
- package/packages/aws-adapter/tests/config-loader.test.ts +20 -0
- package/packages/aws-adapter/tests/connect.test.ts +78 -0
- package/packages/aws-adapter/tests/disconnect-fanout.test.ts +47 -40
- package/packages/aws-adapter/tests/gone-exception.test.ts +31 -26
- package/packages/aws-adapter/tests/handlers.test.ts +154 -53
- package/packages/aws-adapter/tests/nlb-stream.test.ts +478 -0
- package/packages/aws-adapter/tests/ping-checker.test.ts +34 -29
- package/packages/aws-adapter/tests/sweeper.test.ts +25 -18
- package/packages/aws-adapter/tests/transactions.test.ts +25 -20
- package/packages/cf-adapter/package.json +1 -1
- package/packages/cf-adapter/src/cf-runtime.ts +2 -4
- package/packages/cf-adapter/src/config-loader.ts +33 -0
- package/packages/cf-adapter/src/connection-do.ts +111 -46
- package/packages/cf-adapter/src/d1-account-store.ts +198 -0
- package/packages/cf-adapter/src/env.ts +33 -9
- package/packages/cf-adapter/src/index.ts +9 -8
- package/packages/cf-adapter/tests/cf-harness.ts +11 -1
- package/packages/cf-adapter/tests/cf-integration.test.ts +2 -1
- package/packages/cf-adapter/tests/config-loader.test.ts +22 -0
- package/packages/cf-adapter/tests/connection-do-channel-registration.test.ts +37 -0
- package/packages/cf-adapter/tests/connection-do-no-batching-reservation.test.ts +52 -0
- package/packages/cf-adapter/tests/connection-do-sasl-d1.test.ts +166 -0
- package/packages/cf-adapter/tests/d1-account-store.test.ts +226 -0
- package/packages/cf-adapter/tests/raw-modules.d.ts +11 -0
- package/packages/cf-adapter/tests/worker/main.ts +8 -1
- package/packages/cf-adapter/wrangler.test.toml +8 -0
- package/packages/in-memory-runtime/package.json +1 -1
- package/packages/irc-core/package.json +6 -1
- package/packages/irc-core/scripts/generate-build-info.mjs +31 -0
- package/packages/irc-core/src/caps/capabilities.ts +23 -2
- package/packages/irc-core/src/cloak.ts +1 -1
- package/packages/irc-core/src/commands/cap.ts +8 -1
- package/packages/irc-core/src/commands/index.ts +9 -0
- package/packages/irc-core/src/commands/ison.ts +61 -0
- package/packages/irc-core/src/commands/quit.ts +12 -0
- package/packages/irc-core/src/commands/registration.ts +18 -12
- package/packages/irc-core/src/commands/sasl.ts +72 -9
- package/packages/irc-core/src/commands/server-info.ts +129 -0
- package/packages/irc-core/src/commands/userhost.ts +84 -0
- package/packages/irc-core/src/commands/whowas.ts +113 -0
- package/packages/irc-core/src/config.ts +58 -0
- package/packages/irc-core/src/credential-hashing.ts +124 -0
- package/packages/irc-core/src/effects.ts +6 -29
- package/packages/irc-core/src/index.ts +1 -0
- package/packages/irc-core/src/ports.ts +181 -12
- package/packages/irc-core/src/protocol/numerics.ts +14 -8
- package/packages/irc-core/src/types.ts +38 -1
- package/packages/irc-core/tests/account-store.test.ts +45 -2
- package/packages/irc-core/tests/caps/capabilities.test.ts +4 -3
- package/packages/irc-core/tests/commands/cap.test.ts +33 -1
- package/packages/irc-core/tests/commands/ison.test.ts +166 -0
- package/packages/irc-core/tests/commands/quit.test.ts +69 -2
- package/packages/irc-core/tests/commands/registration.test.ts +151 -6
- package/packages/irc-core/tests/commands/sasl.test.ts +118 -10
- package/packages/irc-core/tests/commands/server-info.test.ts +274 -0
- package/packages/irc-core/tests/commands/tagmsg.test.ts +9 -35
- package/packages/irc-core/tests/commands/userhost.test.ts +264 -0
- package/packages/irc-core/tests/commands/whowas.test.ts +312 -0
- package/packages/irc-core/tests/config.test.ts +95 -1
- package/packages/irc-core/tests/credential-hashing.test.ts +170 -0
- package/packages/irc-core/tests/effects.test.ts +0 -27
- package/packages/irc-core/tests/nick-history-store.test.ts +162 -0
- package/packages/irc-core/tests/numerics.test.ts +12 -0
- package/packages/irc-core/tests/types.test.ts +35 -1
- package/packages/irc-core/tsconfig.build.json +1 -1
- package/packages/irc-core/tsconfig.test.json +1 -1
- package/packages/irc-server/package.json +1 -1
- package/packages/irc-server/src/actor.ts +158 -14
- package/packages/irc-server/src/dispatch.ts +0 -3
- package/packages/irc-server/src/index.ts +10 -2
- package/packages/irc-server/src/routing.ts +12 -0
- package/packages/irc-server/src/transport.ts +101 -0
- package/packages/irc-server/tests/actor.test.ts +400 -3
- package/packages/irc-server/tests/dispatch.test.ts +0 -17
- package/packages/irc-server/tests/routing.test.ts +4 -0
- package/packages/irc-server/tests/transport.test.ts +230 -0
- package/packages/irc-test-support/package.json +1 -1
- package/packages/irc-test-support/src/harness.ts +44 -9
- package/packages/irc-test-support/src/in-memory-harness.ts +73 -9
- package/packages/irc-test-support/src/index.ts +3 -0
- package/packages/irc-test-support/src/scenarios.ts +132 -2
- package/packages/irc-test-support/tests/in-memory-harness.test.ts +2 -1
- package/packages/irc-test-support/tests/in-memory-scenarios.test.ts +23 -9
- package/pnpm-workspace.yaml +9 -1
- package/tools/ci-hardening/package.json +1 -1
- package/tools/package.json +4 -0
- package/tools/seed-aws-accounts.ts +5 -6
- package/tools/seed-cf-accounts.ts +104 -0
- package/tools/tcp-ws-forwarder/package.json +1 -1
- package/docs/ADR-001-pure-reducers-and-effect-system.md +0 -74
- package/docs/ADR-002-location-of-authority.md +0 -82
- package/docs/ADR-003-durable-object-sharding.md +0 -93
- package/docs/ADR-004-dynamodb-schema.md +0 -96
- package/docs/ADR-005-wss-only-transport-v1.md +0 -83
- package/docs/ADR-006-sasl-mechanism-scope.md +0 -86
- package/docs/ADR-007-deterministic-ports.md +0 -82
- package/docs/ADR-008-monorepo-tooling.md +0 -60
- package/docs/AWS-Adapter-Architecture.md +0 -496
- package/docs/AWS-Deployment.md +0 -1186
- package/docs/Cloudflare-Deployment-Guide.md +0 -660
- package/docs/Home.md +0 -11
- package/docs/Observability.md +0 -87
- package/docs/PlanIRCv3Websocket.md +0 -489
- package/docs/PlanWebClient.md +0 -451
- package/docs/Release-Process.md +0 -443
|
@@ -1,660 +0,0 @@
|
|
|
1
|
-
# Cloudflare Deployment Guide
|
|
2
|
-
|
|
3
|
-
End-to-end guide for deploying ServerlessIRCd to Cloudflare Workers
|
|
4
|
-
(Phase 3 of `PLAN.md`). Covers prerequisites, first-time account setup,
|
|
5
|
-
local development, staging deploy, production deploy, configuration,
|
|
6
|
-
secrets, sharding, CI/CD, cost, and troubleshooting.
|
|
7
|
-
|
|
8
|
-
Cross-reference: `PLAN.md` §6.1 (CF mapping), `apps/cf-worker/wrangler.toml`,
|
|
9
|
-
`packages/cf-adapter/`, `.github/workflows/deploy-cf.yml`. For the AWS
|
|
10
|
-
equivalent, see `docs/deployment-aws.md` (TICKET-044).
|
|
11
|
-
|
|
12
|
-
**Acceptance criterion (TICKET-038):** a new contributor can deploy their
|
|
13
|
-
own staging instance following only this doc.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## 1. What gets deployed
|
|
18
|
-
|
|
19
|
-
A single Cloudflare Worker (`serverless-ircd`) plus three Durable Object
|
|
20
|
-
namespaces that hold all IRC state:
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
24
|
-
│ Worker: serverless-ircd (apps/cf-worker/src/worker.ts) │
|
|
25
|
-
│ │
|
|
26
|
-
│ fetch(request, env): │
|
|
27
|
-
│ Upgrade: websocket ──▶ ConnectionDO.idFromName(uuid) │
|
|
28
|
-
│ else ──▶ 200 human health string │
|
|
29
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
30
|
-
│ env.CONNECTION_DO.get(id).fetch()
|
|
31
|
-
▼
|
|
32
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
33
|
-
│ ConnectionDO (one per WebSocket connection) │
|
|
34
|
-
│ • hibernatable WS via HibernatingWebSocketHandler │
|
|
35
|
-
│ • owns ConnectionState, drives ConnectionActor │
|
|
36
|
-
│ • DO storage persists state across hibernation │
|
|
37
|
-
│ • alarm() drives the PING / no-PONG disconnect sweep │
|
|
38
|
-
└────┬───────────────────────────────┬────────────────────────┘
|
|
39
|
-
│ stub() RPC │ stub() RPC
|
|
40
|
-
▼ ▼
|
|
41
|
-
┌──────────────────────┐ ┌──────────────────────────────────┐
|
|
42
|
-
│ RegistryDO │ │ ChannelDO │
|
|
43
|
-
│ (sharded by nick) │ │ (one per lowercased chan name) │
|
|
44
|
-
│ • nick uniqueness │ │ • roster + modes + topic │
|
|
45
|
-
│ • nick→connId map │ │ • fanout to members │
|
|
46
|
-
└──────────────────────┘ └──────────────────────────────────┘
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
The Worker itself is a thin edge: it allocates a server-generated
|
|
50
|
-
`connectionId` (`crypto.randomUUID()`) and routes the upgrade to that
|
|
51
|
-
connection's `ConnectionDO`. All IRC protocol logic lives in the shared
|
|
52
|
-
`irc-core` reducers, run by `ConnectionActor` inside the DO. No state is
|
|
53
|
-
held in the Worker process itself.
|
|
54
|
-
|
|
55
|
-
The same artifacts serve both staging and production; the only difference
|
|
56
|
-
is the `--env` flag and the `[env.staging]` block in `wrangler.toml`.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## 2. Prerequisites
|
|
61
|
-
|
|
62
|
-
| Requirement | Version / detail |
|
|
63
|
-
|-----------------------|--------------------------------------------------------|
|
|
64
|
-
| Node.js | ≥ 20 (matches CI; `engines.node` in root `package.json`)|
|
|
65
|
-
| pnpm | 9.x (`packageManager: pnpm@9.15.9` in root `package.json`)|
|
|
66
|
-
| Cloudflare account | Free tier is enough for staging. Workers Paid plan |
|
|
67
|
-
| | (USD $5/mo) is recommended for production — see §10. |
|
|
68
|
-
| `wrangler` CLI | Comes from `apps/cf-worker/devDependencies`; no global install needed. |
|
|
69
|
-
| Git checkout | Clean working tree on `main` for production deploys. |
|
|
70
|
-
|
|
71
|
-
A **Workers Paid plan** is not strictly required for staging, but
|
|
72
|
-
Durable Objects only run on the Paid plan in any meaningful production
|
|
73
|
-
scenario. The free tier caps DO requests and disables hibernation
|
|
74
|
-
budget headroom. See §10 (Cost).
|
|
75
|
-
|
|
76
|
-
Confirm the local environment:
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
node --version # v20.x or newer
|
|
80
|
-
pnpm --version # 9.x
|
|
81
|
-
pnpm install # from repo root, installs the whole workspace
|
|
82
|
-
pnpm build # builds irc-core, irc-server, cf-adapter, cf-worker
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
`pnpm build` must succeed before `wrangler deploy` — the Worker's
|
|
86
|
-
`main = "src/worker.ts"` is transpiled by wrangler, but it imports
|
|
87
|
-
compiled `dist/` from the workspace packages.
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## 3. First-time Cloudflare setup
|
|
92
|
-
|
|
93
|
-
These steps are done once per Cloudflare account.
|
|
94
|
-
|
|
95
|
-
### 3.1 Claim a workers.dev subdomain
|
|
96
|
-
|
|
97
|
-
Every Worker is reachable at `<worker-name>.<subdomain>.workers.dev`.
|
|
98
|
-
Claim your subdomain in the dashboard: **Workers & Pages → General →
|
|
99
|
-
Subdomain** (or via `wrangler subdomain <name>`). This guide assumes
|
|
100
|
-
your subdomain is `example`; substitute your own.
|
|
101
|
-
|
|
102
|
-
If you intend to use a custom domain (`irc.example.com`), you can skip
|
|
103
|
-
the workers.dev subdomain and add a **Route** + DNS record instead (see
|
|
104
|
-
§8.4).
|
|
105
|
-
|
|
106
|
-
### 3.2 Create an API token
|
|
107
|
-
|
|
108
|
-
The `wrangler` CLI needs a token with permission to deploy Workers and
|
|
109
|
-
manage Durable Objects.
|
|
110
|
-
|
|
111
|
-
1. Go to <https://dash.cloudflare.com/profile/api-tokens> → **Create
|
|
112
|
-
Token**.
|
|
113
|
-
2. Use the **"Edit Cloudflare Workers"** template, which grants:
|
|
114
|
-
- `Account · Workers Scripts · Edit`
|
|
115
|
-
- `Account · Durable Objects · Edit`
|
|
116
|
-
- `Account · Worker Routes · Edit` (only if using custom domains)
|
|
117
|
-
3. Restrict to the target **Account Resources**.
|
|
118
|
-
4. Copy the token. You will set it as `CLOUDFLARE_API_TOKEN` (env var
|
|
119
|
-
for local CLI; Actions secret for CI).
|
|
120
|
-
|
|
121
|
-
Also grab your **Account ID** from the dashboard sidebar — set it as
|
|
122
|
-
`CLOUDFLARE_ACCOUNT_ID` if your token doesn't carry an unambiguous
|
|
123
|
-
account context.
|
|
124
|
-
|
|
125
|
-
### 3.3 Authenticate the CLI locally
|
|
126
|
-
|
|
127
|
-
Two equivalent options:
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
# Interactive (recommended for humans):
|
|
131
|
-
npx wrangler login
|
|
132
|
-
|
|
133
|
-
# Non-interactive (CI or ephemeral):
|
|
134
|
-
export CLOUDFLARE_API_TOKEN=...
|
|
135
|
-
export CLOUDFLARE_ACCOUNT_ID=...
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
When `CLOUDFLARE_API_TOKEN` is set in the environment, `wrangler` uses
|
|
139
|
-
it directly and skips the OAuth store. The deploy commands in
|
|
140
|
-
`apps/cf-worker/package.json` (`deploy:staging`, `deploy:prod`) honor
|
|
141
|
-
both.
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## 4. Local development
|
|
146
|
-
|
|
147
|
-
Before deploying, run the Worker locally with the real `workerd`
|
|
148
|
-
runtime. This exercises the DOs, storage, and alarms against Miniflare
|
|
149
|
-
without touching Cloudflare.
|
|
150
|
-
|
|
151
|
-
From the repo root:
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
pnpm build
|
|
155
|
-
pnpm --filter @serverless-ircd/cf-worker dev
|
|
156
|
-
# → boots wrangler dev on http://localhost:8787
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
In another terminal, run the smoke e2e against the local URL (the
|
|
160
|
-
script defaults to `ws://localhost:8787`):
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
node apps/cf-worker/scripts/smoke.mjs
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Expected output (success):
|
|
167
|
-
|
|
168
|
-
```json
|
|
169
|
-
{"ts":"...","level":"info","msg":"cf-worker smoke e2e passed","url":"ws://localhost:8787"}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
The smoke script (`scripts/smoke.mjs`) replays
|
|
173
|
-
CONNECT → NICK/USER → JOIN #smoke → PRIVMSG → QUIT and asserts the
|
|
174
|
-
server emits `001`, `376`, `353`, `366`, and closes the socket. It is
|
|
175
|
-
the exact same script CI runs against the deployed staging URL.
|
|
176
|
-
|
|
177
|
-
The unit + integration suites live in `packages/cf-adapter/tests/` and
|
|
178
|
-
`apps/cf-worker/tests/`; both run under `@cloudflare/vitest-pool-workers`
|
|
179
|
-
against real `workerd`, so behavior matches production. Run them with:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
pnpm --filter @serverless-ircd/cf-adapter test
|
|
183
|
-
pnpm --filter @serverless-ircd/cf-worker test
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## 5. Deploy staging
|
|
189
|
-
|
|
190
|
-
Staging is the environment CI deploys on every push to `main`; you can
|
|
191
|
-
also deploy it manually from a clean checkout.
|
|
192
|
-
|
|
193
|
-
### 5.1 Deploy from your machine
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# From the repo root:
|
|
197
|
-
pnpm deploy:cf:staging
|
|
198
|
-
# Equivalent to:
|
|
199
|
-
# pnpm --filter @serverless-ircd/cf-worker deploy:staging
|
|
200
|
-
# → wrangler deploy --env staging
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
The first deploy of a given account will:
|
|
204
|
-
|
|
205
|
-
1. Create the Worker `serverless-ircd-staging`.
|
|
206
|
-
2. Apply the `[[env.staging.migrations]]` block (`tag = "v1"`,
|
|
207
|
-
`new_classes = [ConnectionDO, RegistryDO, ChannelDO]`). This is what
|
|
208
|
-
provisions the three DO namespaces.
|
|
209
|
-
3. Print the deployed URL, e.g.
|
|
210
|
-
`https://serverless-ircd-staging.example.workers.dev`.
|
|
211
|
-
|
|
212
|
-
If you see `Migration tag has already been applied`, the namespaces
|
|
213
|
-
already exist; subsequent deploys just update the Worker code.
|
|
214
|
-
|
|
215
|
-
### 5.2 Verify with the smoke script
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
node apps/cf-worker/scripts/smoke.mjs \
|
|
219
|
-
--url wss://serverless-ircd-staging.example.workers.dev
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
The same JSON `level: "info"` line on stdout means the full
|
|
223
|
-
REGISTER/JOIN/PRIVMSG/QUIT flow completed against the deployed Worker.
|
|
224
|
-
|
|
225
|
-
### 5.3 Connect a real IRC client
|
|
226
|
-
|
|
227
|
-
Point any RFC-compliant WebSocket-aware IRC client at the deployed URL.
|
|
228
|
-
For WeeChat:
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
/server add ircd serverless-ircd-staging.example.workers.dev/443
|
|
232
|
-
/set irc.server.ircd.ssl on
|
|
233
|
-
/connect ircd
|
|
234
|
-
/join #test
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
For a quick text-only check, the `apps/local-cli` and
|
|
238
|
-
`tools/tcp-ws-forwarder` packages bridge a plain TCP IRC client to the
|
|
239
|
-
Worker's WebSocket endpoint — see the README "Bridging raw TCP clients"
|
|
240
|
-
section.
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
## 6. Deploy production
|
|
245
|
-
|
|
246
|
-
Production is the default `wrangler.toml` environment (no `--env`
|
|
247
|
-
flag). It deploys the Worker named `serverless-ircd` (no `-staging`
|
|
248
|
-
suffix) with its own DO namespaces.
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
# From the repo root:
|
|
252
|
-
pnpm deploy:cf:prod
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Before your first production deploy, edit `apps/cf-worker/wrangler.toml`:
|
|
256
|
-
|
|
257
|
-
1. Set `[vars].SERVER_NAME` to the public hostname clients should see
|
|
258
|
-
in numerics (`001`, `005`, etc.) — e.g. `irc.example.com`.
|
|
259
|
-
2. Set `[vars].NETWORK_NAME` to your network label.
|
|
260
|
-
3. Set `[vars].MOTD_LINES` to your message-of-the-day (newline-delimited).
|
|
261
|
-
4. (Optional) Add a custom-domain Route under `[[routes]]` — see §8.4.
|
|
262
|
-
|
|
263
|
-
**First-time production migration:** the default `[[migrations]]` block
|
|
264
|
-
applies on the first `deploy:cf:prod` and creates the production DO
|
|
265
|
-
classes. This is one-way: once a DO namespace has data, you cannot
|
|
266
|
-
rename or delete a class without an explicit migration entry (see
|
|
267
|
-
§9.2).
|
|
268
|
-
|
|
269
|
-
There is **no CI auto-deploy to production** — production deploys are
|
|
270
|
-
always manual (`workflow_dispatch` only is intentionally not wired; see
|
|
271
|
-
`.github/workflows/deploy-cf.yml`). Staging deploys on every push to
|
|
272
|
-
`main`.
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## 7. Configuration reference
|
|
277
|
-
|
|
278
|
-
All deployment knobs live in `apps/cf-worker/wrangler.toml`. The file
|
|
279
|
-
is the single source of truth for both environments.
|
|
280
|
-
|
|
281
|
-
### 7.1 Top-level / `[vars]`
|
|
282
|
-
|
|
283
|
-
| Var | Purpose | Default |
|
|
284
|
-
|-----------------|----------------------------------------------------|--------------------------------------|
|
|
285
|
-
| `name` | Worker name. Staging overrides to `...-staging`. | `serverless-ircd` |
|
|
286
|
-
| `main` | Worker entry. | `src/worker.ts` |
|
|
287
|
-
| `compatibility_date` | Pins Workers runtime behavior. | `2024-11-01` |
|
|
288
|
-
| `compatibility_flags` | `nodejs_compat` enables Node-style APIs. | `["nodejs_compat"]` |
|
|
289
|
-
| `SERVER_NAME` | Server name sent in `001`/`005` numerics. | `irc.example.com` (override!) |
|
|
290
|
-
| `NETWORK_NAME` | Network label in `005 NETWORK=…`. | `ServerlessIRCd` |
|
|
291
|
-
| `MOTD_LINES` | Message-of-the-day, `\n`-delimited. | Welcome banner string. |
|
|
292
|
-
|
|
293
|
-
These are read by `ConnectionDO` via `Env` (see
|
|
294
|
-
`packages/cf-adapter/src/env.ts:20` and the `serverConfig()` method in
|
|
295
|
-
`connection-do.ts:337`). They are **not** secrets — they ship in the
|
|
296
|
-
bundle and are visible in the dashboard.
|
|
297
|
-
|
|
298
|
-
### 7.2 `[env.staging]`
|
|
299
|
-
|
|
300
|
-
The staging block overrides `name` and `[vars]` only. The DO bindings
|
|
301
|
-
and migrations must be redeclared per-environment (wrangler requires
|
|
302
|
-
explicit per-env blocks — they do not inherit):
|
|
303
|
-
|
|
304
|
-
```toml
|
|
305
|
-
[env.staging]
|
|
306
|
-
name = "serverless-ircd-staging"
|
|
307
|
-
|
|
308
|
-
[env.staging.vars]
|
|
309
|
-
SERVER_NAME = "irc-staging.example.com"
|
|
310
|
-
NETWORK_NAME = "ServerlessIRCd (staging)"
|
|
311
|
-
MOTD_LINES = "..."
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### 7.3 Durable Object bindings
|
|
315
|
-
|
|
316
|
-
Three DO classes are exported from `src/worker.ts` (re-exported from
|
|
317
|
-
`@serverless-ircd/cf-adapter`) and bound in `wrangler.toml`:
|
|
318
|
-
|
|
319
|
-
| Binding name | Class | Owned state |
|
|
320
|
-
|-------------------|----------------|--------------------------------------------|
|
|
321
|
-
| `CONNECTION_DO` | `ConnectionDO` | Socket + ConnectionState + PING alarms. |
|
|
322
|
-
| `REGISTRY_DO` | `RegistryDO` | Nick uniqueness, nick→connId map (sharded).|
|
|
323
|
-
| `CHANNEL_DO` | `ChannelDO` | Per-channel roster, modes, topic, fanout. |
|
|
324
|
-
|
|
325
|
-
The class names in `wrangler.toml`'s `class_name` field MUST match the
|
|
326
|
-
re-exports at the top of `apps/cf-worker/src/worker.ts:29`.
|
|
327
|
-
|
|
328
|
-
### 7.4 Migrations
|
|
329
|
-
|
|
330
|
-
```toml
|
|
331
|
-
[[migrations]]
|
|
332
|
-
tag = "v1"
|
|
333
|
-
new_classes = ["ConnectionDO", "RegistryDO", "ChannelDO"]
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
`tag` is the migration id (string, monotonically tracked by wrangler).
|
|
337
|
-
`new_classes` declares the DO classes on first deploy. To **rename** or
|
|
338
|
-
**delete** a class after data exists, append a new `[[migrations]]`
|
|
339
|
-
block with `tag = "v2"` (etc.) and a `renamed_classes` or `deleted_classes`
|
|
340
|
-
entry. See <https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/>.
|
|
341
|
-
|
|
342
|
-
Both the default and staging environments carry their own migration
|
|
343
|
-
list. Keep them in sync unless you intentionally diverge.
|
|
344
|
-
|
|
345
|
-
### 7.5 Custom domain (optional)
|
|
346
|
-
|
|
347
|
-
To serve the Worker on `irc.example.com` instead of the workers.dev
|
|
348
|
-
subdomain, add a route and bind a Cloudflare-managed DNS record:
|
|
349
|
-
|
|
350
|
-
```toml
|
|
351
|
-
[[routes]]
|
|
352
|
-
pattern = "irc.example.com/*"
|
|
353
|
-
zone_name = "example.com"
|
|
354
|
-
custom_domain = false # true if you'd rather use a Worker Custom Domain
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
Custom domains are optional for staging and recommended for production
|
|
358
|
-
(many IRC clients expect a stable, owned hostname). DNS records are
|
|
359
|
-
managed separately in the dashboard.
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
## 8. Secrets
|
|
364
|
-
|
|
365
|
-
**As of v1 the Worker consumes no secret bindings.** Server password,
|
|
366
|
-
SASL `AccountStore` credentials, and oper creds land in later tickets
|
|
367
|
-
(TICKET-046 / TICKET-047). When they ship, secrets will be set via:
|
|
368
|
-
|
|
369
|
-
```bash
|
|
370
|
-
wrangler secret put SERVER_PASSWORD --env staging
|
|
371
|
-
# → prompts for the value; stores it in the Workers secret store,
|
|
372
|
-
# NOT in wrangler.toml or the repo.
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
Secrets are visible to the Worker as plain `env.SECRET_NAME` bindings,
|
|
376
|
-
but their values are never written to disk, the bundle, or the
|
|
377
|
-
dashboard's variable listing. To rotate, run `wrangler secret put`
|
|
378
|
-
again; to remove, `wrangler secret delete <NAME>`.
|
|
379
|
-
|
|
380
|
-
**Never** put credentials, API tokens, or password hashes in
|
|
381
|
-
`wrangler.toml`, in `[vars]`, or in committed files. The
|
|
382
|
-
`wrangler.toml` header enforces this with a comment block (see lines
|
|
383
|
-
15-20).
|
|
384
|
-
|
|
385
|
-
The CI deploy uses two **GitHub Actions secrets**, not Workers
|
|
386
|
-
secrets:
|
|
387
|
-
|
|
388
|
-
| Secret | Used by | Purpose |
|
|
389
|
-
|-------------------------|--------------------------|--------------------------------------|
|
|
390
|
-
| `CLOUDFLARE_API_TOKEN` | `deploy-cf.yml` | Authenticates `wrangler deploy`. |
|
|
391
|
-
| `CLOUDFLARE_ACCOUNT_ID` | `deploy-cf.yml` | Disambiguates account context. |
|
|
392
|
-
|
|
393
|
-
And one **Actions variable**:
|
|
394
|
-
|
|
395
|
-
| Variable | Purpose |
|
|
396
|
-
|----------------|------------------------------------------------------------|
|
|
397
|
-
| `CF_SMOKE_URL` | `wss://` URL the smoke e2e step hits. If unset, smoke is skipped with a warning. |
|
|
398
|
-
|
|
399
|
-
Configure both under repo **Settings → Secrets and variables → Actions**.
|
|
400
|
-
|
|
401
|
-
---
|
|
402
|
-
|
|
403
|
-
## 9. Sharding
|
|
404
|
-
|
|
405
|
-
### 9.1 How nick registry sharding works
|
|
406
|
-
|
|
407
|
-
The `RegistryDO` fleet is sharded so no single DO becomes a hot spot
|
|
408
|
-
for popular nicknames. Shard assignment is:
|
|
409
|
-
|
|
410
|
-
```
|
|
411
|
-
shard = fnv1a32(lowercased(nick)) mod N
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
Properties (see `packages/cf-adapter/src/sharding.ts` for full rationale):
|
|
415
|
-
|
|
416
|
-
- **Deterministic** — every Worker instance computes the same shard for
|
|
417
|
-
a given nick with zero coordination.
|
|
418
|
-
- **Case-insensitive** — `Alice`, `alice`, and `ALICE` collide in the
|
|
419
|
-
same shard, so the single-shard uniqueness check covers all RFC 1459
|
|
420
|
-
case variants.
|
|
421
|
-
- **Synchronous & dependency-free** — runs on every nick reservation,
|
|
422
|
-
so no `await` and no external hash library.
|
|
423
|
-
|
|
424
|
-
The shard id (`s0`, `s1`, …, `s31`) becomes the `idFromName()` key for
|
|
425
|
-
that nick's `RegistryDO`. Two clients racing on `Alice` both route to
|
|
426
|
-
`RegistryDO s7`, where DO single-threadedness makes the uniqueness
|
|
427
|
-
invariant **structural** rather than optimistic.
|
|
428
|
-
|
|
429
|
-
### 9.2 `REGISTRY_SHARDS`
|
|
430
|
-
|
|
431
|
-
The default fleet size is **32**, defined as
|
|
432
|
-
`DEFAULT_REGISTRY_SHARDS` in
|
|
433
|
-
`packages/cf-adapter/src/sharding.ts:42`. This is the value used by
|
|
434
|
-
the production `CfRuntime` (`cf-runtime.ts:91`).
|
|
435
|
-
|
|
436
|
-
> **Planned knob:** `sharding.ts` documents a future `REGISTRY_SHARDS`
|
|
437
|
-
> environment variable (see the doc comment at line 39). That override
|
|
438
|
-
> path is **not yet wired** through `Env` / `ConnectionDO` — the shard
|
|
439
|
-
> count is currently a code-level default. Once TICKET-047 (config
|
|
440
|
-
> schema) ships, this will become a true env var. Until then, changing
|
|
441
|
-
> the shard count requires a code edit in `cf-runtime.ts`.
|
|
442
|
-
|
|
443
|
-
### 9.3 Re-sharding caveat
|
|
444
|
-
|
|
445
|
-
**Changing `REGISTRY_SHARDS` after the DOs hold data is a migration.**
|
|
446
|
-
Existing nick→connId mappings live in the *old* shard layout; the new
|
|
447
|
-
layout will not find them. Plan a migration window:
|
|
448
|
-
|
|
449
|
-
1. Drain live connections (announce + reconnect window), or accept that
|
|
450
|
-
in-flight nick reservations during the cutover can briefly succeed
|
|
451
|
-
against both layouts.
|
|
452
|
-
2. Iterate the old shard range, read each `nick→connId` entry, and write
|
|
453
|
-
it to the shard computed under the new `N`.
|
|
454
|
-
3. Verify with a sample of known nicks before re-enrolling write traffic.
|
|
455
|
-
|
|
456
|
-
There is **no in-repo re-sharding tool** today (post-v1 work). For v1
|
|
457
|
-
deployments the recommendation is: pick `REGISTRY_SHARDS` once, and
|
|
458
|
-
prefer over-provisioning (64 or 128) if you anticipate >10k concurrent
|
|
459
|
-
users — the per-shard cost is negligible because hibernated DOs are
|
|
460
|
-
free to hold.
|
|
461
|
-
|
|
462
|
-
---
|
|
463
|
-
|
|
464
|
-
## 10. Cost notes
|
|
465
|
-
|
|
466
|
-
Cloudflare bills Durable Objects on three dimensions (figures below are
|
|
467
|
-
the public list price as of 2024-11; verify current pricing at
|
|
468
|
-
<https://developers.cloudflare.com/durable-objects/platform/pricing/>):
|
|
469
|
-
|
|
470
|
-
| Dimension | Notes for ServerlessIRCd |
|
|
471
|
-
|----------------------------|-------------------------------------------------------|
|
|
472
|
-
| **Duration** (GB-second) | Hibernation (`HibernatingWebSocketHandler`) drops idle connections to ~zero memory while asleep. A 10k-user deployment with most connections idle is the entire reason this adapter exists. |
|
|
473
|
-
| **Requests** | Each WebSocket frame in/out is a request. PRIVMSG to a 1k-member channel fans out via the ChannelDO; each member's `ConnectionDO.deliver()` is one request. |
|
|
474
|
-
| **DO storage** (MB-month) | ConnectionState is small (a few KB). Channel roster / modes are small per channel. The Nicks registry is the only fleet that grows linearly with MAU. |
|
|
475
|
-
|
|
476
|
-
Practical numbers:
|
|
477
|
-
|
|
478
|
-
- **Workers Free plan**: sufficient to bring up staging, exercise the
|
|
479
|
-
smoke e2e, and validate a handful of concurrent connections. Not
|
|
480
|
-
suitable for production traffic (request caps, no reserved DO
|
|
481
|
-
compute).
|
|
482
|
-
- **Workers Paid plan** (USD $5/mo base + usage): enough headroom for a
|
|
483
|
-
small production network. The dominant cost driver at scale is
|
|
484
|
-
**fanout requests on hot channels**, not connection count — thanks to
|
|
485
|
-
hibernation. Plan accordingly for channels with >1k members.
|
|
486
|
-
|
|
487
|
-
Other billable surfaces (all optional for v1):
|
|
488
|
-
|
|
489
|
-
- **Workers KV** — not used today; planned for MOTD / config offload.
|
|
490
|
-
- **D1** — not used today; planned for account/SASL persistence.
|
|
491
|
-
- **Workers Analytics** — free tier covers basic dashboards.
|
|
492
|
-
|
|
493
|
-
See PLAN §10 (Risk / Cost) for the scaling ceilings and post-v1
|
|
494
|
-
mitigations (batched fanout, per-channel send-list cache).
|
|
495
|
-
|
|
496
|
-
---
|
|
497
|
-
|
|
498
|
-
## 11. CI/CD
|
|
499
|
-
|
|
500
|
-
The GitHub Actions workflow at `.github/workflows/deploy-cf.yml`
|
|
501
|
-
deploys staging on every push to `main` and replays the smoke e2e. It
|
|
502
|
-
is the canonical deploy path — manual `pnpm deploy:cf:staging` is for
|
|
503
|
-
iteration only.
|
|
504
|
-
|
|
505
|
-
Steps performed by the workflow (in order):
|
|
506
|
-
|
|
507
|
-
1. Checkout (frozen lockfile).
|
|
508
|
-
2. Install pnpm 9 + Node 20.
|
|
509
|
-
3. `pnpm install --frozen-lockfile`.
|
|
510
|
-
4. `pnpm build` — builds all workspace packages.
|
|
511
|
-
5. `pnpm typecheck` and `pnpm test` — gate the deploy.
|
|
512
|
-
6. `pnpm deploy:cf:staging` — `wrangler deploy --env staging`.
|
|
513
|
-
7. Resolve the smoke URL from the `CF_SMOKE_URL` repo variable. If
|
|
514
|
-
unset, the smoke step is skipped with a warning.
|
|
515
|
-
8. Run `node scripts/smoke.mjs --url "$SMOKE_URL"`. Failure fails the
|
|
516
|
-
build.
|
|
517
|
-
|
|
518
|
-
Concurrency is serialized via `concurrency.group: cf-staging` so two
|
|
519
|
-
deploys cannot race the same DO namespace.
|
|
520
|
-
|
|
521
|
-
Required repo configuration (under Settings → Secrets and variables →
|
|
522
|
-
Actions):
|
|
523
|
-
|
|
524
|
-
- **Secret `CLOUDFLARE_API_TOKEN`** — required.
|
|
525
|
-
- **Secret `CLOUDFLARE_ACCOUNT_ID`** — required if the token's account
|
|
526
|
-
context is ambiguous.
|
|
527
|
-
- **Variable `CF_SMOKE_URL`** — set to the staging Worker's `wss://`
|
|
528
|
-
URL. Without it, the smoke step silently no-ops.
|
|
529
|
-
|
|
530
|
-
There is **no auto-deploy to production**. Production deploys are
|
|
531
|
-
intentionally manual (`pnpm deploy:cf:prod` from a clean checkout on
|
|
532
|
-
`main`).
|
|
533
|
-
|
|
534
|
-
---
|
|
535
|
-
|
|
536
|
-
## 12. Troubleshooting
|
|
537
|
-
|
|
538
|
-
### 12.1 `wrangler deploy` fails with `Migration tag has already been applied`
|
|
539
|
-
|
|
540
|
-
The on-disk migration list in `wrangler.toml` doesn't match the live
|
|
541
|
-
Worker state. If you previously deployed `tag = "v1"` and then edited
|
|
542
|
-
the `[[migrations]]` block, wrangler refuses to proceed.
|
|
543
|
-
|
|
544
|
-
- If you intentionally changed the DO schema, append a new
|
|
545
|
-
`[[migrations]]` block with `tag = "v2"` (and `renamed_classes` /
|
|
546
|
-
`deleted_classes` as needed). Never edit an already-applied `tag`.
|
|
547
|
-
- If the staging namespace has stale state from an aborted experiment,
|
|
548
|
-
you can destroy and recreate it from the dashboard (Workers & Pages →
|
|
549
|
-
Durable Objects → namespaces). **Production namespaces must never be
|
|
550
|
-
deleted** — that data is gone permanently.
|
|
551
|
-
|
|
552
|
-
### 12.2 `Cannot find module '@serverless-ircd/cf-adapter'`
|
|
553
|
-
|
|
554
|
-
The workspace packages weren't built. Run `pnpm build` from the repo
|
|
555
|
-
root before `wrangler deploy`. The Worker entry imports compiled
|
|
556
|
-
`dist/` from `irc-core`, `irc-server`, and `cf-adapter`.
|
|
557
|
-
|
|
558
|
-
### 12.3 Smoke e2e times out waiting for `001`
|
|
559
|
-
|
|
560
|
-
The connection upgrade succeeded but registration didn't complete.
|
|
561
|
-
Common causes:
|
|
562
|
-
|
|
563
|
-
- The deployed Worker is reachable but the DO threw on the first frame.
|
|
564
|
-
Tail the logs: `wrangler tail --env staging` and reproduce.
|
|
565
|
-
- The `MOTD_LINES` or `SERVER_NAME` var was deleted — `ConnectionDO`'s
|
|
566
|
-
`serverConfig()` falls back to defaults, but a malformed value can
|
|
567
|
-
break parsing. Check the `[env.staging.vars]` block.
|
|
568
|
-
- Client connected over `ws://` to a Worker that requires `wss://`.
|
|
569
|
-
Use the `wss://` URL the deploy step printed.
|
|
570
|
-
|
|
571
|
-
### 12.4 `wrangler tail` shows `alarm() threw`
|
|
572
|
-
|
|
573
|
-
The DO alarm fired but the handler threw. The most likely cause is a
|
|
574
|
-
stale persisted-state version after a code change; the serializer in
|
|
575
|
-
`packages/cf-adapter/src/serialize.ts` carries `PERSISTED_STATE_VERSION`
|
|
576
|
-
and will reject incompatible blobs. If this happens after an upgrade,
|
|
577
|
-
ship a `deserialize` migration that upgrades the old version (or, on
|
|
578
|
-
staging, clear the DO storage from the dashboard).
|
|
579
|
-
|
|
580
|
-
### 12.5 Nick reservation always fails
|
|
581
|
-
|
|
582
|
-
A client's `NICK` command always returns `433 ERR_NICKNAMEINUSE`, even
|
|
583
|
-
for nicknames that should be free. This happens when two deployments
|
|
584
|
-
share a `RegistryDO` namespace but were supposed to be separate —
|
|
585
|
-
e.g., staging and production point at the same DO class name. Verify
|
|
586
|
-
that each environment has its own DO namespace (the Worker name
|
|
587
|
-
differs: `serverless-ircd` vs `serverless-ircd-staging`, and wrangler
|
|
588
|
-
allocates a distinct namespace per Worker).
|
|
589
|
-
|
|
590
|
-
### 12.6 High request cost / DO request spike
|
|
591
|
-
|
|
592
|
-
Hot-channel fanout is the dominant cost driver. Each PRIVMSG to a
|
|
593
|
-
channel of N members produces ~N `ConnectionDO.deliver()` RPC requests
|
|
594
|
-
(one per member). Mitigations:
|
|
595
|
-
|
|
596
|
-
- Cap channel size in application policy (no built-in cap today beyond
|
|
597
|
-
`+l` mode).
|
|
598
|
-
- For very hot announcement channels, consider a future batched-fanout
|
|
599
|
-
path (post-v1 — PLAN §10).
|
|
600
|
-
|
|
601
|
-
Reach for the Workers Analytics dashboard to identify the channel
|
|
602
|
-
driving the spike before optimizing.
|
|
603
|
-
|
|
604
|
-
### 12.7 Lost connection state after a deploy
|
|
605
|
-
|
|
606
|
-
DO storage persists across Worker code deploys by design. If state
|
|
607
|
-
appears lost, either:
|
|
608
|
-
|
|
609
|
-
- The DO namespace was deleted (irreversible — see 12.1).
|
|
610
|
-
- A `[[migrations]]` rename or split moved the data to a different
|
|
611
|
-
class id without a migration entry mapping the old class to the new.
|
|
612
|
-
- The persisted-state version changed without a deserialize migration
|
|
613
|
-
(see 12.4).
|
|
614
|
-
|
|
615
|
-
For staging, the fastest recovery is usually to clear DO storage and
|
|
616
|
-
re-test. For production, treat any migration tag change as a release
|
|
617
|
-
blocker requiring a runbook entry.
|
|
618
|
-
|
|
619
|
-
---
|
|
620
|
-
|
|
621
|
-
## 13. Quick reference
|
|
622
|
-
|
|
623
|
-
```bash
|
|
624
|
-
# One-time account setup
|
|
625
|
-
npx wrangler login # or set CLOUDFLARE_API_TOKEN
|
|
626
|
-
|
|
627
|
-
# Local dev
|
|
628
|
-
pnpm install
|
|
629
|
-
pnpm build
|
|
630
|
-
pnpm --filter @serverless-ircd/cf-worker dev # http://localhost:8787
|
|
631
|
-
node apps/cf-worker/scripts/smoke.mjs # smoke against localhost
|
|
632
|
-
|
|
633
|
-
# Staging
|
|
634
|
-
pnpm deploy:cf:staging
|
|
635
|
-
node apps/cf-worker/scripts/smoke.mjs \
|
|
636
|
-
--url wss://serverless-ircd-staging.<subdomain>.workers.dev
|
|
637
|
-
npx wrangler tail --env staging # live logs
|
|
638
|
-
|
|
639
|
-
# Production (manual only)
|
|
640
|
-
pnpm deploy:cf:prod
|
|
641
|
-
npx wrangler tail # default env = production
|
|
642
|
-
|
|
643
|
-
# Tests / lint
|
|
644
|
-
pnpm test # full workspace
|
|
645
|
-
pnpm --filter @serverless-ircd/cf-adapter test
|
|
646
|
-
pnpm --filter @serverless-ircd/cf-worker test
|
|
647
|
-
pnpm lint
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
Key files:
|
|
651
|
-
|
|
652
|
-
| Path | What |
|
|
653
|
-
|-----------------------------------------|----------------------------------------------|
|
|
654
|
-
| `apps/cf-worker/wrangler.toml` | Deploy config, DO bindings, migrations. |
|
|
655
|
-
| `apps/cf-worker/src/worker.ts` | Edge fetch handler; re-exports DO classes. |
|
|
656
|
-
| `apps/cf-worker/scripts/smoke.mjs` | CI + local smoke e2e. |
|
|
657
|
-
| `packages/cf-adapter/src/` | `ConnectionDO`, `RegistryDO`, `ChannelDO`, `CfRuntime`, sharding. |
|
|
658
|
-
| `packages/cf-adapter/src/sharding.ts` | Shard function + `DEFAULT_REGISTRY_SHARDS`. |
|
|
659
|
-
| `packages/cf-adapter/src/env.ts` | `Env` interface (binding contract). |
|
|
660
|
-
| `.github/workflows/deploy-cf.yml` | Staging deploy + smoke e2e CI. |
|
package/docs/Home.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Welcome to the Wiki.
|
|
2
|
-
|
|
3
|
-
## Pages
|
|
4
|
-
|
|
5
|
-
- [AWS Adapter Architecture](AWS-Adapter-Architecture)
|
|
6
|
-
- [AWS Deployment Guide](AWS-Deployment)
|
|
7
|
-
- [Cloudflare Deployment Guide](Cloudflare-Deployment-Guide)
|
|
8
|
-
- [Observability](Observability)
|
|
9
|
-
- [IRCv3 WebSocket Extension Plan](PlanIRCv3Websocket)
|
|
10
|
-
- [Web Client Plan](PlanWebClient)
|
|
11
|
-
- [Release Process](Release-Process)
|