Skip to content

Commit

Permalink
Crate standalone fs router package (#11)
Browse files Browse the repository at this point in the history
* refactor: moved fs-router to standalone package

* chore: remove useless split source function

* feat: add simple test cases

* fix: README formatting

* fix: remove useless RouteSubNode

* feat: update version to v0.4.4
  • Loading branch information
Valerioageno authored Jul 8, 2024
1 parent bc7ffc2 commit e4d4a75
Showing 31 changed files with 261 additions and 724 deletions.
2 changes: 1 addition & 1 deletion crates/tuono/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tuono"
version = "0.4.3"
version = "0.4.4"
edition = "2021"
authors = ["V. Ageno <valerioageno@yahoo.it>"]
description = "The react/rust fullstack framework"
4 changes: 2 additions & 2 deletions crates/tuono_lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tuono_lib"
version = "0.4.3"
version = "0.4.4"
edition = "2021"
authors = ["V. Ageno <valerioageno@yahoo.it>"]
description = "The react/rust fullstack framework"
@@ -31,7 +31,7 @@ regex = "1.10.5"
either = "1.13.0"
tower-http = {version = "0.5.2", features = ["fs"]}

tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.4.3"}
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.4.4"}
# Match the same version used by axum
tokio-tungstenite = "0.21.0"
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
2 changes: 1 addition & 1 deletion crates/tuono_lib_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tuono_lib_macros"
version = "0.4.3"
version = "0.4.4"
edition = "2021"
description = "The react/rust fullstack framework"
keywords = [ "react", "typescript", "fullstack", "web", "ssr"]
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -13,7 +13,8 @@
},
"workspaces": [
"tuono",
"tuono-lazy-fn-vite-plugin"
"tuono-lazy-fn-vite-plugin",
"tuono-fs-router-vite-plugin"
],
"author": "Valerio Ageno",
"license": "MIT",
12 changes: 12 additions & 0 deletions packages/fs-router-vite-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# tuono-fs-router-vite-plugin

This is a vite plugin for [tuono](https://github.com/Valerioageno/tuono).

This package specifically handles the file system based routing.

Check [tuono](https://github.com/Valerioageno/tuono) for more.

## Credits

This plugin is strongly inspired by the [@tanstack/router](https://tanstack.com/router/latest)
route generator plugin.
51 changes: 51 additions & 0 deletions packages/fs-router-vite-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "tuono-fs-router-vite-plugin",
"version": "0.4.4",
"description": "Plugin for the tuono's file system router. Tuono is the react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
"build": "vite build",
"lint": "eslint --ext .ts,.tsx ./src -c ../../.eslintrc",
"format": "prettier -u --write --ignore-unknown '**/*'",
"format:check": "prettier --check --ignore-unknown '**/*'",
"types": "tsc --noEmit",
"test:watch": "vitest",
"test": "vitest run"
},
"keywords": [],
"author": "Valerio Ageno",
"license": "MIT",
"type": "module",
"types": "dist/esm/index.d.ts",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.js",
"files": [
"dist",
"src",
"README.md"
],
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/cjs/index.d.cts",
"default": "./dist/cjs/index.cjs"
}
},
"./package.json": "./package.json"
},
"dependencies": {
"@babel/core": "^7.24.4",
"@babel/types": "^7.24.0",
"prettier": "^3.2.4",
"vite": "^5.2.11"
},
"devDependencies": {
"@tanstack/config": "^0.7.11",
"@types/babel__core": "^7.20.5",
"vitest": "^1.5.2"
}
}
3 changes: 3 additions & 0 deletions packages/fs-router-vite-plugin/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const ROUTES_FOLDER = './src/routes/'
export const ROOT_PATH_ID = '__root'
export const GENERATED_ROUTE_TREE = './.tuono/routeTree.gen.ts'
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as fs from 'fs'
import * as fsp from 'fs/promises'
import path from 'path'

@@ -15,14 +14,11 @@ import {
removeLayoutSegments,
} from './utils'

import type { Config, RouteNode, RouteSubNode } from './types'
import type { Config, RouteNode } from './types'
import { ROUTES_FOLDER, ROOT_PATH_ID, GENERATED_ROUTE_TREE } from './constants'

import { format } from 'prettier'

const ROUTES_FOLDER = './src/routes/'
const ROOT_PATH_ID = '__root'
const GENERATED_ROUTE_TREE = './.tuono/routeTree.gen.ts'

let latestTask = 0

const defaultConfig: Config = {
@@ -168,8 +164,6 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
(d): string => d.routePath,
]).filter((d) => ![`/${ROOT_PATH_ID}`].includes(d.routePath || ''))

const routePiecesByPath: Record<string, RouteSubNode> = {}

// Loop over the flat list of routeNodes and
// build up a tree based on the routeNodes' routePath
const routeNodes: RouteNode[] = []
@@ -202,10 +196,6 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
return
}

if (node.isLayout && !node.children?.length) {
return
}

const route = `${node.variableName}Route`

