stitchkit 0.100.2 → 0.101.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/CHANGELOG.md +153 -0
- package/README.md +2 -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.js +209 -210
- 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 +116 -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 +11 -3
- package/dist/entrypoints/telegram.d.ts.map +1 -1
- package/dist/entrypoints/telegram.js +779 -159
- 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 +224 -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-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-e05cjgtf.js +144 -0
- package/dist/{index-yw4fzmdz.js → index-e6c2spsd.js} +79 -30
- 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-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-sznqf8fx.js +20 -0
- 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/internal/secret-shapes.d.ts +21 -0
- package/dist/internal/secret-shapes.d.ts.map +1 -0
- 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/bot-api.d.ts +7 -4
- package/dist/telegram/bot-api.d.ts.map +1 -1
- 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 +3 -44
- package/dist/telegram/init-data.d.ts.map +1 -1
- package/dist/telegram/operator-channel.d.ts +19 -3
- package/dist/telegram/operator-channel.d.ts.map +1 -1
- package/dist/telegram/operator-dedupe.d.ts +44 -0
- package/dist/telegram/operator-dedupe.d.ts.map +1 -0
- 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 +25 -0
- package/dist/telegram/send-failure.d.ts.map +1 -1
- package/dist/telegram/update-intake.d.ts +82 -0
- package/dist/telegram/update-intake.d.ts.map +1 -0
- package/dist/telegram/update-store-check.d.ts +22 -0
- package/dist/telegram/update-store-check.d.ts.map +1 -0
- package/dist/telegram/update-store-postgres.d.ts +33 -0
- package/dist/telegram/update-store-postgres.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/user.d.ts +51 -0
- package/dist/telegram/user.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/cli.txt +8 -2
- package/llms/observability.txt +15 -2
- package/llms/react-keyboard.txt +193 -0
- package/llms/server.4.txt +16 -0
- package/llms/stitchkit.txt +10 -4
- package/llms/telegram-html.txt +35 -0
- package/llms/telegram-screens.txt +365 -0
- package/llms/telegram.txt +245 -11
- package/llms/{upgrading-0.74.0-0.100.0.txt → upgrading-0.74.0-0.101.0.txt} +39 -3
- package/llms/upgrading.txt +1 -1
- package/llms-full.txt +889 -19
- package/llms.txt +12 -7
- 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,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* From what the chat shows to what it should show, in the fewest Bot API calls
|
|
3
|
+
* that keep the chat in order.
|
|
4
|
+
*
|
|
5
|
+
* Telegram orders messages by when they were sent, and a sent message cannot
|
|
6
|
+
* move. So a message is kept (and edited in place) only while the new view's
|
|
7
|
+
* order allows it: walking the new view top to bottom, a message whose key the
|
|
8
|
+
* chat already shows — below the last one kept, and editable into the new
|
|
9
|
+
* shape — is kept. The first message that cannot be kept is sent, and so is
|
|
10
|
+
* every message after it, because anything sent lands at the bottom; whatever
|
|
11
|
+
* the chat showed and was not kept is deleted.
|
|
12
|
+
*
|
|
13
|
+
* Editable means what the Bot API can do in place: text into text and rich
|
|
14
|
+
* into rich (`editMessageText`), text or rich into media and media into media
|
|
15
|
+
* of any kind (`editMessageMedia`). Media into text or rich, and text into rich
|
|
16
|
+
* or back, is a new message.
|
|
17
|
+
*
|
|
18
|
+
* The plan is data. Carrying it out — and recovering when Telegram refuses an
|
|
19
|
+
* edit it allowed a moment ago — is `execute`'s.
|
|
20
|
+
*/
|
|
21
|
+
import type { MessageFingerprint, OutgoingMessage, RenderedKind } from './render.js';
|
|
22
|
+
/** A message the chat shows, as the chat's state remembers it. */
|
|
23
|
+
export interface ShownMessage {
|
|
24
|
+
readonly key: string;
|
|
25
|
+
readonly id: number;
|
|
26
|
+
readonly kind: RenderedKind;
|
|
27
|
+
/** `null` for a message whose content is not known — one adopted from a press. */
|
|
28
|
+
readonly fingerprint: MessageFingerprint | null;
|
|
29
|
+
}
|
|
30
|
+
export interface EditParts {
|
|
31
|
+
readonly content: boolean;
|
|
32
|
+
readonly media: boolean;
|
|
33
|
+
readonly markup: boolean;
|
|
34
|
+
}
|
|
35
|
+
export type PlanStep = {
|
|
36
|
+
readonly op: 'keep';
|
|
37
|
+
readonly id: number;
|
|
38
|
+
readonly from: ShownMessage;
|
|
39
|
+
readonly message: OutgoingMessage;
|
|
40
|
+
} | {
|
|
41
|
+
readonly op: 'edit';
|
|
42
|
+
readonly id: number;
|
|
43
|
+
readonly from: ShownMessage;
|
|
44
|
+
readonly message: OutgoingMessage;
|
|
45
|
+
readonly parts: EditParts;
|
|
46
|
+
} | {
|
|
47
|
+
readonly op: 'send';
|
|
48
|
+
readonly message: OutgoingMessage;
|
|
49
|
+
};
|
|
50
|
+
export interface ViewPlan {
|
|
51
|
+
/** The new view, top to bottom: each message kept, edited or sent. */
|
|
52
|
+
readonly steps: readonly PlanStep[];
|
|
53
|
+
/** Messages the chat showed that the new view does not keep. */
|
|
54
|
+
readonly deletions: readonly number[];
|
|
55
|
+
}
|
|
56
|
+
export declare function isEditable(from: RenderedKind, to: RenderedKind): boolean;
|
|
57
|
+
export interface PlanOptions {
|
|
58
|
+
/**
|
|
59
|
+
* The message a press came from, when it is not part of the view the chat
|
|
60
|
+
* state knows. It becomes the first message of the new view if it can.
|
|
61
|
+
*/
|
|
62
|
+
readonly adopt?: ShownMessage;
|
|
63
|
+
/** Send the whole view anew below everything, deleting what was shown. */
|
|
64
|
+
readonly fresh?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export declare function planView(shown: readonly ShownMessage[], next: readonly OutgoingMessage[], options?: PlanOptions): ViewPlan;
|
|
67
|
+
//# sourceMappingURL=reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAElF,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,kFAAkF;IAClF,QAAQ,CAAC,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,QAAQ,GAChB;IACE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;CACnC,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAID,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,GAAG,OAAO,CAExE;AAgBD,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,IAAI,EAAE,SAAS,eAAe,EAAE,EAChC,OAAO,GAAE,WAAgB,GACxB,QAAQ,CAiCV"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The screens a bot declared, by id and by object, with the tree between them.
|
|
3
|
+
*
|
|
4
|
+
* Checked once, when the bot is composed: two screens with one path or one id
|
|
5
|
+
* would make a button mean two things, and a screen whose id collides with
|
|
6
|
+
* another's derived id would do so silently on the next release.
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from 'grammy';
|
|
9
|
+
import type { ButtonResolver } from './render.js';
|
|
10
|
+
import type { AnyTelegramScreen, ScreenActions, ScreenDefinition, ScreenParams, TelegramScreen } from './screen-types.js';
|
|
11
|
+
export type DeclaredScreen<C extends Context> = TelegramScreen<C, ScreenParams, unknown, ScreenActions>;
|
|
12
|
+
export interface RegisteredScreen<C extends Context> {
|
|
13
|
+
readonly screen: DeclaredScreen<C>;
|
|
14
|
+
readonly definition: ScreenDefinition<C>;
|
|
15
|
+
readonly parent: RegisteredScreen<C> | undefined;
|
|
16
|
+
}
|
|
17
|
+
export interface ScreenRegistry<C extends Context> {
|
|
18
|
+
byId(id: string): RegisteredScreen<C> | undefined;
|
|
19
|
+
entryOf(screen: AnyTelegramScreen): RegisteredScreen<C>;
|
|
20
|
+
resolverFor(entry: RegisteredScreen<C>): ButtonResolver;
|
|
21
|
+
}
|
|
22
|
+
export declare function createScreenRegistry<C extends Context>(screens: readonly DeclaredScreen<C>[]): ScreenRegistry<C>;
|
|
23
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,OAAO,IAAI,cAAc,CAC5D,CAAC,EACD,YAAY,EACZ,OAAO,EACP,aAAa,CACd,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,OAAO;IACjD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CAClD;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,OAAO;IAC/C,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAClD,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACxD,WAAW,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC;CACzD;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EACpD,OAAO,EAAE,SAAS,cAAc,CAAC,CAAC,CAAC,EAAE,GACpC,cAAc,CAAC,CAAC,CAAC,CAkFnB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A view as Telegram will receive it: payloads, `callback_data` and the
|
|
3
|
+
* fingerprints the next render is compared against.
|
|
4
|
+
*
|
|
5
|
+
* Buttons are resolved here, against the registered screens: a link becomes
|
|
6
|
+
* its target's id and params, `back` the parent of the screen being shown, an
|
|
7
|
+
* action the screen's own id, params and input. An address longer than
|
|
8
|
+
* Telegram's 64 bytes is kept in the chat's state under a short token and the
|
|
9
|
+
* button carries the token — so a long param never makes a screen unrenderable.
|
|
10
|
+
*/
|
|
11
|
+
import type { InlineKeyboardButton, InlineKeyboardMarkup, InputRichMessageWithoutUpload } from 'grammy/types';
|
|
12
|
+
import { type TelegramText } from './html.js';
|
|
13
|
+
import type { AnyTelegramScreen, ScreenParams } from './screen-types.js';
|
|
14
|
+
import { ScreenButton, type ScreenMediaKind, type ScreenViewResult } from './view.js';
|
|
15
|
+
export type RenderedKind = 'text' | 'rich' | ScreenMediaKind;
|
|
16
|
+
/** The parts of a message that are edited separately, as digests. */
|
|
17
|
+
export interface MessageFingerprint {
|
|
18
|
+
readonly content: string;
|
|
19
|
+
readonly media: string;
|
|
20
|
+
readonly markup: string;
|
|
21
|
+
}
|
|
22
|
+
export interface OutgoingMessage {
|
|
23
|
+
readonly key: string;
|
|
24
|
+
readonly kind: RenderedKind;
|
|
25
|
+
/**
|
|
26
|
+
* Telegram HTML: the text of a text message, the caption of a media one.
|
|
27
|
+
* Always sent with `parse_mode: 'HTML'`, plain strings escaped — so no
|
|
28
|
+
* `parse_mode` default an application sets elsewhere can reinterpret it.
|
|
29
|
+
*/
|
|
30
|
+
readonly html: string | undefined;
|
|
31
|
+
readonly rich: InputRichMessageWithoutUpload | undefined;
|
|
32
|
+
readonly linkPreview: boolean | undefined;
|
|
33
|
+
readonly media: string | undefined;
|
|
34
|
+
readonly markup: InlineKeyboardMarkup | undefined;
|
|
35
|
+
readonly fingerprint: MessageFingerprint;
|
|
36
|
+
}
|
|
37
|
+
/** Where a screen button leads, resolved against the registered screens. */
|
|
38
|
+
export interface ButtonResolver {
|
|
39
|
+
/** The id and param order of a registered screen; throws for one not registered. */
|
|
40
|
+
addressOf(screen: AnyTelegramScreen): {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly params: readonly string[];
|
|
43
|
+
};
|
|
44
|
+
/** The parent of the screen being rendered, or `undefined` at the root. */
|
|
45
|
+
readonly parent: {
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly params: readonly string[];
|
|
48
|
+
} | undefined;
|
|
49
|
+
readonly path: string;
|
|
50
|
+
}
|
|
51
|
+
export interface RenderContext {
|
|
52
|
+
readonly prefix: string;
|
|
53
|
+
readonly resolver: ButtonResolver;
|
|
54
|
+
readonly params: ScreenParams;
|
|
55
|
+
}
|
|
56
|
+
export interface RenderedView {
|
|
57
|
+
readonly messages: readonly OutgoingMessage[];
|
|
58
|
+
/** Addresses too long for a button, by token. */
|
|
59
|
+
readonly tokens: Readonly<Record<string, string>>;
|
|
60
|
+
}
|
|
61
|
+
/** Text as Telegram HTML: markup as it is, a plain string escaped. */
|
|
62
|
+
export declare function htmlOf(text: TelegramText): string;
|
|
63
|
+
export declare function renderView(view: ScreenViewResult, context: RenderContext): RenderedView;
|
|
64
|
+
/**
|
|
65
|
+
* A link for a message the screens do not own — a notification. It carries
|
|
66
|
+
* its whole address, because no view record will hold a token for it, and it
|
|
67
|
+
* opens its screen below rather than changing the message it sits on.
|
|
68
|
+
*/
|
|
69
|
+
export declare function renderDetachedButton(button: ScreenButton, prefix: string, addressOf: ButtonResolver['addressOf']): InlineKeyboardButton.CallbackButton;
|
|
70
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,6BAA6B,EAC9B,MAAM,cAAc,CAAC;AAUtB,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EAIL,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,EAEtB,MAAM,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC;AAE7D,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,6BAA6B,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;CAC1C;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,oFAAoF;IACpF,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG;QACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;KACpC,CAAC;IACF,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC;IACzF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD;AAED,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEjD;AAoKD,wBAAgB,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,GAAG,YAAY,CA8BvF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GACrC,oBAAoB,CAAC,cAAc,CAmBrC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The screens of one bot, as grammY middleware.
|
|
3
|
+
*
|
|
4
|
+
* `bot.use(screens)` takes the presses whose `callback_data` carries this
|
|
5
|
+
* runtime's prefix and the messages a shown screen takes as input; every other
|
|
6
|
+
* update goes to the next handler untouched, and it is handed on outside the
|
|
7
|
+
* chat's queue. `screens.open(ctx, screen)` shows a screen from a command or a
|
|
8
|
+
* deep link; `screens.button(link(…))` puts a link to a screen into a message
|
|
9
|
+
* the screens do not own — a notification.
|
|
10
|
+
*
|
|
11
|
+
* Every chat is handled one update at a time: read the chat's record, resolve
|
|
12
|
+
* the screen, render, reconcile against what the chat shows, carry the plan
|
|
13
|
+
* out, write the record. The record is written after Telegram has answered, so
|
|
14
|
+
* it never names a message that was not sent; a crash in between leaves the
|
|
15
|
+
* chat ahead of its record, and the next press is handled as a press on a
|
|
16
|
+
* message the record does not know. Two processes serving one chat — builds
|
|
17
|
+
* overlapping during a release, a webhook fan-out — are not serialised: the
|
|
18
|
+
* last write wins.
|
|
19
|
+
*/
|
|
20
|
+
import type { Context, MiddlewareFn, MiddlewareObj } from 'grammy';
|
|
21
|
+
import type { InlineKeyboardButton } from 'grammy/types';
|
|
22
|
+
import { type DisplayRequest } from './display.js';
|
|
23
|
+
import type { ExecutionReport, ScreenApi } from './execute.js';
|
|
24
|
+
import type { ScreenOutcomeBuilders } from './outcome.js';
|
|
25
|
+
import { type DeclaredScreen, type ScreenRegistry } from './registry.js';
|
|
26
|
+
import type { AnyTelegramScreen, ScreenHandlerResult, ScreenLinkArgs } from './screen-types.js';
|
|
27
|
+
import { type ScreenChatState, type TelegramScreenStorage } from './state.js';
|
|
28
|
+
import type { ScreenButton } from './view.js';
|
|
29
|
+
/** Why a press could not be answered by the screen it names. */
|
|
30
|
+
export type ScreenStaleReason = 'malformed' | 'forged' | 'inaccessible' | 'unknown-token' | 'unknown-screen' | 'invalid-params' | 'unknown-action' | 'invalid-input';
|
|
31
|
+
export type ScreenTrigger = 'open' | 'press' | 'input';
|
|
32
|
+
export interface ScreenStaleContext<C extends Context> extends ScreenOutcomeBuilders {
|
|
33
|
+
readonly ctx: C;
|
|
34
|
+
readonly reason: ScreenStaleReason;
|
|
35
|
+
}
|
|
36
|
+
export interface ScreenErrorContext<C extends Context> extends ScreenOutcomeBuilders {
|
|
37
|
+
readonly ctx: C;
|
|
38
|
+
readonly trigger: ScreenTrigger;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* What happened, for the application's journal. Never carries message text:
|
|
42
|
+
* screens are named by their path template, messages by id.
|
|
43
|
+
*/
|
|
44
|
+
export type ScreenEvent = {
|
|
45
|
+
readonly type: 'transition';
|
|
46
|
+
readonly trigger: ScreenTrigger;
|
|
47
|
+
readonly chat: string;
|
|
48
|
+
/** The screen shown before, as its path template; absent when none was. */
|
|
49
|
+
readonly from: string | undefined;
|
|
50
|
+
readonly to: string;
|
|
51
|
+
readonly durationMs: number;
|
|
52
|
+
readonly report: ExecutionReport;
|
|
53
|
+
}
|
|
54
|
+
/** A stored record did not match this release's schema and was set aside. */
|
|
55
|
+
| {
|
|
56
|
+
readonly type: 'state-discarded';
|
|
57
|
+
readonly chat: string;
|
|
58
|
+
}
|
|
59
|
+
/** Messages Telegram would not delete — an expired remark, the user's input. */
|
|
60
|
+
| {
|
|
61
|
+
readonly type: 'message-kept';
|
|
62
|
+
readonly chat: string;
|
|
63
|
+
readonly messageIds: readonly number[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Deleting expired remarks on their timer failed — no update was there to
|
|
67
|
+
* carry the error. The chat's next update sweeps them again.
|
|
68
|
+
*/
|
|
69
|
+
| {
|
|
70
|
+
readonly type: 'sweep-failed';
|
|
71
|
+
readonly chat: string;
|
|
72
|
+
readonly error: unknown;
|
|
73
|
+
};
|
|
74
|
+
export interface TelegramScreensConfig<C extends Context> {
|
|
75
|
+
readonly screens: readonly DeclaredScreen<C>[];
|
|
76
|
+
/** Where each chat's screen survives a restart — any grammY `StorageAdapter`. */
|
|
77
|
+
readonly storage: TelegramScreenStorage;
|
|
78
|
+
/** The storage key of a chat's record. Default: `screens:<chat id>`, apart from grammY sessions. */
|
|
79
|
+
readonly chatKey?: (ctx: C) => string | undefined;
|
|
80
|
+
/** What every screen button's `callback_data` starts with. Default `"~"`. */
|
|
81
|
+
readonly callbackPrefix?: string;
|
|
82
|
+
/** Which chats screens answer in. Default `'private'`: in a group any member could press or type. */
|
|
83
|
+
readonly chats?: 'private' | 'all';
|
|
84
|
+
/** A press this bot no longer understands, or that no button carried. Default: answered silently. */
|
|
85
|
+
readonly onStale?: (c: ScreenStaleContext<C>) => ScreenHandlerResult;
|
|
86
|
+
/**
|
|
87
|
+
* A load, action or input that threw. Its outcome is shown instead; without
|
|
88
|
+
* it the press is answered silently and the error reaches `bot.catch`.
|
|
89
|
+
*/
|
|
90
|
+
readonly onError?: (error: unknown, c: ScreenErrorContext<C>) => ScreenHandlerResult;
|
|
91
|
+
readonly onEvent?: (event: ScreenEvent) => void;
|
|
92
|
+
/** Epoch milliseconds, for expiring notices. Default `Date.now`. */
|
|
93
|
+
readonly clock?: () => number;
|
|
94
|
+
}
|
|
95
|
+
export interface OpenOptions {
|
|
96
|
+
/** The view the chat showed: kept as it is (default) or deleted. */
|
|
97
|
+
readonly previous?: 'keep' | 'delete';
|
|
98
|
+
}
|
|
99
|
+
export type OpenArgs<TScreen> = ScreenLinkArgs<TScreen> extends [params: infer P] ? [params: P, options?: OpenOptions] : ScreenLinkArgs<TScreen> extends [params?: infer P] ? [params?: P, options?: OpenOptions] : never;
|
|
100
|
+
export interface TelegramScreens<C extends Context> extends MiddlewareObj<C> {
|
|
101
|
+
middleware(): MiddlewareFn<C>;
|
|
102
|
+
/** Show a screen as a new message at the bottom of the chat. */
|
|
103
|
+
open<TScreen extends AnyTelegramScreen>(ctx: C, screen: TScreen, ...args: OpenArgs<TScreen>): Promise<void>;
|
|
104
|
+
/** A link for a message the screens do not own; pressing it opens the screen below. */
|
|
105
|
+
button(link: ScreenButton): InlineKeyboardButton.CallbackButton;
|
|
106
|
+
/** Cancel pending expiry timers; remarks left behind are swept on the chat's next update. */
|
|
107
|
+
close(): void;
|
|
108
|
+
}
|
|
109
|
+
/** What dispatch and display share for one bot. */
|
|
110
|
+
export interface ScreensRuntime<C extends Context> {
|
|
111
|
+
readonly registry: ScreenRegistry<C>;
|
|
112
|
+
readonly config: TelegramScreensConfig<C>;
|
|
113
|
+
readonly prefix: string;
|
|
114
|
+
readonly clock: () => number;
|
|
115
|
+
chatKey(ctx: C): string | undefined;
|
|
116
|
+
answers(ctx: C): boolean;
|
|
117
|
+
/** Run `task` alone in the chat; a call from inside the chat's own task runs inline. */
|
|
118
|
+
exclusive<T>(ctx: C, chat: string, task: () => Promise<T>): Promise<T>;
|
|
119
|
+
readState(chat: string): Promise<ScreenChatState>;
|
|
120
|
+
display(request: DisplayRequest<C>): Promise<void>;
|
|
121
|
+
/** `open` showed a screen for this update. */
|
|
122
|
+
markOpened(ctx: C): void;
|
|
123
|
+
/** Whether `open` showed a screen for this update — from inside its handler, its navigation stands. */
|
|
124
|
+
openedDuring(ctx: C): boolean;
|
|
125
|
+
scheduleSweep(api: ScreenApi, chat: string, chatId: number, delayMs: number): void;
|
|
126
|
+
emit(event: ScreenEvent): void;
|
|
127
|
+
}
|
|
128
|
+
export interface OwnedScreensRuntime<C extends Context> extends ScreensRuntime<C> {
|
|
129
|
+
/** Expiry timers not yet fired, so `close()` can cancel them. */
|
|
130
|
+
readonly timers: Set<ReturnType<typeof setTimeout>>;
|
|
131
|
+
}
|
|
132
|
+
export declare function createScreensRuntime<C extends Context>(config: TelegramScreensConfig<C>): OwnedScreensRuntime<C>;
|
|
133
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The types a screen is declared with, and the loose shape the runtime drives.
|
|
3
|
+
*
|
|
4
|
+
* A declared screen is typed end to end — its params come from its path (or a
|
|
5
|
+
* params schema), its data from its loads, its action buttons from its
|
|
6
|
+
* actions — and the runtime sees none of that. It holds a
|
|
7
|
+
* {@link ScreenDefinition}: closures over the typed declaration that take raw,
|
|
8
|
+
* untrusted params and input, validate them, and only then call the
|
|
9
|
+
* application. The one crossing from raw to typed is the params schema, which
|
|
10
|
+
* runs on every resolution.
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from 'grammy';
|
|
13
|
+
import type { Message } from 'grammy/types';
|
|
14
|
+
import type { ActionValue } from './callback-codec.js';
|
|
15
|
+
import type { TelegramText } from './html.js';
|
|
16
|
+
import type { ScreenOutcome, ScreenOutcomeBuilders } from './outcome.js';
|
|
17
|
+
import type { ScreenPath } from './path.js';
|
|
18
|
+
import type { ButtonLabel, ScreenButton, ScreenViewResult } from './view.js';
|
|
19
|
+
/** A param value after its schema: text, or a number a schema produced. */
|
|
20
|
+
export type ScreenParamValue = string | number;
|
|
21
|
+
export type ScreenParams = Readonly<Record<string, ScreenParamValue>>;
|
|
22
|
+
declare const noInput: unique symbol;
|
|
23
|
+
/** An action declared without an input schema. */
|
|
24
|
+
export type NoActionInput = typeof noInput;
|
|
25
|
+
/** Action name → what its button takes (`NoActionInput` when nothing). */
|
|
26
|
+
export type ScreenActions = Readonly<Record<string, unknown>>;
|
|
27
|
+
export type MaybePromise<TValue> = TValue | Promise<TValue>;
|
|
28
|
+
/** What a handler may answer with; nothing — a body with no `return` — is `stay()`. */
|
|
29
|
+
export type ScreenHandlerResult = MaybePromise<ScreenOutcome | undefined> | MaybePromise<void>;
|
|
30
|
+
export interface ScreenLoadContext<C extends Context, P extends ScreenParams, D> extends ScreenOutcomeBuilders {
|
|
31
|
+
/** The grammY context of the update being answered. */
|
|
32
|
+
readonly ctx: C;
|
|
33
|
+
/** Params from the button that was pressed — user input, validated by the params schema. */
|
|
34
|
+
readonly params: P;
|
|
35
|
+
/** What the enclosing group loaded; `undefined` outside a group. */
|
|
36
|
+
readonly data: D;
|
|
37
|
+
}
|
|
38
|
+
export interface ScreenActionContext<C extends Context, P extends ScreenParams, D, I> extends ScreenOutcomeBuilders {
|
|
39
|
+
readonly ctx: C;
|
|
40
|
+
readonly params: P;
|
|
41
|
+
/** What this screen's loads returned for this press. */
|
|
42
|
+
readonly data: D;
|
|
43
|
+
/** The button's input, parsed by the action's schema. */
|
|
44
|
+
readonly input: I;
|
|
45
|
+
}
|
|
46
|
+
/** An outcome after a message: there is no press to answer, so no toast. */
|
|
47
|
+
export type ScreenInputOutcomeBuilders = Omit<ScreenOutcomeBuilders, 'toast'>;
|
|
48
|
+
export interface ScreenInputContext<C extends Context, P extends ScreenParams, D> extends ScreenInputOutcomeBuilders {
|
|
49
|
+
readonly ctx: C;
|
|
50
|
+
readonly params: P;
|
|
51
|
+
readonly data: D;
|
|
52
|
+
/** The message as Telegram sent it. It is never stored. */
|
|
53
|
+
readonly message: Message;
|
|
54
|
+
/** Its text, or its caption, or `''`. */
|
|
55
|
+
readonly text: string;
|
|
56
|
+
/** Show a "working on it" message; it is removed when the handler ends, however it ends. */
|
|
57
|
+
pending(content: TelegramText): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
/** The action buttons of a screen, one factory per declared action. */
|
|
60
|
+
export type ScreenActionButtons<A extends ScreenActions> = {
|
|
61
|
+
readonly [K in keyof A]: A[K] extends NoActionInput ? (label: ButtonLabel) => ScreenButton : (label: ButtonLabel, input: A[K]) => ScreenButton;
|
|
62
|
+
};
|
|
63
|
+
export interface ScreenViewContext<C extends Context, P extends ScreenParams, D, A extends ScreenActions> {
|
|
64
|
+
readonly ctx: C;
|
|
65
|
+
readonly params: P;
|
|
66
|
+
readonly data: D;
|
|
67
|
+
readonly act: ScreenActionButtons<A>;
|
|
68
|
+
}
|
|
69
|
+
/** Message kinds a screen can take as input. */
|
|
70
|
+
export type ScreenInputKind = 'text' | 'rich' | 'photo' | 'video' | 'animation' | 'document' | 'audio' | 'voice' | 'video_note' | 'sticker' | 'location' | 'contact';
|
|
71
|
+
export interface ScreenInputOptions {
|
|
72
|
+
/** Leave the user's message in the chat. Default: removed before the handler runs. */
|
|
73
|
+
readonly keepMessage?: boolean;
|
|
74
|
+
}
|
|
75
|
+
/** Why raw params or input did not become a screen. */
|
|
76
|
+
export type ScreenRefusal = 'invalid-params' | 'unknown-action' | 'invalid-input';
|
|
77
|
+
/** A screen resolved for one update: params parsed, data loaded. */
|
|
78
|
+
export interface ResolvedScreen {
|
|
79
|
+
readonly params: ScreenParams;
|
|
80
|
+
render(): ScreenViewResult;
|
|
81
|
+
runAction(action: string, input: Readonly<Record<string, ActionValue>> | undefined): Promise<ScreenOutcome | undefined | ScreenRefusal>;
|
|
82
|
+
input(kind: ScreenInputKind): ResolvedScreenInput | undefined;
|
|
83
|
+
}
|
|
84
|
+
export interface ResolvedScreenInput {
|
|
85
|
+
readonly keepMessage: boolean;
|
|
86
|
+
handle(message: Message, pending: (content: TelegramText) => Promise<void>): Promise<ScreenOutcome | undefined>;
|
|
87
|
+
}
|
|
88
|
+
/** The loose screen the runtime drives. Methods, so a narrower context still assigns. */
|
|
89
|
+
export interface ScreenDefinition<C extends Context> {
|
|
90
|
+
readonly path: ScreenPath;
|
|
91
|
+
readonly id: string;
|
|
92
|
+
readonly explicitId: boolean;
|
|
93
|
+
/** Some load — the screen's own or a group's — runs before it: its params are checked. */
|
|
94
|
+
readonly guarded: boolean;
|
|
95
|
+
readonly actions: readonly string[];
|
|
96
|
+
readonly inputKinds: readonly ScreenInputKind[];
|
|
97
|
+
/** The screen takes this kind and leaves the user's message in the chat. */
|
|
98
|
+
keepsInput(kind: ScreenInputKind): boolean;
|
|
99
|
+
/** The params pass the schemas — no load runs. */
|
|
100
|
+
acceptsParams(params: Readonly<Record<string, ActionValue>>): boolean;
|
|
101
|
+
resolve(ctx: C, params: Readonly<Record<string, ActionValue>>): Promise<ResolvedScreen | ScreenOutcome | 'invalid-params'>;
|
|
102
|
+
}
|
|
103
|
+
/** A declared screen. The type parameters exist for the declaration's callers. */
|
|
104
|
+
export declare class TelegramScreen<C extends Context, P extends ScreenParams, D, A extends ScreenActions> {
|
|
105
|
+
readonly definition: ScreenDefinition<C>;
|
|
106
|
+
readonly '~types'?: {
|
|
107
|
+
readonly ctx: C;
|
|
108
|
+
readonly params: P;
|
|
109
|
+
readonly data: D;
|
|
110
|
+
readonly actions: A;
|
|
111
|
+
};
|
|
112
|
+
constructor(definition: ScreenDefinition<C>);
|
|
113
|
+
get path(): string;
|
|
114
|
+
}
|
|
115
|
+
/** Any declared screen, whatever its context, params, data and actions. */
|
|
116
|
+
export type AnyTelegramScreen = TelegramScreen<Context, ScreenParams, unknown, ScreenActions>;
|
|
117
|
+
/**
|
|
118
|
+
* The params argument of a link or a `go`: required exactly when the path has
|
|
119
|
+
* params, and refused when it has none — a param the path does not name would
|
|
120
|
+
* make the button unreadable.
|
|
121
|
+
*/
|
|
122
|
+
export type ScreenLinkArgs<TScreen> = TScreen extends {
|
|
123
|
+
readonly '~types'?: {
|
|
124
|
+
readonly params: infer P;
|
|
125
|
+
};
|
|
126
|
+
} ? keyof P extends never ? [params?: {
|
|
127
|
+
readonly [name: string]: never;
|
|
128
|
+
}] : [params: P] : never;
|
|
129
|
+
export {};
|
|
130
|
+
//# sourceMappingURL=screen-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-types.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/screen-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declaring screens: `tg.screen(path).load(…).action(…).on(…).view(…)`, and
|
|
3
|
+
* groups that share a path, params and a load.
|
|
4
|
+
*
|
|
5
|
+
* Every step narrows the types the next one sees, the way a Hono route or an
|
|
6
|
+
* Elysia handler does: the path names the params, `load` names the data, each
|
|
7
|
+
* `action` adds a typed button factory to `act`. `load` comes first or not at
|
|
8
|
+
* all — actions and input run after it and read what it returned — and `view`
|
|
9
|
+
* ends the declaration.
|
|
10
|
+
*
|
|
11
|
+
* A group is where access is checked once for everything under it:
|
|
12
|
+
* `tg.group('/bot/:botId', { params }).load(ownedBot)` runs its params schema and
|
|
13
|
+
* its load before every screen of the group — before its load, its actions and
|
|
14
|
+
* its input — and hands the screen what it loaded as `c.data`. Params arrive
|
|
15
|
+
* from a button, so they are user input; a screen with params and no load
|
|
16
|
+
* anywhere above it is refused when the bot is composed.
|
|
17
|
+
*
|
|
18
|
+
* What the runtime receives is a {@link ScreenDefinition}: closures over the
|
|
19
|
+
* typed declaration that take raw params and raw button input, validate them,
|
|
20
|
+
* and only then call the application's functions.
|
|
21
|
+
*/
|
|
22
|
+
import type { Context } from 'grammy';
|
|
23
|
+
import { z } from 'zod';
|
|
24
|
+
import { type ActionValue } from './callback-codec.js';
|
|
25
|
+
import { ScreenOutcome } from './outcome.js';
|
|
26
|
+
import { type ScreenPathParams } from './path.js';
|
|
27
|
+
import type { MaybePromise, NoActionInput, ScreenActionContext, ScreenActions, ScreenHandlerResult, ScreenInputContext, ScreenInputKind, ScreenInputOptions, ScreenLoadContext, ScreenParams, ScreenViewContext } from './screen-types.js';
|
|
28
|
+
import { TelegramScreen } from './screen-types.js';
|
|
29
|
+
import { type ScreenViewResult } from './view.js';
|
|
30
|
+
/** A schema for an action's input: an object whose fields a button can carry. */
|
|
31
|
+
export type ActionInputSchema = z.ZodType<Readonly<Record<string, unknown>>, Readonly<Record<string, ActionValue | undefined>>>;
|
|
32
|
+
/** A schema for the params a path segment adds: one field per `:name`. */
|
|
33
|
+
export type ParamsSchemaFor<TPath extends string> = z.ZodType<{
|
|
34
|
+
readonly [K in keyof ScreenPathParams<TPath>]: string | number;
|
|
35
|
+
}, {
|
|
36
|
+
readonly [K in keyof ScreenPathParams<TPath>]: unknown;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* `S` when it accepts what it produces, else `never`. A button carries the
|
|
40
|
+
* parsed params, and the schema parses them again when it is pressed: a
|
|
41
|
+
* transform whose output its own input refuses — `z.string().transform(Number)`
|
|
42
|
+
* — would make every link to the screen stale. `z.coerce.number()` accepts it.
|
|
43
|
+
*/
|
|
44
|
+
export type AcceptsOwnOutput<S> = S extends z.ZodType<infer O, infer I> ? ([O] extends [I] ? S : never) : never;
|
|
45
|
+
export interface ScopeOptions<TSchema> {
|
|
46
|
+
/** Validates (and may coerce) the params this path adds — they come from a button. */
|
|
47
|
+
readonly params?: TSchema;
|
|
48
|
+
}
|
|
49
|
+
export interface ScreenOptions<TSchema> extends ScopeOptions<TSchema> {
|
|
50
|
+
/**
|
|
51
|
+
* The id buttons carry instead of the path. Set it to keep buttons already
|
|
52
|
+
* sent working after the path is renamed. Default: derived from the path.
|
|
53
|
+
*/
|
|
54
|
+
readonly id?: string;
|
|
55
|
+
}
|
|
56
|
+
/** What a scope — the root, or a group — hands the screens declared in it. */
|
|
57
|
+
export interface ScopeCore<C extends Context, P extends ScreenParams, D> {
|
|
58
|
+
readonly prefix: string;
|
|
59
|
+
readonly paramNames: readonly string[];
|
|
60
|
+
readonly parseParams: (raw: Readonly<Record<string, ActionValue>>) => P | undefined;
|
|
61
|
+
readonly load: (ctx: C, params: P) => Promise<D | ScreenOutcome>;
|
|
62
|
+
readonly guarded: boolean;
|
|
63
|
+
}
|
|
64
|
+
interface HandlerBase<C extends Context, P extends ScreenParams, D> {
|
|
65
|
+
readonly ctx: C;
|
|
66
|
+
readonly params: P;
|
|
67
|
+
readonly data: D;
|
|
68
|
+
}
|
|
69
|
+
type ActionEntry<C extends Context, P extends ScreenParams, D> = (base: HandlerBase<C, P, D>, input: Readonly<Record<string, ActionValue>> | undefined) => Promise<ScreenOutcome | undefined | 'invalid-input'>;
|
|
70
|
+
type InputEntry<C extends Context, P extends ScreenParams, D> = {
|
|
71
|
+
readonly keepMessage: boolean;
|
|
72
|
+
readonly handler: (c: ScreenInputContext<C, P, D>) => ScreenHandlerResult;
|
|
73
|
+
};
|
|
74
|
+
/** A screen after `load` (or without one): actions, input and the view. */
|
|
75
|
+
export declare class ScreenBodyBuilder<C extends Context, P extends ScreenParams, D, A extends ScreenActions> {
|
|
76
|
+
protected readonly core: ScopeCore<C, P, D>;
|
|
77
|
+
protected readonly id: {
|
|
78
|
+
readonly value: string;
|
|
79
|
+
readonly explicit: boolean;
|
|
80
|
+
};
|
|
81
|
+
protected readonly actions: ReadonlyMap<string, ActionEntry<C, P, D>>;
|
|
82
|
+
protected readonly inputs: ReadonlyMap<ScreenInputKind, InputEntry<C, P, D>>;
|
|
83
|
+
constructor(core: ScopeCore<C, P, D>, id: {
|
|
84
|
+
readonly value: string;
|
|
85
|
+
readonly explicit: boolean;
|
|
86
|
+
}, actions: ReadonlyMap<string, ActionEntry<C, P, D>>, inputs: ReadonlyMap<ScreenInputKind, InputEntry<C, P, D>>);
|
|
87
|
+
/** A button handler. Its button is `act.<name>(label)`. */
|
|
88
|
+
action<N extends string>(name: N, handler: (c: ScreenActionContext<C, P, D, undefined>) => ScreenHandlerResult): ScreenBodyBuilder<C, P, D, A & {
|
|
89
|
+
readonly [K in N]: NoActionInput;
|
|
90
|
+
}>;
|
|
91
|
+
/** A button handler with typed input. Its button is `act.<name>(label, input)`. */
|
|
92
|
+
action<N extends string, S extends ActionInputSchema>(name: N, schema: S, handler: (c: ScreenActionContext<C, P, D, z.output<S>>) => ScreenHandlerResult): ScreenBodyBuilder<C, P, D, A & {
|
|
93
|
+
readonly [K in N]: z.input<S>;
|
|
94
|
+
}>;
|
|
95
|
+
/**
|
|
96
|
+
* Messages of these kinds, while this screen is shown. Other kinds, and
|
|
97
|
+
* commands, go to the next handler.
|
|
98
|
+
*/
|
|
99
|
+
on(kinds: ScreenInputKind | readonly ScreenInputKind[], handler: (c: ScreenInputContext<C, P, D>) => ScreenHandlerResult, options?: ScreenInputOptions): ScreenBodyBuilder<C, P, D, A>;
|
|
100
|
+
/** What the chat shows. Ends the declaration. */
|
|
101
|
+
view(render: (c: ScreenViewContext<C, P, D, A>) => ScreenViewResult): TelegramScreen<C, P, D, A>;
|
|
102
|
+
}
|
|
103
|
+
/** A screen before `load`: it may still load data. */
|
|
104
|
+
export declare class ScreenBuilder<C extends Context, P extends ScreenParams, D> extends ScreenBodyBuilder<C, P, D, Record<never, never>> {
|
|
105
|
+
/**
|
|
106
|
+
* The data this screen shows and its actions act on. Runs before every show,
|
|
107
|
+
* every action and every input, after the group's load, whose data it reads
|
|
108
|
+
* as `c.data`. Return an outcome instead of data to go somewhere else.
|
|
109
|
+
*/
|
|
110
|
+
load<R>(fetch: (c: ScreenLoadContext<C, P, D>) => MaybePromise<R>): ScreenBodyBuilder<C, P, Exclude<R, ScreenOutcome>, Record<never, never>>;
|
|
111
|
+
}
|
|
112
|
+
/** Where screens are declared: the root, or a group of them. */
|
|
113
|
+
export declare class ScreenScope<C extends Context, P extends ScreenParams, D> {
|
|
114
|
+
protected readonly core: ScopeCore<C, P, D>;
|
|
115
|
+
constructor(core: ScopeCore<C, P, D>);
|
|
116
|
+
/** A screen at `path`, relative to this scope. */
|
|
117
|
+
screen<TPath extends string>(path: TPath, options?: ScreenOptions<undefined>): ScreenBuilder<C, P & ScreenPathParams<TPath>, D>;
|
|
118
|
+
screen<TPath extends string, S extends ParamsSchemaFor<TPath>>(path: TPath, options: ScreenOptions<S> & {
|
|
119
|
+
readonly params: S & AcceptsOwnOutput<S>;
|
|
120
|
+
}): ScreenBuilder<C, P & z.output<S>, D>;
|
|
121
|
+
/** Screens that share a path prefix, its params and — once `load` is called — a load. */
|
|
122
|
+
group<TPath extends string>(path: TPath, options?: ScopeOptions<undefined>): ScreenGroupBuilder<C, P & ScreenPathParams<TPath>, D>;
|
|
123
|
+
group<TPath extends string, S extends ParamsSchemaFor<TPath>>(path: TPath, options: ScopeOptions<S> & {
|
|
124
|
+
readonly params: S & AcceptsOwnOutput<S>;
|
|
125
|
+
}): ScreenGroupBuilder<C, P & z.output<S>, D>;
|
|
126
|
+
}
|
|
127
|
+
/** A group before `load`. */
|
|
128
|
+
export declare class ScreenGroupBuilder<C extends Context, P extends ScreenParams, D> extends ScreenScope<C, P, D> {
|
|
129
|
+
/**
|
|
130
|
+
* Runs before every screen of the group — before its load, its actions and
|
|
131
|
+
* its input. The place to check that the params are the user's to use.
|
|
132
|
+
*/
|
|
133
|
+
load<R>(fetch: (c: ScreenLoadContext<C, P, D>) => MaybePromise<R>): ScreenScope<C, P, Exclude<R, ScreenOutcome>>;
|
|
134
|
+
}
|
|
135
|
+
/** The root: no prefix, no params, nothing loaded. */
|
|
136
|
+
export declare function rootScopeCore<C extends Context>(): ScopeCore<C, Record<never, never>, undefined>;
|
|
137
|
+
export {};
|
|
138
|
+
//# sourceMappingURL=screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../../src/telegram/screens/screen.ts"],"names":[],"mappings":"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"}
|