@teactjs/runtime 0.1.0-alpha.1

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.
Files changed (64) hide show
  1. package/README.md +336 -0
  2. package/dist/index.js +23117 -0
  3. package/dist/react/src/callback-registry.d.ts +11 -0
  4. package/dist/react/src/callback-registry.d.ts.map +1 -0
  5. package/dist/react/src/components.d.ts +396 -0
  6. package/dist/react/src/components.d.ts.map +1 -0
  7. package/dist/react/src/error-boundary.d.ts +19 -0
  8. package/dist/react/src/error-boundary.d.ts.map +1 -0
  9. package/dist/react/src/hooks.d.ts +37 -0
  10. package/dist/react/src/hooks.d.ts.map +1 -0
  11. package/dist/react/src/index.d.ts +11 -0
  12. package/dist/react/src/index.d.ts.map +1 -0
  13. package/dist/renderer/src/index.d.ts +5 -0
  14. package/dist/renderer/src/index.d.ts.map +1 -0
  15. package/dist/renderer/src/nodes.d.ts +23 -0
  16. package/dist/renderer/src/nodes.d.ts.map +1 -0
  17. package/dist/renderer/src/renderer.d.ts +9 -0
  18. package/dist/renderer/src/renderer.d.ts.map +1 -0
  19. package/dist/renderer/src/types.d.ts +36 -0
  20. package/dist/renderer/src/types.d.ts.map +1 -0
  21. package/dist/runtime/src/auth-session.d.ts +51 -0
  22. package/dist/runtime/src/auth-session.d.ts.map +1 -0
  23. package/dist/runtime/src/auth.d.ts +37 -0
  24. package/dist/runtime/src/auth.d.ts.map +1 -0
  25. package/dist/runtime/src/bot.d.ts +143 -0
  26. package/dist/runtime/src/bot.d.ts.map +1 -0
  27. package/dist/runtime/src/config.d.ts +38 -0
  28. package/dist/runtime/src/config.d.ts.map +1 -0
  29. package/dist/runtime/src/context.d.ts +74 -0
  30. package/dist/runtime/src/context.d.ts.map +1 -0
  31. package/dist/runtime/src/conversation.d.ts +310 -0
  32. package/dist/runtime/src/conversation.d.ts.map +1 -0
  33. package/dist/runtime/src/event-hooks.d.ts +49 -0
  34. package/dist/runtime/src/event-hooks.d.ts.map +1 -0
  35. package/dist/runtime/src/i18n.d.ts +55 -0
  36. package/dist/runtime/src/i18n.d.ts.map +1 -0
  37. package/dist/runtime/src/index.d.ts +28 -0
  38. package/dist/runtime/src/index.d.ts.map +1 -0
  39. package/dist/runtime/src/invoice.d.ts +120 -0
  40. package/dist/runtime/src/invoice.d.ts.map +1 -0
  41. package/dist/runtime/src/media-hooks.d.ts +178 -0
  42. package/dist/runtime/src/media-hooks.d.ts.map +1 -0
  43. package/dist/runtime/src/middleware.d.ts +26 -0
  44. package/dist/runtime/src/middleware.d.ts.map +1 -0
  45. package/dist/runtime/src/plugin.d.ts +32 -0
  46. package/dist/runtime/src/plugin.d.ts.map +1 -0
  47. package/dist/runtime/src/router.d.ts +168 -0
  48. package/dist/runtime/src/router.d.ts.map +1 -0
  49. package/dist/runtime/src/session.d.ts +20 -0
  50. package/dist/runtime/src/session.d.ts.map +1 -0
  51. package/dist/runtime/src/stream.d.ts +34 -0
  52. package/dist/runtime/src/stream.d.ts.map +1 -0
  53. package/dist/telegram/src/adapter.d.ts +83 -0
  54. package/dist/telegram/src/adapter.d.ts.map +1 -0
  55. package/dist/telegram/src/conversations.d.ts +175 -0
  56. package/dist/telegram/src/conversations.d.ts.map +1 -0
  57. package/dist/telegram/src/index.d.ts +8 -0
  58. package/dist/telegram/src/index.d.ts.map +1 -0
  59. package/dist/telegram/src/serialize.d.ts +80 -0
  60. package/dist/telegram/src/serialize.d.ts.map +1 -0
  61. package/dist/telegram/src/stream.d.ts +12 -0
  62. package/dist/telegram/src/stream.d.ts.map +1 -0
  63. package/package.json +33 -0
  64. package/src/index.ts +64 -0
