@@ -150,7 +150,24 @@ const TYPE_BY_STATE_KEY: Record<keyof Omit<MetadataState, 'loading' | 'error'>,
150150const SESSION_STORAGE_PREFIX = 'objectui:metadata:' ;
151151
152152/** Dev-only debug logger — silenced in production builds. */
153- const DEV = typeof process !== 'undefined' && process . env && process . env . NODE_ENV !== 'production' ;
153+ // Vite replaces `import.meta.env.MODE` at build time. Fall back to `process.env`
154+ // for non-Vite runtimes (Node-based vitest, SSR) where `import.meta.env` is
155+ // undefined. Wrapped in try/catch so a missing global never breaks rendering.
156+ function isDev ( ) : boolean {
157+ try {
158+ const meta : any = ( import . meta as any ) ;
159+ if ( meta && meta . env && typeof meta . env . MODE === 'string' ) {
160+ return meta . env . MODE !== 'production' ;
161+ }
162+ } catch {
163+ /* import.meta unavailable — fall through */
164+ }
165+ if ( typeof process !== 'undefined' && process . env && typeof process . env . NODE_ENV === 'string' ) {
166+ return process . env . NODE_ENV !== 'production' ;
167+ }
168+ return false ;
169+ }
170+ const DEV = isDev ( ) ;
154171function debug ( ...args : unknown [ ] ) {
155172 if ( DEV ) {
156173 // eslint-disable-next-line no-console
@@ -179,6 +196,16 @@ function extractItem(res: unknown): any | null {
179196 return res ;
180197}
181198
199+ /** Type guard for metadata items that carry a string `name` identifier. */
200+ function isNamedItem ( item : unknown ) : item is { name : string } {
201+ return (
202+ ! ! item &&
203+ typeof item === 'object' &&
204+ 'name' in item &&
205+ typeof ( item as { name : unknown } ) . name === 'string'
206+ ) ;
207+ }
208+
182209/** Build an empty cache entry for a type. */
183210function emptyEntry ( ) : TypeCacheEntry {
184211 return {
@@ -278,8 +305,8 @@ export function MetadataProvider({ children, adapter, ttlMs = DEFAULT_TTL_MS }:
278305 // Hydrate per-name cache so subsequent getItem() calls hit memory.
279306 entry . byName . clear ( ) ;
280307 for ( const it of items ) {
281- if ( it && typeof it === 'object' && 'name' in it && typeof ( it as any ) . name === 'string' ) {
282- entry . byName . set ( ( it as any ) . name , it ) ;
308+ if ( isNamedItem ( it ) ) {
309+ entry . byName . set ( it . name , it ) ;
283310 }
284311 }
285312 if ( type === 'app' ) saveToSession ( type , items ) ;
@@ -422,7 +449,7 @@ export function MetadataProvider({ children, adapter, ttlMs = DEFAULT_TTL_MS }:
422449 entry . status = 'ready' ;
423450 entry . fetchedAt = 0 ; // mark as stale so a background refresh fires
424451 for ( const it of cached ) {
425- if ( it && typeof it === 'object' && typeof it . name === 'string' ) {
452+ if ( isNamedItem ( it ) ) {
426453 entry . byName . set ( it . name , it ) ;
427454 }
428455 }
0 commit comments