@@ -11,6 +11,7 @@ var class_constructors: std.StringHashMap(napi.napi_value) = std.StringHashMap(n
1111
1212pub fn ClassWrapper (comptime T : type , comptime HasInit : bool ) type {
1313 const type_info = @typeInfo (T );
14+
1415 if (type_info != .@"struct" ) {
1516 @compileError ("Class() only support struct type" );
1617 }
@@ -143,9 +144,31 @@ pub fn ClassWrapper(comptime T: type, comptime HasInit: bool) type {
143144 }
144145 }
145146
147+ // Helper function to check if a declaration is a const field
148+ fn isConstDecl (comptime decl_name : []const u8 ) bool {
149+ if (! @hasDecl (T , decl_name )) return false ;
150+ const decl_type = @TypeOf (@field (T , decl_name ));
151+ const decl_type_info = @typeInfo (decl_type );
152+ // Check if it's not a function and not a type
153+ return decl_type_info != .@"fn" and decl_type_info != .type ;
154+ }
155+
156+ // Count const declarations at compile time
157+ fn countConstDecls () usize {
158+ var count : usize = 0 ;
159+ for (decls ) | decl | {
160+ if (comptime isConstDecl (decl .name )) {
161+ count += 1 ;
162+ }
163+ }
164+ return count ;
165+ }
166+
146167 fn define_class (env : napi.napi_env ) ! napi.napi_value {
168+ // Count instance properties and methods
147169 comptime var property_count : usize = fields .len ;
148170
171+ // Count methods
149172 inline for (decls ) | decl | {
150173 const decl_type = @TypeOf (@field (T , decl .name ));
151174 if (@typeInfo (decl_type ) == .@"fn" ) {
@@ -158,9 +181,14 @@ pub fn ClassWrapper(comptime T: type, comptime HasInit: bool) type {
158181 }
159182 }
160183
161- var properties : [property_count ]napi.napi_property_descriptor = undefined ;
184+ // Add const declarations count
185+ const const_count = comptime countConstDecls ();
186+ const total_property_count = comptime property_count + const_count ;
187+
188+ var properties : [total_property_count ]napi.napi_property_descriptor = undefined ;
162189 var prop_idx : usize = 0 ;
163190
191+ // Process instance fields
164192 inline for (fields ) | field | {
165193 const FieldAccessor = struct {
166194 fn getter (getter_env : napi.napi_env , info : napi.napi_callback_info ) callconv (.c ) napi.napi_value {
@@ -203,6 +231,45 @@ pub fn ClassWrapper(comptime T: type, comptime HasInit: bool) type {
203231 prop_idx += 1 ;
204232 }
205233
234+ // Process const declarations as static value properties
235+ // Following napi-rs pattern: use value field with static attribute
236+ inline for (decls ) | decl | {
237+ if (comptime isConstDecl (decl .name )) {
238+ const const_value = @field (T , decl .name );
239+
240+ // Create a static value property descriptor
241+ // The value is converted at define_class time
242+ const StaticValueHolder = struct {
243+ var cached_value : ? napi.napi_value = null ;
244+
245+ fn getValue (holder_env : napi.napi_env ) napi.napi_value {
246+ if (cached_value ) | val | {
247+ return val ;
248+ }
249+ const val = Napi .to_napi_value (holder_env , const_value , decl .name ) catch return null ;
250+ cached_value = val ;
251+ return val ;
252+ }
253+ };
254+
255+ // Get the static value
256+ const static_value = StaticValueHolder .getValue (env );
257+
258+ properties [prop_idx ] = napi.napi_property_descriptor {
259+ .utf8name = @ptrCast (decl .name .ptr ),
260+ .name = null ,
261+ .method = null ,
262+ .getter = null ,
263+ .setter = null ,
264+ .value = static_value ,
265+ .attributes = napi .napi_static | napi .napi_enumerable ,
266+ .data = null ,
267+ };
268+ prop_idx += 1 ;
269+ }
270+ }
271+
272+ // Process methods
206273 inline for (decls ) | decl | {
207274 const decl_type = @TypeOf (@field (T , decl .name ));
208275 if (@typeInfo (decl_type ) == .@"fn" ) {
0 commit comments