diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index ca612f4..109a998 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -2,7 +2,7 @@ name: Docker Image CI on: push: - branches: ["*"] + branches: ['*'] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..6cc0e70 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,14 @@ +repos: + # - repo: https://github.com/pre-commit/mirrors-eslint + # rev: v9.5.0 # Use the version of ESLint you need + # hooks: + # - id: eslint + # additional_dependencies: + # - "@typescript-eslint/eslint-plugin@latest" + # - "@typescript-eslint/parser@latest" + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 # Use the version of Prettier you need + hooks: + - id: prettier + additional_dependencies: [] diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..5c5248c --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,58 @@ +import typescriptEslint from '@typescript-eslint/eslint-plugin' +import globals from 'globals' +import parser from 'vue-eslint-parser' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import js from '@eslint/js' +import { FlatCompat } from '@eslint/eslintrc' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}) + +export default [ + ...compat.extends( + 'plugin:vue/vue3-recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'eslint:recommended', + ), + { + plugins: { + '@typescript-eslint': typescriptEslint, + }, + + languageOptions: { + globals: { + ...globals.node, + }, + + parser: parser, + ecmaVersion: 'latest', + sourceType: 'commonjs', + + parserOptions: { + parser: '@typescript-eslint/parser', + sourceType: 'module', + project: './tsconfig.json', // Ensure this points to your tsconfig.json file + }, + }, + + rules: { + 'no-unused-vars': 'off', + + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, + }, +] diff --git a/index.html b/index.html index 10b9404..7d92d43 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + diff --git a/package.json b/package.json index 37a931b..23ac103 100644 --- a/package.json +++ b/package.json @@ -21,14 +21,14 @@ "vue3-shortkey": "^4.0.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.19.0", - "@typescript-eslint/parser": "^6.19.0", + "@typescript-eslint/eslint-plugin": "^7.13.1", + "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-vue": "^5.0.0", "eslint": "^8.56.0", "eslint-plugin-vue": "^9.20.1", "eslint-scope": "^8.0.0", "sass": "^1.69.7", - "typescript": "^5.3.3", + "typescript": "^5.5.2", "vite": "^5.0.13", "vue-eslint-parser": "^9.4.0" }, diff --git a/src/components/referee/LogoAndActions.vue b/src/components/referee/LogoAndActions.vue index 5d0f16a..0b4296f 100644 --- a/src/components/referee/LogoAndActions.vue +++ b/src/components/referee/LogoAndActions.vue @@ -6,8 +6,10 @@
@@ -68,6 +70,14 @@ + + + + - - + @@ -64,7 +102,7 @@ import Select from '@/components/shared/ui/Select.vue' import Input from '@/components/shared/ui/Input.vue' import Button from '@/components/shared/ui/Button.vue' import { useKeyboardStore } from '@/store/keyboardStore' -import { type Ref, ref, type ComputedRef, computed, watch } from 'vue' +import { type Ref, ref, type ComputedRef, watch } from 'vue' // use stores - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const presetStore = usePresetStore() @@ -77,58 +115,83 @@ const selection = ref<{ [key: string]: string }>({ exploration: 'hard', navigation: 'hard', production: 'c3', -}); -const groundTruthValues = ref<{ [key: string]: string }>({ -}); +}) +const groundTruthValues = ref<{ [key: string]: string }>({}) // Define a method to capitalize the first letter of a string const capitalizeFirstLetter = (str: string) => { - return str.charAt(0).toUpperCase() + str.slice(1); + return str.charAt(0).toUpperCase() + str.slice(1) } // Define a method to get preset options based on the category const getPresetOptions = (category: string) => { - // Filter configPresets to find presets belonging to the specified category - const presetsInCategory = Array.from(configPresets.value) - .filter(preset => preset.category === category); + // Filter configPresets to find presets belonging to the specified category + const presetsInCategory = Array.from(configPresets.value).filter( + (preset) => preset.category === category, + ) // Extract unique preset values from the filtered presets - const uniquePresets = [...new Set(presetsInCategory.map(preset => preset.preset))]; + const uniquePresets = [ + ...new Set(presetsInCategory.map((preset) => preset.preset)), + ] // Return the unique preset values as options - return uniquePresets; + return uniquePresets } function applyChanges(category) { - const currSelection = selection._rawValue[category]; - if (category === "grasping") { - presetStore.sendSetConfigPreset({ category: "challenges/grasping", preset: "grasping" }); - presetStore.sendSetConfigPreset({ category: "challenges/grasping", preset: "grasping_game" }); - return; + const currSelection = selection._rawValue[category] + if (category === 'grasping') { + presetStore.sendSetConfigPreset({ + category: 'challenges/grasping', + preset: 'grasping', + }) + presetStore.sendSetConfigPreset({ + category: 'challenges/grasping', + preset: 'grasping_game', + }) + return } if (currSelection === undefined) { - console.log("Ignoring due to undefined selection"); - } else if (category === "exploration") { - const currPreset = `exploration_${currSelection}`; - presetStore.sendSetConfigPreset({ category: "challenges/exp", preset: currPreset }); - } else if ( category === "navigation") { - const currPreset = `nav_${currSelection}`; - presetStore.sendSetConfigPreset({ category: "challenges/nav", preset: currPreset }); - } else if ( category === "production") { - const currGroundTruth = groundTruthValues._rawValue[category]; - if (currGroundTruth === undefined) { - console.log("Ignoring due to undefined selection of ground truth option"); - } else if (currGroundTruth === "ground truth") { - presetStore.sendSetConfigPreset({ category: "challenges/prod", preset: currSelection }); - } else if (currGroundTruth === "no ground truth") { - presetStore.sendSetConfigPreset({ category: "challenges/prod", preset: currSelection }); + console.log('Ignoring due to undefined selection') + } else if (category === 'exploration') { + const currPreset = `exploration_${currSelection}` + presetStore.sendSetConfigPreset({ + category: 'challenges/exp', + preset: currPreset, + }) + } else if (category === 'navigation') { + const currPreset = `nav_${currSelection}` + presetStore.sendSetConfigPreset({ + category: 'challenges/nav', + preset: currPreset, + }) + } else if (category === 'production') { + const currGroundTruth = groundTruthValues._rawValue[category] + if (currGroundTruth === undefined) { + console.log('Ignoring due to undefined selection of ground truth option') + } else if (currGroundTruth === 'ground truth') { + presetStore.sendSetConfigPreset({ + category: 'challenges/prod', + preset: currSelection, + }) + } else if (currGroundTruth === 'no ground truth') { + presetStore.sendSetConfigPreset({ + category: 'challenges/prod', + preset: currSelection, + }) } else { - console.log("Ignoring due to unknown ground truth selection", currGroundTruth); + console.log( + 'Ignoring due to unknown ground truth selection', + currGroundTruth, + ) } } else { - presetStore.sendSetConfigPreset({ category: category, preset: currSelection }); + presetStore.sendSetConfigPreset({ + category: category, + preset: currSelection, + }) } } - // tabs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const iconLookupMap = { challenges: 'fa-medal', @@ -138,22 +201,26 @@ const iconLookupMap = { game: 'fa-gamepad', comm: 'fa-walkie-talkie', team: 'fa-people-group', - simulation: 'fa-atom' -}; - const defaultIcon = 'fa-khanda'; + simulation: 'fa-atom', +} +const defaultIcon = 'fa-khanda' //const tabs = Array.from(new Set(Array.from(configPresets._rawValue).map(preset => preset.category))); -const tabs = Array.from(new Set( - Array.from(configPresets._rawValue) - .filter(preset => preset.category !== "") // Exclude entries where category is empty - .map(preset => { - const category = preset.category.startsWith('challenges/') ? 'challenges' : preset.category; - return category; - }) -)); +const tabs = Array.from( + new Set( + Array.from(configPresets._rawValue) + .filter((preset) => preset.category !== '') // Exclude entries where category is empty + .map((preset) => { + const category = preset.category.startsWith('challenges/') + ? 'challenges' + : preset.category + return category + }), + ), +) //const tabs: string[] = ['challenges','machines', 'mongodb'] -const tabIcons = tabs.map(tab => iconLookupMap[tab] || defaultIcon); +const tabIcons = tabs.map((tab) => iconLookupMap[tab] || defaultIcon) const activeTab: Ref = ref('challenges') -const tab = undefined; +const tab = undefined // STYLE ----------------------------------------------------------------------- @@ -166,7 +233,9 @@ const tab = undefined; border-radius: 4px; padding: 0.3em 0.7em; border-bottom: 2px solid global.$lighterColor; - box-shadow: 0 1px 0px global.$bgColor, 0 0 0 2px global.$lightestColor inset; + box-shadow: + 0 1px 0px global.$bgColor, + 0 0 0 2px global.$lightestColor inset; background-color: global.$surfaceColor; text-transform: capitalize; } diff --git a/src/components/referee/popups/GameConfigPopup.vue b/src/components/referee/popups/GameConfigPopup.vue index ec17c66..0c13089 100644 --- a/src/components/referee/popups/GameConfigPopup.vue +++ b/src/components/referee/popups/GameConfigPopup.vue @@ -15,9 +15,17 @@
- + - +
@@ -42,17 +50,17 @@ const { gameConfig } = storeToRefs(configStore) // filter config paths - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const filter: Ref = ref('') -const editedValues = ref({}); - +const editedValues = ref({}) function applyChanges(path) { - console.log('editedValues:', editedValues); const newValue = editedValues._rawValue[path]; - console.log('Applying changes for', path, 'with value:', newValue); - configStore.sendSetConfigValue({ path: path, value: newValue }); + console.log('editedValues:', editedValues) + const newValue = editedValues._rawValue[path] + console.log('Applying changes for', path, 'with value:', newValue) + configStore.sendSetConfigValue({ path: path, value: newValue }) } const filteredGameConfigValues: ComputedRef<[string, any][]> = computed(() => - [...gameConfig.value].filter(([path, _]) => path.includes(filter.value)) + [...gameConfig.value].filter(([path, _]) => path.includes(filter.value)), ) const popup: Ref = ref() @@ -62,7 +70,7 @@ watch( if (popup.value) { popup.value.scrollToTop() } - } + }, ) diff --git a/src/components/referee/popups/HelpPopup.vue b/src/components/referee/popups/HelpPopup.vue index 58889d4..3253648 100644 --- a/src/components/referee/popups/HelpPopup.vue +++ b/src/components/referee/popups/HelpPopup.vue @@ -92,7 +92,9 @@ const activeTab: Ref = ref('Q&A') border-radius: 4px; padding: 0.3em 0.7em; border-bottom: 2px solid global.$lighterColor; - box-shadow: 0 1px 0px global.$bgColor, 0 0 0 2px global.$lightestColor inset; + box-shadow: + 0 1px 0px global.$bgColor, + 0 0 0 2px global.$lightestColor inset; background-color: global.$surfaceColor; text-transform: capitalize; } diff --git a/src/components/referee/popups/InstructMachinePopup.vue b/src/components/referee/popups/InstructMachinePopup.vue new file mode 100644 index 0000000..8a2cea2 --- /dev/null +++ b/src/components/referee/popups/InstructMachinePopup.vue @@ -0,0 +1,256 @@ +// TEMPLATE -------------------------------------------------------------------- + + +// SCRIPT ---------------------------------------------------------------------- + + +// STYLE ----------------------------------------------------------------------- + diff --git a/src/components/shared/ui/AutoScrollContainer.vue b/src/components/shared/ui/AutoScrollContainer.vue index 2a1009e..72e72fa 100644 --- a/src/components/shared/ui/AutoScrollContainer.vue +++ b/src/components/shared/ui/AutoScrollContainer.vue @@ -74,7 +74,7 @@ watch( scrollToEnd() } }, - { deep: true, immediate: true } + { deep: true, immediate: true }, ) defineExpose({ scrollToEnd }) diff --git a/src/components/shared/ui/PopupWrapper.vue b/src/components/shared/ui/PopupWrapper.vue index 7e62a50..5df2ef6 100644 --- a/src/components/shared/ui/PopupWrapper.vue +++ b/src/components/shared/ui/PopupWrapper.vue @@ -1,7 +1,11 @@ // TEMPLATE -------------------------------------------------------------------- // SCRIPT ---------------------------------------------------------------------- - diff --git a/src/components/shared/util/ConnectToDbBackend.vue b/src/components/shared/util/ConnectToDbBackend.vue index 0051f75..2aa47d8 100644 --- a/src/components/shared/util/ConnectToDbBackend.vue +++ b/src/components/shared/util/ConnectToDbBackend.vue @@ -77,7 +77,7 @@ (new Date(reportItem.end_time).getTime() - new Date(reportItem.start_time).getTime()) / 1000, - true + true, ) }} @@ -189,7 +189,7 @@ const filteredGameReportsList: ComputedRef = computed(() => { (report) => report.report_name.includes(filter.value) || report.teams[0].includes(filter.value) || - report.teams[1].includes(filter.value) + report.teams[1].includes(filter.value), ) }) const scrollToTop = inject('scrollToTop') as Function @@ -197,7 +197,7 @@ watch( () => filter.value, () => { scrollToTop() - } + }, ) // select report - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -220,7 +220,7 @@ watch( if (newReport && (!oldReport || oldReport != newReport)) { emit('connected') } - } + }, ) diff --git a/src/components/shared/util/ConnectToWebsocket.vue b/src/components/shared/util/ConnectToWebsocket.vue index c5b08bc..f4c1176 100644 --- a/src/components/shared/util/ConnectToWebsocket.vue +++ b/src/components/shared/util/ConnectToWebsocket.vue @@ -1,24 +1,32 @@ // TEMPLATE -------------------------------------------------------------------- // SCRIPT ---------------------------------------------------------------------- + diff --git a/src/components/spectator/GameInfoBoard.vue b/src/components/spectator/GameInfoBoard.vue index 73568d5..69e13ff 100644 --- a/src/components/spectator/GameInfoBoard.vue +++ b/src/components/spectator/GameInfoBoard.vue @@ -121,7 +121,7 @@ • {{ formatTime( - PRODUCTION_DURATION + OVERTIME_DURATION - game_time + PRODUCTION_DURATION + OVERTIME_DURATION - game_time, ) }} remaining diff --git a/src/components/spectator/PlayingField.vue b/src/components/spectator/PlayingField.vue index e4bce3a..e92b99d 100644 --- a/src/components/spectator/PlayingField.vue +++ b/src/components/spectator/PlayingField.vue @@ -1,5 +1,9 @@ // TEMPLATE -------------------------------------------------------------------- @@ -24,6 +44,16 @@ @@ -35,14 +65,14 @@ v-if=" robotStore.robotByColorAndId( agentTask.team_color, - agentTask.robot_id + agentTask.robot_id, ) != null " :task="agentTask" :robot=" robotStore.robotByColorAndId( agentTask.team_color, - agentTask.robot_id + agentTask.robot_id, ) as Robot " /> @@ -58,6 +88,7 @@ // STYLE ----------------------------------------------------------------------- @@ -65,6 +115,15 @@ const machine: ComputedRef = computed(() => { } } + &.selected { + border: 2px solid blue; // Highlight selected square + background-color: global.$surfaceColor; + } + + &.targeted { + border: 2px solid red; // Highlight targeted square + } + .zone-info { display: none; diff --git a/src/components/spectator/ScoreBoard.vue b/src/components/spectator/ScoreBoard.vue index 92050ff..6af39c2 100644 --- a/src/components/spectator/ScoreBoard.vue +++ b/src/components/spectator/ScoreBoard.vue @@ -5,12 +5,12 @@

