Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
e80818c
docs: rework onboarding path and consolidate capabilities
pratyush618 Jul 8, 2026
490c8fd
docs: fix core guides (expires, batch, glosses)
pratyush618 Jul 8, 2026
2ea2b5f
docs: fix reliability guides (dedup, retries, Celery)
pratyush618 Jul 8, 2026
b7cbe34
docs: fix advanced-execution guides
pratyush618 Jul 8, 2026
a70a2da
docs: fix workflow guides (worker note, canvas mapping)
pratyush618 Jul 8, 2026
bc60914
docs: add no-broker story and worker-first onboarding
pratyush618 Jul 8, 2026
f88921d
docs: fix resource guides (DI rationale, terms)
pratyush618 Jul 8, 2026
8c8cfb4
docs: fix operations guides (pool, mesh, migration)
pratyush618 Jul 8, 2026
ea20bb2
docs: fix dashboard guides (pause, routes, port)
pratyush618 Jul 8, 2026
7c4c3c9
docs: fix extensibility (serializer default, signals)
pratyush618 Jul 8, 2026
57fd274
docs: fix integration guides (extras, metrics)
pratyush618 Jul 8, 2026
690c793
docs: fix observability guides
pratyush618 Jul 8, 2026
b03357c
docs: fix API reference (CLI, task params, status)
pratyush618 Jul 8, 2026
ebaf4ee
docs: fix examples (worker startup, real APIs)
pratyush618 Jul 8, 2026
e21b25c
docs: fix architecture (no-broker, delivery, serializer)
pratyush618 Jul 8, 2026
3f0242e
docs: fix comparison and faq (distributed, serializer)
pratyush618 Jul 8, 2026
d2b481d
docs: fix ML workflow example step arg/result flow
pratyush618 Jul 8, 2026
0a6a7fb
docs: rework landing hero copy and CTAs
pratyush618 Jul 9, 2026
79544b4
docs: fix hero code panel to a consistent size
pratyush618 Jul 9, 2026
75e79f5
docs(node): fix getting-started and core guides
pratyush618 Jul 9, 2026
e02238a
docs(node): fix reliability and workflow guides
pratyush618 Jul 9, 2026
709fc24
docs(node): fix operations and integration guides
pratyush618 Jul 9, 2026
56eacc2
docs(node): fix API reference and examples
pratyush618 Jul 9, 2026
32c618a
docs(java): fix getting-started and core guides
pratyush618 Jul 9, 2026
38d43fb
docs(java): fix reliability and workflow guides
pratyush618 Jul 9, 2026
5d26e40
docs(java): fix operations and integration guides
pratyush618 Jul 9, 2026
e887766
docs(java): fix API reference and examples
pratyush618 Jul 9, 2026
7fd5e2b
feat(docs): add turquoise color token
pratyush618 Jul 10, 2026
223e00a
docs: make FAQ content SDK-specific
pratyush618 Jul 10, 2026
b23a17d
fix(docs): filter on-this-page TOC by active SDK
pratyush618 Jul 10, 2026
849ef7b
fix(docs): make mermaid sequence numbers theme-aware
pratyush618 Jul 10, 2026
d097cb1
feat(docs): hide SDK selector on landing nav
pratyush618 Jul 10, 2026
8b07b0e
refactor(docs): move HowItWorks above ScenarioFinder
pratyush618 Jul 10, 2026
14fdb9f
feat(docs): auto-number FAQ questions
pratyush618 Jul 10, 2026
ec6debc
fix(docs): use turquoise for info callout
pratyush618 Jul 10, 2026
239ee5d
fix(docs): align list bullets with wrapped text
pratyush618 Jul 10, 2026
2e17f7d
fix(docs): hide sidebar search on desktop
pratyush618 Jul 10, 2026
9e8225a
fix(docs): pad gradient heading so descenders show
pratyush618 Jul 10, 2026
bd3318d
style(docs): reduce hero heading max size
pratyush618 Jul 10, 2026
09ebe01
feat(docs): freeze header and first column on large tables
pratyush618 Jul 10, 2026
b39e5df
fix(docs): wrap long labels in frozen table column
pratyush618 Jul 10, 2026
1e38f04
feat(docs): mark nested subsections in on-this-page TOC
pratyush618 Jul 10, 2026
b2f0d15
fix(docs): theme subgraph clusters and default nodes in diagrams
pratyush618 Jul 10, 2026
b18ffbe
fix(docs): render wide diagrams at full size with scroll
pratyush618 Jul 10, 2026
83b4184
fix(docs): restore numbers on ordered lists
pratyush618 Jul 10, 2026
70af692
feat(docs): open diagrams enlarged in overlay on click
pratyush618 Jul 10, 2026
8a42f1e
docs: list all six workflow terminal states
pratyush618 Jul 10, 2026
0cb4572
docs: don't call Postgres an embedded database
pratyush618 Jul 10, 2026
fbf45bb
docs(java): clarify Redis is still required when selected
pratyush618 Jul 10, 2026
28ca820
docs(node): note queue.result timeout semantics in migration
pratyush618 Jul 10, 2026
da47139
docs(node): BullMQ QueueEvents uses Redis Streams
pratyush618 Jul 10, 2026
6f8d190
docs: reframe exactly-once around effect atomicity
pratyush618 Jul 10, 2026
2e12ff7
docs(node): spell out enforceable SSRF protections
pratyush618 Jul 10, 2026
11c8e51
docs: use a credential-free NoProxy session example
pratyush618 Jul 10, 2026
869980a
docs: build DB engine in factory and dispose in teardown
pratyush618 Jul 10, 2026
bc63104
fix(docs): manage focus in enlarged diagram overlay
pratyush618 Jul 10, 2026
3d3a077
fix(docs): restore focus to remounted diagram trigger
pratyush618 Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions docs/app/components/docs/toc.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
import { useEffect, useState } from "react";
import { useLocation } from "react-router";
import { useActiveSdk } from "@/hooks";
import type { Sdk } from "@/lib";