package/README.md ADDED
@@ -0,0 +1,336 @@
1
+ # @teactjs/runtime
2
+
3
+ The bot engine powering Teact. Provides `createBot`, routing, sessions, hooks, middleware, conversations, forms, streaming, authentication, events, i18n, and payments.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bun add @teactjs/runtime
9
+ ```
10
+
11
+ ## createBot
12
+
13
+ ```ts
14
+ import { createBot } from "@teactjs/runtime";
15
+ import { TelegramAdapter } from "@teactjs/telegram";
16
+
17
+ const bot = createBot({
18
+ component: App, // root component (or use `router`)
19
+ adapter: new TelegramAdapter(),
20
+ token: process.env.BOT_TOKEN,
21
+ mode: "polling", // "polling" | "webhook"
22
+ session: { ttl: 3600_000 },
23
+ plugins: [storagePlugin()],
24
+ commands: {
25
+ start: { description: "Start the bot", route: "/" },
26
+ help: { description: "Show help", handler: (ctx) => ctx.reply("Help text") },
27
+ },
28
+ });
29
+
30
+ await bot.start();
31
+ ```
32
+
33
+ **Options:** `component` or `router` (mutually exclusive), `adapter`, `token`, `mode`, `webhook` (`{ domain, port?, path?, secretToken? }`), `session` (`{ store?, ttl? }`), `middleware`, `plugins`, `commands`, `providers`, `experimental`.
34
+
35
+ ## Routing
36
+
37
+ ```ts
38
+ import { createRouter } from "@teactjs/runtime";
39
+
40
+ const router = createRouter(
41
+ {
42
+ "/": Home,
43
+ "/settings": { component: Settings, beforeLoad: guardAuth },
44
+ "/pokemon/:id": PokemonDetail,
45
+ },
46
+ { notFound: NotFoundPage }, // optional custom 404
47
+ );
48
+
49
+ const bot = createBot({ router, adapter, token });
50
+ ```
51
+
52
+ ### Route Guards
53
+
54
+ Guards run before a route loads. They can redirect, reply with a message, or render JSX:
55
+
56
+ ```ts
57
+ // Redirect
58
+ beforeLoad: ({ session }) => {
59
+ if (!session.auth) return redirect("/login");
60
+ }
61
+
62
+ // Reply with a message and buttons (same API as command handlers)
63
+ beforeLoad: ({ session, reply }) => {
64
+ if (!session.auth) return reply("Please log in.", {
65
+ buttons: [[{ text: "Login", route: "/login" }, { text: "Home", route: "/" }]],
66
+ });
67
+ }
68
+
69
+ // Return JSX directly
70
+ beforeLoad: ({ session }) => {
71
+ if (!session.auth) return <LoginPage />;
72
+ }
73
+ ```
74
+
75
+ ### Navigation Hooks
76
+
77
+ ```tsx
78
+ function Home() {
79
+ const navigate = useNavigate();
80
+ const { path, params } = useRoute();
81
+
82
+ return (
83
+ <Message text="Home">
84
+ <InlineKeyboard>
85
+ <Button text="Settings" onClick={() => navigate("/settings")} />
86
+ <Button text="Back" onClick={() => navigate("/", { mode: "dismiss" })} />
87
+ </InlineKeyboard>
88
+ </Message>
89
+ );
90
+ }
91
+ ```
92
+
93
+ - `useNavigate()` -- returns `(path, opts?) => void`. Modes: `push`, `replace`, `stack`, `dismiss`.
94
+ - `useParams<T>()` -- typed route params.
95
+ - `useRoute()` -- current `{ path, params }`.
96
+
97
+ ## Context Hooks
98
+
99
+ | Hook | Returns |
100
+ |------|---------|
101
+ | `useBot()` | Bot instance and metadata |
102
+ | `useSession()` | `[sessionData, patchFn]` -- read and update session |
103
+ | `usePlatform()` | Current platform string |
104
+ | `useChatId()` | Current chat ID |
105
+ | `useText()` | Last message text |
106
+ | `useCallbackData()` | Last callback query data |
107
+ | `useCommand()` | Parsed command and args |
108
+
109
+ ## Conversations
110
+
111
+ Multi-step user flows with validation.
112
+
113
+ ```tsx
114
+ const { step, value, actions } = useConversation({
115
+ name: { prompt: "What's your name?", validate: (v) => v.length > 0 || "Name required" },
116
+ age: { prompt: "How old are you?", validate: (v) => Number(v) > 0 || "Must be a number" },
117
+ });
118
+ ```
119
+
120
+ Declarative alternative:
121
+
122
+ ```tsx
123
+ <Conversation>
124
+ <Conversation.Prompt text="What's your name?" step="name" />
125
+ <Conversation.Prompt text="How old are you?" step="age" />
126
+ <Conversation.Complete>
127
+ {(data) => <Message text={`Hi ${data.name}, age ${data.age}`} />}
128
+ </Conversation.Complete>
129
+ </Conversation>
130
+ ```
131
+
132
+ ## Forms
133
+
134
+ Schema-driven forms with `useForm`:
135
+
136
+ ```tsx
137
+ const form = useForm({
138
+ name: { type: "string", required: true },
139
+ email: { type: "string", validate: validateEmail },
140
+ });
141
+ ```
142
+
143
+ ## Events
144
+
145
+ ```tsx
146
+ useOn("message:text", (ctx) => {
147
+ console.log("Text received:", ctx.raw);
148
+ });
149
+
150
+ const photo = useEventData("message:photo");
151
+ ```
152
+
153
+ Supported events include `message`, `message:text`, `message:photo`, `callback_query`, `pre_checkout_query`, `successful_payment`, and `*` for all events.
154
+
155
+ ## Media Hooks
156
+
157
+ Send media programmatically:
158
+
159
+ ```ts
160
+ const sendPhoto = usePhoto();
161
+ const sendVideo = useVideo();
162
+ const sendDocument = useDocument();
163
+ const sendVoice = useVoice();
164
+ const sendAudio = useAudio();
165
+ const sendSticker = useSticker();
166
+ const sendLocation = useLocation();
167
+ const sendContact = useContact();
168
+ const sendPoll = usePoll();
169
+ ```
170
+
171
+ Each returns an async function that calls the Telegram API directly.
172
+
173
+ ## Streaming
174
+
175
+ Real-time text updates:
176
+
177
+ ```tsx
178
+ const { text, isStreaming, stream } = useStream({ throttleMs: 100 });
179
+
180
+ async function handleStream() {
181
+ await stream(generateTokens());
182
+ }
183
+
184
+ return <Message text={isStreaming ? text : "Done: " + text} />;
185
+ ```
186
+
187
+ ## Authentication
188
+
189
+ ```ts
190
+ import { authPlugin, useAuth } from "@teactjs/runtime";
191
+
192
+ // Register the plugin
193
+ const bot = createBot({
194
+ plugins: [authPlugin({ admins: [123456789] })],
195
+ // ...
196
+ });
197
+
198
+ // In a component
199
+ function Admin() {
200
+ const { isAdmin, role, is, hasAny } = useAuth();
201
+ if (!isAdmin) return <Message text="Unauthorized" />;
202
+ return <Message text="Admin panel" />;
203
+ }
204
+ ```
205
+
206
+ ## Auth Sessions
207
+
208
+ Token-based auth backed by the session store:
209
+
210
+ ```tsx
211
+ import { useAuthSession } from "@teactjs/runtime";
212
+
213
+ function LoginPage() {
214
+ const auth = useAuthSession();
215
+
216
+ if (auth.isAuthenticated) {
217
+ return <Message text={`Welcome back! Token: ${auth.accessToken}`} />;
218
+ }
219
+
220
+ return (
221
+ <Message text="Please log in">
222
+ <InlineKeyboard>
223
+ <ButtonRow>
224
+ <Button
225
+ text="Login"
226
+ onClick={() => auth.login({ accessToken: "tok_abc", refreshToken: "ref_xyz" })}
227
+ />
228
+ </ButtonRow>
229
+ </InlineKeyboard>
230
+ </Message>
231
+ );
232
+ }
233
+ ```
234
+
235
+ - `auth.isAuthenticated` — `true` when a non-expired access token exists.
236
+ - `auth.login(tokens)` — store access/refresh tokens + optional `expiresAt`.
237
+ - `auth.logout()` — clear all auth data.
238
+ - `auth.setAccessToken(token, expiresAt?)` — update the token (e.g. after refresh).
239
+
240
+ ## i18n
241
+
242
+ ```ts
243
+ import { createI18n, useLocale } from "@teactjs/runtime";
244
+
245
+ const i18n = createI18n({
246
+ defaultLocale: "en",
247
+ resources: {
248
+ en: { greeting: "Hello {{name}}!" },
249
+ es: { greeting: "Hola {{name}}!" },
250
+ },
251
+ });
252
+
253
+ function Greeting() {
254
+ const { t, locale, setLocale } = useLocale();
255
+ return <Message text={t("greeting", { name: "World" })} />;
256
+ }
257
+ ```
258
+
259
+ ## Payments
260
+
261
+ ```tsx
262
+ const { send, status, receipt, error } = useInvoice({
263
+ title: "Premium Plan",
264
+ description: "Monthly subscription",
265
+ currency: "USD",
266
+ prices: [{ label: "Premium", amount: 999 }],
267
+ providerToken: process.env.PAYMENT_TOKEN,
268
+ });
269
+ ```
270
+
271
+ ## Middleware
272
+
273
+ Middleware runs on every update before rendering. `next()` is called automatically if your middleware doesn't call it, so simple middleware like loggers just work:
274
+
275
+ ```ts
276
+ const logger: Middleware = async (ctx) => {
277
+ console.log(`Update from ${ctx.chatId}: ${ctx.text}`);
278
+ };
279
+
280
+ const bot = createBot({
281
+ middleware: [logger],
282
+ // ...
283
+ });
284
+ ```
285
+
286
+ You can still call `next()` explicitly if you need to run code after the rest of the chain:
287
+
288
+ ```ts
289
+ const timer: Middleware = async (ctx, next) => {
290
+ const start = Date.now();
291
+ await next();
292
+ console.log(`Took ${Date.now() - start}ms`);
293
+ };
294
+ ```
295
+
296
+ ## Debugging
297
+
298
+ Enable verbose logging to diagnose stuck bots or network issues:
299
+
300
+ ```ts
301
+ const bot = createBot({
302
+ adapter: new TelegramAdapter(),
303
+ debug: true, // logs every update, render cycle, middleware execution
304
+ // ...
305
+ });
306
+ ```
307
+
308
+ ## Plugins
309
+
310
+ Implement the `TeactPlugin` interface:
311
+
312
+ ```ts
313
+ const myPlugin: TeactPlugin = {
314
+ name: "my-plugin",
315
+ onStart: (bot) => { /* setup */ },
316
+ middleware: (ctx, next) => { /* per-update */ return next(); },
317
+ Provider: ({ children }) => <MyContext.Provider>{children}</MyContext.Provider>,
318
+ onStop: () => { /* cleanup */ },
319
+ };
320
+ ```
321
+
322
+ ## Configuration
323
+
324
+ ```ts
325
+ import { defineConfig } from "@teactjs/runtime";
326
+
327
+ export default defineConfig({
328
+ plugins: [storagePlugin(), authPlugin()],
329
+ });
330
+ ```
331
+
332
+ ## See Also
333
+
334
+ - [`@teactjs/core`](../core) for the barrel import
335
+ - [`@teactjs/react`](../react) for UI components
336
+ - [`@teactjs/telegram`](../telegram) for the Telegram adapter