From 443b06ea4a8b595e8d0d556f310e2012e7225fc2 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sun, 15 Feb 2026 18:59:06 +0100 Subject: [PATCH 1/3] Scrappy first implementation --- package.json | 1 + packages/preact-router/eslint.config.ts | 14 + packages/preact-router/package.json | 74 ++ packages/preact-router/src/Asset.tsx | 188 ++++ packages/preact-router/src/CatchBoundary.tsx | 120 +++ packages/preact-router/src/ClientOnly.tsx | 33 + .../preact-router/src/HeadContent.dev.tsx | 43 + packages/preact-router/src/HeadContent.tsx | 20 + packages/preact-router/src/Match.tsx | 327 +++++++ packages/preact-router/src/Matches.tsx | 284 ++++++ packages/preact-router/src/RouterProvider.tsx | 87 ++ packages/preact-router/src/SafeFragment.tsx | 5 + packages/preact-router/src/ScriptOnce.tsx | 21 + packages/preact-router/src/Scripts.tsx | 80 ++ .../preact-router/src/ScrollRestoration.tsx | 69 ++ packages/preact-router/src/Suspense.tsx | 45 + packages/preact-router/src/Transitioner.tsx | 125 +++ packages/preact-router/src/awaited.tsx | 51 ++ packages/preact-router/src/fileRoute.ts | 289 +++++++ .../preact-router/src/headContentUtils.tsx | 213 +++++ packages/preact-router/src/history.ts | 9 + packages/preact-router/src/index.dev.tsx | 6 + packages/preact-router/src/index.tsx | 360 ++++++++ .../preact-router/src/lazyRouteComponent.tsx | 70 ++ packages/preact-router/src/link.tsx | 805 ++++++++++++++++++ packages/preact-router/src/matchContext.tsx | 6 + packages/preact-router/src/not-found.tsx | 41 + .../preact-router/src/renderRouteNotFound.tsx | 30 + packages/preact-router/src/route.tsx | 723 ++++++++++++++++ packages/preact-router/src/router.ts | 79 ++ packages/preact-router/src/routerContext.tsx | 24 + .../preact-router/src/scroll-restoration.tsx | 45 + packages/preact-router/src/ssr/serializer.ts | 7 + .../preact-router/src/structuralSharing.ts | 45 + packages/preact-router/src/typePrimitives.ts | 84 ++ packages/preact-router/src/useBlocker.tsx | 321 +++++++ packages/preact-router/src/useCanGoBack.ts | 5 + packages/preact-router/src/useLoaderData.tsx | 83 ++ packages/preact-router/src/useLoaderDeps.tsx | 61 ++ packages/preact-router/src/useLocation.tsx | 44 + packages/preact-router/src/useMatch.tsx | 122 +++ packages/preact-router/src/useNavigate.tsx | 61 ++ packages/preact-router/src/useParams.tsx | 98 +++ packages/preact-router/src/useRouteContext.ts | 30 + packages/preact-router/src/useRouter.tsx | 19 + packages/preact-router/src/useRouterState.tsx | 75 ++ packages/preact-router/src/useSearch.tsx | 96 +++ packages/preact-router/src/utils.ts | 66 ++ .../preact-router/tests/ClientOnly.test.tsx | 45 + packages/preact-router/tests/Matches.test.tsx | 79 ++ .../preact-router/tests/Suspense.test.tsx | 137 +++ packages/preact-router/tests/blocker.test.tsx | 90 ++ packages/preact-router/tests/link.test.tsx | 167 ++++ packages/preact-router/tests/loaders.test.tsx | 158 ++++ .../preact-router/tests/navigate.test.tsx | 110 +++ .../preact-router/tests/not-found.test.tsx | 60 ++ packages/preact-router/tests/router.test.tsx | 110 +++ packages/preact-router/tests/setupTests.tsx | 5 + .../preact-router/tests/useBlocker.test.tsx | 137 +++ .../preact-router/tests/useCanGoBack.test.tsx | 92 ++ .../preact-router/tests/useParams.test.tsx | 103 +++ packages/preact-router/tests/utils.ts | 56 ++ packages/preact-router/tsconfig.json | 8 + packages/preact-router/tsconfig.legacy.json | 4 + packages/preact-router/vite.config.ts | 35 + pnpm-lock.yaml | 323 ++++++- 66 files changed, 7221 insertions(+), 2 deletions(-) create mode 100644 packages/preact-router/eslint.config.ts create mode 100644 packages/preact-router/package.json create mode 100644 packages/preact-router/src/Asset.tsx create mode 100644 packages/preact-router/src/CatchBoundary.tsx create mode 100644 packages/preact-router/src/ClientOnly.tsx create mode 100644 packages/preact-router/src/HeadContent.dev.tsx create mode 100644 packages/preact-router/src/HeadContent.tsx create mode 100644 packages/preact-router/src/Match.tsx create mode 100644 packages/preact-router/src/Matches.tsx create mode 100644 packages/preact-router/src/RouterProvider.tsx create mode 100644 packages/preact-router/src/SafeFragment.tsx create mode 100644 packages/preact-router/src/ScriptOnce.tsx create mode 100644 packages/preact-router/src/Scripts.tsx create mode 100644 packages/preact-router/src/ScrollRestoration.tsx create mode 100644 packages/preact-router/src/Suspense.tsx create mode 100644 packages/preact-router/src/Transitioner.tsx create mode 100644 packages/preact-router/src/awaited.tsx create mode 100644 packages/preact-router/src/fileRoute.ts create mode 100644 packages/preact-router/src/headContentUtils.tsx create mode 100644 packages/preact-router/src/history.ts create mode 100644 packages/preact-router/src/index.dev.tsx create mode 100644 packages/preact-router/src/index.tsx create mode 100644 packages/preact-router/src/lazyRouteComponent.tsx create mode 100644 packages/preact-router/src/link.tsx create mode 100644 packages/preact-router/src/matchContext.tsx create mode 100644 packages/preact-router/src/not-found.tsx create mode 100644 packages/preact-router/src/renderRouteNotFound.tsx create mode 100644 packages/preact-router/src/route.tsx create mode 100644 packages/preact-router/src/router.ts create mode 100644 packages/preact-router/src/routerContext.tsx create mode 100644 packages/preact-router/src/scroll-restoration.tsx create mode 100644 packages/preact-router/src/ssr/serializer.ts create mode 100644 packages/preact-router/src/structuralSharing.ts create mode 100644 packages/preact-router/src/typePrimitives.ts create mode 100644 packages/preact-router/src/useBlocker.tsx create mode 100644 packages/preact-router/src/useCanGoBack.ts create mode 100644 packages/preact-router/src/useLoaderData.tsx create mode 100644 packages/preact-router/src/useLoaderDeps.tsx create mode 100644 packages/preact-router/src/useLocation.tsx create mode 100644 packages/preact-router/src/useMatch.tsx create mode 100644 packages/preact-router/src/useNavigate.tsx create mode 100644 packages/preact-router/src/useParams.tsx create mode 100644 packages/preact-router/src/useRouteContext.ts create mode 100644 packages/preact-router/src/useRouter.tsx create mode 100644 packages/preact-router/src/useRouterState.tsx create mode 100644 packages/preact-router/src/useSearch.tsx create mode 100644 packages/preact-router/src/utils.ts create mode 100644 packages/preact-router/tests/ClientOnly.test.tsx create mode 100644 packages/preact-router/tests/Matches.test.tsx create mode 100644 packages/preact-router/tests/Suspense.test.tsx create mode 100644 packages/preact-router/tests/blocker.test.tsx create mode 100644 packages/preact-router/tests/link.test.tsx create mode 100644 packages/preact-router/tests/loaders.test.tsx create mode 100644 packages/preact-router/tests/navigate.test.tsx create mode 100644 packages/preact-router/tests/not-found.test.tsx create mode 100644 packages/preact-router/tests/router.test.tsx create mode 100644 packages/preact-router/tests/setupTests.tsx create mode 100644 packages/preact-router/tests/useBlocker.test.tsx create mode 100644 packages/preact-router/tests/useCanGoBack.test.tsx create mode 100644 packages/preact-router/tests/useParams.test.tsx create mode 100644 packages/preact-router/tests/utils.ts create mode 100644 packages/preact-router/tsconfig.json create mode 100644 packages/preact-router/tsconfig.legacy.json create mode 100644 packages/preact-router/vite.config.ts diff --git a/package.json b/package.json index c6679b70f80..21447309ef1 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "@tanstack/start-client-core": "workspace:*", "@tanstack/start-server-core": "workspace:*", "@tanstack/start-storage-context": "workspace:*", + "@tanstack/preact-router": "workspace:*", "@tanstack/vue-router": "workspace:*", "@tanstack/vue-router-devtools": "workspace:*", "@tanstack/eslint-plugin-router": "workspace:*", diff --git a/packages/preact-router/eslint.config.ts b/packages/preact-router/eslint.config.ts new file mode 100644 index 00000000000..108ae9cff1c --- /dev/null +++ b/packages/preact-router/eslint.config.ts @@ -0,0 +1,14 @@ +import rootConfig from '../../eslint.config.js' + +export default [ + ...rootConfig, + { + files: ['src/**/*.{ts,tsx}', 'tests/**/*.{ts,tsx}'], + }, + { + rules: { + '@typescript-eslint/no-unnecessary-condition': 'off', + 'no-unused-vars': 'off', + }, + }, +] diff --git a/packages/preact-router/package.json b/packages/preact-router/package.json new file mode 100644 index 00000000000..025be04a64b --- /dev/null +++ b/packages/preact-router/package.json @@ -0,0 +1,74 @@ +{ + "name": "@tanstack/preact-router", + "version": "1.160.0", + "description": "Modern and scalable routing for Preact applications", + "author": "Tanner Linsley", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/TanStack/router.git", + "directory": "packages/preact-router" + }, + "homepage": "https://tanstack.com/router", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "keywords": [ + "preact", + "location", + "router", + "routing", + "async", + "async router", + "typescript" + ], + "scripts": { + "clean": "rimraf ./dist && rimraf ./coverage", + "test": "pnpm run test:unit", + "test:eslint": "eslint", + "test:types": "tsc -p tsconfig.legacy.json", + "test:unit": "vitest", + "test:unit:dev": "pnpm run test:unit --watch --hideSkippedTests", + "test:build": "publint --strict && attw --ignore-rules no-resolution --pack .", + "build": "vite build" + }, + "type": "module", + "types": "dist/esm/index.d.ts", + "module": "dist/esm/index.js", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "development": "./dist/esm/index.dev.js", + "default": "./dist/esm/index.js" + } + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "files": [ + "dist", + "src" + ], + "engines": { + "node": ">=12" + }, + "dependencies": { + "@tanstack/history": "workspace:*", + "@tanstack/preact-store": "^0.10.2", + "@tanstack/router-core": "workspace:*", + "isbot": "^5.1.22", + "tiny-invariant": "^1.3.3", + "tiny-warning": "^1.0.3" + }, + "devDependencies": { + "@preact/preset-vite": "^2.9.4", + "@testing-library/preact": "^3.2.4", + "@testing-library/jest-dom": "^6.6.3", + "preact": "^10.25.0" + }, + "peerDependencies": { + "preact": "^10.0.0" + } +} diff --git a/packages/preact-router/src/Asset.tsx b/packages/preact-router/src/Asset.tsx new file mode 100644 index 00000000000..880d65276cb --- /dev/null +++ b/packages/preact-router/src/Asset.tsx @@ -0,0 +1,188 @@ +import { useEffect } from 'preact/hooks' +import { isServer } from '@tanstack/router-core/isServer' +import { useRouter } from './useRouter' +import type { VNode } from 'preact' +import type { RouterManagedTag } from '@tanstack/router-core' + +interface ScriptAttrs { + [key: string]: string | boolean | undefined + src?: string +} + +export function Asset({ + tag, + attrs, + children, + nonce, +}: RouterManagedTag & { nonce?: string }): VNode | null { + switch (tag) { + case 'title': + return ( + + {children} + + ) + case 'meta': + return + case 'link': + return + case 'style': + return ( +