From 67b39e912cc24cfccd6d97c768f9f9722c88c51f Mon Sep 17 00:00:00 2001 From: andylovescode Date: Wed, 27 Aug 2025 20:19:09 -0700 Subject: [PATCH 1/2] Move: Make motion! --- bun.lock | 52 ++- packages/example/package.json | 51 +-- packages/example/src/client.tsx | 27 ++ packages/vortex-move/.gitignore | 34 ++ packages/vortex-move/.npmignore | 33 ++ packages/vortex-move/README.md | 13 + packages/vortex-move/package.json | 31 ++ packages/vortex-move/src/browser.ts | 2 + packages/vortex-move/src/index.ts | 2 + packages/vortex-move/src/scheduler.ts | 85 +++++ packages/vortex-move/src/spring.ts | 74 ++++ packages/vortex-move/tsconfig.json | 28 ++ packages/wormhole/src/cli/statusboard.tsx | 390 +++++++++++----------- 13 files changed, 588 insertions(+), 234 deletions(-) create mode 100644 packages/vortex-move/.gitignore create mode 100644 packages/vortex-move/.npmignore create mode 100644 packages/vortex-move/README.md create mode 100644 packages/vortex-move/package.json create mode 100644 packages/vortex-move/src/browser.ts create mode 100644 packages/vortex-move/src/index.ts create mode 100644 packages/vortex-move/src/scheduler.ts create mode 100644 packages/vortex-move/src/spring.ts create mode 100644 packages/vortex-move/tsconfig.json diff --git a/bun.lock b/bun.lock index 9d901cb..1391fa7 100644 --- a/bun.lock +++ b/bun.lock @@ -11,7 +11,7 @@ }, "packages/args": { "name": "@vortexjs/args", - "version": "0.0.2", + "version": "0.0.5", "dependencies": { "@vortexjs/common": "workspace:*", }, @@ -25,6 +25,7 @@ }, "packages/cataloger": { "name": "@vortexjs/cataloger", + "version": "0.0.3", "bin": { "cataloger": "./src/index.ts", }, @@ -41,7 +42,7 @@ }, "packages/discovery": { "name": "@vortexjs/discovery", - "version": "0.2.1", + "version": "0.2.5", "dependencies": { "@vortexjs/cache": "workspace:*", "@vortexjs/common": "workspace:*", @@ -59,10 +60,11 @@ }, "packages/example": { "name": "@vortexjs/bun-example", - "version": "1.5.6", + "version": "1.5.9", "dependencies": { "@vortexjs/core": "workspace:*", "@vortexjs/dom": "workspace:*", + "@vortexjs/move": "workspace:*", }, "devDependencies": { "@types/bun": "catalog:", @@ -89,7 +91,7 @@ }, "packages/locounter": { "name": "@vortexjs/locounter", - "version": "0.0.1", + "version": "0.0.4", "bin": { "locounter": "./src/index.ts", }, @@ -105,7 +107,7 @@ }, "packages/pippin": { "name": "@vortexjs/pippin", - "version": "0.1.1", + "version": "0.1.5", "dependencies": { "@jridgewell/source-map": "catalog:", "@vortexjs/cache": "workspace:*", @@ -121,7 +123,7 @@ }, "packages/pippin-plugin-tailwind": { "name": "@vortexjs/pippin-plugin-tailwind", - "version": "0.0.2", + "version": "0.0.5", "dependencies": { "@tailwindcss/node": "catalog:", "@tailwindcss/oxide": "catalog:", @@ -138,7 +140,7 @@ }, "packages/vindicator": { "name": "@vortexjs/vindicator", - "version": "0.0.2", + "version": "0.0.5", "dependencies": { "@vortexjs/common": "workspace:*", }, @@ -152,7 +154,7 @@ }, "packages/vortex-cache": { "name": "@vortexjs/cache", - "version": "0.0.2", + "version": "0.0.5", "dependencies": { "@vortexjs/common": "workspace:*", }, @@ -166,7 +168,7 @@ }, "packages/vortex-cli": { "name": "@vortexjs/cli", - "version": "0.0.2", + "version": "0.0.5", "dependencies": { "@vortexjs/common": "workspace:*", "@vortexjs/core": "workspace:*", @@ -183,7 +185,7 @@ }, "packages/vortex-common": { "name": "@vortexjs/common", - "version": "0.1.1", + "version": "0.1.4", "devDependencies": { "@types/bun": "catalog:", "tsdown": "catalog:", @@ -194,7 +196,7 @@ }, "packages/vortex-core": { "name": "@vortexjs/core", - "version": "2.7.0", + "version": "2.7.3", "dependencies": { "@vortexjs/common": "workspace:*", }, @@ -208,7 +210,7 @@ }, "packages/vortex-dom": { "name": "@vortexjs/dom", - "version": "2.0.6", + "version": "2.0.9", "dependencies": { "@vortexjs/common": "workspace:*", "@vortexjs/core": "workspace:*", @@ -223,7 +225,7 @@ }, "packages/vortex-intrinsics": { "name": "@vortexjs/intrinsics", - "version": "0.1.0", + "version": "0.1.3", "dependencies": { "@vortexjs/common": "workspace:*", "@vortexjs/core": "workspace:*", @@ -236,9 +238,25 @@ "typescript": "catalog:", }, }, + "packages/vortex-move": { + "name": "@vortexjs/move", + "version": "1.3.9", + "dependencies": { + "@vortexjs/common": "workspace:*", + "@vortexjs/core": "workspace:*", + "@vortexjs/dom": "workspace:*", + }, + "devDependencies": { + "@types/bun": "catalog:", + "tsdown": "catalog:", + }, + "peerDependencies": { + "typescript": "catalog:", + }, + }, "packages/vortex-prime": { "name": "@vortexjs/prime", - "version": "1.3.6", + "version": "1.3.9", "dependencies": { "@vortexjs/common": "workspace:*", "@vortexjs/core": "workspace:*", @@ -254,7 +272,7 @@ }, "packages/vortex-ssr": { "name": "@vortexjs/ssr", - "version": "0.0.6", + "version": "0.0.9", "dependencies": { "@vortexjs/common": "workspace:*", "@vortexjs/core": "workspace:*", @@ -270,7 +288,7 @@ }, "packages/wormhole": { "name": "@vortexjs/wormhole", - "version": "0.4.0", + "version": "0.4.3", "bin": { "wormhole": "./dist/cli.js", "wh": "./dist/cli.js", @@ -578,6 +596,8 @@ "@vortexjs/locounter": ["@vortexjs/locounter@workspace:packages/locounter"], + "@vortexjs/move": ["@vortexjs/move@workspace:packages/vortex-move"], + "@vortexjs/pippin": ["@vortexjs/pippin@workspace:packages/pippin"], "@vortexjs/pippin-plugin-tailwind": ["@vortexjs/pippin-plugin-tailwind@workspace:packages/pippin-plugin-tailwind"], diff --git a/packages/example/package.json b/packages/example/package.json index de55945..ae98bf6 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -1,27 +1,28 @@ { - "name": "@vortexjs/bun-example", - "version": "1.5.9", - "private": true, - "type": "module", - "license": "MIT-0", - "main": "src/index.ts", - "repository": { - "url": "https://github.com/rectangle-run/vortex" - }, - "module": "src/index.ts", - "scripts": { - "dev": "bun --hot src/index.ts", - "build": "bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='BUN_PUBLIC_*'", - "start": "NODE_ENV=production bun src/index.ts" - }, - "dependencies": { - "@vortexjs/core": "workspace:*", - "@vortexjs/dom": "workspace:*" - }, - "devDependencies": { - "@types/bun": "catalog:" - }, - "peerDependencies": { - "typescript": "catalog:" - } + "name": "@vortexjs/bun-example", + "version": "1.5.9", + "private": true, + "type": "module", + "license": "MIT-0", + "main": "src/index.ts", + "repository": { + "url": "https://github.com/rectangle-run/vortex" + }, + "module": "src/index.ts", + "scripts": { + "dev": "bun --hot src/index.ts", + "build": "bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='BUN_PUBLIC_*'", + "start": "NODE_ENV=production bun src/index.ts" + }, + "dependencies": { + "@vortexjs/core": "workspace:*", + "@vortexjs/dom": "workspace:*", + "@vortexjs/move": "workspace:*" + }, + "devDependencies": { + "@types/bun": "catalog:" + }, + "peerDependencies": { + "typescript": "catalog:" + } } diff --git a/packages/example/src/client.tsx b/packages/example/src/client.tsx index c3655c2..8e5a2f2 100644 --- a/packages/example/src/client.tsx +++ b/packages/example/src/client.tsx @@ -8,6 +8,7 @@ import { when, } from "@vortexjs/core"; import { html } from "@vortexjs/dom"; +import { useSpring } from "@vortexjs/move"; const TestingContext = createContext("TestingContext"); @@ -17,6 +18,30 @@ function TestingComponent() { return

This is a testing component. Context data: {ctxData}

; } +function SpringSliders() { + const targetValue = useState(0); + const spring = useSpring(targetValue); + const height = useDerived((get) => `${get(spring.signal)}px`); + const width = useDerived((get) => `${10000 / get(spring.signal)}px`); + + return ( + <> + +
+ + ); +} + function App() { const counter = useState(0); const name = useState("multiverse"); @@ -60,6 +85,8 @@ function App() { {number} is a number from 1 to {counter}

))} + + ); } diff --git a/packages/vortex-move/.gitignore b/packages/vortex-move/.gitignore new file mode 100644 index 0000000..a14702c --- /dev/null +++ b/packages/vortex-move/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/packages/vortex-move/.npmignore b/packages/vortex-move/.npmignore new file mode 100644 index 0000000..dfe1eec --- /dev/null +++ b/packages/vortex-move/.npmignore @@ -0,0 +1,33 @@ +# dependencies (bun install) +node_modules + +# output +out +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/packages/vortex-move/README.md b/packages/vortex-move/README.md new file mode 100644 index 0000000..e974463 --- /dev/null +++ b/packages/vortex-move/README.md @@ -0,0 +1,13 @@ +# `@vortexjs/prime` + +Vortex Prime is the official library for building accessible component libraries with Vortex. + +## What is Prime? + +Vortex Prime does not come with styles, it only provides helpers you can use to build your own components. If you want a component library, look elsewhere. If you want to build your own component library, this is the place to start. + +## Installation + +```bash +bun add @vortexjs/prime +``` diff --git a/packages/vortex-move/package.json b/packages/vortex-move/package.json new file mode 100644 index 0000000..6243421 --- /dev/null +++ b/packages/vortex-move/package.json @@ -0,0 +1,31 @@ +{ + "name": "@vortexjs/move", + "type": "module", + "license": "MIT-0", + "repository": { + "url": "https://github.com/rectangle-run/vortex" + }, + "devDependencies": { + "@types/bun": "catalog:", + "tsdown": "catalog:" + }, + "dependencies": { + "@vortexjs/core": "workspace:*", + "@vortexjs/dom": "workspace:*", + "@vortexjs/common": "workspace:*" + }, + "peerDependencies": { + "typescript": "catalog:" + }, + "scripts": { + "build": "tsdown ./src/index.ts --format esm --dts --out-dir dist" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.cjs" + } + }, + "version": "1.3.9" +} diff --git a/packages/vortex-move/src/browser.ts b/packages/vortex-move/src/browser.ts new file mode 100644 index 0000000..2cef822 --- /dev/null +++ b/packages/vortex-move/src/browser.ts @@ -0,0 +1,2 @@ +export const isBrowser = + typeof window !== "undefined" && typeof window.document !== "undefined"; diff --git a/packages/vortex-move/src/index.ts b/packages/vortex-move/src/index.ts new file mode 100644 index 0000000..272a95f --- /dev/null +++ b/packages/vortex-move/src/index.ts @@ -0,0 +1,2 @@ +export * from "./scheduler"; +export * from "./spring"; diff --git a/packages/vortex-move/src/scheduler.ts b/packages/vortex-move/src/scheduler.ts new file mode 100644 index 0000000..fe3c2c7 --- /dev/null +++ b/packages/vortex-move/src/scheduler.ts @@ -0,0 +1,85 @@ +import { useHookLifetime } from "@vortexjs/core"; +import { isBrowser } from "./browser"; + +export interface SchedulerCallback { + impl?(tick: TickProps): void; +} + +export interface ClosableSchedulerCallback extends SchedulerCallback { + close(): void; +} + +export interface TickProps { + dtSeconds: number; +} + +const NONE_NUMBER = -1; + +export class Scheduler { + callbacks: ClosableSchedulerCallback[] = []; + animationFrame = NONE_NUMBER; + lastTime = 0; + + tick(time: number) { + this.animationFrame = requestAnimationFrame((t) => this.tick(t)); + + const timeSeconds = time / 1000; + const maxDt = 1 / 10; + const dt = Math.min(timeSeconds - this.lastTime, maxDt); + + this.lastTime = timeSeconds; + + if (Number.isNaN(dt)) return; + + for (const callback of this.callbacks) { + callback.impl?.({ dtSeconds: dt }); + } + } + + updatePrescence() { + if (!isBrowser) return; + + const shouldExist = this.callbacks.length > 0; + + if (shouldExist && this.animationFrame === NONE_NUMBER) { + this.animationFrame = requestAnimationFrame((time) => { + this.tick(time); + }); + } else if (!shouldExist && this.animationFrame !== NONE_NUMBER) { + cancelAnimationFrame(this.animationFrame); + this.animationFrame = NONE_NUMBER; + this.lastTime = NONE_NUMBER; + } + } + + addCallback(callback: SchedulerCallback): ClosableSchedulerCallback { + const closable: ClosableSchedulerCallback = { + close: () => { + const index = this.callbacks.indexOf(closable); + if (index !== -1) { + this.callbacks.splice(index, 1); + this.updatePrescence(); + } + }, + ...callback, + }; + + this.callbacks.push(closable); + this.updatePrescence(); + + return closable; + } +} + +const sceduler = new Scheduler(); + +export function useAnimation(callback: SchedulerCallback) { + const closable = sceduler.addCallback(callback); + const lt = useHookLifetime(); + + lt.onClosed(() => { + closable.close(); + }); + + return closable; +} diff --git a/packages/vortex-move/src/spring.ts b/packages/vortex-move/src/spring.ts new file mode 100644 index 0000000..4bb3aa8 --- /dev/null +++ b/packages/vortex-move/src/spring.ts @@ -0,0 +1,74 @@ +import { + getImmediateValue, + isSignal, + type SignalOrValue, + store, +} from "@vortexjs/core"; +import { useAnimation } from "./scheduler"; + +export class Spring { + target = 0; + value = 0; + velocity = 0; + + // parameters (NOTE: not perfectly realistic) + tension = 100; + reboundFriction = 50; + typicalFriction = 0; + + signal = store(0); + + update(dt: number) { + // Break NaNs + // (shouldn't happen, but just in case) + if (Number.isNaN(this.value)) this.value = 0; + if (Number.isNaN(this.velocity)) this.velocity = 0; + if (Number.isNaN(this.target)) this.target = 0; + + // Move from velocity + this.value += this.velocity * dt; + + // Calculate spring force + const displacement = this.target - this.value; + const springForce = displacement * this.tension; + + if (!Number.isNaN(springForce)) { + this.velocity += springForce * dt; + } + + // Apply friction + const signToTarget = Math.sign(this.target - this.value); + const signVelocity = Math.sign(this.velocity); + const isRebounding = signToTarget !== signVelocity; + const friction = isRebounding + ? this.reboundFriction + : this.typicalFriction; + + // Apply friction in a way that's framerate independent, with framerate independent lerp! + const frictionEffect = 1 / (1 + friction * dt); + + if (!Number.isNaN(frictionEffect)) { + this.velocity *= frictionEffect; + } + + this.signal.set(this.value); + } +} + +export function useSpring( + target: SignalOrValue, + spring = new Spring(), +) { + useAnimation({ + impl: ({ dtSeconds }) => { + const targetValue = isSignal(target) + ? getImmediateValue(target) + : target; + + spring.target = targetValue; + spring.update(dtSeconds); + }, + }); + + return spring; +} diff --git a/packages/vortex-move/tsconfig.json b/packages/vortex-move/tsconfig.json new file mode 100644 index 0000000..e8160d6 --- /dev/null +++ b/packages/vortex-move/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", + "jsxImportSource": "@vortexjs/core", + "allowJs": true, + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + }, + "include": ["src/**/*", "test/**/*"] +} diff --git a/packages/wormhole/src/cli/statusboard.tsx b/packages/wormhole/src/cli/statusboard.tsx index 7c31602..decb125 100644 --- a/packages/wormhole/src/cli/statusboard.tsx +++ b/packages/wormhole/src/cli/statusboard.tsx @@ -1,13 +1,13 @@ import { - awaited, - flatten, - Lifetime, - list, - store, - useDerived, - useEffect, - useInterval, - useTimeout, + awaited, + flatten, + Lifetime, + list, + store, + useDerived, + useEffect, + useInterval, + useTimeout, } from "@vortexjs/core"; import type { Project } from "~/state"; import { getImmediateValue, type Store, useState } from "@vortexjs/core"; @@ -17,250 +17,254 @@ import { theme } from "./theme"; import type { HTTPMethod } from "~/shared/http-method"; function Throbber() { - let i = store(0); + let i = store(0); - useInterval(100, () => { - i.set(getImmediateValue(i) + 1); - }) + useInterval(100, () => { + i.set(getImmediateValue(i) + 1); + }) - const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; - const frame = useDerived((get) => { - return frames[get(i) % frames.length]; - }); + const frame = useDerived((get) => { + return frames[get(i) % frames.length]; + }); - return - {frame} - + return + {frame} + } function TaskView({ task }: { task: Task }) { - return - {" "} - {task.name} - + return + {" "} + {task.name} + } export function StatusBoard(state: Project) { - linearView.enabled = false; + if (process.stdout.rows === undefined || process.stdout.columns === undefined) { + return; + } - const lt = state.lt; - using _hlt = Lifetime.changeHookLifetime(lt); + linearView.enabled = false; - cliApp( - - - ) + const lt = state.lt; + using _hlt = Lifetime.changeHookLifetime(lt); + + cliApp( + + + ) } function Prefix({ text, color }: { text: string; color: string }) { - const width = 6; + const width = 6; - return - {text.padEnd(width, " ")} - + return + {text.padEnd(width, " ")} + } function getMethodColor(method: HTTPMethod): string { - switch (method) { - case "GET": - return colors.blue[400]; - case "POST": - return colors.emerald[400]; - case "DELETE": - return colors.red[400]; - case "PATCH": - return colors.yellow[400]; - } + switch (method) { + case "GET": + return colors.blue[400]; + case "POST": + return colors.emerald[400]; + case "DELETE": + return colors.red[400]; + case "PATCH": + return colors.yellow[400]; + } } function StatusCode({ code }: { code: number }) { - let accent = colors.gray[400]; - - if (code >= 400 && code < 500) { - accent = colors.rose[400]; - } - if (code >= 500) { - accent = colors.red[400]; - } - if (code >= 300 && code < 400) { - accent = colors.emerald[400]; - } - - return - {code.toString().padStart(3, "0")} - + let accent = colors.gray[400]; + + if (code >= 400 && code < 500) { + accent = colors.rose[400]; + } + if (code >= 500) { + accent = colors.red[400]; + } + if (code >= 300 && code < 400) { + accent = colors.emerald[400]; + } + + return + {code.toString().padStart(3, "0")} + } function NetworkTag({ tag }: { tag: RequestTag }) { - let color: string; - - switch (tag) { - case "api": - color = colors.blue[400]; - break; - case "static": - color = colors.emerald[400]; - break; - case "ssr": - color = colors.yellow[400]; - break; - case "query": - color = colors.purple[400]; - break; - case "mutation": - color = colors.orange[400]; - break; - default: - color = colors.gray[400]; - } - - return - {" "}({tag}) - ; + let color: string; + + switch (tag) { + case "api": + color = colors.blue[400]; + break; + case "static": + color = colors.emerald[400]; + break; + case "ssr": + color = colors.yellow[400]; + break; + case "query": + color = colors.purple[400]; + break; + case "mutation": + color = colors.orange[400]; + break; + default: + color = colors.gray[400]; + } + + return + {" "}({tag}) + ; } function LogView({ log }: { log: Log }) { - if (log.type === "raw") { - return - {log.message} - ; - } else if (log.type === "request") { - const urlLength = 25; - - return - {log.url.padEnd(urlLength)} - {list(log.tags).show(tag => )} - ; - } - return <>; + if (log.type === "raw") { + return + {log.message} + ; + } else if (log.type === "request") { + const urlLength = 25; + + return + {log.url.padEnd(urlLength)} + {list(log.tags).show(tag => )} + ; + } + return <>; } function LogPanel() { - enableConsoleLogShim(); - - return - Logger - - - {list(logs).show(log => )} - - - + enableConsoleLogShim(); + + return + Logger + + + {list(logs).show(log => )} + + + } export interface Task { - [Symbol.dispose]: () => void; - name: string; + [Symbol.dispose]: () => void; + name: string; } export type RequestTag = "api" | "static" | "ssr" | "query" | "mutation"; export type Log = { - type: "raw"; - message: string; - color?: string; + type: "raw"; + message: string; + color?: string; } | { - type: "request"; - method: HTTPMethod; - url: string; - responseCode: number; - tags: RequestTag[]; + type: "request"; + method: HTTPMethod; + url: string; + responseCode: number; + tags: RequestTag[]; } export const tasks: Store = useState([]); export const logs: Store = useState([]); export function addLog(log: Log) { - logs.set([...getImmediateValue(logs), log]); + logs.set([...getImmediateValue(logs), log]); } function enableConsoleLogShim() { - const formatArgs = (args: any[]) => { - return args.map(x => typeof x === "string" ? x : Bun.inspect(x)).join(" ") - } - - console.log = (...args: any[]) => { - const formatted = formatArgs(args); - addLog({ type: "raw", message: formatted }); - } - - console.error = (...args: any[]) => { - const formatted = formatArgs(args); - addLog({ type: "raw", message: formatted, color: colors.red[400] }); - } - - console.warn = (...args: any[]) => { - const formatted = formatArgs(args); - addLog({ type: "raw", message: formatted, color: colors.yellow[400] }); - } + const formatArgs = (args: any[]) => { + return args.map(x => typeof x === "string" ? x : Bun.inspect(x)).join(" ") + } + + console.log = (...args: any[]) => { + const formatted = formatArgs(args); + addLog({ type: "raw", message: formatted }); + } + + console.error = (...args: any[]) => { + const formatted = formatArgs(args); + addLog({ type: "raw", message: formatted, color: colors.red[400] }); + } + + console.warn = (...args: any[]) => { + const formatted = formatArgs(args); + addLog({ type: "raw", message: formatted, color: colors.yellow[400] }); + } } function LeftPanel() { - const uptime = useState("uptime"); - let starting = Date.now(); - - setInterval(() => { - const uptimeMs = Date.now() - starting; - let ms = uptimeMs; - let seconds = Math.floor(ms / 1000); - ms -= seconds * 1000; - let minutes = Math.floor(seconds / 60); - seconds -= minutes * 60; - let hours = Math.floor(minutes / 60); - minutes -= hours * 60; - let days = Math.floor(hours / 24); - hours -= days * 24; - - uptime.set( - `${days}d ${hours}h ${minutes}m ${seconds}s` - ); - }, 100); - - return - - - - • - - wormhole - - - {uptime} - - - - Tasks - - - {list(tasks).show((item) => ( - - ))} - - ; + const uptime = useState("uptime"); + let starting = Date.now(); + + setInterval(() => { + const uptimeMs = Date.now() - starting; + let ms = uptimeMs; + let seconds = Math.floor(ms / 1000); + ms -= seconds * 1000; + let minutes = Math.floor(seconds / 60); + seconds -= minutes * 60; + let hours = Math.floor(minutes / 60); + minutes -= hours * 60; + let days = Math.floor(hours / 24); + hours -= days * 24; + + uptime.set( + `${days}d ${hours}h ${minutes}m ${seconds}s` + ); + }, 100); + + return + + + + • + + wormhole + + + {uptime} + + + + Tasks + + + {list(tasks).show((item) => ( + + ))} + + ; } const linearView = { - enabled: true + enabled: true } export function addTask(props: Omit): Task { - const task: Task = { - ...props, - [Symbol.dispose]: () => { - tasks.set(getImmediateValue(tasks).filter((t) => t !== task)); + const task: Task = { + ...props, + [Symbol.dispose]: () => { + tasks.set(getImmediateValue(tasks).filter((t) => t !== task)); - if (linearView.enabled) { - console.log(`[${task.name}]: done`); - } - }, - }; + if (linearView.enabled) { + console.log(`[${task.name}]: done`); + } + }, + }; - if (linearView.enabled) { - console.log(`[${task.name}]: started`); - } + if (linearView.enabled) { + console.log(`[${task.name}]: started`); + } - tasks.set([...getImmediateValue(tasks), task]); + tasks.set([...getImmediateValue(tasks), task]); - return task; + return task; } From 59739971497283ad891f014c3a3272ca2a82f886 Mon Sep 17 00:00:00 2001 From: andylovescode Date: Wed, 27 Aug 2025 20:20:14 -0700 Subject: [PATCH 2/2] Move: Versioning --- .changeset/loud-kings-hope.md | 5 +++++ packages/example/src/client.tsx | 2 +- packages/vortex-move/package.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/loud-kings-hope.md diff --git a/.changeset/loud-kings-hope.md b/.changeset/loud-kings-hope.md new file mode 100644 index 0000000..4da7ecb --- /dev/null +++ b/.changeset/loud-kings-hope.md @@ -0,0 +1,5 @@ +--- +"@vortexjs/move": minor +--- + +Add springs diff --git a/packages/example/src/client.tsx b/packages/example/src/client.tsx index 8e5a2f2..74b4b1a 100644 --- a/packages/example/src/client.tsx +++ b/packages/example/src/client.tsx @@ -37,7 +37,7 @@ function SpringSliders() { top: "50vh", transform: "translate(-50%, -50%)", }} - > + /> ); } diff --git a/packages/vortex-move/package.json b/packages/vortex-move/package.json index 6243421..7b4375a 100644 --- a/packages/vortex-move/package.json +++ b/packages/vortex-move/package.json @@ -27,5 +27,5 @@ "require": "./dist/index.cjs" } }, - "version": "1.3.9" + "version": "0.0.0" }