- {{ teamNameByColor('CYAN') }} + {{ teamNameByColor('MAGENTA') }}

- {{ teamNameByColor('MAGENTA') }} + {{ teamNameByColor('CYAN') }}

@@ -19,47 +19,46 @@
- - + - - + +
diff --git a/src/components/spectator/WelcomeModal.vue b/src/components/spectator/WelcomeModal.vue index c2bf795..deb8cef 100644 --- a/src/components/spectator/WelcomeModal.vue +++ b/src/components/spectator/WelcomeModal.vue @@ -1,6 +1,11 @@ // TEMPLATE -------------------------------------------------------------------- diff --git a/src/components/spectator/popups/ConfirmSetMachinePosePopup.vue b/src/components/spectator/popups/ConfirmSetMachinePosePopup.vue new file mode 100644 index 0000000..6c97660 --- /dev/null +++ b/src/components/spectator/popups/ConfirmSetMachinePosePopup.vue @@ -0,0 +1,54 @@ +// TEMPLATE -------------------------------------------------------------------- + + +// SCRIPT ---------------------------------------------------------------------- + + +// STYLE ----------------------------------------------------------------------- + diff --git a/src/components/spectator/popups/MachinePopup.vue b/src/components/spectator/popups/MachinePopup.vue index eca7713..18128c3 100644 --- a/src/components/spectator/popups/MachinePopup.vue +++ b/src/components/spectator/popups/MachinePopup.vue @@ -49,7 +49,7 @@
@@ -91,8 +91,15 @@ " > {{ machine.bases_added - machine.bases_used }} @@ -235,21 +242,22 @@ const { ordersDeliveredByTeam, fileNameByWorkpiece } = storeToRefs(orderStore) // workpieces - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const workpiecesAtInput: ComputedRef = computed( () => - props.workpieces?.filter((workpiece) => workpiece.at_side == 'INPUT') || [] + props.workpieces?.filter((workpiece) => workpiece.at_side == 'INPUT') || [], ) const workpiecesAtOutput: ComputedRef = computed( () => - props.workpieces?.filter((workpiece) => workpiece.at_side == 'OUTPUT') || [] + props.workpieces?.filter((workpiece) => workpiece.at_side == 'OUTPUT') || + [], ) const workpiecesAtSlide: ComputedRef = computed( () => - props.workpieces?.filter((workpiece) => workpiece.at_side == 'SLIDE') || [] + props.workpieces?.filter((workpiece) => workpiece.at_side == 'SLIDE') || [], ) const workpiecesAtShelf: ComputedRef = computed( () => props.workpieces?.filter((workpiece) => - ['LEFT', 'MIDDLE', 'RIGHT'].includes(workpiece.at_side) - ) || [] + ['LEFT', 'MIDDLE', 'RIGHT'].includes(workpiece.at_side), + ) || [], ) diff --git a/src/components/spectator/popups/OrderPopup.vue b/src/components/spectator/popups/OrderPopup.vue index d817f47..420802f 100644 --- a/src/components/spectator/popups/OrderPopup.vue +++ b/src/components/spectator/popups/OrderPopup.vue @@ -22,12 +22,12 @@ order.delivery_period[1] - game_time < 0 && phase == 'PRODUCTION' " class="text-danger" - > + > ( -
+ {{ formatTime(game_time - order.delivery_period[1]) }} -
+ )

