Skip to content

Commit

Permalink
lib: add navigator.hardwareConcurrency
Browse files Browse the repository at this point in the history
Co-authored-by: Mestery <[email protected]>
Co-authored-by: Voltrex <[email protected]>
  • Loading branch information
3 people committed Jun 3, 2023
1 parent fdf8ecd commit 81fc1cc
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ module.exports = {
DecompressionStream: 'readable',
fetch: 'readable',
FormData: 'readable',
navigator: 'readable',
ReadableStream: 'readable',
ReadableStreamDefaultReader: 'readable',
ReadableStreamBYOBReader: 'readable',
Expand Down
28 changes: 28 additions & 0 deletions doc/api/globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,32 @@ The `MessagePort` class. See [`MessagePort`][] for more details.

This variable may appear to be global but is not. See [`module`][].

## `navigator`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
>
> An implementation of the [Navigator API][]. Similar to [`window.navigator`][]
> in browsers.
### `navigator.hardwareConcurrency`

<!-- YAML
added: REPLACEME
-->

* {number}

The navigator.hardwareConcurrency read-only property returns the number of
logical processors available to run threads on the user's computer.

```js
console.log(`This process is running on ${navigator.hardwareConcurrency}`);
```

## `PerformanceEntry`

<!-- YAML
Expand Down Expand Up @@ -998,6 +1024,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].

[CommonJS module]: modules.md
[ECMAScript module]: esm.md
[Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
[Web Crypto API]: webcrypto.md
[`--no-experimental-fetch`]: cli.md#--no-experimental-fetch
[`--no-experimental-global-customevent`]: cli.md#--no-experimental-global-customevent
Expand Down Expand Up @@ -1057,6 +1084,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
[`setInterval`]: timers.md#setintervalcallback-delay-args
[`setTimeout`]: timers.md#settimeoutcallback-delay-args
[`structuredClone`]: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
[`window.navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
[buffer section]: buffer.md
[built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
[module system documentation]: modules.md
Expand Down
2 changes: 2 additions & 0 deletions lib/.eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ rules:
message: Use `const { MessageEvent } = require('internal/worker/io');` instead of the global.
- name: MessagePort
message: Use `const { MessagePort } = require('internal/worker/io');` instead of the global.
- name: Navigator
message: Use `const navigator = require('internal/navigator');` instead of the global.
- name: PerformanceEntry
message: Use `const { PerformanceEntry } = require('perf_hooks');` instead of the global.
- name: PerformanceMark
Expand Down
9 changes: 9 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ defineLazyProperties(
['structuredClone'],
);

// https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
ObjectDefineProperty(globalThis, 'navigator', {
__proto__: null,
enumerable: true,
configurable: true,
writable: false,
value: require('internal/navigator'),
});

// Set the per-Environment callback that will be called
// when the TrackingTraceStateObserver updates trace state.
// Note that when NODE_USE_V8_PLATFORM is true, the observer is
Expand Down
28 changes: 28 additions & 0 deletions lib/internal/navigator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

const {
ObjectDefineProperties,
} = primordials;

const {
kEnumerableProperty,
} = require('internal/util');

const {
getAvailableParallelism,
} = internalBinding('os');

class Navigator {
/**
* @return {number}
*/
get hardwareConcurrency() {
return getAvailableParallelism();
}
}

ObjectDefineProperties(Navigator.prototype, {
hardwareConcurrency: kEnumerableProperty,
});

module.exports = new Navigator();
4 changes: 4 additions & 0 deletions test/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ if (global.gc) {
knownGlobals.push(global.gc);
}

if (global.navigator) {
knownGlobals.push(global.navigator);
}

if (global.Performance) {
knownGlobals.push(global.Performance);
}
Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const expectedModules = new Set([
'NativeModule async_hooks',
'NativeModule internal/process/task_queues',
'NativeModule timers',
'Internal Binding os',
'NativeModule internal/navigator',
'Internal Binding trace_events',
'NativeModule internal/constants',
'NativeModule path',
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-global.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ builtinModules.forEach((moduleName) => {
'clearImmediate',
'clearInterval',
'clearTimeout',
'navigator',
'atob',
'btoa',
'performance',
Expand Down
15 changes: 15 additions & 0 deletions test/parallel/test-navigator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

require('../common');
const assert = require('assert');

const is = {
number: (value, key) => {
assert(!Number.isNaN(value), `${key} should not be NaN`);
assert.strictEqual(typeof value, 'number');
},
};

is.number(+navigator.hardwareConcurrency, 'hardwareConcurrency');
is.number(navigator.hardwareConcurrency, 'hardwareConcurrency');
assert.ok(navigator.hardwareConcurrency > 0);

0 comments on commit 81fc1cc

Please sign in to comment.