@owlmeans/queue 0.1.18-rc.2 → 0.1.18-rc.20

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 (54) hide show
  1. package/README.md +237 -8
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/queue/SKILL.md +198 -12
  4. package/build/bridge.d.ts +30 -0
  5. package/build/bridge.d.ts.map +1 -0
  6. package/build/bridge.js +108 -0
  7. package/build/bridge.js.map +1 -0
  8. package/build/config.d.ts +22 -0
  9. package/build/config.d.ts.map +1 -0
  10. package/build/config.js +41 -0
  11. package/build/config.js.map +1 -0
  12. package/build/consts.d.ts +33 -0
  13. package/build/consts.d.ts.map +1 -0
  14. package/build/consts.js +35 -0
  15. package/build/consts.js.map +1 -0
  16. package/build/errors.d.ts +59 -0
  17. package/build/errors.d.ts.map +1 -0
  18. package/build/errors.js +90 -0
  19. package/build/errors.js.map +1 -0
  20. package/build/index.d.ts +8 -0
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +8 -1
  23. package/build/index.js.map +1 -1
  24. package/build/protocol.d.ts +11 -0
  25. package/build/protocol.d.ts.map +1 -0
  26. package/build/protocol.js +59 -0
  27. package/build/protocol.js.map +1 -0
  28. package/build/transport.d.ts +15 -0
  29. package/build/transport.d.ts.map +1 -0
  30. package/build/transport.js +62 -0
  31. package/build/transport.js.map +1 -0
  32. package/build/types.d.ts +248 -0
  33. package/build/types.d.ts.map +1 -0
  34. package/build/types.js +2 -0
  35. package/build/types.js.map +1 -0
  36. package/build/worker.d.ts +27 -0
  37. package/build/worker.d.ts.map +1 -0
  38. package/build/worker.js +58 -0
  39. package/build/worker.js.map +1 -0
  40. package/package.json +12 -2
  41. package/src/bridge.ts +126 -0
  42. package/src/config.ts +56 -0
  43. package/src/consts.ts +39 -0
  44. package/src/errors.ts +106 -0
  45. package/src/index.ts +8 -0
  46. package/src/protocol.ts +81 -0
  47. package/src/transport.ts +82 -0
  48. package/src/types.ts +260 -0
  49. package/src/worker.ts +72 -0
  50. package/tests/bridge.spec.ts +64 -0
  51. package/tests/config.spec.ts +66 -0
  52. package/tests/protocol.spec.ts +58 -0
  53. package/tsconfig.json +1 -0
  54. package/build/.gitkeep +0 -0
