Add monorepo support to project (#682)
* feat: add monorepo support * fix: correct relatedProjects structure in vercel.json * update github actions with monorepo support * removed legacy dep * moved jsr config into web package
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
|
||||
export const FLAGS_CONFIG = {
|
||||
UNSET: { value: 0, i18nKey: "position.flags.unset" },
|
||||
ALTITUDE: { value: 1, i18nKey: "position.flags.altitude" },
|
||||
ALTITUDE_MSL: { value: 2, i18nKey: "position.flags.altitudeMsl" },
|
||||
ALTITUDE_GEOIDAL_SEPARATION: {
|
||||
value: 4,
|
||||
i18nKey: "position.flags.altitudeGeoidalSeparation",
|
||||
},
|
||||
DOP: {
|
||||
value: 8,
|
||||
i18nKey: "position.flags.dop",
|
||||
},
|
||||
HDOP_VDOP: {
|
||||
value: 16,
|
||||
i18nKey: "position.flags.hdopVdop",
|
||||
},
|
||||
NUM_SATELLITES: {
|
||||
value: 32,
|
||||
i18nKey: "position.flags.numSatellites",
|
||||
},
|
||||
SEQUENCE_NUMBER: {
|
||||
value: 64,
|
||||
i18nKey: "position.flags.sequenceNumber",
|
||||
},
|
||||
TIMESTAMP: { value: 128, i18nKey: "position.flags.timestamp" },
|
||||
VEHICLE_HEADING: {
|
||||
value: 256,
|
||||
i18nKey: "position.flags.vehicleHeading",
|
||||
},
|
||||
VEHICLE_SPEED: { value: 512, i18nKey: "position.flags.vehicleSpeed" },
|
||||
} as const;
|
||||
|
||||
export type FlagName = keyof typeof FLAGS_CONFIG;
|
||||
|
||||
type UsePositionFlagsProps = {
|
||||
decode: (value: number) => FlagName[];
|
||||
encode: (flagNames: FlagName[]) => number;
|
||||
hasFlag: (value: number, flagName: FlagName) => boolean;
|
||||
getAllFlags: () => typeof FLAGS_CONFIG;
|
||||
isValidValue: (value: number) => boolean;
|
||||
flagsValue: number;
|
||||
activeFlags: FlagName[];
|
||||
toggleFlag: (flagName: FlagName) => void;
|
||||
setFlag: (flagName: FlagName, enabled: boolean) => void;
|
||||
setFlags: (value: number) => void;
|
||||
clearFlags: () => void;
|
||||
};
|
||||
|
||||
export const usePositionFlags = (initialValue = 0): UsePositionFlagsProps => {
|
||||
const [flagsValue, setFlagsValue] = useState<number>(initialValue);
|
||||
|
||||
const FLAGS_BITMASKS = useMemo(() => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(FLAGS_CONFIG).map(([key, conf]) => [key, conf.value]),
|
||||
) as { [K in FlagName]: typeof FLAGS_CONFIG[K]["value"] };
|
||||
}, []);
|
||||
|
||||
const utils = useMemo(() => {
|
||||
const decode = (value: number): FlagName[] => {
|
||||
if (value === FLAGS_CONFIG.UNSET.value) return ["UNSET"];
|
||||
|
||||
const activeFlags: FlagName[] = [];
|
||||
for (const key in FLAGS_CONFIG) {
|
||||
const flagName = key as FlagName;
|
||||
const flagConfig = FLAGS_CONFIG[flagName];
|
||||
if (
|
||||
flagConfig.value !== 0 &&
|
||||
(value & flagConfig.value) === flagConfig.value
|
||||
) {
|
||||
activeFlags.push(flagName);
|
||||
}
|
||||
}
|
||||
return activeFlags;
|
||||
};
|
||||
|
||||
const encode = (flagNames: FlagName[]): number => {
|
||||
if (flagNames.includes("UNSET") && flagNames.length === 1) {
|
||||
return FLAGS_CONFIG.UNSET.value;
|
||||
}
|
||||
return flagNames.reduce((acc, name) => {
|
||||
if (name === "UNSET") return acc;
|
||||
return acc | FLAGS_CONFIG[name].value;
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const hasFlag = (value: number, flagName: FlagName): boolean => {
|
||||
return (value & FLAGS_CONFIG[flagName].value) ===
|
||||
FLAGS_CONFIG[flagName].value;
|
||||
};
|
||||
|
||||
const getAllFlags = (): typeof FLAGS_CONFIG => {
|
||||
return FLAGS_CONFIG;
|
||||
};
|
||||
|
||||
const isValidValue = (value: number): boolean => {
|
||||
const maxValue = Object.values(FLAGS_BITMASKS)
|
||||
.filter((val) => val !== 0)
|
||||
.reduce((acc, val) => acc | val, 0);
|
||||
return Number.isInteger(value) && value >= 0 && value <= maxValue;
|
||||
};
|
||||
|
||||
return {
|
||||
decode,
|
||||
encode,
|
||||
hasFlag,
|
||||
getAllFlags,
|
||||
isValidValue,
|
||||
};
|
||||
}, [FLAGS_BITMASKS]);
|
||||
|
||||
const toggleFlag = useCallback((flagName: FlagName) => {
|
||||
setFlagsValue((prev) => prev ^ FLAGS_CONFIG[flagName].value);
|
||||
}, []);
|
||||
|
||||
const setFlag = useCallback((flagName: FlagName, enabled: boolean) => {
|
||||
const currentFlagValue = FLAGS_CONFIG[flagName].value;
|
||||
setFlagsValue((prev) =>
|
||||
enabled ? prev | currentFlagValue : prev & ~currentFlagValue
|
||||
);
|
||||
}, []);
|
||||
|
||||
const setFlags = useCallback(
|
||||
(value: number) => {
|
||||
if (!utils.isValidValue(value)) {
|
||||
throw new Error(`Invalid flags value: ${value}`);
|
||||
}
|
||||
setFlagsValue(value);
|
||||
},
|
||||
[utils],
|
||||
);
|
||||
|
||||
const clearFlags = useCallback(() => {
|
||||
setFlagsValue(FLAGS_CONFIG.UNSET.value);
|
||||
}, []);
|
||||
|
||||
const activeFlags = utils.decode(flagsValue);
|
||||
|
||||
return {
|
||||
...utils,
|
||||
flagsValue,
|
||||
activeFlags,
|
||||
toggleFlag,
|
||||
setFlag,
|
||||
setFlags,
|
||||
clearFlags,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user