Compare commits

...

29 Commits

Author SHA1 Message Date
Marco Pasqualetti 89d7a2c740 chore: add examples folder to workspaces and make examples packages name unique (#125) 2024-11-20 13:46:31 +01:00
Valerio Ageno 56c31f0204 feat: update version to v0.13.3 2024-11-20 13:45:37 +01:00
renovate[bot] 338cfb5be2 fix(deps): update dependency @types/node to v22.9.1 (#121)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-20 09:03:32 +01:00
renovate[bot] 43f6fe664b chore(deps): update pnpm to v9.14.1 (#124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-20 09:03:03 +01:00
Valerio Ageno 209c9fb7f7 feat: update version to v0.13.2 2024-11-19 17:34:33 +01:00
Valerio Ageno a562f67e8d Feat: added discord to README 2024-11-19 16:43:58 +01:00
Valerio Ageno ef0fe5a425 fix: seo page canonical 2024-11-19 15:50:58 +01:00
Myan V. b50902d23e Update watchexec to v5 and watchexec-signals to v4 (#118)
* fix(deps): update rust crate watchexec to v5

* fix(deps): update rust crate watchexec-signals to v4

* fix: revert unnecessary imports
2024-11-19 14:32:44 +01:00
Marco Pasqualetti 55490579ec refactor: replace () => JSX.Element with React.ComponentType (#120) 2024-11-18 21:45:27 +01:00
renovate[bot] 957d08701f chore(deps): update typescript-eslint monorepo to v8.15.0 (#119)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-18 20:41:04 +01:00
Valerio Ageno 61e1aed35d Add not expiring discord invite to documentation website 2024-11-18 18:36:33 +01:00
Valerio Ageno 2034f0ef5f fix: tutorial/redirections canonical tag 2024-11-18 12:35:14 +01:00
Valerio Ageno fcb92c7f0b fix(doc): spelling 2024-11-17 18:24:56 +01:00
Marco Pasqualetti 28ea1ca1df ci: add format check on repository root (#115) 2024-11-17 17:51:20 +01:00
Valerio Ageno ebc1a458a9 Fix tuono_lib_macro crate (#116)
* fix: tuono lib macro

* feat: remove reqwest re-export

* feat: update version to 0.13.1

* fix: remove reqwest from documentation
2024-11-17 17:11:07 +01:00
Valerio Ageno df92ef5296 Add support for custom global state (#111)
* feat: add 'has_main_file' to App struct

* feat: handle custom state from the main.rs file

* feat: update tutorial template with new setup

* fix: apply clippy hints

* feat: add ApplicationState mention to documentation website

* feat: update version to v0.13.0
2024-11-17 16:28:56 +01:00
Valerio Ageno 253e0a8378 feat(doc): keep social buttons on mobile website 2024-11-17 12:26:58 +01:00
Valerio Ageno a9fbe4eddd feat: add discord channel invite to documentation website 2024-11-17 12:19:25 +01:00
Valerio Ageno cfccc638c6 feat: update version to v0.12.4 2024-11-16 19:23:21 +01:00
renovate[bot] 9f1460cc26 fix(deps): update mantine monorepo to v7.14.1 (#110) 2024-11-16 17:11:02 +01:00
Henry Chen f0a4541420 fix: handle hyphen in route (#109) 2024-11-16 17:10:37 +01:00
renovate[bot] d0ce482680 chore(deps): update dependency vitest to v2.1.5 (#105)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-16 14:29:50 +01:00
renovate[bot] 40e2734a4e fix(deps): update dependency turbo to v2.3.0 (#106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-16 14:28:58 +01:00
Marco Pasqualetti 8552796343 chore: fix typo and improve name on CI (#107) 2024-11-16 11:47:53 +01:00
Marco Pasqualetti 6d72ffb876 ci: create install-node-dependencies action (#100) 2024-11-16 11:27:10 +01:00
Valerio Ageno 65faaf0183 feat: added website to crates/package manifest 2024-11-16 11:08:50 +01:00
Valerio Ageno 7f7c2e8d6f feat: update documentation tuono to v0.12.3 (#104) 2024-11-16 11:02:47 +01:00
Valerio Ageno 3be491baa7 Fix tuono lib release (#103)
* fix: removed service

* feat: update version to v0.12.3
2024-11-16 10:50:02 +01:00
Valerio Ageno 48b974ae58 Fix failing release pipeline (#102)
* feat: add no-verify key to cargo publish script

* feat: update version to v0.12.2
2024-11-16 10:23:59 +01:00
100 changed files with 7841 additions and 258 deletions
+14 -14
View File
@@ -34,51 +34,51 @@ body:
required: false
- type: input
id: tuono-version
attributes:
attributes:
label: Tuono version
placeholder: "[e.g. 0.4.0]"
placeholder: '[e.g. 0.4.0]'
validations:
required: false
- type: input
id: os-version
attributes:
attributes:
label: OS
placeholder: "[e.g. MacOS, Windows]"
placeholder: '[e.g. MacOS, Windows]'
validations:
required: false
- type: input
id: browser-version
attributes:
attributes:
label: Browser
placeholder: "[e.g. chrome, safari]"
placeholder: '[e.g. chrome, safari]'
validations:
required: false
- type: input
id: node-version
attributes:
attributes:
label: Node version
placeholder: "[e.g. 20.0.0]"
placeholder: '[e.g. 20.0.0]'
validations:
required: false
- type: input
id: rust-version
attributes:
attributes:
label: Rust version
placeholder: "[e.g. 1.79.0]"
placeholder: '[e.g. 1.79.0]'
validations:
required: false
- type: input
id: create-version
attributes:
attributes:
label: Crate version
placeholder: "[e.g. 1.78.0]"
placeholder: '[e.g. 1.78.0]'
validations:
required: false
- type: input
id: node-package-manager-version
attributes:
attributes:
label: Node Package Manger version
placeholder: "[e.g. pnpm: 9.5.0] "
placeholder: '[e.g. pnpm: 9.5.0] '
validations:
required: false
- type: textarea
@@ -33,4 +33,3 @@ body:
description: Add any other context or screenshots about the feature request here.
validations:
required: false
@@ -0,0 +1,37 @@
name: Install NodeJS Dependencies
description: This is a composite GitHub Action that sets up pnpm, node and installs the project's dependencies.
inputs:
node-version:
description: 'Explicit node version. Otherwise fallback reading `.nvmrc`. Use in conjunction with matrix'
required: false
registry-url:
description: 'https://github.com/actions/setup-node?tab=readme-ov-file#usage'
required: false
default: ''
runs:
using: composite
steps:
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js (via input)
if: ${{ inputs.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
registry-url: ${{ inputs.registry-url }}
cache: 'pnpm'
- name: Setup Node.js (via .nvmrc)
if: ${{ !inputs.node-version }}
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
registry-url: ${{ inputs.registry-url }}
cache: 'pnpm'
- name: Install Dependencies
shell: bash
run: pnpm install --frozen-lockfile
+1 -1
View File
@@ -1,7 +1,7 @@
## Context & Description
<!--
Thank you for your Pull Request.
Thank you for your Pull Request.
Explain the context and why you're making that change. What is the problem
you're trying to solve? If a new feature is being added, describe the intended
+9 -22
View File
@@ -13,31 +13,22 @@ on:
jobs:
build:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: Check build
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Check out code
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install tuono
run: cargo install tuono@0.10.4
- name: Install pnpm
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install
run: cargo install tuono@0.12.3
- name: Build project
working-directory: ./apps/documentation
@@ -45,20 +36,16 @@ jobs:
fmt-lint-and-types:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: Check format and lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out code
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Install pnpm
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
- name: Check formatting
run: pnpm docs:format:check
+4 -14
View File
@@ -15,27 +15,17 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
steps:
- name: Check out code
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install tuono
run: cargo install tuono@0.10.4
- name: Install pnpm
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install
run: cargo install tuono@0.12.3
- name: Build project
working-directory: ./apps/documentation
+23 -37
View File
@@ -7,42 +7,35 @@ jobs:
publish-on-npm-dry-run:
runs-on: ubuntu-latest
steps:
- name: Checkout
- name: Checkout code
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- uses: pnpm/action-setup@v3
name: Install pnpm
with:
version: 8
run_install: false
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
- name: Publish
run: pnpm publish -r --no-git-checks --dry-run
run: pnpm publish -r --no-git-checks --dry-run
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
publish-on-crates-dry-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: katyo/publish-crates@v2
with:
- uses: katyo/publish-crates@v2
with:
path: './crates/tuono'
dry-run: true
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
@@ -52,27 +45,17 @@ jobs:
needs: [publish-on-crates-dry-run, publish-on-npm-dry-run]
runs-on: ubuntu-latest
steps:
- name: Checkout
- name: Checkout code
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- uses: pnpm/action-setup@v3
name: Install pnpm
with:
version: 8
run_install: false
- name: Clone root README.md on tuono package
run: cp README.md packages/tuono/README.md
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
@@ -85,13 +68,16 @@ jobs:
needs: [publish-on-crates-dry-run, publish-on-npm-dry-run]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: katyo/publish-crates@v2
with:
- uses: katyo/publish-crates@v2
with:
path: './crates/tuono'
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
check-repo: true
+31
View File
@@ -0,0 +1,31 @@
name: Repo root CI
# All workflows are triggered based on specific paths,
# the root repository is something that is not applicable to rust nor typescript
# so it has been moved in a standalone workflow
on:
push:
paths:
- '.github/**'
- './*'
pull_request:
paths:
- '.github/**'
- './*'
jobs:
build-and-test:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: Check format
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
- name: Test project
run: pnpm repo:root:format
+8 -3
View File
@@ -10,16 +10,19 @@ on:
- '.github/**'
- 'crates/**'
env:
env:
CARGO_TERM_COLOR: always
jobs:
lint_and_fmt:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: Check format and lint rust crates
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
- run: cargo fmt --all -- --check
- run: cargo clippy -- -D warnings
@@ -34,7 +37,9 @@ jobs:
- beta
- nightly
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- run: cargo build --verbose
- run: cargo test --verbose
+3 -1
View File
@@ -7,7 +7,9 @@ jobs:
name: runner / LanguageTools
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
- uses: reviewdog/action-languagetool@v1
with:
github_token: ${{ secrets.REVIEWDOG_TOKEN }}
+8 -21
View File
@@ -13,25 +13,16 @@ on:
jobs:
build-and-test:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: Check build and test
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Check out code
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
- name: Build project
run: pnpm build
@@ -41,20 +32,16 @@ jobs:
fmt-lint-and-types:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: Check format and lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out code
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Install pnpm
run: npm i -g pnpm
- name: Install dependencies
run: pnpm install
- name: Install NodeJS Dependencies
uses: ./.github/actions/install-node-dependencies
- name: Check formatting
run: pnpm format:check
+3 -3
View File
@@ -1,12 +1,12 @@
## Node related ignores
node_modules/
dist/
.turbo/
*/**/routeTree.gen.ts
pnpm-lock.yaml
examples/playground/
examples/*/pnpm-lock.yaml
## Rust related ignores
+1
View File
@@ -0,0 +1 @@
pnpm-lock.yaml
+1
View File
@@ -1,4 +1,5 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"singleQuote": true,
"trailingComma": "all"
+11 -11
View File
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best, not just for us as individuals, but for the
- Focusing on what is best, not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
Advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct that could reasonably be considered inappropriate in a
- Other conduct that could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
+4 -1
View File
@@ -4,7 +4,8 @@
# How to Contribute to Tuono
## Contributions
## Contributions
Any feature contribution or suggestion is strongly appreciated.
Since the current project size, there isn't yet a defined way to start a discussion. Consider [opening a new issue](https://github.com/Valerioageno/tuono/issues/new/choose)
or to reach me using my email address, [valerioageno@yahoo.it](mailto:valerioageno@ahoo.it). I'm also available on Twitter (X); DM @valerioageno.
@@ -12,10 +13,12 @@ or to reach me using my email address, [valerioageno@yahoo.it](mailto:valerioage
## Bugs
**Did you find a bug?**
- Ensure the bug was not already reported by searching on GitHub under [Issues](https://github.com/Valerioageno/tuono/issues).
- If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/Valerioageno/tuono/issues/new/choose). Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring.
**Did you write a patch that fixes a bug?**
- Open a new GitHub pull request with the patch.
- Ensure the PR description clearly describes the problem and solution. Include the relevant issue number, if applicable.
- The pull requests must pass all the CI pipelines
+3 -3
View File
@@ -7,8 +7,8 @@ members = [
]
exclude = [
"apps/documentation",
"examples/mdx",
"examples/tuono",
"examples/tutorial",
"examples/wit-mdx",
"examples/tuono-app",
"examples/tuono-tutorial",
"benches/tuono"
]
+1 -1
View File
@@ -1,5 +1,5 @@
[Documentation](https://tuono.dev) | [Tutorial](https://tuono.dev/documentation/tutorial) |
[✨Contributing](https://tuono.dev/documentation/contributing)
[Discord](https://discord.com/invite/khQzPa654B) | [✨Contributing](https://tuono.dev/documentation/contributing)
# Tuono
+1 -1
View File
@@ -8,7 +8,7 @@ name = "tuono"
path = ".tuono/main.rs"
[dependencies]
tuono_lib = "0.12.0"
tuono_lib = "0.12.3"
glob = "0.3.1"
time = { version = "0.3", features = ["macros"] }
serde = { version = "1.0.202", features = ["derive"] }
+1 -1
View File
@@ -18,7 +18,7 @@
"clsx": "^2.1.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"tuono": "npm:tuono@0.12.0"
"tuono": "npm:tuono@0.12.3"
},
"devDependencies": {
"@types/mdx": "^2.0.13",
@@ -1,6 +1,10 @@
import type { JSX } from 'react'
import { Flex, Button, ActionIcon, Group } from '@mantine/core'
import { IconBrandGithub, IconBook, IconBrandX } from '@tabler/icons-react'
import {
IconBrandGithub,
IconBook,
IconBrandDiscord,
} from '@tabler/icons-react'
import { Link } from 'tuono'
import ThemeBtn from '../theme-btn'
@@ -8,10 +12,11 @@ import ThemeBtn from '../theme-btn'
export default function Actions(): JSX.Element {
return (
<Flex gap={8}>
<Group gap={8} visibleFrom="sm">
<Group gap={8}>
<Button
href="/documentation"
component={Link}
href="/documentation"
visibleFrom="sm"
size="compact-lg"
rightSection={<IconBook />}
autoContrast
@@ -31,12 +36,12 @@ export default function Actions(): JSX.Element {
<ActionIcon
variant="default"
size="lg"
aria-label="We are also on X!"
href="https://x.com/tuono_dev"
aria-label="Join the Tuono's community on Discord!"
href="https://discord.com/invite/khQzPa654B"
target="_blank"
component="a"
>
<IconBrandX />
<IconBrandDiscord />
</ActionIcon>
</Group>
<ThemeBtn />
@@ -3,7 +3,11 @@ import { AppShell } from '@mantine/core'
import SidebarLink from './sidebar-link'
export default function Sidebar({ close }: { close: () => void }): JSX.Element {
interface SidebarProps {
close: () => void
}
export default function Sidebar({ close }: SidebarProps): JSX.Element {
return (
<AppShell.Navbar p="md">
<SidebarLink
@@ -69,6 +73,12 @@ export default function Sidebar({ close }: { close: () => void }): JSX.Element {
/>
</SidebarLink>
<SidebarLink href="/documentation/cli" label="CLI" onClick={close} />
<SidebarLink
label="Application state"
href="/documentation/application-state"
onClick={close}
/>
<SidebarLink
label="Routing"
href="/documentation/routing"
@@ -0,0 +1,55 @@
import MetaTags from '../../components/meta-tags'
<MetaTags
title="Tuono - Application state"
canonical="https://tuono.dev/documentation/application-state"
description="Learn how to add features to your Tuono application"
/>
import Breadcrumbs, { Element } from '../../components/breadcrumbs'
<Breadcrumbs breadcrumbs={[{ label: 'Application state' }]} />
# Application state
The main reason Tuono is fast is that it loads just the features that are needed for the project.
To define them, you need to fill the `ApplicationState` struct in the `./src/main.rs` file, and
they will be automatically available in all the handlers you will define across the application.
```rs
// src/main.rs
#[derive(Clone)]
pub struct ApplicationState {
pub website_name: String,
pub base_path: String
}
pub fn main() -> ApplicationState {
let website_name = "tuono".to_string();
let base_path = "http://localhost:3000".to_string();
ApplicationState {
website_name,
base_path
}
}
```
> For the sake of simplicity here we just enable a `String` but you can add Database connections or
> HTTP clients (take a look [here](/documentation/tutorial/api-fetching) for an example with an HTTP client).
Now the `ApplicationState` is available on all the handlers as following:
```rs
// src/routes/index.rs
#[tuono_lib::handler]
// The first argument always is the Request
// The ApplicationState arguments are optional. You can use just the ones you need
// to use in the handler (with no specific order).
async fn my_handler(req: Request, website_name: String) -> Response {
...
}
```
@@ -28,7 +28,7 @@ Clear the `index.rs` file and paste:
```rust
// src/routes/index.rs
use serde::{Deserialize, Serialize};
use tuono_lib::reqwest::Client;
use reqwest::Client;
use tuono_lib::{Props, Request, Response};
const ALL_POKEMON: &str = "https://pokeapi.co/api/v2/pokemon?limit=151";
@@ -56,9 +56,74 @@ async fn get_all_pokemons(_req: Request, fetch: Client) -> Response {
}
```
> The first argument is always the request `req: Request` which contains the request data like the query parameters and the headers.
> The rest of the arguments are optional and they don't need to be specified
> if they are not used. Enabled out of the box a [Reqwest](https://docs.rs/reqwest/latest/reqwest/) HTTP client.
> The first argument is always the request `req: Request` which contains all the request's data like the query parameters and the HTTP headers.
> The rest of the arguments represents the [ApplicationState](/documentation/application-state) and are optional.
The terminal will complain now for two reasons:
1. We don't have imported any `reqwest` crate
2. The second argument `fetch: Client` has not been defined yet as global state.
Let's fix these in the next section.
## Application state
Compared to the common Javascript runtimes, Tuono is fast because only the features you need for your project will be loaded.
You can load them in the `ApplicationState` of your app inside the `./src/main.rs` file. This is the file that will be executed just once at the very beginning of your application.
> For the tutorial we will use [Reqwest](https://docs.rs/reqwest/latest/reqwest/) which is one of the most famous HTTP library.
To install it just run in your terminal:
```bash
$ cargo add reqwest
```
A new entry has just been added to your `Cargo.toml` file.
```diff
[package]
name = "tuono"
version = "0.0.1"
edition = "2021"
[[bin]]
name = "tuono"
path = ".tuono/main.rs"
[dependencies]
tuono_lib = "0.14.0" # the version might be different
serde = { version = "1.0.202", features = ["derive"] }
++ reqwest = "0.12.9" # the version might be different
```
> The `Cargo.toml` is the manifest file of your application, in which you handle Rust's dependencies
> (similarly as the package.json for Javascript).
Now let's define the `ApplicationState` in the `./src/main.rs` file.
```rs
// Import here the just added reqwest library
use reqwest::Client;
#[derive(Clone)]
// Extend this struct with the feature you will need for your application
pub struct ApplicationState {
// This will be available to all your route handlers
pub fetch: Client,
}
pub fn main() -> ApplicationState {
let fetch = Client::new();
return ApplicationState { fetch };
}
```
Now the `fetch: Client` argument is available in the above defined handler, and the terminal should not complain anymore.
Let's see in the next section how to show the fetched data on the browser.
## Handling the page UI
Now the Pokémon are correctly fetched and hydrated on the client side, so we can actually use them. Clear the `index.tsx` file and paste:
@@ -32,7 +32,7 @@ Lets first work on the server side file. Paste into the new `[pokemon].rs` fi
```rust
// src/routes/pokemons/[pokemon].rs
use serde::{Deserialize, Serialize};
use tuono_lib::reqwest::Client;
use reqwest::Client;
use tuono_lib::{Props, Request, Response};
const POKEMON_API: &str = "https://pokeapi.co/api/v2/pokemon";
@@ -27,8 +27,8 @@ Let's see how it works!
```diff
// src/routes/pokemons/[pokemon].rs
use serde::{Deserialize, Serialize};
-- use tuono_lib::reqwest::Client;
++ use tuono_lib::reqwest::{Client, StatusCode};
-- use reqwest::Client;
++ use reqwest::{Client, StatusCode};
use tuono_lib::{Props, Request, Response};
const POKEMON_API: &str = "https://pokeapi.co/api/v2/pokemon";
@@ -69,8 +69,8 @@ async fn get_pokemon(req: Request, fetch: Client) -> Response {
```diff
// src/routes/index.rs
use serde::{Deserialize, Serialize};
-- use tuono_lib::reqwest::Client;
++ use tuono_lib::reqwest::{Client, StatusCode};
-- use reqwest::Client;
++ use reqwest::{Client, StatusCode};
use tuono_lib::{Props, Request, Response};
const ALL_POKEMON: &str = "https://pokeapi.co/api/v2/pokemon?limit=151";
@@ -21,7 +21,7 @@ This tutorial is not meant for people who don't know React - in that case, I sug
If you prefer to just read the code rather than write you can download the finished tutorial project with:
```bash
$ tuono new tutorial --template tutorial
$ tuono new tutorial --template tuono-tutorial
```
> I'd love to hear your thoughts about the framework and the tutorial - feel free to reach me at [valerioageno@yahoo.it](mailto:valerioageno@ahoo.it)
@@ -2,7 +2,7 @@ import MetaTags from '../../../components/meta-tags'
<MetaTags
title="Tuono - Redirection"
canonical="https://tuono.dev/documentation/tutorial/redirection"
canonical="https://tuono.dev/documentation/tutorial/redirections"
description="Learn how to redirect to different route from the server"
/>
@@ -2,7 +2,7 @@ import MetaTags from '../../../components/meta-tags'
<MetaTags
title="Tuono - SEO and meta tags"
canonical="https://tuono.dev/documentation/tutorial/eeo"
canonical="https://tuono.dev/documentation/tutorial/seo"
description="Learn how to handle meaningful meta tags for your Tuono project"
/>
+5 -4
View File
@@ -1,9 +1,10 @@
[package]
name = "tuono"
version = "0.12.1"
version = "0.13.3"
edition = "2021"
authors = ["V. Ageno <valerioageno@yahoo.it>"]
description = "The react/rust fullstack framework"
description = "Superfast React fullstack framework"
homepage = "https://tuono.dev"
keywords = [ "react", "typescript", "fullstack", "web", "ssr"]
repository = "https://github.com/Valerioageno/tuono"
readme = "../../README.md"
@@ -20,9 +21,9 @@ path = "src/lib.rs"
[dependencies]
clap = { version = "4.5.4", features = ["derive", "cargo"] }
watchexec = "4.0.0"
watchexec = "5.0.0"
miette = "7.2.0"
watchexec-signals = "3.0.0"
watchexec-signals = "4.0.0"
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0.202", features = ["derive"] }
watchexec-supervisor = "3.0.0"
+21 -1
View File
@@ -1,6 +1,9 @@
use glob::glob;
use glob::GlobError;
use std::collections::{hash_map::Entry, HashMap};
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::PathBuf;
use std::process::Child;
use std::process::Command;
@@ -15,6 +18,15 @@ const IGNORE_FILES: [&str; 1] = ["__root"];
pub struct App {
pub route_map: HashMap<String, Route>,
pub base_path: PathBuf,
pub has_main_file: bool,
}
fn has_main_file(base_path: PathBuf) -> std::io::Result<bool> {
let file = File::open(base_path.join("src/main.rs"))?;
let mut buf_reader = BufReader::new(file);
let mut contents = String::new();
buf_reader.read_to_string(&mut contents)?;
Ok(contents.contains("pub fn main"))
}
impl App {
@@ -23,7 +35,8 @@ impl App {
let mut app = App {
route_map: HashMap::new(),
base_path,
base_path: base_path.clone(),
has_main_file: has_main_file(base_path).unwrap_or(false),
};
app.collect_routes();
@@ -119,6 +132,8 @@ mod tests {
"/home/user/Documents/tuono/src/routes/index.rs",
"/home/user/Documents/tuono/src/routes/posts/index.rs",
"/home/user/Documents/tuono/src/routes/posts/[post].rs",
"/home/user/Documents/tuono/src/routes/posts/handle-this.rs",
"/home/user/Documents/tuono/src/routes/posts/handle-this/[post].rs",
"/home/user/Documents/tuono/src/routes/posts/UPPERCASE.rs",
"/home/user/Documents/tuono/src/routes/sitemap.xml.rs",
];
@@ -132,6 +147,11 @@ mod tests {
("/about", "about"),
("/posts/index", "posts_index"),
("/posts/[post]", "posts_dyn_post"),
("/posts/handle-this", "posts_handle_hyphen_this"),
(
"/posts/handle-this/[post]",
"posts_handle_hyphen_this_dyn_post",
),
("/posts/UPPERCASE", "posts_uppercase"),
("/sitemap.xml", "sitemap_dot_xml"),
];
+2
View File
@@ -32,6 +32,7 @@ impl AxumInfo {
.to_string()
.replace('/', "_")
.replace('.', "_dot_")
.replace('-', "_hyphen_")
.to_lowercase();
if axum_route.is_empty() {
@@ -47,6 +48,7 @@ impl AxumInfo {
.as_str()
.to_string()
.replace('/', "_")
.replace('-', "_hyphen_")
.replace('[', "dyn_")
.replace(']', ""),
axum_route: axum_route.replace('[', ":").replace(']', ""),
+1 -1
View File
@@ -42,7 +42,7 @@ pub fn create_new_project(folder_name: Option<String>, template: Option<String>)
let folder = folder_name.unwrap_or(".".to_string());
// In case of missing select the tuono example
let template = template.unwrap_or("tuono".to_string());
let template = template.unwrap_or("tuono-app".to_string());
let client = blocking::Client::builder()
.user_agent("")
+33 -2
View File
@@ -42,12 +42,17 @@ const MODE: Mode = /*MODE*/;
// MODULE_IMPORTS
//MAIN_FILE_IMPORT//
#[tokio::main]
async fn main() {
println!("\n ⚡ Tuono v/*VERSION*/");
//MAIN_FILE_DEFINITION//
let router = Router::new()
// ROUTE_BUILDER
;
//MAIN_FILE_USAGE//;
Server::init(router, MODE).start().await
}
@@ -131,7 +136,33 @@ fn generate_axum_source(app: &App, mode: Mode) -> String {
&create_modules_declaration(&app.route_map),
)
.replace("/*VERSION*/", crate_version!())
.replace("/*MODE*/", mode.as_str());
.replace("/*MODE*/", mode.as_str())
.replace(
"//MAIN_FILE_IMPORT//",
if app.has_main_file {
r#"#[path="../src/main.rs"]
mod tuono_main_state;
"#
} else {
""
},
)
.replace(
"//MAIN_FILE_DEFINITION//",
if app.has_main_file {
"let user_custom_state = tuono_main_state::main();"
} else {
""
},
)
.replace(
"//MAIN_FILE_USAGE//",
if app.has_main_file {
".with_state(user_custom_state)"
} else {
""
},
);
let has_server_handlers = app
.route_map
+4 -6
View File
@@ -1,9 +1,10 @@
[package]
name = "tuono_lib"
version = "0.12.1"
version = "0.13.3"
edition = "2021"
authors = ["V. Ageno <valerioageno@yahoo.it>"]
description = "The react/rust fullstack framework"
description = "Superfast React fullstack framework"
homepage = "https://tuono.dev"
keywords = [ "react", "typescript", "fullstack", "web", "ssr"]
repository = "https://github.com/Valerioageno/tuono"
readme = "../../README.md"
@@ -14,9 +15,6 @@ include = [
"Cargo.toml"
]
[lib]
name = "tuono_lib"
path = "src/lib.rs"
[dependencies]
ssr_rs = "0.7.0"
@@ -33,7 +31,7 @@ either = "1.13.0"
tower-http = {version = "0.6.0", features = ["fs"]}
colored = "2.1.0"
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.12.1"}
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.13.3"}
# Match the same version used by axum
tokio-tungstenite = "0.24.0"
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
+1 -2
View File
@@ -1,11 +1,11 @@
mod catch_all;
mod logger;
mod manifest;
mod mode;
mod payload;
mod request;
mod response;
mod server;
mod services;
mod ssr;
mod vite_reverse_proxy;
mod vite_websocket_proxy;
@@ -19,5 +19,4 @@ pub use tuono_lib_macros::handler;
// Re-exports
pub use axum;
pub use reqwest;
pub use tokio;
+5 -10
View File
@@ -1,13 +1,12 @@
use crate::manifest::load_manifest;
use crate::mode::{Mode, GLOBAL_MODE};
use crate::services::logger::LoggerLayer;
use axum::routing::{get, Router};
use colored::Colorize;
use ssr_rs::Ssr;
use tower_http::services::ServeDir;
use crate::{
catch_all::catch_all, vite_reverse_proxy::vite_reverse_proxy,
catch_all::catch_all, logger::LoggerLayer, vite_reverse_proxy::vite_reverse_proxy,
vite_websocket_proxy::vite_websocket_proxy,
};
@@ -15,12 +14,12 @@ const DEV_PUBLIC_DIR: &str = "public";
const PROD_PUBLIC_DIR: &str = "out/client";
pub struct Server {
router: Router<reqwest::Client>,
router: Router,
mode: Mode,
}
impl Server {
pub fn init(router: Router<reqwest::Client>, mode: Mode) -> Server {
pub fn init(router: Router, mode: Mode) -> Server {
Ssr::create_platform();
GLOBAL_MODE.set(mode).unwrap();
@@ -35,8 +34,6 @@ impl Server {
pub async fn start(&self) {
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
let fetch = reqwest::Client::new();
if self.mode == Mode::Dev {
println!(" Ready at: {}\n", "http://localhost:3000".blue().bold());
let router = self
@@ -48,8 +45,7 @@ impl Server {
.fallback_service(
ServeDir::new(DEV_PUBLIC_DIR)
.fallback(get(catch_all).layer(LoggerLayer::new())),
)
.with_state(fetch);
);
axum::serve(listener, router)
.await
@@ -66,8 +62,7 @@ impl Server {
.fallback_service(
ServeDir::new(PROD_PUBLIC_DIR)
.fallback(get(catch_all).layer(LoggerLayer::new())),
)
.with_state(fetch);
);
axum::serve(listener, router)
.await
-1
View File
@@ -1 +0,0 @@
pub mod logger;
+4 -5
View File
@@ -1,5 +1,5 @@
use axum::body::Body;
use axum::extract::{Path, State};
use axum::extract::Path;
use axum::http::{HeaderName, HeaderValue};
use axum::response::{IntoResponse, Response};
@@ -7,10 +7,9 @@ use reqwest::Client;
const VITE_URL: &str = "http://localhost:3001/vite-server";
pub async fn vite_reverse_proxy(
State(client): State<Client>,
Path(path): Path<String>,
) -> impl IntoResponse {
pub async fn vite_reverse_proxy(Path(path): Path<String>) -> impl IntoResponse {
let client = Client::new();
match client.get(format!("{VITE_URL}/{path}")).send().await {
Ok(res) => {
let mut response_builder = Response::builder().status(res.status().as_u16());
+3 -2
View File
@@ -1,8 +1,9 @@
[package]
name = "tuono_lib_macros"
version = "0.12.1"
version = "0.13.3"
edition = "2021"
description = "The react/rust fullstack framework"
description = "Superfast React fullstack framework"
homepage = "https://tuono.dev"
keywords = [ "react", "typescript", "fullstack", "web", "ssr"]
repository = "https://github.com/Valerioageno/tuono"
readme = "../../README.md"
+38 -5
View File
@@ -2,15 +2,35 @@ use proc_macro::TokenStream;
use quote::quote;
use syn::punctuated::Punctuated;
use syn::token::Comma;
use syn::{parse2, parse_macro_input, FnArg, ItemFn, Pat, Type};
use syn::{parse2, parse_macro_input, parse_quote, FnArg, ItemFn, Pat, Stmt};
fn create_struct_fn_arg(arg_name: Pat, arg_type: Type) -> FnArg {
fn create_struct_fn_arg() -> FnArg {
parse2(quote! {
tuono_lib::axum::extract::State(#arg_name): tuono_lib::axum::extract::State<#arg_type>
tuono_lib::axum::extract::State(state): tuono_lib::axum::extract::State<ApplicationState>
})
.unwrap()
}
fn import_main_application_state(argument_names: Punctuated<Pat, Comma>) -> Option<Stmt> {
if !argument_names.is_empty() {
let local: Stmt = parse_quote!(
use crate::tuono_main_state::ApplicationState;
);
return Some(local);
}
None
}
fn crate_application_state_extractor(argument_names: Punctuated<Pat, Comma>) -> Option<Stmt> {
if !argument_names.is_empty() {
let use_item: Stmt = parse_quote!(let ApplicationState { #argument_names } = state;);
return Some(use_item);
}
None
}
fn params_argument() -> FnArg {
parse2(quote! {
tuono_lib::axum::extract::Path(params): tuono_lib::axum::extract::Path<
@@ -41,23 +61,33 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
continue;
}
if i == 1 {
axum_arguments.insert(1, create_struct_fn_arg())
}
if let FnArg::Typed(pat_type) = arg {
let index = i - 1;
let argument_name = *pat_type.pat.clone();
let argument_type = *pat_type.ty.clone();
argument_names.insert(index, argument_name.clone());
axum_arguments.insert(index, create_struct_fn_arg(argument_name, argument_type))
}
}
axum_arguments.insert(axum_arguments.len(), request_argument());
let application_state_extractor = crate_application_state_extractor(argument_names.clone());
let application_state_import = import_main_application_state(argument_names.clone());
quote! {
#application_state_import
#item
pub async fn route(
#axum_arguments
) -> impl tuono_lib::axum::response::IntoResponse {
#application_state_extractor
let pathname = request.uri();
let headers = request.headers();
@@ -69,6 +99,9 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
pub async fn api(
#axum_arguments
) -> impl tuono_lib::axum::response::IntoResponse {
#application_state_extractor
let pathname = request.uri();
let headers = request.headers();
-11
View File
@@ -15,14 +15,3 @@ $ tuono new [NAME] --template [TEMPLATE]
```
`[TEMPLATE]` is the folder name.
## Troubleshooting for contributors
There is a common error that happens during example development due to
pnpm workspace about the findings of different react versions.
To overcome this issue run within the single example folder:
```
pnpm install --ignore-workspace && pnpm upgrade --save
```
@@ -1,5 +1,5 @@
[package]
name = "tuono"
name = "tuono-app"
version = "0.0.1"
edition = "2021"
@@ -1,6 +1,6 @@
{
"name": "tuono",
"description": "The react/rust fullstack framework",
"name": "tuono-app",
"description": "Basic tuono application",
"version": "0.0.1",
"dependencies": {
"react": "18.3.1",

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

@@ -23,7 +23,7 @@ body {
}
main {
width: 673px;
max-width: 673px;
margin: 20px auto;
}
@@ -1,5 +1,5 @@
[package]
name = "tuono"
name = "tuono-tutorial"
version = "0.0.1"
edition = "2021"
@@ -10,4 +10,5 @@ path = ".tuono/main.rs"
[dependencies]
tuono_lib = { path = "../../crates/tuono_lib/"}
serde = { version = "1.0.202", features = ["derive"] }
reqwest = "0.12.9"
+9
View File
@@ -0,0 +1,9 @@
# Tuono tutorial
This project is the outcome of the [tuono tutorial](https://tuono.dev/documentation/tutorial)
If you want to directly install it you can run:
```bash
$ tuono new my-project -t tuono-tutorial
```
@@ -1,6 +1,6 @@
{
"name": "tuono-tutorial",
"description": "The react/rust fullstack framework",
"description": "The basic tutorial for tuono applications",
"version": "0.0.1",
"dependencies": {
"react": "18.3.1",

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

+11
View File
@@ -0,0 +1,11 @@
use reqwest::Client;
#[derive(Clone)]
pub struct ApplicationState {
pub fetch: Client,
}
pub fn main() -> ApplicationState {
let fetch = Client::new();
return ApplicationState { fetch };
}
@@ -1,6 +1,6 @@
// src/routes/index.rs
use reqwest::{Client, StatusCode};
use serde::{Deserialize, Serialize};
use tuono_lib::reqwest::{Client, StatusCode};
use tuono_lib::{Props, Request, Response};
const ALL_POKEMON: &str = "https://pokeapi.co/api/v2/pokemon?limit=151";
@@ -1,6 +1,6 @@
// src/routes/pokemons/[pokemon].rs
use reqwest::{Client, StatusCode};
use serde::{Deserialize, Serialize};
use tuono_lib::reqwest::{Client, StatusCode};
use tuono_lib::{Props, Request, Response};
const POKEMON_API: &str = "https://pokeapi.co/api/v2/pokemon";
-9
View File
@@ -1,9 +0,0 @@
# Tuono tutorial
This project is the outcome of the [tuono tutorial](https://github.com/Valerioageno/tuono/blob/main/docs/tutorial.md)
If you want to directly install it you can run:
```bash
$ tuono new my-project -t tutorial
```
@@ -1,5 +1,5 @@
[package]
name = "tuono"
name = "with-mdx"
version = "0.0.1"
edition = "2021"
@@ -1,6 +1,6 @@
{
"name": "tuono",
"description": "The react/rust fullstack framework",
"name": "with-mdx",
"description": "Tuono example combined with mdx",
"version": "0.0.1",
"dependencies": {
"@mdx-js/react": "^3.0.1",

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "workspace",
"packageManager": "pnpm@9.13.2+sha512.88c9c3864450350e65a33587ab801acf946d7c814ed1134da4a924f6df5a2120fd36b46aab68f7cd1d413149112d53c7db3a4136624cfd00ff1846a0c6cef48a",
"packageManager": "pnpm@9.14.1+sha512.7f1de9cffea40ff4594c48a94776112a0db325e81fb18a9400362ff7b7247f4fbd76c3011611c9f8ac58743c3dc526017894e07948de9b72052f874ee2edfdcd",
"scripts": {
"dev": "turbo dev --filter=./packages/*",
"build": "turbo build --filter=./packages/*",
@@ -14,7 +14,8 @@
"docs:format": "turbo format --filter=documentation",
"docs:format:check": "turbo format:check --filter=documentation",
"docs:types": "turbo types --filter=documentation",
"check-all": "turbo build lint format:check types"
"repo:root:format": "prettier . !./apps/** !./assets/** !./benches/** !./crates !./examples !./packages/** --write",
"check-all": "turbo build lint format:check types --filter=!./examples"
},
"author": "Valerio Ageno",
"license": "MIT",
+2 -1
View File
@@ -1,7 +1,8 @@
{
"name": "tuono-fs-router-vite-plugin",
"version": "0.12.1",
"version": "0.13.3",
"description": "Plugin for the tuono's file system router. Tuono is the react/rust fullstack framework",
"homepage": "https://tuono.dev",
"scripts": {
"dev": "vite build --watch",
"build": "vite build",
+2 -1
View File
@@ -1,7 +1,8 @@
{
"name": "tuono-lazy-fn-vite-plugin",
"version": "0.12.1",
"version": "0.13.3",
"description": "Plugin for the tuono's lazy fn. Tuono is the react/rust fullstack framework",
"homepage": "https://tuono.dev",
"scripts": {
"dev": "vite build --watch",
"build": "vite build",
+2 -1
View File
@@ -1,7 +1,8 @@
{
"name": "tuono-router",
"version": "0.12.1",
"version": "0.13.3",
"description": "React routing component for the framework tuono. Tuono is the react/rust fullstack framework",
"homepage": "https://tuono.dev",
"scripts": {
"dev": "vite build --watch",
"build": "vite build",
+2 -2
View File
@@ -1,4 +1,4 @@
import type { JSX } from 'react'
import type { ComponentType as ReactComponentType } from 'react'
import { trimPath, trimPathRight } from './utils'
import type { Route } from './route'
@@ -12,7 +12,7 @@ interface CreateRouter {
}
interface RouteOptions {
component?: () => JSX.Element
component?: ReactComponentType
hasHandler?: boolean
routeTree?: RouteTree
}
+3 -1
View File
@@ -1,3 +1,5 @@
import type { ComponentType as ReactComponentType } from 'react'
export interface Segment {
type: 'pathname' | 'param' | 'wildcard'
value: string
@@ -17,6 +19,6 @@ export interface RouteProps {
isLoading: boolean
}
export type RouteComponent = ((props: RouteProps) => JSX.Element) & {
export type RouteComponent = ReactComponentType<RouteProps> & {
preload: () => void
}
+3 -2
View File
@@ -1,7 +1,8 @@
{
"name": "tuono",
"version": "0.12.1",
"description": "The react/rust fullstack framework",
"version": "0.13.3",
"description": "Superfast React fullstack framework",
"homepage": "https://tuono.dev",
"scripts": {
"dev": "vite build --watch",
"build": "vite build",
+7345
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
packages:
- 'packages/*'
- 'apps/*'
- '!**/examples/**'
- 'examples/*'
+1 -3
View File
@@ -1,7 +1,5 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"extends": ["config:recommended"],
"ignorePaths": ["**/benches/**"]
}
+1 -1
View File
@@ -21,7 +21,7 @@
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "ES2020",
"target": "ES2020"
},
"include": [".eslintrc.cjs", "prettier.config.js"],
"exclude": ["node_modules"]
+9 -19
View File
@@ -2,31 +2,21 @@
"$schema": "https://turbo.build/schema.json",
"tasks": {
"lint": {
"dependsOn": [
"^build"
]
},
"dependsOn": ["^build"]
},
"format": {},
"format:check": {},
"types": {
"dependsOn": [
"^build"
]
},
"format:check": {},
"types": {
"dependsOn": ["^build"]
},
"test": {},
"test:watch": {},
"build": {
"outputs": [
"dist/**"
],
"dependsOn": [
"^build"
]
"outputs": ["dist/**"],
"dependsOn": ["^build"]
},
"dev": {
"dependsOn": [
"^build"
]
"dependsOn": ["^build"]
}
}
}