@@ -20,7 +20,7 @@ import {
2020} from '../reflection/type.js' ;
2121import { ValidationErrorItem } from '../validator.js' ;
2222import { NamingStrategy } from './naming.js' ;
23- import { HandlerRegistry , TypeGuardRegistry } from './registry.js' ;
23+ import { HandlerRegistry } from './registry.js' ;
2424import { BuildState , SerializationOptions } from './state.js' ;
2525
2626export type SerializeFunction < T = any , R = any > = ( data : T , options ?: SerializationOptions ) => R ;
@@ -53,32 +53,24 @@ export class Serializer {
5353 /** Registry for deserialization handlers */
5454 readonly deserializeRegistry = new HandlerRegistry ( 'deserialize' ) ;
5555
56- /** Registry for type guards at different specificality levels */
57- readonly typeGuards = new TypeGuardRegistry ( ) ;
56+ /** Registry for type guards (unified: fast, strict, and error-collecting all use this) */
57+ readonly typeGuards = new HandlerRegistry ( ) ;
5858
59- /** Registry for validator handlers */
60- readonly validators = new HandlerRegistry ( ) ;
61-
62- /** Registry for fast type guards (pure && chain, no error collection) */
63- readonly fastTypeGuards = new HandlerRegistry ( ) ;
64-
65- /** Registry for strict type guards (reject unknown keys) */
66- readonly strictTypeGuards = new HandlerRegistry ( ) ;
67-
68- /** Cache for built fast type guard functions (prevents infinite recursion for recursive types) */
59+ /** Cache for built fast type guard functions */
6960 private readonly fastTypeGuardCache = new Map < Type , ( data : unknown ) => boolean > ( ) ;
7061
71- /** Cache for built strict type guard functions (prevents infinite recursion for recursive types) */
62+ /** Cache for built strict type guard functions */
7263 private readonly strictTypeGuardCache = new Map < Type , ( data : unknown ) => boolean > ( ) ;
7364
74- /** Types currently being built (for recursive type detection) */
65+ /** Types currently being built as fast guards (for recursive type detection) */
7566 private readonly buildingFastTypeGuards = new Set < Type > ( ) ;
67+
68+ /** Types currently being built as strict guards (for recursive type detection) */
7669 private readonly buildingStrictTypeGuards = new Set < Type > ( ) ;
7770
7871 constructor ( public name : string = 'json' ) {
7972 this . registerSerializers ( ) ;
8073 this . registerTypeGuards ( ) ;
81- this . registerValidators ( ) ;
8274 }
8375
8476 /**
@@ -103,22 +95,17 @@ export class Serializer {
10395 // Guards will be registered via registerDefaultTypeGuards() from handlers.ts
10496 }
10597
106- /**
107- * Register default validators. Override in subclasses to customize.
108- */
109- protected registerValidators ( ) : void {
110- // Validators will be registered via registerDefaultValidators() from validation.ts
111- }
112-
11398 /**
11499 * Clear all registries.
115100 */
116101 clear ( ) : void {
117102 this . serializeRegistry . clear ( ) ;
118103 this . deserializeRegistry . clear ( ) ;
119104 this . typeGuards . clear ( ) ;
120- this . validators . clear ( ) ;
121- this . fastTypeGuards . clear ( ) ;
105+ this . fastTypeGuardCache . clear ( ) ;
106+ this . strictTypeGuardCache . clear ( ) ;
107+ this . buildingFastTypeGuards . clear ( ) ;
108+ this . buildingStrictTypeGuards . clear ( ) ;
122109 }
123110
124111 /**
@@ -174,16 +161,15 @@ export class Serializer {
174161 ( ctx : Context , data : Slot < any > , stateArg : Slot < { errors ?: ValidationErrorItem [ ] } > ) => {
175162 const optionsSlot = ctx . lazyLet ( ctx . ternary ( stateArg , stateArg , ctx . objExpr ( ) ) ) ;
176163
177- const guardRegistry = this . typeGuards . getRegistry ( 1 ) ;
178- const state = new BuildState ( 'validate' , this , ctx , optionsSlot , guardRegistry , {
164+ const state = new BuildState ( 'validate' , this , ctx , optionsSlot , this . typeGuards , {
179165 validation : 'strict' ,
166+ collectErrors : true ,
167+ rejectUnknownKeys : false ,
180168 } ) ;
181169
182- // For validation, we return a boolean score > 0
170+ // For validation, we return a boolean
183171 const result = state . build ( type , data ) ;
184-
185- // Convert score to boolean
186- return ctx . gt ( result , ctx . lit ( 0 ) ) ;
172+ return result as Slot < boolean > ;
187173 } ,
188174 ) ;
189175 }
@@ -202,13 +188,14 @@ export class Serializer {
202188 ( ctx : Context , data : Slot < any > , stateArg : Slot < { errors ?: ValidationErrorItem [ ] } > ) => {
203189 const optionsSlot = ctx . lazyLet ( ctx . ternary ( stateArg , stateArg , ctx . objExpr ( ) ) ) ;
204190
205- const guardRegistry = this . typeGuards . getRegistry ( 1 ) ;
206- const state = new BuildState ( 'validate' , this , ctx , optionsSlot , guardRegistry , {
191+ const state = new BuildState ( 'validate' , this , ctx , optionsSlot , this . typeGuards , {
207192 validation : withLoose ? 'loose' : 'strict' ,
193+ collectErrors : true ,
194+ rejectUnknownKeys : false ,
208195 } ) ;
209196
210197 const result = state . build ( type , data ) ;
211- return ctx . gt ( result , ctx . lit ( 0 ) ) ;
198+ return result as Slot < boolean > ;
212199 } ,
213200 ) as Guard < T > ;
214201 }
@@ -252,8 +239,10 @@ export class Serializer {
252239
253240 try {
254241 const fn = jit . fn ( jit . arg < unknown > ( ) , ( ctx : Context , data : Slot < unknown > ) => {
255- const state = new BuildState ( 'validate' , this , ctx , ctx . objExpr ( ) , this . fastTypeGuards , {
242+ const state = new BuildState ( 'validate' , this , ctx , ctx . objExpr ( ) , this . typeGuards , {
256243 validation : 'fast' ,
244+ collectErrors : false ,
245+ rejectUnknownKeys : false ,
257246 } ) ;
258247 return state . build ( type , data ) ;
259248 } ) as ( data : unknown ) => data is T ;
@@ -304,8 +293,10 @@ export class Serializer {
304293
305294 try {
306295 const fn = jit . fn ( jit . arg < unknown > ( ) , ( ctx : Context , data : Slot < unknown > ) => {
307- const state = new BuildState ( 'validate' , this , ctx , ctx . objExpr ( ) , this . strictTypeGuards , {
296+ const state = new BuildState ( 'validate' , this , ctx , ctx . objExpr ( ) , this . typeGuards , {
308297 validation : 'strict' ,
298+ collectErrors : false ,
299+ rejectUnknownKeys : true ,
309300 } ) ;
310301 return state . build ( type , data ) ;
311302 } ) as ( data : unknown ) => data is T ;
0 commit comments