Line data Source code
1 : import * as React from 'react';
2 :
3 : import { Logger } from './logger.js';
4 : import { WebLogger } from './web_logger.js';
5 :
6 1 : const LOGGER_CTX = React.createContext<Logger | null>(null);
7 1 : let GLOBAL_LOGGER: Logger | null;
8 1 : export function getGlobalLogger(): Logger | null { return GLOBAL_LOGGER; }
9 :
10 1 : export const useLogger = () => React.useContext(LOGGER_CTX)!;
11 :
12 : type Props = {
13 : children: React.ReactElement | React.ReactElement[];
14 : };
15 :
16 1 : export const LoggerProvider: React.FC<Props> = (props: Props) => {
17 1 : const logger = React.useMemo<Logger>(() => {
18 1 : const logger: Logger = new WebLogger();
19 1 : GLOBAL_LOGGER = logger;
20 1 : return logger;
21 1 : }, []);
22 1 : return (
23 1 : <LOGGER_CTX.Provider value={logger}>
24 1 : {props.children}
25 1 : </LOGGER_CTX.Provider>
26 : )
27 1 : };
28 :
29 : /// Poll the log version and translate into React state.
30 : /// We deliberately do not use eager state updates from the log flusher.
31 : /// Pass enabled = false to skip polling, e.g. when a trace subscription already drives the component.
32 1 : export function pollLogVersion(interval: number = 100, enabled: boolean = true) {
33 1 : const logger = useLogger();
34 1 : const [logVersion, setLogVersion] = React.useState<number>(logger.buffer.version);
35 : // Compare against a ref, the interval closure would otherwise only see the initial version
36 1 : const logVersionRef = React.useRef<number>(logVersion);
37 1 : React.useEffect(() => {
38 1 : if (!enabled) {
39 1 : return;
40 : }
41 1 : const intervalId = setInterval(() => {
42 1 : const version = logger.buffer.version;
43 1 : if (version !== logVersionRef.current) {
44 1 : logVersionRef.current = version;
45 1 : setLogVersion(version);
46 1 : }
47 1 : }, interval);
48 1 : return () => {
49 1 : clearInterval(intervalId);
50 1 : };
51 1 : }, [logger, interval, enabled]);
52 1 : return logVersion;
53 1 : }
|