@c9up/bay 0.1.13 → 0.2.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.
Files changed (85) hide show
  1. package/README.md +122 -16
  2. package/dist/BayProvider.d.ts +39 -11
  3. package/dist/BayProvider.d.ts.map +1 -1
  4. package/dist/BayProvider.js +35 -13
  5. package/dist/BayProvider.js.map +1 -1
  6. package/dist/Job.d.ts +99 -0
  7. package/dist/Job.d.ts.map +1 -0
  8. package/dist/Job.js +78 -0
  9. package/dist/Job.js.map +1 -0
  10. package/dist/QueueManager.d.ts +140 -21
  11. package/dist/QueueManager.d.ts.map +1 -1
  12. package/dist/QueueManager.js +247 -53
  13. package/dist/QueueManager.js.map +1 -1
  14. package/dist/adapters.d.ts +68 -0
  15. package/dist/adapters.d.ts.map +1 -0
  16. package/dist/adapters.js +56 -0
  17. package/dist/adapters.js.map +1 -0
  18. package/dist/augmentations.d.ts +28 -0
  19. package/dist/augmentations.d.ts.map +1 -0
  20. package/dist/augmentations.js +17 -0
  21. package/dist/augmentations.js.map +1 -0
  22. package/dist/configure.d.ts +1 -0
  23. package/dist/configure.d.ts.map +1 -1
  24. package/dist/configure.js +24 -7
  25. package/dist/configure.js.map +1 -1
  26. package/dist/console/contract.d.ts +60 -0
  27. package/dist/console/contract.d.ts.map +1 -0
  28. package/dist/console/contract.js +36 -0
  29. package/dist/console/contract.js.map +1 -0
  30. package/dist/console/index.d.ts +29 -0
  31. package/dist/console/index.d.ts.map +1 -0
  32. package/dist/console/index.js +45 -0
  33. package/dist/console/index.js.map +1 -0
  34. package/dist/console/makeJob.d.ts +32 -0
  35. package/dist/console/makeJob.d.ts.map +1 -0
  36. package/dist/console/makeJob.js +118 -0
  37. package/dist/console/makeJob.js.map +1 -0
  38. package/dist/console/queueWork.d.ts +18 -0
  39. package/dist/console/queueWork.d.ts.map +1 -0
  40. package/dist/console/queueWork.js +58 -0
  41. package/dist/console/queueWork.js.map +1 -0
  42. package/dist/drivers/MemoryDriver.d.ts +14 -8
  43. package/dist/drivers/MemoryDriver.d.ts.map +1 -1
  44. package/dist/drivers/MemoryDriver.js +61 -7
  45. package/dist/drivers/MemoryDriver.js.map +1 -1
  46. package/dist/drivers/RedisDriver.d.ts +60 -8
  47. package/dist/drivers/RedisDriver.d.ts.map +1 -1
  48. package/dist/drivers/RedisDriver.js +209 -29
  49. package/dist/drivers/RedisDriver.js.map +1 -1
  50. package/dist/index.d.ts +10 -6
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +8 -4
  53. package/dist/index.js.map +1 -1
  54. package/dist/jobs.d.ts +43 -0
  55. package/dist/jobs.d.ts.map +1 -0
  56. package/dist/jobs.js +105 -0
  57. package/dist/jobs.js.map +1 -0
  58. package/dist/quasar.d.ts +1 -1
  59. package/dist/quasar.js +1 -1
  60. package/dist/testing/FakeQueue.d.ts +15 -9
  61. package/dist/testing/FakeQueue.d.ts.map +1 -1
  62. package/dist/testing/FakeQueue.js +13 -3
  63. package/dist/testing/FakeQueue.js.map +1 -1
  64. package/package.json +5 -3
  65. package/src/BayProvider.ts +79 -26
  66. package/src/Job.ts +137 -0
  67. package/src/QueueManager.ts +411 -56
  68. package/src/adapters.ts +75 -0
  69. package/src/augmentations.ts +31 -0
  70. package/src/configure.ts +25 -7
  71. package/src/console/contract.ts +94 -0
  72. package/src/console/index.ts +68 -0
  73. package/src/console/makeJob.ts +139 -0
  74. package/src/console/queueWork.ts +70 -0
  75. package/src/drivers/MemoryDriver.ts +66 -14
  76. package/src/drivers/RedisDriver.ts +298 -42
  77. package/src/index.ts +35 -6
  78. package/src/jobs.ts +111 -0
  79. package/src/quasar.ts +1 -1
  80. package/src/testing/FakeQueue.ts +25 -15
  81. package/dist/stores.d.ts +0 -41
  82. package/dist/stores.d.ts.map +0 -1
  83. package/dist/stores.js +0 -46
  84. package/dist/stores.js.map +0 -1
  85. package/src/stores.ts +0 -59
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The queue adapter factories a config file names — `{ default, adapters }`.
3
+ *
4
+ * The shape the framework gives a package with several backends and one
5
+ * selected: a `drivers` namespace imported beside `defineConfig`, each entry
6
+ * that namespace's result, and the selection read from the environment. Bay had
7
+ * a single `driver: "memory"` and told everyone else to build the manager by
8
+ * hand, which meant Redis could not be reached from a config file at all.
9
+ *
10
+ * import { defineConfig, drivers } from '@c9up/bay'
11
+ *
12
+ * export default defineConfig({
13
+ * default: env.get('QUEUE_DRIVER'),
14
+ * adapters: {
15
+ * memory: drivers.memory(),
16
+ * redis: drivers.redis({ connection: 'main' }),
17
+ * },
18
+ * })
19
+ *
20
+ * The names are upstream's: `@adonisjs/queue` reads `default` + `adapters` out
21
+ * of `config/queue.ts`, fills them from a `drivers` namespace, and takes the
22
+ * selection from `QUEUE_DRIVER`. Bay said `stores` / `QUEUE_STORE`, which is
23
+ * the vocabulary of a different package. Both still work — see `stores` below.
24
+ *
25
+ * Factories are lazy: only the adapter an application actually uses is built,
26
+ * so naming a Redis queue in a config that runs in memory opens no connection.
27
+ */
28
+ import type { RedisClientSource } from "./drivers/RedisDriver.js";
29
+ import type { QueueDriver } from "./QueueManager.js";
30
+ /** A driver, built on first use. */
31
+ export type AdapterFactory = () => QueueDriver;
32
+ /**
33
+ * The older name for {@link AdapterFactory}, kept for configs typed against it.
34
+ */
35
+ export type QueueStoreFactory = AdapterFactory;
36
+ export declare const drivers: {
37
+ /** In memory. Jobs do not survive a restart — for tests and dev. */
38
+ memory(): AdapterFactory;
39
+ /**
40
+ * Redis. `connection` takes an ioredis-shaped client, a function answering
41
+ * one, or the NAME of a `@c9up/quasar` connection — the last resolved at
42
+ * first use, without bay importing quasar, which stays an optional peer.
43
+ */
44
+ redis(options: {
45
+ connection: RedisClientSource | string;
46
+ prefix?: string;
47
+ visibilityTimeoutMs?: number;
48
+ }): AdapterFactory;
49
+ };
50
+ /**
51
+ * The older name for {@link drivers}, kept for configs written against it. The
52
+ * same object: `stores.redis(...)` and `drivers.redis(...)` are one call.
53
+ */
54
+ export declare const stores: {
55
+ /** In memory. Jobs do not survive a restart — for tests and dev. */
56
+ memory(): AdapterFactory;
57
+ /**
58
+ * Redis. `connection` takes an ioredis-shaped client, a function answering
59
+ * one, or the NAME of a `@c9up/quasar` connection — the last resolved at
60
+ * first use, without bay importing quasar, which stays an optional peer.
61
+ */
62
+ redis(options: {
63
+ connection: RedisClientSource | string;
64
+ prefix?: string;
65
+ visibilityTimeoutMs?: number;
66
+ }): AdapterFactory;
67
+ };
68
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,oCAAoC;AACpC,MAAM,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAE/C,eAAO,MAAM,OAAO;IACnB,oEAAoE;cAC1D,cAAc;IAIxB;;;;OAIG;mBACY;QACd,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAAC;QACvC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC7B,GAAG,cAAc;CAWlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,MAAM;IA/BlB,oEAAoE;cAC1D,cAAc;IAIxB;;;;OAIG;mBACY;QACd,UAAU,EAAE,iBAAiB,GAAG,MAAM,CAAC;QACvC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC7B,GAAG,cAAc;CAiBU,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The queue adapter factories a config file names — `{ default, adapters }`.
3
+ *
4
+ * The shape the framework gives a package with several backends and one
5
+ * selected: a `drivers` namespace imported beside `defineConfig`, each entry
6
+ * that namespace's result, and the selection read from the environment. Bay had
7
+ * a single `driver: "memory"` and told everyone else to build the manager by
8
+ * hand, which meant Redis could not be reached from a config file at all.
9
+ *
10
+ * import { defineConfig, drivers } from '@c9up/bay'
11
+ *
12
+ * export default defineConfig({
13
+ * default: env.get('QUEUE_DRIVER'),
14
+ * adapters: {
15
+ * memory: drivers.memory(),
16
+ * redis: drivers.redis({ connection: 'main' }),
17
+ * },
18
+ * })
19
+ *
20
+ * The names are upstream's: `@adonisjs/queue` reads `default` + `adapters` out
21
+ * of `config/queue.ts`, fills them from a `drivers` namespace, and takes the
22
+ * selection from `QUEUE_DRIVER`. Bay said `stores` / `QUEUE_STORE`, which is
23
+ * the vocabulary of a different package. Both still work — see `stores` below.
24
+ *
25
+ * Factories are lazy: only the adapter an application actually uses is built,
26
+ * so naming a Redis queue in a config that runs in memory opens no connection.
27
+ */
28
+ import { MemoryDriver } from "./drivers/MemoryDriver.js";
29
+ import { RedisDriver } from "./drivers/RedisDriver.js";
30
+ import { quasarConnection } from "./quasar.js";
31
+ export const drivers = {
32
+ /** In memory. Jobs do not survive a restart — for tests and dev. */
33
+ memory() {
34
+ return () => new MemoryDriver();
35
+ },
36
+ /**
37
+ * Redis. `connection` takes an ioredis-shaped client, a function answering
38
+ * one, or the NAME of a `@c9up/quasar` connection — the last resolved at
39
+ * first use, without bay importing quasar, which stays an optional peer.
40
+ */
41
+ redis(options) {
42
+ const source = typeof options.connection === "string"
43
+ ? quasarConnection(options.connection)
44
+ : options.connection;
45
+ return () => new RedisDriver(source, {
46
+ prefix: options.prefix,
47
+ visibilityTimeoutMs: options.visibilityTimeoutMs,
48
+ });
49
+ },
50
+ };
51
+ /**
52
+ * The older name for {@link drivers}, kept for configs written against it. The
53
+ * same object: `stores.redis(...)` and `drivers.redis(...)` are one call.
54
+ */
55
+ export const stores = drivers;
56
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAU/C,MAAM,CAAC,MAAM,OAAO,GAAG;IACtB,oEAAoE;IACpE,MAAM;QACL,OAAO,GAAG,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAIL;QACA,MAAM,MAAM,GACX,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ;YACrC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC;YACtC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QACvB,OAAO,GAAG,EAAE,CACX,IAAI,WAAW,CAAC,MAAM,EAAE;YACvB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;SAChD,CAAC,CAAC;IACL,CAAC;CACD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Teach ream's `ContainerBindings` what `container.make('queue')` returns.
3
+ *
4
+ * ream declares that interface open on purpose: it registers its own entries
5
+ * and expects each package to contribute the one it owns. Nothing filled this
6
+ * one in, so resolving by the string token answered `unknown` and every call
7
+ * site had to assert a type it could not prove.
8
+ *
9
+ * Loaded from the package barrel and from the provider, so registering bay is
10
+ * enough — an application writes no `declare module` of its own.
11
+ *
12
+ * Type-only, and ream stays an OPTIONAL peer: nothing here reaches a runtime
13
+ * import, and a `declare module` for a specifier that does not resolve is
14
+ * simply inert.
15
+ */
16
+ import type { QueueManager } from "./QueueManager.js";
17
+ declare module "@c9up/ream/types" {
18
+ interface ContainerBindings {
19
+ /** The job queue, bound by `BayProvider`. */
20
+ "bay.queue": QueueManager;
21
+ /**
22
+ * The same binding under the name it had before the token carried its
23
+ * package. Kept bound so an existing `container.make(...)` resolves.
24
+ */
25
+ queue: QueueManager;
26
+ }
27
+ }
28
+ //# sourceMappingURL=augmentations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"augmentations.d.ts","sourceRoot":"","sources":["../src/augmentations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,QAAQ,kBAAkB,CAAC;IACjC,UAAU,iBAAiB;QAC1B,6CAA6C;QAC7C,WAAW,EAAE,YAAY,CAAC;QAC1B;;;WAGG;QACH,KAAK,EAAE,YAAY,CAAC;KACpB;CACD"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Teach ream's `ContainerBindings` what `container.make('queue')` returns.
3
+ *
4
+ * ream declares that interface open on purpose: it registers its own entries
5
+ * and expects each package to contribute the one it owns. Nothing filled this
6
+ * one in, so resolving by the string token answered `unknown` and every call
7
+ * site had to assert a type it could not prove.
8
+ *
9
+ * Loaded from the package barrel and from the provider, so registering bay is
10
+ * enough — an application writes no `declare module` of its own.
11
+ *
12
+ * Type-only, and ream stays an OPTIONAL peer: nothing here reaches a runtime
13
+ * import, and a `declare module` for a specifier that does not resolve is
14
+ * simply inert.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=augmentations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"augmentations.js","sourceRoot":"","sources":["../src/augmentations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -8,6 +8,7 @@
8
8
  */
9
9
  interface Codemods {
10
10
  addProvider(importPath: string): Promise<void>;
11
+ registerCommand(importPath: string): Promise<void>;
11
12
  addEnvVars(vars: Record<string, string>): Promise<void>;
12
13
  writeFile(filePath: string, content: string, options?: {
13
14
  force?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,UAAU,QAAQ;IACjB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,SAAS,CACR,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBjE"}
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,UAAU,QAAQ;IACjB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,SAAS,CACR,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CjE"}
package/dist/configure.js CHANGED
@@ -11,21 +11,38 @@ export async function configure(codemods) {
11
11
  // without them leaves an application whose config asks the environment for
12
12
  // something nothing ever put there.
13
13
  await codemods.addEnvVars({
14
- QUEUE_STORE: "memory",
14
+ QUEUE_DRIVER: "memory",
15
15
  });
16
16
  await codemods.addProvider("@c9up/bay/provider");
17
- await codemods.writeFile("config/queue.ts", `import { defineConfig, stores } from '@c9up/bay'
17
+ // `queue:work` and `make:job` are the package's, not the binary's: a
18
+ // project reaches them by listing the module, never by upgrading `ream`.
19
+ await codemods.registerCommand("@c9up/bay/commands");
20
+ await codemods.writeFile("config/queue.ts", `import { defineConfig, drivers } from '@c9up/bay'
18
21
  import env from '#start/env'
19
22
 
20
23
  export default defineConfig({
21
- // Which store to run on. Memory forgets everything on restart, which is
24
+ // Which adapter to run on. Memory forgets everything on restart, which is
22
25
  // what a single process in development wants and nothing else does.
23
- default: env.get('QUEUE_STORE', 'memory'),
26
+ default: env.get('QUEUE_DRIVER', 'memory'),
24
27
 
25
- stores: {
26
- memory: stores.memory(),
27
- redis: stores.redis({ connection: 'main' }),
28
+ adapters: {
29
+ memory: drivers.memory(),
30
+ redis: drivers.redis({ connection: 'main' }),
28
31
  },
32
+
33
+ // What the worker does between jobs: how long it waits after finding
34
+ // nothing, how often it reclaims jobs a crashed worker left behind, how many
35
+ // it runs at once, and which named queues it serves.
36
+ worker: {
37
+ idleDelay: 2_000,
38
+ stalledInterval: 30_000,
39
+ concurrency: 1,
40
+ // queues: ['critical', 'default'],
41
+ },
42
+
43
+ // Where the job classes live. Every module under here is imported at boot,
44
+ // so a worker resolves a queued record by the class's own name.
45
+ locations: ['app/jobs'],
29
46
  })`);
30
47
  }
31
48
  //# sourceMappingURL=configure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB;IACjD,4EAA4E;IAC5E,2EAA2E;IAC3E,oCAAoC;IACpC,MAAM,QAAQ,CAAC,UAAU,CAAC;QACzB,WAAW,EAAE,QAAQ;KACrB,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;IACjD,MAAM,QAAQ,CAAC,SAAS,CACvB,iBAAiB,EACjB;;;;;;;;;;;;GAYC,CACD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB;IACjD,4EAA4E;IAC5E,2EAA2E;IAC3E,oCAAoC;IACpC,MAAM,QAAQ,CAAC,UAAU,CAAC;QACzB,YAAY,EAAE,QAAQ;KACtB,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;IACjD,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,QAAQ,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;IACrD,MAAM,QAAQ,CAAC,SAAS,CACvB,iBAAiB,EACjB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BC,CACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The console command contract, declared locally.
3
+ *
4
+ * Bay stays framework-agnostic: it must not import `@c9up/ream`, so it
5
+ * describes the shape Ream's console kernel dispatches against rather than
6
+ * importing it.
7
+ *
8
+ * Ream's decorators (`@args` / `@flags`) live in the framework, so the helpers
9
+ * below build the same metadata without them.
10
+ */
11
+ export interface CommandOptions {
12
+ /** Boot the application before `run()`. Off by default. */
13
+ startApp?: boolean;
14
+ staysAlive?: boolean;
15
+ allowUnknownFlags?: boolean;
16
+ }
17
+ export interface ArgumentMetaData {
18
+ type: "string" | "spread";
19
+ propertyName: string;
20
+ argumentName: string;
21
+ description?: string;
22
+ required: boolean;
23
+ default?: string | string[];
24
+ }
25
+ export interface FlagMetaData {
26
+ type: "string" | "boolean" | "number" | "array";
27
+ propertyName: string;
28
+ flagName: string;
29
+ description?: string;
30
+ alias: string[];
31
+ default?: string | string[] | number | boolean;
32
+ required: boolean;
33
+ }
34
+ /** The static side the kernel reads. */
35
+ export interface BayCommandClass {
36
+ new (): {
37
+ run(): Promise<void> | void;
38
+ };
39
+ commandName: string;
40
+ description: string;
41
+ options?: CommandOptions;
42
+ args?: readonly ArgumentMetaData[];
43
+ flags?: readonly FlagMetaData[];
44
+ help?: string | string[];
45
+ }
46
+ export declare function flag(propertyName: string, type: FlagMetaData["type"], options?: {
47
+ flagName?: string;
48
+ description?: string;
49
+ alias?: string[];
50
+ default?: FlagMetaData["default"];
51
+ required?: boolean;
52
+ }): FlagMetaData;
53
+ export declare function argument(propertyName: string, options?: {
54
+ type?: ArgumentMetaData["type"];
55
+ argumentName?: string;
56
+ description?: string;
57
+ required?: boolean;
58
+ default?: ArgumentMetaData["default"];
59
+ }): ArgumentMetaData;
60
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/console/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,cAAc;IAC9B,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC;IAC/C,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,wCAAwC;AACxC,MAAM,WAAW,eAAe;IAC/B,QAAQ;QAAE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,IAAI,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACnC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACzB;AAOD,wBAAgB,IAAI,CACnB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAC1B,OAAO,GAAE;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACd,GACJ,YAAY,CAUd;AAED,wBAAgB,QAAQ,CACvB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;IACR,IAAI,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;CACjC,GACJ,gBAAgB,CASlB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The console command contract, declared locally.
3
+ *
4
+ * Bay stays framework-agnostic: it must not import `@c9up/ream`, so it
5
+ * describes the shape Ream's console kernel dispatches against rather than
6
+ * importing it.
7
+ *
8
+ * Ream's decorators (`@args` / `@flags`) live in the framework, so the helpers
9
+ * below build the same metadata without them.
10
+ */
11
+ /** `startServer` → `start-server`, matching the framework's decorators. */
12
+ function dashCase(value) {
13
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
14
+ }
15
+ export function flag(propertyName, type, options = {}) {
16
+ return {
17
+ type,
18
+ propertyName,
19
+ flagName: options.flagName ?? dashCase(propertyName),
20
+ description: options.description,
21
+ alias: options.alias ?? [],
22
+ default: options.default,
23
+ required: options.required ?? false,
24
+ };
25
+ }
26
+ export function argument(propertyName, options = {}) {
27
+ return {
28
+ type: options.type ?? "string",
29
+ propertyName,
30
+ argumentName: options.argumentName ?? dashCase(propertyName),
31
+ description: options.description,
32
+ required: options.required ?? options.default === undefined,
33
+ default: options.default,
34
+ };
35
+ }
36
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/console/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuCH,2EAA2E;AAC3E,SAAS,QAAQ,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,IAAI,CACnB,YAAoB,EACpB,IAA0B,EAC1B,UAMI,EAAE;IAEN,OAAO;QACN,IAAI;QACJ,YAAY;QACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,YAAY,CAAC;QACpD,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;KACnC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CACvB,YAAoB,EACpB,UAMI,EAAE;IAEN,OAAO;QACN,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ;QAC9B,YAAY;QACZ,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,CAAC;QAC5D,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAC3D,OAAO,EAAE,OAAO,CAAC,OAAO;KACxB,CAAC;AACH,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `@c9up/bay/commands` — the commands bay ships.
3
+ *
4
+ * // reamrc.ts, written by `configure()`
5
+ * commands: [() => import('@c9up/bay/commands')]
6
+ *
7
+ * A module answering `getMetaData()` / `getCommand()`, which is how a package
8
+ * adds commands: by shipping them, never by a change to the `ream` binary.
9
+ *
10
+ * `jobsDir` is read through a getter, not captured: these classes are built
11
+ * when the module is imported — before the application boots — while `run()`
12
+ * happens after it, when the config exists.
13
+ */
14
+ import type { BayCommandClass } from "./contract.js";
15
+ /** What the kernel reads to list a command without importing it. */
16
+ interface CommandMetaData {
17
+ commandName: string;
18
+ namespace: string | null;
19
+ description: string;
20
+ help?: string | string[];
21
+ aliases: string[];
22
+ options: Record<string, unknown>;
23
+ args: readonly unknown[];
24
+ flags: readonly unknown[];
25
+ }
26
+ export declare function getMetaData(): Promise<CommandMetaData[]>;
27
+ export declare function getCommand(metadata: CommandMetaData): Promise<BayCommandClass | null>;
28
+ export type { BayCommandClass } from "./contract.js";
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/console/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAarD,oEAAoE;AACpE,UAAU,eAAe;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IACzB,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;CAC1B;AAgBD,wBAAsB,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAE9D;AAED,wBAAsB,UAAU,CAC/B,QAAQ,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAKjC;AAED,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * `@c9up/bay/commands` — the commands bay ships.
3
+ *
4
+ * // reamrc.ts, written by `configure()`
5
+ * commands: [() => import('@c9up/bay/commands')]
6
+ *
7
+ * A module answering `getMetaData()` / `getCommand()`, which is how a package
8
+ * adds commands: by shipping them, never by a change to the `ream` binary.
9
+ *
10
+ * `jobsDir` is read through a getter, not captured: these classes are built
11
+ * when the module is imported — before the application boots — while `run()`
12
+ * happens after it, when the config exists.
13
+ */
14
+ import { getJobsDir } from "../jobs.js";
15
+ import { makeJobCommand } from "./makeJob.js";
16
+ import { queueWorkCommand } from "./queueWork.js";
17
+ const COMMANDS = [
18
+ queueWorkCommand(),
19
+ makeJobCommand({
20
+ get jobsDir() {
21
+ return getJobsDir();
22
+ },
23
+ }),
24
+ ];
25
+ function serialize(command) {
26
+ const colon = command.commandName.indexOf(":");
27
+ return {
28
+ commandName: command.commandName,
29
+ namespace: colon === -1 ? null : command.commandName.slice(0, colon),
30
+ description: command.description,
31
+ help: command.help,
32
+ aliases: [],
33
+ options: { ...command.options },
34
+ args: command.args ?? [],
35
+ flags: command.flags ?? [],
36
+ };
37
+ }
38
+ export async function getMetaData() {
39
+ return COMMANDS.map(serialize);
40
+ }
41
+ export async function getCommand(metadata) {
42
+ return (COMMANDS.find((command) => command.commandName === metadata.commandName) ??
43
+ null);
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/console/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,QAAQ,GAA+B;IAC5C,gBAAgB,EAAE;IAClB,cAAc,CAAC;QACd,IAAI,OAAO;YACV,OAAO,UAAU,EAAE,CAAC;QACrB,CAAC;KACD,CAAC;CACF,CAAC;AAcF,SAAS,SAAS,CAAC,OAAwB;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO;QACN,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,SAAS,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;QACpE,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE;QAC/B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;KAC1B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAChC,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,QAAyB;IAEzB,OAAO,CACN,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,WAAW,CAAC;QACxE,IAAI,CACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * `make:job` — scaffold a job class.
3
+ *
4
+ * ream make:job SendWelcomeEmail → app/jobs/send_welcome_email.ts
5
+ * ream make:job emails/SendWelcomeEmail → app/jobs/emails/send_welcome_email.ts
6
+ *
7
+ * A subdirectory is allowed and is the only reason the name is not a plain
8
+ * identifier: `..` and every other way out of the jobs directory is refused
9
+ * before anything is written.
10
+ */
11
+ import { type BayCommandClass } from "./contract.js";
12
+ export interface MakeJobOptions {
13
+ /** Directory the job files are scaffolded into. */
14
+ jobsDir: string;
15
+ }
16
+ /** `SendWelcomeEmail` → `send_welcome_email`, `HTTPPing` → `http_ping`. */
17
+ export declare function toSnakeCase(name: string): string;
18
+ /** `send_welcome_email` / `sendWelcomeEmail` → `SendWelcomeEmail`. */
19
+ export declare function toPascalCase(name: string): string;
20
+ /**
21
+ * Split `emails/SendWelcomeEmail` into the directory it goes in and the class
22
+ * it declares, refusing anything that would leave the jobs directory.
23
+ */
24
+ export declare function resolveJobName(input: string): {
25
+ dir: string;
26
+ className: string;
27
+ fileName: string;
28
+ };
29
+ /** The file a fresh job starts as. */
30
+ export declare function jobStub(className: string): string;
31
+ export declare function makeJobCommand(options: MakeJobOptions): BayCommandClass;
32
+ //# sourceMappingURL=makeJob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"makeJob.d.ts","sourceRoot":"","sources":["../../src/console/makeJob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC9B,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACjB,CAwBA;AAED,sCAAsC;AACtC,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2BjD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAoCvE"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * `make:job` — scaffold a job class.
3
+ *
4
+ * ream make:job SendWelcomeEmail → app/jobs/send_welcome_email.ts
5
+ * ream make:job emails/SendWelcomeEmail → app/jobs/emails/send_welcome_email.ts
6
+ *
7
+ * A subdirectory is allowed and is the only reason the name is not a plain
8
+ * identifier: `..` and every other way out of the jobs directory is refused
9
+ * before anything is written.
10
+ */
11
+ import * as fsp from "node:fs/promises";
12
+ import * as path from "node:path";
13
+ import { argument } from "./contract.js";
14
+ /** `SendWelcomeEmail` → `send_welcome_email`, `HTTPPing` → `http_ping`. */
15
+ export function toSnakeCase(name) {
16
+ return name
17
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
18
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
19
+ .replace(/[-\s]+/g, "_")
20
+ .toLowerCase();
21
+ }
22
+ /** `send_welcome_email` / `sendWelcomeEmail` → `SendWelcomeEmail`. */
23
+ export function toPascalCase(name) {
24
+ return name
25
+ .split(/[_\-\s]+/)
26
+ .filter((part) => part.length > 0)
27
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
28
+ .join("");
29
+ }
30
+ /**
31
+ * Split `emails/SendWelcomeEmail` into the directory it goes in and the class
32
+ * it declares, refusing anything that would leave the jobs directory.
33
+ */
34
+ export function resolveJobName(input) {
35
+ const parts = input.split("/").filter((part) => part.length > 0);
36
+ const last = parts.pop();
37
+ if (last === undefined || last.length === 0) {
38
+ throw new Error(`Invalid job name: '${input}'`);
39
+ }
40
+ for (const part of [...parts, last]) {
41
+ // `..` is the traversal; the rest are characters a filename has no
42
+ // business carrying and a shell has opinions about.
43
+ if (part === ".." || /[\\'";`]/.test(part)) {
44
+ throw new Error(`Invalid job name: '${input}'`);
45
+ }
46
+ }
47
+ const className = toPascalCase(last);
48
+ if (!/^[A-Za-z][A-Za-z0-9]*$/.test(className)) {
49
+ throw new Error(`Invalid job name: '${input}' — a job's name becomes a class name`);
50
+ }
51
+ return {
52
+ dir: parts.join("/"),
53
+ className,
54
+ fileName: `${toSnakeCase(last)}.ts`,
55
+ };
56
+ }
57
+ /** The file a fresh job starts as. */
58
+ export function jobStub(className) {
59
+ return `import { Job } from '@c9up/bay'
60
+ import type { JobOptions } from '@c9up/bay'
61
+
62
+ interface ${className}Payload {
63
+ // What \`dispatch(${className}, …)\` must be given.
64
+ }
65
+
66
+ export default class ${className} extends Job<${className}Payload> {
67
+ static options: JobOptions = {
68
+ // queue: 'default',
69
+ // maxRetries: 3,
70
+ // delay: '10s',
71
+ // timeout: '1m',
72
+ }
73
+
74
+ async execute(): Promise<void> {
75
+ // The work. Throwing is what makes the attempt fail.
76
+ void this.payload
77
+ }
78
+
79
+ async failed(error: Error): Promise<void> {
80
+ // Once the last attempt has failed — the alert or the cleanup.
81
+ void error
82
+ }
83
+ }
84
+ `;
85
+ }
86
+ export function makeJobCommand(options) {
87
+ return class MakeJob {
88
+ static commandName = "make:job";
89
+ static description = "Scaffold a background job class";
90
+ // Pure filesystem work: no reason to boot the app and open a connection.
91
+ static options = { startApp: false };
92
+ static args = [
93
+ argument("name", {
94
+ description: "Job class name, optionally under a subdirectory",
95
+ }),
96
+ ];
97
+ async run() {
98
+ let resolved;
99
+ try {
100
+ resolved = resolveJobName(this.name);
101
+ }
102
+ catch (err) {
103
+ console.error(`[bay] ${err instanceof Error ? err.message : String(err)}`);
104
+ process.exitCode = 1;
105
+ return;
106
+ }
107
+ const dir = path.join(options.jobsDir, resolved.dir);
108
+ const filePath = path.join(dir, resolved.fileName);
109
+ await fsp.mkdir(dir, { recursive: true });
110
+ // `wx`: an existing job is never clobbered, and the error says so.
111
+ await fsp.writeFile(filePath, jobStub(resolved.className), {
112
+ flag: "wx",
113
+ });
114
+ console.log(`Created ${filePath}`);
115
+ }
116
+ };
117
+ }
118
+ //# sourceMappingURL=makeJob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"makeJob.js","sourceRoot":"","sources":["../../src/console/makeJob.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `queue:work` — run the worker that takes jobs off the queue.
3
+ *
4
+ * The command a deployment runs as its own process, beside the HTTP one:
5
+ *
6
+ * ream queue:work
7
+ * ream queue:work --queue=emails,notifications
8
+ * ream queue:work --concurrency=10
9
+ *
10
+ * It stays alive on purpose — `staysAlive` — and the loop it starts is the
11
+ * application's, so a SIGTERM reaches `BayProvider.shutdown()`, which stops the
12
+ * worker and lets the job in flight finish rather than dropping it.
13
+ */
14
+ import { type BayCommandClass } from "./contract.js";
15
+ /** Split `--queue=a,b` into names, dropping the empties a trailing comma makes. */
16
+ export declare function parseQueues(value: string | undefined): string[] | undefined;
17
+ export declare function queueWorkCommand(): BayCommandClass;
18
+ //# sourceMappingURL=queueWork.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queueWork.d.ts","sourceRoot":"","sources":["../../src/console/queueWork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,eAAe,EAAQ,MAAM,eAAe,CAAC;AAE3D,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAO3E;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CA0ClD"}