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"
}