@shipfox/api-triggers 2.0.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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +224 -0
- package/LICENSE +21 -0
- package/README.md +300 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +42 -0
- package/dist/config.js.map +1 -0
- package/dist/core/compute-next-fire-at.d.ts +9 -0
- package/dist/core/compute-next-fire-at.d.ts.map +1 -0
- package/dist/core/compute-next-fire-at.js +28 -0
- package/dist/core/compute-next-fire-at.js.map +1 -0
- package/dist/core/config.d.ts +26 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +68 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/dispatch-integration-event.d.ts +14 -0
- package/dist/core/dispatch-integration-event.d.ts.map +1 -0
- package/dist/core/dispatch-integration-event.js +136 -0
- package/dist/core/dispatch-integration-event.js.map +1 -0
- package/dist/core/drain-cron-schedules.d.ts +30 -0
- package/dist/core/drain-cron-schedules.d.ts.map +1 -0
- package/dist/core/drain-cron-schedules.js +76 -0
- package/dist/core/drain-cron-schedules.js.map +1 -0
- package/dist/core/entities/cron-schedule.d.ts +11 -0
- package/dist/core/entities/cron-schedule.d.ts.map +1 -0
- package/dist/core/entities/cron-schedule.js +3 -0
- package/dist/core/entities/cron-schedule.js.map +1 -0
- package/dist/core/entities/decision.d.ts +23 -0
- package/dist/core/entities/decision.d.ts.map +1 -0
- package/dist/core/entities/decision.js +7 -0
- package/dist/core/entities/decision.js.map +1 -0
- package/dist/core/entities/index.d.ts +3 -0
- package/dist/core/entities/index.d.ts.map +1 -0
- package/dist/core/entities/index.js +3 -0
- package/dist/core/entities/index.js.map +1 -0
- package/dist/core/entities/job-listener-subscription.d.ts +14 -0
- package/dist/core/entities/job-listener-subscription.d.ts.map +1 -0
- package/dist/core/entities/job-listener-subscription.js +3 -0
- package/dist/core/entities/job-listener-subscription.js.map +1 -0
- package/dist/core/entities/received-event.d.ts +28 -0
- package/dist/core/entities/received-event.d.ts.map +1 -0
- package/dist/core/entities/received-event.js +14 -0
- package/dist/core/entities/received-event.js.map +1 -0
- package/dist/core/entities/subscription.d.ts +13 -0
- package/dist/core/entities/subscription.d.ts.map +1 -0
- package/dist/core/entities/subscription.js +3 -0
- package/dist/core/entities/subscription.js.map +1 -0
- package/dist/core/errors.d.ts +25 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +41 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/fire-cron.d.ts +28 -0
- package/dist/core/fire-cron.d.ts.map +1 -0
- package/dist/core/fire-cron.js +85 -0
- package/dist/core/fire-cron.js.map +1 -0
- package/dist/core/fire-manual.d.ts +9 -0
- package/dist/core/fire-manual.d.ts.map +1 -0
- package/dist/core/fire-manual.js +87 -0
- package/dist/core/fire-manual.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/record-trigger-history.d.ts +35 -0
- package/dist/core/record-trigger-history.d.ts.map +1 -0
- package/dist/core/record-trigger-history.js +75 -0
- package/dist/core/record-trigger-history.js.map +1 -0
- package/dist/core/route-event-to-job-listeners.d.ts +31 -0
- package/dist/core/route-event-to-job-listeners.d.ts.map +1 -0
- package/dist/core/route-event-to-job-listeners.js +140 -0
- package/dist/core/route-event-to-job-listeners.js.map +1 -0
- package/dist/db/cron-schedules.d.ts +36 -0
- package/dist/db/cron-schedules.d.ts.map +1 -0
- package/dist/db/cron-schedules.js +104 -0
- package/dist/db/cron-schedules.js.map +1 -0
- package/dist/db/db.d.ts +2515 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +28 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/event-history.d.ts +50 -0
- package/dist/db/event-history.d.ts.map +1 -0
- package/dist/db/event-history.js +207 -0
- package/dist/db/event-history.js.map +1 -0
- package/dist/db/event-queries.d.ts +38 -0
- package/dist/db/event-queries.d.ts.map +1 -0
- package/dist/db/event-queries.js +78 -0
- package/dist/db/event-queries.js.map +1 -0
- package/dist/db/index.d.ts +11 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +14 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/job-listener-subscriptions.d.ts +24 -0
- package/dist/db/job-listener-subscriptions.d.ts.map +1 -0
- package/dist/db/job-listener-subscriptions.js +69 -0
- package/dist/db/job-listener-subscriptions.js.map +1 -0
- package/dist/db/received-events.d.ts +7 -0
- package/dist/db/received-events.d.ts.map +1 -0
- package/dist/db/received-events.js +11 -0
- package/dist/db/received-events.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/cron-schedules.d.ts +148 -0
- package/dist/db/schema/cron-schedules.d.ts.map +1 -0
- package/dist/db/schema/cron-schedules.js +39 -0
- package/dist/db/schema/cron-schedules.js.map +1 -0
- package/dist/db/schema/decisions.d.ts +284 -0
- package/dist/db/schema/decisions.d.ts.map +1 -0
- package/dist/db/schema/decisions.js +70 -0
- package/dist/db/schema/decisions.js.map +1 -0
- package/dist/db/schema/job-listener-subscriptions.d.ts +185 -0
- package/dist/db/schema/job-listener-subscriptions.d.ts.map +1 -0
- package/dist/db/schema/job-listener-subscriptions.js +41 -0
- package/dist/db/schema/job-listener-subscriptions.js.map +1 -0
- package/dist/db/schema/outbox.d.ts +195 -0
- package/dist/db/schema/outbox.d.ts.map +1 -0
- package/dist/db/schema/outbox.js +5 -0
- package/dist/db/schema/outbox.js.map +1 -0
- package/dist/db/schema/received-events.d.ts +544 -0
- package/dist/db/schema/received-events.d.ts.map +1 -0
- package/dist/db/schema/received-events.js +86 -0
- package/dist/db/schema/received-events.js.map +1 -0
- package/dist/db/schema/subscriptions.d.ts +182 -0
- package/dist/db/schema/subscriptions.d.ts.map +1 -0
- package/dist/db/schema/subscriptions.js +39 -0
- package/dist/db/schema/subscriptions.js.map +1 -0
- package/dist/db/subscriptions.d.ts +26 -0
- package/dist/db/subscriptions.d.ts.map +1 -0
- package/dist/db/subscriptions.js +103 -0
- package/dist/db/subscriptions.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +3 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +4 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +15 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +32 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/metrics/service.d.ts +2 -0
- package/dist/metrics/service.d.ts.map +1 -0
- package/dist/metrics/service.js +15 -0
- package/dist/metrics/service.js.map +1 -0
- package/dist/presentation/dto/trigger-events.d.ts +7 -0
- package/dist/presentation/dto/trigger-events.d.ts.map +1 -0
- package/dist/presentation/dto/trigger-events.js +47 -0
- package/dist/presentation/dto/trigger-events.js.map +1 -0
- package/dist/presentation/index.d.ts +3 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +4 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/routes/fire-manual.d.ts +2 -0
- package/dist/presentation/routes/fire-manual.d.ts.map +1 -0
- package/dist/presentation/routes/fire-manual.js +71 -0
- package/dist/presentation/routes/fire-manual.js.map +1 -0
- package/dist/presentation/routes/get-trigger-event.d.ts +2 -0
- package/dist/presentation/routes/get-trigger-event.d.ts.map +1 -0
- package/dist/presentation/routes/get-trigger-event.js +37 -0
- package/dist/presentation/routes/get-trigger-event.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +3 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +27 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/list-trigger-event-facets.d.ts +2 -0
- package/dist/presentation/routes/list-trigger-event-facets.d.ts.map +1 -0
- package/dist/presentation/routes/list-trigger-event-facets.js +29 -0
- package/dist/presentation/routes/list-trigger-event-facets.js.map +1 -0
- package/dist/presentation/routes/list-trigger-events.d.ts +2 -0
- package/dist/presentation/routes/list-trigger-events.d.ts.map +1 -0
- package/dist/presentation/routes/list-trigger-events.js +56 -0
- package/dist/presentation/routes/list-trigger-events.js.map +1 -0
- package/dist/presentation/subscribers/index.d.ts +6 -0
- package/dist/presentation/subscribers/index.d.ts.map +1 -0
- package/dist/presentation/subscribers/index.js +7 -0
- package/dist/presentation/subscribers/index.js.map +1 -0
- package/dist/presentation/subscribers/on-definition-deleted.d.ts +3 -0
- package/dist/presentation/subscribers/on-definition-deleted.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-definition-deleted.js +8 -0
- package/dist/presentation/subscribers/on-definition-deleted.js.map +1 -0
- package/dist/presentation/subscribers/on-definition-resolved.d.ts +3 -0
- package/dist/presentation/subscribers/on-definition-resolved.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-definition-resolved.js +11 -0
- package/dist/presentation/subscribers/on-definition-resolved.js.map +1 -0
- package/dist/presentation/subscribers/on-integration-event-received.d.ts +4 -0
- package/dist/presentation/subscribers/on-integration-event-received.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-integration-event-received.js +17 -0
- package/dist/presentation/subscribers/on-integration-event-received.js.map +1 -0
- package/dist/presentation/subscribers/on-job-activated.d.ts +3 -0
- package/dist/presentation/subscribers/on-job-activated.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-job-activated.js +13 -0
- package/dist/presentation/subscribers/on-job-activated.js.map +1 -0
- package/dist/presentation/subscribers/on-job-terminated.d.ts +3 -0
- package/dist/presentation/subscribers/on-job-terminated.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-job-terminated.js +6 -0
- package/dist/presentation/subscribers/on-job-terminated.js.map +1 -0
- package/dist/temporal/activities/drain-cron-batch.d.ts +4 -0
- package/dist/temporal/activities/drain-cron-batch.d.ts.map +1 -0
- package/dist/temporal/activities/drain-cron-batch.js +20 -0
- package/dist/temporal/activities/drain-cron-batch.js.map +1 -0
- package/dist/temporal/activities/index.d.ts +10 -0
- package/dist/temporal/activities/index.d.ts.map +1 -0
- package/dist/temporal/activities/index.js +15 -0
- package/dist/temporal/activities/index.js.map +1 -0
- package/dist/temporal/activities/prune-trigger-events.d.ts +4 -0
- package/dist/temporal/activities/prune-trigger-events.d.ts.map +1 -0
- package/dist/temporal/activities/prune-trigger-events.js +11 -0
- package/dist/temporal/activities/prune-trigger-events.js.map +1 -0
- package/dist/temporal/constants.d.ts +7 -0
- package/dist/temporal/constants.d.ts.map +1 -0
- package/dist/temporal/constants.js +7 -0
- package/dist/temporal/constants.js.map +1 -0
- package/dist/temporal/workflows/cron-tick-cron.d.ts +9 -0
- package/dist/temporal/workflows/cron-tick-cron.d.ts.map +1 -0
- package/dist/temporal/workflows/cron-tick-cron.js +54 -0
- package/dist/temporal/workflows/cron-tick-cron.js.map +1 -0
- package/dist/temporal/workflows/index.d.ts +3 -0
- package/dist/temporal/workflows/index.d.ts.map +1 -0
- package/dist/temporal/workflows/index.js +4 -0
- package/dist/temporal/workflows/index.js.map +1 -0
- package/dist/temporal/workflows/prune-trigger-events-cron.d.ts +2 -0
- package/dist/temporal/workflows/prune-trigger-events-cron.d.ts.map +1 -0
- package/dist/temporal/workflows/prune-trigger-events-cron.js +18 -0
- package/dist/temporal/workflows/prune-trigger-events-cron.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +109 -0
- package/drizzle/meta/0000_snapshot.json +905 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +14 -0
- package/package.json +83 -0
- package/src/config.test.ts +33 -0
- package/src/config.ts +53 -0
- package/src/core/compute-next-fire-at.test.ts +69 -0
- package/src/core/compute-next-fire-at.ts +37 -0
- package/src/core/config.test.ts +213 -0
- package/src/core/config.ts +86 -0
- package/src/core/dispatch-integration-event.history-failure.test.ts +66 -0
- package/src/core/dispatch-integration-event.test.ts +1006 -0
- package/src/core/dispatch-integration-event.ts +150 -0
- package/src/core/drain-cron-schedules.test.ts +265 -0
- package/src/core/drain-cron-schedules.ts +90 -0
- package/src/core/entities/cron-schedule.ts +10 -0
- package/src/core/entities/decision.ts +24 -0
- package/src/core/entities/index.ts +5 -0
- package/src/core/entities/job-listener-subscription.ts +14 -0
- package/src/core/entities/received-event.ts +36 -0
- package/src/core/entities/subscription.ts +12 -0
- package/src/core/errors.ts +63 -0
- package/src/core/fire-cron.test.ts +146 -0
- package/src/core/fire-cron.ts +98 -0
- package/src/core/fire-manual.test.ts +157 -0
- package/src/core/fire-manual.ts +92 -0
- package/src/core/index.ts +34 -0
- package/src/core/record-trigger-history.test.ts +159 -0
- package/src/core/record-trigger-history.ts +145 -0
- package/src/core/route-event-to-job-listeners.test.ts +369 -0
- package/src/core/route-event-to-job-listeners.ts +184 -0
- package/src/db/cron-schedules.test.ts +358 -0
- package/src/db/cron-schedules.ts +163 -0
- package/src/db/db.ts +31 -0
- package/src/db/event-history.test.ts +421 -0
- package/src/db/event-history.ts +279 -0
- package/src/db/event-queries.ts +140 -0
- package/src/db/index.ts +51 -0
- package/src/db/job-listener-subscriptions.test.ts +270 -0
- package/src/db/job-listener-subscriptions.ts +133 -0
- package/src/db/received-events.ts +16 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/cron-schedules.ts +37 -0
- package/src/db/schema/decisions.test.ts +279 -0
- package/src/db/schema/decisions.ts +77 -0
- package/src/db/schema/job-listener-subscriptions.ts +65 -0
- package/src/db/schema/outbox.ts +4 -0
- package/src/db/schema/received-events.test.ts +135 -0
- package/src/db/schema/received-events.ts +93 -0
- package/src/db/schema/subscriptions.ts +46 -0
- package/src/db/subscriptions.test.ts +340 -0
- package/src/db/subscriptions.ts +179 -0
- package/src/index.ts +108 -0
- package/src/metrics/index.ts +8 -0
- package/src/metrics/instance.ts +33 -0
- package/src/metrics/service.ts +18 -0
- package/src/presentation/dto/trigger-events.test.ts +144 -0
- package/src/presentation/dto/trigger-events.ts +60 -0
- package/src/presentation/index.ts +6 -0
- package/src/presentation/routes/fire-manual.test.ts +118 -0
- package/src/presentation/routes/fire-manual.ts +70 -0
- package/src/presentation/routes/get-trigger-event.test.ts +184 -0
- package/src/presentation/routes/get-trigger-event.ts +37 -0
- package/src/presentation/routes/index.ts +21 -0
- package/src/presentation/routes/list-trigger-event-facets.test.ts +116 -0
- package/src/presentation/routes/list-trigger-event-facets.ts +29 -0
- package/src/presentation/routes/list-trigger-events.test.ts +379 -0
- package/src/presentation/routes/list-trigger-events.ts +68 -0
- package/src/presentation/subscribers/index.ts +5 -0
- package/src/presentation/subscribers/on-definition-deleted.test.ts +42 -0
- package/src/presentation/subscribers/on-definition-deleted.ts +6 -0
- package/src/presentation/subscribers/on-definition-resolved.test.ts +67 -0
- package/src/presentation/subscribers/on-definition-resolved.ts +11 -0
- package/src/presentation/subscribers/on-integration-event-received.test.ts +53 -0
- package/src/presentation/subscribers/on-integration-event-received.ts +21 -0
- package/src/presentation/subscribers/on-job-activated.ts +14 -0
- package/src/presentation/subscribers/on-job-terminated.ts +6 -0
- package/src/temporal/activities/drain-cron-batch.ts +20 -0
- package/src/temporal/activities/index.ts +15 -0
- package/src/temporal/activities/prune-trigger-events.test.ts +78 -0
- package/src/temporal/activities/prune-trigger-events.ts +9 -0
- package/src/temporal/constants.ts +7 -0
- package/src/temporal/workflows/cron-tick-cron.ts +56 -0
- package/src/temporal/workflows/index.ts +2 -0
- package/src/temporal/workflows/prune-trigger-events-cron.ts +17 -0
- package/test/env.ts +8 -0
- package/test/factories/cron-schedule.ts +34 -0
- package/test/factories/decision.ts +49 -0
- package/test/factories/job-listener-subscription.ts +42 -0
- package/test/factories/received-event.ts +49 -0
- package/test/factories/subscription.ts +38 -0
- package/test/globalSetup.ts +20 -0
- package/test/index.ts +5 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +11 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"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"}
|
package/dist/db/db.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { drizzle } from '@shipfox/node-drizzle';
|
|
2
|
+
import { pgClient } from '@shipfox/node-postgres';
|
|
3
|
+
import { triggersCronSchedules } from './schema/cron-schedules.js';
|
|
4
|
+
import { triggersDecisions } from './schema/decisions.js';
|
|
5
|
+
import { jobListenerSubscriptions } from './schema/job-listener-subscriptions.js';
|
|
6
|
+
import { triggersOutbox } from './schema/outbox.js';
|
|
7
|
+
import { triggersReceivedEvents } from './schema/received-events.js';
|
|
8
|
+
import { triggerSubscriptions } from './schema/subscriptions.js';
|
|
9
|
+
export const schema = {
|
|
10
|
+
triggersCronSchedules,
|
|
11
|
+
jobListenerSubscriptions,
|
|
12
|
+
triggerSubscriptions,
|
|
13
|
+
triggersOutbox,
|
|
14
|
+
triggersReceivedEvents,
|
|
15
|
+
triggersDecisions
|
|
16
|
+
};
|
|
17
|
+
let _db;
|
|
18
|
+
export function db() {
|
|
19
|
+
if (!_db) _db = drizzle(pgClient(), {
|
|
20
|
+
schema
|
|
21
|
+
});
|
|
22
|
+
return _db;
|
|
23
|
+
}
|
|
24
|
+
export function closeDb() {
|
|
25
|
+
_db = undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/db/db.ts"],"sourcesContent":["import {drizzle, type NodePgDatabase} from '@shipfox/node-drizzle';\nimport {pgClient} from '@shipfox/node-postgres';\nimport {triggersCronSchedules} from './schema/cron-schedules.js';\nimport {triggersDecisions} from './schema/decisions.js';\nimport {jobListenerSubscriptions} from './schema/job-listener-subscriptions.js';\nimport {triggersOutbox} from './schema/outbox.js';\nimport {triggersReceivedEvents} from './schema/received-events.js';\nimport {triggerSubscriptions} from './schema/subscriptions.js';\n\nexport const schema = {\n triggersCronSchedules,\n jobListenerSubscriptions,\n triggerSubscriptions,\n triggersOutbox,\n triggersReceivedEvents,\n triggersDecisions,\n};\n\nlet _db: NodePgDatabase<typeof schema> | undefined;\n\nexport function db() {\n if (!_db) _db = drizzle(pgClient(), {schema});\n return _db;\n}\n\nexport type Tx = Parameters<Parameters<ReturnType<typeof db>['transaction']>[0]>[0];\nexport type Executor = ReturnType<typeof db> | Tx;\n\nexport function closeDb(): void {\n _db = undefined;\n}\n"],"names":["drizzle","pgClient","triggersCronSchedules","triggersDecisions","jobListenerSubscriptions","triggersOutbox","triggersReceivedEvents","triggerSubscriptions","schema","_db","db","closeDb","undefined"],"mappings":"AAAA,SAAQA,OAAO,QAA4B,wBAAwB;AACnE,SAAQC,QAAQ,QAAO,yBAAyB;AAChD,SAAQC,qBAAqB,QAAO,6BAA6B;AACjE,SAAQC,iBAAiB,QAAO,wBAAwB;AACxD,SAAQC,wBAAwB,QAAO,yCAAyC;AAChF,SAAQC,cAAc,QAAO,qBAAqB;AAClD,SAAQC,sBAAsB,QAAO,8BAA8B;AACnE,SAAQC,oBAAoB,QAAO,4BAA4B;AAE/D,OAAO,MAAMC,SAAS;IACpBN;IACAE;IACAG;IACAF;IACAC;IACAH;AACF,EAAE;AAEF,IAAIM;AAEJ,OAAO,SAASC;IACd,IAAI,CAACD,KAAKA,MAAMT,QAAQC,YAAY;QAACO;IAAM;IAC3C,OAAOC;AACT;AAKA,OAAO,SAASE;IACdF,MAAMG;AACR"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { JobListenerSubscription } from '#core/entities/job-listener-subscription.js';
|
|
2
|
+
import type { TriggerEventOrigin } from '#core/entities/received-event.js';
|
|
3
|
+
import type { TriggerSubscription } from '#core/entities/subscription.js';
|
|
4
|
+
export interface InsertReceivedEventParams {
|
|
5
|
+
eventRef: string;
|
|
6
|
+
origin: TriggerEventOrigin;
|
|
7
|
+
workspaceId: string;
|
|
8
|
+
provider: string | null;
|
|
9
|
+
source: string;
|
|
10
|
+
event: string;
|
|
11
|
+
deliveryId: string | null;
|
|
12
|
+
connectionId: string | null;
|
|
13
|
+
connectionName: string | null;
|
|
14
|
+
payload: Record<string, unknown> | null;
|
|
15
|
+
receivedAt: Date;
|
|
16
|
+
}
|
|
17
|
+
export declare function insertReceivedEvent(params: InsertReceivedEventParams): Promise<string>;
|
|
18
|
+
export declare function markReceivedEventDiscarded(id: string): Promise<void>;
|
|
19
|
+
export declare function markReceivedEventRouted(id: string, matchedCount: number): Promise<void>;
|
|
20
|
+
export declare function markReceivedEventFailed(id: string, matchedCount: number): Promise<void>;
|
|
21
|
+
export declare function markReceivedEventErrored(id: string, matchedCount: number): Promise<void>;
|
|
22
|
+
export interface UpsertTriggeredDecisionParams {
|
|
23
|
+
receivedEventId: string;
|
|
24
|
+
subscription: TriggerSubscription;
|
|
25
|
+
run: {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export declare function upsertTriggeredDecision(params: UpsertTriggeredDecisionParams): Promise<void>;
|
|
31
|
+
export interface UpsertFailedDecisionParams {
|
|
32
|
+
receivedEventId: string;
|
|
33
|
+
subscription: TriggerSubscription;
|
|
34
|
+
reason: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function upsertFilterErrorDecision(params: UpsertFailedDecisionParams): Promise<void>;
|
|
37
|
+
export declare function upsertDispatchErrorDecision(params: UpsertFailedDecisionParams): Promise<void>;
|
|
38
|
+
export interface UpsertListenerTriggeredDecisionParams {
|
|
39
|
+
receivedEventId: string;
|
|
40
|
+
subscription: JobListenerSubscription;
|
|
41
|
+
}
|
|
42
|
+
export declare function upsertListenerTriggeredDecision(params: UpsertListenerTriggeredDecisionParams): Promise<void>;
|
|
43
|
+
export interface UpsertListenerFailedDecisionParams {
|
|
44
|
+
receivedEventId: string;
|
|
45
|
+
subscription: JobListenerSubscription;
|
|
46
|
+
reason: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function upsertListenerFilterErrorDecision(params: UpsertListenerFailedDecisionParams): Promise<void>;
|
|
49
|
+
export declare function upsertListenerDispatchErrorDecision(params: UpsertListenerFailedDecisionParams): Promise<void>;
|
|
50
|
+
//# sourceMappingURL=event-history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-history.d.ts","sourceRoot":"","sources":["../../src/db/event-history.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,6CAA6C,CAAC;AACzF,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAKxE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,UAAU,EAAE,IAAI,CAAC;CAClB;AAID,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B5F;AAED,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E;AAED,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7F;AAID,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7F;AAOD,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB9F;AAED,MAAM,WAAW,6BAA6B;IAC5C,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;IAClC,GAAG,EAAE;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;CACjC;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjG;AAGD,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAEf;AA6BD,MAAM,WAAW,qCAAqC;IACpD,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,uBAAuB,CAAC;CACvC;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,MAAM,WAAW,kCAAkC;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,uBAAuB,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,kCAAkC,GACzC,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,mCAAmC,CACvD,MAAM,EAAE,kCAAkC,GACzC,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { and, eq, ne, notInArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { db } from './db.js';
|
|
3
|
+
import { triggersDecisions } from './schema/decisions.js';
|
|
4
|
+
import { triggersReceivedEvents } from './schema/received-events.js';
|
|
5
|
+
// `event_ref` is unique and delivery is at-least-once, so the same event can
|
|
6
|
+
// arrive twice; either path returns the row id used to attach decisions.
|
|
7
|
+
export async function insertReceivedEvent(params) {
|
|
8
|
+
const [inserted] = await db().insert(triggersReceivedEvents).values({
|
|
9
|
+
eventRef: params.eventRef,
|
|
10
|
+
origin: params.origin,
|
|
11
|
+
workspaceId: params.workspaceId,
|
|
12
|
+
provider: params.provider,
|
|
13
|
+
source: params.source,
|
|
14
|
+
event: params.event,
|
|
15
|
+
deliveryId: params.deliveryId,
|
|
16
|
+
connectionId: params.connectionId,
|
|
17
|
+
connectionName: params.connectionName,
|
|
18
|
+
payload: params.payload,
|
|
19
|
+
receivedAt: params.receivedAt
|
|
20
|
+
}).onConflictDoNothing({
|
|
21
|
+
target: triggersReceivedEvents.eventRef
|
|
22
|
+
}).returning({
|
|
23
|
+
id: triggersReceivedEvents.id
|
|
24
|
+
});
|
|
25
|
+
if (inserted) return inserted.id;
|
|
26
|
+
const [existing] = await db().select({
|
|
27
|
+
id: triggersReceivedEvents.id
|
|
28
|
+
}).from(triggersReceivedEvents).where(eq(triggersReceivedEvents.eventRef, params.eventRef));
|
|
29
|
+
if (!existing) {
|
|
30
|
+
throw new Error(`received_events row missing after conflict for event_ref ${params.eventRef}`);
|
|
31
|
+
}
|
|
32
|
+
return existing.id;
|
|
33
|
+
}
|
|
34
|
+
export async function markReceivedEventDiscarded(id) {
|
|
35
|
+
await db().update(triggersReceivedEvents).set({
|
|
36
|
+
outcome: 'discarded',
|
|
37
|
+
matchedCount: 0,
|
|
38
|
+
processedAt: new Date()
|
|
39
|
+
}).where(and(eq(triggersReceivedEvents.id, id), notInArray(triggersReceivedEvents.outcome, [
|
|
40
|
+
'routed',
|
|
41
|
+
'errored'
|
|
42
|
+
])));
|
|
43
|
+
}
|
|
44
|
+
export async function markReceivedEventRouted(id, matchedCount) {
|
|
45
|
+
await db().update(triggersReceivedEvents).set({
|
|
46
|
+
outcome: 'routed',
|
|
47
|
+
matchedCount,
|
|
48
|
+
processedAt: new Date()
|
|
49
|
+
}).where(eq(triggersReceivedEvents.id, id));
|
|
50
|
+
}
|
|
51
|
+
// No processedAt: `failed` is transient. Under at-least-once dispatch, a late
|
|
52
|
+
// failure must not clobber a sibling invocation's terminal outcome.
|
|
53
|
+
export async function markReceivedEventFailed(id, matchedCount) {
|
|
54
|
+
await db().update(triggersReceivedEvents).set({
|
|
55
|
+
outcome: 'failed',
|
|
56
|
+
matchedCount
|
|
57
|
+
}).where(and(eq(triggersReceivedEvents.id, id), notInArray(triggersReceivedEvents.outcome, [
|
|
58
|
+
'routed',
|
|
59
|
+
'discarded',
|
|
60
|
+
'errored'
|
|
61
|
+
])));
|
|
62
|
+
}
|
|
63
|
+
// Terminal outcome for a fan-out that produced no new run this pass. The CASE is a
|
|
64
|
+
// cross-attempt safety net: under at-least-once delivery a prior attempt may already have
|
|
65
|
+
// created a run (its decision row is `triggered`, which is never downgraded), so promote the
|
|
66
|
+
// event to `routed` rather than falsely record `errored`. Guarded so it never downgrades a
|
|
67
|
+
// terminal success.
|
|
68
|
+
export async function markReceivedEventErrored(id, matchedCount) {
|
|
69
|
+
await db().update(triggersReceivedEvents).set({
|
|
70
|
+
outcome: sql`CASE WHEN EXISTS (
|
|
71
|
+
SELECT 1
|
|
72
|
+
FROM ${triggersDecisions}
|
|
73
|
+
WHERE ${triggersDecisions.receivedEventId} = ${triggersReceivedEvents.id}
|
|
74
|
+
AND ${triggersDecisions.decision} = 'triggered'
|
|
75
|
+
) THEN 'routed' ELSE 'errored' END`,
|
|
76
|
+
matchedCount,
|
|
77
|
+
processedAt: new Date()
|
|
78
|
+
}).where(and(eq(triggersReceivedEvents.id, id), notInArray(triggersReceivedEvents.outcome, [
|
|
79
|
+
'routed',
|
|
80
|
+
'discarded'
|
|
81
|
+
])));
|
|
82
|
+
}
|
|
83
|
+
export async function upsertTriggeredDecision(params) {
|
|
84
|
+
await db().insert(triggersDecisions).values({
|
|
85
|
+
receivedEventId: params.receivedEventId,
|
|
86
|
+
subscriptionKind: 'trigger',
|
|
87
|
+
subscriptionId: params.subscription.id,
|
|
88
|
+
subscriptionName: params.subscription.name,
|
|
89
|
+
workflowDefinitionId: params.subscription.workflowDefinitionId,
|
|
90
|
+
projectId: params.subscription.projectId,
|
|
91
|
+
decision: 'triggered',
|
|
92
|
+
runId: params.run.id,
|
|
93
|
+
runName: params.run.name,
|
|
94
|
+
reason: null
|
|
95
|
+
}).onConflictDoUpdate({
|
|
96
|
+
target: [
|
|
97
|
+
triggersDecisions.receivedEventId,
|
|
98
|
+
triggersDecisions.subscriptionKind,
|
|
99
|
+
triggersDecisions.subscriptionId
|
|
100
|
+
],
|
|
101
|
+
set: {
|
|
102
|
+
decision: 'triggered',
|
|
103
|
+
runId: params.run.id,
|
|
104
|
+
runName: params.run.name,
|
|
105
|
+
reason: null
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
export async function upsertFilterErrorDecision(params) {
|
|
110
|
+
await upsertFailedDecision(params, 'filter-error');
|
|
111
|
+
}
|
|
112
|
+
// A created run is ground truth. A later retry failure must not erase it.
|
|
113
|
+
export async function upsertDispatchErrorDecision(params) {
|
|
114
|
+
await upsertFailedDecision(params, 'dispatch-error');
|
|
115
|
+
}
|
|
116
|
+
async function upsertFailedDecision(params, decision) {
|
|
117
|
+
await db().insert(triggersDecisions).values({
|
|
118
|
+
receivedEventId: params.receivedEventId,
|
|
119
|
+
subscriptionKind: 'trigger',
|
|
120
|
+
subscriptionId: params.subscription.id,
|
|
121
|
+
subscriptionName: params.subscription.name,
|
|
122
|
+
workflowDefinitionId: params.subscription.workflowDefinitionId,
|
|
123
|
+
projectId: params.subscription.projectId,
|
|
124
|
+
decision,
|
|
125
|
+
reason: params.reason
|
|
126
|
+
}).onConflictDoUpdate({
|
|
127
|
+
target: [
|
|
128
|
+
triggersDecisions.receivedEventId,
|
|
129
|
+
triggersDecisions.subscriptionKind,
|
|
130
|
+
triggersDecisions.subscriptionId
|
|
131
|
+
],
|
|
132
|
+
set: {
|
|
133
|
+
decision,
|
|
134
|
+
reason: params.reason,
|
|
135
|
+
runId: null,
|
|
136
|
+
runName: null
|
|
137
|
+
},
|
|
138
|
+
setWhere: ne(triggersDecisions.decision, 'triggered')
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export async function upsertListenerTriggeredDecision(params) {
|
|
142
|
+
await db().insert(triggersDecisions).values({
|
|
143
|
+
...listenerDecisionIdentity(params),
|
|
144
|
+
decision: 'triggered',
|
|
145
|
+
runId: null,
|
|
146
|
+
runName: null,
|
|
147
|
+
reason: null
|
|
148
|
+
}).onConflictDoUpdate({
|
|
149
|
+
target: [
|
|
150
|
+
triggersDecisions.receivedEventId,
|
|
151
|
+
triggersDecisions.subscriptionKind,
|
|
152
|
+
triggersDecisions.subscriptionId
|
|
153
|
+
],
|
|
154
|
+
set: {
|
|
155
|
+
decision: 'triggered',
|
|
156
|
+
runId: null,
|
|
157
|
+
runName: null,
|
|
158
|
+
reason: null
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
export async function upsertListenerFilterErrorDecision(params) {
|
|
163
|
+
await upsertListenerFailedDecision(params, 'filter-error');
|
|
164
|
+
}
|
|
165
|
+
export async function upsertListenerDispatchErrorDecision(params) {
|
|
166
|
+
await upsertListenerFailedDecision(params, 'dispatch-error');
|
|
167
|
+
}
|
|
168
|
+
async function upsertListenerFailedDecision(params, decision) {
|
|
169
|
+
await db().insert(triggersDecisions).values({
|
|
170
|
+
...listenerDecisionIdentity(params),
|
|
171
|
+
decision,
|
|
172
|
+
reason: params.reason
|
|
173
|
+
}).onConflictDoUpdate({
|
|
174
|
+
target: [
|
|
175
|
+
triggersDecisions.receivedEventId,
|
|
176
|
+
triggersDecisions.subscriptionKind,
|
|
177
|
+
triggersDecisions.subscriptionId
|
|
178
|
+
],
|
|
179
|
+
set: {
|
|
180
|
+
decision,
|
|
181
|
+
reason: params.reason,
|
|
182
|
+
runId: null,
|
|
183
|
+
runName: null
|
|
184
|
+
},
|
|
185
|
+
setWhere: ne(triggersDecisions.decision, 'triggered')
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function listenerDecisionIdentity(params) {
|
|
189
|
+
const { subscription } = params;
|
|
190
|
+
return {
|
|
191
|
+
receivedEventId: params.receivedEventId,
|
|
192
|
+
subscriptionKind: 'listener',
|
|
193
|
+
subscriptionId: subscription.id,
|
|
194
|
+
subscriptionName: listenerSubscriptionName(subscription),
|
|
195
|
+
workflowDefinitionId: null,
|
|
196
|
+
projectId: null,
|
|
197
|
+
workflowRunId: subscription.workflowRunId,
|
|
198
|
+
jobId: subscription.jobId,
|
|
199
|
+
matcherKind: subscription.kind,
|
|
200
|
+
matcherOrdinal: subscription.matcherOrdinal
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function listenerSubscriptionName(subscription) {
|
|
204
|
+
return `listener ${subscription.kind}[${subscription.matcherOrdinal}] ${subscription.source}/${subscription.event}`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//# sourceMappingURL=event-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/db/event-history.ts"],"sourcesContent":["import {and, eq, ne, notInArray, sql} from 'drizzle-orm';\nimport type {JobListenerSubscription} from '#core/entities/job-listener-subscription.js';\nimport type {TriggerEventOrigin} from '#core/entities/received-event.js';\nimport type {TriggerSubscription} from '#core/entities/subscription.js';\nimport {db} from './db.js';\nimport {triggersDecisions} from './schema/decisions.js';\nimport {triggersReceivedEvents} from './schema/received-events.js';\n\nexport interface InsertReceivedEventParams {\n eventRef: string;\n origin: TriggerEventOrigin;\n workspaceId: string;\n provider: string | null;\n source: string;\n event: string;\n deliveryId: string | null;\n connectionId: string | null;\n connectionName: string | null;\n payload: Record<string, unknown> | null;\n receivedAt: Date;\n}\n\n// `event_ref` is unique and delivery is at-least-once, so the same event can\n// arrive twice; either path returns the row id used to attach decisions.\nexport async function insertReceivedEvent(params: InsertReceivedEventParams): Promise<string> {\n const [inserted] = await db()\n .insert(triggersReceivedEvents)\n .values({\n eventRef: params.eventRef,\n origin: params.origin,\n workspaceId: params.workspaceId,\n provider: params.provider,\n source: params.source,\n event: params.event,\n deliveryId: params.deliveryId,\n connectionId: params.connectionId,\n connectionName: params.connectionName,\n payload: params.payload,\n receivedAt: params.receivedAt,\n })\n .onConflictDoNothing({target: triggersReceivedEvents.eventRef})\n .returning({id: triggersReceivedEvents.id});\n if (inserted) return inserted.id;\n\n const [existing] = await db()\n .select({id: triggersReceivedEvents.id})\n .from(triggersReceivedEvents)\n .where(eq(triggersReceivedEvents.eventRef, params.eventRef));\n if (!existing) {\n throw new Error(`received_events row missing after conflict for event_ref ${params.eventRef}`);\n }\n return existing.id;\n}\n\nexport async function markReceivedEventDiscarded(id: string): Promise<void> {\n await db()\n .update(triggersReceivedEvents)\n .set({outcome: 'discarded', matchedCount: 0, processedAt: new Date()})\n .where(\n and(\n eq(triggersReceivedEvents.id, id),\n notInArray(triggersReceivedEvents.outcome, ['routed', 'errored']),\n ),\n );\n}\n\nexport async function markReceivedEventRouted(id: string, matchedCount: number): Promise<void> {\n await db()\n .update(triggersReceivedEvents)\n .set({outcome: 'routed', matchedCount, processedAt: new Date()})\n .where(eq(triggersReceivedEvents.id, id));\n}\n\n// No processedAt: `failed` is transient. Under at-least-once dispatch, a late\n// failure must not clobber a sibling invocation's terminal outcome.\nexport async function markReceivedEventFailed(id: string, matchedCount: number): Promise<void> {\n await db()\n .update(triggersReceivedEvents)\n .set({outcome: 'failed', matchedCount})\n .where(\n and(\n eq(triggersReceivedEvents.id, id),\n notInArray(triggersReceivedEvents.outcome, ['routed', 'discarded', 'errored']),\n ),\n );\n}\n\n// Terminal outcome for a fan-out that produced no new run this pass. The CASE is a\n// cross-attempt safety net: under at-least-once delivery a prior attempt may already have\n// created a run (its decision row is `triggered`, which is never downgraded), so promote the\n// event to `routed` rather than falsely record `errored`. Guarded so it never downgrades a\n// terminal success.\nexport async function markReceivedEventErrored(id: string, matchedCount: number): Promise<void> {\n await db()\n .update(triggersReceivedEvents)\n .set({\n outcome: sql`CASE WHEN EXISTS (\n SELECT 1\n FROM ${triggersDecisions}\n WHERE ${triggersDecisions.receivedEventId} = ${triggersReceivedEvents.id}\n AND ${triggersDecisions.decision} = 'triggered'\n ) THEN 'routed' ELSE 'errored' END`,\n matchedCount,\n processedAt: new Date(),\n })\n .where(\n and(\n eq(triggersReceivedEvents.id, id),\n notInArray(triggersReceivedEvents.outcome, ['routed', 'discarded']),\n ),\n );\n}\n\nexport interface UpsertTriggeredDecisionParams {\n receivedEventId: string;\n subscription: TriggerSubscription;\n run: {id: string; name: string};\n}\n\nexport async function upsertTriggeredDecision(\n params: UpsertTriggeredDecisionParams,\n): Promise<void> {\n await db()\n .insert(triggersDecisions)\n .values({\n receivedEventId: params.receivedEventId,\n subscriptionKind: 'trigger',\n subscriptionId: params.subscription.id,\n subscriptionName: params.subscription.name,\n workflowDefinitionId: params.subscription.workflowDefinitionId,\n projectId: params.subscription.projectId,\n decision: 'triggered',\n runId: params.run.id,\n runName: params.run.name,\n reason: null,\n })\n .onConflictDoUpdate({\n target: [\n triggersDecisions.receivedEventId,\n triggersDecisions.subscriptionKind,\n triggersDecisions.subscriptionId,\n ],\n set: {decision: 'triggered', runId: params.run.id, runName: params.run.name, reason: null},\n });\n}\n\nexport interface UpsertFailedDecisionParams {\n receivedEventId: string;\n subscription: TriggerSubscription;\n reason: string;\n}\n\nexport async function upsertFilterErrorDecision(params: UpsertFailedDecisionParams): Promise<void> {\n await upsertFailedDecision(params, 'filter-error');\n}\n\n// A created run is ground truth. A later retry failure must not erase it.\nexport async function upsertDispatchErrorDecision(\n params: UpsertFailedDecisionParams,\n): Promise<void> {\n await upsertFailedDecision(params, 'dispatch-error');\n}\n\nasync function upsertFailedDecision(\n params: UpsertFailedDecisionParams,\n decision: 'filter-error' | 'dispatch-error',\n): Promise<void> {\n await db()\n .insert(triggersDecisions)\n .values({\n receivedEventId: params.receivedEventId,\n subscriptionKind: 'trigger',\n subscriptionId: params.subscription.id,\n subscriptionName: params.subscription.name,\n workflowDefinitionId: params.subscription.workflowDefinitionId,\n projectId: params.subscription.projectId,\n decision,\n reason: params.reason,\n })\n .onConflictDoUpdate({\n target: [\n triggersDecisions.receivedEventId,\n triggersDecisions.subscriptionKind,\n triggersDecisions.subscriptionId,\n ],\n set: {decision, reason: params.reason, runId: null, runName: null},\n setWhere: ne(triggersDecisions.decision, 'triggered'),\n });\n}\n\nexport interface UpsertListenerTriggeredDecisionParams {\n receivedEventId: string;\n subscription: JobListenerSubscription;\n}\n\nexport async function upsertListenerTriggeredDecision(\n params: UpsertListenerTriggeredDecisionParams,\n): Promise<void> {\n await db()\n .insert(triggersDecisions)\n .values({\n ...listenerDecisionIdentity(params),\n decision: 'triggered',\n runId: null,\n runName: null,\n reason: null,\n })\n .onConflictDoUpdate({\n target: [\n triggersDecisions.receivedEventId,\n triggersDecisions.subscriptionKind,\n triggersDecisions.subscriptionId,\n ],\n set: {decision: 'triggered', runId: null, runName: null, reason: null},\n });\n}\n\nexport interface UpsertListenerFailedDecisionParams {\n receivedEventId: string;\n subscription: JobListenerSubscription;\n reason: string;\n}\n\nexport async function upsertListenerFilterErrorDecision(\n params: UpsertListenerFailedDecisionParams,\n): Promise<void> {\n await upsertListenerFailedDecision(params, 'filter-error');\n}\n\nexport async function upsertListenerDispatchErrorDecision(\n params: UpsertListenerFailedDecisionParams,\n): Promise<void> {\n await upsertListenerFailedDecision(params, 'dispatch-error');\n}\n\nasync function upsertListenerFailedDecision(\n params: UpsertListenerFailedDecisionParams,\n decision: 'filter-error' | 'dispatch-error',\n): Promise<void> {\n await db()\n .insert(triggersDecisions)\n .values({\n ...listenerDecisionIdentity(params),\n decision,\n reason: params.reason,\n })\n .onConflictDoUpdate({\n target: [\n triggersDecisions.receivedEventId,\n triggersDecisions.subscriptionKind,\n triggersDecisions.subscriptionId,\n ],\n set: {decision, reason: params.reason, runId: null, runName: null},\n setWhere: ne(triggersDecisions.decision, 'triggered'),\n });\n}\n\nfunction listenerDecisionIdentity(params: {\n receivedEventId: string;\n subscription: JobListenerSubscription;\n}) {\n const {subscription} = params;\n return {\n receivedEventId: params.receivedEventId,\n subscriptionKind: 'listener' as const,\n subscriptionId: subscription.id,\n subscriptionName: listenerSubscriptionName(subscription),\n workflowDefinitionId: null,\n projectId: null,\n workflowRunId: subscription.workflowRunId,\n jobId: subscription.jobId,\n matcherKind: subscription.kind,\n matcherOrdinal: subscription.matcherOrdinal,\n };\n}\n\nfunction listenerSubscriptionName(subscription: JobListenerSubscription): string {\n return `listener ${subscription.kind}[${subscription.matcherOrdinal}] ${subscription.source}/${subscription.event}`;\n}\n"],"names":["and","eq","ne","notInArray","sql","db","triggersDecisions","triggersReceivedEvents","insertReceivedEvent","params","inserted","insert","values","eventRef","origin","workspaceId","provider","source","event","deliveryId","connectionId","connectionName","payload","receivedAt","onConflictDoNothing","target","returning","id","existing","select","from","where","Error","markReceivedEventDiscarded","update","set","outcome","matchedCount","processedAt","Date","markReceivedEventRouted","markReceivedEventFailed","markReceivedEventErrored","receivedEventId","decision","upsertTriggeredDecision","subscriptionKind","subscriptionId","subscription","subscriptionName","name","workflowDefinitionId","projectId","runId","run","runName","reason","onConflictDoUpdate","upsertFilterErrorDecision","upsertFailedDecision","upsertDispatchErrorDecision","setWhere","upsertListenerTriggeredDecision","listenerDecisionIdentity","upsertListenerFilterErrorDecision","upsertListenerFailedDecision","upsertListenerDispatchErrorDecision","listenerSubscriptionName","workflowRunId","jobId","matcherKind","kind","matcherOrdinal"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TriggerDecision } from '#core/entities/decision.js';
|
|
2
|
+
import type { TriggerEventOutcome, TriggerReceivedEvent, TriggerReceivedEventSummary } from '#core/entities/received-event.js';
|
|
3
|
+
export interface TriggerEventCursor {
|
|
4
|
+
receivedAt: Date;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
export interface TriggerEventListFilters {
|
|
8
|
+
source?: string[] | undefined;
|
|
9
|
+
event?: string[] | undefined;
|
|
10
|
+
outcomes?: TriggerEventOutcome[] | undefined;
|
|
11
|
+
from?: Date | undefined;
|
|
12
|
+
to?: Date | undefined;
|
|
13
|
+
}
|
|
14
|
+
export interface ListTriggerEventsParams {
|
|
15
|
+
workspaceId: string;
|
|
16
|
+
limit: number;
|
|
17
|
+
cursor?: TriggerEventCursor | undefined;
|
|
18
|
+
filters?: TriggerEventListFilters | undefined;
|
|
19
|
+
}
|
|
20
|
+
export interface ListTriggerEventsResult {
|
|
21
|
+
events: TriggerReceivedEventSummary[];
|
|
22
|
+
nextCursor: TriggerEventCursor | null;
|
|
23
|
+
}
|
|
24
|
+
export declare function listTriggerEvents(params: ListTriggerEventsParams): Promise<ListTriggerEventsResult>;
|
|
25
|
+
export declare function getTriggerEventById(id: string): Promise<TriggerReceivedEvent | undefined>;
|
|
26
|
+
export interface TriggerEventFacet {
|
|
27
|
+
value: string;
|
|
28
|
+
count: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ListTriggerEventFacetsResult {
|
|
31
|
+
sources: TriggerEventFacet[];
|
|
32
|
+
events: TriggerEventFacet[];
|
|
33
|
+
}
|
|
34
|
+
export declare function listTriggerEventFacets(params: {
|
|
35
|
+
workspaceId: string;
|
|
36
|
+
}): Promise<ListTriggerEventFacetsResult>;
|
|
37
|
+
export declare function listDecisionsByReceivedEventId(receivedEventId: string): Promise<TriggerDecision[]>;
|
|
38
|
+
//# sourceMappingURL=event-queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-queries.d.ts","sourceRoot":"","sources":["../../src/db/event-queries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,2BAA2B,EAC5B,MAAM,kCAAkC,CAAC;AAU1C,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,IAAI,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC7C,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACxB,EAAE,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,2BAA2B,EAAE,CAAC;IACtC,UAAU,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACvC;AAqBD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAgBlC;AAED,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAO/F;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAmBD,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAMxC;AAID,wBAAsB,8BAA8B,CAClD,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,EAAE,CAAC,CAO5B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { paginateTimestampIdRows, timestampIdCursorWhere } from '@shipfox/node-drizzle';
|
|
2
|
+
import { and, asc, count, desc, eq, gte, inArray, lte } from 'drizzle-orm';
|
|
3
|
+
import { db } from './db.js';
|
|
4
|
+
import { toTriggerDecision, triggersDecisions } from './schema/decisions.js';
|
|
5
|
+
import { toTriggerReceivedEvent, toTriggerReceivedEventSummary, triggerReceivedEventSummaryColumns, triggersReceivedEvents } from './schema/received-events.js';
|
|
6
|
+
function listConditions(params) {
|
|
7
|
+
const { workspaceId, cursor, filters } = params;
|
|
8
|
+
const conditions = [
|
|
9
|
+
eq(triggersReceivedEvents.workspaceId, workspaceId)
|
|
10
|
+
];
|
|
11
|
+
const cursorCondition = timestampIdCursorWhere({
|
|
12
|
+
timestampColumn: triggersReceivedEvents.receivedAt,
|
|
13
|
+
idColumn: triggersReceivedEvents.id,
|
|
14
|
+
cursor: cursor ? {
|
|
15
|
+
createdAt: cursor.receivedAt,
|
|
16
|
+
id: cursor.id
|
|
17
|
+
} : undefined
|
|
18
|
+
});
|
|
19
|
+
if (cursorCondition) conditions.push(cursorCondition);
|
|
20
|
+
if (filters?.source?.length) conditions.push(inArray(triggersReceivedEvents.source, filters.source));
|
|
21
|
+
if (filters?.event?.length) conditions.push(inArray(triggersReceivedEvents.event, filters.event));
|
|
22
|
+
if (filters?.outcomes?.length) conditions.push(inArray(triggersReceivedEvents.outcome, filters.outcomes));
|
|
23
|
+
if (filters?.from) conditions.push(gte(triggersReceivedEvents.receivedAt, filters.from));
|
|
24
|
+
if (filters?.to) conditions.push(lte(triggersReceivedEvents.receivedAt, filters.to));
|
|
25
|
+
return conditions;
|
|
26
|
+
}
|
|
27
|
+
export async function listTriggerEvents(params) {
|
|
28
|
+
const rows = await db().select(triggerReceivedEventSummaryColumns).from(triggersReceivedEvents).where(and(...listConditions(params))).orderBy(desc(triggersReceivedEvents.receivedAt), desc(triggersReceivedEvents.id)).limit(params.limit + 1);
|
|
29
|
+
const page = paginateTimestampIdRows({
|
|
30
|
+
rows,
|
|
31
|
+
limit: params.limit,
|
|
32
|
+
timestampKey: 'receivedAt'
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
events: page.pageRows.map(toTriggerReceivedEventSummary),
|
|
36
|
+
nextCursor: page.nextCursor ? {
|
|
37
|
+
receivedAt: page.nextCursor.createdAt,
|
|
38
|
+
id: page.nextCursor.id
|
|
39
|
+
} : null
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function getTriggerEventById(id) {
|
|
43
|
+
const [row] = await db().select().from(triggersReceivedEvents).where(eq(triggersReceivedEvents.id, id)).limit(1);
|
|
44
|
+
return row ? toTriggerReceivedEvent(row) : undefined;
|
|
45
|
+
}
|
|
46
|
+
// Distinct filter values for a workspace, capped so one noisy integration can't flood
|
|
47
|
+
// the dropdown. Workspace-unfiltered by design: a stable option list, not one that
|
|
48
|
+
// shifts as the other filters change. The (workspace_id, source) / (workspace_id, event)
|
|
49
|
+
// indexes back the group-by. Ties break on the value so the order is deterministic.
|
|
50
|
+
const FACET_LIMIT = 50;
|
|
51
|
+
async function listFacet(workspaceId, column) {
|
|
52
|
+
const rows = await db().select({
|
|
53
|
+
value: column,
|
|
54
|
+
count: count()
|
|
55
|
+
}).from(triggersReceivedEvents).where(eq(triggersReceivedEvents.workspaceId, workspaceId)).groupBy(column).orderBy(desc(count()), asc(column)).limit(FACET_LIMIT);
|
|
56
|
+
return rows.map((row)=>({
|
|
57
|
+
value: row.value,
|
|
58
|
+
count: Number(row.count)
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
export async function listTriggerEventFacets(params) {
|
|
62
|
+
const [sources, events] = await Promise.all([
|
|
63
|
+
listFacet(params.workspaceId, triggersReceivedEvents.source),
|
|
64
|
+
listFacet(params.workspaceId, triggersReceivedEvents.event)
|
|
65
|
+
]);
|
|
66
|
+
return {
|
|
67
|
+
sources,
|
|
68
|
+
events
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// `received_event_id` is a globally-unique uuid, so the parent-event lookup is the
|
|
72
|
+
// workspace gate; the decision query needs no separate workspace predicate.
|
|
73
|
+
export async function listDecisionsByReceivedEventId(receivedEventId) {
|
|
74
|
+
const rows = await db().select().from(triggersDecisions).where(eq(triggersDecisions.receivedEventId, receivedEventId)).orderBy(asc(triggersDecisions.createdAt), asc(triggersDecisions.id));
|
|
75
|
+
return rows.map(toTriggerDecision);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=event-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/db/event-queries.ts"],"sourcesContent":["import {paginateTimestampIdRows, timestampIdCursorWhere} from '@shipfox/node-drizzle';\nimport {and, asc, count, desc, eq, gte, inArray, lte, type SQL} from 'drizzle-orm';\nimport type {PgColumn} from 'drizzle-orm/pg-core';\nimport type {TriggerDecision} from '#core/entities/decision.js';\nimport type {\n TriggerEventOutcome,\n TriggerReceivedEvent,\n TriggerReceivedEventSummary,\n} from '#core/entities/received-event.js';\nimport {db} from './db.js';\nimport {toTriggerDecision, triggersDecisions} from './schema/decisions.js';\nimport {\n toTriggerReceivedEvent,\n toTriggerReceivedEventSummary,\n triggerReceivedEventSummaryColumns,\n triggersReceivedEvents,\n} from './schema/received-events.js';\n\nexport interface TriggerEventCursor {\n receivedAt: Date;\n id: string;\n}\n\nexport interface TriggerEventListFilters {\n source?: string[] | undefined;\n event?: string[] | undefined;\n outcomes?: TriggerEventOutcome[] | undefined;\n from?: Date | undefined;\n to?: Date | undefined;\n}\n\nexport interface ListTriggerEventsParams {\n workspaceId: string;\n limit: number;\n cursor?: TriggerEventCursor | undefined;\n filters?: TriggerEventListFilters | undefined;\n}\n\nexport interface ListTriggerEventsResult {\n events: TriggerReceivedEventSummary[];\n nextCursor: TriggerEventCursor | null;\n}\n\nfunction listConditions(params: ListTriggerEventsParams): SQL[] {\n const {workspaceId, cursor, filters} = params;\n const conditions: SQL[] = [eq(triggersReceivedEvents.workspaceId, workspaceId)];\n const cursorCondition = timestampIdCursorWhere({\n timestampColumn: triggersReceivedEvents.receivedAt,\n idColumn: triggersReceivedEvents.id,\n cursor: cursor ? {createdAt: cursor.receivedAt, id: cursor.id} : undefined,\n });\n if (cursorCondition) conditions.push(cursorCondition);\n if (filters?.source?.length)\n conditions.push(inArray(triggersReceivedEvents.source, filters.source));\n if (filters?.event?.length) conditions.push(inArray(triggersReceivedEvents.event, filters.event));\n if (filters?.outcomes?.length)\n conditions.push(inArray(triggersReceivedEvents.outcome, filters.outcomes));\n if (filters?.from) conditions.push(gte(triggersReceivedEvents.receivedAt, filters.from));\n if (filters?.to) conditions.push(lte(triggersReceivedEvents.receivedAt, filters.to));\n return conditions;\n}\n\nexport async function listTriggerEvents(\n params: ListTriggerEventsParams,\n): Promise<ListTriggerEventsResult> {\n const rows = await db()\n .select(triggerReceivedEventSummaryColumns)\n .from(triggersReceivedEvents)\n .where(and(...listConditions(params)))\n .orderBy(desc(triggersReceivedEvents.receivedAt), desc(triggersReceivedEvents.id))\n .limit(params.limit + 1);\n\n const page = paginateTimestampIdRows({rows, limit: params.limit, timestampKey: 'receivedAt'});\n\n return {\n events: page.pageRows.map(toTriggerReceivedEventSummary),\n nextCursor: page.nextCursor\n ? {receivedAt: page.nextCursor.createdAt, id: page.nextCursor.id}\n : null,\n };\n}\n\nexport async function getTriggerEventById(id: string): Promise<TriggerReceivedEvent | undefined> {\n const [row] = await db()\n .select()\n .from(triggersReceivedEvents)\n .where(eq(triggersReceivedEvents.id, id))\n .limit(1);\n return row ? toTriggerReceivedEvent(row) : undefined;\n}\n\nexport interface TriggerEventFacet {\n value: string;\n count: number;\n}\n\nexport interface ListTriggerEventFacetsResult {\n sources: TriggerEventFacet[];\n events: TriggerEventFacet[];\n}\n\n// Distinct filter values for a workspace, capped so one noisy integration can't flood\n// the dropdown. Workspace-unfiltered by design: a stable option list, not one that\n// shifts as the other filters change. The (workspace_id, source) / (workspace_id, event)\n// indexes back the group-by. Ties break on the value so the order is deterministic.\nconst FACET_LIMIT = 50;\n\nasync function listFacet(workspaceId: string, column: PgColumn): Promise<TriggerEventFacet[]> {\n const rows = await db()\n .select({value: column, count: count()})\n .from(triggersReceivedEvents)\n .where(eq(triggersReceivedEvents.workspaceId, workspaceId))\n .groupBy(column)\n .orderBy(desc(count()), asc(column))\n .limit(FACET_LIMIT);\n return rows.map((row) => ({value: row.value as string, count: Number(row.count)}));\n}\n\nexport async function listTriggerEventFacets(params: {\n workspaceId: string;\n}): Promise<ListTriggerEventFacetsResult> {\n const [sources, events] = await Promise.all([\n listFacet(params.workspaceId, triggersReceivedEvents.source),\n listFacet(params.workspaceId, triggersReceivedEvents.event),\n ]);\n return {sources, events};\n}\n\n// `received_event_id` is a globally-unique uuid, so the parent-event lookup is the\n// workspace gate; the decision query needs no separate workspace predicate.\nexport async function listDecisionsByReceivedEventId(\n receivedEventId: string,\n): Promise<TriggerDecision[]> {\n const rows = await db()\n .select()\n .from(triggersDecisions)\n .where(eq(triggersDecisions.receivedEventId, receivedEventId))\n .orderBy(asc(triggersDecisions.createdAt), asc(triggersDecisions.id));\n return rows.map(toTriggerDecision);\n}\n"],"names":["paginateTimestampIdRows","timestampIdCursorWhere","and","asc","count","desc","eq","gte","inArray","lte","db","toTriggerDecision","triggersDecisions","toTriggerReceivedEvent","toTriggerReceivedEventSummary","triggerReceivedEventSummaryColumns","triggersReceivedEvents","listConditions","params","workspaceId","cursor","filters","conditions","cursorCondition","timestampColumn","receivedAt","idColumn","id","createdAt","undefined","push","source","length","event","outcomes","outcome","from","to","listTriggerEvents","rows","select","where","orderBy","limit","page","timestampKey","events","pageRows","map","nextCursor","getTriggerEventById","row","FACET_LIMIT","listFacet","column","value","groupBy","Number","listTriggerEventFacets","sources","Promise","all","listDecisionsByReceivedEventId","receivedEventId"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { advanceCronSchedule, claimDueCronSchedules, countDueCronSchedules, deleteCronScheduleForSubscription, getCronScheduleBySubscriptionId, syncCronSchedule, } from './cron-schedules.js';
|
|
2
|
+
export { closeDb, db, type Executor, schema, type Tx } from './db.js';
|
|
3
|
+
export { getTriggerEventById, type ListTriggerEventFacetsResult, type ListTriggerEventsParams, type ListTriggerEventsResult, listDecisionsByReceivedEventId, listTriggerEventFacets, listTriggerEvents, type TriggerEventCursor, type TriggerEventFacet, type TriggerEventListFilters, } from './event-queries.js';
|
|
4
|
+
export { type FindMatchingJobListenerSubscriptionsParams, findMatchingJobListenerSubscriptions, type ListenerMatcher, type ProjectJobListenerSubscriptionsParams, projectJobListenerSubscriptions, removeJobListenerSubscriptionsForJob, } from './job-listener-subscriptions.js';
|
|
5
|
+
export { type CronScheduleDb, type CronScheduleInsertDb, toCronSchedule, triggersCronSchedules, } from './schema/cron-schedules.js';
|
|
6
|
+
export { jobListenerSubscriptions } from './schema/job-listener-subscriptions.js';
|
|
7
|
+
export { triggersOutbox } from './schema/outbox.js';
|
|
8
|
+
export { triggerSubscriptions } from './schema/subscriptions.js';
|
|
9
|
+
export { deleteSubscriptionsForDefinition, findMatchingSubscriptions, getManualSubscriptionByDefinitionId, getTriggerSubscriptionById, listSubscriptionsByWorkflowDefinitionIds, projectDefinitionTriggers, } from './subscriptions.js';
|
|
10
|
+
export declare const migrationsPath: string;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,iCAAiC,EACjC,+BAA+B,EAC/B,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,OAAO,EAAE,EAAE,EAAE,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAC,MAAM,SAAS,CAAC;AACpE,OAAO,EACL,mBAAmB,EACnB,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,8BAA8B,EAC9B,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,0CAA0C,EAC/C,oCAAoC,EACpC,KAAK,eAAe,EACpB,KAAK,qCAAqC,EAC1C,+BAA+B,EAC/B,oCAAoC,GACrC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,cAAc,EACd,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,wBAAwB,EAAC,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,0BAA0B,EAC1B,wCAAwC,EACxC,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,cAAc,QAAoE,CAAC"}
|
package/dist/db/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
export { advanceCronSchedule, claimDueCronSchedules, countDueCronSchedules, deleteCronScheduleForSubscription, getCronScheduleBySubscriptionId, syncCronSchedule } from './cron-schedules.js';
|
|
4
|
+
export { closeDb, db, schema } from './db.js';
|
|
5
|
+
export { getTriggerEventById, listDecisionsByReceivedEventId, listTriggerEventFacets, listTriggerEvents } from './event-queries.js';
|
|
6
|
+
export { findMatchingJobListenerSubscriptions, projectJobListenerSubscriptions, removeJobListenerSubscriptionsForJob } from './job-listener-subscriptions.js';
|
|
7
|
+
export { toCronSchedule, triggersCronSchedules } from './schema/cron-schedules.js';
|
|
8
|
+
export { jobListenerSubscriptions } from './schema/job-listener-subscriptions.js';
|
|
9
|
+
export { triggersOutbox } from './schema/outbox.js';
|
|
10
|
+
export { triggerSubscriptions } from './schema/subscriptions.js';
|
|
11
|
+
export { deleteSubscriptionsForDefinition, findMatchingSubscriptions, getManualSubscriptionByDefinitionId, getTriggerSubscriptionById, listSubscriptionsByWorkflowDefinitionIds, projectDefinitionTriggers } from './subscriptions.js';
|
|
12
|
+
export const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport {\n advanceCronSchedule,\n claimDueCronSchedules,\n countDueCronSchedules,\n deleteCronScheduleForSubscription,\n getCronScheduleBySubscriptionId,\n syncCronSchedule,\n} from './cron-schedules.js';\nexport {closeDb, db, type Executor, schema, type Tx} from './db.js';\nexport {\n getTriggerEventById,\n type ListTriggerEventFacetsResult,\n type ListTriggerEventsParams,\n type ListTriggerEventsResult,\n listDecisionsByReceivedEventId,\n listTriggerEventFacets,\n listTriggerEvents,\n type TriggerEventCursor,\n type TriggerEventFacet,\n type TriggerEventListFilters,\n} from './event-queries.js';\nexport {\n type FindMatchingJobListenerSubscriptionsParams,\n findMatchingJobListenerSubscriptions,\n type ListenerMatcher,\n type ProjectJobListenerSubscriptionsParams,\n projectJobListenerSubscriptions,\n removeJobListenerSubscriptionsForJob,\n} from './job-listener-subscriptions.js';\nexport {\n type CronScheduleDb,\n type CronScheduleInsertDb,\n toCronSchedule,\n triggersCronSchedules,\n} from './schema/cron-schedules.js';\nexport {jobListenerSubscriptions} from './schema/job-listener-subscriptions.js';\nexport {triggersOutbox} from './schema/outbox.js';\nexport {triggerSubscriptions} from './schema/subscriptions.js';\nexport {\n deleteSubscriptionsForDefinition,\n findMatchingSubscriptions,\n getManualSubscriptionByDefinitionId,\n getTriggerSubscriptionById,\n listSubscriptionsByWorkflowDefinitionIds,\n projectDefinitionTriggers,\n} from './subscriptions.js';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n"],"names":["dirname","resolve","fileURLToPath","advanceCronSchedule","claimDueCronSchedules","countDueCronSchedules","deleteCronScheduleForSubscription","getCronScheduleBySubscriptionId","syncCronSchedule","closeDb","db","schema","getTriggerEventById","listDecisionsByReceivedEventId","listTriggerEventFacets","listTriggerEvents","findMatchingJobListenerSubscriptions","projectJobListenerSubscriptions","removeJobListenerSubscriptionsForJob","toCronSchedule","triggersCronSchedules","jobListenerSubscriptions","triggersOutbox","triggerSubscriptions","deleteSubscriptionsForDefinition","findMatchingSubscriptions","getManualSubscriptionByDefinitionId","getTriggerSubscriptionById","listSubscriptionsByWorkflowDefinitionIds","projectDefinitionTriggers","migrationsPath","url"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,SACEC,mBAAmB,EACnBC,qBAAqB,EACrBC,qBAAqB,EACrBC,iCAAiC,EACjCC,+BAA+B,EAC/BC,gBAAgB,QACX,sBAAsB;AAC7B,SAAQC,OAAO,EAAEC,EAAE,EAAiBC,MAAM,QAAgB,UAAU;AACpE,SACEC,mBAAmB,EAInBC,8BAA8B,EAC9BC,sBAAsB,EACtBC,iBAAiB,QAIZ,qBAAqB;AAC5B,SAEEC,oCAAoC,EAGpCC,+BAA+B,EAC/BC,oCAAoC,QAC/B,kCAAkC;AACzC,SAGEC,cAAc,EACdC,qBAAqB,QAChB,6BAA6B;AACpC,SAAQC,wBAAwB,QAAO,yCAAyC;AAChF,SAAQC,cAAc,QAAO,qBAAqB;AAClD,SAAQC,oBAAoB,QAAO,4BAA4B;AAC/D,SACEC,gCAAgC,EAChCC,yBAAyB,EACzBC,mCAAmC,EACnCC,0BAA0B,EAC1BC,wCAAwC,EACxCC,yBAAyB,QACpB,qBAAqB;AAE5B,OAAO,MAAMC,iBAAiB7B,QAAQD,QAAQE,cAAc,YAAY6B,GAAG,IAAI,iBAAiB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { JobListenerSubscription } from '#core/entities/job-listener-subscription.js';
|
|
2
|
+
export interface ListenerMatcher {
|
|
3
|
+
source: string;
|
|
4
|
+
event: string;
|
|
5
|
+
inputs?: Readonly<Record<string, unknown>> | undefined;
|
|
6
|
+
filter?: string | undefined;
|
|
7
|
+
filter_snapshot?: Readonly<Record<string, unknown>> | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface ProjectJobListenerSubscriptionsParams {
|
|
10
|
+
workspaceId: string;
|
|
11
|
+
workflowRunId: string;
|
|
12
|
+
jobId: string;
|
|
13
|
+
on: readonly ListenerMatcher[] | null;
|
|
14
|
+
until: readonly ListenerMatcher[] | null;
|
|
15
|
+
}
|
|
16
|
+
export declare function projectJobListenerSubscriptions(params: ProjectJobListenerSubscriptionsParams): Promise<void>;
|
|
17
|
+
export declare function removeJobListenerSubscriptionsForJob(jobId: string): Promise<number>;
|
|
18
|
+
export interface FindMatchingJobListenerSubscriptionsParams {
|
|
19
|
+
workspaceId: string;
|
|
20
|
+
source: string;
|
|
21
|
+
event: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function findMatchingJobListenerSubscriptions(params: FindMatchingJobListenerSubscriptionsParams): Promise<JobListenerSubscription[]>;
|
|
24
|
+
//# sourceMappingURL=job-listener-subscriptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-listener-subscriptions.d.ts","sourceRoot":"","sources":["../../src/db/job-listener-subscriptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,6CAA6C,CAAC;AASrD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;IACtC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,IAAI,CAAC,CA4Cf;AA6BD,wBAAsB,oCAAoC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF;AAED,MAAM,WAAW,0CAA0C;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,0CAA0C,GACjD,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAYpC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { and, eq, notInArray } from 'drizzle-orm';
|
|
2
|
+
import { db } from './db.js';
|
|
3
|
+
import { jobListenerSubscriptions, toJobListenerSubscription } from './schema/job-listener-subscriptions.js';
|
|
4
|
+
export async function projectJobListenerSubscriptions(params) {
|
|
5
|
+
await db().transaction(async (tx)=>{
|
|
6
|
+
await pruneStaleMatchers(tx, params.jobId, 'on', params.on ?? []);
|
|
7
|
+
await pruneStaleMatchers(tx, params.jobId, 'until', params.until ?? []);
|
|
8
|
+
for (const [kind, matchers] of [
|
|
9
|
+
[
|
|
10
|
+
'on',
|
|
11
|
+
params.on ?? []
|
|
12
|
+
],
|
|
13
|
+
[
|
|
14
|
+
'until',
|
|
15
|
+
params.until ?? []
|
|
16
|
+
]
|
|
17
|
+
]){
|
|
18
|
+
for (const [matcherOrdinal, matcher] of matchers.entries()){
|
|
19
|
+
const config = {};
|
|
20
|
+
if (matcher.inputs !== undefined) config.inputs = matcher.inputs;
|
|
21
|
+
if (matcher.filter !== undefined) config.filter = matcher.filter;
|
|
22
|
+
if (matcher.filter_snapshot !== undefined) config.filter_snapshot = matcher.filter_snapshot;
|
|
23
|
+
await tx.insert(jobListenerSubscriptions).values({
|
|
24
|
+
workspaceId: params.workspaceId,
|
|
25
|
+
workflowRunId: params.workflowRunId,
|
|
26
|
+
jobId: params.jobId,
|
|
27
|
+
kind,
|
|
28
|
+
matcherOrdinal,
|
|
29
|
+
source: matcher.source,
|
|
30
|
+
event: matcher.event,
|
|
31
|
+
config
|
|
32
|
+
}).onConflictDoUpdate({
|
|
33
|
+
target: [
|
|
34
|
+
jobListenerSubscriptions.jobId,
|
|
35
|
+
jobListenerSubscriptions.kind,
|
|
36
|
+
jobListenerSubscriptions.matcherOrdinal
|
|
37
|
+
],
|
|
38
|
+
set: {
|
|
39
|
+
workspaceId: params.workspaceId,
|
|
40
|
+
workflowRunId: params.workflowRunId,
|
|
41
|
+
source: matcher.source,
|
|
42
|
+
event: matcher.event,
|
|
43
|
+
config
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function pruneStaleMatchers(tx, jobId, kind, matchers) {
|
|
51
|
+
const base = and(eq(jobListenerSubscriptions.jobId, jobId), eq(jobListenerSubscriptions.kind, kind));
|
|
52
|
+
if (matchers.length === 0) {
|
|
53
|
+
await tx.delete(jobListenerSubscriptions).where(base);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await tx.delete(jobListenerSubscriptions).where(and(base, notInArray(jobListenerSubscriptions.matcherOrdinal, matchers.map((_matcher, index)=>index))));
|
|
57
|
+
}
|
|
58
|
+
export async function removeJobListenerSubscriptionsForJob(jobId) {
|
|
59
|
+
const rows = await db().delete(jobListenerSubscriptions).where(eq(jobListenerSubscriptions.jobId, jobId)).returning({
|
|
60
|
+
id: jobListenerSubscriptions.id
|
|
61
|
+
});
|
|
62
|
+
return rows.length;
|
|
63
|
+
}
|
|
64
|
+
export async function findMatchingJobListenerSubscriptions(params) {
|
|
65
|
+
const rows = await db().select().from(jobListenerSubscriptions).where(and(eq(jobListenerSubscriptions.workspaceId, params.workspaceId), eq(jobListenerSubscriptions.source, params.source), eq(jobListenerSubscriptions.event, params.event)));
|
|
66
|
+
return rows.map(toJobListenerSubscription);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=job-listener-subscriptions.js.map
|