[READ-ONLY] Mirror of https://github.com/flo-bit/skywatched. review movies and tv shows, based on at proto
skywatched.app
1.5 kB
60 lines
1import { getFormatter } from './formatter';
2import { render } from './render';
3import type { Callback, RenderState } from './render';
4
5interface UpdateState extends RenderState {
6 update: number;
7}
8
9// keep track of each instance
10const instances = new Map<Object, UpdateState>();
11
12// we use a single timer for efficiency and to keep updates in sync
13let updateInterval: number | NodeJS.Timeout;
14
15// register or update instance
16export function register(
17 instance: Object,
18 date: Date | number,
19 locale: string,
20 live: boolean,
21 callback: Callback
22) {
23 // get the formatter for the given locale, we do this here so we don't keep having to look it up on each tick
24 const formatter = getFormatter(locale);
25
26 // create state to render
27 const state = { date, callback, formatter };
28
29 // initial render is immediate, so works for SSR
30 const update = render(state, Date.now());
31
32 // if it's to update live, we keep a track and schedule the next update
33 if (live) {
34 instances.set(instance, { ...state, update });
35 } else {
36 instances.delete(instance);
37 }
38
39 // start the clock ticking if there are any live instances
40 if (instances.size) {
41 updateInterval =
42 updateInterval ||
43 setInterval(() => {
44 const now = Date.now();
45 for (const state of instances.values()) {
46 if (state.update <= now) {
47 state.update = render(state, now);
48 }
49 }
50 }, 1000);
51 }
52}
53
54export function unregister(instance: Object) {
55 instances.delete(instance);
56 if (instances.size === 0) {
57 clearInterval(updateInterval);
58 updateInterval = 0;
59 }
60}