SHOP

tcmts.cli.test.e2e.jobs.SHOP · #3pple2sn · term · runs anywhere

export const SHOP = (outbox: string, version: string) => `// tcm: namespace shop
import assert from "node:assert/strict";
import { appendFileSync } from "node:fs";
import { enqueue, enqueueAfter, every, request, runJobs } from "#codebase/lib/server";

const OUTBOX = ${JSON.stringify(outbox)};
const tries = new Map<string, number>();

export async function sendWelcome(user: string): Promise<void> {
  appendFileSync(OUTBOX, "welcome " + user + " (${version})\\n");
}
export async function flaky(id: string): Promise<void> {
  const n = (tries.get(id) ?? 0) + 1;
  tries.set(id, n);
  if (n < 2) throw new Error("transient failure " + n);
  appendFileSync(OUTBOX, "flaky " + id + " ok after " + n + "\\n");
}
export async function signup(user: string): Promise<string> {
  request();
  return enqueue(sendWelcome, user);
}
export async function signupLater(user: string): Promise<string> {
  request();
  return enqueueAfter(3, sendWelcome, user);
}
export async function startFlaky(): Promise<string> {
  request();
  return enqueue(flaky, "x");
}
export async function enqueueInline(): Promise<string> {
  request();
  return enqueue(async () => {});
}
export const heartbeat = every("1s", async () => appendFileSync(OUTBOX, "tick\\n"));

export async function main() {
  const b = document.createElement("button");
  b.onclick = async () => console.log(await signup("ada"), await signupLater("grace"), await startFlaky(), await enqueueInline());
  document.body.append(b);
}

// jobs are testable inline, no server: runJobs() drains the queue
const ran: string[] = [];
export async function record(x: string): Promise<void> { ran.push(x); }
export const testJobsRunInline = async () => {
  enqueue(record, "a");
  enqueue(record, "b");
  assert.deepEqual(await runJobs(), { done: 2, failed: 0 });
  assert.deepEqual(ran, ["a", "b"]);
};
`

used by