rustica 1.0.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.
@@ -0,0 +1,71 @@
1
+ import type { Schema, ValidationResult, ValidationError } from "../schema/types";
2
+ import type { SchemaBuilder } from "../schema/builders";
3
+ /**
4
+ * WASM module interface
5
+ * Auto-generated by wasm-pack
6
+ */
7
+ export interface WasmModule {
8
+ WasmValidator: {
9
+ validate(schema_json: string, value_json: string): string;
10
+ validate_at_path(schema_json: string, value_json: string, path_json: string): string;
11
+ };
12
+ }
13
+ /**
14
+ * Initialize WASM module
15
+ * Can be called explicitly for eager loading, or will auto-initialize on first use
16
+ */
17
+ export declare function initWasm(): Promise<void>;
18
+ /**
19
+ * Core validator using WASM
20
+ */
21
+ export declare class Validator {
22
+ /**
23
+ * Validate data against a schema
24
+ * Auto-initializes WASM on first use
25
+ *
26
+ * @param schema - Schema definition (builder or JSON)
27
+ * @param value - Data to validate
28
+ * @returns Validation result with errors if any
29
+ */
30
+ static validate<T>(schema: SchemaBuilder<T> | Schema, value: unknown): Promise<ValidationResult>;
31
+ /**
32
+ * Validate data at a specific path in the schema
33
+ * Useful for field-level validation in forms
34
+ * Auto-initializes WASM on first use
35
+ *
36
+ * @param schema - Schema definition
37
+ * @param value - Complete data object
38
+ * @param path - Path to validate (e.g., ['user', 'email'])
39
+ * @returns Validation result for the specific field
40
+ */
41
+ static validateAtPath<T>(schema: SchemaBuilder<T> | Schema, value: unknown, path: string[]): Promise<ValidationResult>;
42
+ /**
43
+ * Validate and throw on error (for convenience)
44
+ * Auto-initializes WASM on first use
45
+ */
46
+ static parse<T>(schema: SchemaBuilder<T> | Schema, value: unknown): Promise<T>;
47
+ /**
48
+ * Safe parse that returns result object
49
+ * Auto-initializes WASM on first use
50
+ */
51
+ static safeParse<T>(schema: SchemaBuilder<T> | Schema, value: unknown): Promise<{
52
+ success: true;
53
+ data: T;
54
+ } | {
55
+ success: false;
56
+ errors: ValidationError[];
57
+ }>;
58
+ }
59
+ /**
60
+ * Validation exception for parse() method
61
+ */
62
+ export declare class ValidationException extends Error {
63
+ errors: ValidationError[];
64
+ constructor(errors: ValidationError[]);
65
+ }
66
+ /**
67
+ * Auto-initialization wrapper
68
+ * Automatically initializes WASM on first use
69
+ */
70
+ export declare function createValidator(): Promise<typeof Validator>;
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validator/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,gBAAgB,EAChB,eAAe,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE;QACb,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;QAC1D,gBAAgB,CACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC;KACX,CAAC;CACH;AAQD;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAsC9C;AA0BD;;GAEG;AACH,qBAAa,SAAS;IACpB;;;;;;;OAOG;WACU,QAAQ,CAAC,CAAC,EACrB,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,EACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,gBAAgB,CAAC;IAkB5B;;;;;;;;;OASG;WACU,cAAc,CAAC,CAAC,EAC3B,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,EACjC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,gBAAgB,CAAC;IAqB5B;;;OAGG;WACU,KAAK,CAAC,CAAC,EAClB,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,EACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,CAAC,CAAC;IAUb;;;OAGG;WACU,SAAS,CAAC,CAAC,EACtB,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,EACjC,KAAK,EAAE,OAAO,GACb,OAAO,CACR;QAAE,OAAO,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,CAAC,CAAA;KAAE,GAAG;QAAE,OAAO,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,eAAe,EAAE,CAAA;KAAE,CAC3E;CASF;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IACzB,MAAM,EAAE,eAAe,EAAE;gBAAzB,MAAM,EAAE,eAAe,EAAE;CAO7C;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,SAAS,CAAC,CAGjE"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Lazy-loaded WASM module singleton
3
+ */
4
+ let wasmModule = null;
5
+ let wasmInitPromise = null;
6
+ /**
7
+ * Initialize WASM module
8
+ * Can be called explicitly for eager loading, or will auto-initialize on first use
9
+ */
10
+ export async function initWasm() {
11
+ if (wasmModule)
12
+ return;
13
+ if (wasmInitPromise)
14
+ return wasmInitPromise;
15
+ wasmInitPromise = (async () => {
16
+ try {
17
+ // Dynamic import of WASM module
18
+ // Use package-relative path that works both in development and when installed
19
+ const module = (await import("rustica/pkg/rustica.js"));
20
+ console.log("WASM module loaded:", module);
21
+ console.log("Has WasmValidator?", !!module.WasmValidator);
22
+ console.log("Has default?", typeof module.default);
23
+ // For bundler/web target with async init, call default function
24
+ if (typeof module.default === "function") {
25
+ await module.default();
26
+ }
27
+ // Always set wasmModule to the imported module (it has WasmValidator)
28
+ wasmModule = module;
29
+ // Verify WasmValidator is accessible
30
+ if (!module.WasmValidator) {
31
+ throw new Error("WasmValidator not found in WASM module");
32
+ }
33
+ console.log("WASM initialization complete");
34
+ }
35
+ catch (error) {
36
+ console.error("WASM initialization failed:", error);
37
+ wasmInitPromise = null; // Reset on error so it can be retried
38
+ throw new Error(`Failed to load WASM module. Make sure to run 'npm run build:wasm' first. Error: ${error}`);
39
+ }
40
+ })();
41
+ return wasmInitPromise;
42
+ }
43
+ /**
44
+ * Get initialized WASM module (auto-initializes if needed)
45
+ */
46
+ async function getWasm() {
47
+ // If initialization is in progress, wait for it
48
+ if (wasmInitPromise && !wasmModule) {
49
+ await wasmInitPromise;
50
+ }
51
+ // If not initialized at all, start initialization
52
+ if (!wasmModule) {
53
+ await initWasm();
54
+ }
55
+ // Final check
56
+ if (!wasmModule) {
57
+ throw new Error("WASM module not initialized. Call initWasm() before validation.");
58
+ }
59
+ return wasmModule;
60
+ }
61
+ /**
62
+ * Core validator using WASM
63
+ */
64
+ export class Validator {
65
+ /**
66
+ * Validate data against a schema
67
+ * Auto-initializes WASM on first use
68
+ *
69
+ * @param schema - Schema definition (builder or JSON)
70
+ * @param value - Data to validate
71
+ * @returns Validation result with errors if any
72
+ */
73
+ static async validate(schema, value) {
74
+ const wasm = await getWasm();
75
+ // Serialize schema to JSON
76
+ const schemaJson = JSON.stringify(schema instanceof Object && "toJSON" in schema ? schema.toJSON() : schema);
77
+ // Serialize value to JSON
78
+ const valueJson = JSON.stringify(value);
79
+ // Call WASM validator (single call, zero-copy)
80
+ const resultJson = wasm.WasmValidator.validate(schemaJson, valueJson);
81
+ // Parse result
82
+ return JSON.parse(resultJson);
83
+ }
84
+ /**
85
+ * Validate data at a specific path in the schema
86
+ * Useful for field-level validation in forms
87
+ * Auto-initializes WASM on first use
88
+ *
89
+ * @param schema - Schema definition
90
+ * @param value - Complete data object
91
+ * @param path - Path to validate (e.g., ['user', 'email'])
92
+ * @returns Validation result for the specific field
93
+ */
94
+ static async validateAtPath(schema, value, path) {
95
+ const wasm = await getWasm();
96
+ // Serialize inputs
97
+ const schemaJson = JSON.stringify(schema instanceof Object && "toJSON" in schema ? schema.toJSON() : schema);
98
+ const valueJson = JSON.stringify(value);
99
+ const pathJson = JSON.stringify(path);
100
+ // Call WASM validator (single call)
101
+ const resultJson = wasm.WasmValidator.validate_at_path(schemaJson, valueJson, pathJson);
102
+ // Parse result
103
+ return JSON.parse(resultJson);
104
+ }
105
+ /**
106
+ * Validate and throw on error (for convenience)
107
+ * Auto-initializes WASM on first use
108
+ */
109
+ static async parse(schema, value) {
110
+ const result = await this.validate(schema, value);
111
+ if (!result.success) {
112
+ throw new ValidationException(result.errors || []);
113
+ }
114
+ return value;
115
+ }
116
+ /**
117
+ * Safe parse that returns result object
118
+ * Auto-initializes WASM on first use
119
+ */
120
+ static async safeParse(schema, value) {
121
+ const result = await this.validate(schema, value);
122
+ if (result.success) {
123
+ return { success: true, data: value };
124
+ }
125
+ else {
126
+ return { success: false, errors: result.errors || [] };
127
+ }
128
+ }
129
+ }
130
+ /**
131
+ * Validation exception for parse() method
132
+ */
133
+ export class ValidationException extends Error {
134
+ constructor(errors) {
135
+ super("Validation failed:\n" +
136
+ errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n"));
137
+ this.errors = errors;
138
+ this.name = "ValidationException";
139
+ }
140
+ }
141
+ /**
142
+ * Auto-initialization wrapper
143
+ * Automatically initializes WASM on first use
144
+ */
145
+ export async function createValidator() {
146
+ await initWasm();
147
+ return Validator;
148
+ }
149
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validator/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "rustica",
3
+ "version": "1.0.0",
4
+ "description": "Production-grade schema validation powered by Rust and WebAssembly",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./pkg/*": "./pkg/*"
14
+ },
15
+ "author": "fourth-ally",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/fourth-ally/rustica.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/fourth-ally/rustica/issues"
23
+ },
24
+ "homepage": "https://github.com/fourth-ally/rustica#readme",
25
+ "files": [
26
+ "dist",
27
+ "pkg",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
31
+ "scripts": {
32
+ "build:wasm": "wasm-pack build --target bundler --out-dir pkg",
33
+ "build:wasm:node": "wasm-pack build --target nodejs --out-dir pkg",
34
+ "build:ts": "tsc",
35
+ "build": "npm run build:wasm && npm run build:ts",
36
+ "dev": "tsc --watch",
37
+ "test": "cargo test && npm run test:ts",
38
+ "test:ts": "npm run build:wasm:node && node --import tsx --test tests/*.test.ts && npm run build:wasm",
39
+ "prepublishOnly": "npm run build && npm test"
40
+ },
41
+ "keywords": [
42
+ "validation",
43
+ "schema",
44
+ "wasm",
45
+ "rust",
46
+ "zod",
47
+ "forms",
48
+ "react",
49
+ "typescript",
50
+ "webassembly",
51
+ "form-validation"
52
+ ],
53
+ "devDependencies": {
54
+ "@types/node": "^25.0.9",
55
+ "@types/react": "^18.2.0",
56
+ "react": "^18.2.0",
57
+ "tsx": "^4.7.0",
58
+ "typescript": "^5.3.0"
59
+ },
60
+ "peerDependencies": {
61
+ "react": ">=18.0.0"
62
+ },
63
+ "peerDependenciesMeta": {
64
+ "react": {
65
+ "optional": true
66
+ }
67
+ },
68
+ "engines": {
69
+ "node": ">=18.0.0"
70
+ }
71
+ }
package/pkg/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *
package/pkg/.npmignore ADDED
@@ -0,0 +1,3 @@
1
+ # Override the .gitignore for npm publishing
2
+ # We want to include the WASM build artifacts in the npm package
3
+ !*
package/pkg/README.md ADDED
@@ -0,0 +1,289 @@
1
+ # Rustica
2
+
3
+ ![Rustica - Validate 'Em All'](./assets/rustica-banner.png)
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)
7
+ [![Rust](https://img.shields.io/badge/Rust-1.70+-orange)](https://www.rust-lang.org/)
8
+ [![WebAssembly](https://img.shields.io/badge/WebAssembly-✓-blueviolet)](https://webassembly.org/)
9
+
10
+ Production-grade schema and form validation system powered by Rust and WebAssembly.
11
+
12
+ ## ✨ Features
13
+
14
+ <table>
15
+ <tr>
16
+ <td width="50%">
17
+
18
+ ### 🦀 Rust Core
19
+
20
+ - **WASM-powered** validation
21
+ - **Zero-copy** architecture
22
+ - **~0.1-0.5ms** per validation
23
+ - **Single call** per validation
24
+
25
+ </td>
26
+ <td width="50%">
27
+
28
+ ### 📝 TypeScript API
29
+
30
+ - **Fluent API** like Zod
31
+ - **Full type inference**
32
+ - **Schema serialization**
33
+ - **UI metadata** support
34
+
35
+ </td>
36
+ </tr>
37
+ <tr>
38
+ <td width="50%">
39
+
40
+ ### ⚛️ React Integration
41
+
42
+ - **useWasmForm** hook
43
+ - **Field registration**
44
+ - **Auto re-rendering**
45
+ - **RHF-compatible** API
46
+
47
+ </td>
48
+ <td width="50%">
49
+
50
+ ### 🔧 Framework Agnostic
51
+
52
+ - **createForm** for any framework
53
+ - **Vanilla JS** support
54
+ - **Node.js** compatible
55
+ - **Browser** ready
56
+
57
+ </td>
58
+ </tr>
59
+ </table>
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ npm install rustica
65
+ ```
66
+
67
+ ## Quick Start
68
+
69
+ ```typescript
70
+ import { r, useWasmForm } from 'rustica';
71
+
72
+ // Define schema with optional custom error messages
73
+ // WASM auto-initializes on first validation - no setup needed!
74
+ const loginSchema = r.object({
75
+ email: r.string()
76
+ .min(3)
77
+ .email()
78
+ .ui({ label: "Email" })
79
+ .messages({
80
+ email: "Please enter a valid email address",
81
+ min: "Email must be at least 3 characters"
82
+ }),
83
+ password: r.string()
84
+ .min(8)
85
+ .ui({ label: "Password" })
86
+ .messages({
87
+ min: "Password must be at least 8 characters for security"
88
+ })
89
+ });
90
+
91
+ // Infer types
92
+ type LoginForm = r.Infer<typeof loginSchema>;
93
+
94
+ // Use in React - works immediately!
95
+ function LoginForm() {
96
+ const form = useWasmForm({
97
+ schema: loginSchema,
98
+ defaultValues: { email: '', password: '' },
99
+ onSubmit: async (data) => {
100
+ console.log('Valid data:', data);
101
+ }
102
+ });
103
+
104
+ return (
105
+ <form onSubmit={form.handleSubmit}>
106
+ <input {...form.register('email')} />
107
+ {form.errors.email && <span>{form.errors.email.message}</span>}
108
+
109
+ <input type="password" {...form.register('password')} />
110
+ {form.errors.password && <span>{form.errors.password.message}</span>}
111
+
112
+ <button type="submit">Login</button>
113
+ </form>
114
+ );
115
+ }
116
+ ```
117
+
118
+ **Note**: WASM auto-initializes on the first validation call. For eager loading (optional), you can manually call `await initWasm()` at app startup.
119
+
120
+ ````
121
+
122
+ ## Custom Error Messages (Optional)
123
+
124
+ Customize validation error messages for better UX:
125
+
126
+ ```typescript
127
+ // String validation with custom messages
128
+ const usernameSchema = r.string().min(3).max(20).messages({
129
+ invalid_type: "Username must be text",
130
+ min: "Username is too short - minimum 3 characters",
131
+ max: "Username is too long - maximum 20 characters",
132
+ });
133
+
134
+ // Number validation with custom messages
135
+ const ageSchema = r.number().min(18).integer().messages({
136
+ invalid_type: "Age must be a number",
137
+ min: "You must be at least 18 years old",
138
+ integer: "Age must be a whole number",
139
+ });
140
+
141
+ // Object validation with custom messages
142
+ const formSchema = r
143
+ .object({
144
+ email: r.string().email().messages({
145
+ email: "Please enter a valid email like user@example.com",
146
+ }),
147
+ terms: r.boolean().messages({
148
+ invalid_type: "You must accept the terms and conditions",
149
+ }),
150
+ })
151
+ .messages({
152
+ invalid_type: "Form data must be an object",
153
+ required: "This field is required",
154
+ });
155
+ ````
156
+
157
+ **Available message keys by type:**
158
+
159
+ - **String**: `invalid_type`, `min`, `max`, `email`, `url`, `pattern`
160
+ - **Number**: `invalid_type`, `min`, `max`, `integer`, `positive`
161
+ - **Boolean**: `invalid_type`
162
+ - **Object**: `invalid_type`, `required`
163
+
164
+ If not provided, default messages are used. See [examples/custom-messages.ts](./examples/custom-messages.ts) for more examples.
165
+
166
+ ## Building from Source
167
+
168
+ ```bash
169
+ # Quick setup (recommended)
170
+ chmod +x scripts/setup.sh
171
+ ./scripts/setup.sh
172
+
173
+ # Or manual setup
174
+ npm install
175
+ npm run build
176
+ ```
177
+
178
+ See [Getting Started Guide](./docs/GETTING_STARTED.md) for detailed instructions.
179
+
180
+ ## Architecture
181
+
182
+ - **Rust Core** (`src/lib.rs`, `src/schema.rs`, `src/validator.rs`) - Schema definitions and validation logic
183
+ - **WASM Interface** (`src/wasm.rs`) - WebAssembly bindings with wasm-bindgen
184
+ - **TypeScript Schema Builder** (`src/schema/`) - Fluent API for schema definition
185
+ - **Form Runtime** (`src/form/`) - Form state management
186
+ - **React Hook** (`src/react/`) - React integration
187
+
188
+ ## Documentation
189
+
190
+ - 📖 **[Complete Documentation Index](./docs/INDEX.md)** - All docs in one place
191
+ - 🚀 **[Getting Started Guide](./docs/GETTING_STARTED.md)** - Quick start tutorial
192
+ - 📚 **[API Reference](./docs/API.md)** - Complete API documentation
193
+ - 🏗️ **[Architecture Guide](./docs/ARCHITECTURE.md)** - How it works
194
+ - 📊 **[Feature Comparison](./docs/COMPARISON.md)** - vs Zod, Yup, Joi
195
+ - 🤝 **[Contributing Guide](./CONTRIBUTING.md)** - How to contribute
196
+
197
+ ## Project Structure
198
+
199
+ ```
200
+ rustica/
201
+ ├── src/ # Rust source (validation core)
202
+ │ ├── lib.rs # Module exports
203
+ │ ├── schema.rs # Schema AST types
204
+ │ ├── validator.rs # Validation engine
205
+ │ └── wasm.rs # WASM bindings
206
+ ├── src/ # TypeScript source
207
+ │ ├── schema/ # Schema builders (r.string(), etc.)
208
+ │ ├── validator/ # WASM wrapper
209
+ │ ├── form/ # Form runtime
210
+ │ ├── react/ # React hooks
211
+ │ └── index.ts # Main entry point
212
+ ├── examples/ # Usage examples
213
+ │ ├── quick-test.ts # Basic validation tests
214
+ │ ├── standalone.ts # Standalone examples
215
+ │ ├── forms.tsx # Form component examples
216
+ │ └── react-form-app/ # Full React app with API integration
217
+ ├── tests/ # Test suite
218
+ ├── docs/ # Documentation
219
+ └── scripts/ # Build scripts
220
+ ```
221
+
222
+ ## Commands
223
+
224
+ ```bash
225
+ # Development
226
+ make install # Install dependencies
227
+ make build # Build WASM + TypeScript
228
+ make test # Run all tests
229
+ make dev # Watch mode
230
+
231
+ # Quick Commands
232
+ make example # Run quick test
233
+ make clean # Clean build artifacts
234
+ make help # Show all commands
235
+ ```
236
+
237
+ ## Performance
238
+
239
+ <table>
240
+ <tr>
241
+ <td><b>Metric</b></td>
242
+ <td><b>Value</b></td>
243
+ <td><b>Notes</b></td>
244
+ </tr>
245
+ <tr>
246
+ <td>Validation Speed</td>
247
+ <td>~0.1-0.5ms</td>
248
+ <td>Per validation (warm)</td>
249
+ </tr>
250
+ <tr>
251
+ <td>Throughput</td>
252
+ <td>5,000-10,000/sec</td>
253
+ <td>1000 validations in ~100-200ms</td>
254
+ </tr>
255
+ <tr>
256
+ <td>WASM Size</td>
257
+ <td>~15-20KB</td>
258
+ <td>Gzipped: ~8-10KB</td>
259
+ </tr>
260
+ <tr>
261
+ <td>Overhead</td>
262
+ <td>Single call</td>
263
+ <td>Zero-copy where possible</td>
264
+ </tr>
265
+ </table>
266
+
267
+ See [Performance Comparison](./docs/COMPARISON.md) for detailed benchmarks.
268
+
269
+ ## Contributing
270
+
271
+ We welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
272
+
273
+ ## Roadmap
274
+
275
+ - [x] Core validation (string, number, boolean, object)
276
+ - [x] React hooks
277
+ - [x] Form runtime
278
+ - [x] Type inference
279
+ - [x] Custom error messages (optional)
280
+ - [ ] Array/tuple schemas
281
+ - [ ] Union/intersection types
282
+ - [ ] Async validation helpers
283
+ - [ ] i18n support
284
+
285
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
286
+
287
+ ## License
288
+
289
+ MIT
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "rustica",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "files": [
6
+ "rustica_bg.wasm",
7
+ "rustica.js",
8
+ "rustica_bg.js",
9
+ "rustica.d.ts"
10
+ ],
11
+ "main": "rustica.js",
12
+ "types": "rustica.d.ts",
13
+ "sideEffects": [
14
+ "./rustica.js",
15
+ "./snippets/*"
16
+ ]
17
+ }
@@ -0,0 +1,42 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /**
5
+ * WASM interface for validation
6
+ *
7
+ * This module exposes exactly two functions to JavaScript:
8
+ * - validate: validates entire data against schema
9
+ * - validate_at_path: validates data at a specific path
10
+ *
11
+ * Both functions accept and return JSON strings for zero-copy performance
12
+ */
13
+ export class WasmValidator {
14
+ private constructor();
15
+ free(): void;
16
+ [Symbol.dispose](): void;
17
+ /**
18
+ * Validate data against a schema
19
+ *
20
+ * # Arguments
21
+ * * `schema_json` - JSON string representing the schema AST
22
+ * * `value_json` - JSON string representing the data to validate
23
+ *
24
+ * # Returns
25
+ * JSON string with validation result:
26
+ * - Success: `{"success": true}`
27
+ * - Error: `{"success": false, "errors": [...]}`
28
+ */
29
+ static validate(schema_json: string, value_json: string): string;
30
+ /**
31
+ * Validate data at a specific path in the schema
32
+ *
33
+ * # Arguments
34
+ * * `schema_json` - JSON string representing the schema AST
35
+ * * `value_json` - JSON string representing the data to validate
36
+ * * `path_json` - JSON array of path segments as strings
37
+ *
38
+ * # Returns
39
+ * JSON string with validation result (same format as validate)
40
+ */
41
+ static validate_at_path(schema_json: string, value_json: string, path_json: string): string;
42
+ }
package/pkg/rustica.js ADDED
@@ -0,0 +1,9 @@
1
+ /* @ts-self-types="./rustica.d.ts" */
2
+
3
+ import * as wasm from "./rustica_bg.wasm";
4
+ import { __wbg_set_wasm } from "./rustica_bg.js";
5
+ __wbg_set_wasm(wasm);
6
+
7
+ export {
8
+ WasmValidator
9
+ } from "./rustica_bg.js";