@effect-ak/tg-bot-client 0.4.1 → 0.5.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/dist/index.js CHANGED
@@ -30,90 +30,70 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- BotFactoryService: () => BotFactoryService,
34
- BotFactoryServiceDefault: () => BotFactoryServiceDefault,
35
33
  BotResponse: () => BotResponse,
36
- BotUpdatePollerService: () => BotUpdatePollerService,
37
- BotUpdatesPollerServiceDefault: () => BotUpdatesPollerServiceDefault,
34
+ BotRunService: () => BotRunService,
35
+ BotUpdateHandlersTag: () => BotUpdateHandlersTag,
38
36
  MESSAGE_EFFECTS: () => MESSAGE_EFFECTS,
39
37
  defaultBaseUrl: () => defaultBaseUrl,
40
38
  isMessageEffect: () => isMessageEffect,
39
+ launchBot: () => launchBot,
41
40
  makeTgBotClient: () => makeTgBotClient,
42
41
  messageEffectIdCodes: () => messageEffectIdCodes,
43
42
  runTgChatBot: () => runTgChatBot
44
43
  });
45
44
  module.exports = __toCommonJS(src_exports);
46
45
 
47
- // src/bot/factory/_service.ts
46
+ // src/bot/internal/launch.ts
48
47
  var Micro6 = __toESM(require("effect/Micro"));
49
- var Context4 = __toESM(require("effect/Context"));
48
+ var Context6 = __toESM(require("effect/Context"));
50
49
 
51
- // src/bot/message-handler/_service.ts
50
+ // src/client/config.ts
52
51
  var Context = __toESM(require("effect/Context"));
53
- var BotMessageHandler = class extends Context.Tag("BotMessageHandler")() {
54
- };
55
-
56
- // src/bot/update-poller/_service.ts
57
- var Micro4 = __toESM(require("effect/Micro"));
58
- var Context3 = __toESM(require("effect/Context"));
59
52
 
60
- // src/bot/update-poller/poll-updates.ts
61
- var Micro3 = __toESM(require("effect/Micro"));
53
+ // src/const.ts
54
+ var defaultBaseUrl = "https://api.telegram.org";
55
+ var MESSAGE_EFFECTS = {
56
+ "\u{1F525}": "5104841245755180586",
57
+ "\u{1F44D}": "5107584321108051014",
58
+ "\u{1F44E}": "5104858069142078462",
59
+ "\u2764\uFE0F": "5159385139981059251",
60
+ "\u{1F389}": "5046509860389126442",
61
+ "\u{1F4A9}": "5046589136895476101"
62
+ };
63
+ var messageEffectIdCodes = Object.keys(MESSAGE_EFFECTS);
64
+ var isMessageEffect = (input) => {
65
+ return typeof input === "string" && input in MESSAGE_EFFECTS;
66
+ };
62
67
 
