diff --git a/docs/src/app/(home)/comparison.tsx b/docs/src/app/(home)/comparison.tsx index d7f0ea6..37a82c2 100644 --- a/docs/src/app/(home)/comparison.tsx +++ b/docs/src/app/(home)/comparison.tsx @@ -1,23 +1,6 @@ -"use client"; +import { highlight } from "fumadocs-core/highlight"; -import { useState } from "react"; - -type Stack = "taskito" | "celery"; - -const STACKS: Record< - Stack, - { - label: string; - services: string; - install: string; - code: string; - } -> = { - taskito: { - label: "taskito", - services: "1 process", - install: "pip install taskito", - code: `from taskito import Queue +const TASKITO_CODE = `from taskito import Queue queue = Queue(db_path="tasks.db") @@ -29,13 +12,9 @@ def send_email(to, subject, body): send_email.delay("alice@example.com", "Hi", "Body") # Run the worker -# $ taskito worker --app tasks:queue`, - }, - celery: { - label: "Celery + Redis", - services: "3 processes (Redis + worker + beat)", - install: "pip install celery[redis]\n# also: install + run Redis server", - code: `from celery import Celery +# $ taskito worker --app tasks:queue`; + +const CELERY_CODE = `from celery import Celery app = Celery( "myapp", @@ -55,75 +34,164 @@ def send_email(self, to, subject, body): send_email.delay("alice@example.com", "Hi", "Body") # Run the worker (in a separate terminal, plus Redis) -# $ celery -A myapp worker --loglevel=info`, +# $ celery -A myapp worker --loglevel=info`; + +type Tone = "primary" | "muted"; + +const ROWS: { label: string; taskito: string; celery: string }[] = [ + { + label: "Install", + taskito: "pip install taskito", + celery: "pip install celery[redis] + run Redis daemon", }, -}; + { + label: "Background services", + taskito: "1 (worker)", + celery: "3 (worker, beat, Redis)", + }, + { + label: "Default storage", + taskito: "SQLite file (built-in)", + celery: "Redis (separate daemon)", + }, + { + label: "Retry config in the example above", + taskito: "max_retries=3 decorator arg", + celery: "try/except + self.retry(exc=…)", + }, +]; -export function Comparison() { - const [stack, setStack] = useState("taskito"); - const data = STACKS[stack]; +export async function Comparison() { + const [taskitoHighlighted, celeryHighlighted] = await Promise.all([ + renderHighlighted(TASKITO_CODE), + renderHighlighted(CELERY_CODE), + ]); return ( -
-
- {(Object.keys(STACKS) as Stack[]).map((key) => { - const active = stack === key; - return ( - - ); - })} -
-
- - - +
+
+ + {taskitoHighlighted} + + + {celeryHighlighted} +
-
-        {data.code}
-      
+
); } -function Stat({ +async function renderHighlighted(code: string) { + return highlight(code, { + lang: "python", + themes: { + light: "github-light", + dark: "github-dark", + }, + components: { + pre: ({ children, ...props }) => ( +
+          {children}
+        
+ ), + }, + }); +} + +function CodePanel({ label, - value, - mono, + caption, + tone, + children, }: { label: string; - value: string; - mono?: boolean; + caption: string; + tone: Tone; + children: React.ReactNode; }) { + const accent = + tone === "primary" ? "border-t-fd-primary" : "border-t-fd-border"; return ( -
-
- {label} -
-
- {value} +
+
+ + {label} + + {caption}
+ {children} +
+ ); +} + +function DifferentiatorTable() { + return ( +
+ + + + + + + + + + {ROWS.map((row, i) => ( + + + + + + ))} + +
+ Property + + taskito + + Celery + Redis +
+ {row.label} + + {row.taskito} + + {row.celery} +
); } diff --git a/docs/src/app/(home)/page.tsx b/docs/src/app/(home)/page.tsx index b1869ae..0246559 100644 --- a/docs/src/app/(home)/page.tsx +++ b/docs/src/app/(home)/page.tsx @@ -196,7 +196,7 @@ function ComparisonSection() { Less to operate

- The same task, two stacks. Pick the one with fewer moving parts. + The same task, two stacks. Side by side, with the operational delta.