@objectstack/core 1.0.1 → 1.0.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @objectstack/core
2
2
 
3
+ ## 1.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - @objectstack/spec@1.0.4
8
+
9
+ ## 1.0.3
10
+
11
+ ### Patch Changes
12
+
13
+ - fb2eabd: fix: resolve "process is not defined" runtime error in browser environments by adding safe environment detection and polyfills
14
+ - @objectstack/spec@1.0.3
15
+
16
+ ## 1.0.2
17
+
18
+ ### Patch Changes
19
+
20
+ - a0a6c85: Infrastructure and development tooling improvements
21
+
22
+ - Add changeset configuration for automated version management
23
+ - Add comprehensive GitHub Actions workflows (CI, CodeQL, linting, releases)
24
+ - Add development configuration files (.cursorrules, .github/prompts)
25
+ - Add documentation files (ARCHITECTURE.md, CONTRIBUTING.md, workflows docs)
26
+ - Update test script configuration in package.json
27
+ - Add @objectstack/cli to devDependencies for better development experience
28
+
29
+ - 109fc5b: Unified patch release to align all package versions.
30
+ - Updated dependencies [a0a6c85]
31
+ - Updated dependencies [109fc5b]
32
+ - @objectstack/spec@1.0.2
33
+
3
34
  ## 1.0.1
4
35
 
5
36
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"api-registry.d.ts","sourceRoot":"","sources":["../src/api-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAA4C;IACxD,OAAO,CAAC,SAAS,CAA8E;IAC/F,OAAO,CAAC,MAAM,CAAiF;IAG/F,OAAO,CAAC,UAAU,CAAuC;IACzD,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,YAAY,CAAuC;IAE3D,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;gBAGxB,MAAM,EAAE,MAAM,EACd,kBAAkB,GAAE,0BAAoC,EACxD,OAAO,GAAE,MAAgB;IAQ3B;;;;;OAKG;IACH,WAAW,CAAC,GAAG,EAAE,qBAAqB,GAAG,IAAI;IAiC7C;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAqBlC;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAmBrB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA8E3B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,WAAW;IAKnB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAInD;;;;OAIG;IACH,UAAU,IAAI,gBAAgB,EAAE;IAIhC;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,oBAAoB;IAsGxD;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS;IAKnF;;;;;;OAMG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QACjD,GAAG,EAAE,gBAAgB,CAAC;QACtB,QAAQ,EAAE,uBAAuB,CAAC;KACnC,GAAG,SAAS;IAkBb;;;;OAIG;IACH,WAAW,IAAI,eAAe;IAwC9B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,KAAK,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI;IA4B9C;;;;OAIG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACxC;IAsBD;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAezB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAStB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;CAGhC"}
1
+ {"version":3,"file":"api-registry.d.ts","sourceRoot":"","sources":["../src/api-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAA4C;IACxD,OAAO,CAAC,SAAS,CAA8E;IAC/F,OAAO,CAAC,MAAM,CAAiF;IAG/F,OAAO,CAAC,UAAU,CAAuC;IACzD,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,YAAY,CAAuC;IAE3D,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;gBAGxB,MAAM,EAAE,MAAM,EACd,kBAAkB,GAAE,0BAAoC,EACxD,OAAO,GAAE,MAAgB;IAQ3B;;;;;OAKG;IACH,WAAW,CAAC,GAAG,EAAE,qBAAqB,GAAG,IAAI;IAiC7C;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAqBlC;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAmBrB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA8E3B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,WAAW;IAKnB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAInD;;;;OAIG;IACH,UAAU,IAAI,gBAAgB,EAAE;IAIhC;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,oBAAoB;IAsGxD;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS;IAKnF;;;;;;OAMG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QACjD,GAAG,EAAE,gBAAgB,CAAC;QACtB,QAAQ,EAAE,uBAAuB,CAAC;KACnC,GAAG,SAAS;IAkBb;;;;OAIG;IACH,WAAW,IAAI,eAAe;IAwC9B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,KAAK,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI;IA4B9C;;;;OAIG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACxC;IAsBD;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAezB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAStB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;CAGhC"}
@@ -1,4 +1,5 @@
1
1
  import { ApiRegistryEntrySchema } from '@objectstack/spec/api';
2
+ import { getEnv } from './utils/env.js';
2
3
  /**
3
4
  * API Registry Service
4
5
  *
@@ -594,6 +595,6 @@ export class ApiRegistry {
594
595
  * @internal
595
596
  */
596
597
  isProductionEnvironment() {
597
- return process.env.NODE_ENV === 'production';
598
+ return getEnv('NODE_ENV') === 'production';
598
599
  }
599
600
  }
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ export * from './api-registry.js';
14
14
  export * from './api-registry-plugin.js';