@@ -117,7 +117,11 @@
- + These order recipes are only basic drafts of the required steps and do not include e.g. the acquisition of additional bases from the base station for payment. Teams can additionally choose to combine the diff --git a/src/components/spectator/popups/TimelinePopup.vue b/src/components/spectator/popups/TimelinePopup.vue index 6a3db8f..0010d62 100644 --- a/src/components/spectator/popups/TimelinePopup.vue +++ b/src/components/spectator/popups/TimelinePopup.vue @@ -6,7 +6,10 @@ min="0" :max="gameReport?.game_end_time" :value="cont_time" - @input="(e: Event) => reportStore.jumpTo(parseInt((e.target as HTMLInputElement).value))" + @input=" + (e: Event) => + reportStore.jumpTo(parseInt((e.target as HTMLInputElement).value)) + " />
Total time: diff --git a/src/main.ts b/src/main.ts index a824e3c..d6790f2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -135,7 +135,7 @@ library.add( faTruck, faUserTie, faWalkieTalkie, - faXmark + faXmark, ) // create the app diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts index 4ca75b5..2b97bd9 100644 --- a/src/shims-vue.d.ts +++ b/src/shims-vue.d.ts @@ -2,4 +2,4 @@ declare module '*.vue' { import type { DefineComponent } from 'vue' const component: DefineComponent<{}, {}, any> export default component -} \ No newline at end of file +} diff --git a/src/store/eventStore.ts b/src/store/eventStore.ts index f9bdf71..6435ea9 100644 --- a/src/store/eventStore.ts +++ b/src/store/eventStore.ts @@ -30,11 +30,11 @@ export const useEventStore = defineStore('eventStore', () => { return gameEvents.value.filter((gameEvent) => !gameEvent.team) case 'cyan': return gameEvents.value.filter( - (gameEvent) => gameEvent.team == 'CYAN' + (gameEvent) => gameEvent.team == 'CYAN', ) case 'magenta': return gameEvents.value.filter( - (gameEvent) => gameEvent.team == 'MAGENTA' + (gameEvent) => gameEvent.team == 'MAGENTA', ) default: return gameEvents.value diff --git a/src/store/fieldStore.ts b/src/store/fieldStore.ts index 63b15a5..a0b3a9d 100644 --- a/src/store/fieldStore.ts +++ b/src/store/fieldStore.ts @@ -6,6 +6,8 @@ import { useMachineStore } from '@/store/machineStore' import { useConfigStore } from '@/store/configStore' import type RandomizeFieldOutMsg from '@/types/messages/outgoing/RandomizeFieldOutMsg' import { useSocketStore } from '@/store/socketStore' +import type MachinePose from '@/types/MachinePose' +import SetMachinePoseOutMsg from '@/types/messages/outgoing/SetMachinePoseOutMsg' // FIELD STORE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // the field store provides information about and interaction with the playing @@ -27,25 +29,25 @@ export const useFieldStore = defineStore('fieldStore', () => { // COMPUTED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> config const horizontalFieldSize: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/game/field/width') + () => configStore.gameConfig.get('/llsfrb/game/field/width'), ) const isFieldMirrored: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/game/field/mirrored') + () => configStore.gameConfig.get('/llsfrb/game/field/mirrored'), ) const verticalFieldSize: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/game/field/height') + () => configStore.gameConfig.get('/llsfrb/game/field/height'), ) // -> full horizontal field size (in number of squares) const fullHorizontalFieldSize: ComputedRef = computed(() => isFieldMirrored.value ? horizontalFieldSize.value * 2 - : horizontalFieldSize.value + : horizontalFieldSize.value, ) // -> number of pixels of the horiontal or vertical diameter of a square const squareDiameterPixels: ComputedRef = computed( - () => fieldHeightPixels.value / verticalFieldSize.value + () => fieldHeightPixels.value / verticalFieldSize.value, ) // -> position of a waypoint (either field or machine) @@ -56,7 +58,7 @@ export const useFieldStore = defineStore('fieldStore', () => { // machine with the name of the waypoint - if we cannot find one, we assume the waypoint is // a zone const machine = machineStore.machines.find( - (machine) => machine.name == el + (machine) => machine.name == el, ) let zone if (machine) { @@ -104,6 +106,32 @@ export const useFieldStore = defineStore('fieldStore', () => { socketStore.sendMessage(msg) } + // -> send a message to the websocket to set a config value + function sendSetMachinePose(start_zone: string, target_zone: string) { + const machine = machineStore.machines.find( + (machine) => machine.zone === start_zone, + ) + if (machine) { + if (start_zone === target_zone) { + const msg: SetMachinePoseOutMsg = { + command: 'set_machine_pose', + name: machine.name, + rotation: (machine.rotation + 45) % 360, + zone: target_zone, + } + socketStore.sendMessage(msg) + } else { + const msg: SetMachinePoseOutMsg = { + command: 'set_machine_pose', + name: machine.name, + rotation: machine.rotation, + zone: target_zone, + } + socketStore.sendMessage(msg) + } + } + } + // -> reset function reset() { // no need to change fieldWrapperWidthPixels, fieldWrapperHeightPixels, @@ -125,6 +153,7 @@ export const useFieldStore = defineStore('fieldStore', () => { positionOfWaypoint, positionOfRobot, sendRandomizeField, + sendSetMachinePose, reset, } }) diff --git a/src/store/gameStore.ts b/src/store/gameStore.ts index 5d7af04..89f1301 100644 --- a/src/store/gameStore.ts +++ b/src/store/gameStore.ts @@ -58,21 +58,20 @@ export const useGameStore = defineStore('gameStore', () => { // COMPUTED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> config const SETUP_DURATION: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/globals/setup-time') + () => configStore.gameConfig.get('/llsfrb/globals/setup-time'), ) const PRODUCTION_DURATION: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/globals/production-time') + () => configStore.gameConfig.get('/llsfrb/globals/production-time'), ) const EXPLORATION_DURATION: ComputedRef = computed( - () => - configStore.gameConfig.get('/llsfrb/game/exploration-time') + () => configStore.gameConfig.get('/llsfrb/game/exploration-time'), ) const OVERTIME_DURATION: ComputedRef = computed( () => - configStore.gameConfig.get('/llsfrb/globals/production-overtime') + configStore.gameConfig.get('/llsfrb/globals/production-overtime'), ) const PHASES: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/globals/phases') + () => configStore.gameConfig.get('/llsfrb/globals/phases'), ) // -> other color @@ -98,7 +97,7 @@ export const useGameStore = defineStore('gameStore', () => { return nameTeamMagenta.value ? nameTeamMagenta.value : 'MAGENTA' } } - } + }, ) // -> score by color @@ -115,7 +114,7 @@ export const useGameStore = defineStore('gameStore', () => { () => { return (color: Color) => rewards.value.filter((rewardFi) => rewardFi.team == color) - } + }, ) // -> rewards by color and order @@ -124,7 +123,7 @@ export const useGameStore = defineStore('gameStore', () => { > = computed(() => { return (color: Color, orderId: number) => rewards.value.filter( - (rewardFi) => rewardFi.team == color && rewardFi.order == orderId + (rewardFi) => rewardFi.team == color && rewardFi.order == orderId, ) }) @@ -189,8 +188,8 @@ export const useGameStore = defineStore('gameStore', () => { scoreByColor.value('CYAN') > scoreByColor.value('MAGENTA') ? 'CYAN' : scoreByColor.value('CYAN') < scoreByColor.value('MAGENTA') - ? 'MAGENTA' - : undefined + ? 'MAGENTA' + : undefined eventStore.addEvent({ icon: 'fa-medal', @@ -206,24 +205,28 @@ export const useGameStore = defineStore('gameStore', () => { // -> add a reward function addReward(rewardArg: Reward) { - const rewardExists = rewards.value.some(reward => { + const rewardExists = rewards.value.some((reward) => { return ( reward.game_time === rewardArg.game_time && reward.phase === rewardArg.phase && reward.points === rewardArg.points && reward.reason === rewardArg.reason && reward.team === rewardArg.team - ); - }); + ) + }) // If the reward doesn't already exist, add it to the rewards array and log the event - if (!rewardExists && rewardArg.points !== 0 && teamNameByColor.value(rewardArg.team) !== '') { + if ( + !rewardExists && + rewardArg.points !== 0 && + teamNameByColor.value(rewardArg.team) !== '' + ) { eventStore.addEvent({ icon: 'fa-trophy', msg: `${teamNameByColor.value(rewardArg.team)} received ${rewardArg.points} points`, team: rewardArg.team, - }); - rewards.value.push(rewardArg); + }) + rewards.value.push(rewardArg) } } @@ -241,7 +244,7 @@ export const useGameStore = defineStore('gameStore', () => { // ---> ... reset the refbox function sendReset() { const msg: ResetOutMsg = { - command: 'reset' + command: 'reset', } socketStore.sendMessage(msg) } diff --git a/src/store/machineStore.ts b/src/store/machineStore.ts index c0da34d..d8664c2 100644 --- a/src/store/machineStore.ts +++ b/src/store/machineStore.ts @@ -5,8 +5,19 @@ import type Machine from '@/types/Machine' import type RingSpec from '@/types/RingSpec' import type Color from '@/types/Color' import type ShelfSlot from '@/types/ShelfSlot' +import { useSocketStore } from '@/store/socketStore' import { useConfigStore } from '@/store/configStore' +import type InstructBS from '@/types/InstructBS' +import InstructBSOutMsg from '@/types/messages/outgoing/InstructBSOutMsg' +import type InstructCS from '@/types/InstructCS' +import InstructCSOutMsg from '@/types/messages/outgoing/InstructCSOutMsg' +import type InstructRS from '@/types/InstructRS' +import InstructRSOutMsg from '@/types/messages/outgoing/InstructRSOutMsg' +import type InstructDS from '@/types/InstructDS' +import InstructDSOutMsg from '@/types/messages/outgoing/InstructDSOutMsg' +import type InstructSS from '@/types/InstructSS' +import InstructSSOutMsg from '@/types/messages/outgoing/InstructSSOutMsg' // MACHINE STORE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // the machine stores stores the machines and related information and provides // methods to interact with them @@ -16,13 +27,15 @@ export const useMachineStore = defineStore('machineStore', () => { const shelfSlots: Ref = ref([]) const ringSpecs: Ref = ref([]) + const socketStore = useSocketStore() + // COMPUTED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> machines by color const machinesByColor: ComputedRef<(color: Color) => Machine[]> = computed( () => { return (color: Color) => machines.value.filter((machine) => machine.team == color) - } + }, ) // -> payment by ring @@ -30,7 +43,7 @@ export const useMachineStore = defineStore('machineStore', () => { computed(() => { return (ring: string) => { const ringSpec = ringSpecs.value.find( - (ringSpec) => ringSpec.color == ring + (ringSpec) => ringSpec.color == ring, ) if (ringSpec) { return ringSpec.req_bases @@ -71,7 +84,7 @@ export const useMachineStore = defineStore('machineStore', () => { function setMachine(machineArg: Machine): void { // try to find the machine const index = machines.value.findIndex( - (machine) => machine.name === machineArg.name + (machine) => machine.name === machineArg.name, ) // if we have found a machine, replace it @@ -106,7 +119,7 @@ export const useMachineStore = defineStore('machineStore', () => { (slotFi) => slotFi.name == slotArg.name && slotFi.shelf == slotArg.shelf && - slotFi.slot == slotArg.slot + slotFi.slot == slotArg.slot, ) // if we have found a shelf slot, replace it @@ -123,7 +136,7 @@ export const useMachineStore = defineStore('machineStore', () => { function setRingSpec(ringSpecArg: RingSpec): void { // try to find the shelf slot const index = ringSpecs.value.findIndex( - (ringSpecFi) => ringSpecFi.color == ringSpecArg.color + (ringSpecFi) => ringSpecFi.color == ringSpecArg.color, ) // if we have found a shelf slot, replace it @@ -136,6 +149,70 @@ export const useMachineStore = defineStore('machineStore', () => { } } + function sendInstructBS({ + team_name, + machine, + side, + base_color, + }: InstructBS) { + const msg: InstructBSOutMsg = { + command: 'instruct_bs', + team_name, + machine, + side, + base_color, + } + socketStore.sendMessage(msg) + } + + function sendInstructCS({ team_name, machine, operation }: InstructCS) { + const msg: InstructCSOutMsg = { + command: 'instruct_cs', + team_name, + machine, + operation, + } + socketStore.sendMessage(msg) + } + + function sendInstructRS({ team_name, machine, ring_color }: InstructRS) { + const msg: InstructRSOutMsg = { + command: 'instruct_rs', + team_name, + machine, + ring_color, + } + socketStore.sendMessage(msg) + } + + function sendInstructDS({ team_name, machine, order }: InstructDS) { + const msg: InstructDSOutMsg = { + command: 'instruct_ds', + team_name, + machine, + order, + } + socketStore.sendMessage(msg) + } + + function sendInstructSS({ + team_name, + machine, + operation, + shelf, + slot, + }: InstructSS) { + const msg: InstructSSOutMsg = { + command: 'instruct_ss', + team_name, + machine, + operation, + shelf, + slot, + } + socketStore.sendMessage(msg) + } + // -> reset function reset() { machines.value = [] @@ -154,6 +231,11 @@ export const useMachineStore = defineStore('machineStore', () => { setMachine, setShelfSlot, setRingSpec, + sendInstructBS, + sendInstructRS, + sendInstructCS, + sendInstructDS, + sendInstructSS, reset, } }) diff --git a/src/store/orderStore.ts b/src/store/orderStore.ts index ed655f1..fda62f3 100644 --- a/src/store/orderStore.ts +++ b/src/store/orderStore.ts @@ -28,7 +28,8 @@ export const useOrderStore = defineStore('orderStore', () => { // COMPUTED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> config const MAX_NUMBER_OF_ORDERS: ComputedRef = computed( - () => configStore.gameConfig.get('/llsfrb/globals/number-of-orders') + () => + configStore.gameConfig.get('/llsfrb/globals/number-of-orders'), ) // -> open orders @@ -37,8 +38,8 @@ export const useOrderStore = defineStore('orderStore', () => { (order) => gameStore.game_time >= order.delivery_period[0] - 1 && gameStore.game_time < order.delivery_period[1] + 1 && - gameStore.phase == 'PRODUCTION' - ) + gameStore.phase == 'PRODUCTION', + ), ) // -> upcoming orders @@ -48,22 +49,22 @@ export const useOrderStore = defineStore('orderStore', () => { (['PRE_GAME', 'SETUP', 'EXPLORATION'].includes(gameStore.phase) || (gameStore.phase == 'PRODUCTION' && gameStore.game_time < order.delivery_period[0])) && - order.delivery_period[0] < gameStore.PRODUCTION_DURATION - ) + order.delivery_period[0] < gameStore.PRODUCTION_DURATION, + ), ) // -> upcoming acivated orders const upcomingActivatedOrders: ComputedRef = computed(() => upcomingOrders.value.filter( - (order) => gameStore.game_time >= order.activate_at - ) + (order) => gameStore.game_time >= order.activate_at, + ), ) // -> upcoming not yet activated orders const upcomingNonActivatedOrders: ComputedRef = computed(() => upcomingOrders.value.filter( - (order) => gameStore.game_time < order.activate_at - ) + (order) => gameStore.game_time < order.activate_at, + ), ) // -> expired orders @@ -72,20 +73,20 @@ export const useOrderStore = defineStore('orderStore', () => { (order) => gameStore.phase == 'POST_GAME' || (gameStore.phase == 'PRODUCTION' && - gameStore.game_time >= order.delivery_period[1]) - ) + gameStore.game_time >= order.delivery_period[1]), + ), ) // -> overtime order const overtimeOrder: ComputedRef = computed(() => orders.value.find( - (order) => order.delivery_period[0] == gameStore.PRODUCTION_DURATION - ) + (order) => order.delivery_period[0] == gameStore.PRODUCTION_DURATION, + ), ) // -> unconfirmed orders const unconfirmedOrders: ComputedRef = computed(() => - orders.value.filter((order) => order.unconfirmed_deliveries.length > 0) + orders.value.filter((order) => order.unconfirmed_deliveries.length > 0), ) // -> orders delivered by team @@ -101,7 +102,7 @@ export const useOrderStore = defineStore('orderStore', () => { throw new Error('team name not found') } return orders.value.filter( - (order) => order.quantity_delivered[index] >= 1 + (order) => order.quantity_delivered[index] >= 1, ) } }) @@ -187,7 +188,7 @@ export const useOrderStore = defineStore('orderStore', () => { function setWorkpiece(workpieceArg: Workpiece) { // try to find a workpiece with the same name const index = workpieces.value.findIndex( - (workpieceFi) => workpieceFi.name == workpieceArg.name + (workpieceFi) => workpieceFi.name == workpieceArg.name, ) // if we have not found such a workpiece, add it as a new one if (index === -1) { diff --git a/src/store/presetStore.ts b/src/store/presetStore.ts index 0e4410c..89e1da0 100644 --- a/src/store/presetStore.ts +++ b/src/store/presetStore.ts @@ -14,10 +14,12 @@ export const usePresetStore = defineStore('presetStore', () => { // CONSTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const defaultConfigPresets: Set = new Set([ { category: 'challenges', preset: 'production' }, - ]); + ]) // REFS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> game config - const configPresets: Ref> = ref(new Set(defaultConfigPresets)) + const configPresets: Ref> = ref( + new Set(defaultConfigPresets), + ) // FUNCTIONS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> set config value diff --git a/src/store/reportStore.ts b/src/store/reportStore.ts index d406b8a..17b09da 100644 --- a/src/store/reportStore.ts +++ b/src/store/reportStore.ts @@ -26,8 +26,15 @@ export const useReportStore = defineStore('reportStore', () => { const configStore = useConfigStore() // REFS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + const getBackendURL = () => { + const protocol = window.location.protocol === 'https:' ? 'https:' : 'http:' + const host = window.location.hostname + const port = '8085' + return `${protocol}//${host}:${port}` + } + // -> consts - const DEFAULT_BACKEND_URL: Ref = ref('http://localhost:8085') + const DEFAULT_BACKEND_URL: Ref = ref(getBackendURL()) const MIN_VERSION: Ref = ref('2') const MAX_VERSION: Ref = ref('2') @@ -71,7 +78,7 @@ export const useReportStore = defineStore('reportStore', () => { ? gameReport.value?.agent_task_history.filter( (agentTask) => gameStore.game_time >= agentTask.start_time && - gameStore.game_time <= agentTask.end_time + gameStore.game_time <= agentTask.end_time, ) || [] : [] }) @@ -81,7 +88,7 @@ export const useReportStore = defineStore('reportStore', () => { ? gameReport.value?.workpiece_history.filter( (workpiece) => gameStore.game_time >= workpiece.start_time && - gameStore.game_time <= workpiece.end_time + gameStore.game_time <= workpiece.end_time, ) || [] : [] }) @@ -102,7 +109,7 @@ export const useReportStore = defineStore('reportStore', () => { new URLSearchParams({ min_version: MIN_VERSION.value, max_version: MAX_VERSION.value, - }) + }), ) responseJSON = <{ reports: GameReport[]; incompatibleCount: number }>( await response.json() @@ -111,11 +118,11 @@ export const useReportStore = defineStore('reportStore', () => { console.error(err) if (response && response.status != 200) { alert( - `Something went wrong. Response: ${response?.status} - ${response?.statusText}` + `Something went wrong. Response: ${response?.status} - ${response?.statusText}`, ) } else { alert( - 'Could not connect: Have you specified the right URL and made sure the game report provider is started?' + 'Could not connect: Have you specified the right URL and made sure the game report provider is started?', ) } } finally { @@ -139,14 +146,14 @@ export const useReportStore = defineStore('reportStore', () => { `${baseUrl}/api/getReportById?` + new URLSearchParams({ reportId, - }) + }), ) newGameReport = await response.json() } catch (err) { console.error(err) if (response && !response?.ok) { alert( - `Something went wrong. Response: ${response?.status} - ${response?.statusText}` + `Something went wrong. Response: ${response?.status} - ${response?.statusText}`, ) } else { alert('Unknown connection error') @@ -196,19 +203,19 @@ export const useReportStore = defineStore('reportStore', () => { configStore.setConfigValue({ path: '/llsfrb/game/field/height', value: gameReport.value.config.find( - (cfg) => cfg.path == '/llsfrb/game/field/height' + (cfg) => cfg.path == '/llsfrb/game/field/height', )?.value, }) configStore.setConfigValue({ path: '/llsfrb/game/field/mirrored', value: gameReport.value.config.find( - (cfg) => cfg.path == '/llsfrb/game/field/mirrored' + (cfg) => cfg.path == '/llsfrb/game/field/mirrored', )?.value, }) configStore.setConfigValue({ path: '/llsfrb/game/field/width', value: gameReport.value.config.find( - (cfg) => cfg.path == '/llsfrb/game/field/width' + (cfg) => cfg.path == '/llsfrb/game/field/width', )?.value, }) @@ -335,7 +342,7 @@ export const useReportStore = defineStore('reportStore', () => { const newMachineCurrent = gameReport.value.machine_history[machineHistoryIndex.value] const machine = machineStore.machines.find( - (machineFi) => machineFi.name == newMachineCurrent.name + (machineFi) => machineFi.name == newMachineCurrent.name, ) if (machine) { // we do not rewrite the whole machine object because the machine @@ -369,11 +376,11 @@ export const useReportStore = defineStore('reportStore', () => { machine.order_id != 0 ) { const order = orderStore.orders.find( - (order) => order.id == machine.order_id + (order) => order.id == machine.order_id, ) if (!order) { throw new Error( - 'order referenced in delivery station not found by id' + 'order referenced in delivery station not found by id', ) } else { const orderDeliveredIndex = machine.team == 'CYAN' ? 0 : 1 @@ -382,7 +389,7 @@ export const useReportStore = defineStore('reportStore', () => { } } else { throw new Error( - 'Machine in machine history array not found in machines store' + 'Machine in machine history array not found in machines store', ) } machineHistoryIndex.value += 1 @@ -396,7 +403,7 @@ export const useReportStore = defineStore('reportStore', () => { .game_time <= gameStore.game_time ) { machineStore.setShelfSlot( - gameReport.value.shelf_slot_history[shelfSlotHistoryIndex.value] + gameReport.value.shelf_slot_history[shelfSlotHistoryIndex.value], ) shelfSlotHistoryIndex.value += 1 } @@ -408,7 +415,7 @@ export const useReportStore = defineStore('reportStore', () => { gameStore.game_time ) { robotStore.setRobot( - gameReport.value.robot_history[robotHistoryIndex.value] + gameReport.value.robot_history[robotHistoryIndex.value], ) robotHistoryIndex.value += 1 } @@ -445,7 +452,7 @@ export const useReportStore = defineStore('reportStore', () => { (newActiveAgentTasks, _) => { robotStore.agentTasks = newActiveAgentTasks }, - { deep: true } + { deep: true }, ) // whenever the computed property `activeWorkpieces` changes, update the @@ -455,7 +462,7 @@ export const useReportStore = defineStore('reportStore', () => { (newWorkpieces, _) => { orderStore.workpieces = newWorkpieces }, - { deep: true } + { deep: true }, ) // EXPORTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/store/robotStore.ts b/src/store/robotStore.ts index 7b6dfa3..0dd9281 100644 --- a/src/store/robotStore.ts +++ b/src/store/robotStore.ts @@ -25,19 +25,19 @@ export const useRobotStore = defineStore('robotStore', () => { // -> config const MAX_NUMBER_OF_ROBOTS: ComputedRef = computed( () => - configStore.gameConfig.get('/llsfrb/globals/max-robots-per-team') + configStore.gameConfig.get('/llsfrb/globals/max-robots-per-team'), ) const MAX_MAINTENANCE_CYCLES: ComputedRef = computed( () => ( configStore.gameConfig.get('/llsfrb/globals/maintenance-allowed-cycles') - ) + ), ) const MAINTENANCE_DURATION: ComputedRef = computed( () => ( configStore.gameConfig.get('/llsfrb/globals/maintenance-allowed-time') - ) + ), ) // -> name by robot @@ -60,7 +60,7 @@ export const useRobotStore = defineStore('robotStore', () => { return (color: Color, id: number) => { return ( robots.value.find( - (robot) => robot.team_color == color && robot.number == id + (robot) => robot.team_color == color && robot.number == id, ) || null ) } @@ -73,7 +73,7 @@ export const useRobotStore = defineStore('robotStore', () => { const index = robots.value.findIndex( (robotFi) => robotFi.team_color === robotArg.team_color && - robotFi.number == robotArg.number + robotFi.number == robotArg.number, ) // if we could find a robot, we replace it @@ -156,7 +156,7 @@ export const useRobotStore = defineStore('robotStore', () => { // try to find an agent task that the robot that does the new agent task is // currently doing const index = agentTasks.value.findIndex( - (taskFi) => taskFi.robot_id == agentTask.robot_id + (taskFi) => taskFi.robot_id == agentTask.robot_id, ) // check if we need to create an event @@ -170,8 +170,8 @@ export const useRobotStore = defineStore('robotStore', () => { msg: `${nameByRobot.value( robotByColorAndId.value( agentTask.team_color, - agentTask.robot_id - ) as Robot + agentTask.robot_id, + ) as Robot, )} is delivering at ${agentTask.task_parameters.machine_id}`, team: agentTask.team_color, }) @@ -185,8 +185,8 @@ export const useRobotStore = defineStore('robotStore', () => { msg: `${nameByRobot.value( robotByColorAndId.value( agentTask.team_color, - agentTask.robot_id - ) as Robot + agentTask.robot_id, + ) as Robot, )} is retrieving at ${agentTask.task_parameters.machine_id}`, team: agentTask.team_color, }) diff --git a/src/store/socketStore.ts b/src/store/socketStore.ts index 1fb5167..ec0d18c 100644 --- a/src/store/socketStore.ts +++ b/src/store/socketStore.ts @@ -28,7 +28,14 @@ export const useSocketStore = defineStore('socketStore', () => { // REFS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> consts - const DEFAULT_WS_URL: Ref = ref('ws://localhost:1234') + const getWebSocketURL = () => { + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' + const host = window.location.hostname + const port = '1234' + return `${protocol}//${host}:${port}` + } + + const DEFAULT_WS_URL: Ref = ref(getWebSocketURL()) // -> socket & connection const socket: Ref = ref(null) @@ -45,21 +52,24 @@ export const useSocketStore = defineStore('socketStore', () => { (msg) => msg.level === 'attention' && gameStore.game_time >= msg.game_time && - gameStore.game_time <= msg.game_time + parseFloat(msg.time_to_display) - ) as AttentionMessage[] + gameStore.game_time <= + msg.game_time + parseFloat(msg.time_to_display), + ) as AttentionMessage[], ) // METHODS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -> establish websocket connection - function connectToWebsocket(url: string): void { + function connectToWebsocket(url: string, retry: boolean): void { attemptingConnection.value = true const newSocket = new WebSocket(url) - setTimeout(() => { - if (attemptingConnection.value) { - alert('Could not connect :/ Refbox does not respond!') - } - attemptingConnection.value = false - }, 10000) + if (!retry) { + setTimeout(() => { + if (attemptingConnection.value) { + alert('Could not connect :/ Refbox does not respond!') + } + attemptingConnection.value = false + }, 10000) + } // configure behaviour on open newSocket.onopen = (_e) => { @@ -142,15 +152,23 @@ export const useSocketStore = defineStore('socketStore', () => { // configure behaviour on close newSocket.onclose = (e) => { socket.value = null - console.log('Closing socket') + if (retry) { + connectToWebsocket(DEFAULT_WS_URL.value, retry) + } else { + console.log('Closing socket') + } } // configure on error newSocket.onerror = (e) => { - alert( - 'Could not connect :/ Make sure the refbox is started and accessed via the right url!' - ) - attemptingConnection.value = false + if (retry) { + connectToWebsocket(DEFAULT_WS_URL.value, retry) + } else { + alert( + 'Could not connect :/ Make sure the refbox is started and accessed via the right url!', + ) + attemptingConnection.value = false + } console.error(e) } } diff --git a/src/types/ConfigPreset.ts b/src/types/ConfigPreset.ts index a7ecd7e..1ebb9a4 100644 --- a/src/types/ConfigPreset.ts +++ b/src/types/ConfigPreset.ts @@ -1,4 +1,4 @@ -// CONFIGPRESET - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// CONFIGPRESET - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // the ConfigPreset type represents a pre-stored yaml file to be loaded // received by the websocket and stored in game reports type ConfigPreset = { diff --git a/src/types/InstructBS.ts b/src/types/InstructBS.ts new file mode 100644 index 0000000..86f4e78 --- /dev/null +++ b/src/types/InstructBS.ts @@ -0,0 +1,8 @@ +// them +type InstructBS = { + team_name: string // e.g. Carologistics, + machine: string // e.g. 'C-BS' + side: 'INPUT' | 'OUTPUT' + base_color: 'BASE_RED' | 'BASE_BLACK' | 'BASE_SILVER' +} +export default InstructBS diff --git a/src/types/InstructCS.ts b/src/types/InstructCS.ts new file mode 100644 index 0000000..f2dc67c --- /dev/null +++ b/src/types/InstructCS.ts @@ -0,0 +1,6 @@ +type InstructCS = { + team_name: string // e.g. Carologistics, + machine: string // e.g. 'C-BS' + operation: 'RETRIEVE_CAP' | 'MOUNT_CAP' +} +export default InstructCS diff --git a/src/types/InstructDS.ts b/src/types/InstructDS.ts new file mode 100644 index 0000000..0b8fbe2 --- /dev/null +++ b/src/types/InstructDS.ts @@ -0,0 +1,6 @@ +type InstructDS = { + team_name: string // e.g. Carologistics, + machine: string // e.g. 'C-BS' + order: number +} +export default InstructDS diff --git a/src/types/InstructRS.ts b/src/types/InstructRS.ts new file mode 100644 index 0000000..026df53 --- /dev/null +++ b/src/types/InstructRS.ts @@ -0,0 +1,6 @@ +type InstructRS = { + team_name: string // e.g. Carologistics, + machine: string // e.g. 'C-BS' + ring_color: 'RING_BLUE' | 'RING_YELLOW' | 'RING_GREEN' | 'RING_ORANGE' +} +export default InstructRS diff --git a/src/types/InstructSS.ts b/src/types/InstructSS.ts new file mode 100644 index 0000000..9a0225b --- /dev/null +++ b/src/types/InstructSS.ts @@ -0,0 +1,8 @@ +type InstructSS = { + team_name: string // e.g. Carologistics, + machine: string // e.g. 'C-BS' + operation: 'STORE' | 'RETRIEVE' + shelf: number + slot: number +} +export default InstructSS diff --git a/src/types/MachinePose.ts b/src/types/MachinePose.ts new file mode 100644 index 0000000..3fa3bbc --- /dev/null +++ b/src/types/MachinePose.ts @@ -0,0 +1,7 @@ +// them +type MachinePose = { + name: string // e.g. 'C-BS' + rotation: number // in 45 steps + zone: string // e.g. 'C_Z12' +} +export default MachinePose diff --git a/src/types/messages/OutgoingMessage.ts b/src/types/messages/OutgoingMessage.ts index 89960e1..a9c7ca3 100644 --- a/src/types/messages/OutgoingMessage.ts +++ b/src/types/messages/OutgoingMessage.ts @@ -1,5 +1,10 @@ import AddPointsTeamOutMsg from '@/types/messages/outgoing/AddRewardOutMsg' import ConfirmDeliveryOutMsg from '@/types/messages/outgoing/ConfirmDeliveryOutMsg' +import InstructBSOutMsg from '@/types/messages/outgoing/InstructBSOutMsg' +import InstructCSOutMsg from '@/types/messages/outgoing/InstructCSOutMsg' +import InstructRSOutMsg from '@/types/messages/outgoing/InstructRSOutMsg' +import InstructDSOutMsg from '@/types/messages/outgoing/InstructDSOutMsg' +import InstructSSOutMsg from '@/types/messages/outgoing/InstructSSOutMsg' import SetTeamNameOutMsg from '@/types/messages/outgoing/SetTeamNameOutMsg' import SetGamephaseOutMsg from '@/types/messages/outgoing/SetGamephaseOutMsg' import SetGamestateOutMsg from '@/types/messages/outgoing/SetGamestateOutMsg' @@ -7,6 +12,7 @@ import RandomizeFieldOutMsg from '@/types/messages/outgoing/RandomizeFieldOutMsg import SetRobotMaintenanceOutMsg from '@/types/messages/outgoing/RobotMainenanceOutMsg' import SetConfigValueOutMsg from '@/types/messages/outgoing/SetConfigValueOutMsg' import SetConfigPresetOutMsg from '@/types/messages/outgoing/SetConfigPresetOutMsg' +import SetMachinePoseOutMsg from '@/types/messages/outgoing/SetMachinePoseOutMsg' import ResetOutMsg from '@/types/messages/outgoing/ResetOutMsg' // OUTGOINGMESSAGE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -14,6 +20,11 @@ import ResetOutMsg from '@/types/messages/outgoing/ResetOutMsg' // connection as described in the 'outgoing' subfolder type OutgoingMessage = | AddPointsTeamOutMsg + | InstructBSOutMsg + | InstructCSOutMsg + | InstructRSOutMsg + | InstructDSOutMsg + | InstructSSOutMsg | ConfirmDeliveryOutMsg | SetTeamNameOutMsg | SetGamephaseOutMsg @@ -22,5 +33,6 @@ type OutgoingMessage = | SetRobotMaintenanceOutMsg | SetConfigValueOutMsg | SetConfigPresetOutMsg + | SetMachinePoseOutMsg | ResetOutMsg export default OutgoingMessage diff --git a/src/types/messages/outgoing/InstructBSOutMsg.ts b/src/types/messages/outgoing/InstructBSOutMsg.ts new file mode 100644 index 0000000..bab0cbc --- /dev/null +++ b/src/types/messages/outgoing/InstructBSOutMsg.ts @@ -0,0 +1,7 @@ +import type InstructBS from '@/types/InstructBS' + +type InstructBSOutMsg = { + command: 'instruct_bs' +} & InstructBS + +export default InstructBSOutMsg diff --git a/src/types/messages/outgoing/InstructCSOutMsg.ts b/src/types/messages/outgoing/InstructCSOutMsg.ts new file mode 100644 index 0000000..65ff53c --- /dev/null +++ b/src/types/messages/outgoing/InstructCSOutMsg.ts @@ -0,0 +1,7 @@ +import type InstructCS from '@/types/InstructCS' + +type InstructCSOutMsg = { + command: 'instruct_cs' +} & InstructCS + +export default InstructCSOutMsg diff --git a/src/types/messages/outgoing/InstructDSOutMsg.ts b/src/types/messages/outgoing/InstructDSOutMsg.ts new file mode 100644 index 0000000..7f42c4a --- /dev/null +++ b/src/types/messages/outgoing/InstructDSOutMsg.ts @@ -0,0 +1,7 @@ +import type InstructDS from '@/types/InstructDS' + +type InstructDSOutMsg = { + command: 'instruct_ds' +} & InstructDS + +export default InstructDSOutMsg diff --git a/src/types/messages/outgoing/InstructRSOutMsg.ts b/src/types/messages/outgoing/InstructRSOutMsg.ts new file mode 100644 index 0000000..0451e7e --- /dev/null +++ b/src/types/messages/outgoing/InstructRSOutMsg.ts @@ -0,0 +1,7 @@ +import type InstructRS from '@/types/InstructRS' + +type InstructRSOutMsg = { + command: 'instruct_rs' +} & InstructRS + +export default InstructRSOutMsg diff --git a/src/types/messages/outgoing/InstructSSOutMsg.ts b/src/types/messages/outgoing/InstructSSOutMsg.ts new file mode 100644 index 0000000..59056ba --- /dev/null +++ b/src/types/messages/outgoing/InstructSSOutMsg.ts @@ -0,0 +1,7 @@ +import type InstructSS from '@/types/InstructSS' + +type InstructSSOutMsg = { + command: 'instruct_ss' +} & InstructSS + +export default InstructSSOutMsg diff --git a/src/types/messages/outgoing/SetMachinePoseOutMsg.ts b/src/types/messages/outgoing/SetMachinePoseOutMsg.ts new file mode 100644 index 0000000..5580e7b --- /dev/null +++ b/src/types/messages/outgoing/SetMachinePoseOutMsg.ts @@ -0,0 +1,9 @@ +import type MachinePose from '@/types/MachinePose' + +// SETCONFIGVALUEOUTMSG - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// we send this message if we want to set a config value +type SetMachinePoseOutMsg = { + command: 'set_machine_pose' +} & MachinePose + +export default SetMachinePoseOutMsg diff --git a/src/utils/formatTime.ts b/src/utils/formatTime.ts index ba275e9..4548a85 100644 --- a/src/utils/formatTime.ts +++ b/src/utils/formatTime.ts @@ -3,7 +3,7 @@ // output is (M)Mm or (S)Ss instead. export default function formatTime( gameTimeArg: number | string, - verbal: boolean = false + verbal: boolean = false, ): string { let gameTime: number if (typeof gameTimeArg === 'string') { diff --git a/tsconfig.json b/tsconfig.json index 3b96af4..3406944 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,15 @@ { - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "importHelpers": true, - "isolatedModules": true, - "noEmit": true, - "strict": true, - "baseUrl": "./src", - "paths": { - "@/*": ["./*"], - } + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "importHelpers": true, + "isolatedModules": true, + "noEmit": true, + "strict": true, + "baseUrl": "./src", + "paths": { + "@/*": ["./*"] } + } } - \ No newline at end of file diff --git a/vite.config.mjs b/vite.config.mjs index 7feac08..fb54d2f 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -6,17 +6,20 @@ export default defineConfig({ plugins: [vue()], resolve: { alias: { - extensions: [ - '.mjs', - '.js', - '.ts', - '.jsx', - '.tsx', - '.json', - '.vue', - '.scss', - ], - '@': path.resolve(__dirname, './src'), + '@': path.resolve( + path.dirname(new URL(import.meta.url).pathname), + './src', + ), }, + extensions: [ + '.mjs', + '.js', + '.ts', + '.jsx', + '.tsx', + '.json', + '.vue', + '.scss', + ], }, }) diff --git a/yarn.lock b/yarn.lock index 5bd09eb..cd5ca45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -134,7 +134,12 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0": + version "4.10.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.1.tgz#361461e5cb3845d874e61731c11cfedd664d83a0" + integrity sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA== + +"@eslint-community/regexpp@^4.6.1": version "4.10.0" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== @@ -341,16 +346,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== -"@types/json-schema@^7.0.12": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/semver@^7.5.0": - version "7.5.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" - integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== - "@types/webidl-conversions@*": version "7.0.3" resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz#1306dbfa53768bcbcfc95a1c8cde367975581859" @@ -363,91 +358,86 @@ dependencies: "@types/webidl-conversions" "*" -"@typescript-eslint/eslint-plugin@^6.19.0": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz#bb0676af940bc23bf299ca58dbdc6589c2548c2e" - integrity sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg== +"@typescript-eslint/eslint-plugin@^7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz#cdc521c8bca38b55585cf30db787fb2abad3f9fd" + integrity sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg== dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.19.1" - "@typescript-eslint/type-utils" "6.19.1" - "@typescript-eslint/utils" "6.19.1" - "@typescript-eslint/visitor-keys" "6.19.1" - debug "^4.3.4" + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "7.13.1" + "@typescript-eslint/type-utils" "7.13.1" + "@typescript-eslint/utils" "7.13.1" + "@typescript-eslint/visitor-keys" "7.13.1" graphemer "^1.4.0" - ignore "^5.2.4" + ignore "^5.3.1" natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^6.19.0": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.19.1.tgz#68a87bb21afaf0b1689e9cdce0e6e75bc91ada78" - integrity sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ== +"@typescript-eslint/parser@^7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.13.1.tgz#fac57811b3e519185f7259bac312291f7b9c4e72" + integrity sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A== dependencies: - "@typescript-eslint/scope-manager" "6.19.1" - "@typescript-eslint/types" "6.19.1" - "@typescript-eslint/typescript-estree" "6.19.1" - "@typescript-eslint/visitor-keys" "6.19.1" + "@typescript-eslint/scope-manager" "7.13.1" + "@typescript-eslint/types" "7.13.1" + "@typescript-eslint/typescript-estree" "7.13.1" + "@typescript-eslint/visitor-keys" "7.13.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.19.1": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz#2f527ee30703a6169a52b31d42a1103d80acd51b" - integrity sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w== +"@typescript-eslint/scope-manager@7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz#c08041206904bf36f0e6997efdb0ca775e0c452e" + integrity sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg== dependencies: - "@typescript-eslint/types" "6.19.1" - "@typescript-eslint/visitor-keys" "6.19.1" + "@typescript-eslint/types" "7.13.1" + "@typescript-eslint/visitor-keys" "7.13.1" -"@typescript-eslint/type-utils@6.19.1": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz#6a130e3afe605a4898e043fa9f72e96309b54935" - integrity sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg== +"@typescript-eslint/type-utils@7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz#63bec3f1fb43cf0bc409cbdb88ef96d118ca8632" + integrity sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg== dependencies: - "@typescript-eslint/typescript-estree" "6.19.1" - "@typescript-eslint/utils" "6.19.1" + "@typescript-eslint/typescript-estree" "7.13.1" + "@typescript-eslint/utils" "7.13.1" debug "^4.3.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" -"@typescript-eslint/types@6.19.1": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.19.1.tgz#2d4c9d492a63ede15e7ba7d129bdf7714b77f771" - integrity sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg== +"@typescript-eslint/types@7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.13.1.tgz#787db283bd0b58751094c90d5b58bbf5e9fc9bd8" + integrity sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw== -"@typescript-eslint/typescript-estree@6.19.1": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz#796d88d88882f12e85bb33d6d82d39e1aea54ed1" - integrity sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA== +"@typescript-eslint/typescript-estree@7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz#3412841b130e070db2f675e3d9b8cb1ae49e1c3f" + integrity sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw== dependencies: - "@typescript-eslint/types" "6.19.1" - "@typescript-eslint/visitor-keys" "6.19.1" + "@typescript-eslint/types" "7.13.1" + "@typescript-eslint/visitor-keys" "7.13.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" -"@typescript-eslint/utils@6.19.1": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.19.1.tgz#df93497f9cfddde2bcc2a591da80536e68acd151" - integrity sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w== +"@typescript-eslint/utils@7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.13.1.tgz#611083379caa0d3a2c09d126c65065a3e4337ba2" + integrity sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.19.1" - "@typescript-eslint/types" "6.19.1" - "@typescript-eslint/typescript-estree" "6.19.1" - semver "^7.5.4" + "@typescript-eslint/scope-manager" "7.13.1" + "@typescript-eslint/types" "7.13.1" + "@typescript-eslint/typescript-estree" "7.13.1" -"@typescript-eslint/visitor-keys@6.19.1": - version "6.19.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz#2164073ed4fc34a5ff3b5e25bb5a442100454c4c" - integrity sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ== +"@typescript-eslint/visitor-keys@7.13.1": + version "7.13.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz#9c229a795a919db61f2d7f2337ef584ac05fbe96" + integrity sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA== dependencies: - "@typescript-eslint/types" "6.19.1" - eslint-visitor-keys "^3.4.1" + "@typescript-eslint/types" "7.13.1" + eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -1064,11 +1054,16 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== +ignore@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + immutable@^4.0.0: version "4.3.5" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" @@ -1237,13 +1232,6 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1251,6 +1239,13 @@ minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" + integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== + dependencies: + brace-expansion "^2.0.1" + mongodb-connection-string-url@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz#b4f87f92fd8593f3b9365f592515a06d304a1e9c" @@ -1479,6 +1474,11 @@ semver@^7.3.6, semver@^7.5.4: dependencies: lru-cache "^6.0.0" +semver@^7.6.0: + version "7.6.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -1546,10 +1546,10 @@ tr46@^4.1.1: dependencies: punycode "^2.3.0" -ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -1563,10 +1563,10 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -typescript@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" - integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typescript@^5.5.2: + version "5.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.2.tgz#c26f023cb0054e657ce04f72583ea2d85f8d0507" + integrity sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew== uri-js@^4.2.2: version "4.4.1"