Initial commit

This commit is contained in:
Aditya Gupta
2026-06-29 19:29:19 +05:30
committed by GitHub
commit aabb8986aa
292 changed files with 17976 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
export { withSuspense } from './with-suspense.js';
export { withErrorBoundary } from './with-error-boundary.js';

View File

@@ -0,0 +1,15 @@
import { ErrorBoundary } from 'react-error-boundary';
import type { ComponentType } from 'react';
import type { FallbackProps } from 'react-error-boundary';
export const withErrorBoundary = <T extends Record<string, unknown>>(
Component: ComponentType<T>,
FallbackComponent: ComponentType<FallbackProps>,
) =>
function WithErrorBoundary(props: T) {
return (
<ErrorBoundary FallbackComponent={FallbackComponent}>
<Component {...props} />
</ErrorBoundary>
);
};

View File

@@ -0,0 +1,10 @@
import { Suspense } from 'react';
import type { ComponentType, ReactElement } from 'react';
export const withSuspense =
<T extends Record<string, unknown>>(Component: ComponentType<T>, SuspenseComponent: ReactElement) =>
(props: T) => (
<Suspense fallback={SuspenseComponent}>
<Component {...props} />
</Suspense>
);

View File

@@ -0,0 +1 @@
export * from './use-storage.js';

View File

@@ -0,0 +1,56 @@
import { useRef, useSyncExternalStore } from 'react';
import type { BaseStorageType } from '@extension/storage';
type WrappedPromise = ReturnType<typeof wrapPromise>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const storageMap: Map<BaseStorageType<any>, WrappedPromise> = new Map();
const wrapPromise = <R,>(promise: Promise<R>) => {
let status = 'pending';
let result: R;
const suspender = promise.then(
r => {
status = 'success';
result = r;
},
e => {
status = 'error';
result = e;
},
);
return {
read() {
switch (status) {
case 'pending':
throw suspender;
case 'error':
throw result;
default:
return result;
}
},
};
};
export const useStorage = <
Storage extends BaseStorageType<Data>,
Data = Storage extends BaseStorageType<infer Data> ? Data : unknown,
>(
storage: Storage,
) => {
const initializedRef = useRef(false);
const _data = useSyncExternalStore<Data | null>(storage.subscribe, storage.getSnapshot);
if (!storageMap.has(storage)) {
storageMap.set(storage, wrapPromise(storage.get()));
}
if (_data || initializedRef.current) {
storageMap.set(storage, { read: () => _data });
initializedRef.current = true;
}
return (_data ?? storageMap.get(storage)!.read()) as Exclude<Data, PromiseLike<unknown>>;
};

View File

@@ -0,0 +1,27 @@
import { COLORS } from './const.js';
import type { ColorType, ValueOf } from './types.js';
export const colorfulLog = (message: string, type: ColorType) => {
let color: ValueOf<typeof COLORS>;
switch (type) {
case 'success':
color = COLORS.FgGreen;
break;
case 'info':
color = COLORS.FgBlue;
break;
case 'error':
color = COLORS.FgRed;
break;
case 'warning':
color = COLORS.FgYellow;
break;
default:
color = COLORS[type];
break;
}
console.info(color, message);
console.info(COLORS['Reset']);
};

View File

@@ -0,0 +1,25 @@
export const COLORS = {
Reset: '\x1b[0m',
Bright: '\x1b[1m',
Dim: '\x1b[2m',
Underscore: '\x1b[4m',
Blink: '\x1b[5m',
Reverse: '\x1b[7m',
Hidden: '\x1b[8m',
FgBlack: '\x1b[30m',
FgRed: '\x1b[31m',
FgGreen: '\x1b[32m',
FgYellow: '\x1b[33m',
FgBlue: '\x1b[34m',
FgMagenta: '\x1b[35m',
FgCyan: '\x1b[36m',
FgWhite: '\x1b[37m',
BgBlack: '\x1b[40m',
BgRed: '\x1b[41m',
BgGreen: '\x1b[42m',
BgYellow: '\x1b[43m',
BgBlue: '\x1b[44m',
BgMagenta: '\x1b[45m',
BgCyan: '\x1b[46m',
BgWhite: '\x1b[47m',
} as const;

View File

@@ -0,0 +1,8 @@
import type { ExcludeValuesFromBaseArrayType } from './types.js';
export const excludeValuesFromBaseArray = <B extends string[], E extends (string | number)[]>(
baseArray: B,
excludeArray: E,
) => baseArray.filter(value => !excludeArray.includes(value)) as ExcludeValuesFromBaseArrayType<B, E>;
export const sleep = async (time: number) => new Promise(r => setTimeout(r, time));

View File

@@ -0,0 +1,4 @@
export * from './helpers.js';
export * from './colorful-logger.js';
export * from './init-app-with-shadow.js';
export type * from './types.js';

View File

@@ -0,0 +1,34 @@
import { createRoot } from 'react-dom/client';
import type { ReactElement } from 'react';
export const initAppWithShadow = ({ id, app, inlineCss }: { id: string; inlineCss: string; app: ReactElement }) => {
const root = document.createElement('div');
root.id = id;
document.body.append(root);
const rootIntoShadow = document.createElement('div');
rootIntoShadow.id = `shadow-root-${id}`;
const shadowRoot = root.attachShadow({ mode: 'open' });
if (navigator.userAgent.includes('Firefox')) {
/**
* In the firefox environment, adoptedStyleSheets cannot be used due to the bug
* @url https://bugzilla.mozilla.org/show_bug.cgi?id=1770592
*
* Injecting styles into the document, this may cause style conflicts with the host page
*/
const styleElement = document.createElement('style');
styleElement.innerHTML = inlineCss;
shadowRoot.appendChild(styleElement);
} else {
/** Inject styles into shadow dom */
const globalStyleSheet = new CSSStyleSheet();
globalStyleSheet.replaceSync(inlineCss);
shadowRoot.adoptedStyleSheets = [globalStyleSheet];
}
shadowRoot.appendChild(rootIntoShadow);
createRoot(rootIntoShadow).render(app);
};

View File

@@ -0,0 +1,10 @@
import type { COLORS } from './const.js';
import type { TupleToUnion } from 'type-fest';
export type * from 'type-fest';
export type ColorType = 'success' | 'info' | 'error' | 'warning' | keyof typeof COLORS;
export type ExcludeValuesFromBaseArrayType<B extends string[], E extends (string | number)[]> = Exclude<
TupleToUnion<B>,
TupleToUnion<E>
>[];
export type ManifestType = chrome.runtime.ManifestV3;