if (node.children?.length) {
47 changes: 47 additions & 0 deletions packages/fs-router-vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { routeGenerator } from './generator'

import { normalize } from 'path'

import type { Plugin } from 'vite'

const ROUTES_DIRECTORY_PATH = './src/routes'

let lock = false

export default function RouterGenerator(): Plugin {
const generate = async (): Promise<void> => {
if (lock) return
lock = true

try {
await routeGenerator()
} catch (err) {
console.error(err)
} finally {
lock = false
}
}

const handleFile = async (file: string): Promise<void> => {
const filePath = normalize(file)

if (filePath.startsWith(ROUTES_DIRECTORY_PATH)) {
await generate()
}
}

return {
name: 'vite-plugin-tuono-fs-router',
configResolved: async (): Promise<void> => {
await generate()
},
watchChange: async (
file: string,
context: { event: string },
): Promise<void> => {
if (['create', 'update', 'delete'].includes(context.event)) {
await handleFile(file)
}
},
}
}
Original file line number Diff line number Diff line change
@@ -11,17 +11,6 @@ export interface RouteNode {
variableName?: string
}

/**
* @deprecated
*/
export interface RouteSubNode {
component?: RouteNode
errorComponent?: RouteNode
pendingComponent?: RouteNode
loader?: RouteNode
lazy?: RouteNode
}

export interface Config {
folderName: string
generatedRouteTree: string
File renamed without changes.
43 changes: 43 additions & 0 deletions packages/fs-router-vite-plugin/tests/generator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import fs from 'fs/promises'
import { describe, it, expect } from 'vitest'
import { routeGenerator } from '../src/generator'

function makeFolderDir(folder: string) {
return process.cwd() + `/tests/generator/${folder}`
}

async function getRouteTreeFileText(folder: string) {
const dir = makeFolderDir(folder)
return await fs.readFile(dir + '/routeTree.gen.ts', 'utf-8')
}

async function getExpectedRouteTreeFileText(folder: string) {
const dir = makeFolderDir(folder)
const location = dir + '/routeTree.expected.ts'
return await fs.readFile(location, 'utf-8')
}

describe('generator works', async () => {
const folderNames = await fs.readdir(process.cwd() + '/tests/generator')

it.each(folderNames.map((folder) => [folder]))(
'should wire-up the routes for a "%s" tree',
async (folderName) => {
const currentFolder = `${process.cwd()}/tests/generator/${folderName}`

await routeGenerator({
folderName: `${currentFolder}/routes`,
generatedRouteTree: `${currentFolder}/routeTree.gen.ts`,
})

const [expectedRouteTree, generatedRouteTree] = await Promise.all([
getExpectedRouteTreeFileText(folderName),
getRouteTreeFileText(folderName),
])

console.log(generatedRouteTree)

expect(generatedRouteTree).equal(expectedRouteTree)
},
)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This file is auto-generated by Tuono

import { createRoute, dynamic } from 'tuono'

import RootImport from './routes/__root'

const AboutImport = dynamic(() => import('./routes/about'))
const IndexImport = dynamic(() => import('./routes/index'))
const PostsMyPostImport = dynamic(() => import('./routes/posts/my-post'))

const rootRoute = createRoute({ isRoot: true, component: RootImport })

const About = createRoute({ component: AboutImport })
const Index = createRoute({ component: IndexImport })
const PostsMyPost = createRoute({ component: PostsMyPostImport })

// Create/Update Routes

const AboutRoute = About.update({
path: '/about',
getParentRoute: () => rootRoute,
})

const IndexRoute = Index.update({
path: '/',
getParentRoute: () => rootRoute,
})

const PostsMyPostRoute = PostsMyPost.update({
path: '/posts/my-post',
getParentRoute: () => rootRoute,
})

// Create and export the route tree

export const routeTree = rootRoute.addChildren([
IndexRoute,
AboutRoute,
PostsMyPostRoute,
])
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// This file is auto-generated by Tuono

import { createRoute, dynamic } from 'tuono'

import RootImport from './routes/__root'

const AboutImport = dynamic(() => import('./routes/about'))
const IndexImport = dynamic(() => import('./routes/index'))

const rootRoute = createRoute({ isRoot: true, component: RootImport })

const About = createRoute({ component: AboutImport })
const Index = createRoute({ component: IndexImport })

// Create/Update Routes

const AboutRoute = About.update({
path: '/about',
getParentRoute: () => rootRoute,
})

const IndexRoute = Index.update({
path: '/',
getParentRoute: () => rootRoute,
})

// Create and export the route tree

export const routeTree = rootRoute.addChildren([IndexRoute, AboutRoute])
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** */
4 changes: 4 additions & 0 deletions packages/fs-router-vite-plugin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.json",
"include": ["src", "vite.config.ts"]
}
12 changes: 12 additions & 0 deletions packages/fs-router-vite-plugin/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackBuildConfig } from '@tanstack/config/build'

const config = defineConfig({})

export default mergeConfig(
config,
tanstackBuildConfig({
entry: './src/index.ts',
srcDir: './src',
}),
)
2 changes: 1 addition & 1 deletion packages/lazy-fn-vite-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tuono-lazy-fn-vite-plugin",
"version": "0.4.3",
"version": "0.4.4",
"description": "Plugin for the tuono's lazy fn. Tuono is the react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
5 changes: 3 additions & 2 deletions packages/tuono/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tuono",
"version": "0.4.3",
"version": "0.4.4",
"description": "The react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
@@ -88,7 +88,7 @@
"@types/node": "^20.12.7",
"@vitejs/plugin-react-swc": "^3.7.0",
"fast-text-encoding": "^1.0.6",
"prettier": "^3.2.4",
"tuono-fs-router-vite-plugin": "workspace:*",
"tuono-lazy-fn-vite-plugin": "workspace:*",
"vite": "^5.2.11",
"zustand": "4.4.7"
@@ -100,6 +100,7 @@
"@types/babel__traverse": "^7.20.6",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"prettier": "^3.2.4",
"jsdom": "^24.0.0",
"vitest": "^1.5.2"
},
Loading

0 comments on commit e4d4a75

Please sign in to comment.