@gobing-ai/ts-infra 0.1.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/README.md +389 -0
- package/dist/api-client.d.ts +31 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +112 -0
- package/dist/event-bus/event-bus.d.ts +33 -0
- package/dist/event-bus/event-bus.d.ts.map +1 -0
- package/dist/event-bus/event-bus.js +211 -0
- package/dist/event-bus/index.d.ts +3 -0
- package/dist/event-bus/index.d.ts.map +1 -0
- package/dist/event-bus/index.js +1 -0
- package/dist/event-bus/types.d.ts +35 -0
- package/dist/event-bus/types.d.ts.map +1 -0
- package/dist/event-bus/types.js +3 -0
- package/dist/events/app-events.d.ts +7 -0
- package/dist/events/app-events.d.ts.map +1 -0
- package/dist/events/app-events.js +4 -0
- package/dist/events/create-system-bus.d.ts +6 -0
- package/dist/events/create-system-bus.d.ts.map +1 -0
- package/dist/events/create-system-bus.js +7 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +9 -0
- package/dist/job-queue/index.d.ts +2 -0
- package/dist/job-queue/index.d.ts.map +1 -0
- package/dist/job-queue/index.js +0 -0
- package/dist/job-queue/types.d.ts +57 -0
- package/dist/job-queue/types.d.ts.map +1 -0
- package/dist/job-queue/types.js +8 -0
- package/dist/logger.d.ts +28 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +100 -0
- package/dist/scheduler/action.d.ts +5 -0
- package/dist/scheduler/action.d.ts.map +1 -0
- package/dist/scheduler/action.js +0 -0
- package/dist/scheduler/cloudflare.d.ts +27 -0
- package/dist/scheduler/cloudflare.d.ts.map +1 -0
- package/dist/scheduler/cloudflare.js +24 -0
- package/dist/scheduler/factory.d.ts +19 -0
- package/dist/scheduler/factory.d.ts.map +1 -0
- package/dist/scheduler/factory.js +45 -0
- package/dist/scheduler/index.d.ts +6 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +4 -0
- package/dist/scheduler/node.d.ts +16 -0
- package/dist/scheduler/node.d.ts.map +1 -0
- package/dist/scheduler/node.js +63 -0
- package/dist/scheduler/noop.d.ts +11 -0
- package/dist/scheduler/noop.d.ts.map +1 -0
- package/dist/scheduler/noop.js +12 -0
- package/dist/scheduler/types.d.ts +12 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +3 -0
- package/dist/telemetry/config.d.ts +42 -0
- package/dist/telemetry/config.d.ts.map +1 -0
- package/dist/telemetry/config.js +24 -0
- package/dist/telemetry/db-sanitize.d.ts +15 -0
- package/dist/telemetry/db-sanitize.d.ts.map +1 -0
- package/dist/telemetry/db-sanitize.js +72 -0
- package/dist/telemetry/index.d.ts +7 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +5 -0
- package/dist/telemetry/metrics.d.ts +32 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +109 -0
- package/dist/telemetry/sdk.d.ts +13 -0
- package/dist/telemetry/sdk.d.ts.map +1 -0
- package/dist/telemetry/sdk.js +54 -0
- package/dist/telemetry/tracing.d.ts +13 -0
- package/dist/telemetry/tracing.d.ts.map +1 -0
- package/dist/telemetry/tracing.js +54 -0
- package/package.json +50 -0
- package/src/api-client.ts +162 -0
- package/src/event-bus/event-bus.ts +236 -0
- package/src/event-bus/index.ts +9 -0
- package/src/event-bus/types.ts +40 -0
- package/src/events/app-events.ts +8 -0
- package/src/events/create-system-bus.ts +8 -0
- package/src/events/index.ts +2 -0
- package/src/index.ts +74 -0
- package/src/job-queue/index.ts +9 -0
- package/src/job-queue/types.ts +60 -0
- package/src/logger.ts +123 -0
- package/src/scheduler/action.ts +4 -0
- package/src/scheduler/cloudflare.ts +45 -0
- package/src/scheduler/factory.ts +57 -0
- package/src/scheduler/index.ts +5 -0
- package/src/scheduler/node.ts +83 -0
- package/src/scheduler/noop.ts +20 -0
- package/src/scheduler/types.ts +13 -0
- package/src/telemetry/config.ts +63 -0
- package/src/telemetry/db-sanitize.ts +79 -0
- package/src/telemetry/index.ts +29 -0
- package/src/telemetry/metrics.ts +150 -0
- package/src/telemetry/sdk.ts +65 -0
- package/src/telemetry/tracing.ts +64 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { getLogger } from '../logger.js';
|
|
2
|
+
let _busLogger;
|
|
3
|
+
function busLogger() {
|
|
4
|
+
if (!_busLogger)
|
|
5
|
+
_busLogger = getLogger('event-bus');
|
|
6
|
+
return _busLogger;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Type-safe event bus supporting both synchronous (in-process) and
|
|
10
|
+
* asynchronous handlers with optional job-queue enqueue instrumentation.
|
|
11
|
+
*/
|
|
12
|
+
export class EventBus {
|
|
13
|
+
syncHandlers = new Map();
|
|
14
|
+
asyncHandlers = new Map();
|
|
15
|
+
asyncHandlerIds = new WeakMap();
|
|
16
|
+
jobQueue;
|
|
17
|
+
lifecycleBus;
|
|
18
|
+
nextAsyncHandlerId = 0;
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
this.jobQueue = opts?.jobQueue ?? null;
|
|
21
|
+
this.lifecycleBus = opts?.lifecycleBus ?? null;
|
|
22
|
+
}
|
|
23
|
+
on(event, handler, opts) {
|
|
24
|
+
if (opts?.async) {
|
|
25
|
+
this.registerAsync(event, handler);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.registerSync(event, handler);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
once(event, handler, opts) {
|
|
32
|
+
const wrapped = ((...args) => {
|
|
33
|
+
this.off(event, wrapped);
|
|
34
|
+
handler(...args);
|
|
35
|
+
});
|
|
36
|
+
this.on(event, wrapped, opts);
|
|
37
|
+
}
|
|
38
|
+
off(event, handler) {
|
|
39
|
+
const syncSet = this.syncHandlers.get(event);
|
|
40
|
+
if (syncSet) {
|
|
41
|
+
syncSet.delete(handler);
|
|
42
|
+
if (syncSet.size === 0) {
|
|
43
|
+
this.syncHandlers.delete(event);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const asyncSet = this.asyncHandlers.get(event);
|
|
47
|
+
if (asyncSet) {
|
|
48
|
+
asyncSet.delete(handler);
|
|
49
|
+
if (asyncSet.size === 0) {
|
|
50
|
+
this.asyncHandlers.delete(event);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
removeAllListeners(event) {
|
|
55
|
+
if (event !== undefined) {
|
|
56
|
+
this.syncHandlers.delete(event);
|
|
57
|
+
this.asyncHandlers.delete(event);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.syncHandlers.clear();
|
|
61
|
+
this.asyncHandlers.clear();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async emit(event, ...args) {
|
|
65
|
+
const eventName = String(event);
|
|
66
|
+
const startMs = performance.now();
|
|
67
|
+
let syncCount = 0;
|
|
68
|
+
let asyncCount = 0;
|
|
69
|
+
let errors = 0;
|
|
70
|
+
const syncSet = this.syncHandlers.get(event);
|
|
71
|
+
if (syncSet) {
|
|
72
|
+
syncCount = syncSet.size;
|
|
73
|
+
for (const handler of syncSet) {
|
|
74
|
+
try {
|
|
75
|
+
handler(...args);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
errors++;
|
|
79
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80
|
+
busLogger().error('sync handler threw', { event: eventName, error: message });
|
|
81
|
+
this.publishHandlerError(eventName, 'sync', message);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const asyncSet = this.asyncHandlers.get(event);
|
|
86
|
+
if (asyncSet && asyncSet.size > 0) {
|
|
87
|
+
const handlers = [...asyncSet];
|
|
88
|
+
asyncCount = handlers.length;
|
|
89
|
+
for (const handler of handlers) {
|
|
90
|
+
if (this.jobQueue) {
|
|
91
|
+
try {
|
|
92
|
+
const jobId = await this.jobQueue.enqueue(eventName, {
|
|
93
|
+
event: eventName,
|
|
94
|
+
args,
|
|
95
|
+
handlerId: this.getAsyncHandlerId(handler),
|
|
96
|
+
});
|
|
97
|
+
busLogger().debug('async job enqueued', { event: eventName, jobId, handlerCount: 1 });
|
|
98
|
+
this.publishAsyncEnqueued(eventName, jobId, 1);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
errors++;
|
|
102
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
103
|
+
busLogger().error('async enqueue failed', { event: eventName, error: message });
|
|
104
|
+
this.publishHandlerError(eventName, 'async', message);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
busLogger().warn('async handlers registered but no JobQueue injected', {
|
|
110
|
+
event: eventName,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
await Promise.resolve().then(() => handler(...args));
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
errors++;
|
|
118
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
119
|
+
busLogger().error('async handler threw', { event: eventName, error: message });
|
|
120
|
+
this.publishHandlerError(eventName, 'async', message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const durationMs = performance.now() - startMs;
|
|
125
|
+
const detail = args.length === 1 ? args[0] : args.length > 1 ? args : undefined;
|
|
126
|
+
this.publishEmitDone({ event: eventName, syncCount, asyncCount, emitDurationMs: durationMs, errors, detail });
|
|
127
|
+
if (syncCount === 0 && asyncCount === 0) {
|
|
128
|
+
busLogger().debug('emit with zero handlers', { event: eventName });
|
|
129
|
+
this.publishEmitNoop(eventName);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
listenerCount(event, mode) {
|
|
133
|
+
const sync = mode !== 'async' ? (this.syncHandlers.get(event)?.size ?? 0) : 0;
|
|
134
|
+
const async = mode !== 'sync' ? (this.asyncHandlers.get(event)?.size ?? 0) : 0;
|
|
135
|
+
return sync + async;
|
|
136
|
+
}
|
|
137
|
+
eventNames() {
|
|
138
|
+
const names = new Set();
|
|
139
|
+
for (const key of this.syncHandlers.keys())
|
|
140
|
+
names.add(String(key));
|
|
141
|
+
for (const key of this.asyncHandlers.keys())
|
|
142
|
+
names.add(String(key));
|
|
143
|
+
return [...names];
|
|
144
|
+
}
|
|
145
|
+
registerSync(event, handler) {
|
|
146
|
+
let set = this.syncHandlers.get(event);
|
|
147
|
+
if (!set) {
|
|
148
|
+
set = new Set();
|
|
149
|
+
this.syncHandlers.set(event, set);
|
|
150
|
+
}
|
|
151
|
+
set.add(handler);
|
|
152
|
+
}
|
|
153
|
+
registerAsync(event, handler) {
|
|
154
|
+
let set = this.asyncHandlers.get(event);
|
|
155
|
+
if (!set) {
|
|
156
|
+
set = new Set();
|
|
157
|
+
this.asyncHandlers.set(event, set);
|
|
158
|
+
}
|
|
159
|
+
set.add(handler);
|
|
160
|
+
}
|
|
161
|
+
getAsyncHandlerId(handler) {
|
|
162
|
+
const existing = this.asyncHandlerIds.get(handler);
|
|
163
|
+
if (existing)
|
|
164
|
+
return existing;
|
|
165
|
+
const id = `handler-${++this.nextAsyncHandlerId}`;
|
|
166
|
+
this.asyncHandlerIds.set(handler, id);
|
|
167
|
+
return id;
|
|
168
|
+
}
|
|
169
|
+
publishEmitDone(detail) {
|
|
170
|
+
if (this.lifecycleBus) {
|
|
171
|
+
try {
|
|
172
|
+
void this.lifecycleBus.emit('bus.emit.done', detail);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Lifecycle bus failures must never affect the primary bus.
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
publishEmitNoop(event) {
|
|
180
|
+
if (this.lifecycleBus) {
|
|
181
|
+
try {
|
|
182
|
+
void this.lifecycleBus.emit('bus.emit.noop', { event });
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Swallow.
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
publishHandlerError(event, mode, error) {
|
|
190
|
+
if (this.lifecycleBus) {
|
|
191
|
+
const detail = { event, mode, error };
|
|
192
|
+
try {
|
|
193
|
+
void this.lifecycleBus.emit('bus.handler.error', detail);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Swallow.
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
publishAsyncEnqueued(event, jobId, handlerCount) {
|
|
201
|
+
if (this.lifecycleBus) {
|
|
202
|
+
const detail = { event, jobId, handlerCount };
|
|
203
|
+
try {
|
|
204
|
+
void this.lifecycleBus.emit('bus.handler.async.enqueued', detail);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Swallow.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/event-bus/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EACR,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EventBus } from './event-bus.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event bus types — shared constraints for typed pub-sub.
|
|
3
|
+
*/
|
|
4
|
+
export type EventMap = Record<string, (...args: never[]) => void>;
|
|
5
|
+
export interface SubscribeOptions {
|
|
6
|
+
/** When true, the handler is dispatched through the async handler path. */
|
|
7
|
+
async?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface EmitDoneDetail {
|
|
10
|
+
event: string;
|
|
11
|
+
syncCount: number;
|
|
12
|
+
asyncCount: number;
|
|
13
|
+
emitDurationMs: number;
|
|
14
|
+
errors: number;
|
|
15
|
+
detail?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface HandlerErrorDetail {
|
|
18
|
+
event: string;
|
|
19
|
+
mode: 'sync' | 'async';
|
|
20
|
+
error: string;
|
|
21
|
+
}
|
|
22
|
+
export interface AsyncEnqueuedDetail {
|
|
23
|
+
event: string;
|
|
24
|
+
jobId: string;
|
|
25
|
+
handlerCount: number;
|
|
26
|
+
}
|
|
27
|
+
export type BusLifecycleEvents = {
|
|
28
|
+
'bus.emit.done': (detail: EmitDoneDetail) => void;
|
|
29
|
+
'bus.emit.noop': (detail: {
|
|
30
|
+
event: string;
|
|
31
|
+
}) => void;
|
|
32
|
+
'bus.handler.error': (detail: HandlerErrorDetail) => void;
|
|
33
|
+
'bus.handler.async.enqueued': (detail: AsyncEnqueuedDetail) => void;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/event-bus/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAC7B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC7B,eAAe,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACrD,mBAAmB,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC1D,4BAA4B,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACvE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application event definitions — generic typed event map pattern.
|
|
3
|
+
* Apps extend this with their own event types.
|
|
4
|
+
*/
|
|
5
|
+
export type AppEvents = Record<string, (...args: never[]) => void>;
|
|
6
|
+
export type AppInternalEvents = Record<string, (...args: never[]) => void>;
|
|
7
|
+
//# sourceMappingURL=app-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-events.d.ts","sourceRoot":"","sources":["../../src/events/app-events.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-system-bus.d.ts","sourceRoot":"","sources":["../../src/events/create-system-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD;;GAEG;AACH,wBAAgB,eAAe,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC,CAEtF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createSystemBus } from './create-system-bus.js';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { APIClient, type APIClientConfig, APIError, type RequestOptions } from './api-client';
|
|
2
|
+
export { EventBus, type EventMap, type SubscribeOptions } from './event-bus/index';
|
|
3
|
+
export type { AppEvents, AppInternalEvents } from './events/index';
|
|
4
|
+
export { createSystemBus } from './events/index';
|
|
5
|
+
export type { EnqueueOptions, Job, JobHandler, JobQueue, QueueConsumer, QueueConsumerConfig, QueueStats, } from './job-queue/index';
|
|
6
|
+
export { getLogger, initializeLogger, type Logger, type LogLevel } from './logger';
|
|
7
|
+
export { CloudflareSchedulerAdapter, getSchedulerAdapter, initScheduler, NodeSchedulerAdapter, NoopSchedulerAdapter, type ScheduledAction, type SchedulerAdapter, setSchedulerAdapter, } from './scheduler/index';
|
|
8
|
+
export { addSpanAttributes, addSpanEvent, extractSqlOperation, getActiveSpan, getDbOperationDuration, getDbOperationErrors, getDbOperationTotal, getEventbusEmitsTotal, getEventbusErrorsTotal, getHttpClientRequestDuration, getHttpClientRequestErrors, getHttpClientRequestTotal, getHttpServerRequestDuration, getHttpServerRequestErrors, getHttpServerRequestTotal, getQueueJobCompletedTotal, getQueueJobEnqueuedTotal, getQueueJobFailedTotal, getQueueJobProcessingDuration, getSchedulerJobDuration, getSchedulerJobExecutedTotal, getSchedulerJobFailedTotal, getTelemetryConfig, getTracer, initMetrics, initTelemetry, isTelemetryEnabled, sanitizeSql, shutdownMetrics, shutdownTelemetry, type TelemetryConfig, type TelemetryConfigPartial, traceAsync, traceSync, withSpan, } from './telemetry/index';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9F,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGnF,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,YAAY,EACR,cAAc,EACd,GAAG,EACH,UAAU,EACV,QAAQ,EACR,aAAa,EACb,mBAAmB,EACnB,UAAU,GACb,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGnF,OAAO,EACH,0BAA0B,EAC1B,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,mBAAmB,GACtB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACH,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,EAC1B,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,UAAU,EACV,SAAS,EACT,QAAQ,GACX,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// API Client
|
|
2
|
+
export { APIClient, APIError } from './api-client.js';
|
|
3
|
+
// Event Bus
|
|
4
|
+
export { EventBus } from './event-bus/index.js';
|
|
5
|
+
export { createSystemBus } from './events/index.js';
|
|
6
|
+
// Logger
|
|
7
|
+
export { getLogger, initializeLogger } from './logger.js';
|
|
8
|
+
// Scheduler
|
|
9
|
+
export { CloudflareSchedulerAdapter, getSchedulerAdapter, initScheduler, NodeSchedulerAdapter, NoopSchedulerAdapter, setSchedulerAdapter, } from './scheduler/index.js';
|
|
10
|
+
// Telemetry
|
|
11
|
+
export { addSpanAttributes, addSpanEvent, extractSqlOperation, getActiveSpan, getDbOperationDuration, getDbOperationErrors, getDbOperationTotal, getEventbusEmitsTotal, getEventbusErrorsTotal, getHttpClientRequestDuration, getHttpClientRequestErrors, getHttpClientRequestTotal, getHttpServerRequestDuration, getHttpServerRequestErrors, getHttpServerRequestTotal, getQueueJobCompletedTotal, getQueueJobEnqueuedTotal, getQueueJobFailedTotal, getQueueJobProcessingDuration, getSchedulerJobDuration, getSchedulerJobExecutedTotal, getSchedulerJobFailedTotal, getTelemetryConfig, getTracer, initMetrics, initTelemetry, isTelemetryEnabled, sanitizeSql, shutdownMetrics, shutdownTelemetry, traceAsync, traceSync, withSpan, } from './telemetry/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/job-queue/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,cAAc,EACd,GAAG,EACH,UAAU,EACV,QAAQ,EACR,aAAa,EACb,mBAAmB,EACnB,UAAU,GACb,MAAM,SAAS,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job queue types for async work processing with retry.
|
|
3
|
+
*
|
|
4
|
+
* **Types only** — the DB-backed `DbQueue` and `DbConsumer` implementations
|
|
5
|
+
* that drive the job-queue subsystem live in `@spur/core`. These interfaces
|
|
6
|
+
* are provided here so `EventBus` and other infra components can reference
|
|
7
|
+
* the queue contract without a circular dependency on the DB layer.
|
|
8
|
+
*/
|
|
9
|
+
export interface Job<T = unknown> {
|
|
10
|
+
id: string;
|
|
11
|
+
type: string;
|
|
12
|
+
payload: T;
|
|
13
|
+
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
14
|
+
attempts: number;
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
updatedAt: number;
|
|
18
|
+
nextRetryAt: number | null;
|
|
19
|
+
lastError: string | null;
|
|
20
|
+
processingAt: number | null;
|
|
21
|
+
}
|
|
22
|
+
export interface EnqueueOptions {
|
|
23
|
+
maxRetries?: number;
|
|
24
|
+
delay?: number;
|
|
25
|
+
ttlMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface JobQueue<T = unknown> {
|
|
28
|
+
enqueue(type: string, payload: T, options?: EnqueueOptions): Promise<string>;
|
|
29
|
+
enqueueBatch(jobs: Array<{
|
|
30
|
+
type: string;
|
|
31
|
+
payload: T;
|
|
32
|
+
} & EnqueueOptions>): Promise<string[]>;
|
|
33
|
+
}
|
|
34
|
+
export type JobHandler<T = unknown> = (job: Job<T>) => Promise<void>;
|
|
35
|
+
export interface QueueStats {
|
|
36
|
+
pending: number;
|
|
37
|
+
processing: number;
|
|
38
|
+
completed: number;
|
|
39
|
+
failed: number;
|
|
40
|
+
}
|
|
41
|
+
export interface QueueConsumerConfig {
|
|
42
|
+
pollInterval?: number;
|
|
43
|
+
batchSize?: number;
|
|
44
|
+
maxConcurrency?: number;
|
|
45
|
+
visibilityTimeout?: number;
|
|
46
|
+
baseDelay?: number;
|
|
47
|
+
maxDelay?: number;
|
|
48
|
+
drainTimeoutMs?: number;
|
|
49
|
+
maxPollBackoff?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface QueueConsumer<T = unknown> {
|
|
52
|
+
register(type: string, handler: JobHandler<T>): void;
|
|
53
|
+
start(): Promise<void>;
|
|
54
|
+
stop(): Promise<void>;
|
|
55
|
+
stats(): Promise<QueueStats>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/job-queue/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,OAAO;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACjC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,CAAC,CAAA;KAAE,GAAG,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC/F;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CAChC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job queue types for async work processing with retry.
|
|
3
|
+
*
|
|
4
|
+
* **Types only** — the DB-backed `DbQueue` and `DbConsumer` implementations
|
|
5
|
+
* that drive the job-queue subsystem live in `@spur/core`. These interfaces
|
|
6
|
+
* are provided here so `EventBus` and other infra components can reference
|
|
7
|
+
* the queue contract without a circular dependency on the DB layer.
|
|
8
|
+
*/
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured JSON logger with levels (trace/debug/info/warn/error/fatal).
|
|
3
|
+
*
|
|
4
|
+
* No external dependencies — console-based implementation.
|
|
5
|
+
*/
|
|
6
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
7
|
+
export interface Logger {
|
|
8
|
+
trace(msg: string, data?: Record<string, unknown>): void;
|
|
9
|
+
debug(msg: string, data?: Record<string, unknown>): void;
|
|
10
|
+
info(msg: string, data?: Record<string, unknown>): void;
|
|
11
|
+
warn(msg: string, data?: Record<string, unknown>): void;
|
|
12
|
+
error(msg: string, data?: Record<string, unknown>): void;
|
|
13
|
+
fatal(msg: string, data?: Record<string, unknown>): void;
|
|
14
|
+
child(context: Record<string, unknown>): Logger;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Mute or unmute all logger console output. Useful for tests.
|
|
18
|
+
*/
|
|
19
|
+
export declare function setLoggerMuted(muted: boolean): void;
|
|
20
|
+
/**
|
|
21
|
+
* Get or create a logger for the given category.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getLogger(category: string): Logger;
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the logger subsystem with a minimum log level.
|
|
26
|
+
*/
|
|
27
|
+
export declare function initializeLogger(level?: LogLevel): void;
|
|
28
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAW/E,MAAM,WAAW,MAAM;IACnB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CACnD;AAwED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEnD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,QAAiB,GAAG,IAAI,CAG/D"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured JSON logger with levels (trace/debug/info/warn/error/fatal).
|
|
3
|
+
*
|
|
4
|
+
* No external dependencies — console-based implementation.
|
|
5
|
+
*/
|
|
6
|
+
const LEVEL_ORDER = {
|
|
7
|
+
trace: 0,
|
|
8
|
+
debug: 1,
|
|
9
|
+
info: 2,
|
|
10
|
+
warn: 3,
|
|
11
|
+
error: 4,
|
|
12
|
+
fatal: 5,
|
|
13
|
+
};
|
|
14
|
+
class ConsoleLogger {
|
|
15
|
+
category;
|
|
16
|
+
minLevel;
|
|
17
|
+
context;
|
|
18
|
+
constructor(category, minLevel = 'info', context = {}) {
|
|
19
|
+
this.category = category;
|
|
20
|
+
this.minLevel = minLevel;
|
|
21
|
+
this.context = { category, ...context };
|
|
22
|
+
}
|
|
23
|
+
log(level, msg, data) {
|
|
24
|
+
if (LEVEL_ORDER[level] < LEVEL_ORDER[this.minLevel])
|
|
25
|
+
return;
|
|
26
|
+
if (globalMuted)
|
|
27
|
+
return;
|
|
28
|
+
const entry = {
|
|
29
|
+
level,
|
|
30
|
+
message: msg,
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
32
|
+
...this.context,
|
|
33
|
+
...data,
|
|
34
|
+
};
|
|
35
|
+
const json = JSON.stringify(entry);
|
|
36
|
+
switch (level) {
|
|
37
|
+
case 'error':
|
|
38
|
+
case 'fatal':
|
|
39
|
+
console.error(json);
|
|
40
|
+
break;
|
|
41
|
+
case 'warn':
|
|
42
|
+
console.warn(json);
|
|
43
|
+
break;
|
|
44
|
+
case 'debug':
|
|
45
|
+
case 'trace':
|
|
46
|
+
console.debug(json);
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
console.log(json);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
trace(msg, data) {
|
|
53
|
+
this.log('trace', msg, data);
|
|
54
|
+
}
|
|
55
|
+
debug(msg, data) {
|
|
56
|
+
this.log('debug', msg, data);
|
|
57
|
+
}
|
|
58
|
+
info(msg, data) {
|
|
59
|
+
this.log('info', msg, data);
|
|
60
|
+
}
|
|
61
|
+
warn(msg, data) {
|
|
62
|
+
this.log('warn', msg, data);
|
|
63
|
+
}
|
|
64
|
+
error(msg, data) {
|
|
65
|
+
this.log('error', msg, data);
|
|
66
|
+
}
|
|
67
|
+
fatal(msg, data) {
|
|
68
|
+
this.log('fatal', msg, data);
|
|
69
|
+
}
|
|
70
|
+
child(context) {
|
|
71
|
+
return new ConsoleLogger(this.category, this.minLevel, { ...this.context, ...context });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const loggers = new Map();
|
|
75
|
+
let globalLevel = 'info';
|
|
76
|
+
let globalMuted = false;
|
|
77
|
+
/**
|
|
78
|
+
* Mute or unmute all logger console output. Useful for tests.
|
|
79
|
+
*/
|
|
80
|
+
export function setLoggerMuted(muted) {
|
|
81
|
+
globalMuted = muted;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get or create a logger for the given category.
|
|
85
|
+
*/
|
|
86
|
+
export function getLogger(category) {
|
|
87
|
+
const existing = loggers.get(category);
|
|
88
|
+
if (existing)
|
|
89
|
+
return existing;
|
|
90
|
+
const logger = new ConsoleLogger(category, globalLevel);
|
|
91
|
+
loggers.set(category, logger);
|
|
92
|
+
return logger;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Initialize the logger subsystem with a minimum log level.
|
|
96
|
+
*/
|
|
97
|
+
export function initializeLogger(level = 'info') {
|
|
98
|
+
globalLevel = level;
|
|
99
|
+
loggers.clear();
|
|
100
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/scheduler/action.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Workers scheduler adapter using Cron Triggers.
|
|
3
|
+
* Uses minimal local type declarations — no @cloudflare/workers-types dependency.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScheduledAction, SchedulerAdapter } from './types';
|
|
6
|
+
interface CfScheduledEvent {
|
|
7
|
+
cron: string;
|
|
8
|
+
scheduledTime: number;
|
|
9
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
10
|
+
}
|
|
11
|
+
interface CfEventContext {
|
|
12
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
13
|
+
}
|
|
14
|
+
export declare class CloudflareSchedulerAdapter implements SchedulerAdapter {
|
|
15
|
+
private readonly entries;
|
|
16
|
+
constructor();
|
|
17
|
+
register(cron: string, action: ScheduledAction): void;
|
|
18
|
+
start(): Promise<void>;
|
|
19
|
+
stop(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Handle a Cloudflare Workers Cron Trigger event.
|
|
22
|
+
* Call this from the Worker's `scheduled()` export.
|
|
23
|
+
*/
|
|
24
|
+
handleScheduledEvent(event: CfScheduledEvent, ctx: CfEventContext): void;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/scheduler/cloudflare.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEjE,UAAU,gBAAgB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED,UAAU,cAAc;IACpB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED,qBAAa,0BAA2B,YAAW,gBAAgB;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;;IAI9D,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IAI/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;;OAGG;IACH,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI;CAM3E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class CloudflareSchedulerAdapter {
|
|
2
|
+
entries = new Map();
|
|
3
|
+
constructor() { }
|
|
4
|
+
register(cron, action) {
|
|
5
|
+
this.entries.set(cron, action);
|
|
6
|
+
}
|
|
7
|
+
async start() {
|
|
8
|
+
// Cloudflare Workers use cron triggers defined in wrangler.toml.
|
|
9
|
+
// The `scheduled()` handler should call `handleScheduledEvent()`.
|
|
10
|
+
}
|
|
11
|
+
async stop() {
|
|
12
|
+
this.entries.clear();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Handle a Cloudflare Workers Cron Trigger event.
|
|
16
|
+
* Call this from the Worker's `scheduled()` export.
|
|
17
|
+
*/
|
|
18
|
+
handleScheduledEvent(event, ctx) {
|
|
19
|
+
const action = this.entries.get(event.cron);
|
|
20
|
+
if (action) {
|
|
21
|
+
ctx.waitUntil(action());
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|