nuxt-bee-queue 1.0.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/README.md +84 -0
- package/dist/module.d.mts +9 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +175 -0
- package/dist/runtime/plugin.d.ts +2 -0
- package/dist/runtime/plugin.js +4 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/server/utils/defineJob.d.ts +7 -0
- package/dist/runtime/server/utils/defineJob.js +6 -0
- package/dist/runtime/server/utils/useQueue.d.ts +7 -0
- package/dist/runtime/server/utils/useQueue.js +13 -0
- package/dist/types.d.mts +3 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Get your module up and running quickly.
|
|
3
|
+
|
|
4
|
+
Find and replace all on all files (CMD+SHIFT+F):
|
|
5
|
+
- Name: My Module
|
|
6
|
+
- Package name: my-module
|
|
7
|
+
- Description: My new Nuxt module
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
# My Module
|
|
11
|
+
|
|
12
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
13
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
14
|
+
[![License][license-src]][license-href]
|
|
15
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
16
|
+
|
|
17
|
+
My new Nuxt module for doing amazing things.
|
|
18
|
+
|
|
19
|
+
- [✨ Release Notes](/CHANGELOG.md)
|
|
20
|
+
<!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
|
|
21
|
+
<!-- - [📖 Documentation](https://example.com) -->
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
<!-- Highlight some of the features your module provide here -->
|
|
26
|
+
- ⛰ Foo
|
|
27
|
+
- 🚠 Bar
|
|
28
|
+
- 🌲 Baz
|
|
29
|
+
|
|
30
|
+
## Quick Setup
|
|
31
|
+
|
|
32
|
+
Install the module to your Nuxt application with one command:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx nuxi module add my-module
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That's it! You can now use My Module in your Nuxt app ✨
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Contribution
|
|
42
|
+
|
|
43
|
+
<details>
|
|
44
|
+
<summary>Local development</summary>
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Install dependencies
|
|
48
|
+
npm install
|
|
49
|
+
|
|
50
|
+
# Generate type stubs
|
|
51
|
+
npm run dev:prepare
|
|
52
|
+
|
|
53
|
+
# Develop with the playground
|
|
54
|
+
npm run dev
|
|
55
|
+
|
|
56
|
+
# Build the playground
|
|
57
|
+
npm run dev:build
|
|
58
|
+
|
|
59
|
+
# Run ESLint
|
|
60
|
+
npm run lint
|
|
61
|
+
|
|
62
|
+
# Run Vitest
|
|
63
|
+
npm run test
|
|
64
|
+
npm run test:watch
|
|
65
|
+
|
|
66
|
+
# Release new version
|
|
67
|
+
npm run release
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<!-- Badges -->
|
|
74
|
+
[npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=020420&colorB=00DC82
|
|
75
|
+
[npm-version-href]: https://npmjs.com/package/my-module
|
|
76
|
+
|
|
77
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=020420&colorB=00DC82
|
|
78
|
+
[npm-downloads-href]: https://npm.chart.dev/my-module
|
|
79
|
+
|
|
80
|
+
[license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=020420&colorB=00DC82
|
|
81
|
+
[license-href]: https://npmjs.com/package/my-module
|
|
82
|
+
|
|
83
|
+
[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt
|
|
84
|
+
[nuxt-href]: https://nuxt.com
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { useNuxt, createResolver, defineNuxtModule, addServerTemplate, addTemplate, addServerImports } from '@nuxt/kit';
|
|
2
|
+
import { parse, relative } from 'node:path';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import fg from 'fast-glob';
|
|
5
|
+
|
|
6
|
+
const scanFolder = async (path) => {
|
|
7
|
+
const nuxt = useNuxt();
|
|
8
|
+
const { resolve } = createResolver(import.meta.url);
|
|
9
|
+
const resolvedPath = resolve(nuxt.options.rootDir, path);
|
|
10
|
+
const files = [];
|
|
11
|
+
const updatedFiles = await fg("**/*.{ts,js,mjs}", {
|
|
12
|
+
cwd: resolvedPath,
|
|
13
|
+
absolute: true,
|
|
14
|
+
onlyFiles: true
|
|
15
|
+
});
|
|
16
|
+
files.push(...new Set(updatedFiles));
|
|
17
|
+
return files;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const module$1 = defineNuxtModule({
|
|
21
|
+
meta: {
|
|
22
|
+
name: "nuxt-bee-queue",
|
|
23
|
+
configKey: "nuxtBeeQueue"
|
|
24
|
+
},
|
|
25
|
+
// Default configuration options of the Nuxt module
|
|
26
|
+
defaults: {
|
|
27
|
+
redis: "redis://localhost:6379"
|
|
28
|
+
},
|
|
29
|
+
async setup(options, nuxt) {
|
|
30
|
+
const resolver = createResolver(import.meta.url);
|
|
31
|
+
const jobsDir = resolver.resolve(nuxt.options.serverDir, "job");
|
|
32
|
+
addServerTemplate({
|
|
33
|
+
filename: "#queue/bee-queue-jobs.mjs",
|
|
34
|
+
// Virtual filename
|
|
35
|
+
getContents: () => {
|
|
36
|
+
const imports = [];
|
|
37
|
+
const mapEntries = [];
|
|
38
|
+
if (fs.existsSync(jobsDir)) {
|
|
39
|
+
const jobFiles = fs.readdirSync(jobsDir).filter((f) => f.endsWith(".ts") || f.endsWith(".mjs"));
|
|
40
|
+
jobFiles.forEach((file, index) => {
|
|
41
|
+
const name = parse(file).name;
|
|
42
|
+
const importName = `job_${index}`;
|
|
43
|
+
const absolutePath = resolver.resolve(jobsDir, file);
|
|
44
|
+
imports.push(`import ${importName} from '${absolutePath}'`);
|
|
45
|
+
mapEntries.push(`'${name}': ${importName}`);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return `
|
|
49
|
+
${imports.join("\n")}
|
|
50
|
+
import { createClient } from 'redis';
|
|
51
|
+
|
|
52
|
+
export const jobRegistry = {
|
|
53
|
+
${mapEntries.join(",\n")}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let client = globalThis.redis;
|
|
57
|
+
|
|
58
|
+
if (!client) {
|
|
59
|
+
client = createClient({
|
|
60
|
+
url: "${options.redis}"
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
client.instanceId = Math.floor(Math.random() * 10000);
|
|
64
|
+
|
|
65
|
+
// In Redis v4+, you must explicitly connect
|
|
66
|
+
if (!client.isOpen) {
|
|
67
|
+
client.connect().catch(console.error);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Save to global for hot-reloading
|
|
71
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
72
|
+
globalThis.redis = client;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const redis = client;
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
nuxt.hook("nitro:prepare:types", ({ references }) => {
|
|
81
|
+
references.push({
|
|
82
|
+
path: resolver.resolve(nuxt.options.buildDir, "types/bee-queue-jobs.d.ts")
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
addTemplate({
|
|
86
|
+
filename: "types/bee-queue-jobs.d.ts",
|
|
87
|
+
getContents: () => `
|
|
88
|
+
declare module '#queue/bee-queue-jobs.mjs' {
|
|
89
|
+
export const jobRegistry: Record<string, any>;
|
|
90
|
+
export const redis: RedisClientType;
|
|
91
|
+
}
|
|
92
|
+
`
|
|
93
|
+
});
|
|
94
|
+
addTemplate({
|
|
95
|
+
filename: "types/bee-queue-types.d.ts",
|
|
96
|
+
getContents: () => {
|
|
97
|
+
const names = [];
|
|
98
|
+
const jobMappings = [];
|
|
99
|
+
if (fs.existsSync(jobsDir)) {
|
|
100
|
+
const jobFiles = fs.readdirSync(jobsDir).filter((f) => f.endsWith(".ts") || f.endsWith(".mjs"));
|
|
101
|
+
jobFiles.forEach((file, _index) => {
|
|
102
|
+
const name = parse(file).name;
|
|
103
|
+
names.push(`"${name}"`);
|
|
104
|
+
jobMappings.push(` '${name}': typeof import('~/server/job/${name}').default`);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return `
|
|
108
|
+
import type { RedisClientType } from 'redis'
|
|
109
|
+
export type JobsNamesType = ${!names.length ? '""' : names.join("|")}
|
|
110
|
+
|
|
111
|
+
export interface QueueJobs{
|
|
112
|
+
${jobMappings.join("\n")}
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
addServerImports({
|
|
118
|
+
name: "defineJob",
|
|
119
|
+
as: "defineJob",
|
|
120
|
+
from: resolver.resolve("./runtime/server/utils/defineJob")
|
|
121
|
+
});
|
|
122
|
+
addServerImports([{
|
|
123
|
+
name: "useQueue",
|
|
124
|
+
from: resolver.resolve("./runtime/server/utils/useQueue")
|
|
125
|
+
}]);
|
|
126
|
+
function createWorkersRollupPlugin() {
|
|
127
|
+
const VIRTUAL_ID = "\0nuxt-bee-queue-entry";
|
|
128
|
+
let virtualCode = "";
|
|
129
|
+
let entryRefId = null;
|
|
130
|
+
return {
|
|
131
|
+
name: "nuxt-bee-queue-emit",
|
|
132
|
+
async buildStart() {
|
|
133
|
+
const workerFiles = await scanFolder(jobsDir);
|
|
134
|
+
if (workerFiles.length === 0) {
|
|
135
|
+
virtualCode = "";
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
virtualCode = fs.readFileSync(resolver.resolve("./template/worker.js"), "utf8");
|
|
139
|
+
for (const id of workerFiles) {
|
|
140
|
+
this.addWatchFile(id);
|
|
141
|
+
}
|
|
142
|
+
entryRefId = this.emitFile({ type: "chunk", id: VIRTUAL_ID, fileName: "workers/_entry.mjs" });
|
|
143
|
+
},
|
|
144
|
+
resolveId(id) {
|
|
145
|
+
if (id === VIRTUAL_ID) return VIRTUAL_ID;
|
|
146
|
+
},
|
|
147
|
+
load(id) {
|
|
148
|
+
if (id === VIRTUAL_ID) return virtualCode ?? "export {}\n";
|
|
149
|
+
},
|
|
150
|
+
generateBundle() {
|
|
151
|
+
if (!virtualCode || !entryRefId) return;
|
|
152
|
+
const entryFile = this.getFileName(entryRefId);
|
|
153
|
+
const fromDir = "workers";
|
|
154
|
+
const rel = "./" + relative(fromDir, entryFile).split("\\").join("/");
|
|
155
|
+
const wrapper = fs.readFileSync(resolver.resolve("./template/main.js"), "utf8").replace("{{$rel}}", rel);
|
|
156
|
+
this.emitFile({ type: "asset", fileName: "workers/index.mjs", source: wrapper });
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
nuxt.hooks.hook("nitro:config", (nitroConfig) => {
|
|
161
|
+
nitroConfig.rollupConfig = nitroConfig.rollupConfig ?? {};
|
|
162
|
+
const plugin = createWorkersRollupPlugin();
|
|
163
|
+
const current = nitroConfig.rollupConfig.plugins;
|
|
164
|
+
if (Array.isArray(current)) {
|
|
165
|
+
nitroConfig.rollupConfig.plugins = [...current, plugin];
|
|
166
|
+
} else if (current) {
|
|
167
|
+
nitroConfig.rollupConfig.plugins = [current, plugin];
|
|
168
|
+
} else {
|
|
169
|
+
nitroConfig.rollupConfig.plugins = [plugin];
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
export { module$1 as default };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Job, DoneCallback, QueueSettings } from 'bee-queue';
|
|
2
|
+
export interface JobHandler<T, D> {
|
|
3
|
+
concurrency?: number;
|
|
4
|
+
process: (job: Job<T>, done: DoneCallback<D>) => Promise<unknown> | unknown;
|
|
5
|
+
setting?: QueueSettings;
|
|
6
|
+
}
|
|
7
|
+
export declare function defineJob<TPayload, TResult>(handler: ((job: Job<TPayload>) => TResult) | JobHandler<TPayload, TResult>): JobHandler<TPayload, TResult>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Job, QueueSettings } from 'bee-queue';
|
|
2
|
+
import BeeQueue from 'bee-queue';
|
|
3
|
+
import type { QueueJobs } from '#build/types/bee-queue-types';
|
|
4
|
+
type ExtractTFromProcess<TProcess> = TProcess extends (job: Job<infer T>, ...args: any[]) => any ? T : never;
|
|
5
|
+
type CustomQueueSettings = Omit<QueueSettings, 'redis' | 'isWorker'>;
|
|
6
|
+
export declare function useQueue<T extends keyof QueueJobs>(name: T, setting?: CustomQueueSettings): BeeQueue<ExtractTFromProcess<QueueJobs[T]["process"]>>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import BeeQueue from "bee-queue";
|
|
2
|
+
import { redis } from "#queue/bee-queue-jobs.mjs";
|
|
3
|
+
const _queues = {};
|
|
4
|
+
export function useQueue(name, setting) {
|
|
5
|
+
if (!_queues[name]) {
|
|
6
|
+
_queues[name] = new BeeQueue(name, {
|
|
7
|
+
redis,
|
|
8
|
+
isWorker: false,
|
|
9
|
+
...setting
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return _queues[name];
|
|
13
|
+
}
|
package/dist/types.d.mts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nuxt-bee-queue",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Nuxt 3/4/5 adapter for bee-queue ",
|
|
5
|
+
"repository": "https://github.com/nexthis/nuxt-bee-queue",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Paweł Romanowski",
|
|
8
|
+
"url": "https://pawel-romanowski.pl/"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/types.d.mts",
|
|
15
|
+
"import": "./dist/module.mjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/module.mjs",
|
|
19
|
+
"typesVersions": {
|
|
20
|
+
"*": {
|
|
21
|
+
".": [
|
|
22
|
+
"./dist/types.d.mts"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"prepack": "nuxt-module-build build",
|
|
31
|
+
"dev": "npm run dev:prepare && nuxi dev playground",
|
|
32
|
+
"dev:build": "nuxi build playground",
|
|
33
|
+
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
|
|
34
|
+
"release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
|
|
35
|
+
"lint": "eslint .",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"test:watch": "vitest watch",
|
|
38
|
+
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@nuxt/kit": "^4.2.2",
|
|
42
|
+
"bee-queue": "^2.0.0",
|
|
43
|
+
"fast-glob": "^3.3.3",
|
|
44
|
+
"redis": "^5.10.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@nuxt/devtools": "^3.1.1",
|
|
48
|
+
"@nuxt/eslint-config": "^1.12.1",
|
|
49
|
+
"@nuxt/module-builder": "^1.0.2",
|
|
50
|
+
"@nuxt/schema": "^4.2.2",
|
|
51
|
+
"@nuxt/test-utils": "^3.21.0",
|
|
52
|
+
"@types/node": "latest",
|
|
53
|
+
"changelogen": "^0.6.2",
|
|
54
|
+
"eslint": "^9.39.2",
|
|
55
|
+
"nuxt": "^4.2.2",
|
|
56
|
+
"typescript": "~5.9.3",
|
|
57
|
+
"vitest": "^4.0.16",
|
|
58
|
+
"vue-tsc": "^3.2.1"
|
|
59
|
+
}
|
|
60
|
+
}
|