63
- // src/bot/update-poller/settings.ts
64
- var makeSettingsFrom = (input) => {
65
- let limit = input.batch_size ?? 10;
66
- let timeout = input.timeout ?? 10;
67
- let max_empty_responses = input.max_empty_responses;
68
- let log_level = input.log_level;
69
- let on_error = input.on_error;
70
- if (limit < 10 || limit > 100) {
71
- console.warn("Wrong limit, must be in [10..100], using 10 instead");
72
- limit = 10;
73
- }
74
- if (timeout < 2 || timeout > 10) {
75
- console.warn("Wrong timeout, must be in [2..10], using 2 instead");
76
- limit = 10;
77
- }
78
- if (max_empty_responses && max_empty_responses < 2) {
79
- console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
80
- max_empty_responses = void 0;
81
- }
82
- if (max_empty_responses && max_empty_responses < 2) {
83
- console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
84
- max_empty_responses = void 0;
85
- }
86
- if (!log_level) {
87
- log_level = "info";
88
- }
89
- if (!on_error) {
90
- on_error = "stop";
91
- }
92
- const config = {
93
- limit,
94
- timeout,
95
- max_empty_responses,
96
- log_level,
97
- on_error
98
- };
99
- console.log("bot configuration", config);
100
- return config;
68
+ // src/client/config.ts
69
+ var makeTgBotClientConfig = (input) => TgBotClientConfig.of({
70
+ ...input,
71
+ base_url: input.base_url ?? defaultBaseUrl
72
+ });
73
+ var TgBotClientConfig = class extends Context.Tag("TgBotClientConfig")() {
101
74
  };
102
75
 
103
- // src/bot/update-poller/fetch-and-handle.ts
104
- var Micro2 = __toESM(require("effect/Micro"));
76
+ // src/bot/internal/types.ts
105
77
  var Data = __toESM(require("effect/Data"));
106
-
107
- // src/bot/message-handler/types.ts
108
- var import_Data = require("effect/Data");
109
- var BotResponse = class _BotResponse extends (0, import_Data.TaggedClass)("BotResponse") {
78
+ var Context2 = __toESM(require("effect/Context"));
79
+ var BotResponse = class _BotResponse extends Data.TaggedClass("BotResponse") {
110
80
  static make(result) {
111
81
  return new _BotResponse({ response: result });
112
82
  }
113
83
  static ignore = new _BotResponse({});
114
84
  };
85
+ var BotUpdateHandlersTag = class extends Context2.Tag("BotUpdateHandlers")() {
86
+ };
87
+
88
+ // src/bot/service/run.ts
89
+ var Micro4 = __toESM(require("effect/Micro"));
90
+ var Context5 = __toESM(require("effect/Context"));
91
+
92
+ // src/bot/internal/handle-update.ts
93
+ var Micro2 = __toESM(require("effect/Micro"));
94
+ var Data3 = __toESM(require("effect/Data"));
115
95
 
116
- // src/bot/message-handler/utils.ts
96
+ // src/bot/internal/utils.ts
117
97
  var extractUpdate = (input) => {
118
98
  for (const [field, value] of Object.entries(input)) {
119
99
  if (field == "update_id") {
@@ -132,8 +112,8 @@ var Micro = __toESM(require("effect/Micro"));
132
112
  var String = __toESM(require("effect/String"));
133
113
 
134
114
  // src/client/errors.ts
135
- var import_Data2 = require("effect/Data");
136
- var TgBotClientError = class _TgBotClientError extends (0, import_Data2.TaggedError)("TgBotClientError") {
115
+ var import_Data = require("effect/Data");
116
+ var TgBotClientError = class _TgBotClientError extends (0, import_Data.TaggedError)("TgBotClientError") {
137
117
  static missingSuccess = new _TgBotClientError({
138
118
  reason: {
139
119
  type: "ClientInternalError",
@@ -142,32 +122,6 @@ var TgBotClientError = class _TgBotClientError extends (0, import_Data2.TaggedEr
142
122
  });
143
123
  };
144
124
 
145
- // src/client/config.ts
146
- var Context2 = __toESM(require("effect/Context"));
147
-
148
- // src/const.ts
149
- var defaultBaseUrl = "https://api.telegram.org";
150
- var MESSAGE_EFFECTS = {
151
- "\u{1F525}": "5104841245755180586",
152
- "\u{1F44D}": "5107584321108051014",
153
- "\u{1F44E}": "5104858069142078462",
154
- "\u2764\uFE0F": "5159385139981059251",
155
- "\u{1F389}": "5046509860389126442",
156
- "\u{1F4A9}": "5046589136895476101"
157
- };
158
- var messageEffectIdCodes = Object.keys(MESSAGE_EFFECTS);
159
- var isMessageEffect = (input) => {
160
- return typeof input === "string" && input in MESSAGE_EFFECTS;
161
- };
162
-
163
- // src/client/config.ts
164
- var makeTgBotClientConfig = (input) => TgBotClientConfig.of({
165
- ...input,
166
- base_url: input.base_url ?? defaultBaseUrl
167
- });
168
- var TgBotClientConfig = class extends Context2.Tag("TgBotClientConfig")() {
169
- };
170
-
171
125
  // src/client/guards.ts
172
126
  var isFileContent = (input) => typeof input == "object" && input != null && ("file_content" in input && input.file_content instanceof Uint8Array) && ("file_name" in input && typeof input.file_name == "string");
173
127
  var isTgBotApiResponse = (input) => typeof input == "object" && input != null && ("ok" in input && typeof input.ok == "boolean");
@@ -229,55 +183,129 @@ var execute = (method, input) => Micro.gen(function* () {
229
183
  return response.result;
230
184
  });
231
185
 
232
- // src/bot/update-poller/fetch-and-handle.ts
233
- var HandleUpdateError = class extends Data.TaggedError("HandleUpdateError") {
186
+ // src/bot/internal/poll-settings.ts
187
+ var Context3 = __toESM(require("effect/Context"));
188
+ var Data2 = __toESM(require("effect/Data"));
189
+ var BotPollSettings = class _BotPollSettings extends Data2.Class {
190
+ static make(input) {
191
+ let batch_size = input.batch_size ?? 10;
192
+ let poll_timeout = input.poll_timeout ?? 10;
193
+ let max_empty_responses = input.max_empty_responses;
194
+ let log_level = input.log_level ?? "info";
195
+ let on_error = input.on_error;
196
+ if (batch_size < 10 || batch_size > 100) {
197
+ console.warn("Wrong batch_size, must be in [10..100], using 10 instead");
198
+ batch_size = 10;
199
+ }
200
+ if (poll_timeout < 2 || poll_timeout > 10) {
201
+ console.warn("Wrong poll_timeout, must be in [2..10], using 2 instead");
202
+ poll_timeout = 10;
203
+ }
204
+ if (max_empty_responses && max_empty_responses < 2) {
205
+ console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity");
206
+ max_empty_responses = void 0;
207
+ }
208
+ if (!log_level) {
209
+ log_level = "info";
210
+ }
211
+ if (!on_error) {
212
+ on_error = "stop";
213
+ }
214
+ const config = new _BotPollSettings({
215
+ batch_size,
216
+ poll_timeout,
217
+ max_empty_responses,
218
+ log_level,
219
+ on_error
220
+ });
221
+ console.log("bot poll settings", config);
222
+ return config;
223
+ }
234
224
  };
235
- var fetchAndHandle = ({ state, settings, handlers }) => Micro2.gen(function* () {
236
- const updateId = state.lastUpdateId;
237
- if (settings.log_level == "debug") {
238
- console.debug("getting updates", state);
225
+ var BotPollSettingsTag = class extends Context3.Reference()(
226
+ "BotSettings",
227
+ {
228
+ defaultValue() {
229
+ return BotPollSettings.make({});
230
+ }
239
231
  }
240
- const updates = yield* execute("get_updates", {
241
- ...settings,
242
- ...updateId ? { offset: updateId } : void 0
243
- }).pipe(
244
- Micro2.andThen((_) => _.sort((_2) => _2.update_id))
245
- );
246
- if (updates.length) {
247
- console.debug(`got a batch of updates (${updates.length})`);
232
+ ) {
233
+ };
234
+
235
+ // src/bot/internal/handle-update.ts
236
+ var BatchUpdateResult = class extends Data3.Class {
237
+ };
238
+ var handleUpdates = (updates) => Micro2.gen(function* () {
239
+ const pollSettings = yield* Micro2.service(BotPollSettingsTag);
240
+ const updateHandler = yield* Micro2.service(BotUpdateHandlersTag);
241
+ if (updateHandler.type == "single") {
242
+ return yield* handleOneByOne(updates, updateHandler, pollSettings);
243
+ } else {
244
+ return yield* handleEntireBatch(updates, updateHandler, pollSettings);
248
245
  }
249
- const lastUpdateId = updates.map((_) => _.update_id).sort().at(-1);
250
- if (!lastUpdateId) return { updates: [], lastUpdateId: void 0 };
251
- const hasError = yield* Micro2.forEach(
252
- updates,
253
- (update) => handleUpdate(update, settings, handlers).pipe(
254
- Micro2.catchAll((error) => {
255
- console.log("error", {
256
- updateId: update.update_id,
257
- updateKey: Object.keys(update).at(1),
258
- name: error._tag
259
- });
260
- return Micro2.succeed(void 0);
261
- })
262
- ),
263
- {
264
- concurrency: 10
246
+ });
247
+ var handleEntireBatch = (updates, handlers, pollSettings) => Micro2.try({
248
+ try: () => handlers.on_batch(updates),
249
+ catch: (_) => _
250
+ }).pipe(
251
+ Micro2.andThen((result) => {
252
+ if (result instanceof Promise) {
253
+ return Micro2.tryPromise({
254
+ try: () => result,
255
+ catch: (_) => _
256
+ });
257
+ } else {
258
+ return Micro2.succeed(result);
265
259
  }
266
- ).pipe(
267
- Micro2.andThen((result) => result.every((error) => error == null))
268
- );
269
- if (lastUpdateId) {
270
- yield* execute("get_updates", {
271
- offset: lastUpdateId,
272
- limit: 0
260
+ }),
261
+ Micro2.andThen(
262
+ (doNext) => new BatchUpdateResult({
263
+ hasErrors: !doNext,
264
+ updates
265
+ })
266
+ ),
267
+ Micro2.catchAll((error) => {
268
+ console.log("handle batch error", {
269
+ errorMessage: error instanceof Error ? error.message : void 0,
270
+ updates: updates.map((_) => Object.keys(_).at(1))
273
271
  });
274
- if (settings.log_level == "debug") {
275
- console.debug("committed offset", lastUpdateId);
276
- }
272
+ return Micro2.succeed(
273
+ new BatchUpdateResult({
274
+ hasErrors: true,
275
+ updates
276
+ })
277
+ );
278
+ })
279
+ );
280
+ var HandleUpdateError = class extends Data3.TaggedError("HandleUpdateError") {
281
+ };
282
+ var handleOneByOne = (updates, handlers, pollSettings) => Micro2.forEach(
283
+ updates,
284
+ (update) => handleOneUpdate(update, handlers).pipe(
285
+ Micro2.catchAll((error) => {
286
+ console.log("update handle error", {
287
+ updateId: update.update_id,
288
+ updateKey: Object.keys(update).at(1),
289
+ name: error._tag
290
+ });
291
+ return Micro2.succeed(error);
292
+ })
293
+ ),
294
+ {
295
+ concurrency: 10
277
296
  }
278
- return { updates, lastUpdateId, hasError };
279
- });
280
- var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* () {
297
+ ).pipe(
298
+ Micro2.andThen((batchResult) => {
299
+ if (pollSettings.log_level == "debug") {
300
+ console.debug("handle batch result", batchResult);
301
+ }
302
+ return new BatchUpdateResult({
303
+ hasErrors: !batchResult.every((error) => error == null),
304
+ updates
305
+ });
306
+ })
307
+ );
308
+ var handleOneUpdate = (updateObject, handlers) => Micro2.gen(function* () {
281
309
  const update = extractUpdate(updateObject);
282
310
  if (!update) {
283
311
  return yield* Micro2.fail(
@@ -287,8 +315,8 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
287
315
  })
288
316
  );
289
317
  }
290
- const handler = handlers[`on_${update.type}`];
291
- if (!handler) {
318
+ const updateHandler = handlers[`on_${update.type}`];
319
+ if (!updateHandler) {
292
320
  return yield* Micro2.fail(
293
321
  new HandleUpdateError({
294
322
  name: "HandlerNotDefined",
@@ -305,7 +333,7 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
305
333
  }
306
334
  let handleUpdateError;
307
335
  const handleResult = yield* Micro2.try({
308
- try: () => handler(update),
336
+ try: () => updateHandler(update),
309
337
  catch: (error) => new HandleUpdateError({
310
338
  name: "BotHandlerError",
311
339
  update: updateObject,
@@ -327,6 +355,11 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
327
355
  }),
328
356
  Micro2.catchAll((error) => {
329
357
  handleUpdateError = error;
358
+ console.log("error", {
359
+ updateId: updateObject.update_id,
360
+ updateKey: Object.keys(update).at(1),
361
+ name: error._tag
362
+ });
330
363
  return Micro2.succeed(
331
364
  BotResponse.make({
332
365
  type: "message",
@@ -341,7 +374,8 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
341
374
  );
342
375
  })
343
376
  );
344
- if (!handleResult && settings.log_level == "debug") {
377
+ const pollSettings = yield* Micro2.service(BotPollSettingsTag);
378
+ if (!handleResult && pollSettings.log_level == "debug") {
345
379
  console.log(`Bot response is undefined for update with ID #${updateObject.update_id}.`);
346
380
  return;
347
381
  }
@@ -351,87 +385,144 @@ var handleUpdate = (updateObject, settings, handlers) => Micro2.gen(function* ()
351
385
  ...handleResult.response,
352
386
  chat_id: update.chat.id
353
387
  });
354
- if (settings.log_level == "debug" && "text") {
388
+ if (pollSettings.log_level == "debug" && "text") {
355
389
  console.debug("bot response", response);
356
390
  }
357
391
  }
358
392
  return handleUpdateError;
359
393
  });
360
394
 
361
- // src/bot/update-poller/poll-updates.ts
362
- var pollUpdates = (input) => {
363
- const state = {
364
- lastUpdateId: void 0,
365
- emptyResponses: 0
366
- };
367
- const settings = makeSettingsFrom(input.settings);
368
- return Micro3.delay(1e3)(
369
- fetchAndHandle({
370
- state,
371
- settings,
372
- handlers: input.settings
373
- })
374
- ).pipe(
375
- Micro3.repeat({
376
- while: ({ updates, lastUpdateId, hasError }) => {
377
- if (hasError === true && settings.on_error == "stop") {
378
- console.info("Could not handle some messages, quitting");
379
- return false;
380
- }
381
- if (updates.length == 0) {
382
- state.emptyResponses += 1;
383
- if (settings.max_empty_responses && state.emptyResponses > settings.max_empty_responses) {
384
- console.info("too many empty responses, quitting");
385
- return false;
386
- }
387
- } else {
388
- state.emptyResponses = 0;
389
- }
390
- ;
391
- if (lastUpdateId) {
392
- state.lastUpdateId = lastUpdateId + 1;
393
- }
394
- return true;
395
- }
396
- })
397
- );
395
+ // src/bot/service/fetch-updates.ts
396
+ var Micro3 = __toESM(require("effect/Micro"));
397
+ var Data4 = __toESM(require("effect/Data"));
398
+ var Context4 = __toESM(require("effect/Context"));
399
+ var BotFetchUpdatesService = class extends Context4.Reference()(
400
+ "BotFetchUpdatesService",
401
+ {
402
+ defaultValue: () => {
403
+ const state = {
404
+ lastUpdateId: void 0,
405
+ emptyResponses: 0
406
+ };
407
+ const fetchUpdates = _fetchUpdates(state).pipe(
408
+ Micro3.tap((updates) => {
409
+ const id = updates.map((_) => _.update_id).sort().at(-1);
410
+ console.log("updating last update id", id);
411
+ state.lastUpdateId = id ? id + 1 : void 0;
412
+ console.log(state);
413
+ })
414
+ );
415
+ const commit = _commitLastBatch(state);
416
+ return {
417
+ state,
418
+ fetchUpdates,
419
+ commit
420
+ };
421
+ }
422
+ }
423
+ ) {
398
424
  };
399
-
400
- // src/bot/update-poller/_service.ts
401
- var BotUpdatePollerService = class extends Context3.Tag("BotUpdatePollerService")() {
425
+ var FetchUpdatesError = class extends Data4.TaggedError("FetchUpdatesError") {
402
426
  };
403
- var BotUpdatesPollerServiceDefault = Micro4.gen(function* () {
404
- console.log("Initiating BotUpdatesPollerServiceDefault");
405
- const state = {
406
- fiber: void 0
407
- };
408
- const runBot = Micro4.gen(function* () {
409
- console.log("run bot");
410
- const messageHandler = yield* Micro4.service(BotMessageHandler);
411
- const startFiber = pollUpdates({
412
- settings: messageHandler
427
+ var _fetchUpdates = (pollState) => Micro3.gen(function* () {
428
+ const pollSettings = yield* Micro3.service(BotPollSettingsTag);
429
+ if (pollSettings.max_empty_responses && pollState.emptyResponses == pollSettings.max_empty_responses) {
430
+ return yield* Micro3.fail(
431
+ new FetchUpdatesError({ name: "TooManyEmptyResponses" })
432
+ );
433
+ }
434
+ const updateId = pollState.lastUpdateId;
435
+ if (pollSettings.log_level == "debug") {
436
+ console.debug("getting updates", pollState);
437
+ }
438
+ const updates = yield* execute("get_updates", {
439
+ timeout: pollSettings.poll_timeout,
440
+ ...updateId ? { offset: updateId } : void 0
441
+ }).pipe(
442
+ Micro3.andThen((_) => _.sort((_2) => _2.update_id))
443
+ );
444
+ if (updates.length) {
445
+ console.debug(`got a batch of updates (${updates.length})`);
446
+ pollState.emptyResponses = 0;
447
+ return updates;
448
+ } else {
449
+ pollState.emptyResponses += 1;
450
+ return [];
451
+ }
452
+ });
453
+ var _commitLastBatch = (pollState) => Micro3.gen(function* () {
454
+ console.log("commit", { pollState });
455
+ if (pollState.lastUpdateId) {
456
+ return yield* execute("get_updates", {
457
+ offset: pollState.lastUpdateId,
458
+ limit: 0
413
459
  }).pipe(
414
- Micro4.forkDaemon,
415
- Micro4.tap(
416
- (fiber) => fiber.addObserver((exit) => {
417
- console.log("bot's fiber has been closed", exit);
460
+ Micro3.andThen(
461
+ Micro3.andThen(Micro3.service(BotPollSettingsTag), (pollSettings) => {
462
+ if (pollSettings.log_level == "debug") {
463
+ console.debug("committed offset", pollState);
464
+ }
418
465
  })
419
466
  )
420
467
  );
421
- if (state.fiber) {
422
- console.log("killing previous bot's fiber");
423
- yield* Micro4.fiberInterrupt(state.fiber);
468
+ } else {
469
+ return yield* Micro3.fail(new FetchUpdatesError({
470
+ name: "NoUpdatesToCommit"
471
+ }));
472
+ }
473
+ });
474
+
475
+ // src/bot/service/run.ts
476
+ var BotRunService = class extends Context5.Reference()(
477
+ "BotRunService",
478
+ {
479
+ defaultValue: () => {
480
+ console.log("Initiating BotRunService");
481
+ const state = {
482
+ fiber: void 0
483
+ };
484
+ const runBotInBackground = _runBotDaemon(state);
485
+ const getFiber = () => state.fiber;
486
+ return {
487
+ runBotInBackground,
488
+ getFiber
489
+ };
424
490
  }
425
- state.fiber = yield* startFiber;
426
- console.log("Fetching bot updates via long polling...");
427
- });
428
- return {
429
- runBot,
430
- getFiber: () => state.fiber
431
- };
491
+ }
492
+ ) {
493
+ };
494
+ var _runBotDaemon = (state) => Micro4.gen(function* () {
495
+ console.log("run bot");
496
+ const fetchService = yield* Micro4.service(BotFetchUpdatesService);
497
+ const startFiber = Micro4.delay(1e3)(
498
+ fetchService.fetchUpdates.pipe(
499
+ Micro4.andThen(
500
+ (updates) => handleUpdates(updates)
501
+ ),
502
+ Micro4.tap(
503
+ ({ updates }) => updates.length > 0 ? fetchService.commit : Micro4.void
504
+ )
505
+ )
506
+ ).pipe(
507
+ Micro4.repeat({
508
+ while: (_) => !_.hasErrors
509
+ }),
510
+ Micro4.forkDaemon,
511
+ Micro4.tap(
512
+ (fiber) => fiber.addObserver((exit) => {
513
+ console.log("bot's fiber has been closed", exit);
514
+ })
515
+ )
516
+ );
517
+ if (state.fiber) {
518
+ console.log("killing previous bot's fiber");
519
+ yield* Micro4.fiberInterrupt(state.fiber);
520
+ }
521
+ state.fiber = yield* startFiber;
522
+ console.log("Fetching bot updates via long polling...");
432
523
  });
433
524
 
434
- // src/bot/factory/client-config.ts
525
+ // src/bot/internal/client-config.ts
435
526
  var Micro5 = __toESM(require("effect/Micro"));
436
527
  var makeClientConfigFrom = (input) => Micro5.gen(function* () {
437
528
  if (input.type == "config") {
@@ -453,35 +544,29 @@ var makeClientConfigFrom = (input) => Micro5.gen(function* () {
453
544
  return makeTgBotClientConfig(config);
454
545
  });
455
546
 
456
- // src/bot/factory/_service.ts
457
- var BotFactoryService = class extends Context4.Tag("BotFactoryService")() {
458
- };
459
- var BotFactoryServiceDefault = {
460
- runBot: (input) => Micro6.gen(function* () {
461
- const client = Context4.make(TgBotClientConfig, yield* makeClientConfigFrom(input));
462
- const poller = yield* BotUpdatesPollerServiceDefault.pipe(
463
- Micro6.provideContext(client)
464
- );
465
- yield* poller.runBot.pipe(
466
- Micro6.provideService(BotMessageHandler, input),
467
- Micro6.provideContext(client)
468
- );
469
- const reload = (input2) => poller.runBot.pipe(
470
- Micro6.provideService(BotMessageHandler, input2),
471
- Micro6.provideContext(client),
472
- Micro6.runPromise
473
- );
474
- return {
475
- reload,
476
- fiber: poller.getFiber
477
- };
478
- })
479
- };
547
+ // src/bot/internal/launch.ts
548
+ var launchBot = (input) => Micro6.gen(function* () {
549
+ const clientConfig = Context6.make(TgBotClientConfig, yield* makeClientConfigFrom(input));
550
+ const service8 = yield* Micro6.service(BotRunService);
551
+ yield* service8.runBotInBackground.pipe(
552
+ Micro6.provideContext(clientConfig),
553
+ Micro6.provideService(BotUpdateHandlersTag, input.mode),
554
+ Micro6.provideService(BotPollSettingsTag, BotPollSettings.make(input.poll ?? {}))
555
+ );
556
+ const reload = (mode) => service8.runBotInBackground.pipe(
557
+ Micro6.provideService(BotUpdateHandlersTag, mode),
558
+ Micro6.provideContext(clientConfig),
559
+ Micro6.runPromise
560
+ );
561
+ return {
562
+ reload,
563
+ fiber: service8.getFiber
564
+ };
565
+ });
480
566
 
481
567
  // src/bot/run.ts
482
568
  var Micro7 = __toESM(require("effect/Micro"));
483
- var runTgChatBot = (input) => BotFactoryServiceDefault.runBot(input).pipe(
484
- Micro7.provideService(BotMessageHandler, input),
569
+ var runTgChatBot = (input) => launchBot(input).pipe(
485
570
  Micro7.runPromise
486
571
  );
487
572
 
@@ -490,7 +575,7 @@ var Micro10 = __toESM(require("effect/Micro"));
490
575
 
491
576
  // src/client/file/_service.ts
492
577
  var Micro9 = __toESM(require("effect/Micro"));
493
- var Context5 = __toESM(require("effect/Context"));
578
+ var Context7 = __toESM(require("effect/Context"));
494
579
 
495
580
  // src/client/file/get-file.ts
496
581
  var Micro8 = __toESM(require("effect/Micro"));
@@ -521,7 +606,7 @@ var getFile = (fileId) => Micro8.gen(function* () {
521
606
  });
522
607
 
523
608
  // src/client/file/_service.ts
524
- var ClientFileService = class extends Context5.Tag("ClientFileService")() {
609
+ var ClientFileService = class extends Context7.Tag("ClientFileService")() {
525
610
  };
526
611
  var ClientFileServiceDefault = Micro9.gen(function* () {
527
612
  return {
@@ -553,14 +638,13 @@ var makeTgBotClient = (input) => {
553
638
  };
554
639
  // Annotate the CommonJS export names for ESM import in node:
555
640
  0 && (module.exports = {
556
- BotFactoryService,
557
- BotFactoryServiceDefault,
558
641
  BotResponse,
559
- BotUpdatePollerService,
560
- BotUpdatesPollerServiceDefault,
642
+ BotRunService,
643
+ BotUpdateHandlersTag,
561
644
  MESSAGE_EFFECTS,
562
645
  defaultBaseUrl,
563
646
  isMessageEffect,
647
+ launchBot,
564
648
  makeTgBotClient,
565
649
  messageEffectIdCodes,
566
650
  runTgChatBot