@arbitro/client 0.4.1 → 0.5.2
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 +77 -0
- package/dist/{chunk-6BCX2E2R.mjs → chunk-3EHQPPLU.mjs} +2 -1
- package/dist/chunk-3EHQPPLU.mjs.map +1 -0
- package/dist/{chunk-SKCXQO7R.mjs → chunk-BSPQZJHF.mjs} +2 -2
- package/dist/{constants-KF57DJ2L.mjs → constants-LWTWKOBZ.mjs} +2 -2
- package/dist/index.d.mts +73 -1
- package/dist/index.d.ts +73 -1
- package/dist/index.js +281 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +281 -5
- package/dist/index.mjs.map +1 -1
- package/dist/{publish-UA3YZGMK.mjs → publish-NKAK5BOA.mjs} +3 -3
- package/package.json +1 -1
- package/dist/chunk-6BCX2E2R.mjs.map +0 -1
- /package/dist/{chunk-SKCXQO7R.mjs.map → chunk-BSPQZJHF.mjs.map} +0 -0
- /package/dist/{constants-KF57DJ2L.mjs.map → constants-LWTWKOBZ.mjs.map} +0 -0
- /package/dist/{publish-UA3YZGMK.mjs.map → publish-NKAK5BOA.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -111,6 +111,11 @@ await client.upsertConsumer('orders', { name: 'workers', filter: 'orders.>' })
|
|
|
111
111
|
await client.deleteConsumer('workers')
|
|
112
112
|
await client.deleteStream('orders') // default: delete metadata + data
|
|
113
113
|
await client.deleteStream('orders', { deleteData: false }) // preserve journal bytes
|
|
114
|
+
|
|
115
|
+
// Per-message deletion (tombstones a single message by sequence number)
|
|
116
|
+
await client.deleteMessage('orders', 42n) // true if deleted, false if not found/already deleted
|
|
117
|
+
await stream.deleteMessage(42n) // convenience — delegates to client.deleteMessage
|
|
118
|
+
await consumer.deleteMessage(42n) // convenience — delegates to client.deleteMessage
|
|
114
119
|
```
|
|
115
120
|
|
|
116
121
|
## Stream / consumer sugar
|
|
@@ -248,6 +253,74 @@ await client.publishDelayed("ORDERS", "orders.reminder", payload, 5000); // 5s d
|
|
|
248
253
|
|
|
249
254
|
Messages are persisted immediately — survives broker restart.
|
|
250
255
|
|
|
256
|
+
## Workflow Orchestration
|
|
257
|
+
|
|
258
|
+
Client-side linear pipelines over Arbitro streams. The broker has no workflow-specific code -- everything uses streams, consumer groups, and idempotent publish.
|
|
259
|
+
|
|
260
|
+
### WorkflowBuilder API
|
|
261
|
+
|
|
262
|
+
| Method | Signature | Description |
|
|
263
|
+
|--------|-----------|-------------|
|
|
264
|
+
| `trigger` | `(subject: string) => this` | Subject pattern that triggers new instances. Required. |
|
|
265
|
+
| `triggerStream` | *(not yet implemented)* | Planned: auto-subscribe to an external stream for trigger. |
|
|
266
|
+
| `step` | `(name: string, handler: StepHandler) => this` | Append a processing step. |
|
|
267
|
+
| `compensate` | *(not yet implemented)* | Planned: rollback handler per step (saga pattern). |
|
|
268
|
+
| `maxRetries` | *(not yet implemented)* | Planned: attempts before DLQ. |
|
|
269
|
+
| `maxContextSize` | *(not yet implemented)* | Planned: max context payload in bytes. |
|
|
270
|
+
| `ackWait` | `(ms: number) => this` | Ack timeout for failover (default: 30000). |
|
|
271
|
+
| `inflight` | `(n: number) => this` | Concurrent tasks per worker (default: 10). |
|
|
272
|
+
| `start` | `() => Promise<WorkflowHandle>` | Register streams, consumer, and start processing. |
|
|
273
|
+
|
|
274
|
+
### WorkflowHandle API
|
|
275
|
+
|
|
276
|
+
| Method | Signature | Description |
|
|
277
|
+
|--------|-----------|-------------|
|
|
278
|
+
| `trigger` | `(client: ArbitroClient, context: Buffer) => Promise<number>` | Trigger a new workflow instance. Returns the instance ID. |
|
|
279
|
+
| `name` | `string` (getter) | Workflow name. |
|
|
280
|
+
|
|
281
|
+
### Complete Example
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import { ArbitroClient, WorkflowBuilder } from '@arbitro/client'
|
|
285
|
+
import type { StepContext, StepResult } from '@arbitro/client'
|
|
286
|
+
|
|
287
|
+
const client = new ArbitroClient({ servers: ['127.0.0.1:9898'] })
|
|
288
|
+
await client.connect()
|
|
289
|
+
|
|
290
|
+
const wf = await new WorkflowBuilder(client, 'order-process')
|
|
291
|
+
.trigger('orders.created')
|
|
292
|
+
// Step 1: validate
|
|
293
|
+
.step('validate', async (ctx: StepContext): Promise<StepResult> => {
|
|
294
|
+
const validated = await validateOrder(ctx.context)
|
|
295
|
+
return { context: validated }
|
|
296
|
+
})
|
|
297
|
+
// Step 2: charge
|
|
298
|
+
.step('charge', async (ctx: StepContext): Promise<StepResult> => {
|
|
299
|
+
const receipt = await chargePayment(ctx.context)
|
|
300
|
+
return { context: receipt }
|
|
301
|
+
})
|
|
302
|
+
// Step 3: ship
|
|
303
|
+
.step('ship', async (ctx: StepContext): Promise<StepResult> => {
|
|
304
|
+
const tracking = await createShipment(ctx.context)
|
|
305
|
+
return { context: tracking }
|
|
306
|
+
})
|
|
307
|
+
.ackWait(30_000)
|
|
308
|
+
.inflight(10)
|
|
309
|
+
.start()
|
|
310
|
+
|
|
311
|
+
// Manual trigger
|
|
312
|
+
const instanceId = await wf.trigger(client, Buffer.from('order-123-payload'))
|
|
313
|
+
console.log(`started instance ${instanceId}`)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Internals
|
|
317
|
+
|
|
318
|
+
- Tasks flow through `_wf.{name}.tasks` stream with a consumer `_wf.{name}.workers`.
|
|
319
|
+
- Each step transition publishes with `msgId` format `wf:{instance}:{step}:{attempt}` for deduplication.
|
|
320
|
+
- `ackWait` enables failover: if a worker dies, the broker redelivers to another subscriber.
|
|
321
|
+
|
|
322
|
+
> **Note:** The TypeScript workflow module currently implements the core step pipeline. Compensation (saga), DLQ, `triggerStream`, `maxRetries`, and `maxContextSize` are available in the Rust client and planned for the TS client.
|
|
323
|
+
|
|
251
324
|
## Reconnect behavior
|
|
252
325
|
|
|
253
326
|
The TS client reconnects transport automatically and reattaches active subscriptions and cron jobs after reconnect. That behavior lives in the client, not in the benchmarks. This matters for:
|
|
@@ -271,6 +344,10 @@ npm run test:integration # requires Docker
|
|
|
271
344
|
- `.agent/rules/*.md` — internal coding rules (hot-path discipline, wire protocol, etc.).
|
|
272
345
|
- `CLAUDE.md` — index pointing at the rule files.
|
|
273
346
|
|
|
347
|
+
## Replication
|
|
348
|
+
|
|
349
|
+
Replication is transparent to the client -- `replicas` is set at `create_stream` time. The client publishes normally; the broker handles replication internally.
|
|
350
|
+
|
|
274
351
|
## License
|
|
275
352
|
|
|
276
353
|
MIT — see [LICENSE](./LICENSE).
|
|
@@ -62,6 +62,7 @@ var Action = /* @__PURE__ */ ((Action2) => {
|
|
|
62
62
|
Action2[Action2["ListStreams"] = 1028] = "ListStreams";
|
|
63
63
|
Action2[Action2["PurgeStream"] = 1029] = "PurgeStream";
|
|
64
64
|
Action2[Action2["DrainSubject"] = 1030] = "DrainSubject";
|
|
65
|
+
Action2[Action2["DeleteMessage"] = 1031] = "DeleteMessage";
|
|
65
66
|
Action2[Action2["CreateConsumer"] = 1281] = "CreateConsumer";
|
|
66
67
|
Action2[Action2["DeleteConsumer"] = 1282] = "DeleteConsumer";
|
|
67
68
|
Action2[Action2["GetConsumer"] = 1283] = "GetConsumer";
|
|
@@ -99,4 +100,4 @@ export {
|
|
|
99
100
|
EntryFlag,
|
|
100
101
|
Action
|
|
101
102
|
};
|
|
102
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-3EHQPPLU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/proto/constants.ts"],"sourcesContent":["// V2 wire protocol constants — must match arbitro-proto/src/action.rs exactly.\n\n// ── Hello handshake (only frame without a Header) ───────────────────────\nexport const MAGIC_V2 = 0x32425241 // \"ARB2\" as u32 LE\nexport const HELLO_SIZE = 8\nexport const CURRENT_VERSION = 2\n\nexport const enum Role {\n Client = 0,\n Server = 1,\n}\n\nexport const enum Cap {\n Headers = 1 << 0,\n Reply = 1 << 1,\n BatchHeaders = 1 << 2,\n CompressedPayload = 1 << 3,\n}\n\n// ── Header (16 bytes, every frame after Hello) ──────────────────────────\nexport const HEADER_SIZE = 16\n\n// Byte offsets within the 16-byte header\nexport const OFF_ACTION = 0 // u16 LE\nexport const OFF_FLAGS = 2 // u8\nexport const OFF_ENTRY_FLAGS = 3 // u8\nexport const OFF_MSG_LEN = 4 // u32 LE\nexport const OFF_SEQ = 8 // u64 LE\n\n// ── Transport flags (header.flags, offset 2) ────────────────────────────\nexport const enum Flag {\n None = 0x00,\n AckReq = 0x01,\n Dup = 0x02,\n PriorityHigh = 0x04,\n}\n\n// ── Per-message flags (header.entry_flags, offset 3) ────────────────────\nexport const enum EntryFlag {\n None = 0x00,\n Retain = 0x01,\n Compressed = 0x02,\n NoBackpressure = 0x04,\n}\n\n// ── Action codes (0xFFGG: FF=family, GG=variant) ────────────────────────\nexport const enum Action {\n // 0x00xx — Handshake / control\n Hello = 0x0001,\n Auth = 0x0002,\n\n // 0x01xx — Publish family\n Publish = 0x0101,\n PublishAccumulate = 0x0102,\n PublishBatch = 0x0103,\n PublishWithReply = 0x0104,\n PublishWithHeaders = 0x0105,\n PublishBatchWithHeaders = 0x0106,\n\n // 0x02xx — Delivery / Ack\n Deliver = 0x0200,\n Ack = 0x0201,\n Nack = 0x0202,\n RepOk = 0x0203,\n RepError = 0x0204,\n RepBatch = 0x0205,\n BatchAck = 0x0206,\n FanoutBatch = 0x0207,\n AckSync = 0x0208,\n BatchAckSync = 0x0209,\n BatchNack = 0x020A,\n\n // 0x03xx — Subscription\n Subscribe = 0x0301,\n Unsubscribe = 0x0302,\n\n // 0x04xx — Stream management\n CreateStream = 0x0401,\n DeleteStream = 0x0402,\n GetStream = 0x0403,\n ListStreams = 0x0404,\n PurgeStream = 0x0405,\n DrainSubject = 0x0406,\n DeleteMessage = 0x0407,\n\n // 0x05xx — Consumer management\n CreateConsumer = 0x0501,\n DeleteConsumer = 0x0502,\n GetConsumer = 0x0503,\n ListConsumers = 0x0504,\n ConsumerStats = 0x0505,\n PauseConsumer = 0x0506,\n ResumeConsumer = 0x0507,\n\n // 0x08xx — Delayed publish\n PublishDelayed = 0x0801,\n\n // 0x06xx — System\n Ping = 0x0601,\n Pong = 0x0602,\n Connect = 0x0603,\n Connected = 0x0604,\n Disconnect = 0x0605,\n\n // 0x07xx — Cron scheduling\n CreateCron = 0x0701,\n DeleteCron = 0x0702,\n ListCrons = 0x0703,\n CronFire = 0x0704,\n CronAck = 0x0705,\n\n // 0x09xx reserved (workflow removed — now a client-side library).\n}\n"],"mappings":"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","names":["Role","Cap","Flag","EntryFlag","Action"]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
OFF_FLAGS,
|
|
9
9
|
OFF_MSG_LEN,
|
|
10
10
|
OFF_SEQ
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-3EHQPPLU.mjs";
|
|
12
12
|
|
|
13
13
|
// src/proto/frame.ts
|
|
14
14
|
function frame(action, seq, bodyLen, flags = 0, entryFlags = 0) {
|
|
@@ -121,4 +121,4 @@ export {
|
|
|
121
121
|
packPublishDelayed,
|
|
122
122
|
packPublishBatch
|
|
123
123
|
};
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-BSPQZJHF.mjs.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
OFF_MSG_LEN,
|
|
14
14
|
OFF_SEQ,
|
|
15
15
|
Role
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-3EHQPPLU.mjs";
|
|
17
17
|
export {
|
|
18
18
|
Action,
|
|
19
19
|
CURRENT_VERSION,
|
|
@@ -30,4 +30,4 @@ export {
|
|
|
30
30
|
OFF_SEQ,
|
|
31
31
|
Role
|
|
32
32
|
};
|
|
33
|
-
//# sourceMappingURL=constants-
|
|
33
|
+
//# sourceMappingURL=constants-LWTWKOBZ.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -86,6 +86,8 @@ interface SubjectInflightLimit {
|
|
|
86
86
|
}
|
|
87
87
|
interface ConsumerConfig {
|
|
88
88
|
name?: string;
|
|
89
|
+
/** Shared consumer group name for round-robin delivery. Defaults to `name`. */
|
|
90
|
+
group?: string;
|
|
89
91
|
filter?: string;
|
|
90
92
|
fanout?: boolean;
|
|
91
93
|
/** Consumer-side ACK policy. None = fire-and-forget delivery, Explicit = consumer must ACK. */
|
|
@@ -461,6 +463,8 @@ declare class Consumer {
|
|
|
461
463
|
* from `streamName + name`. Equivalent of NATS `num_ack_pending`.
|
|
462
464
|
*/
|
|
463
465
|
getPendings(): Promise<number>;
|
|
466
|
+
/** Tombstone a single message by seq. Returns true if found. */
|
|
467
|
+
deleteMessage(seq: bigint): Promise<boolean>;
|
|
464
468
|
subscribe(cb?: RawCallback, opts?: SubscribeOptions): Promise<Subscription>;
|
|
465
469
|
subscribe<T extends Record<string, unknown>>(codec: Encoding<T>, cb: (msg: LazyMessage<T>) => void, opts?: SubscribeOptions): Promise<Subscription>;
|
|
466
470
|
}
|
|
@@ -572,6 +576,14 @@ declare class ArbitroClient {
|
|
|
572
576
|
streamExists(name: string): Promise<boolean>;
|
|
573
577
|
purgeStream(name: string): Promise<number>;
|
|
574
578
|
drainSubject(streamName: string, subject: string): Promise<number>;
|
|
579
|
+
/**
|
|
580
|
+
* Tombstone a single message by sequence number.
|
|
581
|
+
*
|
|
582
|
+
* The broker marks the entry as deleted — it will never be delivered
|
|
583
|
+
* to any consumer. Returns `true` if the message was found and
|
|
584
|
+
* tombstoned, `false` if not found or already tombstoned.
|
|
585
|
+
*/
|
|
586
|
+
deleteMessage(streamName: string, seq: bigint): Promise<boolean>;
|
|
575
587
|
createConsumer(streamName: string, config: ConsumerConfig): Promise<Consumer>;
|
|
576
588
|
private createConsumerRaw;
|
|
577
589
|
upsertConsumer(streamName: string, config: ConsumerConfig): Promise<Consumer>;
|
|
@@ -636,6 +648,8 @@ declare class Stream {
|
|
|
636
648
|
* with the broker; the caller decides whether to wait via `await`. */
|
|
637
649
|
publishBatch(messages: BatchPublishEntry[]): Promise<bigint>;
|
|
638
650
|
request(subject: string, data: Buffer, timeoutMs?: number): Promise<Buffer>;
|
|
651
|
+
/** Tombstone a single message by seq. Returns true if found. */
|
|
652
|
+
deleteMessage(seq: bigint): Promise<boolean>;
|
|
639
653
|
consumer(overrides?: Partial<ConsumerConfig>): Consumer;
|
|
640
654
|
topic<T extends Record<string, unknown>>(subject: string, codec: Encoding<T>): Topic<T>;
|
|
641
655
|
}
|
|
@@ -654,6 +668,64 @@ declare class Topic<T extends Record<string, unknown>> {
|
|
|
654
668
|
|
|
655
669
|
declare function streamId(name: Buffer | string): number;
|
|
656
670
|
|
|
671
|
+
declare class WorkflowHandle {
|
|
672
|
+
private readonly workflowName;
|
|
673
|
+
private readonly taskStreamName;
|
|
674
|
+
private readonly dlqStreamName;
|
|
675
|
+
private readonly sub;
|
|
676
|
+
private readonly triggerSub;
|
|
677
|
+
constructor(workflowName: string, taskStreamName: string, dlqStreamName: string, sub: unknown, triggerSub: unknown | undefined);
|
|
678
|
+
get name(): string;
|
|
679
|
+
get taskStream(): string;
|
|
680
|
+
get dlqStream(): string;
|
|
681
|
+
trigger(client: ArbitroClient, context: Buffer): Promise<number>;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
interface StepContext {
|
|
685
|
+
readonly name: string;
|
|
686
|
+
readonly instanceId: number;
|
|
687
|
+
readonly stepIndex: number;
|
|
688
|
+
readonly attempt: number;
|
|
689
|
+
readonly context: Buffer;
|
|
690
|
+
}
|
|
691
|
+
interface StepResult {
|
|
692
|
+
readonly context: Buffer;
|
|
693
|
+
}
|
|
694
|
+
type StepHandler = (ctx: StepContext) => Promise<StepResult>;
|
|
695
|
+
declare class WorkflowBuilder {
|
|
696
|
+
private readonly client;
|
|
697
|
+
private readonly workflowName;
|
|
698
|
+
private triggerSubject;
|
|
699
|
+
private triggerStreamName;
|
|
700
|
+
private readonly steps;
|
|
701
|
+
private ackWaitMs;
|
|
702
|
+
private maxInflightVal;
|
|
703
|
+
private maxRetriesVal;
|
|
704
|
+
private maxContextSizeVal;
|
|
705
|
+
constructor(client: ArbitroClient, workflowName: string);
|
|
706
|
+
trigger(subject: string): this;
|
|
707
|
+
triggerStream(streamName: string): this;
|
|
708
|
+
step(name: string, handler: StepHandler): this;
|
|
709
|
+
/** Compensation handler for the most recently added step. */
|
|
710
|
+
compensate(_stepName: string, handler: StepHandler): this;
|
|
711
|
+
ackWait(ms: number): this;
|
|
712
|
+
inflight(n: number): this;
|
|
713
|
+
maxRetries(n: number): this;
|
|
714
|
+
maxContextSize(bytes: number): this;
|
|
715
|
+
start(): Promise<WorkflowHandle>;
|
|
716
|
+
private subscribeWorker;
|
|
717
|
+
private subscribeTrigger;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/** Bit flag set on stepIndex to mark compensation tasks. */
|
|
721
|
+
declare const COMPENSATION_BIT = 32768;
|
|
722
|
+
interface DecodedTask {
|
|
723
|
+
readonly instanceId: number;
|
|
724
|
+
readonly stepIndex: number;
|
|
725
|
+
readonly attempt: number;
|
|
726
|
+
readonly context: Buffer;
|
|
727
|
+
}
|
|
728
|
+
|
|
657
729
|
/** Wraps a ZodObject schema as an Encoding<T>.
|
|
658
730
|
*
|
|
659
731
|
* - encode: msgpack (no Zod overhead — bytes out)
|
|
@@ -667,4 +739,4 @@ declare function zodCodec<S extends ZodRawShape>(zodSchema: ZodObject<S>): Encod
|
|
|
667
739
|
readonly fields: string[];
|
|
668
740
|
};
|
|
669
741
|
|
|
670
|
-
export { AckPolicy, ArbitroClient, ArbitroError, type BatchPublishEntry, type ClientConfig, type ClientMetricsSnapshot, Codec, Consumer, type ConsumerConfig, type ConsumerInfo, CronBuilder, type CronContext, CronHandle, type CronHandler, type DeleteStreamOpts, DeliverPolicy, type Encoding, ErrorCode, type ErrorCodeValue, type FieldType, type FieldTypeMap, type FlushConfig, type InferSchema, type JournalConfig, JournalType, JsonCodec, type LazyMessage, type LogFn, type Logger, Message, type PublishOpts, type ReconnectConfig, type Schema, Stream, type StreamConfig, type StreamInfo, StringCodec, type SubjectInflightLimit, type SubscribeOptions, Subscription, type TlsConfig, Topic, decodeJson, decodeString, encodeJson, encodeString, makeLazyMessage, schema, streamId, zodCodec };
|
|
742
|
+
export { AckPolicy, ArbitroClient, ArbitroError, type BatchPublishEntry, COMPENSATION_BIT, type ClientConfig, type ClientMetricsSnapshot, Codec, Consumer, type ConsumerConfig, type ConsumerInfo, CronBuilder, type CronContext, CronHandle, type CronHandler, type DecodedTask, type DeleteStreamOpts, DeliverPolicy, type Encoding, ErrorCode, type ErrorCodeValue, type FieldType, type FieldTypeMap, type FlushConfig, type InferSchema, type JournalConfig, JournalType, JsonCodec, type LazyMessage, type LogFn, type Logger, Message, type PublishOpts, type ReconnectConfig, type Schema, type StepContext, type StepHandler, type StepResult, Stream, type StreamConfig, type StreamInfo, StringCodec, type SubjectInflightLimit, type SubscribeOptions, Subscription, type TlsConfig, Topic, WorkflowBuilder, WorkflowHandle, decodeJson, decodeString, encodeJson, encodeString, makeLazyMessage, schema, streamId, zodCodec };
|
package/dist/index.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ interface SubjectInflightLimit {
|
|
|
86
86
|
}
|
|
87
87
|
interface ConsumerConfig {
|
|
88
88
|
name?: string;
|
|
89
|
+
/** Shared consumer group name for round-robin delivery. Defaults to `name`. */
|
|
90
|
+
group?: string;
|
|
89
91
|
filter?: string;
|
|
90
92
|
fanout?: boolean;
|
|
91
93
|
/** Consumer-side ACK policy. None = fire-and-forget delivery, Explicit = consumer must ACK. */
|
|
@@ -461,6 +463,8 @@ declare class Consumer {
|
|
|
461
463
|
* from `streamName + name`. Equivalent of NATS `num_ack_pending`.
|
|
462
464
|
*/
|
|
463
465
|
getPendings(): Promise<number>;
|
|
466
|
+
/** Tombstone a single message by seq. Returns true if found. */
|
|
467
|
+
deleteMessage(seq: bigint): Promise<boolean>;
|
|
464
468
|
subscribe(cb?: RawCallback, opts?: SubscribeOptions): Promise<Subscription>;
|
|
465
469
|
subscribe<T extends Record<string, unknown>>(codec: Encoding<T>, cb: (msg: LazyMessage<T>) => void, opts?: SubscribeOptions): Promise<Subscription>;
|
|
466
470
|
}
|
|
@@ -572,6 +576,14 @@ declare class ArbitroClient {
|
|
|
572
576
|
streamExists(name: string): Promise<boolean>;
|
|
573
577
|
purgeStream(name: string): Promise<number>;
|
|
574
578
|
drainSubject(streamName: string, subject: string): Promise<number>;
|
|
579
|
+
/**
|
|
580
|
+
* Tombstone a single message by sequence number.
|
|
581
|
+
*
|
|
582
|
+
* The broker marks the entry as deleted — it will never be delivered
|
|
583
|
+
* to any consumer. Returns `true` if the message was found and
|
|
584
|
+
* tombstoned, `false` if not found or already tombstoned.
|
|
585
|
+
*/
|
|
586
|
+
deleteMessage(streamName: string, seq: bigint): Promise<boolean>;
|
|
575
587
|
createConsumer(streamName: string, config: ConsumerConfig): Promise<Consumer>;
|
|
576
588
|
private createConsumerRaw;
|
|
577
589
|
upsertConsumer(streamName: string, config: ConsumerConfig): Promise<Consumer>;
|
|
@@ -636,6 +648,8 @@ declare class Stream {
|
|
|
636
648
|
* with the broker; the caller decides whether to wait via `await`. */
|
|
637
649
|
publishBatch(messages: BatchPublishEntry[]): Promise<bigint>;
|
|
638
650
|
request(subject: string, data: Buffer, timeoutMs?: number): Promise<Buffer>;
|
|
651
|
+
/** Tombstone a single message by seq. Returns true if found. */
|
|
652
|
+
deleteMessage(seq: bigint): Promise<boolean>;
|
|
639
653
|
consumer(overrides?: Partial<ConsumerConfig>): Consumer;
|
|
640
654
|
topic<T extends Record<string, unknown>>(subject: string, codec: Encoding<T>): Topic<T>;
|
|
641
655
|
}
|
|
@@ -654,6 +668,64 @@ declare class Topic<T extends Record<string, unknown>> {
|
|
|
654
668
|
|
|
655
669
|
declare function streamId(name: Buffer | string): number;
|
|
656
670
|
|
|
671
|
+
declare class WorkflowHandle {
|
|
672
|
+
private readonly workflowName;
|
|
673
|
+
private readonly taskStreamName;
|
|
674
|
+
private readonly dlqStreamName;
|
|
675
|
+
private readonly sub;
|
|
676
|
+
private readonly triggerSub;
|
|
677
|
+
constructor(workflowName: string, taskStreamName: string, dlqStreamName: string, sub: unknown, triggerSub: unknown | undefined);
|
|
678
|
+
get name(): string;
|
|
679
|
+
get taskStream(): string;
|
|
680
|
+
get dlqStream(): string;
|
|
681
|
+
trigger(client: ArbitroClient, context: Buffer): Promise<number>;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
interface StepContext {
|
|
685
|
+
readonly name: string;
|
|
686
|
+
readonly instanceId: number;
|
|
687
|
+
readonly stepIndex: number;
|
|
688
|
+
readonly attempt: number;
|
|
689
|
+
readonly context: Buffer;
|
|
690
|
+
}
|
|
691
|
+
interface StepResult {
|
|
692
|
+
readonly context: Buffer;
|
|
693
|
+
}
|
|
694
|
+
type StepHandler = (ctx: StepContext) => Promise<StepResult>;
|
|
695
|
+
declare class WorkflowBuilder {
|
|
696
|
+
private readonly client;
|
|
697
|
+
private readonly workflowName;
|
|
698
|
+
private triggerSubject;
|
|
699
|
+
private triggerStreamName;
|
|
700
|
+
private readonly steps;
|
|
701
|
+
private ackWaitMs;
|
|
702
|
+
private maxInflightVal;
|
|
703
|
+
private maxRetriesVal;
|
|
704
|
+
private maxContextSizeVal;
|
|
705
|
+
constructor(client: ArbitroClient, workflowName: string);
|
|
706
|
+
trigger(subject: string): this;
|
|
707
|
+
triggerStream(streamName: string): this;
|
|
708
|
+
step(name: string, handler: StepHandler): this;
|
|
709
|
+
/** Compensation handler for the most recently added step. */
|
|
710
|
+
compensate(_stepName: string, handler: StepHandler): this;
|
|
711
|
+
ackWait(ms: number): this;
|
|
712
|
+
inflight(n: number): this;
|
|
713
|
+
maxRetries(n: number): this;
|
|
714
|
+
maxContextSize(bytes: number): this;
|
|
715
|
+
start(): Promise<WorkflowHandle>;
|
|
716
|
+
private subscribeWorker;
|
|
717
|
+
private subscribeTrigger;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/** Bit flag set on stepIndex to mark compensation tasks. */
|
|
721
|
+
declare const COMPENSATION_BIT = 32768;
|
|
722
|
+
interface DecodedTask {
|
|
723
|
+
readonly instanceId: number;
|
|
724
|
+
readonly stepIndex: number;
|
|
725
|
+
readonly attempt: number;
|
|
726
|
+
readonly context: Buffer;
|
|
727
|
+
}
|
|
728
|
+
|
|
657
729
|
/** Wraps a ZodObject schema as an Encoding<T>.
|
|
658
730
|
*
|
|
659
731
|
* - encode: msgpack (no Zod overhead — bytes out)
|
|
@@ -667,4 +739,4 @@ declare function zodCodec<S extends ZodRawShape>(zodSchema: ZodObject<S>): Encod
|
|
|
667
739
|
readonly fields: string[];
|
|
668
740
|
};
|
|
669
741
|
|
|
670
|
-
export { AckPolicy, ArbitroClient, ArbitroError, type BatchPublishEntry, type ClientConfig, type ClientMetricsSnapshot, Codec, Consumer, type ConsumerConfig, type ConsumerInfo, CronBuilder, type CronContext, CronHandle, type CronHandler, type DeleteStreamOpts, DeliverPolicy, type Encoding, ErrorCode, type ErrorCodeValue, type FieldType, type FieldTypeMap, type FlushConfig, type InferSchema, type JournalConfig, JournalType, JsonCodec, type LazyMessage, type LogFn, type Logger, Message, type PublishOpts, type ReconnectConfig, type Schema, Stream, type StreamConfig, type StreamInfo, StringCodec, type SubjectInflightLimit, type SubscribeOptions, Subscription, type TlsConfig, Topic, decodeJson, decodeString, encodeJson, encodeString, makeLazyMessage, schema, streamId, zodCodec };
|
|
742
|
+
export { AckPolicy, ArbitroClient, ArbitroError, type BatchPublishEntry, COMPENSATION_BIT, type ClientConfig, type ClientMetricsSnapshot, Codec, Consumer, type ConsumerConfig, type ConsumerInfo, CronBuilder, type CronContext, CronHandle, type CronHandler, type DecodedTask, type DeleteStreamOpts, DeliverPolicy, type Encoding, ErrorCode, type ErrorCodeValue, type FieldType, type FieldTypeMap, type FlushConfig, type InferSchema, type JournalConfig, JournalType, JsonCodec, type LazyMessage, type LogFn, type Logger, Message, type PublishOpts, type ReconnectConfig, type Schema, type StepContext, type StepHandler, type StepResult, Stream, type StreamConfig, type StreamInfo, StringCodec, type SubjectInflightLimit, type SubscribeOptions, Subscription, type TlsConfig, Topic, WorkflowBuilder, WorkflowHandle, decodeJson, decodeString, encodeJson, encodeString, makeLazyMessage, schema, streamId, zodCodec };
|