semola 0.5.2 → 0.5.4
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 +88 -13
- package/dist/index-BhGNDjPq.d.mts +13 -0
- package/dist/index-DxSbeGP-.d.cts +13 -0
- package/dist/lib/api/index.cjs +522 -4
- package/dist/lib/api/index.d.cts +270 -4
- package/dist/lib/api/index.d.mts +270 -4
- package/dist/lib/api/index.mjs +520 -2
- package/dist/lib/cache/index.d.cts +19 -7
- package/dist/lib/cache/index.d.mts +19 -7
- package/dist/lib/cache/index.mjs +0 -2
- package/dist/lib/cron/index.cjs +470 -11
- package/dist/lib/cron/index.d.cts +112 -5
- package/dist/lib/cron/index.d.mts +112 -5
- package/dist/lib/cron/index.mjs +461 -12
- package/dist/lib/errors/index.d.cts +2 -13
- package/dist/lib/errors/index.d.mts +2 -13
- package/dist/lib/errors/index.mjs +0 -2
- package/dist/lib/i18n/index.cjs +6 -1
- package/dist/lib/i18n/index.d.cts +12 -4
- package/dist/lib/i18n/index.d.mts +12 -4
- package/dist/lib/i18n/index.mjs +6 -3
- package/dist/lib/logging/index.cjs +387 -0
- package/dist/lib/logging/index.d.cts +108 -0
- package/dist/lib/logging/index.d.mts +108 -0
- package/dist/lib/logging/index.mjs +374 -0
- package/dist/lib/policy/index.cjs +206 -20
- package/dist/lib/policy/index.d.cts +61 -5
- package/dist/lib/policy/index.d.mts +61 -5
- package/dist/lib/policy/index.mjs +187 -3
- package/dist/lib/prompts/index.cjs +374 -14
- package/dist/lib/prompts/index.d.cts +77 -12
- package/dist/lib/prompts/index.d.mts +77 -12
- package/dist/lib/prompts/index.mjs +362 -4
- package/dist/lib/pubsub/index.cjs +82 -13
- package/dist/lib/pubsub/index.d.cts +23 -9
- package/dist/lib/pubsub/index.d.mts +23 -9
- package/dist/lib/pubsub/index.mjs +82 -15
- package/dist/lib/queue/index.d.cts +46 -4
- package/dist/lib/queue/index.d.mts +46 -4
- package/dist/lib/queue/index.mjs +0 -2
- package/dist/lib/workflow/index.cjs +534 -0
- package/dist/lib/workflow/index.d.cts +85 -0
- package/dist/lib/workflow/index.d.mts +85 -0
- package/dist/lib/workflow/index.mjs +533 -0
- package/package.json +29 -3
- package/dist/api/core/index.cjs +0 -206
- package/dist/api/core/index.d.cts +0 -21
- package/dist/api/core/index.d.cts.map +0 -1
- package/dist/api/core/index.d.mts +0 -21
- package/dist/api/core/index.d.mts.map +0 -1
- package/dist/api/core/index.mjs +0 -208
- package/dist/api/core/index.mjs.map +0 -1
- package/dist/api/core/types.d.cts +0 -107
- package/dist/api/core/types.d.cts.map +0 -1
- package/dist/api/core/types.d.mts +0 -107
- package/dist/api/core/types.d.mts.map +0 -1
- package/dist/api/middleware/index.cjs +0 -8
- package/dist/api/middleware/index.d.cts +0 -11
- package/dist/api/middleware/index.d.cts.map +0 -1
- package/dist/api/middleware/index.d.mts +0 -11
- package/dist/api/middleware/index.d.mts.map +0 -1
- package/dist/api/middleware/index.mjs +0 -10
- package/dist/api/middleware/index.mjs.map +0 -1
- package/dist/api/middleware/types.d.cts +0 -16
- package/dist/api/middleware/types.d.cts.map +0 -1
- package/dist/api/middleware/types.d.mts +0 -16
- package/dist/api/middleware/types.d.mts.map +0 -1
- package/dist/api/openapi/index.cjs +0 -254
- package/dist/api/openapi/index.mjs +0 -256
- package/dist/api/openapi/index.mjs.map +0 -1
- package/dist/api/openapi/types.d.cts +0 -60
- package/dist/api/openapi/types.d.cts.map +0 -1
- package/dist/api/openapi/types.d.mts +0 -60
- package/dist/api/openapi/types.d.mts.map +0 -1
- package/dist/api/validation/index.cjs +0 -64
- package/dist/api/validation/index.mjs +0 -61
- package/dist/api/validation/index.mjs.map +0 -1
- package/dist/cache/types.d.cts +0 -17
- package/dist/cache/types.d.cts.map +0 -1
- package/dist/cache/types.d.mts +0 -17
- package/dist/cache/types.d.mts.map +0 -1
- package/dist/cron/scanner.cjs +0 -237
- package/dist/cron/scanner.mjs +0 -238
- package/dist/cron/scanner.mjs.map +0 -1
- package/dist/cron/types.d.cts +0 -11
- package/dist/cron/types.d.cts.map +0 -1
- package/dist/cron/types.d.mts +0 -11
- package/dist/cron/types.d.mts.map +0 -1
- package/dist/errors/types.d.cts +0 -5
- package/dist/errors/types.d.cts.map +0 -1
- package/dist/errors/types.d.mts +0 -5
- package/dist/errors/types.d.mts.map +0 -1
- package/dist/i18n/types.d.cts +0 -13
- package/dist/i18n/types.d.cts.map +0 -1
- package/dist/i18n/types.d.mts +0 -13
- package/dist/i18n/types.d.mts.map +0 -1
- package/dist/lib/cache/index.d.cts.map +0 -1
- package/dist/lib/cache/index.d.mts.map +0 -1
- package/dist/lib/cache/index.mjs.map +0 -1
- package/dist/lib/cron/index.d.cts.map +0 -1
- package/dist/lib/cron/index.d.mts.map +0 -1
- package/dist/lib/cron/index.mjs.map +0 -1
- package/dist/lib/errors/index.d.cts.map +0 -1
- package/dist/lib/errors/index.d.mts.map +0 -1
- package/dist/lib/errors/index.mjs.map +0 -1
- package/dist/lib/i18n/index.d.cts.map +0 -1
- package/dist/lib/i18n/index.d.mts.map +0 -1
- package/dist/lib/i18n/index.mjs.map +0 -1
- package/dist/lib/policy/index.d.cts.map +0 -1
- package/dist/lib/policy/index.d.mts.map +0 -1
- package/dist/lib/policy/index.mjs.map +0 -1
- package/dist/lib/prompts/index.d.cts.map +0 -1
- package/dist/lib/prompts/index.d.mts.map +0 -1
- package/dist/lib/prompts/index.mjs.map +0 -1
- package/dist/lib/pubsub/index.d.cts.map +0 -1
- package/dist/lib/pubsub/index.d.mts.map +0 -1
- package/dist/lib/pubsub/index.mjs.map +0 -1
- package/dist/lib/queue/index.d.cts.map +0 -1
- package/dist/lib/queue/index.d.mts.map +0 -1
- package/dist/lib/queue/index.mjs.map +0 -1
- package/dist/node_modules/@standard-schema/spec/dist/index.d.cts +0 -80
- package/dist/node_modules/@standard-schema/spec/dist/index.d.cts.map +0 -1
- package/dist/node_modules/@standard-schema/spec/dist/index.d.mts +0 -80
- package/dist/node_modules/@standard-schema/spec/dist/index.d.mts.map +0 -1
- package/dist/policy/helpers.cjs +0 -206
- package/dist/policy/helpers.d.cts +0 -50
- package/dist/policy/helpers.d.cts.map +0 -1
- package/dist/policy/helpers.d.mts +0 -50
- package/dist/policy/helpers.d.mts.map +0 -1
- package/dist/policy/helpers.mjs +0 -190
- package/dist/policy/helpers.mjs.map +0 -1
- package/dist/policy/types.d.cts +0 -16
- package/dist/policy/types.d.cts.map +0 -1
- package/dist/policy/types.d.mts +0 -16
- package/dist/policy/types.d.mts.map +0 -1
- package/dist/prompts/core/keys.cjs +0 -165
- package/dist/prompts/core/keys.mjs +0 -167
- package/dist/prompts/core/keys.mjs.map +0 -1
- package/dist/prompts/core/runtime.cjs +0 -104
- package/dist/prompts/core/runtime.mjs +0 -106
- package/dist/prompts/core/runtime.mjs.map +0 -1
- package/dist/prompts/core/session.cjs +0 -98
- package/dist/prompts/core/session.mjs +0 -100
- package/dist/prompts/core/session.mjs.map +0 -1
- package/dist/prompts/core/types.d.cts +0 -21
- package/dist/prompts/core/types.d.cts.map +0 -1
- package/dist/prompts/core/types.d.mts +0 -21
- package/dist/prompts/core/types.d.mts.map +0 -1
- package/dist/prompts/types.d.cts +0 -52
- package/dist/prompts/types.d.cts.map +0 -1
- package/dist/prompts/types.d.mts +0 -52
- package/dist/prompts/types.d.mts.map +0 -1
- package/dist/pubsub/types.d.cts +0 -10
- package/dist/pubsub/types.d.cts.map +0 -1
- package/dist/pubsub/types.d.mts +0 -10
- package/dist/pubsub/types.d.mts.map +0 -1
- package/dist/queue/types.d.cts +0 -47
- package/dist/queue/types.d.cts.map +0 -1
- package/dist/queue/types.d.mts +0 -47
- package/dist/queue/types.d.mts.map +0 -1
|
@@ -4,9 +4,45 @@ const require_lib_errors_index = require("../errors/index.cjs");
|
|
|
4
4
|
var PubSub = class {
|
|
5
5
|
options;
|
|
6
6
|
isSubscribed = false;
|
|
7
|
+
nextHandlerId = 0;
|
|
8
|
+
handlers = /* @__PURE__ */ new Map();
|
|
9
|
+
unsubscribeInFlight = null;
|
|
10
|
+
subscribeInFlight = null;
|
|
7
11
|
constructor(options) {
|
|
8
12
|
this.options = options;
|
|
9
13
|
}
|
|
14
|
+
async onMessage(message, channel) {
|
|
15
|
+
const [parseError, parsed] = require_lib_errors_index.mightThrowSync(() => JSON.parse(message));
|
|
16
|
+
if (parseError) return;
|
|
17
|
+
if (!parsed) return;
|
|
18
|
+
const handlers = Array.from(this.handlers.values());
|
|
19
|
+
for (const handler of handlers) await require_lib_errors_index.mightThrow(Promise.resolve().then(() => handler(parsed, channel)));
|
|
20
|
+
}
|
|
21
|
+
async unsubscribeHandler(handlerId) {
|
|
22
|
+
const inFlightUnsubscribe = this.unsubscribeInFlight;
|
|
23
|
+
if (inFlightUnsubscribe) await inFlightUnsubscribe;
|
|
24
|
+
const handler = this.handlers.get(handlerId);
|
|
25
|
+
if (!handler) return require_lib_errors_index.err("UnsubscribeError", "Not subscribed");
|
|
26
|
+
this.handlers.delete(handlerId);
|
|
27
|
+
if (this.handlers.size > 0) return require_lib_errors_index.ok(true);
|
|
28
|
+
this.isSubscribed = false;
|
|
29
|
+
this.unsubscribeInFlight = require_lib_errors_index.mightThrow(this.options.subscriber.unsubscribe(this.options.channel));
|
|
30
|
+
const unsubscribeInFlight = this.unsubscribeInFlight;
|
|
31
|
+
if (!unsubscribeInFlight) {
|
|
32
|
+
this.handlers.set(handlerId, handler);
|
|
33
|
+
this.isSubscribed = true;
|
|
34
|
+
return require_lib_errors_index.err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
35
|
+
}
|
|
36
|
+
const [unsubscribeError] = await unsubscribeInFlight;
|
|
37
|
+
if (unsubscribeError) {
|
|
38
|
+
this.handlers.set(handlerId, handler);
|
|
39
|
+
this.isSubscribed = true;
|
|
40
|
+
this.unsubscribeInFlight = null;
|
|
41
|
+
return require_lib_errors_index.err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
42
|
+
}
|
|
43
|
+
this.unsubscribeInFlight = null;
|
|
44
|
+
return require_lib_errors_index.ok(true);
|
|
45
|
+
}
|
|
10
46
|
async publish(message) {
|
|
11
47
|
const [stringifyError, stringified] = require_lib_errors_index.mightThrowSync(() => JSON.stringify(message));
|
|
12
48
|
if (stringifyError || !stringified) return require_lib_errors_index.err("SerializationError", "Unable to serialize message");
|
|
@@ -15,33 +51,66 @@ var PubSub = class {
|
|
|
15
51
|
return require_lib_errors_index.ok(count);
|
|
16
52
|
}
|
|
17
53
|
async subscribe(handler) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
54
|
+
const inFlightUnsubscribe = this.unsubscribeInFlight;
|
|
55
|
+
if (inFlightUnsubscribe) await inFlightUnsubscribe;
|
|
56
|
+
const handlerId = this.nextHandlerId;
|
|
57
|
+
this.nextHandlerId += 1;
|
|
58
|
+
this.handlers.set(handlerId, handler);
|
|
59
|
+
if (this.isActive()) return require_lib_errors_index.ok(() => this.unsubscribeHandler(handlerId));
|
|
60
|
+
const inFlightSubscribe = this.subscribeInFlight;
|
|
61
|
+
if (inFlightSubscribe) {
|
|
62
|
+
const [inFlightError] = await inFlightSubscribe;
|
|
63
|
+
if (inFlightError || !this.isSubscribed) {
|
|
64
|
+
this.handlers.delete(handlerId);
|
|
65
|
+
return require_lib_errors_index.err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
66
|
+
}
|
|
67
|
+
return require_lib_errors_index.ok(() => this.unsubscribeHandler(handlerId));
|
|
68
|
+
}
|
|
69
|
+
this.subscribeInFlight = require_lib_errors_index.mightThrow(this.options.subscriber.subscribe(this.options.channel, async (message, channel) => this.onMessage(message, channel)));
|
|
70
|
+
const subscribeInFlight = this.subscribeInFlight;
|
|
71
|
+
if (!subscribeInFlight) {
|
|
72
|
+
this.handlers.delete(handlerId);
|
|
73
|
+
return require_lib_errors_index.err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
74
|
+
}
|
|
75
|
+
const [subscribeError, count] = await subscribeInFlight;
|
|
76
|
+
this.subscribeInFlight = null;
|
|
27
77
|
if (subscribeError) {
|
|
28
|
-
this.
|
|
78
|
+
this.handlers.delete(handlerId);
|
|
29
79
|
return require_lib_errors_index.err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
30
80
|
}
|
|
31
|
-
|
|
81
|
+
if (!count) {
|
|
82
|
+
this.handlers.delete(handlerId);
|
|
83
|
+
return require_lib_errors_index.err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
84
|
+
}
|
|
85
|
+
this.isSubscribed = true;
|
|
86
|
+
return require_lib_errors_index.ok(() => this.unsubscribeHandler(handlerId));
|
|
32
87
|
}
|
|
33
88
|
async unsubscribe() {
|
|
89
|
+
const inFlightUnsubscribe = this.unsubscribeInFlight;
|
|
90
|
+
if (inFlightUnsubscribe) await inFlightUnsubscribe;
|
|
34
91
|
if (!this.isActive()) return require_lib_errors_index.err("UnsubscribeError", "Not subscribed");
|
|
92
|
+
const handlers = new Map(this.handlers);
|
|
93
|
+
this.handlers.clear();
|
|
35
94
|
this.isSubscribed = false;
|
|
36
|
-
|
|
95
|
+
this.unsubscribeInFlight = require_lib_errors_index.mightThrow(this.options.subscriber.unsubscribe(this.options.channel));
|
|
96
|
+
const unsubscribeInFlight = this.unsubscribeInFlight;
|
|
97
|
+
if (!unsubscribeInFlight) {
|
|
98
|
+
this.handlers = handlers;
|
|
99
|
+
this.isSubscribed = true;
|
|
100
|
+
return require_lib_errors_index.err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
101
|
+
}
|
|
102
|
+
const [unsubscribeError] = await unsubscribeInFlight;
|
|
37
103
|
if (unsubscribeError) {
|
|
104
|
+
this.handlers = handlers;
|
|
38
105
|
this.isSubscribed = true;
|
|
106
|
+
this.unsubscribeInFlight = null;
|
|
39
107
|
return require_lib_errors_index.err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
40
108
|
}
|
|
109
|
+
this.unsubscribeInFlight = null;
|
|
41
110
|
return require_lib_errors_index.ok(true);
|
|
42
111
|
}
|
|
43
112
|
isActive() {
|
|
44
|
-
return this.isSubscribed;
|
|
113
|
+
return this.handlers.size > 0 && this.isSubscribed;
|
|
45
114
|
}
|
|
46
115
|
};
|
|
47
116
|
//#endregion
|
|
@@ -1,27 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/lib/pubsub/types.d.ts
|
|
2
|
+
type PubSubOptions = {
|
|
3
|
+
subscriber: Bun.RedisClient;
|
|
4
|
+
publisher: Bun.RedisClient;
|
|
5
|
+
channel: string;
|
|
6
|
+
};
|
|
7
|
+
type MessageHandler<T> = (message: T, channel: string) => void | Promise<void>;
|
|
8
|
+
//#endregion
|
|
3
9
|
//#region src/lib/pubsub/index.d.ts
|
|
4
10
|
declare class PubSub<T extends Record<string, unknown>> {
|
|
5
11
|
private options;
|
|
6
12
|
private isSubscribed;
|
|
13
|
+
private nextHandlerId;
|
|
14
|
+
private handlers;
|
|
15
|
+
private unsubscribeInFlight;
|
|
16
|
+
private subscribeInFlight;
|
|
7
17
|
constructor(options: PubSubOptions);
|
|
8
|
-
|
|
18
|
+
private onMessage;
|
|
19
|
+
private unsubscribeHandler;
|
|
20
|
+
publish(message: T): Promise<readonly [{
|
|
9
21
|
readonly type: "SerializationError";
|
|
10
22
|
readonly message: string;
|
|
11
23
|
}, null] | readonly [{
|
|
12
24
|
readonly type: "PublishError";
|
|
13
25
|
readonly message: string;
|
|
14
|
-
}, null]>;
|
|
15
|
-
subscribe(handler: MessageHandler<T>): Promise<readonly [null,
|
|
26
|
+
}, null] | readonly [null, number]>;
|
|
27
|
+
subscribe(handler: MessageHandler<T>): Promise<readonly [null, () => Promise<readonly [{
|
|
28
|
+
readonly type: "UnsubscribeError";
|
|
29
|
+
readonly message: string;
|
|
30
|
+
}, null] | readonly [null, boolean]>] | readonly [{
|
|
16
31
|
readonly type: "SubscribeError";
|
|
17
32
|
readonly message: string;
|
|
18
33
|
}, null]>;
|
|
19
|
-
unsubscribe(): Promise<readonly [
|
|
34
|
+
unsubscribe(): Promise<readonly [{
|
|
20
35
|
readonly type: "UnsubscribeError";
|
|
21
36
|
readonly message: string;
|
|
22
|
-
}, null]>;
|
|
37
|
+
}, null] | readonly [null, boolean]>;
|
|
23
38
|
isActive(): boolean;
|
|
24
39
|
}
|
|
25
40
|
//#endregion
|
|
26
|
-
export { PubSub };
|
|
27
|
-
//# sourceMappingURL=index.d.cts.map
|
|
41
|
+
export { PubSub };
|
|
@@ -1,27 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/lib/pubsub/types.d.ts
|
|
2
|
+
type PubSubOptions = {
|
|
3
|
+
subscriber: Bun.RedisClient;
|
|
4
|
+
publisher: Bun.RedisClient;
|
|
5
|
+
channel: string;
|
|
6
|
+
};
|
|
7
|
+
type MessageHandler<T> = (message: T, channel: string) => void | Promise<void>;
|
|
8
|
+
//#endregion
|
|
3
9
|
//#region src/lib/pubsub/index.d.ts
|
|
4
10
|
declare class PubSub<T extends Record<string, unknown>> {
|
|
5
11
|
private options;
|
|
6
12
|
private isSubscribed;
|
|
13
|
+
private nextHandlerId;
|
|
14
|
+
private handlers;
|
|
15
|
+
private unsubscribeInFlight;
|
|
16
|
+
private subscribeInFlight;
|
|
7
17
|
constructor(options: PubSubOptions);
|
|
8
|
-
|
|
18
|
+
private onMessage;
|
|
19
|
+
private unsubscribeHandler;
|
|
20
|
+
publish(message: T): Promise<readonly [{
|
|
9
21
|
readonly type: "SerializationError";
|
|
10
22
|
readonly message: string;
|
|
11
23
|
}, null] | readonly [{
|
|
12
24
|
readonly type: "PublishError";
|
|
13
25
|
readonly message: string;
|
|
14
|
-
}, null]>;
|
|
15
|
-
subscribe(handler: MessageHandler<T>): Promise<readonly [null,
|
|
26
|
+
}, null] | readonly [null, number]>;
|
|
27
|
+
subscribe(handler: MessageHandler<T>): Promise<readonly [null, () => Promise<readonly [{
|
|
28
|
+
readonly type: "UnsubscribeError";
|
|
29
|
+
readonly message: string;
|
|
30
|
+
}, null] | readonly [null, boolean]>] | readonly [{
|
|
16
31
|
readonly type: "SubscribeError";
|
|
17
32
|
readonly message: string;
|
|
18
33
|
}, null]>;
|
|
19
|
-
unsubscribe(): Promise<readonly [
|
|
34
|
+
unsubscribe(): Promise<readonly [{
|
|
20
35
|
readonly type: "UnsubscribeError";
|
|
21
36
|
readonly message: string;
|
|
22
|
-
}, null]>;
|
|
37
|
+
}, null] | readonly [null, boolean]>;
|
|
23
38
|
isActive(): boolean;
|
|
24
39
|
}
|
|
25
40
|
//#endregion
|
|
26
|
-
export { PubSub };
|
|
27
|
-
//# sourceMappingURL=index.d.mts.map
|
|
41
|
+
export { PubSub };
|
|
@@ -3,9 +3,45 @@ import { err, mightThrow, mightThrowSync, ok } from "../errors/index.mjs";
|
|
|
3
3
|
var PubSub = class {
|
|
4
4
|
options;
|
|
5
5
|
isSubscribed = false;
|
|
6
|
+
nextHandlerId = 0;
|
|
7
|
+
handlers = /* @__PURE__ */ new Map();
|
|
8
|
+
unsubscribeInFlight = null;
|
|
9
|
+
subscribeInFlight = null;
|
|
6
10
|
constructor(options) {
|
|
7
11
|
this.options = options;
|
|
8
12
|
}
|
|
13
|
+
async onMessage(message, channel) {
|
|
14
|
+
const [parseError, parsed] = mightThrowSync(() => JSON.parse(message));
|
|
15
|
+
if (parseError) return;
|
|
16
|
+
if (!parsed) return;
|
|
17
|
+
const handlers = Array.from(this.handlers.values());
|
|
18
|
+
for (const handler of handlers) await mightThrow(Promise.resolve().then(() => handler(parsed, channel)));
|
|
19
|
+
}
|
|
20
|
+
async unsubscribeHandler(handlerId) {
|
|
21
|
+
const inFlightUnsubscribe = this.unsubscribeInFlight;
|
|
22
|
+
if (inFlightUnsubscribe) await inFlightUnsubscribe;
|
|
23
|
+
const handler = this.handlers.get(handlerId);
|
|
24
|
+
if (!handler) return err("UnsubscribeError", "Not subscribed");
|
|
25
|
+
this.handlers.delete(handlerId);
|
|
26
|
+
if (this.handlers.size > 0) return ok(true);
|
|
27
|
+
this.isSubscribed = false;
|
|
28
|
+
this.unsubscribeInFlight = mightThrow(this.options.subscriber.unsubscribe(this.options.channel));
|
|
29
|
+
const unsubscribeInFlight = this.unsubscribeInFlight;
|
|
30
|
+
if (!unsubscribeInFlight) {
|
|
31
|
+
this.handlers.set(handlerId, handler);
|
|
32
|
+
this.isSubscribed = true;
|
|
33
|
+
return err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
34
|
+
}
|
|
35
|
+
const [unsubscribeError] = await unsubscribeInFlight;
|
|
36
|
+
if (unsubscribeError) {
|
|
37
|
+
this.handlers.set(handlerId, handler);
|
|
38
|
+
this.isSubscribed = true;
|
|
39
|
+
this.unsubscribeInFlight = null;
|
|
40
|
+
return err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
41
|
+
}
|
|
42
|
+
this.unsubscribeInFlight = null;
|
|
43
|
+
return ok(true);
|
|
44
|
+
}
|
|
9
45
|
async publish(message) {
|
|
10
46
|
const [stringifyError, stringified] = mightThrowSync(() => JSON.stringify(message));
|
|
11
47
|
if (stringifyError || !stringified) return err("SerializationError", "Unable to serialize message");
|
|
@@ -14,36 +50,67 @@ var PubSub = class {
|
|
|
14
50
|
return ok(count);
|
|
15
51
|
}
|
|
16
52
|
async subscribe(handler) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
53
|
+
const inFlightUnsubscribe = this.unsubscribeInFlight;
|
|
54
|
+
if (inFlightUnsubscribe) await inFlightUnsubscribe;
|
|
55
|
+
const handlerId = this.nextHandlerId;
|
|
56
|
+
this.nextHandlerId += 1;
|
|
57
|
+
this.handlers.set(handlerId, handler);
|
|
58
|
+
if (this.isActive()) return ok(() => this.unsubscribeHandler(handlerId));
|
|
59
|
+
const inFlightSubscribe = this.subscribeInFlight;
|
|
60
|
+
if (inFlightSubscribe) {
|
|
61
|
+
const [inFlightError] = await inFlightSubscribe;
|
|
62
|
+
if (inFlightError || !this.isSubscribed) {
|
|
63
|
+
this.handlers.delete(handlerId);
|
|
64
|
+
return err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
65
|
+
}
|
|
66
|
+
return ok(() => this.unsubscribeHandler(handlerId));
|
|
67
|
+
}
|
|
68
|
+
this.subscribeInFlight = mightThrow(this.options.subscriber.subscribe(this.options.channel, async (message, channel) => this.onMessage(message, channel)));
|
|
69
|
+
const subscribeInFlight = this.subscribeInFlight;
|
|
70
|
+
if (!subscribeInFlight) {
|
|
71
|
+
this.handlers.delete(handlerId);
|
|
72
|
+
return err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
73
|
+
}
|
|
74
|
+
const [subscribeError, count] = await subscribeInFlight;
|
|
75
|
+
this.subscribeInFlight = null;
|
|
26
76
|
if (subscribeError) {
|
|
27
|
-
this.
|
|
77
|
+
this.handlers.delete(handlerId);
|
|
28
78
|
return err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
29
79
|
}
|
|
30
|
-
|
|
80
|
+
if (!count) {
|
|
81
|
+
this.handlers.delete(handlerId);
|
|
82
|
+
return err("SubscribeError", `Unable to subscribe to ${this.options.channel}`);
|
|
83
|
+
}
|
|
84
|
+
this.isSubscribed = true;
|
|
85
|
+
return ok(() => this.unsubscribeHandler(handlerId));
|
|
31
86
|
}
|
|
32
87
|
async unsubscribe() {
|
|
88
|
+
const inFlightUnsubscribe = this.unsubscribeInFlight;
|
|
89
|
+
if (inFlightUnsubscribe) await inFlightUnsubscribe;
|
|
33
90
|
if (!this.isActive()) return err("UnsubscribeError", "Not subscribed");
|
|
91
|
+
const handlers = new Map(this.handlers);
|
|
92
|
+
this.handlers.clear();
|
|
34
93
|
this.isSubscribed = false;
|
|
35
|
-
|
|
94
|
+
this.unsubscribeInFlight = mightThrow(this.options.subscriber.unsubscribe(this.options.channel));
|
|
95
|
+
const unsubscribeInFlight = this.unsubscribeInFlight;
|
|
96
|
+
if (!unsubscribeInFlight) {
|
|
97
|
+
this.handlers = handlers;
|
|
98
|
+
this.isSubscribed = true;
|
|
99
|
+
return err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
100
|
+
}
|
|
101
|
+
const [unsubscribeError] = await unsubscribeInFlight;
|
|
36
102
|
if (unsubscribeError) {
|
|
103
|
+
this.handlers = handlers;
|
|
37
104
|
this.isSubscribed = true;
|
|
105
|
+
this.unsubscribeInFlight = null;
|
|
38
106
|
return err("UnsubscribeError", `Unable to unsubscribe from ${this.options.channel}`);
|
|
39
107
|
}
|
|
108
|
+
this.unsubscribeInFlight = null;
|
|
40
109
|
return ok(true);
|
|
41
110
|
}
|
|
42
111
|
isActive() {
|
|
43
|
-
return this.isSubscribed;
|
|
112
|
+
return this.handlers.size > 0 && this.isSubscribed;
|
|
44
113
|
}
|
|
45
114
|
};
|
|
46
115
|
//#endregion
|
|
47
116
|
export { PubSub };
|
|
48
|
-
|
|
49
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,5 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/lib/queue/types.d.ts
|
|
2
|
+
type Job<T> = {
|
|
3
|
+
id: string;
|
|
4
|
+
data: T;
|
|
5
|
+
attempts: number;
|
|
6
|
+
maxRetries: number;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
};
|
|
9
|
+
type RetryContext<T> = {
|
|
10
|
+
job: Job<T>;
|
|
11
|
+
error: string;
|
|
12
|
+
nextRetryDelayMs: number;
|
|
13
|
+
retriesRemaining: number;
|
|
14
|
+
backoffMultiplier: number;
|
|
15
|
+
};
|
|
16
|
+
type ErrorContext<T> = {
|
|
17
|
+
job: Job<T>;
|
|
18
|
+
lastError: string;
|
|
19
|
+
totalDurationMs: number;
|
|
20
|
+
totalAttempts: number;
|
|
21
|
+
errorHistory: Array<{
|
|
22
|
+
attempt: number;
|
|
23
|
+
error: string;
|
|
24
|
+
timestamp: number;
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
27
|
+
type ParseErrorContext = {
|
|
28
|
+
rawJobData: string;
|
|
29
|
+
parseError: string;
|
|
30
|
+
timestamp: number;
|
|
31
|
+
};
|
|
32
|
+
type QueueOptions<T> = {
|
|
33
|
+
name: string;
|
|
34
|
+
redis: Bun.RedisClient;
|
|
35
|
+
handler: (data: T, signal?: AbortSignal) => void | Promise<void>;
|
|
36
|
+
onSuccess?: (job: Job<T>) => void | Promise<void>;
|
|
37
|
+
onRetry?: (context: RetryContext<T>) => void | Promise<void>;
|
|
38
|
+
onError?: (context: ErrorContext<T>) => void | Promise<void>;
|
|
39
|
+
onParseError?: (context: ParseErrorContext) => void | Promise<void>;
|
|
40
|
+
retries?: number;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
concurrency?: number;
|
|
43
|
+
pollInterval?: number;
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
3
46
|
//#region src/lib/queue/index.d.ts
|
|
4
47
|
declare class Queue<T> {
|
|
5
48
|
private options;
|
|
@@ -28,5 +71,4 @@ declare class Queue<T> {
|
|
|
28
71
|
private retryJob;
|
|
29
72
|
}
|
|
30
73
|
//#endregion
|
|
31
|
-
export { Queue };
|
|
32
|
-
//# sourceMappingURL=index.d.cts.map
|
|
74
|
+
export { Queue };
|
|
@@ -1,5 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/lib/queue/types.d.ts
|
|
2
|
+
type Job<T> = {
|
|
3
|
+
id: string;
|
|
4
|
+
data: T;
|
|
5
|
+
attempts: number;
|
|
6
|
+
maxRetries: number;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
};
|
|
9
|
+
type RetryContext<T> = {
|
|
10
|
+
job: Job<T>;
|
|
11
|
+
error: string;
|
|
12
|
+
nextRetryDelayMs: number;
|
|
13
|
+
retriesRemaining: number;
|
|
14
|
+
backoffMultiplier: number;
|
|
15
|
+
};
|
|
16
|
+
type ErrorContext<T> = {
|
|
17
|
+
job: Job<T>;
|
|
18
|
+
lastError: string;
|
|
19
|
+
totalDurationMs: number;
|
|
20
|
+
totalAttempts: number;
|
|
21
|
+
errorHistory: Array<{
|
|
22
|
+
attempt: number;
|
|
23
|
+
error: string;
|
|
24
|
+
timestamp: number;
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
27
|
+
type ParseErrorContext = {
|
|
28
|
+
rawJobData: string;
|
|
29
|
+
parseError: string;
|
|
30
|
+
timestamp: number;
|
|
31
|
+
};
|
|
32
|
+
type QueueOptions<T> = {
|
|
33
|
+
name: string;
|
|
34
|
+
redis: Bun.RedisClient;
|
|
35
|
+
handler: (data: T, signal?: AbortSignal) => void | Promise<void>;
|
|
36
|
+
onSuccess?: (job: Job<T>) => void | Promise<void>;
|
|
37
|
+
onRetry?: (context: RetryContext<T>) => void | Promise<void>;
|
|
38
|
+
onError?: (context: ErrorContext<T>) => void | Promise<void>;
|
|
39
|
+
onParseError?: (context: ParseErrorContext) => void | Promise<void>;
|
|
40
|
+
retries?: number;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
concurrency?: number;
|
|
43
|
+
pollInterval?: number;
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
3
46
|
//#region src/lib/queue/index.d.ts
|
|
4
47
|
declare class Queue<T> {
|
|
5
48
|
private options;
|
|
@@ -28,5 +71,4 @@ declare class Queue<T> {
|
|
|
28
71
|
private retryJob;
|
|
29
72
|
}
|
|
30
73
|
//#endregion
|
|
31
|
-
export { Queue };
|
|
32
|
-
//# sourceMappingURL=index.d.mts.map
|
|
74
|
+
export { Queue };
|