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 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
+ - [✨ &nbsp;Release Notes](/CHANGELOG.md)
20
+ <!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
21
+ <!-- - [📖 &nbsp;Documentation](https://example.com) -->
22
+
23
+ ## Features
24
+
25
+ <!-- Highlight some of the features your module provide here -->
26
+ - ⛰ &nbsp;Foo
27
+ - 🚠 &nbsp;Bar
28
+ - 🌲 &nbsp;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
@@ -0,0 +1,9 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ redis?: string;
5
+ }
6
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
7
+
8
+ export { _default as default };
9
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "nuxt-bee-queue",
3
+ "configKey": "nuxtBeeQueue",
4
+ "version": "1.0.0",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "3.6.1"
8
+ }
9
+ }
@@ -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,2 @@
1
+ declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ export default defineNuxtPlugin((_nuxtApp) => {
3
+ console.log("Plugin injected by my-module!");
4
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../../../.nuxt/tsconfig.server.json",
3
+ }
@@ -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,6 @@
1
+ export function defineJob(handler) {
2
+ if (typeof handler === "function") {
3
+ return { process: handler };
4
+ }
5
+ return handler;
6
+ }
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ export { default } from './module.mjs'
2
+
3
+ export { type ModuleOptions } from './module.mjs'
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
+ }