-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog.ts
More file actions
65 lines (53 loc) · 1.66 KB
/
Copy pathlog.ts
File metadata and controls
65 lines (53 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import type { ActivityEvent, ActivityEventInput } from './types';
type AppendListener = (event: ActivityEvent) => void;
type LogState = {
events: ActivityEvent[];
seq: number;
listeners: Set<AppendListener>;
};
const GLOBAL_KEY = Symbol.for('super.activity.events.log');
type GlobalWithLog = typeof globalThis & { [GLOBAL_KEY]?: LogState };
function getState(): LogState {
const g = globalThis as GlobalWithLog;
let existing = g[GLOBAL_KEY];
if (!existing) {
existing = { events: [], seq: 0, listeners: new Set() };
g[GLOBAL_KEY] = existing;
}
return existing;
}
export function appendEvent(input: ActivityEventInput): ActivityEvent {
const state = getState();
state.seq += 1;
const at = input.at ?? new Date().toISOString();
const event = { ...input, seq: state.seq, at } as ActivityEvent;
state.events.push(event);
for (const listener of state.listeners) {
listener(event);
}
return event;
}
export function onAppend(listener: AppendListener): () => void {
const state = getState();
state.listeners.add(listener);
return () => {
state.listeners.delete(listener);
};
}
export function getAllEvents(): readonly ActivityEvent[] {
return getState().events;
}
export function getEventsSince(sinceSeq: number): ActivityEvent[] {
return getState().events.filter((event) => event.seq > sinceSeq);
}
export function getEventsForOffer(offerId: string): ActivityEvent[] {
return getState().events.filter((event) => event.offer_id === offerId);
}
export function getLatestSeq(): number {
return getState().seq;
}
export function __resetActivityEventLog(): void {
const state = getState();
state.events = [];
state.seq = 0;
}