stitchkit 0.100.1 → 0.100.3
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/CHANGELOG.md +99 -0
- package/README.md +2 -1
- package/dist/application/process-lifecycle-transitions.d.ts +13 -2
- package/dist/application/process-lifecycle-transitions.d.ts.map +1 -1
- package/dist/application/process-lifecycle.d.ts +2 -1
- package/dist/application/process-lifecycle.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/browser.js +119 -119
- package/dist/entrypoints/agent-runtime/coding-tools.js +15 -20
- package/dist/entrypoints/agent-runtime/harness.js +55 -63
- package/dist/entrypoints/agent-runtime/openrouter.js +6 -6
- package/dist/entrypoints/agent-runtime/sandbox.js +20 -25
- package/dist/entrypoints/agent-runtime/sqlite/bun.js +11 -13
- package/dist/entrypoints/agent-runtime/sqlite/node.js +11 -13
- package/dist/entrypoints/agent-runtime/testing.js +32 -34
- package/dist/entrypoints/agent-runtime.js +395 -402
- package/dist/entrypoints/application/diagnostic-journal.js +26 -27
- package/dist/entrypoints/application/directory-inbox.js +16 -17
- package/dist/entrypoints/application/grammy.js +13 -13
- package/dist/entrypoints/application/opentelemetry.js +13 -13
- package/dist/entrypoints/application/schemas.js +24 -24
- package/dist/entrypoints/application.d.ts +1 -1
- package/dist/entrypoints/application.d.ts.map +1 -1
- package/dist/entrypoints/application.js +218 -214
- package/dist/entrypoints/bin/upgrade-cli.js +2 -2
- package/dist/entrypoints/cli.js +81 -84
- package/dist/entrypoints/contract.js +54 -57
- package/dist/entrypoints/declaration.js +22 -22
- package/dist/entrypoints/files.js +18 -21
- package/dist/entrypoints/geo.js +7 -8
- package/dist/entrypoints/google.js +2 -2
- package/dist/entrypoints/index.js +150 -154
- package/dist/entrypoints/live.js +45 -47
- package/dist/entrypoints/node.js +68 -74
- package/dist/entrypoints/oauth.js +6 -6
- package/dist/entrypoints/observability.d.ts +1 -0
- package/dist/entrypoints/observability.d.ts.map +1 -1
- package/dist/entrypoints/observability.js +115 -87
- package/dist/entrypoints/primitives.js +35 -35
- package/dist/entrypoints/react/keyboard.d.ts +4 -0
- package/dist/entrypoints/react/keyboard.d.ts.map +1 -0
- package/dist/entrypoints/react/keyboard.js +397 -0
- package/dist/entrypoints/react.js +10 -10
- package/dist/entrypoints/release.js +7 -7
- package/dist/entrypoints/remote.js +15 -17
- package/dist/entrypoints/server.js +198 -200
- package/dist/entrypoints/telegram/html.d.ts +5 -0
- package/dist/entrypoints/telegram/html.d.ts.map +1 -0
- package/dist/entrypoints/telegram/html.js +26 -0
- package/dist/entrypoints/telegram/screens.d.ts +14 -0
- package/dist/entrypoints/telegram/screens.d.ts.map +1 -0
- package/dist/entrypoints/telegram/screens.js +2028 -0
- package/dist/entrypoints/telegram.d.ts +5 -1
- package/dist/entrypoints/telegram.d.ts.map +1 -1
- package/dist/entrypoints/telegram.js +548 -156
- package/dist/entrypoints/testing.js +75 -79
- package/dist/entrypoints/tools/connections.js +30 -32
- package/dist/entrypoints/tools/contract.js +18 -20
- package/dist/entrypoints/tools/invoker.js +12 -17
- package/dist/entrypoints/tools.js +223 -229
- package/dist/entrypoints/tracking/server.js +6 -6
- package/dist/entrypoints/tracking.js +40 -42
- package/dist/entrypoints/voice.js +3 -3
- package/dist/{index-eaysmdtq.js → index-0ndk4555.js} +56 -56
- package/dist/{index-2bxbyab0.js → index-1bx1xv1k.js} +1 -1
- package/dist/{index-p5r7qpdd.js → index-1eeqpadm.js} +4 -4
- package/dist/{index-hadmp193.js → index-3ct7hhq6.js} +210 -210
- package/dist/{index-e01r054k.js → index-45tdvqa3.js} +26 -26
- package/dist/{index-dce5wxcq.js → index-4s0fep5q.js} +8 -8
- package/dist/index-50ejfz75.js +9 -0
- package/dist/{index-m9zn6cpq.js → index-5107q189.js} +12 -12
- package/dist/{index-sbdmyz75.js → index-5cc6r990.js} +3 -3
- package/dist/index-6k1svmjh.js +141 -0
- package/dist/{index-c6bxbsnc.js → index-7kxw1awn.js} +2 -2
- package/dist/{index-0r0fbk7z.js → index-7z9ym7t8.js} +28 -28
- package/dist/{index-p7hgdyhb.js → index-814xpr6d.js} +2 -2
- package/dist/{index-gtj3zc53.js → index-8kzct1d6.js} +99 -99
- package/dist/{index-1zbbzgfh.js → index-9pw0a51a.js} +4 -4
- package/dist/{index-79z7m7dt.js → index-a9pd417t.js} +35 -35
- package/dist/{index-ham5sz8m.js → index-aaj97r4y.js} +45 -45
- package/dist/{index-s812ycat.js → index-aan6hqb9.js} +3 -3
- package/dist/{index-10x2hbx0.js → index-adhgd4pe.js} +44 -44
- package/dist/{index-2gxzjvyr.js → index-afjvjyck.js} +23 -23
- package/dist/{index-qmy6zq75.js → index-ahvsksw5.js} +16 -16
- package/dist/{index-hr4tzbwq.js → index-ap3gqe56.js} +3 -3
- package/dist/{index-znfs20ss.js → index-b2bz0kdm.js} +16 -16
- package/dist/{index-r066jx76.js → index-c6aagrbd.js} +148 -120
- package/dist/{index-k30h66yd.js → index-ck71tbcf.js} +9 -9
- package/dist/{index-eqqvgdb3.js → index-ct75c3at.js} +2 -2
- package/dist/{index-gw8bmyaj.js → index-djjhhgjk.js} +41 -41
- package/dist/{index-8qt2m66q.js → index-dvwj1f43.js} +43 -43
- package/dist/{index-fhwqwxe0.js → index-ej331hah.js} +1 -1
- package/dist/{index-9t3dffv2.js → index-ewbaywk5.js} +5 -5
- package/dist/{index-7p1f0vp2.js → index-fyphpknh.js} +25 -25
- package/dist/{index-83bdg97s.js → index-g149e9pk.js} +1 -1
- package/dist/{index-ngfhvfpd.js → index-g6a3na27.js} +4 -4
- package/dist/{index-qwhynv6x.js → index-h124epcf.js} +20 -20
- package/dist/{index-h6eeys1v.js → index-h97tqqp1.js} +9 -9
- package/dist/{index-zcgf3gqf.js → index-hby4qhax.js} +10 -10
- package/dist/{index-5jrd0yng.js → index-j8aw2c0e.js} +4 -4
- package/dist/{index-d8m8zpd8.js → index-jzczzcsb.js} +14 -14
- package/dist/index-kqnd6a85.js +26 -0
- package/dist/{index-35mh5bhj.js → index-kw1ws0cs.js} +12 -12
- package/dist/{index-yw4fzmdz.js → index-kzz6rq0w.js} +28 -17
- package/dist/{index-4gcnakhx.js → index-m38ej7e5.js} +2 -2
- package/dist/{index-ndddxtyx.js → index-m79yr938.js} +19 -19
- package/dist/{index-5p2m7we1.js → index-m9fndta6.js} +11 -11
- package/dist/index-mnkk1ffz.js +150 -0
- package/dist/index-n15jny5b.js +4 -0
- package/dist/{index-2vtcmrj9.js → index-n53mswt3.js} +20 -20
- package/dist/{index-bt14acb5.js → index-n5yqxd3d.js} +21 -21
- package/dist/{index-bm5rx7n6.js → index-n9tyz8z3.js} +12 -12
- package/dist/index-nmaqxdx7.js +463 -0
- package/dist/{index-mqv3b5rh.js → index-nx6eazt0.js} +30 -30
- package/dist/{index-3z73fh2c.js → index-q0th8q0z.js} +9 -9
- package/dist/{index-v260df89.js → index-qjeggp8w.js} +20 -20
- package/dist/{index-zfrhfn82.js → index-r1z0rd9c.js} +20 -20
- package/dist/{index-wqgjfstn.js → index-r5c4fedv.js} +3 -3
- package/dist/{index-cyktc4bp.js → index-r5hsgkz5.js} +118 -118
- package/dist/{index-0b1ess5e.js → index-r7a7r7ha.js} +1 -1
- package/dist/{index-1j8pm5t0.js → index-rfkh44ss.js} +15 -15
- package/dist/index-rz3z13e9.js +47 -0
- package/dist/{index-k6gpggb9.js → index-s80awwsw.js} +35 -35
- package/dist/{index-vqr7f7v8.js → index-ssmd41kh.js} +124 -124
- package/dist/{index-ensd0r74.js → index-v14qqmys.js} +41 -41
- package/dist/{index-paz6sgdp.js → index-v4a2fjtk.js} +36 -36
- package/dist/{index-d9pk3td4.js → index-w0eqdhyd.js} +14 -14
- package/dist/{index-5qn1kx34.js → index-w575evhq.js} +29 -29
- package/dist/{index-3gye9wzb.js → index-w5s3xftz.js} +26 -26
- package/dist/{index-tm88avnj.js → index-wykebpn9.js} +3 -3
- package/dist/{index-sh3s86na.js → index-xkhk5d6g.js} +17 -17
- package/dist/{index-6k1937bx.js → index-xqhede6x.js} +4 -4
- package/dist/{index-f4fx2tza.js → index-zs4ms3th.js} +181 -181
- package/dist/{index-k5hsfc3j.js → index-zsvzhjtk.js} +1 -1
- package/dist/observability/bounded-logger.d.ts +2 -0
- package/dist/observability/bounded-logger.d.ts.map +1 -1
- package/dist/observability/sanitize.d.ts +6 -0
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/observability/secret-values.d.ts +25 -0
- package/dist/observability/secret-values.d.ts.map +1 -0
- package/dist/react/keyboard/hooks.d.ts +71 -0
- package/dist/react/keyboard/hooks.d.ts.map +1 -0
- package/dist/react/keyboard/layers.d.ts +98 -0
- package/dist/react/keyboard/layers.d.ts.map +1 -0
- package/dist/react/keyboard/zone.d.ts +139 -0
- package/dist/react/keyboard/zone.d.ts.map +1 -0
- package/dist/telegram/crypto.d.ts +16 -0
- package/dist/telegram/crypto.d.ts.map +1 -0
- package/dist/telegram/html/check.d.ts +26 -0
- package/dist/telegram/html/check.d.ts.map +1 -0
- package/dist/telegram/html/nodes.d.ts +70 -0
- package/dist/telegram/html/nodes.d.ts.map +1 -0
- package/dist/telegram/html/parse.d.ts +35 -0
- package/dist/telegram/html/parse.d.ts.map +1 -0
- package/dist/telegram/html/render.d.ts +39 -0
- package/dist/telegram/html/render.d.ts.map +1 -0
- package/dist/telegram/init-data.d.ts.map +1 -1
- package/dist/telegram/operator-channel.d.ts +36 -3
- package/dist/telegram/operator-channel.d.ts.map +1 -1
- package/dist/telegram/screens/callback-codec.d.ts +34 -0
- package/dist/telegram/screens/callback-codec.d.ts.map +1 -0
- package/dist/telegram/screens/dispatch.d.ts +22 -0
- package/dist/telegram/screens/dispatch.d.ts.map +1 -0
- package/dist/telegram/screens/display.d.ts +70 -0
- package/dist/telegram/screens/display.d.ts.map +1 -0
- package/dist/telegram/screens/execute.d.ts +57 -0
- package/dist/telegram/screens/execute.d.ts.map +1 -0
- package/dist/telegram/screens/html.d.ts +36 -0
- package/dist/telegram/screens/html.d.ts.map +1 -0
- package/dist/telegram/screens/outcome.d.ts +74 -0
- package/dist/telegram/screens/outcome.d.ts.map +1 -0
- package/dist/telegram/screens/path.d.ts +29 -0
- package/dist/telegram/screens/path.d.ts.map +1 -0
- package/dist/telegram/screens/reconcile.d.ts +67 -0
- package/dist/telegram/screens/reconcile.d.ts.map +1 -0
- package/dist/telegram/screens/registry.d.ts +23 -0
- package/dist/telegram/screens/registry.d.ts.map +1 -0
- package/dist/telegram/screens/render.d.ts +70 -0
- package/dist/telegram/screens/render.d.ts.map +1 -0
- package/dist/telegram/screens/runtime.d.ts +133 -0
- package/dist/telegram/screens/runtime.d.ts.map +1 -0
- package/dist/telegram/screens/screen-types.d.ts +130 -0
- package/dist/telegram/screens/screen-types.d.ts.map +1 -0
- package/dist/telegram/screens/screen.d.ts +138 -0
- package/dist/telegram/screens/screen.d.ts.map +1 -0
- package/dist/telegram/screens/state.d.ts +115 -0
- package/dist/telegram/screens/state.d.ts.map +1 -0
- package/dist/telegram/screens/telegram-screens.d.ts +18 -0
- package/dist/telegram/screens/telegram-screens.d.ts.map +1 -0
- package/dist/telegram/screens/test-chat-telegram.d.ts +47 -0
- package/dist/telegram/screens/test-chat-telegram.d.ts.map +1 -0
- package/dist/telegram/screens/test-chat.d.ts +66 -0
- package/dist/telegram/screens/test-chat.d.ts.map +1 -0
- package/dist/telegram/screens/view.d.ts +89 -0
- package/dist/telegram/screens/view.d.ts.map +1 -0
- package/dist/telegram/send-failure.d.ts +19 -0
- package/dist/telegram/send-failure.d.ts.map +1 -1
- package/dist/telegram/update-intake.d.ts +78 -0
- package/dist/telegram/update-intake.d.ts.map +1 -0
- package/dist/telegram/update-store-sqlite.d.ts +26 -0
- package/dist/telegram/update-store-sqlite.d.ts.map +1 -0
- package/dist/telegram/update-store.d.ts +67 -0
- package/dist/telegram/update-store.d.ts.map +1 -0
- package/dist/telegram/webhook.d.ts +105 -0
- package/dist/telegram/webhook.d.ts.map +1 -0
- package/dist/tools/cli/args-fields.d.ts +8 -0
- package/dist/tools/cli/args-fields.d.ts.map +1 -1
- package/dist/tools/cli/args-route.d.ts.map +1 -1
- package/dist/tools/cli/args.d.ts.map +1 -1
- package/dist/tools/cli/help.d.ts.map +1 -1
- package/llms/application.2.txt +26 -1
- package/llms/application.txt +18 -27
- package/llms/cli.txt +8 -2
- package/llms/observability.txt +2 -1
- package/llms/react-keyboard.txt +193 -0
- package/llms/stitchkit.txt +7 -1
- package/llms/telegram-html.txt +35 -0
- package/llms/telegram-screens.txt +365 -0
- package/llms/telegram.txt +160 -4
- package/llms-full.txt +755 -11
- package/llms.txt +11 -6
- package/package.json +17 -2
- package/dist/index-2k4yrqkc.js +0 -9
- package/dist/index-crykmqkr.js +0 -26
- package/dist/index-y64k3s0h.js +0 -150
- package/dist/index-y91ry9h2.js +0 -4
- /package/dist/{index-hffjpmq9.js → index-9jfdm5tg.js} +0 -0
- /package/dist/{index-zjjyynm3.js → index-d4pa2bgs.js} +0 -0
- /package/dist/{index-rxfy4cq7.js → index-dwfv9a85.js} +0 -0
- /package/dist/{index-5jm36zv1.js → index-gfk7nrht.js} +0 -0
- /package/dist/{index-b9aefrqd.js → index-n1dqr7gf.js} +0 -0
- /package/dist/{index-q3pyb9n0.js → index-sykb5ag7.js} +0 -0
- /package/dist/{index-48ffdxgk.js → index-xhzq2qvj.js} +0 -0
- /package/dist/{index-kzfs85xp.js → index-zsarb5xp.js} +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A chat with the application's own bot, and no Telegram.
|
|
3
|
+
*
|
|
4
|
+
* `createScreenTestChat(bot)` takes the `Bot` the application composes — its
|
|
5
|
+
* middleware, commands and error boundary, in their real order — and answers
|
|
6
|
+
* its Bot API calls from memory through `bot.api.config.use`. Updates enter
|
|
7
|
+
* through `bot.handleUpdate`, so what a test proves is what the bot does:
|
|
8
|
+
* that `/support` is not swallowed by a screen waiting for text, that a press
|
|
9
|
+
* edits the message it came from.
|
|
10
|
+
*
|
|
11
|
+
* The Telegram it talks to is `test-chat-telegram.ts`, which keeps the rules
|
|
12
|
+
* screens depend on. Nothing here imports grammY at run time; the bot brings it.
|
|
13
|
+
*/
|
|
14
|
+
import type { Bot, Context } from 'grammy';
|
|
15
|
+
import type { InlineKeyboardMarkup } from 'grammy/types';
|
|
16
|
+
import { type TestMessageKind } from './test-chat-telegram.js';
|
|
17
|
+
/** A message as the user sees it. */
|
|
18
|
+
export interface TestChatMessage {
|
|
19
|
+
readonly id: number;
|
|
20
|
+
readonly from: 'bot' | 'user';
|
|
21
|
+
readonly kind: TestMessageKind;
|
|
22
|
+
/** The text, or the caption, as sent — Telegram HTML for the bot's messages. */
|
|
23
|
+
readonly text: string;
|
|
24
|
+
readonly media: string | undefined;
|
|
25
|
+
readonly rich: unknown;
|
|
26
|
+
/** Button labels, row by row. */
|
|
27
|
+
readonly buttons: readonly (readonly string[])[];
|
|
28
|
+
readonly markup: InlineKeyboardMarkup | undefined;
|
|
29
|
+
}
|
|
30
|
+
export interface TestChatCall {
|
|
31
|
+
readonly method: string;
|
|
32
|
+
readonly payload: Readonly<Record<string, unknown>>;
|
|
33
|
+
}
|
|
34
|
+
export interface TestChatOptions {
|
|
35
|
+
readonly chatId?: number;
|
|
36
|
+
readonly chatType?: 'private' | 'group' | 'supergroup';
|
|
37
|
+
readonly userId?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface ScreenTestChat<C extends Context = Context> {
|
|
40
|
+
/** What the chat shows, top to bottom. */
|
|
41
|
+
readonly messages: readonly TestChatMessage[];
|
|
42
|
+
/** Every Bot API call the bot made, in order. */
|
|
43
|
+
readonly calls: readonly TestChatCall[];
|
|
44
|
+
/** Press answers — the toasts — in order; `''` for a silent answer. */
|
|
45
|
+
readonly answers: readonly string[];
|
|
46
|
+
/** The user sends text; a leading `/word` is a command. */
|
|
47
|
+
send(text: string): Promise<void>;
|
|
48
|
+
/** The user sends a photo, with an optional caption. */
|
|
49
|
+
sendPhoto(fileId: string, caption?: string): Promise<void>;
|
|
50
|
+
/** The user presses the lowest button with this label. */
|
|
51
|
+
press(label: string): Promise<void>;
|
|
52
|
+
/** A press carrying arbitrary `callback_data` on a message — what a forged press looks like. */
|
|
53
|
+
pressData(messageId: number, data: string): Promise<void>;
|
|
54
|
+
/** Refuse the next call of `method` the way Telegram would. */
|
|
55
|
+
failNext(method: string, description: string, errorCode?: number): void;
|
|
56
|
+
/** The user deletes a message. */
|
|
57
|
+
deleteByUser(messageId: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* The process restarted: the same chat, as Telegram keeps it, now answered by
|
|
60
|
+
* a new bot — built over the same storage, the way the application builds it.
|
|
61
|
+
*/
|
|
62
|
+
restart(bot: Bot<C>): void;
|
|
63
|
+
clearCalls(): void;
|
|
64
|
+
}
|
|
65
|
+
export declare function createScreenTestChat<C extends Context>(first: Bot<C>, options?: TestChatOptions): ScreenTestChat<C>;
|
|
66
|
+
//# sourceMappingURL=test-chat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-chat.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/test-chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,GAAG,EAAY,OAAO,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAkC,MAAM,cAAc,CAAC;AAEzF,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAE9B,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC;CACnD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO;IACzD,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,2DAA2D;IAC3D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,wDAAwD;IACxD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,0DAA0D;IAC1D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,gGAAgG;IAChG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxE,kCAAkC;IAClC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3B,UAAU,IAAI,IAAI,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EACpD,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EACb,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,CAAC,CAAC,CAgLnB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a screen shows: messages as plain objects.
|
|
3
|
+
*
|
|
4
|
+
* A view is data, so it can be compared. `{ text }` is a text message,
|
|
5
|
+
* `{ rich }` a Bot API rich message (Markdown, HTML or blocks, without file
|
|
6
|
+
* uploads) and `{ photo }` (or `video`, `animation`, `document`, `audio`) a
|
|
7
|
+
* media message with an optional caption; exactly one of those keys is
|
|
8
|
+
* present, and the type says so. A keyboard is rows of buttons where a row or a button may be `false`,
|
|
9
|
+
* `null` or `undefined` — a conditional row is written in the literal, not
|
|
10
|
+
* around it. Buttons are either screen buttons (`link`, `back`, an action) or
|
|
11
|
+
* any Telegram inline button that carries no `callback_data`, as Telegram
|
|
12
|
+
* spells it.
|
|
13
|
+
*/
|
|
14
|
+
import type { InlineKeyboardButton, InputRichMessageWithoutUpload } from 'grammy/types';
|
|
15
|
+
import type { ActionValue } from './callback-codec.js';
|
|
16
|
+
import type { TelegramText } from './html.js';
|
|
17
|
+
import type { AnyTelegramScreen, ScreenLinkArgs } from './screen-types.js';
|
|
18
|
+
export type ScreenMediaKind = 'photo' | 'video' | 'animation' | 'document' | 'audio';
|
|
19
|
+
export declare const SCREEN_MEDIA_KINDS: readonly ScreenMediaKind[];
|
|
20
|
+
/** A button label: its text, or its text with Telegram's style and custom-emoji icon. */
|
|
21
|
+
export type ButtonLabel = string | Omit<InlineKeyboardButton.CallbackButton, 'callback_data'>;
|
|
22
|
+
type ButtonTarget = {
|
|
23
|
+
readonly kind: 'link';
|
|
24
|
+
readonly screen: AnyTelegramScreen;
|
|
25
|
+
readonly params: Readonly<Record<string, ActionValue>>;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'back';
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: 'action';
|
|
30
|
+
readonly screen: AnyTelegramScreen;
|
|
31
|
+
readonly params: Readonly<Record<string, ActionValue>>;
|
|
32
|
+
readonly action: string;
|
|
33
|
+
readonly input: Readonly<Record<string, ActionValue | undefined>> | undefined;
|
|
34
|
+
};
|
|
35
|
+
/** A button the screens runtime answers: it becomes `callback_data` when rendered. */
|
|
36
|
+
export declare class ScreenButton {
|
|
37
|
+
readonly label: ButtonLabel;
|
|
38
|
+
readonly target: ButtonTarget;
|
|
39
|
+
constructor(label: ButtonLabel, target: ButtonTarget);
|
|
40
|
+
}
|
|
41
|
+
/** Any inline button Telegram answers itself — a URL, a Mini App, copy text, … */
|
|
42
|
+
export type PlainKeyboardButton = Exclude<InlineKeyboardButton, InlineKeyboardButton.CallbackButton>;
|
|
43
|
+
export type KeyboardButton = ScreenButton | PlainKeyboardButton;
|
|
44
|
+
type Absent = false | null | undefined;
|
|
45
|
+
export type KeyboardRow = readonly (KeyboardButton | Absent)[];
|
|
46
|
+
export type Keyboard = readonly (KeyboardRow | Absent)[];
|
|
47
|
+
interface ViewMessageCommon {
|
|
48
|
+
/**
|
|
49
|
+
* The message's identity across renders: two renders put the same key in the
|
|
50
|
+
* same Telegram message when they can. The default is `'main'` for the last
|
|
51
|
+
* message and `'s0'`, `'s1'`, … for those above it, so the message that
|
|
52
|
+
* carries a screen's buttons is the one the next screen edits.
|
|
53
|
+
*/
|
|
54
|
+
readonly key?: string;
|
|
55
|
+
readonly keyboard?: Keyboard;
|
|
56
|
+
}
|
|
57
|
+
type ContentKey = 'text' | 'rich' | ScreenMediaKind;
|
|
58
|
+
type Without<TKeys extends string> = {
|
|
59
|
+
readonly [K in TKeys]?: never;
|
|
60
|
+
};
|
|
61
|
+
export interface TextViewMessage extends ViewMessageCommon, Without<Exclude<ContentKey, 'text'> | 'caption'> {
|
|
62
|
+
readonly text: TelegramText;
|
|
63
|
+
/** `false` hides the preview of the first link. Default: Telegram's. */
|
|
64
|
+
readonly linkPreview?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface RichViewMessage extends ViewMessageCommon, Without<Exclude<ContentKey, 'rich'> | 'caption' | 'linkPreview'> {
|
|
67
|
+
/** A rich message as the Bot API takes it; files by `file_id` or URL only. */
|
|
68
|
+
readonly rich: InputRichMessageWithoutUpload;
|
|
69
|
+
}
|
|
70
|
+
type MediaViewMessageOf<TKind extends ScreenMediaKind> = ViewMessageCommon & Without<Exclude<ContentKey, TKind> | 'linkPreview'> & {
|
|
71
|
+
/** A Telegram `file_id` or an HTTP URL Telegram can fetch. */
|
|
72
|
+
readonly [K in TKind]: string;
|
|
73
|
+
} & {
|
|
74
|
+
readonly caption?: TelegramText;
|
|
75
|
+
};
|
|
76
|
+
export type PhotoViewMessage = MediaViewMessageOf<'photo'>;
|
|
77
|
+
export type VideoViewMessage = MediaViewMessageOf<'video'>;
|
|
78
|
+
export type AnimationViewMessage = MediaViewMessageOf<'animation'>;
|
|
79
|
+
export type DocumentViewMessage = MediaViewMessageOf<'document'>;
|
|
80
|
+
export type AudioViewMessage = MediaViewMessageOf<'audio'>;
|
|
81
|
+
export type ViewMessage = TextViewMessage | RichViewMessage | PhotoViewMessage | VideoViewMessage | AnimationViewMessage | DocumentViewMessage | AudioViewMessage;
|
|
82
|
+
/** What `view` returns: one message, or several shown top to bottom. */
|
|
83
|
+
export type ScreenViewResult = ViewMessage | readonly ViewMessage[];
|
|
84
|
+
/** A link to another screen; its params are required exactly when its path has any. */
|
|
85
|
+
export declare function link<TScreen extends AnyTelegramScreen>(label: ButtonLabel, screen: TScreen, ...params: ScreenLinkArgs<TScreen>): ScreenButton;
|
|
86
|
+
/** A link to the parent screen — the nearest declared screen above this path. */
|
|
87
|
+
export declare function back(label: ButtonLabel): ScreenButton;
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/view.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,4 +70,23 @@ export interface TelegramSendFailure {
|
|
|
70
70
|
* which asserts nothing about the recipient and permits no retry.
|
|
71
71
|
*/
|
|
72
72
|
export declare function classifyTelegramSendFailure(error: unknown): TelegramSendFailure;
|
|
73
|
+
/**
|
|
74
|
+
* What a refused edit, deletion or press answer means for the chat — the
|
|
75
|
+
* questions a screen asks after the message exists, which a send never does.
|
|
76
|
+
*
|
|
77
|
+
* - `not-modified`: the edit asked for what is already there. Success.
|
|
78
|
+
* - `message-gone`: the message is not there — the user deleted it, or the id
|
|
79
|
+
* is not a message at all. A deletion of it has nothing left to do.
|
|
80
|
+
* - `message-locked`: the message is there and cannot be changed that way — too
|
|
81
|
+
* old to delete, not the bot's to edit, no text or caption to edit. An edit
|
|
82
|
+
* has to send it anew; a deletion leaves it in the chat.
|
|
83
|
+
* - `query-expired`: the press waited too long to be answered; nothing to do.
|
|
84
|
+
* - `other`: everything else, including a malformed payload — the caller's to
|
|
85
|
+
* raise.
|
|
86
|
+
*
|
|
87
|
+
* Internal to the screens: it reads Telegram's prose the same way
|
|
88
|
+
* {@link classifyTelegramSendFailure} does and is not a public vocabulary.
|
|
89
|
+
*/
|
|
90
|
+
export type TelegramEditRefusal = 'not-modified' | 'message-gone' | 'message-locked' | 'query-expired' | 'other';
|
|
91
|
+
export declare function classifyTelegramEditRefusal(error: unknown): TelegramEditRefusal;
|
|
73
92
|
//# sourceMappingURL=send-failure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-failure.d.ts","sourceRoot":"","sources":["../../src/telegram/send-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,yBAAyB,CAAC;IAClC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,YAAY,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;CAC5D;AAuED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA0D/E"}
|
|
1
|
+
{"version":3,"file":"send-failure.d.ts","sourceRoot":"","sources":["../../src/telegram/send-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,yBAAyB,CAAC;IAClC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,YAAY,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;CAC5D;AAuED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA0D/E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,mBAAmB,GAC3B,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,OAAO,CAAC;AAeZ,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAM/E"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook updates received durably: recorded before Telegram is answered,
|
|
3
|
+
* handled after, and never lost to a restart or a slow handler.
|
|
4
|
+
*
|
|
5
|
+
* Answering Telegram only after an update is handled breaks twice. A long
|
|
6
|
+
* handler — a file of gigabytes arriving from a local Bot API server — holds
|
|
7
|
+
* the connection past Telegram's patience, it gives up and sends the update
|
|
8
|
+
* again while the first attempt still runs; and a process that dies after
|
|
9
|
+
* handling but before answering loses nothing Telegram knows about, while one
|
|
10
|
+
* that dies before handling loses the update for good once it has answered.
|
|
11
|
+
* So the body is written first and Telegram answered at once; handling runs
|
|
12
|
+
* here, outside the request.
|
|
13
|
+
*
|
|
14
|
+
* Updates of one chat run one after another, in `update_id` order; different
|
|
15
|
+
* chats run side by side up to `maxConcurrent`. An attempt holds a lease that
|
|
16
|
+
* is renewed while its handler lives; a sweep takes over what was left —
|
|
17
|
+
* `pending` whose process never got to it, `failed` whose retry is due,
|
|
18
|
+
* `processing` whose lease nobody renewed. Delivery is at least once: a
|
|
19
|
+
* handler that finished but could not be recorded as finished runs again.
|
|
20
|
+
*/
|
|
21
|
+
import type { TelegramUpdateStore } from './update-store.js';
|
|
22
|
+
import type { TelegramUpdateAcceptance } from './webhook.js';
|
|
23
|
+
/** An update as Telegram sends it; name grammY's `Update` to get its full type. */
|
|
24
|
+
export interface TelegramUpdateEnvelope {
|
|
25
|
+
readonly update_id: number;
|
|
26
|
+
}
|
|
27
|
+
export interface TelegramUpdateFailure {
|
|
28
|
+
readonly updateId: number;
|
|
29
|
+
readonly attempt: number;
|
|
30
|
+
readonly error: unknown;
|
|
31
|
+
/** `false` when the update was abandoned — no attempt follows. */
|
|
32
|
+
readonly retrying: boolean;
|
|
33
|
+
}
|
|
34
|
+
export type TelegramUpdateStoreStep = 'claim' | 'renew' | 'settle' | 'sweep';
|
|
35
|
+
export interface TelegramUpdateIntakeConfig<TUpdate extends TelegramUpdateEnvelope> {
|
|
36
|
+
readonly store: TelegramUpdateStore;
|
|
37
|
+
/** Handle one update — with grammY, `(update) => bot.handleUpdate(update)`. */
|
|
38
|
+
readonly handle: (update: TUpdate) => unknown;
|
|
39
|
+
/**
|
|
40
|
+
* After a failed attempt: milliseconds until the next, or `false` to
|
|
41
|
+
* abandon the update. Default: abandon what Telegram said repeating cannot
|
|
42
|
+
* fix (a refused message, a blocked user), wait Telegram's `retry_after`
|
|
43
|
+
* when it gave one, otherwise back off 5 s, 20 s, 80 s … up to 15 minutes.
|
|
44
|
+
*/
|
|
45
|
+
readonly retry?: (error: unknown, attempt: number) => number | false;
|
|
46
|
+
/** Default 5. */
|
|
47
|
+
readonly maxAttempts?: number;
|
|
48
|
+
/** How long an attempt holds its update without renewing. Default 120 000; renewed every quarter. */
|
|
49
|
+
readonly leaseMs?: number;
|
|
50
|
+
/** How long a `pending` update waits for this process before a sweep takes it. Default 60 000. */
|
|
51
|
+
readonly pendingGraceMs?: number;
|
|
52
|
+
/** Default 30 000. */
|
|
53
|
+
readonly sweepEveryMs?: number;
|
|
54
|
+
/** How long finished updates are remembered to refuse Telegram's repeats. Default 24 h. */
|
|
55
|
+
readonly retainMs?: number;
|
|
56
|
+
/** Chats handled at once. Default 32. */
|
|
57
|
+
readonly maxConcurrent?: number;
|
|
58
|
+
/** Every failed attempt. */
|
|
59
|
+
readonly onFailure?: (failure: TelegramUpdateFailure) => void;
|
|
60
|
+
/** The store refused a step; the update is retried when its lease lapses. */
|
|
61
|
+
readonly onStoreError?: (error: unknown, step: TelegramUpdateStoreStep) => void;
|
|
62
|
+
/** Default `Date.now`. */
|
|
63
|
+
readonly now?: () => number;
|
|
64
|
+
}
|
|
65
|
+
export interface TelegramUpdateIntake {
|
|
66
|
+
/** Record one webhook body; handling starts after, once the intake is started. */
|
|
67
|
+
accept(body: string): Promise<TelegramUpdateAcceptance>;
|
|
68
|
+
/** Start handling, beginning with everything recorded before. */
|
|
69
|
+
start(): Promise<void>;
|
|
70
|
+
/** Take over what is due now; how many updates were scheduled. */
|
|
71
|
+
sweep(): Promise<number>;
|
|
72
|
+
/** Resolves once nothing is scheduled. */
|
|
73
|
+
idle(): Promise<void>;
|
|
74
|
+
/** Stop scheduling and wait for the handlers in flight. */
|
|
75
|
+
close(): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export declare function createTelegramUpdateIntake<TUpdate extends TelegramUpdateEnvelope>(config: TelegramUpdateIntakeConfig<TUpdate>): TelegramUpdateIntake;
|
|
78
|
+
//# sourceMappingURL=update-intake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-intake.d.ts","sourceRoot":"","sources":["../../src/telegram/update-intake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAE1D,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE7E,MAAM,WAAW,0BAA0B,CAAC,OAAO,SAAS,sBAAsB;IAChF,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,KAAK,CAAC;IACrE,iBAAiB;IACjB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kGAAkG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB;IACtB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,4BAA4B;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC9D,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAChF,0BAA0B;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACxD,iEAAiE;IACjE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,kEAAkE;IAClE,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,0CAA0C;IAC1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,2DAA2D;IAC3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAsDD,wBAAgB,0BAA0B,CAAC,OAAO,SAAS,sBAAsB,EAC/E,MAAM,EAAE,0BAA0B,CAAC,OAAO,CAAC,GAC1C,oBAAoB,CAgJtB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The update store in SQLite, through the database handle the application
|
|
3
|
+
* already opened — `bun:sqlite`'s `Database` or `node:sqlite`'s `DatabaseSync`
|
|
4
|
+
* as it is. The module imports neither, so it runs wherever its caller does.
|
|
5
|
+
*
|
|
6
|
+
* Each rule of `TelegramUpdateStore` is one conditional statement, so a claim
|
|
7
|
+
* is atomic across processes sharing the file.
|
|
8
|
+
*/
|
|
9
|
+
import type { TelegramUpdateStore } from './update-store.js';
|
|
10
|
+
/** What this store needs of a SQLite handle; both runtimes' handles have it. */
|
|
11
|
+
export interface TelegramSqliteDatabase {
|
|
12
|
+
exec(sql: string): unknown;
|
|
13
|
+
prepare(sql: string): {
|
|
14
|
+
run(...parameters: (string | number | null)[]): {
|
|
15
|
+
readonly changes: number | bigint;
|
|
16
|
+
};
|
|
17
|
+
all(...parameters: (string | number | null)[]): unknown[];
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface SqliteTelegramUpdateStoreConfig {
|
|
21
|
+
readonly database: TelegramSqliteDatabase;
|
|
22
|
+
/** Default `telegram_updates`. Created when missing. */
|
|
23
|
+
readonly table?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function sqliteTelegramUpdateStore(config: SqliteTelegramUpdateStoreConfig): TelegramUpdateStore;
|
|
26
|
+
//# sourceMappingURL=update-store-sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-store-sqlite.d.ts","sourceRoot":"","sources":["../../src/telegram/update-store-sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAExB,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QACpB,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG;YAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACtF,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;KAC3D,CAAC;CACH;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,wDAAwD;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAiBD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,+BAA+B,GACtC,mBAAmB,CAkFrB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where received updates wait, and the rules a store keeps for them.
|
|
3
|
+
*
|
|
4
|
+
* The intake decides; the store only has to make each decision atomic, so two
|
|
5
|
+
* processes sharing one store — an old release still draining beside a new one
|
|
6
|
+
* — never run one update at once. Every rule is a condition on one record:
|
|
7
|
+
*
|
|
8
|
+
* - **claimable** at `now`: `pending`; `failed` whose `dueAt` has come;
|
|
9
|
+
* `processing` whose lease (`dueAt`) has lapsed — its process died;
|
|
10
|
+
* - `claim` takes a claimable record whose `attempts` are under the limit —
|
|
11
|
+
* `processing`, `attempts + 1`, lease until `leaseUntil` — and settles one
|
|
12
|
+
* whose attempts are spent as `abandoned`;
|
|
13
|
+
* - `renew` and `settle` act only while the record is still `processing` under
|
|
14
|
+
* the same attempt, so a process that lost its lease cannot overwrite the
|
|
15
|
+
* one that took it over.
|
|
16
|
+
*/
|
|
17
|
+
export type TelegramUpdateState = 'pending' | 'processing' | 'failed' | 'completed' | 'abandoned';
|
|
18
|
+
export type TelegramUpdateSettlement = {
|
|
19
|
+
readonly state: 'completed';
|
|
20
|
+
readonly at: number;
|
|
21
|
+
} | {
|
|
22
|
+
readonly state: 'failed';
|
|
23
|
+
readonly at: number;
|
|
24
|
+
readonly retryAt: number;
|
|
25
|
+
readonly error: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly state: 'abandoned';
|
|
28
|
+
readonly at: number;
|
|
29
|
+
readonly error: string;
|
|
30
|
+
};
|
|
31
|
+
export interface TelegramUpdateClaimOptions {
|
|
32
|
+
readonly now: number;
|
|
33
|
+
readonly leaseUntil: number;
|
|
34
|
+
readonly maxAttempts: number;
|
|
35
|
+
}
|
|
36
|
+
export interface TelegramUpdateDueQuery {
|
|
37
|
+
readonly now: number;
|
|
38
|
+
/** A `pending` record is due once received at or before this — its own process had its chance. */
|
|
39
|
+
readonly pendingBefore: number;
|
|
40
|
+
readonly limit: number;
|
|
41
|
+
}
|
|
42
|
+
export interface StoredTelegramUpdate {
|
|
43
|
+
readonly updateId: number;
|
|
44
|
+
readonly body: string;
|
|
45
|
+
}
|
|
46
|
+
export interface TelegramUpdateStore {
|
|
47
|
+
/** Record a received update as `pending`; `false` when this `update_id` is already recorded. */
|
|
48
|
+
add(update: StoredTelegramUpdate & {
|
|
49
|
+
readonly receivedAt: number;
|
|
50
|
+
}): Promise<boolean>;
|
|
51
|
+
/** Take a claimable update for one attempt; its number, or `undefined` when not taken. */
|
|
52
|
+
claim(updateId: number, options: TelegramUpdateClaimOptions): Promise<number | undefined>;
|
|
53
|
+
/** Extend the lease of this attempt; `false` when the attempt no longer holds the update. */
|
|
54
|
+
renew(updateId: number, attempt: number, leaseUntil: number): Promise<boolean>;
|
|
55
|
+
/** End this attempt; ignored when the attempt no longer holds the update. */
|
|
56
|
+
settle(updateId: number, attempt: number, settlement: TelegramUpdateSettlement): Promise<void>;
|
|
57
|
+
/** Claimable updates in `update_id` order. */
|
|
58
|
+
due(query: TelegramUpdateDueQuery): Promise<readonly StoredTelegramUpdate[]>;
|
|
59
|
+
/** Forget `completed` and `abandoned` updates settled before `before`; how many were forgotten. */
|
|
60
|
+
prune(before: number): Promise<number>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A store in this process's memory — for tests, and for a bot that accepts
|
|
64
|
+
* losing what was received but not handled when it restarts.
|
|
65
|
+
*/
|
|
66
|
+
export declare function memoryTelegramUpdateStore(): TelegramUpdateStore;
|
|
67
|
+
//# sourceMappingURL=update-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-store.d.ts","sourceRoot":"","sources":["../../src/telegram/update-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACpD;IACE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GACD;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,gGAAgG;IAChG,GAAG,CAAC,MAAM,EAAE,oBAAoB,GAAG;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtF,0FAA0F;IAC1F,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC1F,6FAA6F;IAC7F,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,6EAA6E;IAC7E,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,wBAAwB,GACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,8CAA8C;IAC9C,GAAG,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAC;IAC7E,mGAAmG;IACnG,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxC;AAsBD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,mBAAmB,CAsE/D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bot's webhook: one place in all of Telegram, and who may take it.
|
|
3
|
+
*
|
|
4
|
+
* `setWebhook` moves a bot's updates without asking whose they were. A process
|
|
5
|
+
* started anywhere with the production token — a developer's machine, a
|
|
6
|
+
* staging host, a rehearsal — takes the production bot with one call, and the
|
|
7
|
+
* production process simply stops hearing from Telegram. So a claim sets the
|
|
8
|
+
* webhook only where it already points here, or where the caller named the
|
|
9
|
+
* current owner's host as the one it takes over from (`'none'` when there is no
|
|
10
|
+
* webhook — a bot on long polling is somebody's bot too).
|
|
11
|
+
*
|
|
12
|
+
* "Here" is the address *and* the secret. Telegram never returns the secret,
|
|
13
|
+
* so the address carries a tag derived from it: an `owner` query parameter
|
|
14
|
+
* holding an HMAC of the secret. A process with the production address but a
|
|
15
|
+
* different secret has a different address and is refused, instead of quietly
|
|
16
|
+
* installing its secret and leaving production answering 403 to every update.
|
|
17
|
+
* Routers match the path, which the tag leaves alone; the secret cannot be
|
|
18
|
+
* recovered from it. Errors and reports name hosts only — a foreign webhook's
|
|
19
|
+
* path may itself be a secret.
|
|
20
|
+
*/
|
|
21
|
+
/** `takeoverFrom` when there is no webhook to take over — the bot polls, or is new. */
|
|
22
|
+
export declare const TELEGRAM_WEBHOOK_NONE = "none";
|
|
23
|
+
export interface TelegramWebhookConfig {
|
|
24
|
+
readonly token: string;
|
|
25
|
+
/** Where Telegram should post updates, without the owner tag. */
|
|
26
|
+
readonly url: string;
|
|
27
|
+
/** Telegram's `secret_token`: 1–256 of `A-Z a-z 0-9 _ -`. */
|
|
28
|
+
readonly secret: string;
|
|
29
|
+
/** A local Bot API server. Default: Telegram's. */
|
|
30
|
+
readonly apiRoot?: string;
|
|
31
|
+
readonly fetch?: typeof fetch;
|
|
32
|
+
readonly signal?: AbortSignal;
|
|
33
|
+
}
|
|
34
|
+
export interface ClaimTelegramWebhookConfig extends TelegramWebhookConfig {
|
|
35
|
+
/**
|
|
36
|
+
* The host the webhook may be taken from — the current owner's, as the
|
|
37
|
+
* refusal names it — or `'none'` to set one where there is none. Set it for
|
|
38
|
+
* one switch and remove it: left in place it is a standing permission.
|
|
39
|
+
*/
|
|
40
|
+
readonly takeoverFrom?: string;
|
|
41
|
+
/** Telegram's `allowed_updates`. Default: whatever the webhook had. */
|
|
42
|
+
readonly allowedUpdates?: readonly string[];
|
|
43
|
+
/** Telegram's `max_connections`, 1–100. */
|
|
44
|
+
readonly maxConnections?: number;
|
|
45
|
+
/** Default `false`: updates waiting for the previous owner are this owner's now. */
|
|
46
|
+
readonly dropPendingUpdates?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface TelegramWebhookClaim {
|
|
49
|
+
/** The address set, owner tag included. */
|
|
50
|
+
readonly url: string;
|
|
51
|
+
/** The host it was taken over from; absent when it was already this one's. */
|
|
52
|
+
readonly takenFrom?: string;
|
|
53
|
+
readonly pendingUpdates: number;
|
|
54
|
+
}
|
|
55
|
+
export type TelegramWebhookRefusal =
|
|
56
|
+
/** Another host holds the webhook. */
|
|
57
|
+
'owned-elsewhere'
|
|
58
|
+
/** This address holds it, registered with another secret. */
|
|
59
|
+
| 'other-secret'
|
|
60
|
+
/** Telegram accepted `setWebhook` but reports another address after it. */
|
|
61
|
+
| 'not-confirmed';
|
|
62
|
+
export declare class TelegramWebhookClaimError extends Error {
|
|
63
|
+
readonly reason: TelegramWebhookRefusal;
|
|
64
|
+
/** Where the webhook points, as a host; `'none'` when nowhere. */
|
|
65
|
+
readonly ownerHost: string;
|
|
66
|
+
constructor(reason: TelegramWebhookRefusal, ownerHost: string);
|
|
67
|
+
}
|
|
68
|
+
export interface TelegramWebhookState {
|
|
69
|
+
/** The webhook points to this address with this secret. */
|
|
70
|
+
readonly owned: boolean;
|
|
71
|
+
readonly ownerHost: string;
|
|
72
|
+
readonly pendingUpdates: number;
|
|
73
|
+
/** Telegram's last failure to deliver, if it reported one. */
|
|
74
|
+
readonly lastError?: {
|
|
75
|
+
readonly at: number;
|
|
76
|
+
readonly message: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** The address with its owner tag: the same for every process with this secret. */
|
|
80
|
+
export declare function telegramWebhookUrl(url: string, secret: string): Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Set the webhook if it is this process's to set, and confirm Telegram holds
|
|
83
|
+
* it. Refused — without `setWebhook` — when another host or another secret
|
|
84
|
+
* holds it and `takeoverFrom` does not name that holder.
|
|
85
|
+
*/
|
|
86
|
+
export declare function claimTelegramWebhook(config: ClaimTelegramWebhookConfig): Promise<TelegramWebhookClaim>;
|
|
87
|
+
/**
|
|
88
|
+
* Whether the webhook still points here. A webhook moved to another host, or
|
|
89
|
+
* re-registered with another secret, stops this process hearing from Telegram
|
|
90
|
+
* without any error of its own — a periodic check is how it is noticed.
|
|
91
|
+
*/
|
|
92
|
+
export declare function checkTelegramWebhook(config: TelegramWebhookConfig): Promise<TelegramWebhookState>;
|
|
93
|
+
/** What becomes of an update body: recorded, seen before, or not an update. */
|
|
94
|
+
export type TelegramUpdateAcceptance = 'accepted' | 'duplicate' | 'invalid';
|
|
95
|
+
export interface ReceiveTelegramWebhookOptions {
|
|
96
|
+
readonly secret: string;
|
|
97
|
+
/** Records the update; answered to Telegram as soon as this resolves. */
|
|
98
|
+
readonly accept: (body: string) => Promise<TelegramUpdateAcceptance>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Answer one webhook request: 403 without this secret, 400 for a body that is
|
|
102
|
+
* not an update, 200 once the update is recorded — before it is handled.
|
|
103
|
+
*/
|
|
104
|
+
export declare function receiveTelegramWebhook(request: Request, options: ReceiveTelegramWebhookOptions): Promise<Response>;
|
|
105
|
+
//# sourceMappingURL=webhook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/telegram/webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,uFAAuF;AACvF,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAE5C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA2B,SAAQ,qBAAqB;IACvE;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,2CAA2C;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,oFAAoF;IACpF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,sBAAsB;AAChC,sCAAsC;AACpC,iBAAiB;AACnB,6DAA6D;GAC3D,cAAc;AAChB,2EAA2E;GACzE,eAAe,CAAC;AAEpB,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,MAAM,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,EAa5D;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAcD,mFAAmF;AACnF,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUrF;AA+BD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAS/B;AAED,+EAA+E;AAC/E,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAE5E,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACtE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAUnB"}
|
|
@@ -20,6 +20,14 @@ export interface FieldInfo {
|
|
|
20
20
|
*/
|
|
21
21
|
export declare function describeSchemaFields(schema: z.ZodType | undefined): Map<string, FieldInfo>;
|
|
22
22
|
/** Strict boolean for a RESERVED option — an unrecognised value is a usage error, never a silent `true`. */
|
|
23
|
+
/**
|
|
24
|
+
* The token after a bare boolean flag, when it is the flag's value: exactly
|
|
25
|
+
* `true` or `false` — `--verbose false` is a common habit, and reading it as
|
|
26
|
+
* "on, plus a positional `false`" silently does the opposite of what was said.
|
|
27
|
+
* Only those two words: `1`, `yes` or `no` there stay positionals, since a
|
|
28
|
+
* flag followed by an ordinary value must not swallow it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function separateBoolValue(next: string | undefined): boolean | undefined;
|
|
23
31
|
/** True for a value the reserved-boolean grammar already claims. */
|
|
24
32
|
export declare function isReservedBoolWord(value: string): boolean;
|
|
25
33
|
export declare function parseReservedBool(name: string, value: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args-fields.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6ED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAI1F;AAKD,4GAA4G;AAC5G,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAKtE;AA8BD,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKlD;AAuCD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAaT;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,OAAO,GACb,IAAI,CAsBN"}
|
|
1
|
+
{"version":3,"file":"args-fields.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6ED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAI1F;AAKD,4GAA4G;AAC5G;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAI/E;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAKtE;AA8BD,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKlD;AAuCD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAaT;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,OAAO,GACb,IAAI,CAsBN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args-route.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-route.ts"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAGD,eAAO,MAAM,YAAY,aAA6D,CAAC;AAEvF,eAAO,MAAM,oBAAoB,aAA+C,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAClC;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAcrF;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA+BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"args-route.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-route.ts"],"names":[],"mappings":"AAOA;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAGD,eAAO,MAAM,YAAY,aAA6D,CAAC;AAEvF,eAAO,MAAM,oBAAoB,aAA+C,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAClC;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAcrF;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA+BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,YAAY,CAuHlF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiB7B,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,aAAa,CAAC;AAGjE,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,0FAA0F;IAC1F,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+BAA+B;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB;AA4RD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,EAC7B,MAAM,GAAE;IACN,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,GACL,aAAa,CAUf;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,GAC9B,qBAAqB,CAkDvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AA6DvD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CASrC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAqCT;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,GAAE,SAAS,eAAe,EAAO,GAClD,MAAM,
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AA6DvD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CASrC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAqCT;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,GAAE,SAAS,eAAe,EAAO,GAClD,MAAM,CA6DR"}
|
package/llms/application.2.txt
CHANGED
|
@@ -11,6 +11,31 @@ Parts of this slice:
|
|
|
11
11
|
# Guide: Managed application kernel (docs/guide/application-kernel.md) (continued)
|
|
12
12
|
==============================================================================
|
|
13
13
|
|
|
14
|
+
## Recovering change subscriptions
|
|
15
|
+
|
|
16
|
+
`changeSubscriptionResource` is an optional resource over a consumer-owned driver.
|
|
17
|
+
It uses a finite declared key set, subscribes before reading, reconciles after
|
|
18
|
+
reconnect and periodically repairs lost hints. `reconcileIntervalMs` is explicit;
|
|
19
|
+
notifications alone cannot prove freshness. Within a key, hints coalesce into one
|
|
20
|
+
trailing read and a failed read retries with backoff. Use the supplied
|
|
21
|
+
`context.commit(() => publish(value))` after awaits to reject an obsolete connection.
|
|
22
|
+
|
|
23
|
+
Drivers implement `connect(signal)` and return `subscribe({ signal, hint,
|
|
24
|
+
disconnected })` plus `close()`. Subscribe must establish the notification boundary
|
|
25
|
+
before resolving. A database LISTEN driver owns its connection, channels, decoding
|
|
26
|
+
and transaction ordering; no SQL or database driver is included here. The resource
|
|
27
|
+
owns reconnect, deadlines and shutdown. Drivers must honor abort. If one ignores it,
|
|
28
|
+
its slot remains occupied until settlement; deadlines cannot safely manufacture
|
|
29
|
+
successful cleanup or permit an overlapping connection.
|
|
30
|
+
|
|
31
|
+
For watched reads, set `reconcileIntervalMs` on the existing `createWatchHub` rather
|
|
32
|
+
than building a second read loop. Its per-key machinery is shared with managed
|
|
33
|
+
subscriptions. Limits default to 1024 sources and 1024 subscribers per hub; set
|
|
34
|
+
explicit finite values for larger workloads. Supply a server-verified admission
|
|
35
|
+
scope to `attach` and abort it on logout, permission revocation or session replacement.
|
|
36
|
+
The read callback receives the trusted scope as its third argument. A client owner
|
|
37
|
+
ID in arguments is not authentication.
|
|
38
|
+
|
|
14
39
|
## Multi-action notification delivery
|
|
15
40
|
|
|
16
41
|
Opt into `delivery: { version, actions, project }` on `createNotificationOutbox`.
|
|
@@ -328,7 +353,7 @@ cutovers are covered by the executable
|
|
|
328
353
|
| `LifecycleRunSchema` / `LifecycleRun` / `LifecycleStateSchema` / `LifecycleState` / `LifecycleTerminationSchema` / `LifecycleTermination` | schema / _type_ | versioned process-run state — open (`active`, `draining` with `unavailableAt`) and ended (`clean`, `forced`, `startup-failed`, `hot-reload`, `abnormal`) |
|
|
329
354
|
| `PreviousExitSchema` / `PreviousExit` / `StartFact` / `ReadyFact` / `DrainingFact` / `ShutdownFact` / `ProcessLifecycleFact` | schema / _type_ | first-boot, hot-reload, clean, forced, startup-failed, handoff and abnormal lifecycle facts; `processGapMs` on start, `downtimeMs` (unavailable → ready) on ready |
|
|
330
355
|
| `transitionProcessStart` / `transitionProcessReady` / `transitionProcessDraining` / `transitionProcessShutdown` | function | pure idempotent runId+pid-owned transitions |
|
|
331
|
-
| `LifecycleTransition` / `TransitionStartInput` / `TransitionRunInput` / `TransitionShutdownInput` / `SameVersionOverlap` | _type_ | pure transition inputs (`TransitionRunInput` for ready and draining, extended with `forced` for shutdown), the same-build overlap policy (`abnormal` default / `handoff`) and state+fact result |
|
|
356
|
+
| `LifecycleTransition` / `TransitionStartInput` / `TransitionRunInput` / `TransitionShutdownInput` / `SameVersionOverlap` / `VersionChangeOverlap` | _type_ | pure transition inputs (`TransitionRunInput` for ready and draining, extended with `forced` for shutdown), the same-build overlap policy (`abnormal` default / `handoff`), the version-change overlap policy (`handoff` default / `abnormal`) and state+fact result |
|
|
332
357
|
| `lifecycleLedgerResource` / `LifecycleLedgerResource` / `LifecycleLedgerResourceConfig` | function / _type_ | managed-resource adapter that records start, readiness, admission stop (draining) and shutdown |
|
|
333
358
|
| `createNotificationOutbox` / `NotificationOutbox` / `NotificationOutboxConfig` | function / _type_ | bounded at-least-once queue with durable claims, leases, retries and supersede |
|
|
334
359
|
| `NotificationOutboxItem` / `NotificationOutboxReceipt` / `NotificationOutboxState` / `NotificationSend` / `NotificationFailureClassification` / `DroppedNotification` / `EnqueueNotification` | _type_ | versioned queue records, stable send identity and delivery decisions |
|