diff --git a/.github/workflows/build-test-publish-apps.yml b/.github/workflows/build-test-publish-apps.yml index 229ef28f8..efed9932b 100644 --- a/.github/workflows/build-test-publish-apps.yml +++ b/.github/workflows/build-test-publish-apps.yml @@ -51,6 +51,8 @@ jobs: run: | VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons + # TODO: see if we need to inject updater nightly URL here https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json + - uses: actions/upload-artifact@v3 with: name: prepared-files @@ -61,25 +63,12 @@ jobs: - id: export_version run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT" - - name: Prepare electron-builder.yml file for nightly - if: ${{ github.event_name == 'schedule' }} - run: | - yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/nightly"' electron-builder.yml - - - uses: actions/upload-artifact@v3 - if: ${{ github.event_name == 'schedule' }} - with: - name: prepared-files-nightly - path: | - electron-builder.yml - - name: Prepare electron-builder.yml file for updater test if: ${{ env.CUT_RELEASE_PR == 'true' }} run: | yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml - uses: actions/upload-artifact@v3 - if: ${{ env.CUT_RELEASE_PR == 'true' }} with: name: prepared-files-updater-test path: | @@ -119,16 +108,6 @@ jobs: mkdir src/wasm-lib/pkg cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg - - uses: actions/download-artifact@v3 - if: ${{ github.event_name == 'schedule' }} - name: prepared-files-nightly - - - name: Copy updated electron-builder.yml file for nightly build - if: ${{ github.event_name == 'schedule' }} - run: | - ls -R prepared-files-nightly - cp prepared-files-nightly/electron-builder.yml electron-builder.yml - - name: Sync node version and setup cache uses: actions/setup-node@v4 with: @@ -173,17 +152,11 @@ jobs: - uses: actions/upload-artifact@v3 with: - name: out-arm64-${{ matrix.os }} + name: out-${{ matrix.os }} path: | - out/Zoo*arm64*.* + out/Zoo*.* out/latest*.yml - - uses: actions/upload-artifact@v3 - with: - name: out-x64-${{ matrix.os }} - path: | - out/Zoo*x*64*.* - # TODO: add the 'Build for Mac TestFlight (nightly)' stage back - uses: actions/download-artifact@v3 @@ -203,16 +176,10 @@ jobs: - uses: actions/upload-artifact@v3 if: ${{ env.CUT_RELEASE_PR == 'true' }} with: - name: updater-test-arm64-${{ matrix.os }} + name: updater-test-${{ matrix.os }} path: | - out/Zoo*arm64*.* - - - uses: actions/upload-artifact@v3 - if: ${{ env.CUT_RELEASE_PR == 'true' }} - with: - name: updater-test-x64-${{ matrix.os }} - path: | - out/Zoo*x64*.* + out/Zoo*.* + out/latest*.yml publish-apps-release: @@ -234,32 +201,17 @@ jobs: - uses: actions/download-artifact@v3 with: - name: out-arm64-windows-2022 + name: out-windows-2022 path: out - uses: actions/download-artifact@v3 with: - name: out-x64-windows-2022 + name: out-macos-14 path: out - uses: actions/download-artifact@v3 with: - name: out-arm64-macos-14 - path: out - - - uses: actions/download-artifact@v3 - with: - name: out-x64-macos-14 - path: out - - - uses: actions/download-artifact@v3 - with: - name: out-arm64-ubuntu-22.04 - path: out - - - uses: actions/download-artifact@v3 - with: - name: out-x64-ubuntu-22.04 + name: out-ubuntu-22.04 path: out - name: Generate the download static endpoint diff --git a/e2e/playwright/testing-settings.spec.ts b/e2e/playwright/testing-settings.spec.ts index a38908c63..63aa05f46 100644 --- a/e2e/playwright/testing-settings.spec.ts +++ b/e2e/playwright/testing-settings.spec.ts @@ -9,6 +9,7 @@ import { executorInputPath, } from './test-utils' import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes' +import { SETTINGS_FILE_NAME } from 'lib/constants' import { TEST_SETTINGS_KEY, TEST_SETTINGS_CORRUPTED, @@ -343,7 +344,7 @@ test.describe('Testing settings', () => { // Selectors and constants const errorHeading = page.getByRole('heading', { - name: 'An unextected error occurred', + name: 'An unexpected error occurred', }) const projectDirLink = page.getByText('Loaded from') @@ -372,7 +373,7 @@ test.describe('Testing settings', () => { // Selectors and constants const errorHeading = page.getByRole('heading', { - name: 'An unextected error occurred', + name: 'An unexpected error occurred', }) const projectDirLink = page.getByText('Loaded from') @@ -384,6 +385,66 @@ test.describe('Testing settings', () => { } ) + // It was much easier to test the logo color than the background stream color. + test( + 'user settings reload on external change, on project and modeling view', + { tag: '@electron' }, + async ({ browserName }, testInfo) => { + const { + electronApp, + page, + dir: projectDirName, + } = await setupElectron({ + testInfo, + appSettings: { + app: { + // Doesn't matter what you set it to. It will + // default to 264.5 + themeColor: '0', + }, + }, + }) + + await page.setViewportSize({ width: 1200, height: 500 }) + + const logoLink = page.getByTestId('app-logo') + const projectDirLink = page.getByText('Loaded from') + + await test.step('Wait for project view', async () => { + await expect(projectDirLink).toBeVisible() + await expect(logoLink).toHaveCSS('--primary-hue', '264.5') + }) + + const changeColor = async (color: string) => { + const tempSettingsFilePath = join(projectDirName, SETTINGS_FILE_NAME) + let tomlStr = await fsp.readFile(tempSettingsFilePath, 'utf-8') + tomlStr = tomlStr.replace(/(themeColor = ")[0-9]+(")/, `$1${color}$2`) + await fsp.writeFile(tempSettingsFilePath, tomlStr) + } + + await test.step('Check color of logo changed', async () => { + await changeColor('99') + await expect(logoLink).toHaveCSS('--primary-hue', '99') + }) + + await test.step('Check color of logo changed when in modeling view', async () => { + await page.getByRole('button', { name: 'New project' }).click() + await page.getByTestId('project-link').first().click() + await page.getByRole('button', { name: 'Dismiss' }).click() + await changeColor('58') + await expect(logoLink).toHaveCSS('--primary-hue', '58') + }) + + await test.step('Check going back to projects view still changes the color', async () => { + await logoLink.click() + await expect(projectDirLink).toBeVisible() + await changeColor('21') + await expect(logoLink).toHaveCSS('--primary-hue', '21') + }) + await electronApp.close() + } + ) + test( `Closing settings modal should go back to the original file being viewed`, { tag: '@electron' }, diff --git a/interface.d.ts b/interface.d.ts index fa0f9da00..7319c69c1 100644 --- a/interface.d.ts +++ b/interface.d.ts @@ -23,7 +23,6 @@ export interface IElectronAPI { callback: (eventType: string, path: string) => void ) => void watchFileOff: (path: string) => void - watchFileObliterate: () => void readFile: (path: string) => ReturnType writeFile: ( path: string, diff --git a/package.json b/package.json index 7e763e0c7..7bac99c42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zoo-modeling-app", - "version": "0.25.5", + "version": "0.25.6", "private": true, "productName": "Zoo Modeling App", "author": { @@ -36,6 +36,7 @@ "@xstate/inspect": "^0.8.0", "@xstate/react": "^4.1.1", "bonjour-service": "^1.2.1", + "chokidar": "^4.0.1", "codemirror": "^6.0.1", "decamelize": "^6.0.0", "electron-squirrel-startup": "^1.0.1", diff --git a/src/components/SettingsAuthProvider.tsx b/src/components/SettingsAuthProvider.tsx index 35c602d21..9c4da1a9d 100644 --- a/src/components/SettingsAuthProvider.tsx +++ b/src/components/SettingsAuthProvider.tsx @@ -1,9 +1,10 @@ +import { trap } from 'lib/trap' import { useMachine } from '@xstate/react' import { useNavigate, useRouteLoaderData, useLocation } from 'react-router-dom' import { PATHS } from 'lib/paths' import { authMachine, TOKEN_PERSIST_KEY } from '../machines/authMachine' import withBaseUrl from '../lib/withBaseURL' -import React, { createContext, useEffect } from 'react' +import React, { createContext, useEffect, useState } from 'react' import useStateMachineCommands from '../hooks/useStateMachineCommands' import { settingsMachine } from 'machines/settingsMachine' import { toast } from 'react-hot-toast' @@ -15,7 +16,6 @@ import { } from 'lib/theme' import decamelize from 'decamelize' import { Actor, AnyStateMachine, ContextFrom, Prop, StateFrom } from 'xstate' -import { isDesktop } from 'lib/isDesktop' import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig' import { kclManager, @@ -33,8 +33,14 @@ import { import { useCommandsContext } from 'hooks/useCommandsContext' import { Command } from 'lib/commandTypes' import { BaseUnit } from 'lib/settings/settingsTypes' -import { saveSettings } from 'lib/settings/settingsUtils' +import { + saveSettings, + loadAndValidateSettings, +} from 'lib/settings/settingsUtils' import { reportRejection } from 'lib/trap' +import { getAppSettingsFilePath } from 'lib/desktop' +import { isDesktop } from 'lib/isDesktop' +import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher' type MachineContext = { state: StateFrom @@ -99,6 +105,9 @@ export const SettingsAuthProviderBase = ({ const location = useLocation() const navigate = useNavigate() const { commandBarSend } = useCommandsContext() + const [settingsPath, setSettingsPath] = useState( + undefined + ) const [settingsState, settingsSend, settingsActor] = useMachine( settingsMachine.provide({ @@ -191,7 +200,11 @@ export const SettingsAuthProviderBase = ({ console.error('Error executing AST after settings change', e) } }, - persistSettings: ({ context }) => { + persistSettings: ({ context, event }) => { + // Without this, when a user changes the file, it'd + // create a detection loop with the file-system watcher. + if (event.doNotPersist) return + // eslint-disable-next-line @typescript-eslint/no-floating-promises saveSettings(context, loadedProject?.project?.path) }, @@ -201,6 +214,23 @@ export const SettingsAuthProviderBase = ({ ) settingsStateRef = settingsState.context + useEffect(() => { + if (!isDesktop()) return + getAppSettingsFilePath().then(setSettingsPath).catch(trap) + }, []) + + useFileSystemWatcher( + async () => { + const data = await loadAndValidateSettings(loadedProject?.project?.path) + settingsSend({ + type: 'Set all settings', + settings: data.settings, + doNotPersist: true, + }) + }, + settingsPath ? [settingsPath] : [] + ) + // Add settings commands to the command bar // They're treated slightly differently than other commands // Because their state machine doesn't have a meaningful .nextEvents, diff --git a/src/hooks/useFileSystemWatcher.tsx b/src/hooks/useFileSystemWatcher.tsx index 961bfc8e8..779e58dff 100644 --- a/src/hooks/useFileSystemWatcher.tsx +++ b/src/hooks/useFileSystemWatcher.tsx @@ -1,4 +1,5 @@ import { isDesktop } from 'lib/isDesktop' +import { reportRejection } from 'lib/trap' import { useEffect, useState, useRef } from 'react' type Path = string @@ -11,13 +12,13 @@ type Path = string // watcher.addListener(() => { ... }). export const useFileSystemWatcher = ( - callback: (path: Path) => void, + callback: (path: Path) => Promise, dependencyArray: Path[] ): void => { // Track a ref to the callback. This is how we get the callback updated // across the NodeJS<->Browser boundary. - const callbackRef = useRef<{ fn: (path: Path) => void }>({ - fn: (_path) => {}, + const callbackRef = useRef<{ fn: (path: Path) => Promise }>({ + fn: async (_path) => {}, }) useEffect(() => { @@ -35,7 +36,9 @@ export const useFileSystemWatcher = ( if (!isDesktop()) return return () => { - window.electron.watchFileObliterate() + for (let path of dependencyArray) { + window.electron.watchFileOff(path) + } } }, []) @@ -46,6 +49,9 @@ export const useFileSystemWatcher = ( ] } + const hasDiff = + difference(dependencyArray, dependencyArrayTracked)[0].length !== 0 + // Removing 1 watcher at a time is only possible because in a filesystem, // a path is unique (there can never be two paths with the same name). // Otherwise we would have to obliterate() the whole list and reconstruct it. @@ -53,6 +59,8 @@ export const useFileSystemWatcher = ( // The hook is useless on web. if (!isDesktop()) return + if (!hasDiff) return + const [pathsRemoved, pathsRemaining] = difference( dependencyArrayTracked, dependencyArray @@ -62,10 +70,10 @@ export const useFileSystemWatcher = ( } const [pathsAdded] = difference(dependencyArray, dependencyArrayTracked) for (let path of pathsAdded) { - window.electron.watchFileOn(path, (_eventType: string, path: Path) => - callbackRef.current.fn(path) - ) + window.electron.watchFileOn(path, (_eventType: string, path: Path) => { + callbackRef.current.fn(path).catch(reportRejection) + }) } setDependencyArrayTracked(pathsRemaining.concat(pathsAdded)) - }, [difference(dependencyArray, dependencyArrayTracked)[0].length !== 0]) + }, [hasDiff]) } diff --git a/src/lib/desktop.ts b/src/lib/desktop.ts index 7cdf6fe31..327733ebb 100644 --- a/src/lib/desktop.ts +++ b/src/lib/desktop.ts @@ -379,7 +379,7 @@ const getAppFolderName = () => { return window.electron.packageJson.name } -const getAppSettingsFilePath = async () => { +export const getAppSettingsFilePath = async () => { const isTestEnv = window.electron.process.env.IS_PLAYWRIGHT === 'true' const testSettingsPath = window.electron.process.env.TEST_SETTINGS_FILE_KEY const appConfig = await window.electron.getPath('appData') diff --git a/src/lib/settings/settingsUtils.ts b/src/lib/settings/settingsUtils.ts index 3117ecc91..283301ace 100644 --- a/src/lib/settings/settingsUtils.ts +++ b/src/lib/settings/settingsUtils.ts @@ -177,14 +177,14 @@ export async function loadAndValidateSettings( if (err(appSettingsPayload)) return Promise.reject(appSettingsPayload) - const settings = createSettings() + let settingsNext = createSettings() // Because getting the default directory is async, we need to set it after if (onDesktop) { settings.app.projectDirectory.default = await getInitialDefaultDir() } - setSettingsAtLevel( - settings, + settingsNext = setSettingsAtLevel( + settingsNext, 'user', configurationToSettingsPayload(appSettingsPayload) ) @@ -199,8 +199,8 @@ export async function loadAndValidateSettings( return Promise.reject(new Error('Invalid project settings')) const projectSettingsPayload = projectSettings - setSettingsAtLevel( - settings, + settingsNext = setSettingsAtLevel( + settingsNext, 'project', projectConfigurationToSettingsPayload(projectSettingsPayload) ) @@ -208,7 +208,7 @@ export async function loadAndValidateSettings( // Return the settings object return { - settings, + settings: settingsNext, configuration: appSettingsPayload, } } diff --git a/src/machines/settingsMachine.ts b/src/machines/settingsMachine.ts index 07051d198..571aa606d 100644 --- a/src/machines/settingsMachine.ts +++ b/src/machines/settingsMachine.ts @@ -19,7 +19,7 @@ export const settingsMachine = setup({ types: { context: {} as ReturnType, input: {} as ReturnType, - events: {} as + events: {} as ( | WildcardSetEvent | SetEventTypes | { @@ -34,7 +34,8 @@ export const settingsMachine = setup({ type: 'Reset settings' level: SettingsLevel } - | { type: 'Set all settings'; settings: typeof settings }, + | { type: 'Set all settings'; settings: typeof settings } + ) & { doNotPersist?: boolean }, }, actions: { setEngineTheme: () => {}, diff --git a/src/preload.ts b/src/preload.ts index 573f08e9b..1f458a424 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -5,6 +5,7 @@ import os from 'node:os' import fsSync from 'node:fs' import packageJson from '../package.json' import { MachinesListing } from 'lib/machineManager' +import chokidar from 'chokidar' const open = (args: any) => ipcRenderer.invoke('dialog.showOpenDialog', args) const save = (args: any) => ipcRenderer.invoke('dialog.showSaveDialog', args) @@ -23,36 +24,21 @@ const isMac = os.platform() === 'darwin' const isWindows = os.platform() === 'win32' const isLinux = os.platform() === 'linux' -let fsWatchListeners = new Map< - string, - { - watcher: fsSync.FSWatcher - callback: (eventType: string, path: string) => void - } ->() +let fsWatchListeners = new Map>() -const watchFileOn = ( - path: string, - callback: (eventType: string, path: string) => void -) => { - const watcher = fsSync.watch(path) - watcher.on('change', callback) - fsWatchListeners.set(path, { watcher, callback }) +const watchFileOn = (path: string, callback: (path: string) => void) => { + const watcherMaybe = fsWatchListeners.get(path) + if (watcherMaybe) return + const watcher = chokidar.watch(path) + watcher.on('all', callback) + fsWatchListeners.set(path, watcher) } const watchFileOff = (path: string) => { - const entry = fsWatchListeners.get(path) - if (!entry) return - const { watcher, callback } = entry - watcher.off('change', callback) - watcher.close() + const watcher = fsWatchListeners.get(path) + if (!watcher) return + watcher.unwatch(path) fsWatchListeners.delete(path) } -const watchFileObliterate = () => { - for (let [pathAsKey] of fsWatchListeners) { - watchFileOff(pathAsKey) - } - fsWatchListeners = new Map() -} const readFile = (path: string) => fs.readFile(path, 'utf-8') // It seems like from the node source code this does not actually block but also // don't trust me on that (jess). @@ -103,7 +89,6 @@ contextBridge.exposeInMainWorld('electron', { // exported. watchFileOn, watchFileOff, - watchFileObliterate, readFile, writeFile, exists, diff --git a/src/routes/Home.tsx b/src/routes/Home.tsx index 5a8c39cf4..f54fcbe51 100644 --- a/src/routes/Home.tsx +++ b/src/routes/Home.tsx @@ -57,7 +57,7 @@ const Home = () => { // Re-read projects listing if the projectDir has any updates. useFileSystemWatcher( - () => { + async () => { setProjectsLoaderTrigger(projectsLoaderTrigger + 1) }, projectsDir ? [projectsDir] : [] diff --git a/src/wasm-lib/Cargo.lock b/src/wasm-lib/Cargo.lock index b291d4233..fb4b537e4 100644 --- a/src/wasm-lib/Cargo.lock +++ b/src/wasm-lib/Cargo.lock @@ -934,9 +934,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -949,9 +949,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -959,15 +959,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -976,15 +976,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -993,21 +993,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1966,12 +1966,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oncemutex" diff --git a/src/wasm-lib/Cargo.toml b/src/wasm-lib/Cargo.toml index d0bdd8989..28b88ec02 100644 --- a/src/wasm-lib/Cargo.toml +++ b/src/wasm-lib/Cargo.toml @@ -35,7 +35,7 @@ uuid = { version = "1.10.0", features = ["v4", "js", "serde"] } [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" -futures = "0.3.30" +futures = "0.3.31" js-sys = "0.3.69" tower-lsp = { version = "0.20.0", default-features = false, features = ["runtime-agnostic"] } wasm-bindgen-futures = { version = "0.4.41", features = ["futures-core-03-stream"] } diff --git a/src/wasm-lib/derive-docs/Cargo.toml b/src/wasm-lib/derive-docs/Cargo.toml index d1dda9c82..ad23b40ca 100644 --- a/src/wasm-lib/derive-docs/Cargo.toml +++ b/src/wasm-lib/derive-docs/Cargo.toml @@ -14,7 +14,7 @@ proc-macro = true [dependencies] Inflector = "0.11.4" convert_case = "0.6.0" -once_cell = "1.19.0" +once_cell = "1.20.2" proc-macro2 = "1" quote = "1" regex = "1.10" diff --git a/src/wasm-lib/kcl/Cargo.toml b/src/wasm-lib/kcl/Cargo.toml index 64be818ae..cd4d8193d 100644 --- a/src/wasm-lib/kcl/Cargo.toml +++ b/src/wasm-lib/kcl/Cargo.toml @@ -22,7 +22,7 @@ dashmap = "6.1.0" databake = { version = "0.1.8", features = ["derive"] } derive-docs = { version = "0.1.29", path = "../derive-docs" } form_urlencoded = "1.2.1" -futures = { version = "0.3.30" } +futures = { version = "0.3.31" } git_rev = "0.1.0" gltf-json = "1.4.1" http = { workspace = true } diff --git a/yarn.lock b/yarn.lock index 882680014..a3c83816e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3780,6 +3780,13 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chokidar@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41" + integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA== + dependencies: + readdirp "^4.0.1" + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -8155,6 +8162,11 @@ readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readdirp@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a" + integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA== + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -8773,16 +8785,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8876,14 +8879,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -9757,16 +9753,7 @@ word-wrap@^1.2.3, word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==