summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2025-07-10 13:29:31 +0200
committerYuval Adam <_@yuv.al>2025-07-10 13:29:31 +0200
commitaec2c16d8cd3748d2ce694b76f868243f7ff88af (patch)
treefcfea0aa7fe96cfdc436f013e865d75c7f1c37e8 /src
parent9b7446cd051cdcea7ed8fd96d35e190625e861f9 (diff)
Add durable object
Diffstat (limited to 'src')
-rw-r--r--src/pages/api/counter.ts59
-rw-r--r--src/worker.ts67
2 files changed, 126 insertions, 0 deletions
diff --git a/src/pages/api/counter.ts b/src/pages/api/counter.ts
new file mode 100644
index 0000000..152dc54
--- /dev/null
+++ b/src/pages/api/counter.ts
@@ -0,0 +1,59 @@
+import type { APIRoute } from 'astro';
+
+interface Env {
+ COUNTER_DO: DurableObjectNamespace;
+}
+
+export const GET: APIRoute = async ({ request }) => {
+ const env = request.cf?.env as Env;
+ if (!env?.COUNTER_DO) {
+ return new Response(JSON.stringify({ error: 'Durable Object not available' }), {
+ status: 500,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ const id = env.COUNTER_DO.idFromName('global-counter');
+ const stub = env.COUNTER_DO.get(id);
+
+ const response = await stub.fetch(new Request('https://counter.do/get'));
+ const data = await response.json();
+
+ return new Response(JSON.stringify(data), {
+ headers: { 'Content-Type': 'application/json' }
+ });
+};
+
+export const POST: APIRoute = async ({ request }) => {
+ const env = request.cf?.env as Env;
+ if (!env?.COUNTER_DO) {
+ return new Response(JSON.stringify({ error: 'Durable Object not available' }), {
+ status: 500,
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ const url = new URL(request.url);
+ const action = url.searchParams.get('action') || 'increment';
+
+ const id = env.COUNTER_DO.idFromName('global-counter');
+ const stub = env.COUNTER_DO.get(id);
+
+ let doRequest: Request;
+ switch (action) {
+ case 'reset':
+ doRequest = new Request('https://counter.do/reset');
+ break;
+ case 'increment':
+ default:
+ doRequest = new Request('https://counter.do/increment');
+ break;
+ }
+
+ const response = await stub.fetch(doRequest);
+ const data = await response.json();
+
+ return new Response(JSON.stringify(data), {
+ headers: { 'Content-Type': 'application/json' }
+ });
+}; \ No newline at end of file
diff --git a/src/worker.ts b/src/worker.ts
new file mode 100644
index 0000000..0ad83a6
--- /dev/null
+++ b/src/worker.ts
@@ -0,0 +1,67 @@
+import type { SSRManifest } from 'astro';
+import { App } from 'astro/app';
+import { handle } from '@astrojs/cloudflare/handler';
+import { DurableObject } from 'cloudflare:workers';
+
+interface Env {
+ COUNTER_DO: DurableObjectNamespace;
+}
+
+class CounterDurableObject extends DurableObject<Env> {
+ constructor(ctx: DurableObjectState, env: Env) {
+ super(ctx, env);
+ }
+
+ async fetch(request: Request): Promise<Response> {
+ const url = new URL(request.url);
+ const pathname = url.pathname;
+
+ if (pathname === '/increment') {
+ const currentValue = (await this.ctx.storage.get<number>('counter')) || 0;
+ const newValue = currentValue + 1;
+ await this.ctx.storage.put('counter', newValue);
+
+ return new Response(JSON.stringify({
+ counter: newValue,
+ timestamp: new Date().toISOString()
+ }), {
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ if (pathname === '/get') {
+ const currentValue = (await this.ctx.storage.get<number>('counter')) || 0;
+ return new Response(JSON.stringify({
+ counter: currentValue,
+ timestamp: new Date().toISOString()
+ }), {
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ if (pathname === '/reset') {
+ await this.ctx.storage.put('counter', 0);
+ return new Response(JSON.stringify({
+ counter: 0,
+ message: 'Counter reset',
+ timestamp: new Date().toISOString()
+ }), {
+ headers: { 'Content-Type': 'application/json' }
+ });
+ }
+
+ return new Response('Not found', { status: 404 });
+ }
+}
+
+export function createExports(manifest: SSRManifest) {
+ const app = new App(manifest);
+ return {
+ default: {
+ async fetch(request, env, ctx) {
+ return handle(manifest, app, request, env, ctx);
+ }
+ } satisfies ExportedHandler<Env>,
+ CounterDurableObject: CounterDurableObject,
+ };
+} \ No newline at end of file