@effect-ak/tg-bot-client 0.6.4 → 1.1.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/README.md +294 -0
- package/dist/index.cjs +209 -0
- package/dist/index.d.cts +98 -0
- package/dist/index.d.ts +63 -28
- package/dist/index.js +169 -1
- package/package.json +19 -56
- package/src/client-file.ts +73 -0
- package/src/client.ts +34 -0
- package/src/config.ts +10 -0
- package/src/const.ts +20 -0
- package/src/errors.ts +18 -0
- package/src/execute.ts +81 -0
- package/src/guards.ts +27 -0
- package/src/index.ts +8 -0
- package/src/utils.ts +3 -0
- package/test/execute.test.ts +102 -0
- package/test/file.test.ts +23 -0
- package/test/fixture.ts +35 -0
- package/tsconfig.json +12 -0
- package/tsup.config.json +10 -0
- package/dist/bot-bundle.js +0 -22
- package/dist/bot-bundle.mjs +0 -22
- package/dist/bot.d.ts +0 -111
- package/dist/bot.js +0 -1
- package/dist/bot.mjs +0 -1
- package/dist/config-3uU0YevV.d.ts +0 -3250
- package/dist/index.mjs +0 -1
- package/dist/webapp.d.ts +0 -392
- package/dist/webapp.js +0 -1
- package/dist/webapp.mjs +0 -0
- package/readme.md +0 -236
package/dist/bot.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var ee=Object.create;var T=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty;var se=(e,o)=>{for(var t in o)T(e,t,{get:o[t],enumerable:!0})},P=(e,o,t,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of oe(o))!re.call(e,n)&&n!==t&&T(e,n,{get:()=>o[n],enumerable:!(r=te(o,n))||r.enumerable});return e};var c=(e,o,t)=>(t=e!=null?ee(ne(e)):{},P(o||!e||!e.__esModule?T(t,"default",{value:e,enumerable:!0}):t,e)),ie=e=>P(T({},"__esModule",{value:!0}),e);var me={};se(me,{BatchUpdateResult:()=>B,BotPollSettings:()=>x,BotPollSettingsTag:()=>m,BotResponse:()=>_,BotRunService:()=>U,BotUpdateHandlersTag:()=>g,HandleUpdateError:()=>M,defineBot:()=>le,extractUpdate:()=>z,handleEntireBatch:()=>V,handleOneByOne:()=>W,handleOneUpdate:()=>J,handleUpdates:()=>F,launchBot:()=>I,runTgChatBot:()=>de});module.exports=ie(me);var H=c(require("effect/Data")),_=class e extends H.TaggedClass("BotResponse"){static make(o){return new e({response:o})}static ignore=new e({})};var s=c(require("effect/Micro")),v=c(require("effect/Data")),A=c(require("effect/Function"));var K=c(require("effect/String")),u=c(require("effect/Micro"));var D=c(require("effect/Data")),y=class extends D.TaggedError("TgBotClientError"){};var $=e=>typeof e=="object"&&e!=null&&"file_content"in e&&e.file_content instanceof Uint8Array&&"file_name"in e&&typeof e.file_name=="string",N=e=>typeof e=="object"&&e!=null&&"ok"in e&&typeof e.ok=="boolean";var k=c(require("effect/Context"));var O="https://api.telegram.org",C={"\u{1F525}":"5104841245755180586","\u{1F44D}":"5107584321108051014","\u{1F44E}":"5104858069142078462","\u2764\uFE0F":"5159385139981059251","\u{1F389}":"5046509860389126442","\u{1F4A9}":"5046589136895476101"},Me=Object.keys(C);var E=class extends k.Reference()("TgBotApiBaseUrl",{defaultValue:()=>O}){},h=class extends k.Tag("TgBotApiToken")(){};var G=e=>{let o=Object.entries(e);if(o.length==0)return;let t=new FormData;for(let[r,n]of o)n&&(typeof n!="object"?t.append(r,`${n}`):$(n)?t.append(r,new Blob([n.file_content]),n.file_name):t.append(r,JSON.stringify(n)));return t};var b=(e,o)=>u.gen(function*(){let t=yield*u.service(h),r=yield*u.service(E),n=yield*u.tryPromise({try:()=>fetch(`${r}/bot${t}/${K.snakeToCamel(e)}`,{body:G(o)??null,method:"POST"}),catch:l=>new y({cause:{_tag:"ClientInternalError",cause:l}})}),i=yield*u.tryPromise({try:()=>n.json(),catch:()=>new y({cause:{_tag:"NotJsonResponse",response:n}})});return N(i)?n.ok?i.result:yield*u.fail(new y({cause:{_tag:"NotOkResponse",...i.error_code?{errorCode:i.error_code}:void 0,...i.description?{details:i.description}:void 0}})):yield*u.fail(new y({cause:{_tag:"UnexpectedResponse",response:i}}))});var R=c(require("effect/Context")),j=c(require("effect/Data")),g=class extends R.Tag("BotUpdateHandlers")(){},x=class e extends j.Class{static make(o){let t=o.batch_size??10,r=o.poll_timeout??10,n=o.max_empty_responses,i=o.log_level??"info",l=o.on_error;(t<10||t>100)&&(console.warn("Wrong batch_size, must be in [10..100], using 10 instead"),t=10),(r<2||r>120)&&(console.warn("Wrong poll_timeout, must be in [2..120], using 20 instead"),r=20),n&&n<2&&(console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity"),n=void 0),i||(i="info"),l||(l="stop");let p=new e({batch_size:t,poll_timeout:r,max_empty_responses:n,log_level:i,on_error:l});return console.log("bot poll settings",p),p}},m=class extends R.Reference()("BotSettings",{defaultValue(){return x.make({})}}){};var z=e=>{for(let[o,t]of Object.entries(e))if(o!="update_id")return{type:o,...t}},B=class extends v.Class{},F=e=>s.gen(function*(){let o=yield*s.service(m),t=yield*s.service(g);return t.type=="single"?yield*W(e,t,o):yield*V(e,t)}),V=(e,o)=>s.try({try:()=>o.on_batch(e),catch:A.identity}).pipe(s.andThen(t=>t instanceof Promise?s.tryPromise({try:()=>t,catch:A.identity}):s.succeed(t)),s.andThen(t=>new B({hasErrors:!t,updates:e})),s.catchAll(t=>(console.warn("handle batch error",{errorMessage:t instanceof Error?t.message:void 0,updates:e.map(r=>Object.keys(r).at(1)),error:t}),s.succeed(new B({hasErrors:!0,updates:e}))))),M=class extends v.TaggedError("HandleUpdateError"){},W=(e,o,t)=>s.forEach(e,r=>J(r,o).pipe(s.catchAll(n=>(console.log("update handle error",{updateId:r.update_id,updateKey:Object.keys(r).at(1),name:n._tag,...n.cause instanceof Error?{error:n.cause.message}:void 0}),s.succeed(n)))),{concurrency:10}).pipe(s.andThen(r=>(t.log_level=="debug"&&console.debug("handle batch result",r),new B({hasErrors:!r.every(n=>n==null),updates:e})))),J=(e,o)=>s.gen(function*(){let t=z(e);if(!t)return yield*s.fail(new M({name:"UnknownUpdate",update:e}));let r=o[`on_${t.type}`];if(!r)return yield*s.fail(new M({name:"HandlerNotDefined",update:e}));t.type=="message"&&"text"in t&&console.info("Got a new text message",{chatId:t.chat.id,chatType:t.chat.type,message:`${t.text.slice(0,5)}...`});let n,i=yield*s.try({try:()=>r(t),catch:p=>new M({name:"BotHandlerError",update:e,cause:p})}).pipe(s.andThen(p=>p instanceof Promise?s.tryPromise({try:()=>p,catch:Z=>new M({name:"BotHandlerError",update:e,cause:Z})}):s.succeed(p)),s.catchAll(p=>(n=p,console.log("error",{updateId:e.update_id,updateKey:Object.keys(e).at(1),name:p._tag,...p.cause instanceof Error?{error:p.cause.message}:void 0}),s.succeed(_.make({type:"message",text:`Some internal error has happend(${p.name}) while handling this message`,message_effect_id:C["\u{1F4A9}"],...e.message?.message_id?{reply_parameters:{message_id:e.message?.message_id}}:void 0}))))),l=yield*s.service(m);if(!i&&l.log_level=="debug"){console.log(`Bot response is undefined for update with ID #${e.update_id}.`);return}if("chat"in t&&i.response){let p=yield*b(`send_${i.response.type}`,{...i.response,chat_id:t.chat.id});l.log_level=="debug"&&console.debug("bot response",p)}return n});var f=c(require("effect/Micro")),X=c(require("effect/Context"));var Q=c(require("effect/Context")),a=c(require("effect/Micro"));var L=c(require("effect/Context")),q=c(require("effect/Data")),d=c(require("effect/Micro"));var w=class extends L.Reference()("BotFetchUpdatesService",{defaultValue:()=>{let o={lastUpdateId:void 0,emptyResponses:0},t=ae(o).pipe(d.tap(n=>{let i=n.map(l=>l.update_id).sort().at(-1);console.log("updating last update id",i),o.lastUpdateId=i?i+1:void 0,console.log(o)})),r=ce(o);return{state:o,fetchUpdates:t,commit:r}}}){},S=class extends q.TaggedError("FetchUpdatesError"){},ae=e=>d.gen(function*(){let o=yield*d.service(m);if(o.max_empty_responses&&e.emptyResponses==o.max_empty_responses)return yield*d.fail(new S({name:"TooManyEmptyResponses"}));let t=e.lastUpdateId;o.log_level=="debug"&&console.debug("getting updates",e);let r=yield*b("get_updates",{timeout:o.poll_timeout,...t?{offset:t}:void 0}).pipe(d.andThen(n=>n.sort(i=>i.update_id)));return r.length?(console.debug(`got a batch of updates (${r.length})`),e.emptyResponses=0,r):(e.emptyResponses+=1,[])}),ce=e=>d.gen(function*(){return console.log("commit",{pollState:e}),e.lastUpdateId?yield*b("get_updates",{offset:e.lastUpdateId,limit:0}).pipe(d.andThen(d.andThen(d.service(m),o=>{o.log_level=="debug"&&console.debug("committed offset",e)}))):yield*d.fail(new S({name:"NoUpdatesToCommit"}))});var U=class extends Q.Reference()("BotRunService",{defaultValue:()=>{console.log("Initiating BotRunService");let o={fiber:void 0};return{runBotInBackground:pe(o),getFiber:()=>o.fiber}}}){},pe=e=>a.gen(function*(){console.log("running telegram chat bot");let o=yield*a.service(w),t=yield*a.service(m),r=i=>t.on_error=="continue"?!0:!i,n=a.delay(1e3)(o.fetchUpdates.pipe(a.andThen(F),a.tap(i=>i.updates.length>0&&r(i.hasErrors)?o.commit:a.void))).pipe(a.repeat({while:i=>r(i.hasErrors)}),a.forkDaemon,a.tap(i=>i.addObserver(l=>{console.log("bot's fiber has been closed",l)})));e.fiber&&(console.log("killing previous bot's fiber"),yield*a.fiberInterrupt(e.fiber)),e.fiber=yield*n,console.log("Fetching bot updates via long polling...")});var I=e=>f.gen(function*(){let o=yield*f.service(U),t=X.make(h,e.bot_token);return yield*o.runBotInBackground.pipe(f.provideService(g,e.mode),f.provideService(m,x.make(e.poll??{})),f.provideContext(t)),{reload:n=>o.runBotInBackground.pipe(f.provideService(g,n),f.provideContext(t),f.runPromise),fiber:o.getFiber}});var Y=c(require("effect/Micro"));var de=e=>I(e).pipe(Y.runPromise),le=e=>(Object.keys(e).length==0&&console.warn("No handlers are defined for bot"),e);0&&(module.exports={BatchUpdateResult,BotPollSettings,BotPollSettingsTag,BotResponse,BotRunService,BotUpdateHandlersTag,HandleUpdateError,defineBot,extractUpdate,handleEntireBatch,handleOneByOne,handleOneUpdate,handleUpdates,launchBot,runTgChatBot});
|
package/dist/bot.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import*as C from"effect/Data";var _=class e extends C.TaggedClass("BotResponse"){static make(o){return new e({response:o})}static ignore=new e({})};import*as s from"effect/Micro";import*as E from"effect/Data";import*as S from"effect/Function";import*as D from"effect/String";import*as f from"effect/Micro";import*as A from"effect/Data";var u=class extends A.TaggedError("TgBotClientError"){};var F=e=>typeof e=="object"&&e!=null&&"file_content"in e&&e.file_content instanceof Uint8Array&&"file_name"in e&&typeof e.file_name=="string",I=e=>typeof e=="object"&&e!=null&&"ok"in e&&typeof e.ok=="boolean";import*as U from"effect/Context";var P="https://api.telegram.org",w={"\u{1F525}":"5104841245755180586","\u{1F44D}":"5107584321108051014","\u{1F44E}":"5104858069142078462","\u2764\uFE0F":"5159385139981059251","\u{1F389}":"5046509860389126442","\u{1F4A9}":"5046589136895476101"},ne=Object.keys(w);var b=class extends U.Reference()("TgBotApiBaseUrl",{defaultValue:()=>P}){},y=class extends U.Tag("TgBotApiToken")(){};var H=e=>{let o=Object.entries(e);if(o.length==0)return;let t=new FormData;for(let[r,n]of o)n&&(typeof n!="object"?t.append(r,`${n}`):F(n)?t.append(r,new Blob([n.file_content]),n.file_name):t.append(r,JSON.stringify(n)));return t};var h=(e,o)=>f.gen(function*(){let t=yield*f.service(y),r=yield*f.service(b),n=yield*f.tryPromise({try:()=>fetch(`${r}/bot${t}/${D.snakeToCamel(e)}`,{body:H(o)??null,method:"POST"}),catch:d=>new u({cause:{_tag:"ClientInternalError",cause:d}})}),i=yield*f.tryPromise({try:()=>n.json(),catch:()=>new u({cause:{_tag:"NotJsonResponse",response:n}})});return I(i)?n.ok?i.result:yield*f.fail(new u({cause:{_tag:"NotOkResponse",...i.error_code?{errorCode:i.error_code}:void 0,...i.description?{details:i.description}:void 0}})):yield*f.fail(new u({cause:{_tag:"UnexpectedResponse",response:i}}))});import*as T from"effect/Context";import*as $ from"effect/Data";var g=class extends T.Tag("BotUpdateHandlers")(){},x=class e extends $.Class{static make(o){let t=o.batch_size??10,r=o.poll_timeout??10,n=o.max_empty_responses,i=o.log_level??"info",d=o.on_error;(t<10||t>100)&&(console.warn("Wrong batch_size, must be in [10..100], using 10 instead"),t=10),(r<2||r>120)&&(console.warn("Wrong poll_timeout, must be in [2..120], using 20 instead"),r=20),n&&n<2&&(console.warn("Wrong max_empty_responses, must be in [2..infinity], using infinity"),n=void 0),i||(i="info"),d||(d="stop");let c=new e({batch_size:t,poll_timeout:r,max_empty_responses:n,log_level:i,on_error:d});return console.log("bot poll settings",c),c}},m=class extends T.Reference()("BotSettings",{defaultValue(){return x.make({})}}){};var J=e=>{for(let[o,t]of Object.entries(e))if(o!="update_id")return{type:o,...t}},B=class extends E.Class{},N=e=>s.gen(function*(){let o=yield*s.service(m),t=yield*s.service(g);return t.type=="single"?yield*q(e,t,o):yield*L(e,t)}),L=(e,o)=>s.try({try:()=>o.on_batch(e),catch:S.identity}).pipe(s.andThen(t=>t instanceof Promise?s.tryPromise({try:()=>t,catch:S.identity}):s.succeed(t)),s.andThen(t=>new B({hasErrors:!t,updates:e})),s.catchAll(t=>(console.warn("handle batch error",{errorMessage:t instanceof Error?t.message:void 0,updates:e.map(r=>Object.keys(r).at(1)),error:t}),s.succeed(new B({hasErrors:!0,updates:e}))))),M=class extends E.TaggedError("HandleUpdateError"){},q=(e,o,t)=>s.forEach(e,r=>Q(r,o).pipe(s.catchAll(n=>(console.log("update handle error",{updateId:r.update_id,updateKey:Object.keys(r).at(1),name:n._tag,...n.cause instanceof Error?{error:n.cause.message}:void 0}),s.succeed(n)))),{concurrency:10}).pipe(s.andThen(r=>(t.log_level=="debug"&&console.debug("handle batch result",r),new B({hasErrors:!r.every(n=>n==null),updates:e})))),Q=(e,o)=>s.gen(function*(){let t=J(e);if(!t)return yield*s.fail(new M({name:"UnknownUpdate",update:e}));let r=o[`on_${t.type}`];if(!r)return yield*s.fail(new M({name:"HandlerNotDefined",update:e}));t.type=="message"&&"text"in t&&console.info("Got a new text message",{chatId:t.chat.id,chatType:t.chat.type,message:`${t.text.slice(0,5)}...`});let n,i=yield*s.try({try:()=>r(t),catch:c=>new M({name:"BotHandlerError",update:e,cause:c})}).pipe(s.andThen(c=>c instanceof Promise?s.tryPromise({try:()=>c,catch:W=>new M({name:"BotHandlerError",update:e,cause:W})}):s.succeed(c)),s.catchAll(c=>(n=c,console.log("error",{updateId:e.update_id,updateKey:Object.keys(e).at(1),name:c._tag,...c.cause instanceof Error?{error:c.cause.message}:void 0}),s.succeed(_.make({type:"message",text:`Some internal error has happend(${c.name}) while handling this message`,message_effect_id:w["\u{1F4A9}"],...e.message?.message_id?{reply_parameters:{message_id:e.message?.message_id}}:void 0}))))),d=yield*s.service(m);if(!i&&d.log_level=="debug"){console.log(`Bot response is undefined for update with ID #${e.update_id}.`);return}if("chat"in t&&i.response){let c=yield*h(`send_${i.response.type}`,{...i.response,chat_id:t.chat.id});d.log_level=="debug"&&console.debug("bot response",c)}return n});import*as l from"effect/Micro";import*as j from"effect/Context";import*as K from"effect/Context";import*as a from"effect/Micro";import*as O from"effect/Context";import*as G from"effect/Data";import*as p from"effect/Micro";var k=class extends O.Reference()("BotFetchUpdatesService",{defaultValue:()=>{let o={lastUpdateId:void 0,emptyResponses:0},t=X(o).pipe(p.tap(n=>{let i=n.map(d=>d.update_id).sort().at(-1);console.log("updating last update id",i),o.lastUpdateId=i?i+1:void 0,console.log(o)})),r=Y(o);return{state:o,fetchUpdates:t,commit:r}}}){},R=class extends G.TaggedError("FetchUpdatesError"){},X=e=>p.gen(function*(){let o=yield*p.service(m);if(o.max_empty_responses&&e.emptyResponses==o.max_empty_responses)return yield*p.fail(new R({name:"TooManyEmptyResponses"}));let t=e.lastUpdateId;o.log_level=="debug"&&console.debug("getting updates",e);let r=yield*h("get_updates",{timeout:o.poll_timeout,...t?{offset:t}:void 0}).pipe(p.andThen(n=>n.sort(i=>i.update_id)));return r.length?(console.debug(`got a batch of updates (${r.length})`),e.emptyResponses=0,r):(e.emptyResponses+=1,[])}),Y=e=>p.gen(function*(){return console.log("commit",{pollState:e}),e.lastUpdateId?yield*h("get_updates",{offset:e.lastUpdateId,limit:0}).pipe(p.andThen(p.andThen(p.service(m),o=>{o.log_level=="debug"&&console.debug("committed offset",e)}))):yield*p.fail(new R({name:"NoUpdatesToCommit"}))});var v=class extends K.Reference()("BotRunService",{defaultValue:()=>{console.log("Initiating BotRunService");let o={fiber:void 0};return{runBotInBackground:Z(o),getFiber:()=>o.fiber}}}){},Z=e=>a.gen(function*(){console.log("running telegram chat bot");let o=yield*a.service(k),t=yield*a.service(m),r=i=>t.on_error=="continue"?!0:!i,n=a.delay(1e3)(o.fetchUpdates.pipe(a.andThen(N),a.tap(i=>i.updates.length>0&&r(i.hasErrors)?o.commit:a.void))).pipe(a.repeat({while:i=>r(i.hasErrors)}),a.forkDaemon,a.tap(i=>i.addObserver(d=>{console.log("bot's fiber has been closed",d)})));e.fiber&&(console.log("killing previous bot's fiber"),yield*a.fiberInterrupt(e.fiber)),e.fiber=yield*n,console.log("Fetching bot updates via long polling...")});var z=e=>l.gen(function*(){let o=yield*l.service(v),t=j.make(y,e.bot_token);return yield*o.runBotInBackground.pipe(l.provideService(g,e.mode),l.provideService(m,x.make(e.poll??{})),l.provideContext(t)),{reload:n=>o.runBotInBackground.pipe(l.provideService(g,n),l.provideContext(t),l.runPromise),fiber:o.getFiber}});import*as V from"effect/Micro";var Pe=e=>z(e).pipe(V.runPromise),He=e=>(Object.keys(e).length==0&&console.warn("No handlers are defined for bot"),e);export{B as BatchUpdateResult,x as BotPollSettings,m as BotPollSettingsTag,_ as BotResponse,v as BotRunService,g as BotUpdateHandlersTag,M as HandleUpdateError,He as defineBot,J as extractUpdate,L as handleEntireBatch,q as handleOneByOne,Q as handleOneUpdate,N as handleUpdates,z as launchBot,Pe as runTgChatBot};
|