@loydjs/vite 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,171 +1,200 @@
1
1
  <div align="center">
2
2
 
3
- <h1>Loyd</h1>
3
+ <h1>@loydjs/vite</h1>
4
4
 
5
-
6
- **High-performance, tree-shakable schema validation for TypeScript.**
5
+ <p><strong>AOT compilation plugin for Vite and Rollup.</strong><br/>
6
+ Replaces compile() calls with flat inline validators at build time · Zero runtime overhead.</p>
7
7
 
8
8
  [![CI](https://github.com/b3nito404/loyd/actions/workflows/ci.yml/badge.svg)](https://github.com/b3nito404/loyd/actions/workflows/ci.yml)
9
9
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
- [![Bundle](https://img.shields.io/badge/bundle-0.8kb-brightgreen.svg)](https://bundlephobia.com/package/@loydjs/schema)
10
+ [![Bundle](https://img.shields.io/badge/bundle-~2kb-brightgreen.svg)](https://bundlephobia.com/package/@loydjs/vite)
11
11
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.4%2B-blue.svg)](https://www.typescriptlang.org)
12
- [![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://github.com/b3nito404/loyd/releases)
12
+ [![npm downloads](https://img.shields.io/npm/dm/@loydjs/vite?color=6366f1&label=downloads)](https://www.npmjs.com/package/@loydjs/vite)
13
13
 
14
14
  </div>
15
15
 
16
16
  ---
17
17
 
18
- ## Key features
18
+ ## Overview
19
+
20
+ `@loydjs/vite` is a Vite and Rollup plugin that performs Ahead-of-Time (AOT) compilation of Loyd schemas. When enabled, it replaces `compile(schema)` calls in your source code with the flat inline validator functions at build time — so your production bundle contains zero compilation overhead and no dependency on `@loydjs/compiler` at runtime.
19
21
 
20
- - **0.8 kb minimal bundle** : functional `pipe()` composition enables full tree-shaking; import only what you use
21
- - **JIT compiler** : `compile(schema)` generates a pure JavaScript function via `new Function()`; subsequent calls are **2× faster** than `safeParse` on hot paths
22
- - **Structured i18n** : validators emit `{ code, path, meta }`, never locale strings; swap locales at runtime without touching your schemas
23
- - **Two-pass async pipeline** : sync rules execute first; async rules only if sync passes; multiple async rules run in parallel via `Promise.all`
24
- - **Field dependency graph** : `buildDag(schema, deps)` enables incremental revalidation; change one field -> revalidate only it and its dependents
25
- - **Native React integration** : `useForm`, `useField`, `useFieldArray` with zero external dependencies, backed by the DAG
22
+ In development, the plugin is a no-op JIT compilation runs as normal for fast HMR.
26
23
 
27
24
  ---
28
25
 
29
26
  ## Installation
30
27
 
31
28
  ```sh
32
- # Core start here
33
- npm install @loydjs/schema @loydjs/core @loydjs/types
34
-
35
- # Optional packages
36
- npm install @loydjs/async # two-pass async pipeline
37
- npm install @loydjs/compiler # JIT compilation
38
- npm install @loydjs/error-engine # structured i18n
39
- npm install @loydjs/react # React hooks (requires @loydjs/graph)
40
- npm install @loydjs/graph # field dependency DAG
41
- npm install @loydjs/zod-compat # Zod migration utilities
42
- npm install @loydjs/openapi # OpenAPI 3.1 / JSON Schema export
43
- npm install @loydjs/vite # Vite / Rollup AOT plugin
29
+ npm install @loydjs/vite
44
30
  ```
45
- > **Requires** Node.js ≥ 20, TypeScript ≥ 5.4, and `"strict": true` in your `tsconfig.json`.
31
+
32
+ > **Requires** `@loydjs/core` · `@loydjs/compiler` · Vite ≥ 5.0.0 · Node.js ≥ 20 · TypeScript ≥ 5.4
46
33
 
47
34
  ---
48
35
 
49
- ## Quick start
36
+ ## Setup
37
+
38
+ ### Vite
50
39
 
51
40
  ```ts
52
- import { object, pipe, string, number, email, minLength } from "@loydjs/schema";
53
- import { parse, safeParse } from "@loydjs/core";
54
- import type { Infer } from "@loydjs/types";
55
-
56
- // 1. Define your schema
57
- const UserSchema = object({
58
- name: pipe(string(), minLength(2)),
59
- email: pipe(string(), email()),
60
- age: number().int().min(0),
41
+ // vite.config.ts
42
+ import { defineConfig } from "vite";
43
+ import { loydPlugin } from "@loydjs/vite";
44
+
45
+ export default defineConfig({
46
+ plugins: [
47
+ loydPlugin({
48
+ // Schemas to resolve statically at build time.
49
+ // Key = variable name as it appears in your source code.
50
+ schemas: {
51
+ UserSchema,
52
+ PostSchema,
53
+ CommentSchema,
54
+ },
55
+ }),
56
+ ],
61
57
  });
62
-
63
- // 2. Infer the TypeScript type - zero runtime cost
64
- type User = Infer<typeof UserSchema>;
65
- // -> { name: string; email: string; age: number }
66
-
67
- // 3a. parse() throws LoydError on failure
68
- const user = parse(UserSchema, req.body);
69
-
70
- // 3b. safeParse() never throws
71
- const result = safeParse(UserSchema, formData);
72
- if (result.success) {
73
- console.log(result.data.name); // typed as User
74
- } else {
75
- result.issues.forEach(issue => {
76
- console.log(issue.code); // "ERR_STRING_TOO_SHORT"
77
- console.log(issue.path); // ["name"]
78
- console.log(issue.meta); // { min: 2, actual: 1 }
79
- });
80
- }
81
58
  ```
82
59
 
83
- ### React forms
84
-
85
- ```tsx
86
- import { useForm } from "@loydjs/react";
87
-
88
- function LoginForm() {
89
- const { register, handleSubmit, state } = useForm({
90
- schema: LoginSchema,
91
- defaultValues: { email: "", password: "" },
92
- mode: "onChange",
93
- });
94
-
95
- return (
96
- <form onSubmit={handleSubmit(onValid, onInvalid)}>
97
- <input {...register("email")} type="email" />
98
- <input {...register("password")} type="password" />
99
- <button type="submit" disabled={state.isSubmitting}>Sign in</button>
100
- </form>
101
- );
102
- }
60
+ ### Rollup
61
+
62
+ ```js
63
+ // rollup.config.js
64
+ import { loydPlugin } from "@loydjs/vite";
65
+
66
+ export default {
67
+ input: "src/index.ts",
68
+ plugins: [
69
+ loydPlugin({ schemas: { UserSchema } }),
70
+ ],
71
+ };
103
72
  ```
104
73
 
105
- ### JIT compilation
74
+ ---
75
+
76
+ ## How it works
77
+
78
+ Your source code, untouched:
106
79
 
107
80
  ```ts
108
81
  import { compile } from "@loydjs/compiler";
82
+ import { UserSchema } from "./schemas";
109
83
 
110
84
  const validate = compile(UserSchema);
85
+ const result = validate(req.body);
86
+ ```
111
87
 
112
- // faster on hot paths - compiled once, cached per schema instance
113
- const result = validate(input); // LoydResult<User>
88
+ After AOT transform what ships in your production bundle:
89
+
90
+ ```js
91
+ // @loydjs/compiler: AOT-inlined validator for UserSchema
92
+ function __loyd_UserSchema__(input) {
93
+ "use strict";
94
+ let __input__ = input;
95
+ const __issues__ = [];
96
+ if (typeof __input__ !== "object" || __input__ === null || Array.isArray(__input__)) {
97
+ __issues__.push({ code: "ERR_OBJECT_INVALID_TYPE", path: [] });
98
+ } else {
99
+ const __fname__ = __input__["name"];
100
+ if (typeof __fname__ !== "string") {
101
+ __issues__.push({ code: "ERR_STRING_INVALID_TYPE", path: ["name"] });
102
+ } else {
103
+ if (__fname__.length < 2) { __issues__.push({ code: "ERR_STRING_TOO_SHORT", path: ["name"], meta: { min: 2, actual: __fname__.length } }); }
104
+ if (__fname__.length > 100) { __issues__.push({ code: "ERR_STRING_TOO_LONG", path: ["name"], meta: { max: 100, actual: __fname__.length } }); }
105
+ }
106
+ // ...
107
+ }
108
+ if (__issues__.length > 0) return { success: false, data: undefined, issues: __issues__ };
109
+ return { success: true, data: __input__, issues: [] };
110
+ }
111
+ const validate = __loyd_UserSchema__;
112
+ const result = validate(req.body);
114
113
  ```
115
114
 
116
- ### i18n error formatting
115
+ ---
116
+
117
+ ## Plugin options
117
118
 
118
119
  ```ts
119
- import { configureFormatter, fr } from "@loydjs/error-engine";
120
+ interface LoydVitePluginOptions {
121
+ /**
122
+ * Schemas to resolve statically at build time.
123
+ * Key = variable name as it appears in source code.
124
+ */
125
+ schemas?: Record<string, LoydSchema<unknown>>;
126
+
127
+ /**
128
+ * Enable/disable the plugin entirely.
129
+ * @default true
130
+ */
131
+ enabled?: boolean;
132
+
133
+ /**
134
+ * Log transformed files.
135
+ * @default false
136
+ */
137
+ verbose?: boolean;
138
+
139
+ /**
140
+ * Force AOT even in development mode.
141
+ * By default, AOT is only active during production builds.
142
+ * @default false
143
+ */
144
+ forceAot?: boolean;
145
+
146
+ /**
147
+ * Generate sourcemaps for transformed files.
148
+ * @default true
149
+ */
150
+ sourcemap?: boolean;
151
+ }
152
+ ```
120
153
 
121
- // Call once at app startup
122
- configureFormatter("fr", fr);
154
+ ---
123
155
 
124
- // Issues are now formatted in French
125
- const result = safeParse(UserSchema, badInput);
126
- // result.issues[0].message -> "Minimum 2 caractères (reçu : 1)"
127
- ```
156
+ ## Emit standalone validators
128
157
 
129
- ### Migrate from Zod
158
+ Use the `emit()` function from `@loydjs/compiler` to generate standalone `.js` + `.d.ts` validator files, independent of the Vite plugin.
130
159
 
131
160
  ```ts
132
- import { fromZod, runCodemod } from "@loydjs/zod-compat";
133
-
134
- // Convert a single schema
135
- const LoydUser = fromZod(zodUserSchema);
161
+ import { emit } from "@loydjs/compiler";
162
+ import { UserSchema } from "./schemas";
163
+
164
+ await emit(UserSchema, {
165
+ outFile: "./dist/validators/user.js",
166
+ exportName: "validateUser",
167
+ format: "esm",
168
+ dts: true,
169
+ });
136
170
 
137
- // Or run the automated codemod across your entire codebase
138
- await runCodemod("./src", { write: true, verbose: true });
171
+ // dist/validators/user.js — flat inline validator, no imports
172
+ // dist/validators/user.d.ts — TypeScript declarations
139
173
  ```
140
174
 
141
175
  ---
142
176
 
143
- ## Packages
144
-
145
- | Package | Description | Size |
146
- |---|---|---|
147
- | `@loydjs/core` | `parse`, `safeParse`, `LoydError`, `BaseSchema` | 3.9 kb |
148
- | `@loydjs/schema` | All primitives, composites, modifiers, refinements | tree-shakeable |
149
- | `@loydjs/types` | `Infer<>`, `InferInput<>`, `InferOutput<>` | 0 kb runtime |
150
- | `@loydjs/async` | `parseAsync`, two-pass pipeline, `AbortSignal` | ~2 kb |
151
- | `@loydjs/compiler` | `compile()`, JIT codegen, cache management | ~4 kb |
152
- | `@loydjs/error-engine` | `createFormatter`, en/fr/es/ar locales | ~3 kb |
153
- | `@loydjs/graph` | `buildDag`, `validateIncremental`, dirty tracking | ~3 kb |
154
- | `@loydjs/react` | `useForm`, `useField`, `useFieldArray`, `FormProvider` | ~8 kb |
155
- | `@loydjs/zod-compat` | `fromZod`, `toZod`, `runCodemod` | ~5 kb |
156
- | `@loydjs/openapi` | `toOpenApi`, `toJsonSchema`, `toOpenApiComponents` | ~4 kb |
157
- | `@loydjs/vite` | `loydPlugin()` - Vite/Rollup AOT compilation | ~2 kb |
177
+ ## Dependencies
178
+
179
+ | Package | Role |
180
+ |:---|:---|
181
+ | `@loydjs/core` | `LoydSchema` type |
182
+ | `@loydjs/compiler` | `generateCode`, `optimize` for AOT codegen |
183
+
184
+ ## Peer dependencies
185
+
186
+ | Package | Version |
187
+ |:---|:---|
188
+ | `vite` | 5.0.0 |
158
189
 
159
190
  ---
160
191
 
161
192
  ## Documentation
162
193
 
163
- For the full API reference, guides, and examples, visit the official documentation:
164
-
165
- **[https://loyddev-psi.vercel.app](https://loyddev-psi.vercel.app)**
194
+ **[loyddev-psi.vercel.app](https://loyddev-psi.vercel.app)**
166
195
 
167
196
  ---
168
197
 
169
198
  ## License
170
199
 
171
- MIT
200
+ MIT © [b3nito404](https://github.com/b3nito404)