hazo_notify 5.0.1 → 5.3.1
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 +42 -10
- package/dist/components/notification_bell/index.d.ts +11 -1
- package/dist/components/notification_bell/index.d.ts.map +1 -1
- package/dist/components/notification_bell/index.js +33 -1
- package/dist/components/notification_bell/index.js.map +1 -1
- package/dist/lib/adapters/email/adapter.d.ts +2 -0
- package/dist/lib/adapters/email/adapter.d.ts.map +1 -1
- package/dist/lib/adapters/email/adapter.js +53 -22
- package/dist/lib/adapters/email/adapter.js.map +1 -1
- package/dist/lib/adapters/webhook/adapter.d.ts +10 -0
- package/dist/lib/adapters/webhook/adapter.d.ts.map +1 -0
- package/dist/lib/adapters/webhook/adapter.js +90 -0
- package/dist/lib/adapters/webhook/adapter.js.map +1 -0
- package/dist/lib/adapters/webhook/index.d.ts +8 -0
- package/dist/lib/adapters/webhook/index.d.ts.map +1 -0
- package/dist/lib/adapters/webhook/index.js +3 -0
- package/dist/lib/adapters/webhook/index.js.map +1 -0
- package/dist/lib/adapters/webhook/types.d.ts +45 -0
- package/dist/lib/adapters/webhook/types.d.ts.map +1 -0
- package/dist/lib/adapters/webhook/types.js +12 -0
- package/dist/lib/adapters/webhook/types.js.map +1 -0
- package/dist/lib/api/inbox.d.ts +32 -0
- package/dist/lib/api/inbox.d.ts.map +1 -1
- package/dist/lib/api/inbox.js +68 -0
- package/dist/lib/api/inbox.js.map +1 -1
- package/dist/lib/dispatcher/index.d.ts +2 -2
- package/dist/lib/dispatcher/index.d.ts.map +1 -1
- package/dist/lib/dispatcher/index.js +30 -8
- package/dist/lib/dispatcher/index.js.map +1 -1
- package/dist/lib/inbox/broadcaster.d.ts +44 -0
- package/dist/lib/inbox/broadcaster.d.ts.map +1 -0
- package/dist/lib/inbox/broadcaster.js +62 -0
- package/dist/lib/inbox/broadcaster.js.map +1 -0
- package/dist/lib/inbox/index.d.ts +2 -0
- package/dist/lib/inbox/index.d.ts.map +1 -1
- package/dist/lib/inbox/index.js +1 -0
- package/dist/lib/inbox/index.js.map +1 -1
- package/dist/lib/inbox/storage.d.ts.map +1 -1
- package/dist/lib/inbox/storage.js +8 -2
- package/dist/lib/inbox/storage.js.map +1 -1
- package/dist/lib/inbox/types.d.ts +10 -1
- package/dist/lib/inbox/types.d.ts.map +1 -1
- package/dist/lib/jobs/digest.d.ts +77 -0
- package/dist/lib/jobs/digest.d.ts.map +1 -0
- package/dist/lib/jobs/digest.js +127 -0
- package/dist/lib/jobs/digest.js.map +1 -0
- package/dist/lib/jobs/index.d.ts +2 -0
- package/dist/lib/jobs/index.d.ts.map +1 -1
- package/dist/lib/jobs/index.js +1 -0
- package/dist/lib/jobs/index.js.map +1 -1
- package/dist/lib/jobs/submit.d.ts.map +1 -1
- package/dist/lib/jobs/submit.js +1 -0
- package/dist/lib/jobs/submit.js.map +1 -1
- package/dist/lib/jobs/types.d.ts +1 -0
- package/dist/lib/jobs/types.d.ts.map +1 -1
- package/dist/lib/lifecycle/default_templates.d.ts +9 -0
- package/dist/lib/lifecycle/default_templates.d.ts.map +1 -0
- package/dist/lib/lifecycle/default_templates.js +196 -0
- package/dist/lib/lifecycle/default_templates.js.map +1 -0
- package/dist/lib/lifecycle/dispatch.d.ts +37 -0
- package/dist/lib/lifecycle/dispatch.d.ts.map +1 -0
- package/dist/lib/lifecycle/dispatch.js +32 -0
- package/dist/lib/lifecycle/dispatch.js.map +1 -0
- package/dist/lib/lifecycle/events.d.ts +34 -0
- package/dist/lib/lifecycle/events.d.ts.map +1 -0
- package/dist/lib/lifecycle/events.js +118 -0
- package/dist/lib/lifecycle/events.js.map +1 -0
- package/dist/lib/lifecycle/handler.d.ts +29 -0
- package/dist/lib/lifecycle/handler.d.ts.map +1 -0
- package/dist/lib/lifecycle/handler.js +145 -0
- package/dist/lib/lifecycle/handler.js.map +1 -0
- package/dist/lib/lifecycle/index.d.ts +23 -0
- package/dist/lib/lifecycle/index.d.ts.map +1 -0
- package/dist/lib/lifecycle/index.js +21 -0
- package/dist/lib/lifecycle/index.js.map +1 -0
- package/dist/lib/lifecycle/register.d.ts +29 -0
- package/dist/lib/lifecycle/register.d.ts.map +1 -0
- package/dist/lib/lifecycle/register.js +29 -0
- package/dist/lib/lifecycle/register.js.map +1 -0
- package/dist/lib/lifecycle/resolver.d.ts +22 -0
- package/dist/lib/lifecycle/resolver.d.ts.map +1 -0
- package/dist/lib/lifecycle/resolver.js +105 -0
- package/dist/lib/lifecycle/resolver.js.map +1 -0
- package/dist/lib/lifecycle/scheduler.d.ts +27 -0
- package/dist/lib/lifecycle/scheduler.d.ts.map +1 -0
- package/dist/lib/lifecycle/scheduler.js +108 -0
- package/dist/lib/lifecycle/scheduler.js.map +1 -0
- package/dist/lib/lifecycle/status.d.ts +39 -0
- package/dist/lib/lifecycle/status.d.ts.map +1 -0
- package/dist/lib/lifecycle/status.js +67 -0
- package/dist/lib/lifecycle/status.js.map +1 -0
- package/dist/lib/lifecycle/types.d.ts +165 -0
- package/dist/lib/lifecycle/types.d.ts.map +1 -0
- package/dist/lib/lifecycle/types.js +11 -0
- package/dist/lib/lifecycle/types.js.map +1 -0
- package/dist/lib/preferences/index.d.ts +3 -0
- package/dist/lib/preferences/index.d.ts.map +1 -0
- package/dist/lib/preferences/index.js +3 -0
- package/dist/lib/preferences/index.js.map +1 -0
- package/dist/lib/preferences/storage.d.ts +33 -0
- package/dist/lib/preferences/storage.d.ts.map +1 -0
- package/dist/lib/preferences/storage.js +129 -0
- package/dist/lib/preferences/storage.js.map +1 -0
- package/dist/lib/preferences/types.d.ts +59 -0
- package/dist/lib/preferences/types.d.ts.map +1 -0
- package/dist/lib/preferences/types.js +20 -0
- package/dist/lib/preferences/types.js.map +1 -0
- package/dist/lib/template_manager/db/template_repository.d.ts +4 -1
- package/dist/lib/template_manager/db/template_repository.d.ts.map +1 -1
- package/dist/lib/template_manager/db/template_repository.js +17 -1
- package/dist/lib/template_manager/db/template_repository.js.map +1 -1
- package/dist/lib/template_manager/types.d.ts +1 -0
- package/dist/lib/template_manager/types.d.ts.map +1 -1
- package/migrations/008_lifecycle_status.pg.sql +27 -0
- package/migrations/008_lifecycle_status.sqlite.sql +24 -0
- package/migrations/009_templates_locale.pg.sql +6 -0
- package/migrations/009_templates_locale.sqlite.sql +4 -0
- package/migrations/010_preferences.pg.sql +26 -0
- package/migrations/010_preferences.sqlite.sql +32 -0
- package/migrations/011_digest_status.pg.sql +21 -0
- package/migrations/011_digest_status.sqlite.sql +43 -0
- package/migrations/012_preferences_digest.pg.sql +12 -0
- package/migrations/012_preferences_digest.sqlite.sql +51 -0
- package/package.json +15 -3
package/dist/lib/api/inbox.js
CHANGED
|
@@ -49,4 +49,72 @@ export function createInboxRoutes(opts) {
|
|
|
49
49
|
},
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns a Next.js-compatible GET handler for `text/event-stream`.
|
|
54
|
+
*
|
|
55
|
+
* Consumer mounting:
|
|
56
|
+
* ```ts
|
|
57
|
+
* // app/api/notifications/stream/route.ts
|
|
58
|
+
* import { createInboxStreamRoute } from 'hazo_notify/api/inbox';
|
|
59
|
+
* import { subscribe } from '@/lib/notify-init';
|
|
60
|
+
* export const GET = createInboxStreamRoute({ getAuth, subscribe });
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* Events pushed to clients:
|
|
64
|
+
* event: notification.created\ndata: {"user_id":"…","inbox_id":"…"}\n\n
|
|
65
|
+
*
|
|
66
|
+
* The client (NotificationBell with realtime enabled) listens for
|
|
67
|
+
* `notification.created` and refreshes its unread count on receipt.
|
|
68
|
+
*/
|
|
69
|
+
export function createInboxStreamRoute(opts) {
|
|
70
|
+
const heartbeat_ms = opts.heartbeat_ms ?? 20000;
|
|
71
|
+
return async function GET(req) {
|
|
72
|
+
const auth = await opts.getAuth(req);
|
|
73
|
+
if (!auth) {
|
|
74
|
+
return new Response('Unauthorized', { status: 401 });
|
|
75
|
+
}
|
|
76
|
+
const { user_id } = auth;
|
|
77
|
+
const encoder = new TextEncoder();
|
|
78
|
+
let unsub = null;
|
|
79
|
+
let heartbeat = null;
|
|
80
|
+
const stream = new ReadableStream({
|
|
81
|
+
start(controller) {
|
|
82
|
+
// Send an initial connection confirmation event
|
|
83
|
+
controller.enqueue(encoder.encode(`event: connected\ndata: {"user_id":"${user_id}"}\n\n`));
|
|
84
|
+
// Subscribe to broadcaster events for this user
|
|
85
|
+
unsub = opts.subscribe(user_id, (event) => {
|
|
86
|
+
try {
|
|
87
|
+
controller.enqueue(encoder.encode(`event: notification.created\ndata: ${JSON.stringify(event)}\n\n`));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Stream closed — subscriber will be cleaned up in cancel()
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Heartbeat to keep proxy connections alive
|
|
94
|
+
heartbeat = setInterval(() => {
|
|
95
|
+
try {
|
|
96
|
+
controller.enqueue(encoder.encode(`: ping\n\n`));
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
if (heartbeat)
|
|
100
|
+
clearInterval(heartbeat);
|
|
101
|
+
}
|
|
102
|
+
}, heartbeat_ms);
|
|
103
|
+
},
|
|
104
|
+
cancel() {
|
|
105
|
+
if (heartbeat)
|
|
106
|
+
clearInterval(heartbeat);
|
|
107
|
+
unsub?.();
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
return new Response(stream, {
|
|
111
|
+
headers: {
|
|
112
|
+
'Content-Type': 'text/event-stream',
|
|
113
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
114
|
+
Connection: 'keep-alive',
|
|
115
|
+
'X-Accel-Buffering': 'no', // Disable nginx buffering
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
}
|
|
52
120
|
//# sourceMappingURL=inbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../../src/lib/api/inbox.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,WAAW,GACZ,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../../src/lib/api/inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DispatchInput, DispatchResult } from
|
|
2
|
-
export type { DispatchInput, DispatchResult } from
|
|
1
|
+
import type { DispatchInput, DispatchResult } from '../inbox/types.js';
|
|
2
|
+
export type { DispatchInput, DispatchResult } from '../inbox/types.js';
|
|
3
3
|
export declare function dispatch(input: DispatchInput): Promise<DispatchResult>;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/dispatcher/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/dispatcher/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEvE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIvE,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CA6F5E"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { getChannel } from
|
|
2
|
-
import { upsertInboxRow, upsertDelivery } from
|
|
3
|
-
import { buildBatchKey } from
|
|
1
|
+
import { getChannel } from '../channels/registry.js';
|
|
2
|
+
import { upsertInboxRow, upsertDelivery } from '../inbox/storage.js';
|
|
3
|
+
import { buildBatchKey } from './batch-key.js';
|
|
4
|
+
import { batchGetPreferences } from '../preferences/storage.js';
|
|
5
|
+
import { getInboxBroadcaster } from '../inbox/broadcaster.js';
|
|
4
6
|
const DEFAULT_BATCH_WINDOW_MS = 5 * 60000;
|
|
5
7
|
export async function dispatch(input) {
|
|
6
8
|
const enabled = Object.entries(input.channels)
|
|
@@ -16,20 +18,29 @@ export async function dispatch(input) {
|
|
|
16
18
|
throw new Error(`dispatch: channel_payloads.${id} required`);
|
|
17
19
|
const v = adapter.validate(payload);
|
|
18
20
|
if (!v.ok)
|
|
19
|
-
throw new Error(`dispatch: validation failed for ${id}: ${(v.errors ?? []).join(
|
|
21
|
+
throw new Error(`dispatch: validation failed for ${id}: ${(v.errors ?? []).join('; ')}`);
|
|
20
22
|
}
|
|
21
23
|
if (input.recipient_user_ids.length === 0 || enabled.length === 0) {
|
|
22
24
|
return {
|
|
23
25
|
inbox_rows_upserted: 0, inbox_rows_inserted: 0, inbox_rows_aggregated: 0,
|
|
24
|
-
deliveries_created: 0, deliveries_refreshed: 0,
|
|
26
|
+
deliveries_created: 0, deliveries_refreshed: 0, deliveries_skipped_by_preference: 0,
|
|
25
27
|
channels_dispatched: enabled,
|
|
26
28
|
};
|
|
27
29
|
}
|
|
30
|
+
// Batch-fetch preferences for all recipients × channels before the loop.
|
|
31
|
+
const pref_map = await batchGetPreferences({
|
|
32
|
+
user_ids: input.recipient_user_ids,
|
|
33
|
+
scope_id: input.scope_id,
|
|
34
|
+
event_type: input.event_type,
|
|
35
|
+
channel_ids: enabled,
|
|
36
|
+
default_mode: input.preference_default ?? 'on',
|
|
37
|
+
});
|
|
38
|
+
const broadcaster = getInboxBroadcaster();
|
|
28
39
|
const window_ms = input.batch_window_ms ?? DEFAULT_BATCH_WINDOW_MS;
|
|
29
40
|
const now = Date.now();
|
|
30
41
|
const batch_closed_at = window_ms === 0 ? new Date(now).toISOString() : null;
|
|
31
42
|
const flush_after = new Date(now + window_ms).toISOString();
|
|
32
|
-
let inserted = 0, aggregated = 0, deliveries_created = 0, deliveries_refreshed = 0;
|
|
43
|
+
let inserted = 0, aggregated = 0, deliveries_created = 0, deliveries_refreshed = 0, deliveries_skipped = 0;
|
|
33
44
|
for (const user_id of input.recipient_user_ids) {
|
|
34
45
|
const batch_key = buildBatchKey(input.event_type, input.subject_id, user_id, window_ms);
|
|
35
46
|
const inbox = await upsertInboxRow({
|
|
@@ -44,16 +55,26 @@ export async function dispatch(input) {
|
|
|
44
55
|
surfaces: input.surfaces,
|
|
45
56
|
batch_closed_at,
|
|
46
57
|
});
|
|
47
|
-
if (inbox.inserted)
|
|
58
|
+
if (inbox.inserted) {
|
|
48
59
|
inserted++;
|
|
49
|
-
|
|
60
|
+
broadcaster?.notify(user_id, { user_id, inbox_id: inbox.id });
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
50
63
|
aggregated++;
|
|
64
|
+
}
|
|
51
65
|
for (const channel_id of enabled) {
|
|
66
|
+
const mode = pref_map.get(user_id)?.get(channel_id) ?? (input.preference_default ?? 'on');
|
|
67
|
+
if (mode === 'off') {
|
|
68
|
+
deliveries_skipped++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const initial_status = mode === 'digest' ? 'digesting' : 'pending';
|
|
52
72
|
const d = await upsertDelivery({
|
|
53
73
|
inbox_id: inbox.id,
|
|
54
74
|
channel_id,
|
|
55
75
|
payload: input.channel_payloads[channel_id],
|
|
56
76
|
flush_after,
|
|
77
|
+
initial_status,
|
|
57
78
|
});
|
|
58
79
|
if (d.inserted)
|
|
59
80
|
deliveries_created++;
|
|
@@ -67,6 +88,7 @@ export async function dispatch(input) {
|
|
|
67
88
|
inbox_rows_aggregated: aggregated,
|
|
68
89
|
deliveries_created,
|
|
69
90
|
deliveries_refreshed,
|
|
91
|
+
deliveries_skipped_by_preference: deliveries_skipped,
|
|
70
92
|
channels_dispatched: enabled,
|
|
71
93
|
};
|
|
72
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/dispatcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/dispatcher/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process broadcaster for inbox push events.
|
|
3
|
+
*
|
|
4
|
+
* Single-instance: use createInboxBroadcaster() — returns a matched
|
|
5
|
+
* { broadcaster, subscribe } pair backed by an in-process Map.
|
|
6
|
+
*
|
|
7
|
+
* Multi-instance: provide your own InboxBroadcaster implementation (e.g.
|
|
8
|
+
* backed by Redis pub/sub) and register it with setInboxBroadcaster().
|
|
9
|
+
* The subscribe function used by createInboxStreamRoute must be wired to
|
|
10
|
+
* the same channel.
|
|
11
|
+
*
|
|
12
|
+
* Both setInboxBroadcaster and the subscribe Map are stored on globalThis
|
|
13
|
+
* so they survive Next.js dev-mode bundle isolation.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
/** Payload pushed to SSE clients when a new inbox row is inserted. */
|
|
18
|
+
export interface InboxBroadcastEvent {
|
|
19
|
+
user_id: string;
|
|
20
|
+
inbox_id: string;
|
|
21
|
+
}
|
|
22
|
+
/** Minimal broadcaster interface. Implement this for multi-instance fan-out. */
|
|
23
|
+
export interface InboxBroadcaster {
|
|
24
|
+
notify(user_id: string, event: InboxBroadcastEvent): void;
|
|
25
|
+
}
|
|
26
|
+
/** Register a broadcaster. Call once at app boot. */
|
|
27
|
+
export declare function setInboxBroadcaster(broadcaster: InboxBroadcaster): void;
|
|
28
|
+
/** Returns the registered broadcaster, or null if not configured. */
|
|
29
|
+
export declare function getInboxBroadcaster(): InboxBroadcaster | null;
|
|
30
|
+
/**
|
|
31
|
+
* Create an in-process broadcaster + matching subscribe function.
|
|
32
|
+
*
|
|
33
|
+
* Consumer wiring:
|
|
34
|
+
* ```ts
|
|
35
|
+
* const { broadcaster, subscribe } = createInboxBroadcaster();
|
|
36
|
+
* setInboxBroadcaster(broadcaster);
|
|
37
|
+
* export const GET = createInboxStreamRoute({ getAuth, subscribe });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function createInboxBroadcaster(): {
|
|
41
|
+
broadcaster: InboxBroadcaster;
|
|
42
|
+
subscribe: (user_id: string, fn: (event: InboxBroadcastEvent) => void) => () => void;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=broadcaster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcaster.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/broadcaster.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;GAeG;AAEH,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC3D;AAOD,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAEvE;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,IAAI,CAE7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CACtF,CAwBA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/lib/inbox/broadcaster.ts
|
|
2
|
+
/**
|
|
3
|
+
* In-process broadcaster for inbox push events.
|
|
4
|
+
*
|
|
5
|
+
* Single-instance: use createInboxBroadcaster() — returns a matched
|
|
6
|
+
* { broadcaster, subscribe } pair backed by an in-process Map.
|
|
7
|
+
*
|
|
8
|
+
* Multi-instance: provide your own InboxBroadcaster implementation (e.g.
|
|
9
|
+
* backed by Redis pub/sub) and register it with setInboxBroadcaster().
|
|
10
|
+
* The subscribe function used by createInboxStreamRoute must be wired to
|
|
11
|
+
* the same channel.
|
|
12
|
+
*
|
|
13
|
+
* Both setInboxBroadcaster and the subscribe Map are stored on globalThis
|
|
14
|
+
* so they survive Next.js dev-mode bundle isolation.
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
const BROADCASTER_KEY = '__hazo_notify_broadcaster__';
|
|
19
|
+
const g = globalThis;
|
|
20
|
+
/** Register a broadcaster. Call once at app boot. */
|
|
21
|
+
export function setInboxBroadcaster(broadcaster) {
|
|
22
|
+
g[BROADCASTER_KEY] = broadcaster;
|
|
23
|
+
}
|
|
24
|
+
/** Returns the registered broadcaster, or null if not configured. */
|
|
25
|
+
export function getInboxBroadcaster() {
|
|
26
|
+
return g[BROADCASTER_KEY] ?? null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create an in-process broadcaster + matching subscribe function.
|
|
30
|
+
*
|
|
31
|
+
* Consumer wiring:
|
|
32
|
+
* ```ts
|
|
33
|
+
* const { broadcaster, subscribe } = createInboxBroadcaster();
|
|
34
|
+
* setInboxBroadcaster(broadcaster);
|
|
35
|
+
* export const GET = createInboxStreamRoute({ getAuth, subscribe });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function createInboxBroadcaster() {
|
|
39
|
+
const subs = new Map();
|
|
40
|
+
const broadcaster = {
|
|
41
|
+
notify(user_id, event) {
|
|
42
|
+
subs.get(user_id)?.forEach((fn) => {
|
|
43
|
+
try {
|
|
44
|
+
fn(event);
|
|
45
|
+
}
|
|
46
|
+
catch { /* swallow subscriber errors */ }
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
function subscribe(user_id, fn) {
|
|
51
|
+
if (!subs.has(user_id))
|
|
52
|
+
subs.set(user_id, new Set());
|
|
53
|
+
subs.get(user_id).add(fn);
|
|
54
|
+
return () => {
|
|
55
|
+
subs.get(user_id)?.delete(fn);
|
|
56
|
+
if (subs.get(user_id)?.size === 0)
|
|
57
|
+
subs.delete(user_id);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return { broadcaster, subscribe };
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=broadcaster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcaster.js","sourceRoot":"","sources":["../../../src/lib/inbox/broadcaster.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B;;;;;;;;;;;;;;;GAeG;AAaH,MAAM,eAAe,GAAG,6BAA6B,CAAC;AACtD,MAAM,CAAC,GAAG,UAET,CAAC;AAEF,qDAAqD;AACrD,MAAM,UAAU,mBAAmB,CAAC,WAA6B;IAC/D,CAAC,CAAC,eAAe,CAAC,GAAG,WAAW,CAAC;AACnC,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB;IAIpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAqD,CAAC;IAE1E,MAAM,WAAW,GAAqB;QACpC,MAAM,CAAC,OAAe,EAAE,KAA0B;YAChD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;gBAChC,IAAI,CAAC;oBAAC,EAAE,CAAC,KAAK,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,+BAA+B,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEF,SAAS,SAAS,CAChB,OAAe,EACf,EAAwC;QAExC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1D,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -6,4 +6,6 @@ export { startInboxWorker } from "./worker/start.js";
|
|
|
6
6
|
export type { StartInboxWorkerOptions, WorkerHandle } from "./worker/start.js";
|
|
7
7
|
export { flushChannelOnce } from "./worker/flush.js";
|
|
8
8
|
export type { FlushOptions, FlushResult } from "./worker/flush.js";
|
|
9
|
+
export { setInboxBroadcaster, createInboxBroadcaster } from "./broadcaster.js";
|
|
10
|
+
export type { InboxBroadcaster, InboxBroadcastEvent } from "./broadcaster.js";
|
|
9
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACV,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAC3C,aAAa,EAAE,cAAc,GAC9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GACtD,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACV,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAC3C,aAAa,EAAE,cAAc,GAC9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GACtD,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/lib/inbox/index.js
CHANGED
|
@@ -3,4 +3,5 @@ export { initInbox } from "./connection.js";
|
|
|
3
3
|
export { listUnreadForUser, unreadCount, markRead, markAllRead, } from "./storage.js";
|
|
4
4
|
export { startInboxWorker } from "./worker/start.js";
|
|
5
5
|
export { flushChannelOnce } from "./worker/flush.js";
|
|
6
|
+
export { setInboxBroadcaster, createInboxBroadcaster } from "./broadcaster.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/inbox/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM5C,OAAO,EACL,iBAAiB,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GACtD,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/inbox/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM5C,OAAO,EACL,iBAAiB,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GACtD,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4C1F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8C1F;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAwD3G;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASpF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtG;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW1E;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxE;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlF;AAID,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAarB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpF;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAU5E;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { QueryBuilder, createCrudService } from "hazo_connect/server";
|
|
2
3
|
import { getInboxConnection } from "./connection.js";
|
|
3
4
|
/**
|
|
@@ -34,9 +35,11 @@ export async function upsertInboxRow(i) {
|
|
|
34
35
|
return { id: claimed[0].id, inserted: false };
|
|
35
36
|
}
|
|
36
37
|
// No open batch — insert a new row.
|
|
38
|
+
const new_inbox_id = randomUUID();
|
|
37
39
|
const rows = await adapter.query(new QueryBuilder()
|
|
38
40
|
.from("hazo_notify_inbox")
|
|
39
41
|
.returning("id"), "POST", {
|
|
42
|
+
id: new_inbox_id,
|
|
40
43
|
scope_id: i.scope_id,
|
|
41
44
|
user_id: i.user_id,
|
|
42
45
|
event_type: i.event_type,
|
|
@@ -48,7 +51,7 @@ export async function upsertInboxRow(i) {
|
|
|
48
51
|
surfaces: JSON.stringify(i.surfaces),
|
|
49
52
|
batch_closed_at: i.batch_closed_at,
|
|
50
53
|
});
|
|
51
|
-
return { id: rows[0]
|
|
54
|
+
return { id: rows[0]?.id ?? new_inbox_id, inserted: true };
|
|
52
55
|
}
|
|
53
56
|
/**
|
|
54
57
|
* Upsert a channel delivery row using a two-claim strategy that preserves the
|
|
@@ -88,15 +91,18 @@ export async function upsertDelivery(i) {
|
|
|
88
91
|
return { id: claimedInFlight[0].id, inserted: false, attempt_in_flight: true };
|
|
89
92
|
}
|
|
90
93
|
// Step 3: no existing row — insert a new delivery.
|
|
94
|
+
const new_delivery_id = randomUUID();
|
|
91
95
|
const rows = await adapter.query(new QueryBuilder()
|
|
92
96
|
.from("hazo_notify_channel_deliveries")
|
|
93
97
|
.returning("id"), "POST", {
|
|
98
|
+
id: new_delivery_id,
|
|
94
99
|
inbox_id: i.inbox_id,
|
|
95
100
|
channel_id: i.channel_id,
|
|
96
101
|
payload: JSON.stringify(i.payload),
|
|
102
|
+
status: i.initial_status ?? "pending",
|
|
97
103
|
flush_after: i.flush_after,
|
|
98
104
|
});
|
|
99
|
-
return { id: rows[0]
|
|
105
|
+
return { id: rows[0]?.id ?? new_delivery_id, inserted: true, attempt_in_flight: false };
|
|
100
106
|
}
|
|
101
107
|
export async function claimDueDeliveries(channel_id, batch_size) {
|
|
102
108
|
const adapter = getInboxConnection();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/lib/inbox/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAUrD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,CAAsB;IACzD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IAErC,iDAAiD;IACjD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,SAAS,CAAiB;QACtD,KAAK,EAAE,mBAAmB;QAC1B,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE;QACxD,GAAG,EAAE;YACH,eAAe,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE;YACjC,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAClC,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SAC3B;QACD,SAAS,EAAE,CAAC,IAAI,CAAC;QACjB,KAAK,EAAE,CAAC;KACT,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC;IAED,oCAAoC;IACpC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAC9B,IAAI,YAAY,EAAE;SACf,IAAI,CAAC,mBAAmB,CAAC;SACzB,SAAS,CAAC,IAAI,CAAC,EAClB,MAAM,EACN;QACE,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAClC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;QACpC,eAAe,EAAE,CAAC,CAAC,eAAe;KACnC,CACuB,CAAC;IAE3B,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/lib/inbox/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ export interface DeliveryRow {
|
|
|
24
24
|
inbox_id: string;
|
|
25
25
|
channel_id: string;
|
|
26
26
|
payload: Record<string, unknown>;
|
|
27
|
-
status: "pending" | "sent" | "failed";
|
|
27
|
+
status: "pending" | "sent" | "failed" | "digesting";
|
|
28
28
|
flush_after: string;
|
|
29
29
|
attempt_count: number;
|
|
30
30
|
message_id: string | null;
|
|
@@ -45,6 +45,11 @@ export interface DispatchInput {
|
|
|
45
45
|
channel_payloads?: Record<string, Record<string, unknown>>;
|
|
46
46
|
payload?: Record<string, unknown>;
|
|
47
47
|
batch_window_ms?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Default preference mode applied when no preference row exists for a
|
|
50
|
+
* (user × channel) pair. Defaults to 'on' (backward-compatible).
|
|
51
|
+
*/
|
|
52
|
+
preference_default?: 'on' | 'off';
|
|
48
53
|
}
|
|
49
54
|
export interface DispatchResult {
|
|
50
55
|
inbox_rows_upserted: number;
|
|
@@ -53,6 +58,8 @@ export interface DispatchResult {
|
|
|
53
58
|
deliveries_created: number;
|
|
54
59
|
deliveries_refreshed: number;
|
|
55
60
|
channels_dispatched: string[];
|
|
61
|
+
/** Delivery rows skipped because the user's preference mode was 'off'. */
|
|
62
|
+
deliveries_skipped_by_preference: number;
|
|
56
63
|
}
|
|
57
64
|
export interface UpsertInboxRowInput {
|
|
58
65
|
scope_id: string;
|
|
@@ -75,6 +82,8 @@ export interface UpsertDeliveryInput {
|
|
|
75
82
|
channel_id: string;
|
|
76
83
|
payload: Record<string, unknown>;
|
|
77
84
|
flush_after: string;
|
|
85
|
+
/** Default 'pending'. Use 'digesting' for digest-mode deliveries. */
|
|
86
|
+
initial_status?: 'pending' | 'digesting';
|
|
78
87
|
}
|
|
79
88
|
export interface UpsertDeliveryResult {
|
|
80
89
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/inbox/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Digest flush job handler factory.
|
|
3
|
+
*
|
|
4
|
+
* Claims all channel_deliveries rows with status='digesting', groups them by
|
|
5
|
+
* (user_id, channel_id), and fires one `send` call per group. Intended to be
|
|
6
|
+
* registered with hazo_jobs against `DIGEST_FLUSH_JOB_TYPE`.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import type { SendTemplateEmailOptions } from "../template_manager/types.js";
|
|
11
|
+
import type { HazoJobHandler } from "./types.js";
|
|
12
|
+
/** Stable job type registered with hazo_jobs. */
|
|
13
|
+
export declare const DIGEST_FLUSH_JOB_TYPE = "hazo_notify.digest_flush";
|
|
14
|
+
/** Payload shape for the digest flush job (all config lives in handler opts). */
|
|
15
|
+
export interface DigestFlushPayload {
|
|
16
|
+
/** Optional cap on rows claimed in one invocation. Overrides handler default. */
|
|
17
|
+
batch_size?: number;
|
|
18
|
+
}
|
|
19
|
+
/** Internal minimal adapter surface used by the handler. */
|
|
20
|
+
export interface DigestAdapter {
|
|
21
|
+
claimRows<T>(opts: {
|
|
22
|
+
table: string;
|
|
23
|
+
where: Record<string, unknown>;
|
|
24
|
+
set: Record<string, unknown>;
|
|
25
|
+
returning: string[];
|
|
26
|
+
limit: number;
|
|
27
|
+
orderBy?: {
|
|
28
|
+
column: string;
|
|
29
|
+
direction: "asc" | "desc";
|
|
30
|
+
};
|
|
31
|
+
}): Promise<T[]>;
|
|
32
|
+
query(builder: unknown, method: string): Promise<unknown[]>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Injectable send function. Accepts the template options and an adapter cast
|
|
36
|
+
* as `unknown` so callers can pass either a HazoConnectAdapter (production)
|
|
37
|
+
* or a test double.
|
|
38
|
+
*/
|
|
39
|
+
export type DigestSendFn = (options: SendTemplateEmailOptions, hazo_connect: unknown) => Promise<{
|
|
40
|
+
success: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
export interface CreateDigestFlushHandlerOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Given a user_id, returns the recipient address for that user (e.g. email).
|
|
45
|
+
*/
|
|
46
|
+
resolve_recipient: (user_id: string) => Promise<string>;
|
|
47
|
+
/** Template name used when rendering the digest email. */
|
|
48
|
+
template_name: string;
|
|
49
|
+
/** Static variables injected into every template render call. */
|
|
50
|
+
template_variables?: Record<string, string>;
|
|
51
|
+
/** Maximum rows claimed per invocation. Defaults to 500. */
|
|
52
|
+
batch_size?: number;
|
|
53
|
+
/** scope_id forwarded to send_template_email. Defaults to null. */
|
|
54
|
+
scope_id?: string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Injectable adapter for testing. When omitted, `getInboxConnection()` is
|
|
57
|
+
* called at invocation time.
|
|
58
|
+
*/
|
|
59
|
+
_adapter?: DigestAdapter;
|
|
60
|
+
/**
|
|
61
|
+
* Injectable send function for testing. When omitted, `send_template_email`
|
|
62
|
+
* is used.
|
|
63
|
+
*/
|
|
64
|
+
_send?: DigestSendFn;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Factory that creates a hazo_jobs-compatible handler for digest flush.
|
|
68
|
+
*
|
|
69
|
+
* The handler:
|
|
70
|
+
* 1. Claims all deliveries with status='digesting' up to `batch_size`.
|
|
71
|
+
* 2. Enriches each row with user_id from hazo_notify_inbox when not already
|
|
72
|
+
* present on the claimed row.
|
|
73
|
+
* 3. Groups rows by (user_id, channel_id).
|
|
74
|
+
* 4. Fires one `_send` call per group, then marks each row sent/failed.
|
|
75
|
+
*/
|
|
76
|
+
export declare function createDigestFlushHandler(opts: CreateDigestFlushHandlerOptions): HazoJobHandler<DigestFlushPayload>;
|
|
77
|
+
//# sourceMappingURL=digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../../src/lib/jobs/digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,iDAAiD;AACjD,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAcD,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7B,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC;KACzD,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACjB,KAAK,CACH,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,wBAAwB,EACjC,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEnC,MAAM,WAAW,+BAA+B;IAC9C;;OAEG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAExD,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IAEtB,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE5C,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;;OAGG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,+BAA+B,GACpC,cAAc,CAAC,kBAAkB,CAAC,CA0IpC"}
|