@adityanair98/api-oracle 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +74 -0
- package/dist/dashboard/public/app.js +1004 -0
- package/dist/dashboard/public/index.html +142 -0
- package/dist/dashboard/public/public/app.js +1004 -0
- package/dist/dashboard/public/public/index.html +142 -0
- package/dist/dashboard/public/public/styles.css +1464 -0
- package/dist/dashboard/public/styles.css +1464 -0
- package/dist/dashboard/routes/api.d.ts +7 -0
- package/dist/dashboard/routes/api.js +245 -0
- package/dist/dashboard/server.d.ts +9 -0
- package/dist/dashboard/server.js +45 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +23 -0
- package/dist/knowledge/db.d.ts +22 -0
- package/dist/knowledge/db.js +182 -0
- package/dist/knowledge/schema.d.ts +275 -0
- package/dist/knowledge/schema.js +135 -0
- package/dist/knowledge/scorer.d.ts +63 -0
- package/dist/knowledge/scorer.js +314 -0
- package/dist/knowledge/search.d.ts +37 -0
- package/dist/knowledge/search.js +111 -0
- package/dist/knowledge/synonyms.d.ts +36 -0
- package/dist/knowledge/synonyms.js +523 -0
- package/dist/knowledge/tfidf.d.ts +42 -0
- package/dist/knowledge/tfidf.js +138 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +40 -0
- package/dist/tools/check-freshness.d.ts +9 -0
- package/dist/tools/check-freshness.js +95 -0
- package/dist/tools/compare-apis.d.ts +8 -0
- package/dist/tools/compare-apis.js +149 -0
- package/dist/tools/find-api.d.ts +9 -0
- package/dist/tools/find-api.js +120 -0
- package/dist/tools/get-setup-guide.d.ts +8 -0
- package/dist/tools/get-setup-guide.js +127 -0
- package/dist/updater/linter.d.ts +31 -0
- package/dist/updater/linter.js +219 -0
- package/dist/updater/report.d.ts +29 -0
- package/dist/updater/report.js +96 -0
- package/dist/updater/staleness.d.ts +39 -0
- package/dist/updater/staleness.js +66 -0
- package/dist/updater/version-tracker.d.ts +28 -0
- package/dist/updater/version-tracker.js +50 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.js +13 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.js +32 -0
- package/package.json +56 -0
- package/src/entries/ai/anthropic.json +95 -0
- package/src/entries/ai/eleven-labs.json +90 -0
- package/src/entries/ai/openai.json +95 -0
- package/src/entries/ai/replicate.json +87 -0
- package/src/entries/ai/resemble-ai.json +88 -0
- package/src/entries/ai/stability-ai.json +89 -0
- package/src/entries/analytics/posthog.json +88 -0
- package/src/entries/analytics/sentry.json +84 -0
- package/src/entries/auth/auth0.json +90 -0
- package/src/entries/auth/clerk.json +95 -0
- package/src/entries/cms/contentful.json +92 -0
- package/src/entries/cms/sanity.json +92 -0
- package/src/entries/cms/strapi.json +93 -0
- package/src/entries/commerce/medusa.json +91 -0
- package/src/entries/commerce/shopify-api.json +91 -0
- package/src/entries/communication/sendbird.json +85 -0
- package/src/entries/communication/stream-chat.json +94 -0
- package/src/entries/database/firebase.json +88 -0
- package/src/entries/database/neon.json +94 -0
- package/src/entries/database/planetscale.json +95 -0
- package/src/entries/database/supabase.json +94 -0
- package/src/entries/database/upstash.json +94 -0
- package/src/entries/devops/fly-io.json +90 -0
- package/src/entries/devops/netlify.json +90 -0
- package/src/entries/devops/railway.json +90 -0
- package/src/entries/devops/vercel.json +90 -0
- package/src/entries/email/mailgun.json +91 -0
- package/src/entries/email/postmark.json +91 -0
- package/src/entries/email/resend.json +89 -0
- package/src/entries/email/sendgrid.json +90 -0
- package/src/entries/forms/formspark.json +85 -0
- package/src/entries/forms/typeform.json +98 -0
- package/src/entries/infrastructure/aws-s3.json +104 -0
- package/src/entries/infrastructure/cloudflare-r2.json +92 -0
- package/src/entries/infrastructure/cloudflare-workers.json +92 -0
- package/src/entries/infrastructure/digital-ocean-spaces.json +87 -0
- package/src/entries/integration/nango.json +90 -0
- package/src/entries/integration/zapier.json +92 -0
- package/src/entries/maps/google-maps.json +89 -0
- package/src/entries/maps/mapbox.json +87 -0
- package/src/entries/media/deepgram.json +84 -0
- package/src/entries/media/imgix.json +84 -0
- package/src/entries/media/mux.json +94 -0
- package/src/entries/messaging/ably.json +94 -0
- package/src/entries/messaging/pusher.json +94 -0
- package/src/entries/messaging/twilio.json +94 -0
- package/src/entries/messaging/vonage.json +89 -0
- package/src/entries/notifications/knock.json +84 -0
- package/src/entries/notifications/novu.json +84 -0
- package/src/entries/notifications/onesignal.json +84 -0
- package/src/entries/payments/lemonsqueezy.json +91 -0
- package/src/entries/payments/paddle.json +90 -0
- package/src/entries/payments/paypal.json +91 -0
- package/src/entries/payments/razorpay.json +85 -0
- package/src/entries/payments/square.json +91 -0
- package/src/entries/payments/stripe.json +96 -0
- package/src/entries/scheduling/cal-com.json +90 -0
- package/src/entries/scheduling/calendly.json +90 -0
- package/src/entries/search/algolia.json +96 -0
- package/src/entries/security/arcjet.json +89 -0
- package/src/entries/security/snyk.json +90 -0
- package/src/entries/storage/cloudinary.json +93 -0
- package/src/entries/storage/uploadthing.json +90 -0
- package/src/entries/testing/browserstack.json +86 -0
- package/src/entries/testing/checkly.json +89 -0
- package/src/entries/workflow/inngest.json +88 -0
- package/src/entries/workflow/temporal.json +90 -0
- package/src/entries/workflow/trigger-dev.json +89 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Checkly",
|
|
3
|
+
"slug": "checkly",
|
|
4
|
+
"category": "testing",
|
|
5
|
+
"subcategory": "api-monitoring",
|
|
6
|
+
"website": "https://checklyhq.com",
|
|
7
|
+
"description": "Checkly is a monitoring-as-code platform that runs Playwright browser checks and API checks on a schedule to verify your production app is working. Write checks as code (JavaScript/TypeScript), deploy via CLI, and get alerting when they fail. Think synthetic testing meets uptime monitoring.",
|
|
8
|
+
"useCases": [
|
|
9
|
+
{
|
|
10
|
+
"task": "Monitor production API endpoints with scheduled health checks",
|
|
11
|
+
"fit": "perfect"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"task": "Run Playwright E2E tests against production on a schedule",
|
|
15
|
+
"fit": "perfect"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"task": "Get alerted when a critical user journey breaks in production",
|
|
19
|
+
"fit": "good"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"task": "Verify third-party API integrations are still working",
|
|
23
|
+
"fit": "good"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"auth": {
|
|
27
|
+
"method": "api_key",
|
|
28
|
+
"setupSteps": [
|
|
29
|
+
"Create a Checkly account at checklyhq.com",
|
|
30
|
+
"Navigate to User Settings in the top-right menu",
|
|
31
|
+
"Click on API Keys and then Create API Key",
|
|
32
|
+
"Copy the generated API key",
|
|
33
|
+
"Run npx checkly login or set CHECKLY_API_KEY and CHECKLY_ACCOUNT_ID as environment variables"
|
|
34
|
+
],
|
|
35
|
+
"envVarName": "CHECKLY_API_KEY",
|
|
36
|
+
"codeSnippet": "// CHECKLY_API_KEY=your_api_key\n// CHECKLY_ACCOUNT_ID=your_account_id\n\n// Login via CLI (stores credentials locally)\n// npx checkly login\n\n// Or set env vars for CI environments\nimport { ApiCheck } from '@checkly/cli/constructs';\n\nnew ApiCheck('homepage-health', {\n name: 'Homepage health check',\n request: {\n url: 'https://api.example.com/health',\n method: 'GET',\n assertions: [\n { source: 'STATUS_CODE', comparison: 'EQUALS', target: '200' },\n ],\n },\n});"
|
|
37
|
+
},
|
|
38
|
+
"pricing": {
|
|
39
|
+
"model": "freemium",
|
|
40
|
+
"freeTier": "Free: 10,000 check runs/month, 2 team members, 5 minute check interval",
|
|
41
|
+
"startingPrice": "$20/month (Developer) for 50,000 check runs/month, 1 minute interval, private locations",
|
|
42
|
+
"costPer": null,
|
|
43
|
+
"pricingUrl": "https://www.checklyhq.com/pricing/"
|
|
44
|
+
},
|
|
45
|
+
"rateLimits": {
|
|
46
|
+
"tier": "free tier",
|
|
47
|
+
"limit": "Check frequency minimum: 5 minutes (free), 1 minute (paid). Maximum check execution: 30 seconds for API checks, 4 minutes for browser checks.",
|
|
48
|
+
"notes": "Check run credits roll over within the month. Browser checks (Playwright) consume 2x check run credits vs API checks. Alerting is real-time with no delay.",
|
|
49
|
+
"retryStrategy": "Set check.retryStrategy to LINEAR or EXPONENTIAL in check config to handle transient failures. Configure alerting thresholds (e.g., alert after 2 consecutive failures)."
|
|
50
|
+
},
|
|
51
|
+
"sdk": {
|
|
52
|
+
"primaryLanguage": "typescript",
|
|
53
|
+
"installCommand": "npm install --save-exact @checkly/cli",
|
|
54
|
+
"importStatement": "import { ApiCheck, BrowserCheck, CheckGroup } from '@checkly/cli/constructs';",
|
|
55
|
+
"otherLanguages": ["javascript"]
|
|
56
|
+
},
|
|
57
|
+
"codeExamples": [
|
|
58
|
+
{
|
|
59
|
+
"title": "Define an API health check with Checkly CLI",
|
|
60
|
+
"language": "typescript",
|
|
61
|
+
"code": "import { ApiCheck, AssertionBuilder, Frequency } from '@checkly/cli/constructs';\n\nnew ApiCheck('orders-api-health', {\n name: 'Orders API — health endpoint',\n activated: true,\n muted: false,\n frequency: Frequency.EVERY_5M,\n locations: ['us-east-1', 'eu-west-1'],\n tags: ['api', 'production'],\n request: {\n url: 'https://api.example.com/v1/health',\n method: 'GET',\n followRedirects: true,\n timeout: 10_000,\n assertions: [\n AssertionBuilder.statusCode().equals(200),\n AssertionBuilder.responseTime().lessThan(2000),\n AssertionBuilder.jsonBody('$.status').equals('ok'),\n ],\n },\n retryStrategy: {\n type: 'LINEAR',\n baseBackoffSeconds: 60,\n maxRetries: 2,\n maxDurationSeconds: 600,\n },\n alertChannels: [],\n});",
|
|
62
|
+
"notes": "Use AssertionBuilder for type-safe assertion definitions. Deploy with: npx checkly deploy. The check runs from all specified AWS regions simultaneously, so you detect region-specific outages."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"title": "Define a Playwright browser check",
|
|
66
|
+
"language": "typescript",
|
|
67
|
+
"code": "import { BrowserCheck, Frequency } from '@checkly/cli/constructs';\nimport * as path from 'path';\n\nnew BrowserCheck('checkout-flow', {\n name: 'Checkout flow — add to cart and proceed',\n activated: true,\n frequency: Frequency.EVERY_10M,\n locations: ['us-east-1', 'eu-central-1'],\n tags: ['browser', 'critical-path'],\n code: {\n entrypoint: path.join(__dirname, 'checkout.spec.ts'),\n },\n retryStrategy: {\n type: 'EXPONENTIAL',\n baseBackoffSeconds: 30,\n maxRetries: 2,\n maxDurationSeconds: 300,\n },\n});\n\n// In checkout.spec.ts (co-located file):\n// import { test, expect } from '@playwright/test';\n// test('add to cart and proceed to checkout', async ({ page }) => {\n// await page.goto('https://shop.example.com');\n// await page.getByRole('button', { name: 'Add to cart' }).first().click();\n// await page.getByRole('link', { name: 'Checkout' }).click();\n// await expect(page).toHaveURL(/checkout/);\n// });",
|
|
68
|
+
"notes": "Browser checks reference a separate Playwright spec file via entrypoint. The spec file must live alongside the check definition. Each browser check run consumes 2x credits on the free tier. Set frequency conservatively (every 10 minutes) for credit-heavy browser checks."
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"gotchas": [
|
|
72
|
+
"Checkly browser checks (Playwright) use their own isolated version of Playwright, not the version installed in your project. Playwright API changes between versions can cause checks written for a newer Playwright version to fail on Checkly if they haven't updated yet. Pin your Playwright syntax to a common, stable API.",
|
|
73
|
+
"Check run credits on the free tier (10,000/month) sound like a lot, but a 5-minute interval check running 24/7 consumes 12×24×30 = 8,640 credits/month. Two such checks nearly exhaust the free tier. Plan check frequency carefully.",
|
|
74
|
+
"Checkly runs from global check locations (AWS regions). If your API requires IP allowlisting, you need to allowlist all Checkly IP addresses — which change when new regions are added. Use Checkly Private Locations instead for self-hosted environments."
|
|
75
|
+
],
|
|
76
|
+
"reliability": {
|
|
77
|
+
"uptimeGuarantee": "99.9% uptime SLA (paid plans)",
|
|
78
|
+
"statusPageUrl": "https://status.checklyhq.com",
|
|
79
|
+
"notes": "AWS-hosted multi-region infrastructure. Check results are stored independently of the monitored service, ensuring alerting continues even during partial outages."
|
|
80
|
+
},
|
|
81
|
+
"qualityScore": 8,
|
|
82
|
+
"qualityJustification": "Best monitoring-as-code platform for teams that want Playwright-level testing in production on a schedule. The Checkly CLI is excellent — checks defined as code means they're version-controlled and reviewable. Generous free tier for small projects. Main limitation: browser check credit consumption and Playwright version lag.",
|
|
83
|
+
"alternatives": ["browserstack"],
|
|
84
|
+
"complementary": ["vercel", "fly-io", "sentry"],
|
|
85
|
+
"bestFor": "Synthetic monitoring of production APIs and user journeys — run Playwright checks on a schedule and get alerted the moment a critical flow breaks",
|
|
86
|
+
"lastVerified": "2026-02-25",
|
|
87
|
+
"entryVersion": 1,
|
|
88
|
+
"addedBy": "claude-code-session-4"
|
|
89
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Inngest",
|
|
3
|
+
"slug": "inngest",
|
|
4
|
+
"category": "workflow",
|
|
5
|
+
"subcategory": "background-jobs",
|
|
6
|
+
"website": "https://www.inngest.com",
|
|
7
|
+
"description": "Event-driven background job platform for TypeScript and JavaScript. Write durable functions as plain code that respond to events, with built-in retries, step functions, scheduling, and fan-out. No separate queue infrastructure needed — integrates via HTTP with any serverless platform.",
|
|
8
|
+
"useCases": [
|
|
9
|
+
{
|
|
10
|
+
"task": "Run background tasks after user actions",
|
|
11
|
+
"fit": "perfect"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"task": "Orchestrate multi-step workflows with error recovery",
|
|
15
|
+
"fit": "perfect"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"task": "Run scheduled and cron jobs",
|
|
19
|
+
"fit": "perfect"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"task": "Process incoming webhook events",
|
|
23
|
+
"fit": "good"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"auth": {
|
|
27
|
+
"method": "api_key",
|
|
28
|
+
"setupSteps": [
|
|
29
|
+
"Create an account at inngest.com",
|
|
30
|
+
"Create a new app in the Inngest dashboard to get an event key and signing key",
|
|
31
|
+
"Set the INNGEST_EVENT_KEY and INNGEST_SIGNING_KEY environment variables in your app",
|
|
32
|
+
"Install the SDK and serve the Inngest handler at the /api/inngest route in your framework (Next.js, Express, Fastify, etc.)"
|
|
33
|
+
],
|
|
34
|
+
"envVarName": "INNGEST_EVENT_KEY",
|
|
35
|
+
"codeSnippet": "import { Inngest } from 'inngest';\n\nexport const inngest = new Inngest({\n id: 'my-app',\n eventKey: process.env.INNGEST_EVENT_KEY,\n});"
|
|
36
|
+
},
|
|
37
|
+
"pricing": {
|
|
38
|
+
"model": "freemium",
|
|
39
|
+
"freeTier": "Free: 50,000 function runs/month, 3-day log retention",
|
|
40
|
+
"startingPrice": "$25/month (Basic) for 150,000 runs/month",
|
|
41
|
+
"costPer": null,
|
|
42
|
+
"pricingUrl": "https://www.inngest.com/pricing"
|
|
43
|
+
},
|
|
44
|
+
"rateLimits": {
|
|
45
|
+
"tier": "free tier",
|
|
46
|
+
"limit": "50,000 function runs/month, 3-day log history, community support",
|
|
47
|
+
"notes": "Inngest functions run wherever your app runs (Vercel, Railway, Fly.io). The local dev server (npx inngest-cli@latest dev) runs entirely offline without an account.",
|
|
48
|
+
"retryStrategy": "Built-in automatic retry on thrown errors with exponential backoff. Configure via the retries option in createFunction or the function definition object. Step functions (step.run()) only retry the failed step, not the entire function."
|
|
49
|
+
},
|
|
50
|
+
"sdk": {
|
|
51
|
+
"primaryLanguage": "typescript",
|
|
52
|
+
"installCommand": "npm install --save-exact inngest",
|
|
53
|
+
"importStatement": "import { Inngest } from \"inngest\";",
|
|
54
|
+
"otherLanguages": ["python", "go"]
|
|
55
|
+
},
|
|
56
|
+
"codeExamples": [
|
|
57
|
+
{
|
|
58
|
+
"title": "Define and trigger an Inngest function",
|
|
59
|
+
"language": "typescript",
|
|
60
|
+
"code": "// lib/inngest.ts — shared client\nimport { Inngest } from 'inngest';\n\nexport const inngest = new Inngest({\n id: 'my-app',\n eventKey: process.env.INNGEST_EVENT_KEY,\n});\n\n// inngest/send-welcome-email.ts — function definition\nimport { inngest } from '../lib/inngest';\n\nexport const sendWelcomeEmail = inngest.createFunction(\n { id: 'send-welcome-email', retries: 3 },\n { event: 'user/signup.created' },\n async ({ event, step }) => {\n const { userId, email } = event.data;\n\n await step.run('send-email', async () => {\n // Any thrown error here triggers a retry of this step only\n await fetch('https://api.email.com/send', {\n method: 'POST',\n body: JSON.stringify({ to: email, subject: 'Welcome!' }),\n });\n });\n\n return { sent: true, userId };\n }\n);\n\n// app/api/route.ts — trigger an event from your API\nimport { inngest } from '../../lib/inngest';\n\nexport async function POST(req: Request) {\n const body = await req.json();\n\n await inngest.send({\n name: 'user/signup.created',\n data: { userId: body.userId, email: body.email },\n });\n\n return Response.json({ ok: true });\n}",
|
|
61
|
+
"notes": "The Inngest handler must also be served at /api/inngest. In Next.js App Router: export the handler from app/api/inngest/route.ts using the serve() helper from 'inngest/next'."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"title": "Multi-step workflow with step.run()",
|
|
65
|
+
"language": "typescript",
|
|
66
|
+
"code": "import { inngest } from '../lib/inngest';\nimport { db } from '../lib/db';\nimport { resend } from '../lib/resend';\n\nexport const onboardUser = inngest.createFunction(\n { id: 'onboard-user', retries: 5 },\n { event: 'user/signup.created' },\n async ({ event, step }) => {\n const { userId } = event.data;\n\n // Step 1: Fetch user data — retried independently if it fails\n const user = await step.run('fetch-user', async () => {\n return db.users.findUnique({ where: { id: userId } });\n });\n\n // Step 2: Send welcome email — only runs after step 1 succeeds\n await step.run('send-welcome-email', async () => {\n await resend.emails.send({\n from: 'hello@acme.com',\n to: user.email,\n subject: 'Welcome to Acme!',\n html: `<h1>Hi ${user.name}!</h1>`,\n });\n });\n\n // Step 3: Update onboarding status in DB\n await step.run('mark-onboarded', async () => {\n await db.users.update({\n where: { id: userId },\n data: { onboardedAt: new Date() },\n });\n });\n\n return { userId, onboarded: true };\n }\n);",
|
|
67
|
+
"notes": "Each step.run() call is individually memoized. If step 3 fails and retries, Inngest replays the function but skips steps 1 and 2 using stored results — they do not re-execute."
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"gotchas": [
|
|
71
|
+
"Inngest functions are deployed as part of your existing app, not as standalone workers. Your app must expose an /api/inngest HTTP endpoint that Inngest calls via webhook. If your server is down or cold-starts too slowly, function invocations can be delayed or missed.",
|
|
72
|
+
"The free tier's 3-day log retention makes debugging intermittent production issues difficult. Any log or run older than 3 days cannot be retrieved from the dashboard. For any production app, the paid tier with 30-day retention is practically required.",
|
|
73
|
+
"Code outside of step.run() blocks runs on every replay. When Inngest retries a function, it replays the entire function from the top but skips completed steps using memoized results. Any side effects (API calls, database writes) placed outside step.run() will execute multiple times. Always wrap effectful code in step.run()."
|
|
74
|
+
],
|
|
75
|
+
"reliability": {
|
|
76
|
+
"uptimeGuarantee": "99.9% uptime SLA (Pro tier)",
|
|
77
|
+
"statusPageUrl": "https://www.inngeststatus.com",
|
|
78
|
+
"notes": "Functions execute within your own infrastructure. Inngest acts as an event relay and orchestration layer. Your app's reliability directly affects function execution reliability."
|
|
79
|
+
},
|
|
80
|
+
"qualityScore": 8,
|
|
81
|
+
"qualityJustification": "Excellent developer experience — works within your existing framework (Next.js, Express, Fastify) without a separate worker process. Step functions with automatic memoization and per-step retries are genuinely powerful for complex workflows. The local dev server with no account required is a standout feature. Slight drawback: free tier log retention is too short for production debugging.",
|
|
82
|
+
"alternatives": ["trigger-dev", "temporal"],
|
|
83
|
+
"complementary": ["vercel", "resend", "stripe", "supabase", "neon"],
|
|
84
|
+
"bestFor": "Event-driven background jobs and multi-step workflows that run within your existing serverless or server infrastructure",
|
|
85
|
+
"lastVerified": "2026-02-25",
|
|
86
|
+
"entryVersion": 1,
|
|
87
|
+
"addedBy": "claude-code-session-4"
|
|
88
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Temporal",
|
|
3
|
+
"slug": "temporal",
|
|
4
|
+
"category": "workflow",
|
|
5
|
+
"subcategory": "workflow-engine",
|
|
6
|
+
"website": "https://temporal.io",
|
|
7
|
+
"description": "Open-source, battle-tested distributed workflow engine for running durable, fault-tolerant long-running processes. Write complex business logic as ordinary code; Temporal handles persistence, retries, timeouts, and recovery from infrastructure failures automatically.",
|
|
8
|
+
"useCases": [
|
|
9
|
+
{
|
|
10
|
+
"task": "Orchestrate multi-service business processes",
|
|
11
|
+
"fit": "perfect"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"task": "Long-running workflows spanning days or weeks with human approval steps",
|
|
15
|
+
"fit": "perfect"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"task": "Saga patterns for distributed transactions with compensating actions",
|
|
19
|
+
"fit": "perfect"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"task": "Run reliable scheduled tasks and cron jobs",
|
|
23
|
+
"fit": "good"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"auth": {
|
|
27
|
+
"method": "api_key",
|
|
28
|
+
"setupSteps": [
|
|
29
|
+
"For self-hosted: install Temporal server via Docker using 'docker compose up temporal' from the temporalio/docker-compose repository",
|
|
30
|
+
"Install the TypeScript SDK packages: @temporalio/client, @temporalio/worker, @temporalio/workflow, @temporalio/activity",
|
|
31
|
+
"Connect workers to localhost:7233 for local development",
|
|
32
|
+
"For Temporal Cloud: create a namespace at cloud.temporal.io and generate an API key from account settings",
|
|
33
|
+
"Set the TEMPORAL_API_KEY and TEMPORAL_NAMESPACE environment variables for Temporal Cloud connections"
|
|
34
|
+
],
|
|
35
|
+
"envVarName": "TEMPORAL_API_KEY",
|
|
36
|
+
"codeSnippet": "import { Client, Connection } from '@temporalio/client';\n\nconst connection = await Connection.connect({\n address: process.env.TEMPORAL_ADDRESS ?? 'localhost:7233',\n // For Temporal Cloud, add TLS and API key options here\n});\n\nexport const client = new Client({ connection,\n namespace: process.env.TEMPORAL_NAMESPACE ?? 'default',\n});"
|
|
37
|
+
},
|
|
38
|
+
"pricing": {
|
|
39
|
+
"model": "freemium",
|
|
40
|
+
"freeTier": "Self-host: completely free and unlimited. Temporal Cloud: free trial with $1,000 in credits",
|
|
41
|
+
"startingPrice": "Temporal Cloud: usage-based, approximately $0.42 per 1M workflow actions",
|
|
42
|
+
"costPer": "$0.42/1M workflow actions (executions, signals, queries, timers each count as one action)",
|
|
43
|
+
"pricingUrl": "https://temporal.io/pricing"
|
|
44
|
+
},
|
|
45
|
+
"rateLimits": {
|
|
46
|
+
"tier": "self-hosted",
|
|
47
|
+
"limit": "No limits when self-hosted. Temporal Cloud: configurable rate limits per namespace.",
|
|
48
|
+
"notes": "Self-hosted Temporal can handle millions of concurrent workflows depending on your database and server resources. Temporal Cloud scales automatically but has namespace-level rate limits that can be raised by contacting support.",
|
|
49
|
+
"retryStrategy": "Built-in. RetryPolicy in ActivityOptions controls maxAttempts and backoff coefficients. Workflows are automatically replayed from their event history on worker restart — no in-flight data is lost across restarts or failures."
|
|
50
|
+
},
|
|
51
|
+
"sdk": {
|
|
52
|
+
"primaryLanguage": "typescript",
|
|
53
|
+
"installCommand": "npm install --save-exact @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity",
|
|
54
|
+
"importStatement": "import { Client } from \"@temporalio/client\";",
|
|
55
|
+
"otherLanguages": ["go", "java", "python", "php", "dotnet"]
|
|
56
|
+
},
|
|
57
|
+
"codeExamples": [
|
|
58
|
+
{
|
|
59
|
+
"title": "Define a Workflow with Activities and start it from a Client",
|
|
60
|
+
"language": "typescript",
|
|
61
|
+
"code": "// activities.ts — I/O and side effects go here\nimport type { ActivityOptions } from '@temporalio/activity';\n\nexport async function processPayment(orderId: string, amount: number): Promise<string> {\n // Call your payment provider SDK here\n const result = await stripe.charges.create({ amount, currency: 'usd' });\n return result.id;\n}\n\nexport async function sendConfirmationEmail(orderId: string, chargeId: string): Promise<void> {\n await resend.emails.send({\n from: 'orders@acme.com',\n to: 'customer@example.com',\n subject: `Order ${orderId} confirmed`,\n html: `<p>Charge ID: ${chargeId}</p>`,\n });\n}\n\n// workflow.ts — must be fully deterministic; no I/O, no Date.now(), no Math.random()\nimport { proxyActivities, log } from '@temporalio/workflow';\nimport type * as activities from './activities';\n\nconst { processPayment, sendConfirmationEmail } = proxyActivities<typeof activities>({\n startToCloseTimeout: '30 seconds',\n retry: { maximumAttempts: 3 },\n});\n\nexport async function orderWorkflow(orderId: string, amount: number): Promise<void> {\n log.info('Starting order workflow', { orderId });\n const chargeId = await processPayment(orderId, amount);\n await sendConfirmationEmail(orderId, chargeId);\n log.info('Order workflow complete', { orderId, chargeId });\n}\n\n// worker.ts — runs as a long-lived process alongside your app server\nimport { Worker } from '@temporalio/worker';\nimport * as activities from './activities';\n\nconst worker = await Worker.create({\n workflowsPath: require.resolve('./workflow'),\n activities,\n taskQueue: 'orders',\n});\nawait worker.run();\n\n// client-usage.ts — start the workflow from an API route\nimport { client } from './temporal-client';\n\nconst handle = await client.workflow.start(orderWorkflow, {\n taskQueue: 'orders',\n workflowId: `order-${orderId}`,\n args: [orderId, amount],\n});\nconsole.log('Workflow started:', handle.workflowId);",
|
|
62
|
+
"notes": "Activity functions contain all I/O and side effects. Workflow functions must be deterministic — all non-deterministic operations (network calls, timestamps, randomness) must be wrapped inside activities."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"title": "Long-running workflow with human approval signal",
|
|
66
|
+
"language": "typescript",
|
|
67
|
+
"code": "import {\n defineSignal,\n setHandler,\n condition,\n proxyActivities,\n sleep,\n} from '@temporalio/workflow';\nimport type * as activities from './activities';\n\nexport const approveSignal = defineSignal<[{ approved: boolean; reviewerId: string }]>('approve');\n\nconst { requestHumanReview, processApprovedWithdrawal, notifyRejected } =\n proxyActivities<typeof activities>({ startToCloseTimeout: '10 seconds' });\n\nexport async function withdrawalApprovalWorkflow(\n withdrawalId: string,\n amount: number\n): Promise<string> {\n let approvalResult: { approved: boolean; reviewerId: string } | null = null;\n\n // Register a signal handler — external callers can send this signal to the workflow\n setHandler(approveSignal, (result) => {\n approvalResult = result;\n });\n\n // Notify the review team that action is needed\n await requestHumanReview(withdrawalId, amount);\n\n // Wait up to 48 hours for a human to send the approval signal\n const approved = await condition(() => approvalResult !== null, '48 hours');\n\n if (!approved || !approvalResult?.approved) {\n await notifyRejected(withdrawalId);\n return 'rejected';\n }\n\n await processApprovedWithdrawal(withdrawalId, amount);\n return `approved-by-${approvalResult.reviewerId}`;\n}",
|
|
68
|
+
"notes": "The workflow sleeps durably — the worker process can restart, crash, or be redeployed during the 48-hour wait and the workflow will resume correctly. Send the signal via: client.workflow.getHandle(workflowId).signal(approveSignal, { approved: true, reviewerId: 'alice' })"
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"gotchas": [
|
|
72
|
+
"Temporal Workflows must be strictly deterministic. You cannot use Date.now(), Math.random(), or make direct network/database calls inside a workflow function. All I/O must live in Activities. The TypeScript sandbox enforces this at runtime, but non-deterministic code that slips through causes workflow history replay failures — these are extremely difficult to diagnose in production.",
|
|
73
|
+
"Temporal requires a continuously running worker process alongside your application server. Unlike Inngest or Trigger.dev, Temporal is NOT serverless — you must keep workers deployed and running. This adds meaningful infrastructure overhead: you need to manage worker scaling, health checks, and restarts separately from your app.",
|
|
74
|
+
"Temporal Cloud pricing is per workflow action, where a single workflow execution can generate dozens of actions (one per activity, signal, timer, query, etc.). This makes costs nearly impossible to estimate without load testing. Always profile workflow action counts under realistic load before committing to Temporal Cloud for cost-sensitive use cases.",
|
|
75
|
+
"The event history for a single workflow execution is limited to 51,200 events by default on Temporal Cloud. Workflows with large loops, many activities, or indefinite runtimes will hit this limit and fail with a hard error. Use the Continue-as-New pattern (continueAsNew()) to reset history for workflows that must run indefinitely."
|
|
76
|
+
],
|
|
77
|
+
"reliability": {
|
|
78
|
+
"uptimeGuarantee": "99.99% SLA (Temporal Cloud)",
|
|
79
|
+
"statusPageUrl": "https://status.temporal.io",
|
|
80
|
+
"notes": "Temporal Cloud is fully managed with global multi-region replication and automatic failover. Self-hosted deployments require operating a highly available Temporal server cluster with a supported database (PostgreSQL, MySQL, or Cassandra)."
|
|
81
|
+
},
|
|
82
|
+
"qualityScore": 8,
|
|
83
|
+
"qualityJustification": "The most powerful open-source workflow engine available — handles failures, retries, and persistent state automatically in a way that no other tool matches. Genuinely solves hard distributed systems problems that would otherwise require complex custom infrastructure. High learning curve (determinism constraint, worker management, new mental model) and infrastructure overhead make it best suited for teams with complex, mission-critical workflow needs rather than simple background jobs.",
|
|
84
|
+
"alternatives": ["trigger-dev", "inngest"],
|
|
85
|
+
"complementary": ["neon", "stripe", "resend"],
|
|
86
|
+
"bestFor": "Complex, long-running distributed workflows requiring bulletproof fault tolerance — order processing, financial transactions, and multi-step human-in-the-loop processes",
|
|
87
|
+
"lastVerified": "2026-02-25",
|
|
88
|
+
"entryVersion": 1,
|
|
89
|
+
"addedBy": "claude-code-session-4"
|
|
90
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Trigger.dev",
|
|
3
|
+
"slug": "trigger-dev",
|
|
4
|
+
"category": "workflow",
|
|
5
|
+
"subcategory": "background-jobs",
|
|
6
|
+
"website": "https://trigger.dev",
|
|
7
|
+
"description": "Open-source background job and workflow platform with a developer-first SDK. Write jobs as plain TypeScript functions with built-in retries, delays, concurrency controls, and real-time monitoring dashboard. No separate queue infrastructure needed.",
|
|
8
|
+
"useCases": [
|
|
9
|
+
{
|
|
10
|
+
"task": "Send emails after user signup",
|
|
11
|
+
"fit": "perfect"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"task": "Process uploaded files in the background",
|
|
15
|
+
"fit": "perfect"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"task": "Run scheduled cron jobs",
|
|
19
|
+
"fit": "perfect"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"task": "Fan-out tasks with parallelism",
|
|
23
|
+
"fit": "good"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"auth": {
|
|
27
|
+
"method": "api_key",
|
|
28
|
+
"setupSteps": [
|
|
29
|
+
"Create an account at trigger.dev",
|
|
30
|
+
"Create a new project in the dashboard",
|
|
31
|
+
"Copy the secret key from the project settings page",
|
|
32
|
+
"Set the TRIGGER_SECRET_KEY environment variable in your app",
|
|
33
|
+
"Install the SDK and optionally set TRIGGER_API_URL if self-hosting"
|
|
34
|
+
],
|
|
35
|
+
"envVarName": "TRIGGER_SECRET_KEY",
|
|
36
|
+
"codeSnippet": "import { TriggerClient } from '@trigger.dev/sdk';\n\nexport const client = new TriggerClient({\n id: 'my-app',\n apiKey: process.env.TRIGGER_SECRET_KEY,\n});"
|
|
37
|
+
},
|
|
38
|
+
"pricing": {
|
|
39
|
+
"model": "freemium",
|
|
40
|
+
"freeTier": "Hobby: 50,000 runs/month, 60-day log retention",
|
|
41
|
+
"startingPrice": "$10/month (Pro) for 100K runs/month with team access",
|
|
42
|
+
"costPer": "$0.001/run after included monthly quota",
|
|
43
|
+
"pricingUrl": "https://trigger.dev/pricing"
|
|
44
|
+
},
|
|
45
|
+
"rateLimits": {
|
|
46
|
+
"tier": "cloud hobby",
|
|
47
|
+
"limit": "50K runs/month included, up to 15-minute execution duration per run",
|
|
48
|
+
"notes": "Runs can be paused and resumed using waitFor and waitForEvent. Concurrency can be configured per task. The free tier resets monthly.",
|
|
49
|
+
"retryStrategy": "Built-in retry with configurable maxAttempts (default: 3) and exponential backoff. Set retry.maxAttempts: 0 to disable."
|
|
50
|
+
},
|
|
51
|
+
"sdk": {
|
|
52
|
+
"primaryLanguage": "typescript",
|
|
53
|
+
"installCommand": "npm install --save-exact @trigger.dev/sdk",
|
|
54
|
+
"importStatement": "import { task, logger } from '@trigger.dev/sdk/v3';",
|
|
55
|
+
"otherLanguages": []
|
|
56
|
+
},
|
|
57
|
+
"codeExamples": [
|
|
58
|
+
{
|
|
59
|
+
"title": "Define and trigger a background task",
|
|
60
|
+
"language": "typescript",
|
|
61
|
+
"code": "// src/trigger/send-welcome-email.ts\nimport { task, logger } from '@trigger.dev/sdk/v3';\nimport { sendEmail } from '../lib/email';\n\nexport const sendWelcomeEmail = task({\n id: 'send-welcome-email',\n run: async (payload: { userId: string; email: string }) => {\n logger.log('Sending welcome email', { userId: payload.userId });\n\n await sendEmail({\n to: payload.email,\n subject: 'Welcome!',\n html: '<h1>Welcome aboard</h1>',\n });\n\n return { success: true };\n },\n});\n\n// In your API route:\nimport { sendWelcomeEmail } from '../trigger/send-welcome-email';\n\n// Fire-and-forget: returns a handle immediately\nconst handle = await sendWelcomeEmail.trigger({\n userId: 'user_123',\n email: 'jane@example.com',\n});\n\nconsole.log('Triggered run:', handle.id);",
|
|
62
|
+
"notes": "Tasks must be exported from files inside the trigger/ directory (or wherever TRIGGER_DIRS points). The task id must be unique across your project."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"title": "Task with retry configuration and delay",
|
|
66
|
+
"language": "typescript",
|
|
67
|
+
"code": "import { task, logger, wait } from '@trigger.dev/sdk/v3';\nimport { fetchExternalData, processData } from '../lib/data';\n\nexport const processUserData = task({\n id: 'process-user-data',\n retry: {\n maxAttempts: 5,\n factor: 2,\n minTimeoutInMs: 1_000,\n maxTimeoutInMs: 30_000,\n },\n run: async (payload: { userId: string }) => {\n logger.log('Processing user data', { userId: payload.userId });\n\n const raw = await fetchExternalData(payload.userId);\n\n // Pause the run for 30 seconds (does not block a worker thread)\n await wait.for({ seconds: 30 });\n\n const result = await processData(raw);\n\n logger.log('Processing complete', { result });\n return result;\n },\n});",
|
|
68
|
+
"notes": "wait.for() suspends the run without consuming worker capacity. The run resumes automatically after the delay. Retries use exponential backoff with jitter between minTimeoutInMs and maxTimeoutInMs."
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"gotchas": [
|
|
72
|
+
"Trigger.dev v3 (current) is a major rewrite from v2. The defineJob API from v2 is replaced by task. Any documentation or examples using defineJob are outdated and will not work with the v3 SDK.",
|
|
73
|
+
"Tasks must be registered with Trigger.dev at build time via the trigger deploy command (or trigger dev for local development). You cannot dynamically define or register tasks at runtime — the task id must be statically known.",
|
|
74
|
+
"Long-running tasks must be split into sub-tasks or use checkpoints. The Hobby tier has a 60-second max execution duration per run; Pro allows up to 15 minutes. For tasks that need to run longer, use triggerAndWait() to chain tasks sequentially or use wait.for() to pause mid-run."
|
|
75
|
+
],
|
|
76
|
+
"reliability": {
|
|
77
|
+
"uptimeGuarantee": "99.9% for cloud (Pro tier)",
|
|
78
|
+
"statusPageUrl": "https://status.trigger.dev",
|
|
79
|
+
"notes": "Self-hosted deployment is supported on any Node.js-compatible host. Cloud uses isolated workers per customer. The open-source codebase can be self-hosted with Docker."
|
|
80
|
+
},
|
|
81
|
+
"qualityScore": 8,
|
|
82
|
+
"qualityJustification": "The best open-source background job platform for TypeScript developers. Writing jobs as plain TypeScript functions with live log streaming and local dev mode is an outstanding DX. The v3 rewrite addressed major limitations of v2. Main drawback is a smaller ecosystem compared to Inngest and a steeper initial setup with the deploy step.",
|
|
83
|
+
"alternatives": ["inngest", "temporal"],
|
|
84
|
+
"complementary": ["resend", "supabase", "neon", "stripe", "uploadthing"],
|
|
85
|
+
"bestFor": "TypeScript-first background jobs and workflows with long-running task support and a great local development experience",
|
|
86
|
+
"lastVerified": "2026-02-25",
|
|
87
|
+
"entryVersion": 1,
|
|
88
|
+
"addedBy": "claude-code-session-4"
|
|
89
|
+
}
|