From b997a0f7815324803b551ad1f8ecccb9db16d510 Mon Sep 17 00:00:00 2001 From: Fabian Hiller Date: Fri, 1 Mar 2024 03:10:46 -0500 Subject: [PATCH] Add blog and first post to website --- pnpm-lock.yaml | 6 + website/package.json | 2 + website/src/components/Header.tsx | 3 +- website/src/components/index.ts | 2 +- website/src/routes/blog/(posts)/layout.tsx | 7 + .../should-we-change-valibots-api/index.mdx | 150 ++++++++++++++++++ .../npm-downloads.jpg | Bin 0 -> 46277 bytes website/src/routes/blog/index.tsx | 68 ++++++++ website/src/styles/root.css | 5 + 9 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 website/src/routes/blog/(posts)/layout.tsx create mode 100644 website/src/routes/blog/(posts)/should-we-change-valibots-api/index.mdx create mode 100644 website/src/routes/blog/(posts)/should-we-change-valibots-api/npm-downloads.jpg create mode 100644 website/src/routes/blog/index.tsx diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3d614fa4..c2938c7bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,6 +171,9 @@ importers: rehype-external-links: specifier: ^3.0.0 version: 3.0.0 + sharp: + specifier: ^0.33.2 + version: 0.33.2 tailwindcss: specifier: ^3.4.1 version: 3.4.1 @@ -186,6 +189,9 @@ importers: vite: specifier: ^5.1.3 version: 5.1.3(@types/node@20.11.19) + vite-imagetools: + specifier: ^6.2.9 + version: 6.2.9 vite-tsconfig-paths: specifier: ^4.3.1 version: 4.3.1(typescript@5.3.3)(vite@5.1.3) diff --git a/website/package.json b/website/package.json index 7dddc2450..d7711537c 100644 --- a/website/package.json +++ b/website/package.json @@ -49,11 +49,13 @@ "og-img": "^0.2.0", "postcss": "^8.4.35", "rehype-external-links": "^3.0.0", + "sharp": "^0.33.2", "tailwindcss": "^3.4.1", "tsm": "^2.3.0", "typescript": "^5.3.3", "undici": "^6.6.2", "vite": "^5.1.3", + "vite-imagetools": "^6.2.9", "vite-tsconfig-paths": "^4.3.1" }, "dependencies": { diff --git a/website/src/components/Header.tsx b/website/src/components/Header.tsx index 2e57179e3..6cb4fafd8 100644 --- a/website/src/components/Header.tsx +++ b/website/src/components/Header.tsx @@ -129,7 +129,8 @@ export const Header = component$(({ searchOpen }) => { > {[ { label: 'Guides', href: '/guides/' }, - { label: 'API reference', href: '/api/' }, + { label: 'API', href: '/api/' }, + { label: 'Blog', href: '/blog/' }, { label: 'Playground', href: '/playground/' }, ].map(({ label, href }) => ( ( +
+ +
+)); diff --git a/website/src/routes/blog/(posts)/should-we-change-valibots-api/index.mdx b/website/src/routes/blog/(posts)/should-we-change-valibots-api/index.mdx new file mode 100644 index 000000000..8ae7af6c8 --- /dev/null +++ b/website/src/routes/blog/(posts)/should-we-change-valibots-api/index.mdx @@ -0,0 +1,150 @@ +--- +cover: API Design +title: Should we change Valibot's API? +description: >- + Today I am writing this message to you to discuss the further development of Valibot's API. +published: 2024-02-29 +authors: + - fabian-hiller + - Demivan + - xcfox +--- + +import NpmDownloads from './npm-downloads.jpg?jsx'; + +# Should we change Valibot's API? + +Hi folks, I am [Fabian](https://twitter.com/FabianHiller), the creator and maintainer of Valibot. Today I am writing this message to you to discuss the further development of Valibot's API. With currently more than 80,000 weekly downloads, the library is growing into a serious open source project used by thousands of JavaScript and TypeScript developers around the world. + + + +In the last few days I received two [API proposals](https://github.com/fabian-hiller/valibot/discussions/453) from [@Demivan](https://github.com/Demivan) and [@xcfox](https://github.com/xcfox). Both of them addressed similar pain points of Valibot's current API design. As our v1 release is getting closer and closer, it is important to me to involve the community in such a big decision. + +## Current pain points + +Valibot's current mental model is divided into schemas, methods, validations, and transformations. Schemas validate data types like strings, numbers and objects. Methods are small utilities that help you use or modify a schema. Validations and transformations are used in the `pipe` argument of a schema. They can make changes to the input and check other details, such as the formatting of a string. + +```ts +// With Valibot's current API +const EmailSchema = string([toTrimmed(), email(), endsWith('@example.com')]); +``` + +A drawback of this API design is that the current pipeline implementation is not modular. This increases the initial bundle size of simple schemas like [`string`](https://valibot.dev/api/string/) by more than 200 bytes. This is almost 30% of the total bundle size. + +Another pain point is that the current pipeline implementation does not allow you to transform the data type. This forced me to add a [`transform`](https://valibot.dev/api/transform/) method, resulting in two places where transformations can happen. + +```ts +// With Valibot's current API +const NumberSchema = transform(string([toTrimmed(), decimal()]), (input) => { + return parseInt(input); +}); +``` + +Speaking of methods, it can quickly become confusing if you need to apply multiple methods to the same schema, as these functions must always be nested. + +```ts +// With Valibot's current API +const LengthSchema = brand( + transform(optional(string(), ''), (input) => input.length), + 'Length' +); +``` + +The last pain point that comes to mind is that the current API design gives you less control over the input and output type of a schema. When working with form libraries, it can be useful to have an input type of `string | null` for the initial values, but an output type of just `string` for a required field. + +## The `pipe` function + +After several design iterations, [@Demivan](https://github.com/Demivan) came up with the idea of a `pipe` function. Similar to the current `pipe` argument, it can be used for validations and transformations. The first argument is always a schema, followed by various actions or schemas. + +```ts +// With the new `pipe` function +const LoginSchema = object({ + email: pipe(string(), minLength(1), email()), + password: pipe(string(), minLength(8)), +}); + +// With Valibot's current API +const LoginSchema = object({ + email: string([minLength(1), email()]), + password: string([minLength(8)]), +}); +``` + +The big difference is that the `pipe` function also allows you to transform the data type. This would allow us to move methods like [`transform`](https://valibot.dev/api/transform/) and [`brand`](https://valibot.dev/api/brand/) into the pipeline. This prevents nesting of functions for these methods and simplifies the mental model. + +With the `pipe` function, the mental model is reduced to schemas, methods, and actions. Actions are always used within the `pipe` function to further validate and transform the input and type of a schema. + +> Alternative names for `pipe` are `flow` (idea by [@mtt-artis](https://github.com/mtt-artis)), `schema` (idea by [@genki](https://github.com/genki)), and `compose` (idea by [@MohammedEsafi](https://github.com/MohammedEsafi)), and `vali` (idea by [@Hugos68](https://github.com/Hugos68)). Please share your thoughts. + +## The advantages + +The `pipe` function makes Valibot even more modular, resulting in a smaller bundle size for very simple schemas without a pipeline. For very complex schemas it reduces function nesting when using [`transform`](https://valibot.dev/api/transform/) and [`brand`](https://valibot.dev/api/brand/). + +```ts +// With the new `pipe` function +const LengthSchema = pipe( + optional(string(), ''), + transform((input) => input.length), + brand('Length') +); + +// With Valibot's current API +const LengthSchema = brand( + transform(optional(string(), ''), (input) => input.length), + 'Length' +); +``` + +It also gives you more control over the input and output type, and simplifies the mental model by eliminating the confusion between the [`transform`](https://valibot.dev/api/transform/) method and the pipeline transformations of the current API. + +```ts +// With the new `pipe` function +const NumberSchema = pipe( + string(), + toTrimmed(), + decimal(), + transform(parseInt) +); + +// With Valibot's current API +const NumberSchema = transform( + string([toTrimmed(), decimal()]), + parseInt +); +``` + +Besides that, the `pipe` function would also allow us to easily add a [metadata feature](https://github.com/fabian-hiller/valibot/issues/373) to Valibot. This could be interesting when working with databases to define SQL properties like `PRIMARY KEY`. + +```ts +// With the new `pipe` function +const UserSchema = pipe( + object({ + id: pipe(string(), uuid(), primaryKey()), + name: pipe(string(), maxLength(32), unique()), + bio: pipe(string(), description('Text ...')), + }), + table('users') +); +``` + +## The disadvantages + +The main disadvantage of the `pipe` function is that it requires a bit more code to write for medium sized schemas, and for more complex schemas you may end up nesting multiple pipelines. + +```ts +// With the new `pipe` function +const NumberSchema = pipe( + union([pipe(string(), decimal()), pipe(number(), integer())]), + transform(Number) +); + +// With Valibot's current API +const NumberSchema = transform( + union([string([decimal()]), number([integer()])]), + Number +); +``` + +## Let's discuss + +Your opinion matters to me. I encourage everyone to share their thoughts. Even quick feedback like "I like this ... and I don't like that ..." is welcome and will help to shape Valibot's future API design. Please discuss with me on [GitHub](https://github.com/fabian-hiller/valibot/discussions/463) or share your thoughts on [Twitter](https://twitter.com/FabianHiller/status/1763253086464639035). diff --git a/website/src/routes/blog/(posts)/should-we-change-valibots-api/npm-downloads.jpg b/website/src/routes/blog/(posts)/should-we-change-valibots-api/npm-downloads.jpg new file mode 100644 index 0000000000000000000000000000000000000000..610d7abe75acb90cac33a14f025d19ca057a2805 GIT binary patch literal 46277 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 literal 0 HcmV?d00001 diff --git a/website/src/routes/blog/index.tsx b/website/src/routes/blog/index.tsx new file mode 100644 index 000000000..84c958772 --- /dev/null +++ b/website/src/routes/blog/index.tsx @@ -0,0 +1,68 @@ +import { component$ } from '@builder.io/qwik'; +import { Link } from '@builder.io/qwik-city'; +import clsx from 'clsx'; + +export default component$(() => ( +
+
+

Blog

+

+ Official announcements, project updates and insightful content directly + from the Valibot core team. We're excited to share our journey with you! + Let's validate together! +

+

Latest posts

+
+
    + {[ + { + cover: 'API Design', + title: "Should we change Valibot's API?", + published: '2024-02-29', + authors: ['fabian-hiller', 'Demivan', 'xcfox'], + href: './should-we-change-valibots-api/', + }, + ].map((post) => ( +
  1. + +
    +
    +
    +
    + {post.cover} +
    +
    +

    + {post.title} +

    +
    +
    + {post.authors.map((author, index) => ( + 0 && '-ml-3' + )} + style={{ zIndex: post.authors.length - index }} + key={author} + width="56" + height="56" + src={`https://github.com/${author}.png?size=56`} + alt={`GitHub profile picture of ${author}`} + /> + ))} +
    + +
    + +
  2. + ))} +
+
+)); diff --git a/website/src/styles/root.css b/website/src/styles/root.css index 1e9a196ce..93681dd0f 100644 --- a/website/src/styles/root.css +++ b/website/src/styles/root.css @@ -84,6 +84,11 @@ @apply focus-ring rounded-md text-sky-600 underline decoration-slate-400 decoration-dashed underline-offset-[3px] focus-visible:outline-offset-4 focus-visible:ring-offset-[6px] dark:text-sky-400 dark:decoration-slate-600; } + /* Images */ + .mdx img { + @apply w-full rounded-2xl border-2 border-slate-200 lg:rounded-3xl lg:border-[3px] dark:border-slate-800; + } + /* Lists */ .mdx :is(ul, ol) { @apply space-y-2;