@nuetzliches/croniq-runner 0.1.0 → 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.
- package/CHANGELOG.md +8 -3
- package/README.md +37 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -39
- package/dist/client.js.map +1 -1
- package/dist/http.d.ts +16 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +56 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +23 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +16 -9
- package/dist/runner.js.map +1 -1
- package/dist/trigger.d.ts +97 -0
- package/dist/trigger.d.ts.map +1 -0
- package/dist/trigger.js +166 -0
- package/dist/trigger.js.map +1 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.2.0 - 2026-07-15
|
|
4
|
+
|
|
5
|
+
- First-class producer **trigger client** ([#284](https://github.com/nuetzliches/croniq/issues/284), parity with the .NET SDK [#277](https://github.com/nuetzliches/croniq/issues/277)): `createTriggerClient(...)` / `CroniqTriggerClient.trigger(jobKey, { metadata, require, prefer, timeout, idempotencyKey })` wraps `POST /v1/trigger` and returns `{ executionId, queued, deduplicated }`. Independent of the runner and carries its own `jobs:trigger`-scoped credentials. Unset optionals are omitted from the body; `idempotency_key` drives server-side dedup ([#279](https://github.com/nuetzliches/croniq/issues/279)) with a missing `deduplicated` flag parsed as `false`. A `429` per-job queue-overflow ([#299](https://github.com/nuetzliches/croniq/issues/299)) surfaces as `QueueOverflowError` (subclass of `HttpError`, with `retryAfterMs`); other non-2xx surface as `HttpError`.
|
|
6
|
+
- Conformance against the producer trigger cases in [`sdks/conformance/cases-trigger/`](../conformance/cases-trigger) ([#287](https://github.com/nuetzliches/croniq/issues/287)).
|
|
7
|
+
|
|
8
|
+
## 0.1.0 - 2026-05-25
|
|
4
9
|
|
|
5
10
|
Initial release. Implements the Croniq runner protocol:
|
|
6
11
|
|
|
7
12
|
- Poll / ack / renew / events / register endpoints (`/v1/work/*`, `/v1/jobs/register`).
|
|
8
|
-
- ESM-first, Node
|
|
13
|
+
- ESM-first, Node 20+, native `fetch` and `AbortController`.
|
|
9
14
|
- Streaming `LogWriter` with batch-by-count, batch-by-time, drain-before-ack semantics.
|
|
10
15
|
- Per-execution `AbortSignal` honouring `PollResponse.cancel`.
|
|
11
16
|
- Self-registration of schedule-bearing handlers at startup.
|
|
12
17
|
- `Authorization: ApiKey {key}` and `Bearer {token}` precedence.
|
|
13
18
|
- Persistent runner-id resolution (env → state file → generated).
|
|
14
|
-
- Conformance against
|
|
19
|
+
- Conformance against every runner case in [`sdks/conformance/cases/`](../conformance/cases).
|
package/README.md
CHANGED
|
@@ -51,6 +51,7 @@ await runner.run(controller.signal);
|
|
|
51
51
|
- **Server-side cancellation** — `PollResponse.cancel` aborts the handler's `ctx.signal`.
|
|
52
52
|
- **Streaming `LogWriter`** — bounded queue with backpressure, batch by count (32) / by time (200 ms) / max 100 events per POST, **drain-before-ack**.
|
|
53
53
|
- **Self-registration** — `runner.handle('key', fn, { schedule: '5m' })` calls `POST /v1/jobs/register` once at startup (DSL precedence applies server-side).
|
|
54
|
+
- **Producer trigger client** — `createTriggerClient(...)` fires jobs on demand via `POST /v1/trigger` with its own `jobs:trigger` credentials, `idempotency_key` dedup, and `429` backpressure surfaced as `QueueOverflowError`. See [Trigger a job on demand](#trigger-a-job-on-demand-producer).
|
|
54
55
|
- **Auth precedence** — `Authorization: ApiKey {key}` if set, else `Bearer {token}`.
|
|
55
56
|
- **Persistent runner-id** — env var → state file → generated `{prefix}-{hex8}`, persisted under `$XDG_STATE_HOME/croniq-runner` (Linux/macOS) or `%LOCALAPPDATA%\croniq-runner` (Windows).
|
|
56
57
|
- **OpenTelemetry-ready** — bring your own `@opentelemetry/sdk-node` setup; the SDK plays nicely with the standard `@opentelemetry/api` no-op fallback.
|
|
@@ -117,6 +118,41 @@ runner.handle(
|
|
|
117
118
|
|
|
118
119
|
On startup the SDK calls `POST /v1/jobs/register`. If a Croniqfile (DSL) entry with the same `job_key` exists, the server returns `status=skipped_dsl_precedence` and the SDK logs an info message — your runner still polls and executes the job normally, just driven by the DSL schedule rather than the runner-registered one.
|
|
119
120
|
|
|
121
|
+
## Trigger a job on demand (producer)
|
|
122
|
+
|
|
123
|
+
The runner above is the **consumer** side. The **producer** side — firing a job _immediately_, e.g. in response to an application event — is a separate, first-class client wrapping `POST /v1/trigger`. It is independent of the runner: triggering needs the `jobs:trigger` (or `admin`) scope, which runner poll keys typically don't carry, so the trigger client takes **its own** credentials rather than reusing a runner's. (Parity with the .NET SDK's `ICroniqTriggerClient`.)
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { createTriggerClient } from '@nuetzliches/croniq-runner';
|
|
127
|
+
|
|
128
|
+
const client = createTriggerClient({
|
|
129
|
+
serverUrl: 'http://localhost:4000',
|
|
130
|
+
apiKey: process.env.CRONIQ_TRIGGER_KEY, // jobs:trigger scope — NOT a runner poll key
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const { executionId, queued, deduplicated } = await client.trigger('billing:invoice-generate', {
|
|
134
|
+
metadata: { invoice_id: 'inv_42' },
|
|
135
|
+
require: ['billing'],
|
|
136
|
+
prefer: ['eu-central'],
|
|
137
|
+
timeout: '10m',
|
|
138
|
+
idempotencyKey: 'evt-2026-07-14-001', // optional server-side dedup
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The same registered handler serves both its Croniqfile schedule (safety-net / reconcile floor) and near-real-time, event-driven fires — one execution and observability path, no second code path.
|
|
143
|
+
|
|
144
|
+
- **Unset optionals are omitted** from the JSON body — a producer never sends `metadata` / `require` / `prefer` / `timeout` / `idempotency_key` the caller didn't supply.
|
|
145
|
+
- **Idempotency.** Pass `idempotencyKey` so at-least-once producers (event redelivery, retries, concurrent publishers) coalesce onto one execution. The result's `deduplicated` is `true` when the server returned an existing execution; servers without idempotency support omit the flag and it defaults to `false`.
|
|
146
|
+
- **Backpressure.** A `429` (per-job queue-overflow cap) throws `QueueOverflowError` — a subclass of `HttpError` carrying `retryAfterMs` when the server sends `Retry-After` — so a batching / retrying producer can back off instead of dropping work. Any other non-2xx throws `HttpError`.
|
|
147
|
+
|
|
148
|
+
| Option | Default | Description |
|
|
149
|
+
| ------------------ | -------------- | ---------------------------------------------------- |
|
|
150
|
+
| `serverUrl` | _(required)_ | Croniq server base URL. |
|
|
151
|
+
| `apiKey` | — | `Authorization: ApiKey {…}`. Precedence over bearer. |
|
|
152
|
+
| `bearerToken` | — | `Authorization: Bearer {…}`. |
|
|
153
|
+
| `requestTimeoutMs` | `30_000` | Per-request timeout. |
|
|
154
|
+
| `fetchImpl` | global `fetch` | Custom `fetch` (testing / proxies). |
|
|
155
|
+
|
|
120
156
|
## Configuration
|
|
121
157
|
|
|
122
158
|
| Option | Default | Description |
|
|
@@ -141,7 +177,7 @@ LogWriter sub-options: `channelCapacity` (256), `batchSizeThreshold` (32), `batc
|
|
|
141
177
|
|
|
142
178
|
## Wire-protocol conformance
|
|
143
179
|
|
|
144
|
-
Validated against the shared, language-neutral suite at [`sdks/conformance/`](../conformance/) — the
|
|
180
|
+
Validated against the shared, language-neutral suite at [`sdks/conformance/`](../conformance/) — the runner (consumer) cases in [`cases/`](../conformance/cases), plus the producer (trigger) cases in [`cases-trigger/`](../conformance/cases-trigger) ([#287](https://github.com/nuetzliches/croniq/issues/287)) which the binding's trigger runner picks up automatically once present. The TypeScript binding lives at [`sdks/conformance/bindings/typescript/`](../conformance/bindings/typescript).
|
|
145
181
|
|
|
146
182
|
```sh
|
|
147
183
|
cd sdks/conformance/bindings/typescript
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACV,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACV,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,qBAAa,SAAU,SAAQ,KAAK;aAEhB,MAAM,EAAE,MAAM;aACd,UAAU,EAAE,MAAM;aAClB,IAAI,EAAE,MAAM;aACZ,IAAI,EAAE,MAAM;gBAHZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;CAK/B;AAED;;;;GAIG;AACH,qBAAa,YAAY;;gBAOX,IAAI,EAAE,mBAAmB;IAQ/B,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAKrF,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,KAAK,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxF,WAAW,CAAC,GAAG,EAAE,kBAAkB,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;CAgE1G"}
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AbortError } from './deferred.js';
|
|
2
|
+
import { composeSignals, isAbortLikeError } from './http.js';
|
|
2
3
|
import { trimTrailingSlashes } from './url.js';
|
|
3
4
|
export class HttpError extends Error {
|
|
4
5
|
status;
|
|
@@ -105,43 +106,4 @@ export class CroniqClient {
|
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
|
-
function composeSignals(outer, timeoutMs) {
|
|
109
|
-
if (timeoutMs == null) {
|
|
110
|
-
return { signal: outer, dispose: () => { } };
|
|
111
|
-
}
|
|
112
|
-
// Node 18 doesn't have AbortSignal.any; build one by hand. The caller MUST
|
|
113
|
-
// invoke dispose() in a finally — otherwise long-lived outer signals
|
|
114
|
-
// (e.g. the runner's loop signal) accumulate one listener per poll.
|
|
115
|
-
const ac = new AbortController();
|
|
116
|
-
let timer;
|
|
117
|
-
const onOuterAbort = () => {
|
|
118
|
-
if (timer)
|
|
119
|
-
clearTimeout(timer);
|
|
120
|
-
ac.abort(outer.reason);
|
|
121
|
-
};
|
|
122
|
-
const dispose = () => {
|
|
123
|
-
if (timer)
|
|
124
|
-
clearTimeout(timer);
|
|
125
|
-
outer.removeEventListener('abort', onOuterAbort);
|
|
126
|
-
};
|
|
127
|
-
if (outer.aborted) {
|
|
128
|
-
ac.abort(outer.reason);
|
|
129
|
-
return { signal: ac.signal, dispose };
|
|
130
|
-
}
|
|
131
|
-
timer = setTimeout(() => {
|
|
132
|
-
outer.removeEventListener('abort', onOuterAbort);
|
|
133
|
-
ac.abort(new AbortError('timeout'));
|
|
134
|
-
}, timeoutMs);
|
|
135
|
-
outer.addEventListener('abort', onOuterAbort, { once: true });
|
|
136
|
-
return { signal: ac.signal, dispose };
|
|
137
|
-
}
|
|
138
|
-
function isAbortLikeError(err) {
|
|
139
|
-
if (!(err instanceof Error))
|
|
140
|
-
return false;
|
|
141
|
-
if (err.name === 'AbortError')
|
|
142
|
-
return true;
|
|
143
|
-
// undici exposes the original cause for fetch aborts in some Node versions.
|
|
144
|
-
const cause = err.cause;
|
|
145
|
-
return cause instanceof Error && cause.name === 'AbortError';
|
|
146
|
-
}
|
|
147
109
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ComposedSignal {
|
|
2
|
+
signal: AbortSignal;
|
|
3
|
+
/** Removes the listener we attached to `outer`. Must be called in a finally. */
|
|
4
|
+
dispose: () => void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Combines an outer `AbortSignal` with an optional per-request timeout into a
|
|
8
|
+
* single signal. When `timeoutMs` is omitted the outer signal is returned
|
|
9
|
+
* as-is. Node 18 doesn't have `AbortSignal.any`, so this is built by hand; the
|
|
10
|
+
* caller MUST invoke `dispose()` in a finally — otherwise long-lived outer
|
|
11
|
+
* signals accumulate one listener per request.
|
|
12
|
+
*/
|
|
13
|
+
export declare function composeSignals(outer: AbortSignal | undefined, timeoutMs?: number): ComposedSignal;
|
|
14
|
+
/** True for a native fetch abort, including undici's wrapped-cause variant. */
|
|
15
|
+
export declare function isAbortLikeError(err: unknown): boolean;
|
|
16
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,gFAAgF;IAChF,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAgCjG;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMtD"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Shared HTTP plumbing for the runner client (client.ts) and the producer
|
|
2
|
+
// trigger client (trigger.ts). Kept dependency-free beyond `AbortError` so
|
|
3
|
+
// both clients compose an outer signal with a per-request timeout the same
|
|
4
|
+
// way — and abort classification stays identical across the two.
|
|
5
|
+
import { AbortError } from './deferred.js';
|
|
6
|
+
/**
|
|
7
|
+
* Combines an outer `AbortSignal` with an optional per-request timeout into a
|
|
8
|
+
* single signal. When `timeoutMs` is omitted the outer signal is returned
|
|
9
|
+
* as-is. Node 18 doesn't have `AbortSignal.any`, so this is built by hand; the
|
|
10
|
+
* caller MUST invoke `dispose()` in a finally — otherwise long-lived outer
|
|
11
|
+
* signals accumulate one listener per request.
|
|
12
|
+
*/
|
|
13
|
+
export function composeSignals(outer, timeoutMs) {
|
|
14
|
+
if (timeoutMs == null) {
|
|
15
|
+
if (outer == null)
|
|
16
|
+
return { signal: new AbortController().signal, dispose: () => { } };
|
|
17
|
+
return { signal: outer, dispose: () => { } };
|
|
18
|
+
}
|
|
19
|
+
const ac = new AbortController();
|
|
20
|
+
let timer;
|
|
21
|
+
if (outer == null) {
|
|
22
|
+
timer = setTimeout(() => ac.abort(new AbortError('timeout')), timeoutMs);
|
|
23
|
+
return { signal: ac.signal, dispose: () => timer && clearTimeout(timer) };
|
|
24
|
+
}
|
|
25
|
+
const onOuterAbort = () => {
|
|
26
|
+
if (timer)
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
ac.abort(outer.reason);
|
|
29
|
+
};
|
|
30
|
+
const dispose = () => {
|
|
31
|
+
if (timer)
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
outer.removeEventListener('abort', onOuterAbort);
|
|
34
|
+
};
|
|
35
|
+
if (outer.aborted) {
|
|
36
|
+
ac.abort(outer.reason);
|
|
37
|
+
return { signal: ac.signal, dispose };
|
|
38
|
+
}
|
|
39
|
+
timer = setTimeout(() => {
|
|
40
|
+
outer.removeEventListener('abort', onOuterAbort);
|
|
41
|
+
ac.abort(new AbortError('timeout'));
|
|
42
|
+
}, timeoutMs);
|
|
43
|
+
outer.addEventListener('abort', onOuterAbort, { once: true });
|
|
44
|
+
return { signal: ac.signal, dispose };
|
|
45
|
+
}
|
|
46
|
+
/** True for a native fetch abort, including undici's wrapped-cause variant. */
|
|
47
|
+
export function isAbortLikeError(err) {
|
|
48
|
+
if (!(err instanceof Error))
|
|
49
|
+
return false;
|
|
50
|
+
if (err.name === 'AbortError')
|
|
51
|
+
return true;
|
|
52
|
+
// undici exposes the original cause for fetch aborts in some Node versions.
|
|
53
|
+
const cause = err.cause;
|
|
54
|
+
return cause instanceof Error && cause.name === 'AbortError';
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,2EAA2E;AAC3E,iEAAiE;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,KAA8B,EAAE,SAAkB;IAC/E,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;QACtF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,IAAI,KAAiC,CAAC;IAEtC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACzE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED,MAAM,YAAY,GAAG,GAAS,EAAE;QAC9B,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IACxC,CAAC;IACD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QACtB,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACjD,EAAE,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACtC,CAAC,EAAE,SAAS,CAAC,CAAC;IACd,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC3C,4EAA4E;IAC5E,MAAM,KAAK,GAAI,GAA2B,CAAC,KAAK,CAAC;IACjD,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC;AAC/D,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export { NoHandlerRegisteredError } from './handler.js';
|
|
|
6
6
|
export type { Logger, LogLevel } from './logger.js';
|
|
7
7
|
export { consoleLogger, noopLogger } from './logger.js';
|
|
8
8
|
export type { LogWriter } from './log-writer.js';
|
|
9
|
-
export type { AckRequest, AckStatus, PollRequest, PollResponse, RegisterJobRequest, RegisterJobResponse, RenewRequest, WorkAssignment, WorkEvent, WorkEventLevel, } from './protocol.js';
|
|
9
|
+
export type { AckRequest, AckStatus, PollRequest, PollResponse, RegisterJobRequest, RegisterJobResponse, RenewRequest, TriggerRequest, TriggerResponse, WorkAssignment, WorkEvent, WorkEventLevel, } from './protocol.js';
|
|
10
10
|
export { HttpError } from './client.js';
|
|
11
|
+
export { CroniqTriggerClient, createTriggerClient, QueueOverflowError } from './trigger.js';
|
|
12
|
+
export type { CroniqTriggerClientOptions, TriggerParams, TriggerResult, } from './trigger.js';
|
|
11
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,SAAS,EACT,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,cAAc,EACd,SAAS,EACT,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5F,YAAY,EACV,0BAA0B,EAC1B,aAAa,EACb,aAAa,GACd,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,6 @@ export { CroniqRunner, createRunner } from './runner.js';
|
|
|
3
3
|
export { NoHandlerRegisteredError } from './handler.js';
|
|
4
4
|
export { consoleLogger, noopLogger } from './logger.js';
|
|
5
5
|
export { HttpError } from './client.js';
|
|
6
|
+
// Producer-side trigger (on-demand) client — parity with the .NET SDK (#277).
|
|
7
|
+
export { CroniqTriggerClient, createTriggerClient, QueueOverflowError } from './trigger.js';
|
|
6
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAgBxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,8EAA8E;AAC9E,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -51,4 +51,27 @@ export interface WorkEvent {
|
|
|
51
51
|
message: string;
|
|
52
52
|
fields?: Record<string, string>;
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Wire request for `POST /v1/trigger` (producer side). Optional fields are
|
|
56
|
+
* omitted from the JSON body when unset — a producer never emits a key the
|
|
57
|
+
* caller didn't supply (`JSON.stringify` drops `undefined` values).
|
|
58
|
+
*/
|
|
59
|
+
export interface TriggerRequest {
|
|
60
|
+
job_key: string;
|
|
61
|
+
metadata?: Record<string, unknown>;
|
|
62
|
+
require?: string[];
|
|
63
|
+
prefer?: string[];
|
|
64
|
+
timeout?: string;
|
|
65
|
+
idempotency_key?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Wire response of `POST /v1/trigger`. `deduplicated` is sent by servers that
|
|
69
|
+
* support trigger idempotency keys (#279); older servers omit it and the
|
|
70
|
+
* client defaults it to `false`.
|
|
71
|
+
*/
|
|
72
|
+
export interface TriggerResponse {
|
|
73
|
+
execution_id: string;
|
|
74
|
+
queued: number;
|
|
75
|
+
deduplicated?: boolean;
|
|
76
|
+
}
|
|
54
77
|
//# sourceMappingURL=protocol.d.ts.map
|
package/dist/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,GAAG,wBAAwB,CAAC;CAClD;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3E,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC"}
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,GAAG,wBAAwB,CAAC;CAClD;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3E,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB"}
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC5B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAkB,KAAK,mBAAmB,EAA8B,MAAM,cAAc,CAAC;AAGpG;;;;;;;GAOG;AACH,qBAAa,YAAY;;gBAaX,OAAO,EAAE,mBAAmB;IAYxC;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,IAAI;IAKhF,gFAAgF;IAChF,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAK5C,qEAAqE;IACrE,IAAI,QAAQ,IAAI,MAAM,CAGrB;IAED,sEAAsE;IACtE,IAAI,QAAQ,IAAI,SAAS,MAAM,EAAE,CAEhC;IAED;;;;OAIG;IACG,GAAG,CAAC,MAAM,GAAE,WAA0C,GAAG,OAAO,CAAC,IAAI,CAAC;IA4C5E;;;OAGG;IACH,YAAY,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC5B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAkB,KAAK,mBAAmB,EAA8B,MAAM,cAAc,CAAC;AAGpG;;;;;;;GAOG;AACH,qBAAa,YAAY;;gBAaX,OAAO,EAAE,mBAAmB;IAYxC;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,IAAI;IAKhF,gFAAgF;IAChF,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAK5C,qEAAqE;IACrE,IAAI,QAAQ,IAAI,MAAM,CAGrB;IAED,sEAAsE;IACtE,IAAI,QAAQ,IAAI,SAAS,MAAM,EAAE,CAEhC;IAED;;;;OAIG;IACG,GAAG,CAAC,MAAM,GAAE,WAA0C,GAAG,OAAO,CAAC,IAAI,CAAC;IA4C5E;;;OAGG;IACH,YAAY,IAAI,IAAI;CA4HrB;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAEvE"}
|
package/dist/runner.js
CHANGED
|
@@ -135,15 +135,11 @@ export class CroniqRunner {
|
|
|
135
135
|
}
|
|
136
136
|
async #pollLoop(signal) {
|
|
137
137
|
while (!signal.aborted) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
138
|
+
// Control-slot polling (issue #176): even at capacity we still poll
|
|
139
|
+
// so the server can deliver cancels via PollResponse.cancel. The
|
|
140
|
+
// server returns immediately on capacity=0 (no long-poll), so
|
|
141
|
+
// capacityBackoffMs paces the loop and prevents a stampede.
|
|
142
|
+
const atCapacity = this.#inflight.size >= this.#options.maxInflight;
|
|
147
143
|
const request = {
|
|
148
144
|
runner_id: this.#runnerId,
|
|
149
145
|
capabilities: this.#options.capabilities,
|
|
@@ -172,6 +168,17 @@ export class CroniqRunner {
|
|
|
172
168
|
continue;
|
|
173
169
|
}
|
|
174
170
|
this.#handleCancellations(response.cancel);
|
|
171
|
+
if (atCapacity) {
|
|
172
|
+
// Work is always empty in this branch (server-side capacity
|
|
173
|
+
// check); cancels above are already processed. Pace the loop.
|
|
174
|
+
try {
|
|
175
|
+
await sleep(this.#options.capacityBackoffMs, signal);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
175
182
|
for (const assignment of response.work) {
|
|
176
183
|
if (this.#inflight.has(assignment.execution_id))
|
|
177
184
|
continue;
|
package/dist/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { HttpError } from './client.js';
|
|
2
|
+
/** Options for {@link CroniqTriggerClient} / {@link createTriggerClient}. */
|
|
3
|
+
export interface CroniqTriggerClientOptions {
|
|
4
|
+
/** Base URL of the Croniq server, e.g. `http://localhost:4000`. */
|
|
5
|
+
serverUrl: string;
|
|
6
|
+
/**
|
|
7
|
+
* API key for `Authorization: ApiKey {key}`. Takes precedence over
|
|
8
|
+
* {@link bearerToken} when both are set. Needs the `jobs:trigger` (or
|
|
9
|
+
* `admin`) scope — distinct from a runner's poll scopes.
|
|
10
|
+
*/
|
|
11
|
+
apiKey?: string | undefined;
|
|
12
|
+
/** Bearer token for `Authorization: Bearer {token}`. */
|
|
13
|
+
bearerToken?: string | undefined;
|
|
14
|
+
/** Per-request timeout in milliseconds. Default 30 000 ms. */
|
|
15
|
+
requestTimeoutMs?: number | undefined;
|
|
16
|
+
/** Custom `fetch` implementation. Defaults to the global `fetch`. */
|
|
17
|
+
fetchImpl?: typeof fetch | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** Optional arguments for a single {@link CroniqTriggerClient.trigger} call. */
|
|
20
|
+
export interface TriggerParams {
|
|
21
|
+
/**
|
|
22
|
+
* Arbitrary JSON metadata forwarded to the handler as-is (merged over the
|
|
23
|
+
* job's DSL metadata server-side). Keys starting with `__` are reserved.
|
|
24
|
+
*/
|
|
25
|
+
metadata?: Record<string, unknown>;
|
|
26
|
+
/** Capabilities a runner MUST have to be assigned this execution. */
|
|
27
|
+
require?: string[];
|
|
28
|
+
/** Capabilities used to prefer runners when several are eligible. */
|
|
29
|
+
prefer?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Execution timeout as a server duration string (e.g. `"30s"`, `"5m"`).
|
|
32
|
+
* The server default applies when omitted.
|
|
33
|
+
*/
|
|
34
|
+
timeout?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Optional dedup key (≤ 200 chars, scoped per `job_key`). Servers with
|
|
37
|
+
* trigger-idempotency support (#279) coalesce repeat triggers carrying the
|
|
38
|
+
* same key onto the existing execution (see {@link TriggerResult.deduplicated});
|
|
39
|
+
* older servers ignore it.
|
|
40
|
+
*/
|
|
41
|
+
idempotencyKey?: string;
|
|
42
|
+
/** Abort signal to cancel the underlying HTTP call. */
|
|
43
|
+
signal?: AbortSignal;
|
|
44
|
+
}
|
|
45
|
+
/** Result of an on-demand job trigger (`POST /v1/trigger`). */
|
|
46
|
+
export interface TriggerResult {
|
|
47
|
+
/**
|
|
48
|
+
* Identifier of the execution the trigger resolved to. On a dedup hit this
|
|
49
|
+
* is the EXISTING execution's id, not a new one.
|
|
50
|
+
*/
|
|
51
|
+
executionId: string;
|
|
52
|
+
/** Server work-queue depth after the trigger was processed. */
|
|
53
|
+
queued: number;
|
|
54
|
+
/**
|
|
55
|
+
* `true` when the server coalesced this trigger onto an existing execution
|
|
56
|
+
* because the request carried an `idempotency_key` it had already seen.
|
|
57
|
+
* Always `false` on servers without idempotency-key support (they omit the
|
|
58
|
+
* flag and the client defaults it to `false`).
|
|
59
|
+
*/
|
|
60
|
+
deduplicated: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Thrown when `POST /v1/trigger` is rejected with `429 Too Many Requests`
|
|
64
|
+
* because the job's per-job queue-depth cap is reached (#299). A producer that
|
|
65
|
+
* batches or retries triggers should treat this as backpressure — back off and
|
|
66
|
+
* retry later rather than dropping the work silently. {@link retryAfterMs}
|
|
67
|
+
* carries the server's `Retry-After` hint when present.
|
|
68
|
+
*/
|
|
69
|
+
export declare class QueueOverflowError extends HttpError {
|
|
70
|
+
readonly retryAfterMs?: number | undefined;
|
|
71
|
+
constructor(path: string, body: string, retryAfterMs?: number | undefined);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Client for firing Croniq jobs on demand. Serialises a snake_case JSON body,
|
|
75
|
+
* attaches `Authorization` per request (ApiKey precedence over Bearer), and
|
|
76
|
+
* parses the `TriggerResponse` (defaulting a missing `deduplicated` to
|
|
77
|
+
* `false`). Non-2xx responses surface as errors — `429` as a
|
|
78
|
+
* {@link QueueOverflowError}, everything else as an {@link HttpError}.
|
|
79
|
+
*/
|
|
80
|
+
export declare class CroniqTriggerClient {
|
|
81
|
+
#private;
|
|
82
|
+
constructor(opts: CroniqTriggerClientOptions);
|
|
83
|
+
/**
|
|
84
|
+
* Fire a job immediately. Its registered handler runs on the next eligible
|
|
85
|
+
* runner, exactly like a scheduled fire.
|
|
86
|
+
*
|
|
87
|
+
* @param jobKey Job key, e.g. `billing:invoice-generate`.
|
|
88
|
+
* @param params Optional metadata / routing hints / timeout / idempotency key.
|
|
89
|
+
* @returns The created (or deduplicated) execution and queue depth.
|
|
90
|
+
* @throws {QueueOverflowError} on `429` per-job queue overflow (#299).
|
|
91
|
+
* @throws {HttpError} on any other non-2xx response.
|
|
92
|
+
*/
|
|
93
|
+
trigger(jobKey: string, params?: TriggerParams): Promise<TriggerResult>;
|
|
94
|
+
}
|
|
95
|
+
/** Convenience factory mirroring `createRunner`. */
|
|
96
|
+
export declare function createTriggerClient(opts: CroniqTriggerClientOptions): CroniqTriggerClient;
|
|
97
|
+
//# sourceMappingURL=trigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../src/trigger.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE5B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAC;CACtC;AAED,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,uDAAuD;IACvD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;aAI7B,YAAY,CAAC,EAAE,MAAM;gBAFrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACI,YAAY,CAAC,EAAE,MAAM,YAAA;CAKxC;AAKD;;;;;;GAMG;AACH,qBAAa,mBAAmB;;gBAOlB,IAAI,EAAE,0BAA0B;IAiB5C;;;;;;;;;OASG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;CAoElF;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,0BAA0B,GAAG,mBAAmB,CAEzF"}
|
package/dist/trigger.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Producer-side trigger client — an idiomatic wrapper over `POST /v1/trigger`.
|
|
2
|
+
//
|
|
3
|
+
// Parity with the .NET `ICroniqTriggerClient` (#277): fire a registered job on
|
|
4
|
+
// demand so the *same* handler serves both its Croniqfile schedule and
|
|
5
|
+
// near-real-time, event-driven execution. Deliberately independent of the
|
|
6
|
+
// runner: triggering needs the `jobs:trigger` (or `admin`) scope, which runner
|
|
7
|
+
// poll keys typically do not carry, so the trigger client takes ITS OWN
|
|
8
|
+
// credentials rather than reusing a runner's.
|
|
9
|
+
import { HttpError } from './client.js';
|
|
10
|
+
import { AbortError } from './deferred.js';
|
|
11
|
+
import { composeSignals, isAbortLikeError } from './http.js';
|
|
12
|
+
import { trimTrailingSlashes } from './url.js';
|
|
13
|
+
/**
|
|
14
|
+
* Thrown when `POST /v1/trigger` is rejected with `429 Too Many Requests`
|
|
15
|
+
* because the job's per-job queue-depth cap is reached (#299). A producer that
|
|
16
|
+
* batches or retries triggers should treat this as backpressure — back off and
|
|
17
|
+
* retry later rather than dropping the work silently. {@link retryAfterMs}
|
|
18
|
+
* carries the server's `Retry-After` hint when present.
|
|
19
|
+
*/
|
|
20
|
+
export class QueueOverflowError extends HttpError {
|
|
21
|
+
retryAfterMs;
|
|
22
|
+
constructor(path, body, retryAfterMs) {
|
|
23
|
+
super(429, 'Too Many Requests', path, body);
|
|
24
|
+
this.retryAfterMs = retryAfterMs;
|
|
25
|
+
this.name = 'QueueOverflowError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const TRIGGER_PATH = '/v1/trigger';
|
|
29
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
30
|
+
/**
|
|
31
|
+
* Client for firing Croniq jobs on demand. Serialises a snake_case JSON body,
|
|
32
|
+
* attaches `Authorization` per request (ApiKey precedence over Bearer), and
|
|
33
|
+
* parses the `TriggerResponse` (defaulting a missing `deduplicated` to
|
|
34
|
+
* `false`). Non-2xx responses surface as errors — `429` as a
|
|
35
|
+
* {@link QueueOverflowError}, everything else as an {@link HttpError}.
|
|
36
|
+
*/
|
|
37
|
+
export class CroniqTriggerClient {
|
|
38
|
+
#baseUrl;
|
|
39
|
+
#apiKey;
|
|
40
|
+
#bearerToken;
|
|
41
|
+
#requestTimeoutMs;
|
|
42
|
+
#fetch;
|
|
43
|
+
constructor(opts) {
|
|
44
|
+
if (!opts.serverUrl || typeof opts.serverUrl !== 'string') {
|
|
45
|
+
throw new TypeError('CroniqTriggerClientOptions.serverUrl is required');
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
// eslint-disable-next-line no-new
|
|
49
|
+
new URL(opts.serverUrl);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
throw new TypeError(`CroniqTriggerClientOptions.serverUrl is not a valid URL: ${opts.serverUrl}`);
|
|
53
|
+
}
|
|
54
|
+
this.#baseUrl = trimTrailingSlashes(opts.serverUrl);
|
|
55
|
+
this.#apiKey = opts.apiKey;
|
|
56
|
+
this.#bearerToken = opts.bearerToken;
|
|
57
|
+
this.#requestTimeoutMs = opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
58
|
+
this.#fetch = opts.fetchImpl ?? fetch;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fire a job immediately. Its registered handler runs on the next eligible
|
|
62
|
+
* runner, exactly like a scheduled fire.
|
|
63
|
+
*
|
|
64
|
+
* @param jobKey Job key, e.g. `billing:invoice-generate`.
|
|
65
|
+
* @param params Optional metadata / routing hints / timeout / idempotency key.
|
|
66
|
+
* @returns The created (or deduplicated) execution and queue depth.
|
|
67
|
+
* @throws {QueueOverflowError} on `429` per-job queue overflow (#299).
|
|
68
|
+
* @throws {HttpError} on any other non-2xx response.
|
|
69
|
+
*/
|
|
70
|
+
async trigger(jobKey, params = {}) {
|
|
71
|
+
if (typeof jobKey !== 'string' || jobKey.trim().length === 0) {
|
|
72
|
+
throw new TypeError('trigger(jobKey): jobKey must be a non-empty string');
|
|
73
|
+
}
|
|
74
|
+
// Only assign supplied optionals: JSON.stringify drops `undefined`, so an
|
|
75
|
+
// unset field never reaches the wire.
|
|
76
|
+
const requestBody = { job_key: jobKey };
|
|
77
|
+
if (params.metadata !== undefined)
|
|
78
|
+
requestBody.metadata = params.metadata;
|
|
79
|
+
if (params.require !== undefined)
|
|
80
|
+
requestBody.require = params.require;
|
|
81
|
+
if (params.prefer !== undefined)
|
|
82
|
+
requestBody.prefer = params.prefer;
|
|
83
|
+
if (params.timeout !== undefined)
|
|
84
|
+
requestBody.timeout = params.timeout;
|
|
85
|
+
if (params.idempotencyKey !== undefined)
|
|
86
|
+
requestBody.idempotency_key = params.idempotencyKey;
|
|
87
|
+
const headers = {
|
|
88
|
+
'content-type': 'application/json',
|
|
89
|
+
accept: 'application/json',
|
|
90
|
+
};
|
|
91
|
+
if (this.#apiKey) {
|
|
92
|
+
headers.authorization = `ApiKey ${this.#apiKey}`;
|
|
93
|
+
}
|
|
94
|
+
else if (this.#bearerToken) {
|
|
95
|
+
headers.authorization = `Bearer ${this.#bearerToken}`;
|
|
96
|
+
}
|
|
97
|
+
const { signal, dispose } = composeSignals(params.signal, this.#requestTimeoutMs);
|
|
98
|
+
let response;
|
|
99
|
+
try {
|
|
100
|
+
response = await this.#fetch(`${this.#baseUrl}${TRIGGER_PATH}`, {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers,
|
|
103
|
+
body: JSON.stringify(requestBody),
|
|
104
|
+
signal,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (isAbortLikeError(err)) {
|
|
109
|
+
throw new AbortError(`request to ${TRIGGER_PATH} aborted`);
|
|
110
|
+
}
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
dispose();
|
|
115
|
+
}
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
const text = await response.text().catch(() => '');
|
|
118
|
+
if (response.status === 429) {
|
|
119
|
+
throw new QueueOverflowError(TRIGGER_PATH, text, parseRetryAfterMs(response.headers.get('retry-after')));
|
|
120
|
+
}
|
|
121
|
+
throw new HttpError(response.status, response.statusText, TRIGGER_PATH, text);
|
|
122
|
+
}
|
|
123
|
+
const text = await response.text();
|
|
124
|
+
if (text.length === 0) {
|
|
125
|
+
throw new HttpError(response.status, response.statusText, TRIGGER_PATH, 'empty response body');
|
|
126
|
+
}
|
|
127
|
+
let parsed;
|
|
128
|
+
try {
|
|
129
|
+
parsed = JSON.parse(text);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
throw new HttpError(response.status, response.statusText, TRIGGER_PATH, `non-JSON response body: ${text}`);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
executionId: parsed.execution_id,
|
|
136
|
+
queued: parsed.queued,
|
|
137
|
+
deduplicated: parsed.deduplicated ?? false,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Convenience factory mirroring `createRunner`. */
|
|
142
|
+
export function createTriggerClient(opts) {
|
|
143
|
+
return new CroniqTriggerClient(opts);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parse a `Retry-After` header value into milliseconds. Supports both the
|
|
147
|
+
* delta-seconds form (`"30"`) and the HTTP-date form. Returns `undefined` when
|
|
148
|
+
* the header is absent or unparseable.
|
|
149
|
+
*/
|
|
150
|
+
function parseRetryAfterMs(headerValue) {
|
|
151
|
+
if (!headerValue)
|
|
152
|
+
return undefined;
|
|
153
|
+
const trimmed = headerValue.trim();
|
|
154
|
+
if (trimmed.length === 0)
|
|
155
|
+
return undefined;
|
|
156
|
+
const seconds = Number(trimmed);
|
|
157
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
158
|
+
return Math.round(seconds * 1000);
|
|
159
|
+
}
|
|
160
|
+
const dateMs = Date.parse(trimmed);
|
|
161
|
+
if (!Number.isNaN(dateMs)) {
|
|
162
|
+
return Math.max(0, dateMs - Date.now());
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=trigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger.js","sourceRoot":"","sources":["../src/trigger.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuetzliches/croniq-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Croniq runner SDK for Node.js. Polls a Croniq server for work, dispatches handlers, streams logs back.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"LICENSE-APACHE"
|
|
20
20
|
],
|
|
21
21
|
"engines": {
|
|
22
|
-
"node": ">=
|
|
22
|
+
"node": ">=20.0.0"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsc -p tsconfig.build.json",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"@types/node": "^20.11.30",
|
|
38
38
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
39
39
|
"@typescript-eslint/parser": "^7.18.0",
|
|
40
|
-
"@vitest/coverage-v8": "^
|
|
40
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
41
41
|
"eslint": "^8.57.1",
|
|
42
42
|
"typescript": "^5.5.4",
|
|
43
|
-
"vitest": "^
|
|
43
|
+
"vitest": "^4.1.7"
|
|
44
44
|
},
|
|
45
45
|
"keywords": [
|
|
46
46
|
"croniq",
|