Skip to content

Commit 13e6a5d

Browse files
committed
feat: add environment utilities for Node and Browser compatibility
1 parent d4a594f commit 13e6a5d

6 files changed

Lines changed: 67 additions & 8 deletions

File tree

packages/core/src/api-registry.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
} from '@objectstack/spec/api';
1010
import { ApiRegistryEntrySchema } from '@objectstack/spec/api';
1111
import type { Logger } from '@objectstack/spec/contracts';
12+
import { getEnv } from './utils/env.js';
1213

1314
/**
1415
* API Registry Service
@@ -731,6 +732,6 @@ export class ApiRegistry {
731732
* @internal
732733
*/
733734
private isProductionEnvironment(): boolean {
734-
return process.env.NODE_ENV === 'production';
735+
return getEnv('NODE_ENV') === 'production';
735736
}
736737
}

packages/core/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export * as QA from './qa/index.js';
1818
// Export security utilities
1919
export * from './security/index.js';
2020

21+
// Export environment utilities
22+
export * from './utils/env.js';
23+
2124
// Export Phase 2 components - Advanced lifecycle management
2225
export * from './health-monitor.js';
2326
export * from './hot-reload.js';

packages/core/src/kernel.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createLogger, ObjectLogger } from './logger.js';
33
import type { LoggerConfig } from '@objectstack/spec/system';
44
import { ServiceRequirementDef } from '@objectstack/spec/system';
55
import { PluginLoader, PluginMetadata, ServiceLifecycle, ServiceFactory, PluginStartupResult } from './plugin-loader.js';
6+
import { isNode, safeExit } from './utils/env.js';
67

78
/**
89
* Enhanced Kernel Configuration
@@ -556,15 +557,17 @@ export class ObjectKernel {
556557

557558
try {
558559
await this.shutdown();
559-
process.exit(0);
560+
safeExit(0);
560561
} catch (error) {
561562
this.logger.error('Shutdown failed', error as Error);
562-
process.exit(1);
563+
safeExit(1);
563564
}
564565
};
565566

566-
for (const signal of signals) {
567-
process.on(signal, () => handleShutdown(signal));
567+
if (isNode) {
568+
for (const signal of signals) {
569+
process.on(signal, () => handleShutdown(signal));
570+
}
568571
}
569572
}
570573

packages/core/src/security/sandbox-runtime.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type {
22
SandboxConfig
33
} from '@objectstack/spec/kernel';
44
import type { ObjectLogger } from '../logger.js';
5+
import { getMemoryUsage } from '../utils/env.js';
56

67
/**
78
* Resource Usage Statistics
@@ -387,7 +388,7 @@ export class PluginSandboxRuntime {
387388

388389
// Update memory usage (global process memory - not per-plugin)
389390
// TODO: Implement per-plugin memory tracking
390-
const memoryUsage = process.memoryUsage();
391+
const memoryUsage = getMemoryUsage();
391392
context.resourceUsage.memory.current = memoryUsage.heapUsed;
392393
context.resourceUsage.memory.peak = Math.max(
393394
context.resourceUsage.memory.peak,

packages/core/src/utils/env.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Environment utilities for universal (Node/Browser) compatibility.
3+
*/
4+
5+
// Check if running in a Node.js environment
6+
export const isNode = typeof process !== 'undefined' &&
7+
process.versions != null &&
8+
process.versions.node != null;
9+
10+
/**
11+
* Safely access environment variables
12+
*/
13+
export function getEnv(key: string, defaultValue?: string): string | undefined {
14+
// Node.js
15+
if (typeof process !== 'undefined' && process.env) {
16+
return process.env[key] || defaultValue;
17+
}
18+
19+
// Browser (Vite/Webpack replacement usually handles process.env,
20+
// but if not, we check safe global access)
21+
try {
22+
// @ts-ignore
23+
if (typeof globalThis !== 'undefined' && globalThis.process?.env) {
24+
// @ts-ignore
25+
return globalThis.process.env[key] || defaultValue;
26+
}
27+
} catch (e) {
28+
// Ignore access errors
29+
}
30+
31+
return defaultValue;
32+
}
33+
34+
/**
35+
* Safely exit the process if in Node.js
36+
*/
37+
export function safeExit(code: number = 0): void {
38+
if (isNode) {
39+
process.exit(code);
40+
}
41+
}
42+
43+
/**
44+
* Safely get memory usage
45+
*/
46+
export function getMemoryUsage(): { heapUsed: number; heapTotal: number } {
47+
if (isNode) {
48+
return process.memoryUsage();
49+
}
50+
return { heapUsed: 0, heapTotal: 0 };
51+
}

packages/runtime/src/http-dispatcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ObjectKernel } from '@objectstack/core';
1+
import { ObjectKernel, getEnv } from '@objectstack/core';
22
import { CoreServiceName } from '@objectstack/spec/system';
33

44
export interface HttpProtocolContext {
@@ -60,7 +60,7 @@ export class HttpDispatcher {
6060
return {
6161
name: 'ObjectOS',
6262
version: '1.0.0',
63-
environment: process.env.NODE_ENV || 'development',
63+
environment: getEnv('NODE_ENV', 'development'),
6464
routes: {
6565
data: `${prefix}/data`,
6666
metadata: `${prefix}/metadata`,

0 commit comments

Comments
 (0)