Skip to content

Commit bef9330

Browse files
committed
chore: wip
1 parent fe8763d commit bef9330

21 files changed

Lines changed: 1214 additions & 136 deletions

docs/.vitepress/config.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const nav = [
2222
{ text: 'News', link: 'https://stacksjs.org/news' },
2323
{
2424
text: 'Changelog',
25-
link: 'https://github.com/stacksjs/bun-starter/blob/main/CHANGELOG.md',
25+
link: 'https://github.com/stacksjs/bun-queue/blob/main/CHANGELOG.md',
2626
},
2727
// { text: 'Blog', link: 'https://updates.ow3.org' },
2828
{
@@ -63,12 +63,12 @@ const sidebar = [
6363
{ text: 'Showcase', link: '/Showcase' },
6464
]
6565
const description = 'A TypeScript Starter Kit. For a better Development Experience.'
66-
const title = 'bun-starter | A TypeScript Starter Kit. For a better Development Experience.'
66+
const title = 'bun-queue | A TypeScript Starter Kit. For a better Development Experience.'
6767

6868
export default withPwa(
6969
defineConfig({
7070
lang: 'en-US',
71-
title: 'bun-starter',
71+
title: 'bun-queue',
7272
description,
7373
metaChunk: true,
7474
cleanUrls: true,
@@ -83,15 +83,15 @@ export default withPwa(
8383
['meta', { name: 'author', content: 'Stacks.js, Inc.' }],
8484
['meta', {
8585
name: 'tags',
86-
content: 'bun-starter, stacksjs, reverse proxy, modern, lightweight, zero-config, local development',
86+
content: 'bun-queue, stacksjs, reverse proxy, modern, lightweight, zero-config, local development',
8787
}],
8888

8989
['meta', { property: 'og:type', content: 'website' }],
9090
['meta', { property: 'og:locale', content: 'en' }],
9191
['meta', { property: 'og:title', content: title }],
9292
['meta', { property: 'og:description', content: description }],
9393

94-
['meta', { property: 'og:site_name', content: 'bun-starter' }],
94+
['meta', { property: 'og:site_name', content: 'bun-queue' }],
9595
['meta', { property: 'og:image', content: './images/og-image.jpg' }],
9696
['meta', { property: 'og:url', content: 'https://reverse-proxy.sh/' }],
9797
// ['script', { 'src': 'https://cdn.usefathom.com/script.js', 'data-site': '', 'data-spa': 'auto', 'defer': '' }],
@@ -123,7 +123,7 @@ export default withPwa(
123123
socialLinks: [
124124
{ icon: 'twitter', link: 'https://twitter.com/stacksjs' },
125125
{ icon: 'bluesky', link: 'https://bsky.app/profile/chrisbreuer.dev' },
126-
{ icon: 'github', link: 'https://github.com/stacksjs/bun-starter' },
126+
{ icon: 'github', link: 'https://github.com/stacksjs/bun-queue' },
127127
{ icon: 'discord', link: 'https://discord.gg/stacksjs' },
128128
],
129129

docs/config.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Configuration
22

3-
_This is just an example of the bun-starter docs._
3+
_This is just an example of the bun-queue docs._
44

55
The Reverse Proxy can be configured using a `reverse-proxy.config.ts` _(or `reverse-proxy.config.js`)_ file and it will be automatically loaded when running the `reverse-proxy` command.
66

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
layout: home
44

55
hero:
6-
name: "bun-starter"
6+
name: "bun-queue"
77
text: "For a better local environment."
88
tagline: "Modern and smart reverse proxy."
99
image: /images/logo-white.png

docs/install.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Install
22

3-
_This is just an example of the bun-starter docs._
3+
_This is just an example of the bun-queue docs._
44

55
Installing `rpx` is easy. Simply pull it in via your package manager of choice, or download the binary directly.
66

docs/intro.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ It's rather simple to get your package development started:
1414

1515
```bash
1616
# you may use this GitHub template or the following command:
17-
bunx degit stacksjs/bun-starter my-pkg
17+
bunx degit stacksjs/bun-queue my-pkg
1818
cd my-pkg
1919

2020
# if you don't have pnpm installed, run `npm i -g pnpm`
@@ -47,7 +47,7 @@ Please see our [releases](https://github.com/stacksjs/stacks/releases) page for
4747

4848
## Stargazers
4949

50-
[![Stargazers](https://starchart.cc/stacksjs/bun-starter.svg?variant=adaptive)](https://starchart.cc/stacksjs/bun-starter)
50+
[![Stargazers](https://starchart.cc/stacksjs/bun-queue.svg?variant=adaptive)](https://starchart.cc/stacksjs/bun-queue)
5151

5252
## Contributing
5353

@@ -83,7 +83,7 @@ We would like to extend our thanks to the following sponsors for funding Stacks
8383

8484
## License
8585

86-
The MIT License (MIT). Please see [LICENSE](https://github.com/stacksjs/bun-starter/tree/main/LICENSE.md) for more information.
86+
The MIT License (MIT). Please see [LICENSE](https://github.com/stacksjs/bun-queue/tree/main/LICENSE.md) for more information.
8787

8888
Made with 💙
8989

docs/stargazers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## Stargazers
22

3-
[![Stargazers](https://starchart.cc/stacksjs/bun-starter.svg?variant=adaptive)](https://starchart.cc/stacksjs/bun-starter)
3+
[![Stargazers](https://starchart.cc/stacksjs/bun-queue.svg?variant=adaptive)](https://starchart.cc/stacksjs/bun-queue)

examples/advanced.ts

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
import { Job, Queue, RateLimiter } from '../src'
2+
3+
// Define job data types
4+
interface EmailJob {
5+
to: string
6+
subject: string
7+
body: string
8+
}
9+
10+
interface ReportJob {
11+
reportId: string
12+
userId: string
13+
format: 'pdf' | 'csv' | 'xlsx'
14+
}
15+
16+
interface ImageJob {
17+
imageId: string
18+
operations: Array<{
19+
type: 'resize' | 'crop' | 'filter'
20+
params: Record<string, any>
21+
}>
22+
}
23+
24+
async function main() {
25+
// Create queues for different job types
26+
const emailQueue = new Queue<EmailJob>('emails', {
27+
verbose: true,
28+
logLevel: 'info',
29+
metrics: { enabled: true },
30+
defaultJobOptions: {
31+
attempts: 3,
32+
backoff: {
33+
type: 'exponential',
34+
delay: 1000,
35+
},
36+
},
37+
})
38+
39+
const reportQueue = new Queue<ReportJob>('reports')
40+
const imageQueue = new Queue<ImageJob>('images')
41+
42+
// Set up event listeners for the email queue
43+
emailQueue.events.on('jobCompleted', (jobId, result) => {
44+
console.log(`Email job ${jobId} completed with result:`, result)
45+
})
46+
47+
emailQueue.events.on('jobFailed', (jobId, error) => {
48+
console.log(`Email job ${jobId} failed with error:`, error.message)
49+
})
50+
51+
// Create a rate limiter for the email queue (5 emails per second)
52+
const emailRateLimiter = new RateLimiter(emailQueue, {
53+
max: 5,
54+
duration: 1000,
55+
})
56+
57+
// Add jobs with dependencies
58+
// First, add a report generation job
59+
const reportJob = await reportQueue.add({
60+
reportId: 'report-123',
61+
userId: 'user-456',
62+
format: 'pdf',
63+
}, {
64+
attempts: 2,
65+
jobId: 'report-job-123',
66+
})
67+
68+
console.log(`Added report job ${reportJob.id}`)
69+
70+
// Then, add an email job that depends on the report job
71+
const emailJobWithDep = await emailQueue.add({
72+
to: 'user@example.com',
73+
subject: 'Your report is ready',
74+
body: 'Please find your report attached.',
75+
}, {
76+
dependsOn: reportJob.id, // This job won't process until the report job is done
77+
jobId: 'email-job-123',
78+
})
79+
80+
console.log(`Added email job ${emailJobWithDep.id} depending on report job ${reportJob.id}`)
81+
82+
// Add some image processing jobs
83+
for (let i = 1; i <= 3; i++) {
84+
const imageJob = await imageQueue.add({
85+
imageId: `image-${i}`,
86+
operations: [
87+
{ type: 'resize', params: { width: 800, height: 600 } },
88+
{ type: 'filter', params: { name: 'grayscale' } },
89+
],
90+
}, {
91+
priority: i, // Higher number = higher priority
92+
})
93+
94+
console.log(`Added image job ${imageJob.id} with priority ${i}`)
95+
}
96+
97+
// Add some rate-limited email jobs
98+
for (let i = 1; i <= 10; i++) {
99+
// Check rate limiter before adding the job
100+
const { limited, remaining, resetIn } = await emailRateLimiter.check()
101+
102+
if (!limited) {
103+
const job = await emailQueue.add({
104+
to: `user${i}@example.com`,
105+
subject: `Test Email ${i}`,
106+
body: `This is test email #${i}`,
107+
})
108+
109+
console.log(`Added rate-limited email job ${job.id}. Remaining: ${remaining}`)
110+
}
111+
else {
112+
console.log(`Rate limit reached. Try again in ${resetIn}ms. Skipping email ${i}.`)
113+
// In a real app, you might wait and retry, or queue locally
114+
await new Promise(resolve => setTimeout(resolve, 500))
115+
i-- // Try again
116+
}
117+
}
118+
119+
// Process report jobs
120+
reportQueue.process(2, async (job) => {
121+
console.log(`Processing report job ${job.id} for report ${job.data.reportId}`)
122+
123+
// Update progress
124+
await job.updateProgress(25)
125+
126+
// Simulate report generation work
127+
await new Promise(resolve => setTimeout(resolve, 2000))
128+
129+
await job.updateProgress(75)
130+
131+
// More processing
132+
await new Promise(resolve => setTimeout(resolve, 1000))
133+
134+
await job.updateProgress(100)
135+
console.log(`Report ${job.data.reportId} generated successfully`)
136+
137+
return { reportUrl: `https://example.com/reports/${job.data.reportId}.${job.data.format}` }
138+
})
139+
140+
// Process email jobs
141+
emailQueue.process(5, async (job) => {
142+
console.log(`Processing email job ${job.id} to ${job.data.to}`)
143+
144+
// Update progress
145+
await job.updateProgress(50)
146+
147+
// Simulate sending email
148+
await new Promise(resolve => setTimeout(resolve, 1000))
149+
150+
// Randomly fail some jobs to demonstrate retry
151+
if (Math.random() < 0.3) {
152+
throw new Error('Failed to send email: SMTP error')
153+
}
154+
155+
await job.updateProgress(100)
156+
console.log(`Email sent successfully to ${job.data.to}`)
157+
158+
return {
159+
sent: true,
160+
messageId: `msg-${Date.now()}`,
161+
timestamp: new Date().toISOString(),
162+
}
163+
})
164+
165+
// Process image jobs
166+
imageQueue.process(3, async (job) => {
167+
console.log(`Processing image job ${job.id} for image ${job.data.imageId}`)
168+
169+
// Update progress
170+
await job.updateProgress(25)
171+
172+
// For each operation
173+
for (const [index, operation] of job.data.operations.entries()) {
174+
console.log(`Applying ${operation.type} to image ${job.data.imageId}`)
175+
176+
// Simulate image processing work
177+
await new Promise(resolve => setTimeout(resolve, 1000))
178+
179+
const progressIncrement = 75 / job.data.operations.length
180+
await job.updateProgress(25 + progressIncrement * (index + 1))
181+
}
182+
183+
await job.updateProgress(100)
184+
console.log(`Image ${job.data.imageId} processed successfully`)
185+
186+
return {
187+
imageUrl: `https://example.com/images/${job.data.imageId}-processed.jpg`,
188+
operations: job.data.operations.length,
189+
}
190+
})
191+
192+
// Display job counts and metrics periodically
193+
const interval = setInterval(async () => {
194+
// Get counts for all queues
195+
const [emailCounts, reportCounts, imageCounts] = await Promise.all([
196+
emailQueue.getJobCounts(),
197+
reportQueue.getJobCounts(),
198+
imageQueue.getJobCounts(),
199+
])
200+
201+
console.log('\nJob Counts:')
202+
console.log('Email Queue:', emailCounts)
203+
console.log('Report Queue:', reportCounts)
204+
console.log('Image Queue:', imageCounts)
205+
206+
// Get metrics
207+
const metrics = await emailQueue.getMetrics()
208+
if (metrics) {
209+
console.log('\nEmail Queue Metrics:')
210+
console.log(`Processed per minute: ${metrics.jobsProcessedPerMinute}`)
211+
console.log(`Added per minute: ${metrics.jobsAddedPerMinute}`)
212+
console.log(`Error rate: ${(metrics.errorRate * 100).toFixed(1)}%`)
213+
console.log(`Avg processing time: ${metrics.processingTime.avg.toFixed(0)}ms`)
214+
}
215+
216+
// Check if all jobs are completed or failed
217+
const totalActive = emailCounts.active + reportCounts.active + imageCounts.active
218+
const totalWaiting = emailCounts.waiting + reportCounts.waiting + imageCounts.waiting
219+
const totalDelayed = emailCounts.delayed + reportCounts.delayed + imageCounts.delayed
220+
221+
if (totalActive === 0 && totalWaiting === 0 && totalDelayed === 0) {
222+
console.log('\nAll jobs processed!')
223+
224+
// Display final results
225+
const completed = emailCounts.completed + reportCounts.completed + imageCounts.completed
226+
const failed = emailCounts.failed + reportCounts.failed + imageCounts.failed
227+
console.log(`Total completed: ${completed}`)
228+
console.log(`Total failed: ${failed}`)
229+
230+
// Clean up
231+
clearInterval(interval)
232+
233+
// Close all queues
234+
await Promise.all([
235+
emailQueue.close(),
236+
reportQueue.close(),
237+
imageQueue.close(),
238+
])
239+
240+
console.log('All queues closed, exiting...')
241+
}
242+
}, 2000)
243+
}
244+
245+
main().catch(console.error)

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
"description": "A Redis-backed job queue built for Bun.",
66
"author": "Chris Breuer <chris@stacksjs.org>",
77
"license": "MIT",
8-
"homepage": "https://github.com/stacksjs/bun-starter#readme",
8+
"homepage": "https://github.com/stacksjs/bun-queue#readme",
99
"repository": {
1010
"type": "git",
11-
"url": "git+https://github.com/stacksjs/bun-starter.git"
11+
"url": "git+https://github.com/stacksjs/bun-queue.git"
1212
},
1313
"bugs": {
14-
"url": "https://github.com/stacksjs/bun-starter/issues"
14+
"url": "https://github.com/stacksjs/bun-queue/issues"
1515
},
1616
"keywords": ["typescript", "starter", "kit", "bun", "package"],
1717
"exports": {
@@ -56,7 +56,8 @@
5656
"build:docs": "bun --bun vitepress build docs",
5757
"preview:docs": "bun --bun vitepress preview docs",
5858
"typecheck": "bun --bun tsc --noEmit",
59-
"example:basic": "bun examples/basic.ts"
59+
"example:basic": "bun examples/basic.ts",
60+
"example:advanced": "bun examples/advanced.ts"
6061
},
6162
"dependencies": {
6263
"@types/semver": "^7.7.0",

0 commit comments

Comments
 (0)