interface Heading {
id: string;
text: string;
level: number;
}

function readHeadings(article: Element): Heading[] {
return [...article.querySelectorAll<HTMLElement>("h2[id], h3[id]")].map(
(el) => ({
id: el.id,
text: el.textContent ?? "",
level: el.tagName === "H3" ? 3 : 2,
}),
/** Headings inside an inactive `SdkOnly` block ship in the HTML but are hidden
* via CSS, so skip any heading whose nearest `data-sdk-variant` ancestor isn't
* the active SDK — otherwise the TOC lists every SDK's questions at once. */
function visibleHeadingEls(article: Element, sdk: Sdk): HTMLElement[] {
return [...article.querySelectorAll<HTMLElement>("h2[id], h3[id]")].filter(
(el) => {
const variant = el.closest("[data-sdk-variant]");
return !variant || variant.getAttribute("data-sdk-variant") === sdk;
},
);
}

function toHeading(el: HTMLElement): Heading {
return {
id: el.id,
text: el.textContent ?? "",
level: el.tagName === "H3" ? 3 : 2,
};
}

/** On-this-page TOC, built from the rendered article headings with scroll-spy. */
export function Toc() {
const { pathname } = useLocation();
const sdk = useActiveSdk();
const [headings, setHeadings] = useState<Heading[]>([]);
const [active, setActive] = useState<string>("");

// The article is a lazily-loaded MDX chunk, so its headings are NOT in the DOM
// when this effect first runs after a client-side navigation. Re-scan on every
// article mutation (via MutationObserver) so the TOC fills in once the page
// content actually mounts, and re-arm scroll-spy whenever the heading set changes.
// biome-ignore lint/correctness/useExhaustiveDependencies: re-scan when the path changes
// biome-ignore lint/correctness/useExhaustiveDependencies: re-scan on path or SDK change
useEffect(() => {
const article = document.querySelector(".article");
if (!article) {
Expand All @@ -38,7 +51,8 @@ export function Toc() {
let lastKey = "";

const scan = () => {
const next = readHeadings(article);
const els = visibleHeadingEls(article, sdk);
const next = els.map(toHeading);
const key = next.map((h) => h.id).join("|");
if (key === lastKey) {
return;
Expand All @@ -59,7 +73,7 @@ export function Toc() {
},
{ rootMargin: "-80px 0px -70% 0px" },
);
for (const el of article.querySelectorAll("h2[id], h3[id]")) {
for (const el of els) {
spy.observe(el);
}
};
Expand All @@ -71,7 +85,7 @@ export function Toc() {
content.disconnect();
spy?.disconnect();
};
}, [pathname]);
}, [pathname, sdk]);

if (headings.length === 0) {
return <aside className="toc" aria-hidden="true" />;
Expand Down
34 changes: 14 additions & 20 deletions docs/app/components/landing/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export function Hero() {
// The selected snippet IS the global SDK — clicking a tab sets it, so the hero
// copy, the install/quickstart links, and the docs sidebar switch all follow.
const active = HERO_PANES.find((p) => p.sdk === sdk) ?? HERO_PANES[0];
const label = sdkProfile(active.sdk).label;
const codeHtml =
active.lang === "ts"
? highlightTs(active.code)
Expand All @@ -44,30 +43,33 @@ export function Hero() {
<section className="hero">
<div className="left">
<h1>
One queue.
<span className="grad">Built for {label}.</span>
Keep your app fast —{" "}
<span className="grad">run slow work in the background.</span>
</h1>
<p className="sub">
A Rust-powered task queue with a first-class <b>{label}</b> SDK over
one core and one store — no broker. Start on <code>SQLite</code>,
scale to <code>Postgres</code>.
A task queue with <b>no message broker</b>. Your app hands slow work —
sending email, processing uploads, running pipelines — to a background
worker and gets the result later; the queue, results, and schedules
all live in{" "}
<b>
one <code>SQLite</code> file
</b>{" "}
(scale to <code>Postgres</code>). First-class{" "}
<b>Python, Node, and Java</b> over one Rust core.
</p>
<div className="btns">
<Link className="btn pri" to={active.docHref}>
Quickstart →
</Link>
<Link className="btn sec" to={`/${sdk}/getting-started/installation`}>
Install
</Link>
<a className="btn gho" href="https://github.com/ByteVeda/taskito">
GitHub ↗
</a>
</div>
<div className="metarow">
<span>Brokerless</span>
<span>No broker</span>
<span>Rust core</span>
<span>{label} SDK</span>
<span>DAG workflows</span>
<span>MIT licensed</span>
<span>Python · Node · Java</span>
</div>
</div>

Expand Down Expand Up @@ -124,14 +126,6 @@ export function Hero() {
))}
</div>
</div>

<div className="hero-doclinks">
{HERO_PANES.map((p) => (
<Link key={p.sdk} className="hero-doclink" to={p.docHref}>
{p.docLabel} →
</Link>
))}
</div>
</div>
</section>
);
Expand Down
41 changes: 38 additions & 3 deletions docs/app/components/mdx/table.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,49 @@
import type { ComponentProps } from "react";
import {
Children,
type ComponentProps,
isValidElement,
type ReactNode,
} from "react";

/** Count body rows and the widest row's cell count, so large tables can opt into
* the frozen header/first-column treatment. Walks past thead/tbody to the trs. */
function measure(children: ReactNode): { rows: number; cols: number } {
let rows = 0;
let cols = 0;
const walk = (node: ReactNode) => {
for (const child of Children.toArray(node)) {
if (!isValidElement(child)) {
continue;
}
const el = child as { type: unknown; props?: { children?: ReactNode } };
if (el.type === "tr") {
rows += 1;
const cells = Children.toArray(el.props?.children).filter(
isValidElement,
);
cols = Math.max(cols, cells.length);
} else {
walk(el.props?.children);
}
}
};
walk(children);
return { rows, cols };
}

/**
* Wraps every Markdown/MDX `<table>` in the prototype's `.md-table` shell so
* tables across the docs get the rounded surface, header band, and row rules
* from `docs.css`. Mapped onto the `table` element in `mdxComponents`, so it
* applies everywhere without touching individual pages.
* applies everywhere without touching individual pages. Wide or long tables
* additionally get `sticky` — a frozen header row and first column — so the
* feature/tool axes stay visible while scrolling a large comparison matrix.
*/
export function MdxTable(props: ComponentProps<"table">) {
const { rows, cols } = measure(props.children);
const sticky = cols >= 5 || rows >= 12;
return (
<div className="md-table">
<div className={sticky ? "md-table sticky" : "md-table"}>
<table {...props} />
</div>
);
Expand Down
70 changes: 63 additions & 7 deletions docs/app/components/mermaid.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useId, useRef, useState } from "react";
import { createPortal } from "react-dom";
import {
applyDiagramTheme,
diagramThemeCss,
Expand All @@ -8,9 +9,14 @@ import { useThemeMode } from "@/lib/theme";

export function Mermaid({ chart }: { chart: string }) {
const id = useId();
const containerRef = useRef<HTMLDivElement>(null);
const resolvedTheme = useThemeMode();
const [svg, setSvg] = useState<string>("");
// Inline diagrams fit the column; clicking opens a full-viewport overlay where
// the chart renders large (already "zoomed in") — readable without an inline
// scrollbar. Click anywhere or press Escape to close.
const [zoomed, setZoomed] = useState(false);
const triggerRef = useRef<HTMLButtonElement>(null);
const modalRef = useRef<HTMLButtonElement>(null);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

useEffect(() => {
let cancelled = false;
Expand Down Expand Up @@ -54,12 +60,62 @@ export function Mermaid({ chart }: { chart: string }) {
};
}, [chart, id, resolvedTheme]);

useEffect(() => {
if (!zoomed) {
return;
}
// Focus the overlay; cleanup restores focus to the trigger on close.
modalRef.current?.focus();
const onKey = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setZoomed(false);
} else if (event.key === "Tab") {
// The overlay is the only focusable element — trap Tab on it so
// focus can't reach background controls behind the modal.
event.preventDefault();
modalRef.current?.focus();
}
};
document.addEventListener("keydown", onKey);
const prevOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
return () => {
document.removeEventListener("keydown", onKey);
document.body.style.overflow = prevOverflow;
// Read the ref fresh: the trigger remounts on close and is focusable by
// the time cleanup runs (it was null while zoomed).
triggerRef.current?.focus();
};
}, [zoomed]);

// Only one SVG is in the DOM per state (inline OR overlay), so there's no
// duplicate-id copy to break the arrowhead/marker `url(#…)` references.
return (
<div
ref={containerRef}
className="my-6 flex justify-center [&_svg]:max-w-full"
// biome-ignore lint/security/noDangerouslySetInnerHtml: mermaid produces trusted SVG from author content
dangerouslySetInnerHTML={{ __html: svg }}
/>
<>
{!zoomed && (
<button
ref={triggerRef}
type="button"
className="mermaid-fig"
aria-label="Enlarge diagram"
onClick={() => setZoomed(true)}
// biome-ignore lint/security/noDangerouslySetInnerHtml: mermaid produces trusted SVG from author content
dangerouslySetInnerHTML={{ __html: svg }}
/>
)}
{zoomed &&
createPortal(
<button
ref={modalRef}
type="button"
className="mermaid-modal"
aria-label="Close enlarged diagram"
onClick={() => setZoomed(false)}
// biome-ignore lint/security/noDangerouslySetInnerHtml: mermaid produces trusted SVG from author content
dangerouslySetInnerHTML={{ __html: svg }}
/>,
document.body,
)}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
</>
);
}
5 changes: 4 additions & 1 deletion docs/app/components/ui/site-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,12 @@ const LINKS: { label: string; href: string; sdk?: boolean }[] = [
export function SiteNav({
onSearch,
onMenu,
showSdkSelect = true,
}: {
onSearch?: () => void;
onMenu?: () => void;
// Landing hides it — the hero language tabs already own SDK selection there.
showSdkSelect?: boolean;
}) {
const sdk = useActiveSdk();
return (
Expand Down Expand Up @@ -197,7 +200,7 @@ export function SiteNav({
))}
</div>
<div className="navright">
<SdkSelect />
{showSdkSelect ? <SdkSelect /> : null}
<button type="button" className="kbar" onClick={onSearch}>
<Search size={14} />
<span>Search</span>
Expand Down
4 changes: 2 additions & 2 deletions docs/app/lib/landing-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ import org.byteveda.taskito.task.Task;
import org.byteveda.taskito.worker.Worker;

Task<int[]> add = Task.of("add", int[].class).retries(3);

try (Taskito queue = Taskito.builder().sqlite("tasks.db").open();
Worker worker = queue.worker()
.handle(add, p -> p[0] + p[1])
.start()) {
String id = queue.enqueue(add, new int[] {2, 3});
queue.awaitJob(id, java.time.Duration.ofSeconds(10));
System.out.println(queue.getResult(id, Integer.class).orElseThrow()); // → 5
var sum = queue.getResult(id, Integer.class).orElseThrow();
System.out.println(sum); // → 5
}`,
output: [
{ glyph: "$", glyphKind: "p", text: "java -cp app.jar Tasks" },
Expand Down
16 changes: 16 additions & 0 deletions docs/app/lib/mermaid-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const DARK_VARIABLES = {
actorLineColor: "#5c5c70",
signalColor: "#ececf4",
signalTextColor: "#ececf4",
// Badge circle is filled with signalColor (near-white here); use dark text.
sequenceNumberColor: "#08080c",
labelBoxBkgColor: "#13131d",
labelBoxBorderColor: "#33334a",
loopTextColor: "#ececf4",
Expand Down Expand Up @@ -82,6 +84,8 @@ const LIGHT_VARIABLES = {
actorLineColor: "#8b877a",
signalColor: "#1b1a15",
signalTextColor: "#1b1a15",
// Badge circle is filled with signalColor (near-black here); use light text.
sequenceNumberColor: "#ffffff",
labelBoxBkgColor: "#ffffff",
labelBoxBorderColor: "#cfc9ba",
loopTextColor: "#1b1a15",
Expand All @@ -106,6 +110,12 @@ const DARK_THEME_CSS = `
.er.relationshipLabel,
.er.relationshipLabelBox { fill: #ececf4 !important; }
.er.relationshipLabelBox + text { fill: #0f0f17 !important; }
/* subgraph cluster + unstyled ("default") flowchart nodes aren't covered by
themeVariables reliably, so pin them here; turquoise marks the cluster. */
.cluster rect { fill: #0c0c13 !important; stroke: #40e0d0 !important; }
.cluster .nodeLabel, .cluster span, .cluster text { fill: #ececf4 !important; color: #ececf4 !important; }
.node.default rect, .node.default polygon, .node.default path { fill: #13131d !important; stroke: #33334a !important; }
.node.default .nodeLabel, .node.default span, .node.default text { fill: #ececf4 !important; color: #ececf4 !important; }
`;

const LIGHT_THEME_CSS = `
Expand All @@ -116,6 +126,12 @@ const LIGHT_THEME_CSS = `
.er .er.attribute-text,
.er .attribute-text,
.er text { fill: #1b1a15 !important; }
/* subgraph cluster + unstyled ("default") flowchart nodes aren't covered by
themeVariables reliably, so pin them here; turquoise marks the cluster. */
.cluster rect { fill: #fbf9f3 !important; stroke: #0d9e8f !important; }
.cluster .nodeLabel, .cluster span, .cluster text { fill: #1b1a15 !important; color: #1b1a15 !important; }
.node.default rect, .node.default polygon, .node.default path { fill: #ffffff !important; stroke: #cfc9ba !important; }
.node.default .nodeLabel, .node.default span, .node.default text { fill: #1b1a15 !important; color: #1b1a15 !important; }
`;

export function diagramThemeCss(theme: DiagramTheme): string {
Expand Down
6 changes: 5 additions & 1 deletion docs/app/routes/docs.$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,12 @@ export default function DocRoute({ params }: Route.ComponentProps) {
);
}

// Last path segment as a page id, so page-specific styling (e.g. FAQ question
// numbering) can hook a single page via `.article[data-page="faq"]`.
const pageId = path.split("/").filter(Boolean).pop() ?? "";

return (
<article className="article">
<article className="article" data-page={pageId}>
<Breadcrumb path={path} />
{meta?.title ? <h1>{meta.title}</h1> : null}
{meta?.description ? <p className="lead">{meta.description}</p> : null}
Expand Down
Loading