nuxt-processor 0.0.14 → 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 CHANGED
@@ -54,20 +54,20 @@ export default defineNuxtConfig({
54
54
  redis: {
55
55
  // Prefer a single URL if available (takes precedence over other fields)
56
56
  // e.g. redis://user:pass@host:6379/0
57
- url: process.env.NUXT_REDIS_URL,
58
- host: process.env.NUXT_REDIS_HOST ?? '127.0.0.1',
59
- port: Number(process.env.NUXT_REDIS_PORT ?? 6379),
60
- password: process.env.NUXT_REDIS_PASSWORD ?? '',
61
- username: process.env.NUXT_REDIS_USERNAME,
62
- db: Number(process.env.NUXT_REDIS_DB ?? 0),
57
+ url: process.env.REDIS_URL,
58
+ host: process.env.REDIS_HOST ?? '127.0.0.1',
59
+ port: Number(process.env.REDIS_PORT ?? 6379),
60
+ password: process.env.REDIS_PASSWORD ?? '',
61
+ username: process.env.REDIS_USERNAME,
62
+ db: Number(process.env.REDIS_DB ?? 0),
63
63
  // Optional connection behavior
64
64
  // Delay connecting until first Redis command (useful to avoid build-time connects)
65
- lazyConnect: process.env.NUXT_REDIS_LAZY_CONNECT
66
- ? process.env.NUXT_REDIS_LAZY_CONNECT === 'true'
65
+ lazyConnect: process.env.REDIS_LAZY_CONNECT
66
+ ? process.env.REDIS_LAZY_CONNECT === 'true'
67
67
  : undefined,
68
68
  // Milliseconds to wait before giving up when establishing the connection
69
- connectTimeout: process.env.NUXT_REDIS_CONNECT_TIMEOUT
70
- ? Number(process.env.NUXT_REDIS_CONNECT_TIMEOUT)
69
+ connectTimeout: process.env.REDIS_CONNECT_TIMEOUT
70
+ ? Number(process.env.REDIS_CONNECT_TIMEOUT)
71
71
  : undefined,
72
72
  },
73
73
  },
@@ -121,13 +121,22 @@ nuxi dev
121
121
  node .nuxt/dev/workers/index.mjs
122
122
  ```
123
123
 
124
+ By default all workers run. To run only specific workers, use the `--workers=` flag with a comma-separated list of worker names:
125
+
126
+ ```bash
127
+ node .nuxt/dev/workers/index.mjs --workers=basic,hello
128
+ ```
129
+
124
130
  ### CLI
125
131
 
126
- A simple CLI is provided to run workers in development.
132
+ A simple CLI is provided to run workers in development (with file watching and restarts).
127
133
 
128
134
  ```bash
129
- # from your project root
135
+ # from your project root – runs all workers
130
136
  npx nuxt-processor dev
137
+
138
+ # run only specific workers
139
+ npx nuxt-processor dev --workers=basic,hello
131
140
  ```
132
141
 
133
142
  Notes:
@@ -155,6 +164,12 @@ nuxi build
155
164
  node .output/server/workers/index.mjs
156
165
  ```
157
166
 
167
+ To run only specific workers in production:
168
+
169
+ ```bash
170
+ node .output/server/workers/index.mjs --workers=basic,hello
171
+ ```
172
+
158
173
  ## Bull Board
159
174
 
160
175
  [Bull Board](https://github.com/felixmosh/bull-board) is an excellent UI for watching your queues, you can follow the setup in the playground to use it.
package/dist/cli.cjs CHANGED
@@ -2,28 +2,76 @@
2
2
 
3
3
  const node_child_process = require('node:child_process');
4
4
  const node_fs = require('node:fs');
5
- const promises = require('node:readline/promises');
6
- const node_process = require('node:process');
7
5
  const pathe = require('pathe');
8
- const consola = require('consola');
9
6
  const citty = require('citty');
10
7
  const kit = require('@nuxt/kit');
11
- const _package = require('./shared/nuxt-processor.B8GgoFqc.cjs');
8
+ const logger = require('./shared/nuxt-processor.BbReXIMn.cjs');
9
+ const promises = require('node:readline/promises');
10
+ const node_process = require('node:process');
11
+ require('consola');
12
12
 
13
13
  const ensureNuxtProject = async (args) => {
14
14
  const dir = pathe.resolve(args.dir);
15
15
  const nuxtConfig = await kit.loadNuxtConfig({ cwd: dir });
16
16
  if (!nuxtConfig || !nuxtConfig._layers[0]?.configFile) {
17
- consola.consola.error("You are not in a Nuxt project.");
18
- process.exit();
17
+ logger.logger.error("You are not in a Nuxt project.");
18
+ process.exit(1);
19
19
  }
20
20
  };
21
21
 
22
+ const PROCESSOR_DEV_SCRIPT = "nuxt-processor dev";
23
+ async function ensureProcessorDevScript(projectRoot, options) {
24
+ const pkgPath = pathe.resolve(projectRoot, "package.json");
25
+ if (!node_fs.existsSync(pkgPath)) {
26
+ return false;
27
+ }
28
+ let pkg;
29
+ try {
30
+ const pkgRaw = JSON.parse(node_fs.readFileSync(pkgPath, "utf8"));
31
+ pkg = pkgRaw;
32
+ } catch (error) {
33
+ logger.logger.error("Failed to parse", error);
34
+ return false;
35
+ }
36
+ if (pkg?.scripts?.["processor:dev"]) {
37
+ return true;
38
+ }
39
+ logger.logger.warn('No "processor:dev" script found in package.json.');
40
+ let answer;
41
+ {
42
+ const rl = promises.createInterface({ input: node_process.stdin, output: node_process.stdout });
43
+ try {
44
+ answer = await rl.question("Add script to package.json? (y/N) ");
45
+ } finally {
46
+ rl.close();
47
+ }
48
+ }
49
+ const isYes = typeof answer === "string" && /^y(?:es)?$/i.test(answer.trim());
50
+ if (!isYes) {
51
+ return false;
52
+ }
53
+ const updated = {
54
+ ...pkg,
55
+ scripts: {
56
+ ...pkg.scripts ?? {},
57
+ "processor:dev": PROCESSOR_DEV_SCRIPT
58
+ }
59
+ };
60
+ try {
61
+ node_fs.writeFileSync(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
62
+ logger.logger.success('Added "processor:dev" script to package.json');
63
+ return true;
64
+ } catch {
65
+ logger.logger.error("Failed to write to package.json");
66
+ return false;
67
+ }
68
+ }
69
+
22
70
  const main = citty.createMain({
23
71
  meta: {
24
- name: _package.name,
25
- description: _package.description,
26
- version: _package.version
72
+ name: logger.name,
73
+ description: logger.description,
74
+ version: logger.version
27
75
  },
28
76
  subCommands: {
29
77
  dev: citty.defineCommand({
@@ -39,6 +87,10 @@ const main = citty.createMain({
39
87
  nodeArgs: {
40
88
  type: "string",
41
89
  description: "Extra Node args (e.g. --inspect)"
90
+ },
91
+ workers: {
92
+ type: "string",
93
+ description: "Workers to run, comma-separated; use --workers=name1,name2 (default: all)"
42
94
  }
43
95
  },
44
96
  async run({ args }) {
@@ -47,88 +99,31 @@ const main = citty.createMain({
47
99
  const projectRoot = pathe.resolve(dirArg);
48
100
  const indexFile = pathe.resolve(projectRoot, ".nuxt/dev/workers/index.mjs");
49
101
  const watchDir = pathe.resolve(projectRoot, ".nuxt/dev/workers");
50
- if (node_fs.existsSync(indexFile)) {
51
- const pkgPath = pathe.resolve(projectRoot, "package.json");
52
- if (node_fs.existsSync(pkgPath)) {
53
- try {
54
- const pkgRaw = JSON.parse(node_fs.readFileSync(pkgPath, "utf8"));
55
- const pkg = pkgRaw;
56
- const hasProcessorDev = Boolean(pkg && pkg.scripts && pkg.scripts["processor:dev"]);
57
- if (!hasProcessorDev) {
58
- consola.consola.warn('No "processor:dev" script found in package.json.');
59
- const rl = promises.createInterface({ input: node_process.stdin, output: node_process.stdout });
60
- const answer = await rl.question("Add script to package.json? (y/N) ");
61
- rl.close();
62
- const isYes = typeof answer === "string" && /^y(?:es)?$/i.test(answer.trim());
63
- if (isYes) {
64
- const updated = {
65
- ...pkg,
66
- scripts: {
67
- ...pkg.scripts ?? {},
68
- "processor:dev": "nuxt-processor dev"
69
- }
70
- };
71
- try {
72
- node_fs.writeFileSync(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
73
- consola.consola.success('Added "processor:dev" script to package.json');
74
- } catch {
75
- consola.consola.error("Failed to write to package.json");
76
- }
77
- }
78
- }
79
- } catch {
80
- }
81
- }
82
- }
102
+ const scriptEnsured = await ensureProcessorDevScript(projectRoot);
83
103
  if (!node_fs.existsSync(indexFile)) {
84
- const pkgPath = pathe.resolve(projectRoot, "package.json");
85
- let hasProcessorDev = false;
86
- if (node_fs.existsSync(pkgPath)) {
87
- try {
88
- const pkgRaw = JSON.parse(node_fs.readFileSync(pkgPath, "utf8"));
89
- const pkg = pkgRaw;
90
- hasProcessorDev = Boolean(pkg && pkg.scripts && pkg.scripts["processor:dev"]);
91
- if (!hasProcessorDev) {
92
- consola.consola.warn('No "processor:dev" script found in package.json.');
93
- const rl = promises.createInterface({ input: node_process.stdin, output: node_process.stdout });
94
- const answer = await rl.question("Add script to package.json? (y/N) ");
95
- rl.close();
96
- const isYes = typeof answer === "string" && /^y(?:es)?$/i.test(answer.trim());
97
- if (isYes) {
98
- const updated = {
99
- ...pkg,
100
- scripts: {
101
- ...pkg.scripts || {},
102
- "processor:dev": "nuxt-processor dev"
103
- }
104
- };
105
- try {
106
- node_fs.writeFileSync(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
107
- consola.consola.success('Added "processor:dev" script to package.json');
108
- } catch {
109
- consola.consola.error("Failed to write to package.json");
110
- }
111
- }
112
- }
113
- } catch {
114
- }
115
- }
116
- consola.consola.error("No entry file found at .nuxt/dev/workers/index.mjs");
117
- consola.consola.info("Please start your Nuxt dev server (e.g. `npm run dev`).");
118
- consola.consola.info("After it starts, run `npx nuxt-processor dev` again to start the processor.");
104
+ logger.logger.error("No entry file found at .nuxt/dev/workers/index.mjs");
105
+ logger.logger.info("Please start your Nuxt dev server (e.g. `npm run dev`).");
106
+ logger.logger.info("After it starts, run `npx nuxt-processor dev` again to start the processor.");
107
+ process.exit(1);
108
+ }
109
+ if (!scriptEnsured) {
110
+ logger.logger.error("Could not ensure processor:dev script in package.json.");
119
111
  process.exit(1);
120
112
  }
121
113
  const nodeBin = process.execPath;
122
114
  const nodeArgsInput = Array.isArray(args.nodeArgs) ? args.nodeArgs : typeof args.nodeArgs === "string" ? args.nodeArgs.split(" ") : [];
123
115
  const extraArgs = nodeArgsInput.filter(Boolean);
116
+ const workersValue = typeof args.workers === "string" ? args.workers.trim() : "";
117
+ const workersFlag = workersValue ? `--workers=${workersValue}` : null;
124
118
  const nodeArgs = [
125
119
  ...extraArgs,
126
120
  "--watch",
127
121
  "--watch-path",
128
122
  watchDir,
129
- indexFile
123
+ indexFile,
124
+ ...workersFlag ? [workersFlag] : []
130
125
  ];
131
- consola.consola.info(`Running watcher for processor`);
126
+ logger.logger.info(`Running watcher for processor`);
132
127
  const child = node_child_process.spawn(nodeBin, nodeArgs, {
133
128
  stdio: "inherit",
134
129
  cwd: projectRoot,
package/dist/cli.mjs CHANGED
@@ -1,22 +1,70 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
3
- import { createInterface } from 'node:readline/promises';
4
- import { stdout, stdin } from 'node:process';
5
3
  import { resolve } from 'pathe';
6
- import { consola } from 'consola';
7
4
  import { createMain, defineCommand } from 'citty';
8
5
  import { loadNuxtConfig } from '@nuxt/kit';
9
- import { v as version, d as description, n as name } from './shared/nuxt-processor.C2dSAYu4.mjs';
6
+ import { l as logger, v as version, d as description, n as name } from './shared/nuxt-processor.DCy15jfQ.mjs';
7
+ import { createInterface } from 'node:readline/promises';
8
+ import { stdout, stdin } from 'node:process';
9
+ import 'consola';
10
10
 
11
11
  const ensureNuxtProject = async (args) => {
12
12
  const dir = resolve(args.dir);
13
13
  const nuxtConfig = await loadNuxtConfig({ cwd: dir });
14
14
  if (!nuxtConfig || !nuxtConfig._layers[0]?.configFile) {
15
- consola.error("You are not in a Nuxt project.");
16
- process.exit();
15
+ logger.error("You are not in a Nuxt project.");
16
+ process.exit(1);
17
17
  }
18
18
  };
19
19
 
20
+ const PROCESSOR_DEV_SCRIPT = "nuxt-processor dev";
21
+ async function ensureProcessorDevScript(projectRoot, options) {
22
+ const pkgPath = resolve(projectRoot, "package.json");
23
+ if (!existsSync(pkgPath)) {
24
+ return false;
25
+ }
26
+ let pkg;
27
+ try {
28
+ const pkgRaw = JSON.parse(readFileSync(pkgPath, "utf8"));
29
+ pkg = pkgRaw;
30
+ } catch (error) {
31
+ logger.error("Failed to parse", error);
32
+ return false;
33
+ }
34
+ if (pkg?.scripts?.["processor:dev"]) {
35
+ return true;
36
+ }
37
+ logger.warn('No "processor:dev" script found in package.json.');
38
+ let answer;
39
+ {
40
+ const rl = createInterface({ input: stdin, output: stdout });
41
+ try {
42
+ answer = await rl.question("Add script to package.json? (y/N) ");
43
+ } finally {
44
+ rl.close();
45
+ }
46
+ }
47
+ const isYes = typeof answer === "string" && /^y(?:es)?$/i.test(answer.trim());
48
+ if (!isYes) {
49
+ return false;
50
+ }
51
+ const updated = {
52
+ ...pkg,
53
+ scripts: {
54
+ ...pkg.scripts ?? {},
55
+ "processor:dev": PROCESSOR_DEV_SCRIPT
56
+ }
57
+ };
58
+ try {
59
+ writeFileSync(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
60
+ logger.success('Added "processor:dev" script to package.json');
61
+ return true;
62
+ } catch {
63
+ logger.error("Failed to write to package.json");
64
+ return false;
65
+ }
66
+ }
67
+
20
68
  const main = createMain({
21
69
  meta: {
22
70
  name,
@@ -37,6 +85,10 @@ const main = createMain({
37
85
  nodeArgs: {
38
86
  type: "string",
39
87
  description: "Extra Node args (e.g. --inspect)"
88
+ },
89
+ workers: {
90
+ type: "string",
91
+ description: "Workers to run, comma-separated; use --workers=name1,name2 (default: all)"
40
92
  }
41
93
  },
42
94
  async run({ args }) {
@@ -45,88 +97,31 @@ const main = createMain({
45
97
  const projectRoot = resolve(dirArg);
46
98
  const indexFile = resolve(projectRoot, ".nuxt/dev/workers/index.mjs");
47
99
  const watchDir = resolve(projectRoot, ".nuxt/dev/workers");
48
- if (existsSync(indexFile)) {
49
- const pkgPath = resolve(projectRoot, "package.json");
50
- if (existsSync(pkgPath)) {
51
- try {
52
- const pkgRaw = JSON.parse(readFileSync(pkgPath, "utf8"));
53
- const pkg = pkgRaw;
54
- const hasProcessorDev = Boolean(pkg && pkg.scripts && pkg.scripts["processor:dev"]);
55
- if (!hasProcessorDev) {
56
- consola.warn('No "processor:dev" script found in package.json.');
57
- const rl = createInterface({ input: stdin, output: stdout });
58
- const answer = await rl.question("Add script to package.json? (y/N) ");
59
- rl.close();
60
- const isYes = typeof answer === "string" && /^y(?:es)?$/i.test(answer.trim());
61
- if (isYes) {
62
- const updated = {
63
- ...pkg,
64
- scripts: {
65
- ...pkg.scripts ?? {},
66
- "processor:dev": "nuxt-processor dev"
67
- }
68
- };
69
- try {
70
- writeFileSync(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
71
- consola.success('Added "processor:dev" script to package.json');
72
- } catch {
73
- consola.error("Failed to write to package.json");
74
- }
75
- }
76
- }
77
- } catch {
78
- }
79
- }
80
- }
100
+ const scriptEnsured = await ensureProcessorDevScript(projectRoot);
81
101
  if (!existsSync(indexFile)) {
82
- const pkgPath = resolve(projectRoot, "package.json");
83
- let hasProcessorDev = false;
84
- if (existsSync(pkgPath)) {
85
- try {
86
- const pkgRaw = JSON.parse(readFileSync(pkgPath, "utf8"));
87
- const pkg = pkgRaw;
88
- hasProcessorDev = Boolean(pkg && pkg.scripts && pkg.scripts["processor:dev"]);
89
- if (!hasProcessorDev) {
90
- consola.warn('No "processor:dev" script found in package.json.');
91
- const rl = createInterface({ input: stdin, output: stdout });
92
- const answer = await rl.question("Add script to package.json? (y/N) ");
93
- rl.close();
94
- const isYes = typeof answer === "string" && /^y(?:es)?$/i.test(answer.trim());
95
- if (isYes) {
96
- const updated = {
97
- ...pkg,
98
- scripts: {
99
- ...pkg.scripts || {},
100
- "processor:dev": "nuxt-processor dev"
101
- }
102
- };
103
- try {
104
- writeFileSync(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
105
- consola.success('Added "processor:dev" script to package.json');
106
- } catch {
107
- consola.error("Failed to write to package.json");
108
- }
109
- }
110
- }
111
- } catch {
112
- }
113
- }
114
- consola.error("No entry file found at .nuxt/dev/workers/index.mjs");
115
- consola.info("Please start your Nuxt dev server (e.g. `npm run dev`).");
116
- consola.info("After it starts, run `npx nuxt-processor dev` again to start the processor.");
102
+ logger.error("No entry file found at .nuxt/dev/workers/index.mjs");
103
+ logger.info("Please start your Nuxt dev server (e.g. `npm run dev`).");
104
+ logger.info("After it starts, run `npx nuxt-processor dev` again to start the processor.");
105
+ process.exit(1);
106
+ }
107
+ if (!scriptEnsured) {
108
+ logger.error("Could not ensure processor:dev script in package.json.");
117
109
  process.exit(1);
118
110
  }
119
111
  const nodeBin = process.execPath;
120
112
  const nodeArgsInput = Array.isArray(args.nodeArgs) ? args.nodeArgs : typeof args.nodeArgs === "string" ? args.nodeArgs.split(" ") : [];
121
113
  const extraArgs = nodeArgsInput.filter(Boolean);
114
+ const workersValue = typeof args.workers === "string" ? args.workers.trim() : "";
115
+ const workersFlag = workersValue ? `--workers=${workersValue}` : null;
122
116
  const nodeArgs = [
123
117
  ...extraArgs,
124
118
  "--watch",
125
119
  "--watch-path",
126
120
  watchDir,
127
- indexFile
121
+ indexFile,
122
+ ...workersFlag ? [workersFlag] : []
128
123
  ];
129
- consola.info(`Running watcher for processor`);
124
+ logger.info(`Running watcher for processor`);
130
125
  const child = spawn(nodeBin, nodeArgs, {
131
126
  stdio: "inherit",
132
127
  cwd: projectRoot,
package/dist/module.cjs CHANGED
@@ -1,9 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  const kit = require('@nuxt/kit');
4
- const _package = require('./shared/nuxt-processor.B8GgoFqc.cjs');
4
+ const logger = require('./shared/nuxt-processor.BbReXIMn.cjs');
5
5
  const node_path = require('node:path');
6
6
  const fg = require('fast-glob');
7
+ require('consola');
7
8
 
8
9
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
10
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
@@ -21,21 +22,26 @@ const scanFolder = async (path) => {
21
22
  onlyFiles: true
22
23
  });
23
24
  files.push(...new Set(updatedFiles));
25
+ if (files.length === 0) {
26
+ logger.logger.warn("No worker files found in project");
27
+ }
24
28
  return files;
25
29
  };
26
30
 
27
- function generateWorkersEntryContent(workerFiles, redisInline) {
31
+ function generateWorkersEntryContent(workerFiles) {
28
32
  const toImportArray = workerFiles.map((id) => `() => import(${JSON.stringify(id)})`).join(",\n ");
29
33
  return `
30
34
  import { fileURLToPath } from 'node:url'
31
35
  import { resolve as resolvePath } from 'node:path'
32
36
  import { consola } from 'consola'
37
+ import { useRuntimeConfig } from '#imports'
33
38
  import { $workers } from '#processor-utils'
34
39
 
35
40
  // Initialize connection as early as possible so any imports that register
36
41
  // workers/queues have a valid connection available.
37
42
  const api = $workers()
38
- api.setConnection(${redisInline})
43
+ const { redis } = useRuntimeConfig()
44
+ api.setConnection(process.env.REDIS_URL ? { ...redis, url: process.env.REDIS_URL } : redis)
39
45
 
40
46
  export async function createWorkersApp() {
41
47
  // Avoid EPIPE when stdout/stderr are closed by terminal (e.g., Ctrl+C piping)
@@ -54,15 +60,28 @@ ${toImportArray}
54
60
  for (const loader of modules) {
55
61
  await loader()
56
62
  }
63
+ // Parse --workers flag (e.g. --workers=basic,hello)
64
+ const workersArg = process.argv.find(a => typeof a === 'string' && a.startsWith('--workers='))
65
+ const selectedWorkers = workersArg
66
+ ? workersArg.split('=')[1].split(',').map(s => s.trim()).filter(Boolean)
67
+ : null
68
+ const workersToRun = selectedWorkers
69
+ ? (Array.isArray(api.workers) ? api.workers.filter(w => w && selectedWorkers.includes(w.name)) : [])
70
+ : (Array.isArray(api.workers) ? api.workers : [])
57
71
  const logger = consola.create({}).withTag('nuxt-processor')
72
+ if (selectedWorkers && workersToRun.length === 0) {
73
+ const available = (Array.isArray(api.workers) ? api.workers.map(w => w && w.name).filter(Boolean) : [])
74
+ logger.warn('No workers matched --workers=' + selectedWorkers.join(',') + (available.length ? '. Available: ' + available.join(', ') : '.'))
75
+ process.exit(1)
76
+ }
58
77
  try {
59
- const workerNames = Array.isArray(api.workers) ? api.workers.map(w => w && w.name).filter(Boolean) : []
78
+ const workerNames = workersToRun.map(w => w && w.name).filter(Boolean)
60
79
  logger.info('starting workers:\\n' + workerNames.map(n => ' - ' + n).join('\\n'))
61
- for (const w of api.workers) {
80
+ for (const w of workersToRun) {
62
81
  w.on('error', (err) => logger.error('worker error', err))
63
82
  }
64
83
  // Explicitly start workers since autorun is disabled
65
- for (const w of api.workers) {
84
+ for (const w of workersToRun) {
66
85
  try {
67
86
  // run() returns a promise that resolves when the worker stops; do not await to avoid blocking
68
87
  // eslint-disable-next-line promise/catch-or-return
@@ -76,7 +95,10 @@ logger.success('workers started')
76
95
  } catch (err) {
77
96
  logger.error('failed to initialize workers', err)
78
97
  }
79
- return { stop: api.stopAll, workers: api.workers }
98
+ const closeRunningWorkers = async () => {
99
+ await Promise.allSettled(workersToRun.map(w => w.close()))
100
+ }
101
+ return { stop: closeRunningWorkers, workers: workersToRun }
80
102
  }
81
103
 
82
104
  const isMain = (() => {
@@ -118,36 +140,41 @@ export default { createWorkersApp }
118
140
 
119
141
  const module$1 = kit.defineNuxtModule({
120
142
  meta: {
121
- name: _package.name,
122
- version: _package.version,
123
- compatibility: _package.compatibility,
124
- configKey: _package.configKey
143
+ name: logger.name,
144
+ version: logger.version,
145
+ compatibility: logger.compatibility,
146
+ configKey: logger.configKey
125
147
  },
126
148
  // Default configuration options of the Nuxt module
127
149
  defaults: {
128
150
  redis: {
129
- host: process.env.NUXT_REDIS_HOST ?? "127.0.0.1",
130
- port: Number(process.env.NUXT_REDIS_PORT ?? 6379),
131
- password: process.env.NUXT_REDIS_PASSWORD ?? "",
132
- username: process.env.NUXT_REDIS_USERNAME ?? void 0,
151
+ host: process.env.REDIS_HOST ?? "127.0.0.1",
152
+ port: Number(process.env.REDIS_PORT ?? 6379),
153
+ password: process.env.REDIS_PASSWORD ?? "",
154
+ username: process.env.REDIS_USERNAME ?? void 0,
133
155
  // needs Redis >= 6
134
- db: Number(process.env.NUXT_REDIS_DB ?? 0),
156
+ db: Number(process.env.REDIS_DB ?? 0),
135
157
  // Defaults to 0 on ioredis
136
- lazyConnect: process.env.NUXT_REDIS_LAZY_CONNECT === "true" ? true : void 0,
137
- connectTimeout: process.env.NUXT_REDIS_CONNECT_TIMEOUT ? Number(process.env.NUXT_REDIS_CONNECT_TIMEOUT) : void 0,
138
- url: process.env.NUXT_REDIS_URL ?? void 0
158
+ lazyConnect: process.env.REDIS_LAZY_CONNECT === "true" ? true : void 0,
159
+ connectTimeout: process.env.REDIS_CONNECT_TIMEOUT ? Number(process.env.REDIS_CONNECT_TIMEOUT) : void 0,
160
+ url: process.env.REDIS_URL ?? void 0
139
161
  },
140
162
  workers: "server/workers"
141
163
  },
142
164
  async setup(_options, nuxt) {
143
165
  const { resolve } = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('module.cjs', document.baseURI).href)));
144
- const redisInline = JSON.stringify(_options.redis ?? {});
166
+ const runtimeConfig = nuxt.options.runtimeConfig;
167
+ runtimeConfig.redis = {
168
+ ..._options.redis ?? {},
169
+ ...runtimeConfig.redis ?? {}
170
+ };
145
171
  const nitroPlugin = `
146
- import { defineNitroPlugin } from '#imports'
172
+ import { defineNitroPlugin, useRuntimeConfig } from '#imports'
147
173
  import { $workers } from '#processor-utils'
148
174
 
149
175
  export default defineNitroPlugin(() => {
150
- $workers().setConnection(${redisInline})
176
+ const { redis } = useRuntimeConfig()
177
+ $workers().setConnection(process.env.REDIS_URL ? { ...redis, url: process.env.REDIS_URL } : redis)
151
178
  })
152
179
  `;
153
180
  const tpl = kit.addTemplate({
@@ -197,7 +224,7 @@ declare module '#bullmq' {
197
224
  virtualCode = "";
198
225
  return;
199
226
  }
200
- virtualCode = generateWorkersEntryContent(workerFiles, redisInline);
227
+ virtualCode = generateWorkersEntryContent(workerFiles);
201
228
  for (const id of workerFiles) {
202
229
  this.addWatchFile(id);
203
230
  }
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-processor",
3
- "version": "0.0.14",
3
+ "version": "1.0.0",
4
4
  "compatibility": {
5
5
  "nuxt": "^4.0.0 || ^3.0.0"
6
6
  },
package/dist/module.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import { useNuxt, createResolver, defineNuxtModule, addTemplate, addServerPlugin, addTypeTemplate } from '@nuxt/kit';
2
- import { c as configKey, a as compatibility, v as version, n as name } from './shared/nuxt-processor.C2dSAYu4.mjs';
2
+ import { l as logger, c as configKey, a as compatibility, v as version, n as name } from './shared/nuxt-processor.DCy15jfQ.mjs';
3
3
  import { relative } from 'node:path';
4
4
  import fg from 'fast-glob';
5
+ import 'consola';
5
6
 
6
7
  const scanFolder = async (path) => {
7
8
  const nuxt = useNuxt();
@@ -14,21 +15,26 @@ const scanFolder = async (path) => {
14
15
  onlyFiles: true
15
16
  });
16
17
  files.push(...new Set(updatedFiles));
18
+ if (files.length === 0) {
19
+ logger.warn("No worker files found in project");
20
+ }
17
21
  return files;
18
22
  };
19
23
 
20
- function generateWorkersEntryContent(workerFiles, redisInline) {
24
+ function generateWorkersEntryContent(workerFiles) {
21
25
  const toImportArray = workerFiles.map((id) => `() => import(${JSON.stringify(id)})`).join(",\n ");
22
26
  return `
23
27
  import { fileURLToPath } from 'node:url'
24
28
  import { resolve as resolvePath } from 'node:path'
25
29
  import { consola } from 'consola'
30
+ import { useRuntimeConfig } from '#imports'
26
31
  import { $workers } from '#processor-utils'
27
32
 
28
33
  // Initialize connection as early as possible so any imports that register
29
34
  // workers/queues have a valid connection available.
30
35
  const api = $workers()
31
- api.setConnection(${redisInline})
36
+ const { redis } = useRuntimeConfig()
37
+ api.setConnection(process.env.REDIS_URL ? { ...redis, url: process.env.REDIS_URL } : redis)
32
38
 
33
39
  export async function createWorkersApp() {
34
40
  // Avoid EPIPE when stdout/stderr are closed by terminal (e.g., Ctrl+C piping)
@@ -47,15 +53,28 @@ ${toImportArray}
47
53
  for (const loader of modules) {
48
54
  await loader()
49
55
  }
56
+ // Parse --workers flag (e.g. --workers=basic,hello)
57
+ const workersArg = process.argv.find(a => typeof a === 'string' && a.startsWith('--workers='))
58
+ const selectedWorkers = workersArg
59
+ ? workersArg.split('=')[1].split(',').map(s => s.trim()).filter(Boolean)
60
+ : null
61
+ const workersToRun = selectedWorkers
62
+ ? (Array.isArray(api.workers) ? api.workers.filter(w => w && selectedWorkers.includes(w.name)) : [])
63
+ : (Array.isArray(api.workers) ? api.workers : [])
50
64
  const logger = consola.create({}).withTag('nuxt-processor')
65
+ if (selectedWorkers && workersToRun.length === 0) {
66
+ const available = (Array.isArray(api.workers) ? api.workers.map(w => w && w.name).filter(Boolean) : [])
67
+ logger.warn('No workers matched --workers=' + selectedWorkers.join(',') + (available.length ? '. Available: ' + available.join(', ') : '.'))
68
+ process.exit(1)
69
+ }
51
70
  try {
52
- const workerNames = Array.isArray(api.workers) ? api.workers.map(w => w && w.name).filter(Boolean) : []
71
+ const workerNames = workersToRun.map(w => w && w.name).filter(Boolean)
53
72
  logger.info('starting workers:\\n' + workerNames.map(n => ' - ' + n).join('\\n'))
54
- for (const w of api.workers) {
73
+ for (const w of workersToRun) {
55
74
  w.on('error', (err) => logger.error('worker error', err))
56
75
  }
57
76
  // Explicitly start workers since autorun is disabled
58
- for (const w of api.workers) {
77
+ for (const w of workersToRun) {
59
78
  try {
60
79
  // run() returns a promise that resolves when the worker stops; do not await to avoid blocking
61
80
  // eslint-disable-next-line promise/catch-or-return
@@ -69,7 +88,10 @@ logger.success('workers started')
69
88
  } catch (err) {
70
89
  logger.error('failed to initialize workers', err)
71
90
  }
72
- return { stop: api.stopAll, workers: api.workers }
91
+ const closeRunningWorkers = async () => {
92
+ await Promise.allSettled(workersToRun.map(w => w.close()))
93
+ }
94
+ return { stop: closeRunningWorkers, workers: workersToRun }
73
95
  }
74
96
 
75
97
  const isMain = (() => {
@@ -119,28 +141,33 @@ const module$1 = defineNuxtModule({
119
141
  // Default configuration options of the Nuxt module
120
142
  defaults: {
121
143
  redis: {
122
- host: process.env.NUXT_REDIS_HOST ?? "127.0.0.1",
123
- port: Number(process.env.NUXT_REDIS_PORT ?? 6379),
124
- password: process.env.NUXT_REDIS_PASSWORD ?? "",
125
- username: process.env.NUXT_REDIS_USERNAME ?? void 0,
144
+ host: process.env.REDIS_HOST ?? "127.0.0.1",
145
+ port: Number(process.env.REDIS_PORT ?? 6379),
146
+ password: process.env.REDIS_PASSWORD ?? "",
147
+ username: process.env.REDIS_USERNAME ?? void 0,
126
148
  // needs Redis >= 6
127
- db: Number(process.env.NUXT_REDIS_DB ?? 0),
149
+ db: Number(process.env.REDIS_DB ?? 0),
128
150
  // Defaults to 0 on ioredis
129
- lazyConnect: process.env.NUXT_REDIS_LAZY_CONNECT === "true" ? true : void 0,
130
- connectTimeout: process.env.NUXT_REDIS_CONNECT_TIMEOUT ? Number(process.env.NUXT_REDIS_CONNECT_TIMEOUT) : void 0,
131
- url: process.env.NUXT_REDIS_URL ?? void 0
151
+ lazyConnect: process.env.REDIS_LAZY_CONNECT === "true" ? true : void 0,
152
+ connectTimeout: process.env.REDIS_CONNECT_TIMEOUT ? Number(process.env.REDIS_CONNECT_TIMEOUT) : void 0,
153
+ url: process.env.REDIS_URL ?? void 0
132
154
  },
133
155
  workers: "server/workers"
134
156
  },
135
157
  async setup(_options, nuxt) {
136
158
  const { resolve } = createResolver(import.meta.url);
137
- const redisInline = JSON.stringify(_options.redis ?? {});
159
+ const runtimeConfig = nuxt.options.runtimeConfig;
160
+ runtimeConfig.redis = {
161
+ ..._options.redis ?? {},
162
+ ...runtimeConfig.redis ?? {}
163
+ };
138
164
  const nitroPlugin = `
139
- import { defineNitroPlugin } from '#imports'
165
+ import { defineNitroPlugin, useRuntimeConfig } from '#imports'
140
166
  import { $workers } from '#processor-utils'
141
167
 
142
168
  export default defineNitroPlugin(() => {
143
- $workers().setConnection(${redisInline})
169
+ const { redis } = useRuntimeConfig()
170
+ $workers().setConnection(process.env.REDIS_URL ? { ...redis, url: process.env.REDIS_URL } : redis)
144
171
  })
145
172
  `;
146
173
  const tpl = addTemplate({
@@ -190,7 +217,7 @@ declare module '#bullmq' {
190
217
  virtualCode = "";
191
218
  return;
192
219
  }
193
- virtualCode = generateWorkersEntryContent(workerFiles, redisInline);
220
+ virtualCode = generateWorkersEntryContent(workerFiles);
194
221
  for (const id of workerFiles) {
195
222
  this.addWatchFile(id);
196
223
  }
@@ -8,8 +8,8 @@ export declare function $workers(): {
8
8
  } & {
9
9
  path: string;
10
10
  }> & {
11
- disconnectTimeout?: number;
12
- tls?: import("node:tls").ConnectionOptions;
11
+ disconnectTimeout?: number | undefined;
12
+ tls?: import("node:tls").ConnectionOptions | undefined;
13
13
  } & {
14
14
  url?: string;
15
15
  })) => void;
@@ -1,15 +1,20 @@
1
1
  'use strict';
2
2
 
3
+ const consola = require('consola');
4
+
3
5
  const name = "nuxt-processor";
4
- const version = "0.0.14";
6
+ const version = "1.0.0";
5
7
  const description = "Nuxt Processor";
6
8
  const configKey = "processor";
7
9
  const compatibility = {
8
10
  nuxt: "^4.0.0 || ^3.0.0"
9
11
  };
10
12
 
13
+ const logger = consola.createConsola({}).withTag(name);
14
+
11
15
  exports.compatibility = compatibility;
12
16
  exports.configKey = configKey;
13
17
  exports.description = description;
18
+ exports.logger = logger;
14
19
  exports.name = name;
15
20
  exports.version = version;
@@ -0,0 +1,13 @@
1
+ import { createConsola } from 'consola';
2
+
3
+ const name = "nuxt-processor";
4
+ const version = "1.0.0";
5
+ const description = "Nuxt Processor";
6
+ const configKey = "processor";
7
+ const compatibility = {
8
+ nuxt: "^4.0.0 || ^3.0.0"
9
+ };
10
+
11
+ const logger = createConsola({}).withTag(name);
12
+
13
+ export { compatibility as a, configKey as c, description as d, logger as l, name as n, version as v };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-processor",
3
- "version": "0.0.14",
3
+ "version": "1.0.0",
4
4
  "description": "Nuxt Processor",
5
5
  "repository": "https://github.com/aidanhibbard/nuxt-processor",
6
6
  "license": "MIT",
@@ -35,9 +35,12 @@
35
35
  "dev": "npm run dev:prepare && nuxi dev playground",
36
36
  "dev:build": "nuxi build playground",
37
37
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
38
- "release": "npm run lint && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
38
+ "release": "npm run ci && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
39
39
  "lint": "eslint .",
40
+ "lint:fix": "eslint . --fix",
41
+ "typecheck": "nuxi typecheck",
40
42
  "test": "vitest run",
43
+ "ci": "npm run lint && npm run typecheck && npm run test",
41
44
  "test:coverage": "vitest run --coverage",
42
45
  "test:watch": "vitest watch",
43
46
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
@@ -46,30 +49,31 @@
46
49
  "vp:preview": "vitepress preview docs"
47
50
  },
48
51
  "dependencies": {
49
- "@nuxt/kit": "^4.3.0",
50
- "bullmq": "^5.67.2",
51
- "citty": "^0.2.0",
52
+ "@nuxt/kit": "^4.4.5",
53
+ "bullmq": "^5.76.7",
54
+ "citty": "^0.2.2",
52
55
  "consola": "^3.4.2",
53
56
  "fast-glob": "^3.3.3",
54
- "ioredis": "^5.9.2",
57
+ "ioredis": "^5.10.1",
55
58
  "pathe": "^2.0.3"
56
59
  },
57
60
  "devDependencies": {
58
- "@nuxt/devtools": "^2.6.3",
59
- "@nuxt/eslint": "^1.9.0",
60
- "@nuxt/eslint-config": "^1.9.0",
61
+ "@nuxt/devtools": "^4.0.0-alpha.4",
62
+ "@nuxt/eslint": "^1.15.2",
63
+ "@nuxt/eslint-config": "^1.15.2",
61
64
  "@nuxt/module-builder": "^1.0.2",
62
- "@nuxt/schema": "^4.0.3",
63
- "@nuxt/test-utils": "^3.19.2",
65
+ "@nuxt/schema": "^4.4.5",
66
+ "@nuxt/test-utils": "^4.0.3",
64
67
  "@types/node": "latest",
65
- "@vitest/coverage-v8": "^3.2.4",
68
+ "@vitest/coverage-v8": "^4.1.5",
66
69
  "changelogen": "^0.6.2",
67
- "eslint": "^9.34.0",
68
- "happy-dom": "^20.0.11",
69
- "nuxt": "^4.0.3",
70
+ "eslint": "^10.3.0",
71
+ "happy-dom": "^20.9.0",
72
+ "nuxt": "^4.4.5",
70
73
  "typescript": "~5.9.2",
74
+ "unbuild": "^3.6.1",
71
75
  "vitepress": "^2.0.0-alpha.12",
72
- "vitest": "^3.2.4",
73
- "vue-tsc": "^3.0.6"
76
+ "vitest": "^4.1.5",
77
+ "vue-tsc": "^3.2.8"
74
78
  }
75
79
  }
@@ -1,9 +0,0 @@
1
- const name = "nuxt-processor";
2
- const version = "0.0.14";
3
- const description = "Nuxt Processor";
4
- const configKey = "processor";
5
- const compatibility = {
6
- nuxt: "^4.0.0 || ^3.0.0"
7
- };
8
-
9
- export { compatibility as a, configKey as c, description as d, name as n, version as v };