diff --git a/Cargo.lock b/Cargo.lock index 6796f3f7f..234727c72 100644 Binary files a/Cargo.lock and b/Cargo.lock differ diff --git a/Cargo.toml b/Cargo.toml index cdcd937bf..da4b5530a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ rust-version = "1.81" [workspace.dependencies] # Third party dependencies used by one or more of our crates async-channel = "2.3" -async-stream = "0.3.5" +async-stream = "0.3.6" async-trait = "0.1.80" axum = "0.6.20" # Update blocked by hyper base64 = "0.22.1" @@ -30,7 +30,7 @@ chrono = "0.4.38" ed25519-dalek = "2.1" futures = "0.3.30" futures-concurrency = "7.6" -globset = "0.4.14" +globset = "0.4.15" http = "0.2" # Update blocked by axum hyper = "0.14" # Update blocked due to API breaking changes image = "0.24.9" # Update blocked due to https://github.com/image-rs/image/issues/2230 @@ -41,7 +41,7 @@ mimalloc = "0.1.43" normpath = "1.2" pin-project-lite = "0.2.14" rand = "0.9.0-alpha.2" -regex = "1.10" +regex = "1.11" reqwest = { version = "0.11", default-features = false } # Update blocked by hyper rmp = "0.8.14" rmp-serde = "1.3" @@ -52,11 +52,11 @@ serde_json = "1.0" specta = "=2.0.0-rc.20" strum = "0.26" strum_macros = "0.26" -tempfile = "3.10" +tempfile = "3.13" thiserror = "1.0" -tokio = "1.38" -tokio-stream = "0.1.15" -tokio-util = "0.7.11" +tokio = "1.40" +tokio-stream = "0.1.16" +tokio-util = "0.7.12" tracing = "0.1.40" tracing-subscriber = "0.3.18" tracing-test = "0.2.5" @@ -81,10 +81,10 @@ rev = "4f9ef9d38c" git = "https://github.com/spacedriveapp/if-watch.git" rev = "a92c17d3f8" -# We hack it to the high heavens +# We use our own version of rspc [patch.crates-io.rspc] git = "https://github.com/spacedriveapp/rspc.git" -rev = "0018e80231" +rev = "bc882f4724" # Add `Control::open_stream_with_addrs` [patch.crates-io.libp2p] diff --git a/apps/desktop/crates/linux/Cargo.toml b/apps/desktop/crates/linux/Cargo.toml index 9c4755b73..ae1d5408c 100644 --- a/apps/desktop/crates/linux/Cargo.toml +++ b/apps/desktop/crates/linux/Cargo.toml @@ -13,5 +13,5 @@ tokio = { workspace = true, features = ["fs"] } [target.'cfg(target_os = "linux")'.dependencies] wgpu = { version = "22.1", default-features = false } # WARNING: gtk should follow the same version used by tauri -# https://github.com/tauri-apps/tauri/blob/tauri-v2.0.0-rc.2/core/tauri/Cargo.toml +# https://github.com/tauri-apps/tauri/blob/tauri-v2.0.0/crates/tauri/Cargo.toml#L100 gtk = { version = "0.18", features = ["v3_24"] } diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 1ec124294..f6e07500a 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -12,18 +12,18 @@ "lint": "eslint src --cache" }, "dependencies": { - "@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2", - "@oscartbeaumont-sd/rspc-tauri": "=0.0.0-main-dc31e5b2", + "@oscartbeaumont-sd/rspc-client": "github:spacedriveapp/rspc#path:packages/client&bc882f4724", + "@oscartbeaumont-sd/rspc-tauri": "github:spacedriveapp/rspc#path:packages/tauri&bc882f4724", "@remix-run/router": "=1.13.1", "@sd/client": "workspace:*", "@sd/interface": "workspace:*", "@sd/ui": "workspace:*", "@t3-oss/env-core": "^0.7.1", "@tanstack/react-query": "^4.36.1", - "@tauri-apps/api": "=2.0.0-rc.0", - "@tauri-apps/plugin-dialog": "=2.0.0-rc.0", - "@tauri-apps/plugin-os": "=2.0.0-rc.0", - "@tauri-apps/plugin-shell": "=2.0.0-rc.0", + "@tauri-apps/api": "=2.0.1", + "@tauri-apps/plugin-dialog": "2.0.0", + "@tauri-apps/plugin-os": "2.0.0", + "@tauri-apps/plugin-shell": "2.0.0", "consistent-hash": "^1.2.2", "immer": "^10.0.3", "react": "^18.2.0", @@ -34,11 +34,11 @@ "devDependencies": { "@sd/config": "workspace:*", "@sentry/vite-plugin": "^2.16.0", - "@tauri-apps/cli": "=2.0.0-rc.3", + "@tauri-apps/cli": "2.0.1", "@types/react": "^18.2.67", "@types/react-dom": "^18.2.22", "sass": "^1.72.0", - "typescript": "^5.4.2", + "typescript": "^5.6.2", "vite": "^5.2.0", "vite-tsconfig-paths": "^4.3.2" } diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 49d7ded48..de19d391d 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -22,7 +22,7 @@ http = { workspace = true } hyper = { workspace = true } prisma-client-rust = { workspace = true } rand = { workspace = true } -rspc = { workspace = true, features = ["tauri", "tracing"] } +rspc = { workspace = true, features = ["tauri"] } serde = { workspace = true } serde_json = { workspace = true } specta = { workspace = true } @@ -36,22 +36,22 @@ uuid = { workspace = true, features = ["serde"] } # WARNING: Do NOT enable default features, as that vendors dbus (see below) opener = { version = "0.7.1", features = ["reveal"], default-features = false } specta-typescript = "=0.0.7" -tauri-plugin-dialog = "=2.0.0-rc.0" -tauri-plugin-os = "=2.0.0-rc.0" -tauri-plugin-shell = "=2.0.0-rc.0" -tauri-plugin-updater = "=2.0.0-rc.0" +tauri-plugin-dialog = "=2.0.1" +tauri-plugin-os = "=2.0.1" +tauri-plugin-shell = "=2.0.1" +tauri-plugin-updater = "=2.0.2" # memory allocator mimalloc = { workspace = true } [dependencies.tauri] features = ["linux-libxdo", "macos-private-api", "native-tls-vendored", "unstable"] -version = "=2.0.0-rc.2" +version = "=2.0.1" [dependencies.tauri-specta] features = ["derive", "typescript"] git = "https://github.com/spacedriveapp/tauri-specta" -rev = "6069a05029" +rev = "1baf68be47" [target.'cfg(target_os = "linux")'.dependencies] # Spacedrive Sub-crates @@ -60,8 +60,8 @@ sd-desktop-linux = { path = "../crates/linux" } # Specific Desktop dependencies # WARNING: dbus must NOT be vendored, as that breaks the app on Linux,X11,Nvidia dbus = { version = "0.9.7", features = ["stdfd"] } -# https://github.com/tauri-apps/tauri/blob/tauri-v2.0.0-rc.2/core/tauri/Cargo.toml#L86 -webkit2gtk = { version = "=2.0.1", features = ["v2_38"] } +# https://github.com/tauri-apps/tauri/blob/tauri-v2.0.0/crates/tauri/Cargo.toml#L101 +webkit2gtk = { version = "=2.0.1", features = ["v2_40"] } [target.'cfg(target_os = "macos")'.dependencies] # Spacedrive Sub-crates @@ -73,7 +73,7 @@ sd-desktop-windows = { path = "../crates/windows" } [build-dependencies] # Specific Desktop dependencies -tauri-build = "=2.0.0-rc.2" +tauri-build = "=2.0.1" [features] ai-models = ["sd-core/ai"] diff --git a/apps/desktop/src/commands.ts b/apps/desktop/src/commands.ts index bde568c77..81581cf81 100644 --- a/apps/desktop/src/commands.ts +++ b/apps/desktop/src/commands.ts @@ -203,7 +203,7 @@ export type Update = { version: string }; type __EventObj__ = { listen: (cb: TAURI_API_EVENT.EventCallback) => ReturnType>; once: (cb: TAURI_API_EVENT.EventCallback) => ReturnType>; - emit: T extends null + emit: null extends T ? (payload?: T) => ReturnType : (payload: T) => ReturnType; }; diff --git a/apps/desktop/src/patches.ts b/apps/desktop/src/patches.ts index a524d62f0..8fd5d4500 100644 --- a/apps/desktop/src/patches.ts +++ b/apps/desktop/src/patches.ts @@ -1,4 +1,4 @@ -import { tauriLink } from '@oscartbeaumont-sd/rspc-tauri/v2'; +import { tauriLink } from '@oscartbeaumont-sd/rspc-tauri/src/v2'; globalThis.isDev = import.meta.env.DEV; globalThis.rspcLinks = [ diff --git a/apps/desktop/src/platform.ts b/apps/desktop/src/platform.ts index 0e0311a41..7c20995d7 100644 --- a/apps/desktop/src/platform.ts +++ b/apps/desktop/src/platform.ts @@ -73,10 +73,7 @@ export const platform = { if (opts?.multiple) return result as any; // Tauri don't properly type narrow on `multiple` argument return result; }, - openFilePickerDialog: () => - dialogOpen({ - multiple: true - }).then((result) => result?.map((r) => r.path) ?? null), + openFilePickerDialog: () => dialogOpen({ multiple: true }), saveFilePickerDialog: (opts) => dialogSave(opts), showDevtools: () => invoke('show_devtools'), confirm: (msg, cb) => confirm(msg).then(cb), diff --git a/apps/mobile/.eslintrc.js b/apps/mobile/.eslintrc.js index 981f773dc..5236cb738 100644 --- a/apps/mobile/.eslintrc.js +++ b/apps/mobile/.eslintrc.js @@ -13,6 +13,7 @@ module.exports = { ], 'tailwindcss/no-contradicting-classname': 'warn', 'tailwindcss/enforces-shorthand': 'off', + '@typescript-eslint/no-require-imports': 'off', 'no-restricted-imports': [ 'error', { diff --git a/apps/mobile/metro.config.js b/apps/mobile/metro.config.js index 16202e297..b8a3cc3e1 100644 --- a/apps/mobile/metro.config.js +++ b/apps/mobile/metro.config.js @@ -5,9 +5,6 @@ const path = require('path'); // Needed for transforming svgs from @sd/assets const [reactSVGPath, reactSVGExclude] = resolveUniqueModule('react-native-svg'); -const [rspcClientPath, rspcClientExclude] = resolveUniqueModule('@oscartbeaumont-sd/rspc-client'); -const [rspcReactPath, rspcReactExclude] = resolveUniqueModule('@oscartbeaumont-sd/rspc-react'); - const { getDefaultConfig } = require('expo/metro-config'); const expoDefaultConfig = getDefaultConfig(__dirname); @@ -23,7 +20,7 @@ const metroConfig = makeMetroConfig({ extraNodeModules: { 'react-native-svg': reactSVGPath }, - blockList: exclusionList([reactSVGExclude, rspcClientExclude, rspcReactExclude]), + blockList: exclusionList([reactSVGExclude]), sourceExts: [...expoDefaultConfig.resolver.sourceExts, 'svg'], assetExts: expoDefaultConfig.resolver.assetExts.filter((ext) => ext !== 'svg'), disableHierarchicalLookup: false, @@ -31,22 +28,6 @@ const metroConfig = makeMetroConfig({ path.resolve(projectRoot, 'node_modules'), path.resolve(workspaceRoot, 'node_modules') ], - resolveRequest: (context, moduleName, platform) => { - if (moduleName.startsWith('@oscartbeaumont-sd/rspc-client/v2')) { - return { - filePath: path.resolve(rspcClientPath, 'dist', 'v2.js'), - type: 'sourceFile' - }; - } - if (moduleName.startsWith('@oscartbeaumont-sd/rspc-react/v2')) { - return { - filePath: path.resolve(rspcReactPath, 'dist', 'v2.js'), - type: 'sourceFile' - }; - } - // Optionally, chain to the standard Metro resolver. - return context.resolveRequest(context, moduleName, platform); - }, platforms: ['ios', 'android'] }, transformer: { diff --git a/apps/mobile/modules/sd-core/src/index.ts b/apps/mobile/modules/sd-core/src/index.ts index 43feea469..fb034782a 100644 --- a/apps/mobile/modules/sd-core/src/index.ts +++ b/apps/mobile/modules/sd-core/src/index.ts @@ -1,4 +1,4 @@ -import { AlphaRSPCError, Link, RspcRequest } from '@oscartbeaumont-sd/rspc-client/v2'; +import { AlphaRSPCError, Link, RspcRequest } from '@oscartbeaumont-sd/rspc-client/src/v2'; import { EventEmitter, requireNativeModule } from 'expo-modules-core'; // It loads the native module object from the JSI or falls back to diff --git a/apps/mobile/package.json b/apps/mobile/package.json index ee91eb800..5dc682437 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -21,8 +21,8 @@ "@dr.pogodin/react-native-fs": "^2.24.1", "@gorhom/bottom-sheet": "^4.6.1", "@hookform/resolvers": "^3.1.0", - "@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2", - "@oscartbeaumont-sd/rspc-react": "=0.0.0-main-dc31e5b2", + "@oscartbeaumont-sd/rspc-client": "github:spacedriveapp/rspc#path:packages/client&bc882f4724", + "@oscartbeaumont-sd/rspc-react": "github:spacedriveapp/rspc#path:packages/react&bc882f4724", "@react-native-async-storage/async-storage": "~1.23.1", "@react-native-masked-view/masked-view": "^0.3.1", "@react-navigation/bottom-tabs": "^6.5.19", @@ -33,7 +33,7 @@ "@sd/client": "workspace:*", "@shopify/flash-list": "1.6.4", "@tanstack/react-query": "^4.36.1", - "babel-preset-solid": "^1.8.9", + "babel-preset-solid": "^1.9.0", "class-variance-authority": "^0.7.0", "dayjs": "^1.11.10", "event-target-polyfill": "^0.0.4", @@ -82,7 +82,7 @@ "@rnx-kit/metro-config": "^1.3.15", "@sd/config": "workspace:*", "@types/react": "^18.2.79", - "babel-plugin-module-resolver": "^5.0.0", + "babel-plugin-module-resolver": "^5.0.2", "eslint-plugin-react-native": "^4.1.0", "react-native-svg-transformer": "^1.3.0", "typescript": "^5.3.3" diff --git a/apps/mobile/src/App.tsx b/apps/mobile/src/App.tsx index b22ebfb8b..3ec7b8c44 100644 --- a/apps/mobile/src/App.tsx +++ b/apps/mobile/src/App.tsx @@ -108,7 +108,7 @@ function AppNavigation() { if (navRef.getRootState().routeNames.includes('GetStarted')) { return; } - currentRouteName && setCurrentPath(currentRouteName); + if (currentRouteName) setCurrentPath(currentRouteName); } }} > diff --git a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx index 3078aae82..0a37496cc 100644 --- a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx +++ b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx @@ -25,7 +25,7 @@ const DrawerLibraryManager = () => { }, [isDrawerOpen]); const { library: currentLibrary, libraries } = useClientContext(); - const navigation = useNavigation(); + const navigation = useNavigation(); const modalRef = useRef(null); const modalRef_import = useRef(null); diff --git a/apps/mobile/src/components/explorer/Explorer.tsx b/apps/mobile/src/components/explorer/Explorer.tsx index 693620c83..10b448d7c 100644 --- a/apps/mobile/src/components/explorer/Explorer.tsx +++ b/apps/mobile/src/components/explorer/Explorer.tsx @@ -63,9 +63,8 @@ const Explorer = (props: Props) => { showAppsSuggestions: false, // If there is not an installed app that can open the file, open the Play Store with suggested apps showOpenWithDialog: true // if there is more than one app that can open the file, show an Open With dialogue box }); - filePath && - filePath.object_id && - (await libraryClient.mutation(['files.updateAccessTime', [filePath.object_id]])); + if (filePath && filePath.object_id) + await libraryClient.mutation(['files.updateAccessTime', [filePath.object_id]]); } catch (error) { toast.error('Error opening object'); } diff --git a/apps/mobile/src/components/job/JobGroup.tsx b/apps/mobile/src/components/job/JobGroup.tsx index a1e03de5c..26dc832ac 100644 --- a/apps/mobile/src/components/job/JobGroup.tsx +++ b/apps/mobile/src/components/job/JobGroup.tsx @@ -170,10 +170,11 @@ const toastErrorSuccess = ( ) => { return { onError: () => { - errorMessage && toast.error(errorMessage); + if (errorMessage) toast.error(errorMessage); }, onSuccess: () => { - successMessage && toast.success(successMessage), successCallBack?.(); + if (successMessage) toast.success(successMessage); + successCallBack?.(); } }; }; diff --git a/apps/mobile/src/components/modal/inspector/ActionsModal.tsx b/apps/mobile/src/components/modal/inspector/ActionsModal.tsx index f388b1ff4..4241010c3 100644 --- a/apps/mobile/src/components/modal/inspector/ActionsModal.tsx +++ b/apps/mobile/src/components/modal/inspector/ActionsModal.tsx @@ -102,9 +102,8 @@ export const ActionsModal = () => { showAppsSuggestions: false, // If there is not an installed app that can open the file, open the Play Store with suggested apps showOpenWithDialog: true // if there is more than one app that can open the file, show an Open With dialogue box }); - filePath && - filePath.object_id && - (await updateAccessTime.mutateAsync([filePath.object_id]).catch(console.error)); + if (filePath && filePath.object_id) + await updateAccessTime.mutateAsync([filePath.object_id]).catch(console.error); } catch (error) { toast.error('Error opening object'); } diff --git a/apps/mobile/src/components/modal/search/SaveSearchModal.tsx b/apps/mobile/src/components/modal/search/SaveSearchModal.tsx index d39febb99..8e0362398 100644 --- a/apps/mobile/src/components/modal/search/SaveSearchModal.tsx +++ b/apps/mobile/src/components/modal/search/SaveSearchModal.tsx @@ -10,7 +10,7 @@ import { useSearchStore } from '~/stores/searchStore'; const SaveSearchModal = forwardRef((_, ref) => { const [searchName, setSearchName] = useState(''); - const navigation = useNavigation(); + const navigation = useNavigation(); const searchStore = useSearchStore(); const saveSearch = useLibraryMutation('search.saved.create', { onSuccess: () => { diff --git a/apps/mobile/src/components/overview/CategoryItem.tsx b/apps/mobile/src/components/overview/CategoryItem.tsx index 8c4409fe6..6f7037491 100644 --- a/apps/mobile/src/components/overview/CategoryItem.tsx +++ b/apps/mobile/src/components/overview/CategoryItem.tsx @@ -19,7 +19,7 @@ interface CategoryItemProps { } const CategoryItem = ({ name, icon, items, style, kind }: CategoryItemProps) => { - const navigation = useNavigation(); + const navigation = useNavigation(); const searchStore = useSearchStore(); return ( { - const navigation = useNavigation(); + const navigation = useNavigation(); const dataForSearch = useSavedSearch(search); const rspc = useRspcLibraryContext(); const deleteSearch = useLibraryMutation('search.saved.delete', { diff --git a/apps/mobile/src/hooks/useSavedSearch.ts b/apps/mobile/src/hooks/useSavedSearch.ts index 45e82f3c8..0bdaa7e59 100644 --- a/apps/mobile/src/hooks/useSavedSearch.ts +++ b/apps/mobile/src/hooks/useSavedSearch.ts @@ -1,5 +1,6 @@ +import { IconTypes } from '@sd/assets/util'; import { useCallback, useMemo } from 'react'; -import { SavedSearch, SearchFilterArgs, useLibraryQuery } from '@sd/client'; +import { SavedSearch, SearchFilterArgs, Tag, useLibraryQuery } from '@sd/client'; import { kinds } from '~/components/search/filters/Kind'; import { Filters, SearchFilters } from '~/stores/searchStore'; @@ -56,7 +57,14 @@ export function useSavedSearch(search: SavedSearch) { // it is then 'matched' with the data from the "Saved Search" const prepFilters = useCallback(() => { - const data = {} as Record; + const data = { + locations: undefined as undefined | { id: number; name: string | null }[], + tags: undefined as undefined | { id: number; color: string | null }[], + kind: undefined as undefined | { name: string; id: number; icon: IconTypes }[], + name: [] as unknown[], + extension: [] as unknown[], + hidden: [] + }; filterKeys.forEach((key: SearchFilters) => { switch (key) { case 'locations': @@ -97,7 +105,7 @@ export function useSavedSearch(search: SavedSearch) { const filters: Partial = useMemo(() => { return parseFilters.reduce( - (acc: Record, curr: keyof SearchFilterArgs) => { + (acc: Record, curr: keyof SearchFilterArgs) => { const objectOrFilePath = Object.keys(curr)[0] as 'filePath' | 'object'; const key = Object.keys(curr[objectOrFilePath])[0] as SearchFilters; //locations, tags, kind, etc... @@ -113,12 +121,22 @@ export function useSavedSearch(search: SavedSearch) { switch (type) { case 'contains': // some filters have a name property and some are just strings - return prepFilters()[key].filter((item: any) => { - return item.name ? item.name === values[type] : item; + return prepFilters()[key]?.filter((item: unknown) => { + return typeof item === 'object' && + item != null && + 'name' in item && + item.name + ? item.name === values[type] + : item; }); case 'in': - return prepFilters()[key].filter((item: any) => - values[type]?.includes(item.id) + return prepFilters()[key]?.filter( + (item: unknown) => + typeof item === 'object' && + item != null && + 'id' in item && + typeof item.id === 'number' && + values[type]?.includes(item.id) ); default: return values; diff --git a/apps/mobile/src/navigation/index.tsx b/apps/mobile/src/navigation/index.tsx index 13dab8721..6a435217f 100644 --- a/apps/mobile/src/navigation/index.tsx +++ b/apps/mobile/src/navigation/index.tsx @@ -42,11 +42,3 @@ export type RootStackScreenProps = Nati RootStackParamList, Screen >; - -// This declaration is used by useNavigation, Link, ref etc. -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace ReactNavigation { - interface RootParamList extends RootStackParamList {} - } -} diff --git a/apps/mobile/src/screens/BackfillWaiting.tsx b/apps/mobile/src/screens/BackfillWaiting.tsx index aedc72364..ab13c54e7 100644 --- a/apps/mobile/src/screens/BackfillWaiting.tsx +++ b/apps/mobile/src/screens/BackfillWaiting.tsx @@ -18,7 +18,7 @@ const { width } = Dimensions.get('window'); const BackfillWaiting = () => { const animation = useSharedValue(0); - const navigation = useNavigation(); + const navigation = useNavigation(); useEffect(() => { animation.value = withRepeat( diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 8cc051cd7..75e6621af 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -29,7 +29,7 @@ "rollup-plugin-node-builtins": "^2.1.2", "storybook": "^8.0.1", "tailwindcss": "^3.4.1", - "typescript": "^5.4.2", + "typescript": "^5.6.2", "vite": "^5.2.0" } } diff --git a/apps/web/package.json b/apps/web/package.json index 2734ee293..b487de1d8 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -17,7 +17,7 @@ "lint": "eslint src --cache" }, "dependencies": { - "@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2", + "@oscartbeaumont-sd/rspc-client": "github:spacedriveapp/rspc#path:packages/client&bc882f4724", "@sd/client": "workspace:*", "@sd/interface": "workspace:*", "@tanstack/react-query": "^4.36.1", @@ -40,7 +40,7 @@ "postcss": "^8.4.36", "rollup-plugin-visualizer": "^5.12.0", "start-server-and-test": "^2.0.3", - "typescript": "^5.4.2", + "typescript": "^5.6.2", "vite": "^5.2.0", "vite-tsconfig-paths": "^4.3.2" } diff --git a/apps/web/src/patches.ts b/apps/web/src/patches.ts index 2e88c5480..2faac6997 100644 --- a/apps/web/src/patches.ts +++ b/apps/web/src/patches.ts @@ -1,4 +1,4 @@ -import { wsBatchLink } from '@oscartbeaumont-sd/rspc-client/v2'; +import { wsBatchLink } from '@oscartbeaumont-sd/rspc-client/src/v2'; globalThis.isDev = import.meta.env.DEV; globalThis.rspcLinks = [ diff --git a/core/Cargo.toml b/core/Cargo.toml index 64a46ff31..49aac5516 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -63,7 +63,7 @@ regex = { workspace = true } reqwest = { workspace = true, features = ["json", "native-tls-vendored"] } rmp-serde = { workspace = true } rmpv = { workspace = true } -rspc = { workspace = true, features = ["alpha", "axum", "chrono", "tracing", "unstable", "uuid"] } +rspc = { workspace = true, features = ["alpha", "axum", "chrono", "unstable", "uuid"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } specta = { workspace = true } diff --git a/core/crates/heavy-lifting/src/job_system/report.rs b/core/crates/heavy-lifting/src/job_system/report.rs index a0ec935c9..9f87b1eb4 100644 --- a/core/crates/heavy-lifting/src/job_system/report.rs +++ b/core/crates/heavy-lifting/src/job_system/report.rs @@ -404,7 +404,7 @@ impl ReportBuilder { } #[must_use] - pub fn new(id: JobId, name: JobName) -> Self { + pub const fn new(id: JobId, name: JobName) -> Self { Self { id, name, diff --git a/core/crates/heavy-lifting/src/media_processor/helpers/thumbnailer.rs b/core/crates/heavy-lifting/src/media_processor/helpers/thumbnailer.rs index 947757a4c..d1637ebb3 100644 --- a/core/crates/heavy-lifting/src/media_processor/helpers/thumbnailer.rs +++ b/core/crates/heavy-lifting/src/media_processor/helpers/thumbnailer.rs @@ -92,7 +92,7 @@ pub static ALL_THUMBNAILABLE_EXTENSIONS: LazyLock> = LazyLock::ne THUMBNAILABLE_EXTENSIONS.clone() }); -static WEBP_CONFIG: std::sync::LazyLock = std::sync::LazyLock::new(|| { +static WEBP_CONFIG: LazyLock = LazyLock::new(|| { let mut config = WebPConfig::new().expect("failed to instantiate global webp config"); config.lossless = 0; config.alpha_compression = 1; diff --git a/core/src/api/auth.rs b/core/src/api/auth.rs index 52673323e..994dc7474 100644 --- a/core/src/api/auth.rs +++ b/core/src/api/auth.rs @@ -42,7 +42,7 @@ pub(crate) fn mount() -> AlphaRouter { let auth_response = match match node .http - .post(&format!( + .post(format!( "{}/login/device/code", &node.env.api_url.lock().await )) @@ -74,7 +74,7 @@ pub(crate) fn mount() -> AlphaRouter { tokio::time::sleep(Duration::from_secs(5)).await; let token_resp = match node.http - .post(&format!("{}/login/oauth/access_token", &node.env.api_url.lock().await)) + .post(format!("{}/login/oauth/access_token", &node.env.api_url.lock().await)) .form(&[ ("grant_type", sd_cloud_api::auth::DEVICE_CODE_URN), ("device_code", &auth_response.device_code), diff --git a/core/src/library/statistics.rs b/core/src/library/statistics.rs index e8c757eba..f6fc4422e 100644 --- a/core/src/library/statistics.rs +++ b/core/src/library/statistics.rs @@ -47,7 +47,7 @@ pub async fn update_library_statistics( node.config .data_directory() .join("libraries") - .join(&format!("{}.db", library.id)), + .join(format!("{}.db", library.id)), ) .await .unwrap_or(0); diff --git a/crates/ai/src/old_image_labeler/model/mod.rs b/crates/ai/src/old_image_labeler/model/mod.rs index edcf21be7..64b30e858 100644 --- a/crates/ai/src/old_image_labeler/model/mod.rs +++ b/crates/ai/src/old_image_labeler/model/mod.rs @@ -127,11 +127,10 @@ impl ModelAndSession { self.maybe_model = Some(new_model); self.maybe_session = Some(session); }) - .map_err(|e| { + .inspect_err(|e| { + error!("Failed to load new model: {e:#?}"); self.maybe_model = None; self.maybe_session = None; - - e }) }) } diff --git a/crates/cloud-api/src/lib.rs b/crates/cloud-api/src/lib.rs index a6d557dca..b505dfa23 100644 --- a/crates/cloud-api/src/lib.rs +++ b/crates/cloud-api/src/lib.rs @@ -127,7 +127,7 @@ pub mod user { config .client - .get(&format!("{}/api/v1/user/me", config.api_url)) + .get(format!("{}/api/v1/user/me", config.api_url)) .with_auth(auth_token) .send() .await @@ -153,7 +153,7 @@ pub mod library { config .client - .get(&format!( + .get(format!( "{}/api/v1/libraries/{}", config.api_url, library_id )) @@ -180,7 +180,7 @@ pub mod library { config .client - .get(&format!("{}/api/v1/libraries", config.api_url)) + .get(format!("{}/api/v1/libraries", config.api_url)) .with_auth(auth_token) .send() .await @@ -219,7 +219,7 @@ pub mod library { config .client - .post(&format!( + .post(format!( "{}/api/v1/libraries/{}", config.api_url, library_id )) @@ -256,7 +256,7 @@ pub mod library { config .client - .patch(&format!( + .patch(format!( "{}/api/v1/libraries/{}", config.api_url, library_id )) @@ -289,7 +289,7 @@ pub mod library { config .client - .patch(&format!( + .patch(format!( "{}/api/v1/libraries/{}/{}", config.api_url, library_id, instance_id )) @@ -325,7 +325,7 @@ pub mod library { config .client - .post(&format!( + .post(format!( "{}/api/v1/libraries/{library_id}/instances/{instance_uuid}", config.api_url )) @@ -372,7 +372,7 @@ pub mod library { let res = config .client - .post(&format!( + .post(format!( "{}/api/v1/libraries/{}/messageCollections/get", config.api_url, library_id )) @@ -439,7 +439,7 @@ pub mod library { let res = config .client - .post(&format!( + .post(format!( "{}/api/v1/libraries/{}/messageCollections/requestAdd", config.api_url, library_id )) @@ -499,7 +499,7 @@ pub mod library { config .client - .post(&format!( + .post(format!( "{}/api/v1/libraries/{}/messageCollections/doAdd", config.api_url, library_id )) @@ -536,7 +536,7 @@ pub mod locations { config .client - .get(&format!("{}/api/v1/locations", config.api_url)) + .get(format!("{}/api/v1/locations", config.api_url)) .with_auth(auth_token) .send() .await @@ -560,7 +560,7 @@ pub mod locations { config .client - .post(&format!("{}/api/v1/locations", config.api_url)) + .post(format!("{}/api/v1/locations", config.api_url)) .json(&json!({ "name": name, })) @@ -587,7 +587,7 @@ pub mod locations { config .client - .post(&format!("{}/api/v1/locations/delete", config.api_url)) + .post(format!("{}/api/v1/locations/delete", config.api_url)) .json(&json!({ "id": id, })) @@ -614,7 +614,7 @@ pub mod locations { config .client - .post(&format!("{}/api/v1/locations/authorize", config.api_url)) + .post(format!("{}/api/v1/locations/authorize", config.api_url)) .json(&json!({ "id": id })) .with_auth(auth_token) .send() diff --git a/crates/images/Cargo.toml b/crates/images/Cargo.toml index 3835927d2..fd13c1e14 100644 --- a/crates/images/Cargo.toml +++ b/crates/images/Cargo.toml @@ -24,7 +24,7 @@ bincode = { version = "=2.0.0-rc.3", features = ["alloc", "derive"], optional = # Disable defaults for libheif* to avoid bindgen and use pre-compiled headers libheif-rs = { version = "1.0", default-features = false, optional = true } libheif-sys = { version = "2.1", default-features = false, optional = true } -resvg = "0.43.0" +resvg = "0.44.0" [dependencies.pdfium-render] default-features = false diff --git a/crates/images/src/svg.rs b/crates/images/src/svg.rs index ec76829f4..c4cac3d91 100644 --- a/crates/images/src/svg.rs +++ b/crates/images/src/svg.rs @@ -35,6 +35,7 @@ impl ImageHandler for SvgHandler { image_href_resolver: usvg::ImageHrefResolver::default(), font_resolver: usvg::FontResolver::default(), fontdb: Arc::new(fontdb), + style_sheet: None, }; let rtree = usvg::Tree::from_data(&data, &options)?; diff --git a/crates/sync/example/web/package.json b/crates/sync/example/web/package.json index 70de393ff..0c95d0ba5 100644 --- a/crates/sync/example/web/package.json +++ b/crates/sync/example/web/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@tanstack/react-query": "^4.36.1", - "typescript": "^5.4.2", + "typescript": "^5.6.2", "vite": "^5.2.0", "tailwindcss": "^3.3.3" } diff --git a/crates/task-system/src/task.rs b/crates/task-system/src/task.rs index 8b0ed2956..1b345e812 100644 --- a/crates/task-system/src/task.rs +++ b/crates/task-system/src/task.rs @@ -258,7 +258,7 @@ impl Drop for Interrupter { } impl Interrupter { - pub(crate) fn new(interrupt_tx: chan::Receiver) -> Self { + pub(crate) const fn new(interrupt_tx: chan::Receiver) -> Self { Self { interrupt_rx: interrupt_tx, } @@ -659,7 +659,7 @@ pub struct TaskWorktable { } impl TaskWorktable { - pub fn new(worker_id: WorkerId, interrupt_tx: chan::Sender) -> Self { + pub const fn new(worker_id: WorkerId, interrupt_tx: chan::Sender) -> Self { Self { started: AtomicBool::new(false), is_running: AtomicBool::new(false), @@ -899,7 +899,7 @@ pub struct PanicOnSenderDrop { } impl PanicOnSenderDrop { - pub fn new( + pub const fn new( task_id: TaskId, done_tx: oneshot::Sender, SystemError>>, ) -> Self { diff --git a/interface/app/$libraryId/Explorer/FilePath/Original.tsx b/interface/app/$libraryId/Explorer/FilePath/Original.tsx index 90c6f0c67..451b13d35 100644 --- a/interface/app/$libraryId/Explorer/FilePath/Original.tsx +++ b/interface/app/$libraryId/Explorer/FilePath/Original.tsx @@ -205,7 +205,11 @@ const Video = ({ paused, blackBars, blackBarsSize, className, ...props }: VideoP useEffect(() => { if (!ref.current) return; - paused ? ref.current.pause() : ref.current.play(); + if (paused) { + ref.current.pause(); + } else { + ref.current.play(); + } }, [paused]); return ( diff --git a/interface/app/$libraryId/Explorer/FilePath/RenameTextBox.tsx b/interface/app/$libraryId/Explorer/FilePath/RenameTextBox.tsx index cf47a5309..5651edd77 100644 --- a/interface/app/$libraryId/Explorer/FilePath/RenameTextBox.tsx +++ b/interface/app/$libraryId/Explorer/FilePath/RenameTextBox.tsx @@ -265,7 +265,7 @@ export const RenameTextBox = forwardRef( }} onMouseDownCapture={(e) => { if (allowRename) e.stopPropagation(); - e.button === 0 && (renamable.current = !disabled); + if (e.button === 0) renamable.current = !disabled; }} onMouseUp={(e) => { if (e.button === 0 || renamable.current || !allowRename) { diff --git a/interface/app/$libraryId/Explorer/Inspector/MediaData.tsx b/interface/app/$libraryId/Explorer/Inspector/MediaData.tsx index 28aafd262..2d04b476f 100644 --- a/interface/app/$libraryId/Explorer/Inspector/MediaData.tsx +++ b/interface/app/$libraryId/Explorer/Inspector/MediaData.tsx @@ -156,14 +156,16 @@ export const MediaData = ({ data }: Props) => { } else if ('FFmpeg' in data) { const streamKinds = new Set( data.FFmpeg.programs.flatMap((program) => - program.streams.map((stream) => stream.codec?.kind) + program.streams + .map((stream) => stream.codec?.kind) + .filter((kind): kind is string => !!kind) ) ); const type = streamKinds.has('video') ? 'Video' : streamKinds.has('audio') ? 'Audio' - : (capitalize(streamKinds.values().next().value) ?? 'Unknown'); + : capitalize(streamKinds.values().next().value ?? 'Unknown'); const bit_rate = humanizeSize(int32ArrayToBigInt(data.FFmpeg.bit_rate), { is_bit: true, diff --git a/interface/app/$libraryId/Explorer/QuickPreview/index.tsx b/interface/app/$libraryId/Explorer/QuickPreview/index.tsx index fb27a430e..ad1b0fdc5 100644 --- a/interface/app/$libraryId/Explorer/QuickPreview/index.tsx +++ b/interface/app/$libraryId/Explorer/QuickPreview/index.tsx @@ -638,12 +638,12 @@ export const QuickPreview = () => { data={item} onLoad={(type) => { setThumbnailLoading('loaded'); - type.variant === 'original' && + if (type.variant === 'original') setThumbErrorToast(undefined); }} onError={(type, error) => { setThumbnailLoading('error'); - type.variant === 'original' && + if (type.variant === 'original') setThumbErrorToast({ title: t('error_loading_original_file'), body: error.message diff --git a/interface/app/$libraryId/Explorer/View/index.tsx b/interface/app/$libraryId/Explorer/View/index.tsx index 4c9b61282..f99fe5f96 100644 --- a/interface/app/$libraryId/Explorer/View/index.tsx +++ b/interface/app/$libraryId/Explorer/View/index.tsx @@ -175,7 +175,7 @@ export const View = ({ emptyNotice, ...contextProps }: ExplorerViewProps) => { // This is to allow drag multi-selection if (e.shiftKey || (isWindowsExplorer ? e.ctrlKey : e.metaKey)) return; - explorer.selectedItems.size !== 0 && explorer.resetSelectedItems(); + if (explorer.selectedItems.size !== 0) explorer.resetSelectedItems(); }} >
diff --git a/interface/app/$libraryId/Layout/Sidebar/DebugPopover.tsx b/interface/app/$libraryId/Layout/Sidebar/DebugPopover.tsx index 7af5e0ac7..21eec1971 100644 --- a/interface/app/$libraryId/Layout/Sidebar/DebugPopover.tsx +++ b/interface/app/$libraryId/Layout/Sidebar/DebugPopover.tsx @@ -141,7 +141,7 @@ export default () => { size="sm" variant="gray" onClick={() => { - platform.reloadWebview && platform.reloadWebview(); + if (platform.reloadWebview) platform.reloadWebview(); }} > Reload diff --git a/interface/app/$libraryId/Layout/Sidebar/JobManager/JobGroup.tsx b/interface/app/$libraryId/Layout/Sidebar/JobManager/JobGroup.tsx index aa5541f4e..90f29f525 100644 --- a/interface/app/$libraryId/Layout/Sidebar/JobManager/JobGroup.tsx +++ b/interface/app/$libraryId/Layout/Sidebar/JobManager/JobGroup.tsx @@ -150,19 +150,19 @@ const toastErrorSuccess = ( ) => { return { onError: () => { - errorMessage && + if (errorMessage) toast.error({ title: 'Error', body: errorMessage }); }, onSuccess: () => { - successMessage && + if (successMessage) toast.success({ title: 'Success', body: successMessage - }), - successCallBack?.(); + }); + successCallBack?.(); } }; }; diff --git a/interface/app/$libraryId/Spacedrop/toast.tsx b/interface/app/$libraryId/Spacedrop/toast.tsx index bf0099866..52120a0e4 100644 --- a/interface/app/$libraryId/Spacedrop/toast.tsx +++ b/interface/app/$libraryId/Spacedrop/toast.tsx @@ -37,7 +37,7 @@ export function useIncomingSpacedropToast() { { duration: 30 * 1000, onClose: ({ event }) => { - event !== 'on-action' && acceptSpacedrop.mutate([data.id, null]); + if (event !== 'on-action') acceptSpacedrop.mutate([data.id, null]); }, action: { label: t('accept'), diff --git a/interface/app/$libraryId/TopBar/TopBarOptions.tsx b/interface/app/$libraryId/TopBar/TopBarOptions.tsx index 6e5716c47..ba08fbbc3 100644 --- a/interface/app/$libraryId/TopBar/TopBarOptions.tsx +++ b/interface/app/$libraryId/TopBar/TopBarOptions.tsx @@ -18,7 +18,7 @@ export interface ToolOption { topBarActive?: boolean; popOverComponent?: JSX.Element | ((props: { triggerClose: () => void }) => JSX.Element); showAtResolution: ShowAtResolution; - keybinds?: Array; + keybinds?: Array; } export type ShowAtResolution = 'sm:flex' | 'md:flex' | 'lg:flex' | 'xl:flex' | '2xl:flex'; diff --git a/interface/app/$libraryId/ephemeral.tsx b/interface/app/$libraryId/ephemeral.tsx index 089262c38..4aacac2b1 100644 --- a/interface/app/$libraryId/ephemeral.tsx +++ b/interface/app/$libraryId/ephemeral.tsx @@ -1,4 +1,4 @@ -import { type AlphaClient } from '@oscartbeaumont-sd/rspc-client/v2'; +import { type AlphaClient } from '@oscartbeaumont-sd/rspc-client/src/v2'; import { ArrowLeft, ArrowRight, Info } from '@phosphor-icons/react'; import * as Dialog from '@radix-ui/react-dialog'; import { iconNames } from '@sd/assets/util'; diff --git a/interface/app/$libraryId/overview/FileKindStats.tsx b/interface/app/$libraryId/overview/FileKindStats.tsx index 6f7b7a1e8..2d2f4fb93 100644 --- a/interface/app/$libraryId/overview/FileKindStats.tsx +++ b/interface/app/$libraryId/overview/FileKindStats.tsx @@ -44,8 +44,6 @@ const interpolateHexColor = (color1: string, color2: string, factor: number): st return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`; }; -interface FileKindStatsProps {} - const defaultFileKinds: FileKind[] = [ { kind: 4, name: 'Package', count: 0n, total_bytes: 0n }, { kind: 8, name: 'Archive', count: 0n, total_bytes: 0n }, @@ -67,7 +65,7 @@ const defaultFileKinds: FileKind[] = [ { kind: 25, name: 'Screenshot', count: 0n, total_bytes: 0n } ]; -const FileKindStats: React.FC = () => { +const FileKindStats: React.FC = () => { const isDark = useIsDark(); const navigate = useNavigate(); const { t } = useLocale(); diff --git a/interface/app/$libraryId/peer/StarfieldEffect.tsx b/interface/app/$libraryId/peer/StarfieldEffect.tsx index b26ab6605..7ac442fa1 100644 --- a/interface/app/$libraryId/peer/StarfieldEffect.tsx +++ b/interface/app/$libraryId/peer/StarfieldEffect.tsx @@ -78,9 +78,9 @@ const StarfieldEffect: React.FC = () => { a: number ) => { const i = (x + y * canvas.width) * 4; - pix[i] += r; - pix[i + 1] += g; - pix[i + 2] += b; + pix[i] = (pix[i] ?? 0) + r; + pix[i + 1] = (pix[i + 1] ?? 0) + g; + pix[i + 2] = (pix[i + 2] ?? 0) + b; pix[i + 3] = a; }; diff --git a/interface/app/$libraryId/settings/node/libraries/DeleteDialog.tsx b/interface/app/$libraryId/settings/node/libraries/DeleteDialog.tsx index 391944337..7425a0df0 100644 --- a/interface/app/$libraryId/settings/node/libraries/DeleteDialog.tsx +++ b/interface/app/$libraryId/settings/node/libraries/DeleteDialog.tsx @@ -27,7 +27,7 @@ export default function DeleteLibraryDialog(props: Props) { queryClient.invalidateQueries(['library.list']); - platform.refreshMenuBar && platform.refreshMenuBar(); + if (platform.refreshMenuBar) platform.refreshMenuBar(); submitPlausibleEvent({ event: { diff --git a/interface/app/$libraryId/settings/node/libraries/JoinDialog.tsx b/interface/app/$libraryId/settings/node/libraries/JoinDialog.tsx index 205cbd6df..759d890e7 100644 --- a/interface/app/$libraryId/settings/node/libraries/JoinDialog.tsx +++ b/interface/app/$libraryId/settings/node/libraries/JoinDialog.tsx @@ -45,7 +45,7 @@ export default (props: UseDialogProps & { librariesCtx: LibraryConfigWrapped[] | return [...(libraries || []), library]; }); - platform.refreshMenuBar && platform.refreshMenuBar(); + if (platform.refreshMenuBar) platform.refreshMenuBar(); navigate(`/${library.uuid}`, { replace: true }); } catch (e: any) { diff --git a/interface/app/index.tsx b/interface/app/index.tsx index 8cf56a19b..3216925a1 100644 --- a/interface/app/index.tsx +++ b/interface/app/index.tsx @@ -1,4 +1,4 @@ -import { initRspc, wsBatchLink, type AlphaClient } from '@oscartbeaumont-sd/rspc-client/v2'; +import { initRspc, wsBatchLink, type AlphaClient } from '@oscartbeaumont-sd/rspc-client/src/v2'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useEffect, useMemo, useState } from 'react'; import { @@ -267,14 +267,12 @@ function RemoteLayout() { { ]); insertLibrary(queryClient, library); - platform.refreshMenuBar && platform.refreshMenuBar(); + if (platform.refreshMenuBar) platform.refreshMenuBar(); if (telemetryState.shareFullTelemetry) { submitPlausibleEvent({ event: { type: 'libraryCreate' } }); diff --git a/interface/app/onboarding/join-library.tsx b/interface/app/onboarding/join-library.tsx index 4ed91c0f0..d4bbed977 100644 --- a/interface/app/onboarding/join-library.tsx +++ b/interface/app/onboarding/join-library.tsx @@ -67,7 +67,7 @@ function CloudLibraries() { return [...(libraries || []), library]; }); - platform.refreshMenuBar && platform.refreshMenuBar(); + if (platform.refreshMenuBar) platform.refreshMenuBar(); resetOnboardingStore(); navigate(`/${library.uuid}`, { replace: true }); diff --git a/interface/components/AlertDialog.tsx b/interface/components/AlertDialog.tsx index 7ab550da5..ee1ca1935 100644 --- a/interface/components/AlertDialog.tsx +++ b/interface/components/AlertDialog.tsx @@ -38,7 +38,7 @@ const AlertDialog = (props: Props) => {