@@ -0,0 +1,66 @@
1
+ import { describe, test, expect } from 'bun:test'
2
+ import { declareQueue, isListening, listenQueues, queueOf, queueOfJob } from '../src/config.js'
3
+ import { UnknownQueue } from '../src/errors.js'
4
+ import type { Config } from '../src/types.js'
5
+
6
+ const cfg = (): Config => ({ ready: false, service: 'test', type: 'backend' } as unknown as Config)
7
+
8
+ describe('declaring queues', () => {
9
+ test('a declaration records the queue and the jobs it accepts', () => {
10
+ const config = declareQueue(cfg(), 'work', ['story:code', 'story:gate'])
11
+
12
+ expect(queueOf(config, 'work').jobs).toEqual(['story:code', 'story:gate'])
13
+ })
14
+
15
+ /**
16
+ * Declaring runs from a helper that an application may call once per app it composes, so the
17
+ * second call must not leave two entries under one name — a duplicate would make `queueOf`
18
+ * answer with whichever happened to be first.
19
+ */
20
+ test('re-declaring the same name replaces rather than appends', () => {
21
+ let config = declareQueue(cfg(), 'work', ['story:code'])
22
+ config = declareQueue(config, 'work', ['story:code', 'story:gate'])
23
+
24
+ expect(config.queue?.queues).toHaveLength(1)
25
+ expect(queueOf(config, 'work').jobs).toHaveLength(2)
26
+ })
27
+
28
+ test('asking for a queue nobody declared is an error, not undefined', () => {
29
+ expect(() => queueOf(cfg(), 'missing')).toThrow(UnknownQueue)
30
+ })
31
+
32
+ test('a job name resolves back to the queue that accepts it', () => {
33
+ const config = declareQueue(declareQueue(cfg(), 'work', ['story:code']), 'ops', ['files:get'])
34
+
35
+ expect(queueOfJob(config, 'files:get')?.name).toBe('ops')
36
+ expect(queueOfJob(config, 'nothing:declared')).toBeUndefined()
37
+ })
38
+ })
39
+
40
+ describe('listening', () => {
41
+ /**
42
+ * Declaring a queue must NOT make this process consume it — that separation is what lets one
43
+ * binary deploy as a producer in one place and a worker in another.
44
+ */
45
+ test('declaring a queue does not make the process listen to it', () => {
46
+ const config = declareQueue(cfg(), 'work', ['story:code'])
47
+
48
+ expect(isListening(config, 'work')).toBe(false)
49
+ expect(config.queue?.listen ?? []).toHaveLength(0)
50
+ })
51
+
52
+ test('listening is additive and free of duplicates', () => {
53
+ let config = listenQueues(cfg(), 'work')
54
+ config = listenQueues(config, 'work', 'ops')
55
+
56
+ expect(config.queue?.listen).toEqual(['work', 'ops'])
57
+ expect(isListening(config, 'ops')).toBe(true)
58
+ })
59
+
60
+ test('listening and declaring do not overwrite each other', () => {
61
+ const config = declareQueue(listenQueues(cfg(), 'work'), 'work', ['story:code'])
62
+
63
+ expect(isListening(config, 'work')).toBe(true)
64
+ expect(queueOf(config, 'work').jobs).toEqual(['story:code'])
65
+ })
66
+ })
@@ -0,0 +1,58 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { contract, protocol, schema } from '@owlmeans/entrypoint'
3
+ import { job, route } from '@owlmeans/route'
4
+ import type { JSONSchemaType } from 'ajv'
5
+ import { enqueueProtocol, waitForProtocol, type JobRecord } from '../src/index.js'
6
+
7
+ interface Input { value: number }
8
+ interface Output { doubled: number }
9
+ const InputSchema = schema<Input>({
10
+ type: 'object', properties: { value: { type: 'number' } }, required: ['value'], additionalProperties: false,
11
+ } as JSONSchemaType<Input>)
12
+ const OutputSchema = schema<Output>({
13
+ type: 'object', properties: { doubled: { type: 'number' } }, required: ['doubled'], additionalProperties: false,
14
+ } as JSONSchemaType<Output>)
15
+ const declaration = protocol(
16
+ route('test:double', '/double', job({ queue: 'test' })),
17
+ contract(InputSchema, OutputSchema),
18
+ )
19
+
20
+ const context = (reply: unknown = { value: { doubled: 6 } }) => {
21
+ const created: Partial<JobRecord>[] = []
22
+ return {
23
+ cfg: { queue: { queues: [{ name: 'test', jobs: [declaration.alias] }] } },
24
+ jobs: () => ({
25
+ create: async (record: Partial<JobRecord>) => {
26
+ created.push(record)
27
+ return { ...record, id: 'job-1' } as JobRecord
28
+ },
29
+ wait: async () => reply,
30
+ }),
31
+ created,
32
+ }
33
+ }
34
+
35
+ describe('protocol-aware queue calls', () => {
36
+ test('derives the broker address and keeps per-call options', async () => {
37
+ const ctx = context()
38
+ const queued = await enqueueProtocol(ctx as never, declaration, { body: { value: 3 } }, {
39
+ delay: 250, attempts: 3, id: 'projection-1',
40
+ })
41
+ expect(queued.queue).toBe('test')
42
+ expect(ctx.created[0]?.name).toBe(declaration.alias)
43
+ expect(ctx.created[0]?.opts).toEqual({ delay: 250, attempts: 3, id: 'projection-1' })
44
+ expect(await waitForProtocol(ctx as never, declaration, queued as never)).toEqual({ doubled: 6 })
45
+ })
46
+
47
+ test('rejects raw aliases and non-queue declarations at runtime', async () => {
48
+ await expect(enqueueProtocol(context() as never, declaration.alias as never, {} as never)).rejects.toThrow()
49
+ const http = protocol(route('test:http', '/http'), contract())
50
+ await expect(enqueueProtocol(context() as never, http, {})).rejects.toThrow()
51
+ })
52
+
53
+ test('rejects a job from another queue or protocol', async () => {
54
+ await expect(waitForProtocol(context() as never, declaration, {
55
+ id: 'x', queue: 'other', name: declaration.alias, data: {},
56
+ } as never)).rejects.toThrow()
57
+ })
58
+ })
package/tsconfig.json CHANGED
@@ -10,6 +10,7 @@
10
10
  "exclude": [
11
11
  "./dist/**/*",
12
12
  "./build/**/*",
13
+ "./tests/**/*",
13
14
  "./*.ts"
14
15
  ]
15
16
  }
package/build/.gitkeep DELETED
File without changes