Skip to content

Commit 81fc1cc

Browse files
anonrigMesteeryVoltrexKeyva
committed
lib: add navigator.hardwareConcurrency
Co-authored-by: Mestery <mestery@protonmail.com> Co-authored-by: Voltrex <mohammadkeyvanzade94@gmail.com>
1 parent fdf8ecd commit 81fc1cc

File tree

9 files changed

+90
-0
lines changed

9 files changed

+90
-0
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ module.exports = {
327327
DecompressionStream: 'readable',
328328
fetch: 'readable',
329329
FormData: 'readable',
330+
navigator: 'readable',
330331
ReadableStream: 'readable',
331332
ReadableStreamDefaultReader: 'readable',
332333
ReadableStreamBYOBReader: 'readable',

doc/api/globals.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,32 @@ The `MessagePort` class. See [`MessagePort`][] for more details.
583583

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

586+
## `navigator`
587+
588+
<!-- YAML
589+
added: REPLACEME
590+
-->
591+
592+
> Stability: 1 - Experimental
593+
>
594+
> An implementation of the [Navigator API][]. Similar to [`window.navigator`][]
595+
> in browsers.
596+
597+
### `navigator.hardwareConcurrency`
598+
599+
<!-- YAML
600+
added: REPLACEME
601+
-->
602+
603+
* {number}
604+
605+
The navigator.hardwareConcurrency read-only property returns the number of
606+
logical processors available to run threads on the user's computer.
607+
608+
```js
609+
console.log(`This process is running on ${navigator.hardwareConcurrency}`);
610+
```
611+
586612
## `PerformanceEntry`
587613

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

9991025
[CommonJS module]: modules.md
10001026
[ECMAScript module]: esm.md
1027+
[Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
10011028
[Web Crypto API]: webcrypto.md
10021029
[`--no-experimental-fetch`]: cli.md#--no-experimental-fetch
10031030
[`--no-experimental-global-customevent`]: cli.md#--no-experimental-global-customevent
@@ -1057,6 +1084,7 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][].
10571084
[`setInterval`]: timers.md#setintervalcallback-delay-args
10581085
[`setTimeout`]: timers.md#settimeoutcallback-delay-args
10591086
[`structuredClone`]: https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
1087+
[`window.navigator`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
10601088
[buffer section]: buffer.md
10611089
[built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
10621090
[module system documentation]: modules.md

lib/.eslintrc.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ rules:
7575
message: Use `const { MessageEvent } = require('internal/worker/io');` instead of the global.
7676
- name: MessagePort
7777
message: Use `const { MessagePort } = require('internal/worker/io');` instead of the global.
78+
- name: Navigator
79+
message: Use `const navigator = require('internal/navigator');` instead of the global.
7880
- name: PerformanceEntry
7981
message: Use `const { PerformanceEntry } = require('perf_hooks');` instead of the global.
8082
- name: PerformanceMark

lib/internal/bootstrap/node.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,15 @@ defineLazyProperties(
224224
['structuredClone'],
225225
);
226226

227+
// https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
228+
ObjectDefineProperty(globalThis, 'navigator', {
229+
__proto__: null,
230+
enumerable: true,
231+
configurable: true,
232+
writable: false,
233+
value: require('internal/navigator'),
234+
});
235+
227236
// Set the per-Environment callback that will be called
228237
// when the TrackingTraceStateObserver updates trace state.
229238
// Note that when NODE_USE_V8_PLATFORM is true, the observer is

lib/internal/navigator.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
3+
const {
4+
ObjectDefineProperties,
5+
} = primordials;
6+
7+
const {
8+
kEnumerableProperty,
9+
} = require('internal/util');
10+
11+
const {
12+
getAvailableParallelism,
13+
} = internalBinding('os');
14+
15+
class Navigator {
16+
/**
17+
* @return {number}
18+
*/
19+
get hardwareConcurrency() {
20+
return getAvailableParallelism();
21+
}
22+
}
23+
24+
ObjectDefineProperties(Navigator.prototype, {
25+
hardwareConcurrency: kEnumerableProperty,
26+
});
27+
28+
module.exports = new Navigator();

test/common/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ if (global.gc) {
309309
knownGlobals.push(global.gc);
310310
}
311311

312+
if (global.navigator) {
313+
knownGlobals.push(global.navigator);
314+
}
315+
312316
if (global.Performance) {
313317
knownGlobals.push(global.Performance);
314318
}

test/parallel/test-bootstrap-modules.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const expectedModules = new Set([
4646
'NativeModule async_hooks',
4747
'NativeModule internal/process/task_queues',
4848
'NativeModule timers',
49+
'Internal Binding os',
50+
'NativeModule internal/navigator',
4951
'Internal Binding trace_events',
5052
'NativeModule internal/constants',
5153
'NativeModule path',

test/parallel/test-global.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ builtinModules.forEach((moduleName) => {
4949
'clearImmediate',
5050
'clearInterval',
5151
'clearTimeout',
52+
'navigator',
5253
'atob',
5354
'btoa',
5455
'performance',

test/parallel/test-navigator.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
6+
const is = {
7+
number: (value, key) => {
8+
assert(!Number.isNaN(value), `${key} should not be NaN`);
9+
assert.strictEqual(typeof value, 'number');
10+
},
11+
};
12+
13+
is.number(+navigator.hardwareConcurrency, 'hardwareConcurrency');
14+
is.number(navigator.hardwareConcurrency, 'hardwareConcurrency');
15+
assert.ok(navigator.hardwareConcurrency > 0);

0 commit comments

Comments
 (0)