15
15
  export * as QA from './qa/index.js';
16
16
  export * from './security/index.js';
17
+ export * from './utils/env.js';
17
18
  export * from './health-monitor.js';
18
19
  export * from './hot-reload.js';
19
20
  export * from './dependency-resolver.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,eAAe,CAAC;AAGpC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AAGzC,YAAY,EACR,MAAM,EACN,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,eAAe,EAClB,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,eAAe,CAAC;AAGpC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AAGzC,YAAY,EACR,MAAM,EACN,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,eAAe,EAClB,MAAM,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -15,6 +15,8 @@ export * from './api-registry-plugin.js';
15
15
  export * as QA from './qa/index.js';
16
16
  // Export security utilities
17
17
  export * from './security/index.js';
18
+ // Export environment utilities
19
+ export * from './utils/env.js';
18
20
  // Export Phase 2 components - Advanced lifecycle management
19
21
  export * from './health-monitor.js';
20
22
  export * from './hot-reload.js';
@@ -1 +1 @@
1
- {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../src/kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAgC,gBAAgB,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAEzH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/B,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA2E;IACxF,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,MAAM,GAAE,kBAAuB;IAoF3C;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxC;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI;IAUlD;;OAEG;IACH,sBAAsB,CAAC,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,SAAS,GAAE,gBAA6C,EACxD,YAAY,CAAC,EAAE,MAAM,EAAE,GACxB,IAAI;IAUP;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAwClC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDhC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC/B;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAWxD;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvC;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAI9B;;OAEG;IACG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,MAAM;YAMJ,qBAAqB;YAerB,sBAAsB;YA6CtB,sBAAsB;YAkBtB,eAAe;IA2B7B,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,uBAAuB;IA2B/B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGjD"}
1
+ {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../src/kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAgC,gBAAgB,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAGzH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/B,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA2E;IACxF,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,MAAM,GAAE,kBAAuB;IAoF3C;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxC;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI;IAUlD;;OAEG;IACH,sBAAsB,CAAC,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,SAAS,GAAE,gBAA6C,EACxD,YAAY,CAAC,EAAE,MAAM,EAAE,GACxB,IAAI;IAUP;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAwClC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDhC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC/B;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAWxD;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvC;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAI9B;;OAEG;IACG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,MAAM;YAMJ,qBAAqB;YAerB,sBAAsB;YA6CtB,sBAAsB;YAkBtB,eAAe;IA2B7B,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,uBAAuB;IA6B/B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGjD"}
package/dist/kernel.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from './logger.js';
2
2
  import { ServiceRequirementDef } from '@objectstack/spec/system';
3
3
  import { PluginLoader, ServiceLifecycle } from './plugin-loader.js';
4
+ import { isNode, safeExit } from './utils/env.js';
4
5
  /**
5
6
  * Enhanced ObjectKernel with Advanced Plugin Management
6
7
  *
@@ -449,15 +450,17 @@ export class ObjectKernel {
449
450
  this.logger.info(`Received ${signal} - initiating graceful shutdown`);
450
451
  try {
451
452
  await this.shutdown();
452
- process.exit(0);
453
+ safeExit(0);
453
454
  }
454
455
  catch (error) {
455
456
  this.logger.error('Shutdown failed', error);
456
- process.exit(1);
457
+ safeExit(1);
457
458
  }
458
459
  };
459
- for (const signal of signals) {
460
- process.on(signal, () => handleShutdown(signal));
460
+ if (isNode) {
461
+ for (const signal of signals) {
462
+ process.on(signal, () => handleShutdown(signal));
463
+ }
461
464
  }
462
465
  }
463
466
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,MAAM;IACvC,OAAO,CAAC,MAAM,CAAkJ;IAChK,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,YAAY,CAAC,CAAM;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAM;gBAEV,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAwB9C;;OAEG;IACH,OAAO,CAAC,cAAc;IAuGtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQxD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBnG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBnG;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY;IAYjD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;IAIzD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAEzE"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,MAAM;IACvC,OAAO,CAAC,MAAM,CAAkJ;IAChK,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,YAAY,CAAC,CAAM;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAM;gBAEV,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAwB9C;;OAEG;IACH,OAAO,CAAC,cAAc;IAuGtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQxD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBnG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBnG;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY;IAYjD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;IAIzD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAEzE"}
package/dist/logger.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { isNode } from './utils/env.js';
1
2
  /**
2
3
  * Universal Logger Implementation
3
4
  *
@@ -16,7 +17,7 @@
16
17
  export class ObjectLogger {
17
18
  constructor(config = {}) {
18
19
  // Detect runtime environment
19
- this.isNode = typeof process !== 'undefined' && process.versions?.node !== undefined;
20
+ this.isNode = isNode;
20
21
  // Set defaults
21
22
  this.config = {
22
23
  name: config.name,
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-runtime.d.ts","sourceRoot":"","sources":["../../src/security/sandbox-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,GAAG,EAAE;QACH,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAe;IAG7B,OAAO,CAAC,SAAS,CAAqC;IAGtD,OAAO,CAAC,mBAAmB,CAAqC;gBAEpD,MAAM,EAAE,YAAY;IAIhC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,cAAc;IA+BtE;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IActC;;OAEG;IACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,EACpD,YAAY,CAAC,EAAE,MAAM,GACpB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA0BxC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAiDvB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAwD1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG;QACrC,YAAY,EAAE,OAAO,CAAC;QACtB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB;IAiCD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAK7D;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAS/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAiC3B;;OAEG;IACH,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI9C;;OAEG;IACH,QAAQ,IAAI,IAAI;CAUjB"}
1
+ {"version":3,"file":"sandbox-runtime.d.ts","sourceRoot":"","sources":["../../src/security/sandbox-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,GAAG,EAAE;QACH,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAe;IAG7B,OAAO,CAAC,SAAS,CAAqC;IAGtD,OAAO,CAAC,mBAAmB,CAAqC;gBAEpD,MAAM,EAAE,YAAY;IAIhC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,cAAc;IA+BtE;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IActC;;OAEG;IACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,EACpD,YAAY,CAAC,EAAE,MAAM,GACpB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA0BxC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAiDvB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAwD1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG;QACrC,YAAY,EAAE,OAAO,CAAC;QACtB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB;IAiCD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAK7D;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAS/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAiC3B;;OAEG;IACH,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI9C;;OAEG;IACH,QAAQ,IAAI,IAAI;CAUjB"}
@@ -1,3 +1,4 @@
1
+ import { getMemoryUsage } from '../utils/env.js';
1
2
  /**
2
3
  * Plugin Sandbox Runtime
3
4
  *
@@ -274,7 +275,7 @@ export class PluginSandboxRuntime {
274
275
  // For now, this is a placeholder structure
275
276
  // Update memory usage (global process memory - not per-plugin)
276
277
  // TODO: Implement per-plugin memory tracking
277
- const memoryUsage = process.memoryUsage();
278
+ const memoryUsage = getMemoryUsage();
278
279
  context.resourceUsage.memory.current = memoryUsage.heapUsed;
279
280
  context.resourceUsage.memory.peak = Math.max(context.resourceUsage.memory.peak, memoryUsage.heapUsed);
280
281
  // Update CPU usage (would use process.cpuUsage() or similar)
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Environment utilities for universal (Node/Browser) compatibility.
3
+ */
4
+ export declare const isNode: boolean;
5
+ /**
6
+ * Safely access environment variables
7
+ */
8
+ export declare function getEnv(key: string, defaultValue?: string): string | undefined;
9
+ /**
10
+ * Safely exit the process if in Node.js
11
+ */
12
+ export declare function safeExit(code?: number): void;
13
+ /**
14
+ * Safely get memory usage
15
+ */
16
+ export declare function getMemoryUsage(): {
17
+ heapUsed: number;
18
+ heapTotal: number;
19
+ };
20
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,MAAM,SAEgC,CAAC;AAEpD;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmB7E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,GAAE,MAAU,GAAG,IAAI,CAI/C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAKxE"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Environment utilities for universal (Node/Browser) compatibility.
3
+ */
4
+ // Check if running in a Node.js environment
5
+ export const isNode = typeof process !== 'undefined' &&
6
+ process.versions != null &&
7
+ process.versions.node != null;
8
+ /**
9
+ * Safely access environment variables
10
+ */
11
+ export function getEnv(key, defaultValue) {
12
+ // Node.js
13
+ if (typeof process !== 'undefined' && process.env) {
14
+ return process.env[key] || defaultValue;
15
+ }
16
+ // Browser (Vite/Webpack replacement usually handles process.env,
17
+ // but if not, we check safe global access)
18
+ try {
19
+ // @ts-ignore
20
+ if (typeof globalThis !== 'undefined' && globalThis.process?.env) {
21
+ // @ts-ignore
22
+ return globalThis.process.env[key] || defaultValue;
23
+ }
24
+ }
25
+ catch (e) {
26
+ // Ignore access errors
27
+ }
28
+ return defaultValue;
29
+ }
30
+ /**
31
+ * Safely exit the process if in Node.js
32
+ */
33
+ export function safeExit(code = 0) {
34
+ if (isNode) {
35
+ process.exit(code);
36
+ }
37
+ }
38
+ /**
39
+ * Safely get memory usage
40
+ */
41
+ export function getMemoryUsage() {
42
+ if (isNode) {
43
+ return process.memoryUsage();
44
+ }
45
+ return { heapUsed: 0, heapTotal: 0 };
46
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=env.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.test.d.ts","sourceRoot":"","sources":["../../src/utils/env.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import * as envUtils from './env';
3
+ describe('Environment Utilities', () => {
4
+ // Save original process
5
+ const originalProcess = globalThis.process;
6
+ afterEach(() => {
7
+ // Restore process after each test
8
+ globalThis.process = originalProcess;
9
+ vi.restoreAllMocks();
10
+ });
11
+ describe('isNode', () => {
12
+ it('should detect Node environment', () => {
13
+ // Since we are running in Vitest (Node), this should be true
14
+ expect(envUtils.isNode).toBe(true);
15
+ });
16
+ });
17
+ describe('getEnv', () => {
18
+ it('should retrieve environment variable in Node', () => {
19
+ process.env.TEST_VAR = 'test_value';
20
+ expect(envUtils.getEnv('TEST_VAR')).toBe('test_value');
21
+ delete process.env.TEST_VAR;
22
+ });
23
+ it('should return default value if variable not found', () => {
24
+ expect(envUtils.getEnv('NON_EXISTENT_VAR', 'default')).toBe('default');
25
+ });
26
+ it('should access globalThis.process.env if process is not available directly', () => {
27
+ // This is tricky to test in Node because 'process' is globally available.
28
+ // We can't easily delete global.process in strict mode or without breaking tooling.
29
+ // But we can verify it works via globalThis
30
+ // @ts-ignore
31
+ globalThis.process.env.TEST_GLOBAL_VAR = 'global_value';
32
+ expect(envUtils.getEnv('TEST_GLOBAL_VAR')).toBe('global_value');
33
+ // @ts-ignore
34
+ delete globalThis.process.env.TEST_GLOBAL_VAR;
35
+ });
36
+ });
37
+ describe('getMemoryUsage', () => {
38
+ it('should return memory usage in Node', () => {
39
+ const usage = envUtils.getMemoryUsage();
40
+ expect(usage).toHaveProperty('heapUsed');
41
+ expect(usage).toHaveProperty('heapTotal');
42
+ expect(usage.heapUsed).toBeGreaterThan(0);
43
+ });
44
+ });
45
+ describe('safeExit', () => {
46
+ it('should call process.exit in Node', () => {
47
+ const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => { }));
48
+ envUtils.safeExit(1);
49
+ expect(exitSpy).toHaveBeenCalledWith(1);
50
+ });
51
+ });
52
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/core",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Microkernel Core for ObjectStack",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  "pino": "^8.17.0",
16
16
  "pino-pretty": "^10.3.0",
17
17
  "zod": "^4.3.6",
18
- "@objectstack/spec": "1.0.1"
18
+ "@objectstack/spec": "1.0.4"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "pino": "^8.0.0"
@@ -9,6 +9,7 @@ import type {
9
9
  } from '@objectstack/spec/api';
10
10
  import { ApiRegistryEntrySchema } from '@objectstack/spec/api';
11
11
  import type { Logger } from '@objectstack/spec/contracts';
12
+ import { getEnv } from './utils/env.js';
12
13
 
13
14
  /**
14
15
  * API Registry Service
@@ -731,6 +732,6 @@ export class ApiRegistry {
731
732
  * @internal
732
733
  */
733
734
  private isProductionEnvironment(): boolean {
734
- return process.env.NODE_ENV === 'production';
735
+ return getEnv('NODE_ENV') === 'production';
735
736
  }
736
737
  }
package/src/index.ts CHANGED
@@ -18,6 +18,9 @@ export * as QA from './qa/index.js';
18
18
  // Export security utilities
19
19
  export * from './security/index.js';
20
20
 
21
+ // Export environment utilities
22
+ export * from './utils/env.js';
23
+
21
24
  // Export Phase 2 components - Advanced lifecycle management
22
25
  export * from './health-monitor.js';
23
26
  export * from './hot-reload.js';
package/src/kernel.ts CHANGED
@@ -3,6 +3,7 @@ import { createLogger, ObjectLogger } from './logger.js';
3
3
  import type { LoggerConfig } from '@objectstack/spec/system';
4
4
  import { ServiceRequirementDef } from '@objectstack/spec/system';
5
5
  import { PluginLoader, PluginMetadata, ServiceLifecycle, ServiceFactory, PluginStartupResult } from './plugin-loader.js';
6
+ import { isNode, safeExit } from './utils/env.js';
6
7
 
7
8
  /**
8
9
  * Enhanced Kernel Configuration
@@ -556,15 +557,17 @@ export class ObjectKernel {
556
557
 
557
558
  try {
558
559
  await this.shutdown();
559
- process.exit(0);
560
+ safeExit(0);
560
561
  } catch (error) {
561
562
  this.logger.error('Shutdown failed', error as Error);
562
- process.exit(1);
563
+ safeExit(1);
563
564
  }
564
565
  };
565
566
 
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
+ }
568
571
  }
569
572
  }
570
573
 
package/src/logger.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { LoggerConfig, LogLevel } from '@objectstack/spec/system';
2
2
  import type { Logger } from '@objectstack/spec/contracts';
3
+ import { isNode } from './utils/env.js';
3
4
 
4
5
  /**
5
6
  * Universal Logger Implementation
@@ -25,7 +26,7 @@ export class ObjectLogger implements Logger {
25
26
 
26
27
  constructor(config: Partial<LoggerConfig> = {}) {
27
28
  // Detect runtime environment
28
- this.isNode = typeof process !== 'undefined' && process.versions?.node !== undefined;
29
+ this.isNode = isNode;
29
30
 
30
31
  // Set defaults
31
32
  this.config = {
@@ -2,6 +2,7 @@ import type {
2
2
  SandboxConfig
3
3
  } from '@objectstack/spec/kernel';
4
4
  import type { ObjectLogger } from '../logger.js';
5
+ import { getMemoryUsage } from '../utils/env.js';
5
6
 
6
7
  /**
7
8
  * Resource Usage Statistics
@@ -387,7 +388,7 @@ export class PluginSandboxRuntime {
387
388
 
388
389
  // Update memory usage (global process memory - not per-plugin)
389
390
  // TODO: Implement per-plugin memory tracking
390
- const memoryUsage = process.memoryUsage();
391
+ const memoryUsage = getMemoryUsage();
391
392
  context.resourceUsage.memory.current = memoryUsage.heapUsed;
392
393
  context.resourceUsage.memory.peak = Math.max(
393
394
  context.resourceUsage.memory.peak,
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import * as envUtils from './env';
3
+
4
+ describe('Environment Utilities', () => {
5
+
6
+ // Save original process
7
+ const originalProcess = globalThis.process;
8
+
9
+ afterEach(() => {
10
+ // Restore process after each test
11
+ globalThis.process = originalProcess;
12
+ vi.restoreAllMocks();
13
+ });
14
+
15
+ describe('isNode', () => {
16
+ it('should detect Node environment', () => {
17
+ // Since we are running in Vitest (Node), this should be true
18
+ expect(envUtils.isNode).toBe(true);
19
+ });
20
+ });
21
+
22
+ describe('getEnv', () => {
23
+ it('should retrieve environment variable in Node', () => {
24
+ process.env.TEST_VAR = 'test_value';
25
+ expect(envUtils.getEnv('TEST_VAR')).toBe('test_value');
26
+ delete process.env.TEST_VAR;
27
+ });
28
+
29
+ it('should return default value if variable not found', () => {
30
+ expect(envUtils.getEnv('NON_EXISTENT_VAR', 'default')).toBe('default');
31
+ });
32
+
33
+ it('should access globalThis.process.env if process is not available directly', () => {
34
+ // This is tricky to test in Node because 'process' is globally available.
35
+ // We can't easily delete global.process in strict mode or without breaking tooling.
36
+ // But we can verify it works via globalThis
37
+
38
+ // @ts-ignore
39
+ globalThis.process.env.TEST_GLOBAL_VAR = 'global_value';
40
+ expect(envUtils.getEnv('TEST_GLOBAL_VAR')).toBe('global_value');
41
+ // @ts-ignore
42
+ delete globalThis.process.env.TEST_GLOBAL_VAR;
43
+ });
44
+ });
45
+
46
+ describe('getMemoryUsage', () => {
47
+ it('should return memory usage in Node', () => {
48
+ const usage = envUtils.getMemoryUsage();
49
+ expect(usage).toHaveProperty('heapUsed');
50
+ expect(usage).toHaveProperty('heapTotal');
51
+ expect(usage.heapUsed).toBeGreaterThan(0);
52
+ });
53
+ });
54
+
55
+ describe('safeExit', () => {
56
+ it('should call process.exit in Node', () => {
57
+ const exitSpy = vi.spyOn(process, 'exit').mockImplementation((() => {}) as any);
58
+ envUtils.safeExit(1);
59
+ expect(exitSpy).toHaveBeenCalledWith(1);
60
+ });
61
+ });
62
+ });
@@ -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
+ }