2.9 KB100 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {ViteHotContext} from 'vite/types/hot';
9import type {CommitInfo, Disposable, Hash} from './types';
10
11export function firstOfIterable<T>(it: IterableIterator<T>): T | undefined {
12 return it.next().value;
13}
14
15/** Get the short 12-character hash from a full hash. */
16export function short(hash: Hash): string {
17 return hash.slice(0, 12);
18}
19
20export function assert(shouldBeTrue: boolean, error: string): asserts shouldBeTrue {
21 if (!shouldBeTrue) {
22 throw new Error(error);
23 }
24}
25
26export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
27 if (a.length !== b.length) {
28 return false;
29 }
30 return a.every((val, i) => b[i] === val);
31}
32
33export type NonNullReactElement = React.ReactElement | React.ReactFragment;
34
35export function getWindowWidthInPixels(): number {
36 if (isTest) {
37 return 1000;
38 }
39 // Use client width and not screen width to handle embedding as an iframe.
40 return document.body.clientWidth;
41}
42
43export function leftPad(val: string | number, len: number, char: string) {
44 const str = val.toString();
45 return `${Array(len - str.length + 1).join(char)}${str}`;
46}
47
48/** Whether running in a test environment. */
49export const isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test';
50
51export const isDev = process.env.NODE_ENV === 'development';
52
53const cleanUpRegister = new FinalizationRegistry<() => void>((cleanUp: () => void) => {
54 cleanUp();
55});
56
57/**
58 * Register a clean up callback or a disposable when `obj` is GC-ed.
59 *
60 * If `hot` is set (`import.meta.hot`), the `cleanUp` is registered with the
61 * hot reload API instead. Note the `import.meta` depends on where it lives.
62 * So we cannot use `import.meta` here (which will affect this `utils.ts` hot
63 * reloading behavior, not the callsite module).
64 */
65export function registerCleanup(obj: object, cleanUp: () => void, hot?: ViteHotContext): void {
66 if (hot != null) {
67 hot.dispose(() => {
68 cleanUp();
69 });
70 } else {
71 cleanUpRegister.register(obj, cleanUp);
72 }
73}
74
75/** Similar to `registerCleanup`, but takes a `Disposable` */
76export function registerDisposable(
77 obj: object,
78 disposable: Disposable,
79 hot?: ViteHotContext,
80): void {
81 registerCleanup(obj, () => disposable.dispose(), hot);
82}
83
84/** Calculate hour difference between two dates (date1 - date2) */
85export function calculateHourDifference(date1: Date, date2: Date): number {
86 const msDifference = date1.getTime() - date2.getTime();
87 const hoursDifference = msDifference / (1000 * 60 * 60);
88 return hoursDifference;
89}
90
91/**
92 * Check if a commit is on the master branch
93 */
94export function isCommitMaster(commit: CommitInfo): boolean {
95 if (commit.remoteBookmarks == null) {
96 return false;
97 }
98 return commit.remoteBookmarks.some(bookmark => bookmark.includes('master'));
99}
100