diff --git a/docs/telegram-bot-playground/index.html b/docs/telegram-bot-playground/index.html
index 70c1f5a..8f85798 100644
--- a/docs/telegram-bot-playground/index.html
+++ b/docs/telegram-bot-playground/index.html
@@ -10,7 +10,7 @@
-
+
diff --git a/docs/telegram-bot-playground/metadata.json b/docs/telegram-bot-playground/metadata.json
index 735b5eb..56f1b6a 100644
--- a/docs/telegram-bot-playground/metadata.json
+++ b/docs/telegram-bot-playground/metadata.json
@@ -1,5 +1,5 @@
{
"styles.css": "oq5lin",
- "_main.js": "e7gy8f",
+ "main.js": "yozt7w",
"web-worker.js": "f5lxb1"
}
\ No newline at end of file
diff --git a/docs/telegram-bot-playground/scripts/main.js b/docs/telegram-bot-playground/scripts/main.js
new file mode 100644
index 0000000..ce086d6
--- /dev/null
+++ b/docs/telegram-bot-playground/scripts/main.js
@@ -0,0 +1,253 @@
+// src/tg-bot-playground/bot-launcher/load.ts
+async function loadWorker() {
+ const version = await fetch("./metadata.json", { cache: "no-cache" }).then((_) => _.json()).then((_) => _["web-worker.js"]);
+ if (!version) {
+ console.warn("Cannot get version from metadata");
+ return;
+ }
+ ;
+ const worker = new Worker(`./scripts/worker/web-worker.js?v=${version}`, { type: "module" });
+ console.log("web worker has been loaded");
+ return worker;
+}
+
+// src/tg-bot-playground/bot-launcher/run.ts
+var makeRunnableBot = (tsTextModel, worker) => (state) => tsTextModel.getJsCode().then((code) => {
+ if (!state.bot.token || state.bot.token.length < 10) return;
+ if (!code.serialized) {
+ console.warn("Serizalized js code not defined");
+ return;
+ }
+ worker.postMessage({
+ command: "run-bot",
+ token: state.bot.token,
+ code: code.serialized
+ });
+ state.bot.status = "active";
+}).catch((error) => {
+ console.warn("cannot run bot", error);
+});
+var checkTokenAndRun = (state, runnableBot) => {
+ const token = state.bot.token;
+ if (!token) return;
+ fetch(`https://api.telegram.org/bot${token}/getMe`).then((_) => _.json()).then((info) => {
+ if (info.ok) {
+ state.bot.name = info.result.first_name;
+ console.log("Running bot");
+ runnableBot(state);
+ } else {
+ state.bot.name = "nameless";
+ }
+ }).catch((error) => {
+ console.warn("check token error", error);
+ });
+};
+
+// src/tg-bot-playground/bot-launcher/_main.ts
+var makeBotLauncher = async (tsTextModel) => {
+ const worker = await loadWorker();
+ if (!worker) return;
+ const runnableBot = makeRunnableBot(tsTextModel, worker);
+ return {
+ worker,
+ runBot: (state) => runnableBot(state),
+ checkTokenAndRun: (state) => checkTokenAndRun(state, runnableBot)
+ };
+};
+
+// src/tg-bot-playground/utils.ts
+var fetchText = (path) => fetch(path).then((_) => _.text());
+var getMonacoLoader = () => {
+ if (!("monaco_loader" in window) || typeof window.monaco_loader != "object" || window.monaco_loader == null) {
+ console.warn("monaco loader is not available");
+ return;
+ }
+ return window.monaco_loader;
+};
+function getAlpine() {
+ if (!("Alpine" in window) || typeof window.Alpine != "object" || window.Alpine == null) {
+ console.warn("Alpine is not available");
+ return;
+ }
+ return window.Alpine;
+}
+
+// src/tg-bot-playground/editor/setup.ts
+var setupDts = async (monaco) => {
+ const dts = await fetchText("https://cdn.jsdelivr.net/npm/@effect-ak/tg-bot-client@0.2.2/dist/index.d.ts");
+ monaco.languages.typescript.typescriptDefaults.setExtraLibs([
+ {
+ content: dts,
+ filePath: "node_modules/@effect-ak/tg-bot-client/index.d.ts"
+ }
+ ]);
+ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
+ ...monaco.languages.typescript.typescriptDefaults.getCompilerOptions(),
+ moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
+ typeRoots: [
+ "node_modules"
+ ],
+ strict: true
+ });
+};
+
+// src/tg-bot-playground/editor/ts-text-model.ts
+var makeTsTextModel = async (monaco) => {
+ const emptyExample = await fetchText("./example/empty.ts");
+ const tsModel = monaco.editor.createModel(emptyExample, "typescript");
+ let cachedWorkerPromise = null;
+ const getTsCode = async () => {
+ if (!cachedWorkerPromise) {
+ cachedWorkerPromise = (async () => {
+ const tsWorker = await monaco.languages.typescript.getTypeScriptWorker();
+ return tsWorker(tsModel.uri);
+ })();
+ }
+ return cachedWorkerPromise.then((_) => _.getEmitOutput(tsModel.uri.toString()));
+ };
+ return {
+ tsModel,
+ getJsCode: async () => {
+ const output = await getTsCode();
+ const code = output.outputFiles[0].text;
+ const defaultExport = await getDefaultExport(code);
+ return {
+ defaultExport,
+ serialized: serialize(defaultExport?.default)
+ };
+ }
+ };
+};
+async function getDefaultExport(code) {
+ try {
+ const encodedCode = encodeURIComponent(code);
+ const module = await import(`data:text/javascript,${encodedCode}`);
+ const result = module.default;
+ return { default: result };
+ } catch (e) {
+ console.warn("get default error", e);
+ return void 0;
+ }
+}
+var serialize = (input) => {
+ if (typeof input != "object" || !input) {
+ return void 0;
+ }
+ const result = [];
+ for (const [key, value] of Object.entries(input)) {
+ if (typeof value != "function") {
+ continue;
+ }
+ result.push([key, value.toString()]);
+ }
+ return JSON.stringify(Object.fromEntries(result));
+};
+
+// src/tg-bot-playground/editor/init.ts
+var initEditor = async (loader) => {
+ const container = document.getElementById("container");
+ if (!container) {
+ console.warn("container not found");
+ return;
+ }
+ loader.config({
+ paths: {
+ vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs"
+ }
+ });
+ const monaco = await loader.init();
+ const tsTextModel = await makeTsTextModel(monaco);
+ const editor = monaco.editor.create(container, {
+ model: tsTextModel.tsModel,
+ contextmenu: false,
+ minimap: {
+ enabled: false
+ }
+ });
+ return {
+ tsTextModel,
+ editor,
+ monaco
+ };
+};
+
+// src/tg-bot-playground/editor/_editor.ts
+var makeEditor = async (state) => {
+ const loader = getMonacoLoader();
+ if (!loader) return;
+ const editor = await initEditor(loader);
+ if (!editor) return;
+ await setupDts(editor.monaco);
+ return {
+ tsTextModel: editor.tsTextModel,
+ loadExample: () => {
+ if (!state.selectedExample) return;
+ fetchText(`./example/${state.selectedExample}`).then((_) => editor.tsTextModel.tsModel.setValue(_));
+ },
+ onCodeChange: (f) => {
+ let timeoutId;
+ const debounceDelay = 1e3;
+ editor.tsTextModel.tsModel.onDidChangeContent(() => {
+ if (timeoutId !== void 0) {
+ clearTimeout(timeoutId);
+ }
+ timeoutId = window.setTimeout(() => {
+ const markers = editor.monaco.editor.getModelMarkers({
+ resource: editor.tsTextModel.tsModel.uri
+ });
+ const hasError = markers.find((_) => _.severity.valueOf() == 8) != null;
+ if (!hasError) {
+ f();
+ } else {
+ console.debug("Code contains errors");
+ }
+ }, debounceDelay);
+ });
+ }
+ };
+};
+
+// src/tg-bot-playground/main.ts
+var makeGlobalState = (alpine) => {
+ const state = alpine.reactive({
+ bot: {
+ name: "nameless",
+ status: "idle",
+ token: ""
+ },
+ selectedExample: "empty.ts",
+ botUpdates: []
+ });
+ return state;
+};
+document.addEventListener("alpine:init", async () => {
+ const Alpine = getAlpine();
+ if (!Alpine) return;
+ const state = makeGlobalState(Alpine);
+ Alpine.store("state", state);
+ const editor = await makeEditor(state);
+ if (!editor) return;
+ const botLauncher = await makeBotLauncher(editor.tsTextModel);
+ if (!botLauncher) return;
+ editor.onCodeChange(() => {
+ botLauncher.runBot(state);
+ });
+ document.addEventListener("check-token", () => {
+ botLauncher.checkTokenAndRun(state);
+ });
+ document.addEventListener("change-example", () => {
+ editor.loadExample();
+ });
+ botLauncher.worker.onmessage = (event) => {
+ const data = event.data;
+ console.log("got message from worker", data);
+ if (!data) return;
+ if (data.botState) {
+ Object.assign(state.bot, data.botState);
+ }
+ state.botUpdates.push(data);
+ };
+});
+export {
+ makeGlobalState
+};
diff --git a/scripts/prep-page.js b/scripts/prep-page.js
index f170049..5677045 100644
--- a/scripts/prep-page.js
+++ b/scripts/prep-page.js
@@ -4,7 +4,7 @@ import * as Path from "path"
const files = [
"styles.css",
- "scripts/_main.js",
+ "scripts/main.js",
"scripts/worker/web-worker.js",
];
diff --git a/src/tg-bot-playground/bot-launcher/_main.ts b/src/tg-bot-playground/bot-launcher/_main.ts
index 344dfd2..699476c 100644
--- a/src/tg-bot-playground/bot-launcher/_main.ts
+++ b/src/tg-bot-playground/bot-launcher/_main.ts
@@ -1,4 +1,4 @@
-import type { GlobalState } from "#tg-bot-playground/_main.js";
+import type { GlobalState } from "#tg-bot-playground/main.js";
import type { TsTextModel } from "#tg-bot-playground/editor/ts-text-model.js";
import { loadWorker } from "./load.js";
import { checkTokenAndRun, makeRunnableBot } from "./run.js";
diff --git a/src/tg-bot-playground/bot-launcher/run.ts b/src/tg-bot-playground/bot-launcher/run.ts
index 2a134c8..2b4c050 100644
--- a/src/tg-bot-playground/bot-launcher/run.ts
+++ b/src/tg-bot-playground/bot-launcher/run.ts
@@ -1,4 +1,4 @@
-import type { GlobalState } from "#tg-bot-playground/_main.js";
+import type { GlobalState } from "#tg-bot-playground/main.js";
import type { TsTextModel } from "#tg-bot-playground/editor/ts-text-model.js";
export type RunnableBot = (ReturnType)
diff --git a/src/tg-bot-playground/editor/_editor.ts b/src/tg-bot-playground/editor/_editor.ts
index 5b6d7c5..85adf64 100644
--- a/src/tg-bot-playground/editor/_editor.ts
+++ b/src/tg-bot-playground/editor/_editor.ts
@@ -1,7 +1,7 @@
import { fetchText, getMonacoLoader } from "#tg-bot-playground/utils.js";
import { setupDts } from "./setup.js";
import { initEditor } from "./init.js";
-import type { GlobalState } from "#tg-bot-playground/_main.js";
+import type { GlobalState } from "#tg-bot-playground/main.js";
export const makeEditor = async (
state: GlobalState
diff --git a/src/tg-bot-playground/_main.ts b/src/tg-bot-playground/main.ts
similarity index 100%
rename from src/tg-bot-playground/_main.ts
rename to src/tg-bot-playground/main.ts
diff --git a/tsup.config.json b/tsup.config.json
index 42642d4..81bb593 100644
--- a/tsup.config.json
+++ b/tsup.config.json
@@ -2,7 +2,7 @@
"$schema": "https://cdn.jsdelivr.net/npm/tsup/schema.json",
"entry": [
"src/tg-bot-playground/worker/web-worker.ts",
- "src/tg-bot-playground/_main.ts"
+ "src/tg-bot-playground/main.ts"
],
"splitting": false,
"outDir": "docs/telegram-bot-playground/scripts",