@valentinkolb/sync 2.0.4 → 2.0.5
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/index.d.ts +5 -0
- package/package.json +1 -1
- package/src/internal/job-utils.d.ts +11 -0
- package/src/internal/topic-utils.d.ts +7 -0
- package/src/job.d.ts +105 -0
- package/src/mutex.d.ts +26 -0
- package/src/queue.d.ts +67 -0
- package/src/ratelimit.d.ts +22 -0
- package/src/topic.d.ts +63 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ratelimit, RateLimitError, type RateLimiter, type RateLimitResult, type RateLimitConfig, } from "./src/ratelimit";
|
|
2
|
+
export { mutex, LockError, type Mutex, type Lock, type MutexConfig } from "./src/mutex";
|
|
3
|
+
export { queue, type Queue, type QueueConfig, type QueueReader, type QueueRecvConfig, type QueueSendConfig, type QueueReceived, } from "./src/queue";
|
|
4
|
+
export { topic, type Topic, type TopicConfig, type TopicReader, type TopicRecvConfig, type TopicPubConfig, type TopicDelivery, type TopicLiveConfig, type TopicLiveEvent, } from "./src/topic";
|
|
5
|
+
export { job, type JobId, type JobStatus, type JobTerminal, type SubmitOptions, type JoinOptions, type CancelOptions, type JobEvent, type JobEvents, type JobContext, type JobHandle, type JobDefinition, } from "./src/job";
|
package/package.json
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type JobTerminalStatus = "completed" | "failed" | "cancelled" | "timed_out";
|
|
2
|
+
export type RetryBackoff = {
|
|
3
|
+
kind: "fixed" | "exp";
|
|
4
|
+
baseMs: number;
|
|
5
|
+
maxMs?: number;
|
|
6
|
+
} | undefined;
|
|
7
|
+
export declare const isTerminalStatus: (status: string) => status is JobTerminalStatus;
|
|
8
|
+
export declare const parseJsonOrNull: <T>(raw: string | null) => T | null;
|
|
9
|
+
export declare const createTimeoutError: () => Error;
|
|
10
|
+
export declare const withTimeout: <T>(promise: Promise<T>, timeoutMs: number) => Promise<T>;
|
|
11
|
+
export declare const computeRetryDelay: (backoff: RetryBackoff, attempt: number) => number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type RawFields = Record<string, string>;
|
|
2
|
+
export type ParsedEntry = {
|
|
3
|
+
id: string;
|
|
4
|
+
fields: RawFields;
|
|
5
|
+
};
|
|
6
|
+
export declare const fieldArrayToObject: (value: unknown) => RawFields;
|
|
7
|
+
export declare const parseFirstStreamEntry: (raw: unknown) => ParsedEntry | null;
|
package/src/job.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { z, type ZodTypeAny } from "zod";
|
|
2
|
+
import { type Topic } from "./topic";
|
|
3
|
+
export type JobId = string;
|
|
4
|
+
export type JobStatus = "completed" | "failed" | "cancelled" | "timed_out";
|
|
5
|
+
export type JobTerminal<Result = unknown> = {
|
|
6
|
+
id: JobId;
|
|
7
|
+
status: JobStatus;
|
|
8
|
+
result?: Result;
|
|
9
|
+
error?: {
|
|
10
|
+
message: string;
|
|
11
|
+
code?: string;
|
|
12
|
+
};
|
|
13
|
+
finishedAt: number;
|
|
14
|
+
};
|
|
15
|
+
export type SubmitOptions = {
|
|
16
|
+
key?: string;
|
|
17
|
+
delayMs?: number;
|
|
18
|
+
at?: number;
|
|
19
|
+
maxAttempts?: number;
|
|
20
|
+
backoff?: {
|
|
21
|
+
kind: "fixed" | "exp";
|
|
22
|
+
baseMs: number;
|
|
23
|
+
maxMs?: number;
|
|
24
|
+
};
|
|
25
|
+
leaseMs?: number;
|
|
26
|
+
meta?: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
export type JoinOptions = {
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
};
|
|
31
|
+
export type CancelOptions = {
|
|
32
|
+
reason?: string;
|
|
33
|
+
};
|
|
34
|
+
export type JobEvent = {
|
|
35
|
+
type: "submitted";
|
|
36
|
+
id: JobId;
|
|
37
|
+
ts: number;
|
|
38
|
+
} | {
|
|
39
|
+
type: "started";
|
|
40
|
+
id: JobId;
|
|
41
|
+
runId: string;
|
|
42
|
+
attempt: number;
|
|
43
|
+
ts: number;
|
|
44
|
+
} | {
|
|
45
|
+
type: "heartbeat";
|
|
46
|
+
id: JobId;
|
|
47
|
+
runId: string;
|
|
48
|
+
ts: number;
|
|
49
|
+
} | {
|
|
50
|
+
type: "retry";
|
|
51
|
+
id: JobId;
|
|
52
|
+
runId: string;
|
|
53
|
+
nextAt: number;
|
|
54
|
+
reason?: string;
|
|
55
|
+
ts: number;
|
|
56
|
+
} | {
|
|
57
|
+
type: "completed";
|
|
58
|
+
id: JobId;
|
|
59
|
+
ts: number;
|
|
60
|
+
} | {
|
|
61
|
+
type: "failed";
|
|
62
|
+
id: JobId;
|
|
63
|
+
reason?: string;
|
|
64
|
+
ts: number;
|
|
65
|
+
} | {
|
|
66
|
+
type: "cancelled";
|
|
67
|
+
id: JobId;
|
|
68
|
+
reason?: string;
|
|
69
|
+
ts: number;
|
|
70
|
+
};
|
|
71
|
+
export type JobEvents = Pick<Topic<JobEvent>, "reader" | "live">;
|
|
72
|
+
export type JobContext = {
|
|
73
|
+
step<T>(cfg: {
|
|
74
|
+
id: string;
|
|
75
|
+
run: () => Promise<T> | T;
|
|
76
|
+
}): Promise<T>;
|
|
77
|
+
heartbeat(cfg?: {
|
|
78
|
+
leaseMs?: number;
|
|
79
|
+
}): Promise<void>;
|
|
80
|
+
signal: AbortSignal;
|
|
81
|
+
};
|
|
82
|
+
export type JobHandle<Input, Result = unknown> = {
|
|
83
|
+
id: string;
|
|
84
|
+
submit(cfg: {
|
|
85
|
+
input: Input;
|
|
86
|
+
} & SubmitOptions): Promise<JobId>;
|
|
87
|
+
join(cfg: {
|
|
88
|
+
id: JobId;
|
|
89
|
+
} & JoinOptions): Promise<JobTerminal<Result>>;
|
|
90
|
+
cancel(cfg: {
|
|
91
|
+
id: JobId;
|
|
92
|
+
} & CancelOptions): Promise<void>;
|
|
93
|
+
events(id: JobId): JobEvents;
|
|
94
|
+
stop(): void;
|
|
95
|
+
};
|
|
96
|
+
export type JobDefinition<TSchema extends ZodTypeAny, Result = unknown> = {
|
|
97
|
+
id: string;
|
|
98
|
+
schema: TSchema;
|
|
99
|
+
defaults?: Omit<SubmitOptions, "key" | "delayMs" | "at" | "meta">;
|
|
100
|
+
process: (cfg: {
|
|
101
|
+
ctx: JobContext;
|
|
102
|
+
input: z.infer<TSchema>;
|
|
103
|
+
}) => Promise<Result> | Result;
|
|
104
|
+
};
|
|
105
|
+
export declare const job: <TSchema extends ZodTypeAny, Result = unknown>(definition: JobDefinition<TSchema, Result>) => JobHandle<z.infer<TSchema>, Result>;
|
package/src/mutex.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type Lock = {
|
|
2
|
+
resource: string;
|
|
3
|
+
value: string;
|
|
4
|
+
ttl: number;
|
|
5
|
+
expiration: number;
|
|
6
|
+
};
|
|
7
|
+
export type MutexConfig = {
|
|
8
|
+
id: string;
|
|
9
|
+
prefix?: string;
|
|
10
|
+
retryCount?: number;
|
|
11
|
+
retryDelay?: number;
|
|
12
|
+
defaultTtl?: number;
|
|
13
|
+
};
|
|
14
|
+
export type Mutex = {
|
|
15
|
+
id: string;
|
|
16
|
+
acquire(resource: string, ttl?: number): Promise<Lock | null>;
|
|
17
|
+
release(lock: Lock): Promise<void>;
|
|
18
|
+
withLock<T>(resource: string, fn: (lock: Lock) => Promise<T> | T, ttl?: number): Promise<T | null>;
|
|
19
|
+
withLockOrThrow<T>(resource: string, fn: (lock: Lock) => Promise<T> | T, ttl?: number): Promise<T>;
|
|
20
|
+
extend(lock: Lock, ttl?: number): Promise<boolean>;
|
|
21
|
+
};
|
|
22
|
+
export declare class LockError extends Error {
|
|
23
|
+
readonly resource: string;
|
|
24
|
+
constructor(resource: string);
|
|
25
|
+
}
|
|
26
|
+
export declare const mutex: (config: MutexConfig) => Mutex;
|
package/src/queue.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
export type QueueConfig<TSchema extends z.ZodTypeAny> = {
|
|
3
|
+
id: string;
|
|
4
|
+
schema: TSchema;
|
|
5
|
+
tenantId?: string;
|
|
6
|
+
prefix?: string;
|
|
7
|
+
ordering?: {
|
|
8
|
+
mode?: "best_effort" | "ordering_key_partitioned";
|
|
9
|
+
partitions?: number;
|
|
10
|
+
};
|
|
11
|
+
limits?: {
|
|
12
|
+
payloadBytes?: number;
|
|
13
|
+
maxMessageAgeMs?: number;
|
|
14
|
+
maxNackDelayMs?: number;
|
|
15
|
+
dlqRetentionMs?: number;
|
|
16
|
+
};
|
|
17
|
+
delivery?: {
|
|
18
|
+
defaultLeaseMs?: number;
|
|
19
|
+
maxDeliveries?: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export type QueueSendConfig<T> = {
|
|
23
|
+
tenantId?: string;
|
|
24
|
+
data: T;
|
|
25
|
+
delayMs?: number;
|
|
26
|
+
orderingKey?: string;
|
|
27
|
+
idempotencyKey?: string;
|
|
28
|
+
idempotencyTtlMs?: number;
|
|
29
|
+
meta?: Record<string, unknown>;
|
|
30
|
+
};
|
|
31
|
+
export type QueueRecvConfig = {
|
|
32
|
+
tenantId?: string;
|
|
33
|
+
wait?: boolean;
|
|
34
|
+
timeoutMs?: number;
|
|
35
|
+
leaseMs?: number;
|
|
36
|
+
consumerId?: string;
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
};
|
|
39
|
+
export type QueueReceived<T> = {
|
|
40
|
+
data: T;
|
|
41
|
+
messageId: string;
|
|
42
|
+
deliveryId: string;
|
|
43
|
+
attempt: number;
|
|
44
|
+
leaseUntil: number;
|
|
45
|
+
orderingKey?: string;
|
|
46
|
+
meta?: Record<string, unknown>;
|
|
47
|
+
ack(): Promise<boolean>;
|
|
48
|
+
nack(cfg?: {
|
|
49
|
+
delayMs?: number;
|
|
50
|
+
reason?: string;
|
|
51
|
+
error?: string;
|
|
52
|
+
}): Promise<boolean>;
|
|
53
|
+
touch(cfg?: {
|
|
54
|
+
leaseMs?: number;
|
|
55
|
+
}): Promise<boolean>;
|
|
56
|
+
};
|
|
57
|
+
export type QueueReader<T> = {
|
|
58
|
+
recv(cfg?: QueueRecvConfig): Promise<QueueReceived<T> | null>;
|
|
59
|
+
stream(cfg?: QueueRecvConfig): AsyncIterable<QueueReceived<T>>;
|
|
60
|
+
};
|
|
61
|
+
export type Queue<T> = QueueReader<T> & {
|
|
62
|
+
send(cfg: QueueSendConfig<T>): Promise<{
|
|
63
|
+
messageId: string;
|
|
64
|
+
}>;
|
|
65
|
+
reader(): QueueReader<T>;
|
|
66
|
+
};
|
|
67
|
+
export declare const queue: <TSchema extends z.ZodTypeAny>(config: QueueConfig<TSchema>) => Queue<z.infer<TSchema>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type RateLimitResult = {
|
|
2
|
+
limited: boolean;
|
|
3
|
+
remaining: number;
|
|
4
|
+
resetIn: number;
|
|
5
|
+
};
|
|
6
|
+
export type RateLimitConfig = {
|
|
7
|
+
id: string;
|
|
8
|
+
limit: number;
|
|
9
|
+
windowSecs?: number;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
};
|
|
12
|
+
export type RateLimiter = {
|
|
13
|
+
id: string;
|
|
14
|
+
check(identifier: string): Promise<RateLimitResult>;
|
|
15
|
+
checkOrThrow(identifier: string): Promise<RateLimitResult>;
|
|
16
|
+
};
|
|
17
|
+
export declare class RateLimitError extends Error {
|
|
18
|
+
readonly remaining: number;
|
|
19
|
+
readonly resetIn: number;
|
|
20
|
+
constructor(result: RateLimitResult);
|
|
21
|
+
}
|
|
22
|
+
export declare const ratelimit: (config: RateLimitConfig) => RateLimiter;
|
package/src/topic.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
export type TopicConfig<TSchema extends z.ZodTypeAny> = {
|
|
3
|
+
id: string;
|
|
4
|
+
schema: TSchema;
|
|
5
|
+
tenantId?: string;
|
|
6
|
+
prefix?: string;
|
|
7
|
+
limits?: {
|
|
8
|
+
payloadBytes?: number;
|
|
9
|
+
};
|
|
10
|
+
retentionMs?: number;
|
|
11
|
+
};
|
|
12
|
+
export type TopicPubConfig<T> = {
|
|
13
|
+
tenantId?: string;
|
|
14
|
+
data: T;
|
|
15
|
+
orderingKey?: string;
|
|
16
|
+
idempotencyKey?: string;
|
|
17
|
+
idempotencyTtlMs?: number;
|
|
18
|
+
meta?: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
export type TopicRecvConfig = {
|
|
21
|
+
tenantId?: string;
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
wait?: boolean;
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
};
|
|
26
|
+
export type TopicDelivery<T> = {
|
|
27
|
+
data: T;
|
|
28
|
+
eventId: string;
|
|
29
|
+
deliveryId: string;
|
|
30
|
+
cursor: string;
|
|
31
|
+
orderingKey?: string;
|
|
32
|
+
publishedAt: number;
|
|
33
|
+
meta?: Record<string, unknown>;
|
|
34
|
+
commit(): Promise<boolean>;
|
|
35
|
+
};
|
|
36
|
+
export type TopicLiveConfig = {
|
|
37
|
+
tenantId?: string;
|
|
38
|
+
after?: string;
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
};
|
|
42
|
+
export type TopicLiveEvent<T> = {
|
|
43
|
+
data: T;
|
|
44
|
+
eventId: string;
|
|
45
|
+
cursor: string;
|
|
46
|
+
orderingKey?: string;
|
|
47
|
+
publishedAt: number;
|
|
48
|
+
meta?: Record<string, unknown>;
|
|
49
|
+
};
|
|
50
|
+
export type TopicReader<T> = {
|
|
51
|
+
group: string;
|
|
52
|
+
recv(cfg?: TopicRecvConfig): Promise<TopicDelivery<T> | null>;
|
|
53
|
+
stream(cfg?: TopicRecvConfig): AsyncIterable<TopicDelivery<T>>;
|
|
54
|
+
};
|
|
55
|
+
export type Topic<T> = {
|
|
56
|
+
pub(cfg: TopicPubConfig<T>): Promise<{
|
|
57
|
+
eventId: string;
|
|
58
|
+
cursor: string;
|
|
59
|
+
}>;
|
|
60
|
+
reader(group?: string): TopicReader<T>;
|
|
61
|
+
live(cfg?: TopicLiveConfig): AsyncIterable<TopicLiveEvent<T>>;
|
|
62
|
+
};
|
|
63
|
+
export declare const topic: <TSchema extends z.ZodTypeAny>(config: TopicConfig<TSchema>) => Topic<z.infer<TSchema>>;
|