-
-
Notifications
You must be signed in to change notification settings - Fork 56
Expand file tree
/
Copy pathplatform.ts
More file actions
128 lines (116 loc) 路 4.29 KB
/
Copy pathplatform.ts
File metadata and controls
128 lines (116 loc) 路 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { GetPlatformMetricsOptions, Machine, OS, PlatformMetrics } from './types.js'
import { runtime as jsRuntime, type JSRuntime } from './utils.js'
const loadNodeOS = async (jsRuntime: JSRuntime, g: typeof globalThis = globalThis) => {
return ['bun', 'deno', 'node'].includes(jsRuntime)
? await import('node:os')
: {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
cpus: typeof g.navigator?.hardwareConcurrency === 'number'
? () => {
return Array
.from(
{ length: (g.navigator as unknown as { hardwareConcurrency: number }).hardwareConcurrency },
() => ({ model: 'unknown', speed: -1 })
)
}
: () => ([]),
freemem: () => -1,
getPriority: () => -1,
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/no-deprecated
machine: typeof g.navigator?.platform === 'string'
? () => normalizeMachine(g.navigator.platform.split(' ')[1]) // eslint-disable-line @typescript-eslint/no-deprecated
: () => 'unknown',
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/no-deprecated
platform: typeof g.navigator?.platform === 'string'
? () => normalizeMachine(g.navigator.platform.split(' ')[0]) // eslint-disable-line @typescript-eslint/no-deprecated
: () => 'unknown',
release: () => 'unknown',
totalmem: typeof (g as unknown as { navigator?: { deviceMemory: number } }).navigator?.deviceMemory === 'number'
? () => (g as unknown as { navigator: { deviceMemory: number } }).navigator.deviceMemory * 2 ** 30
: () => -1,
}
}
/* eslint-disable */
const machineLookup: { [key: string]: Machine } = {
// @ts-ignore __proto__ makes the object null-prototyped and sets it in dictionary mode
__proto__: null,
ia32: "x32",
amd64: "x64",
x86_64: "x64",
}
/* eslint-enable */
/**
* @param machine - a value to normalize
* @returns normalized architecture
*/
export function normalizeMachine (machine?: unknown): Machine {
return typeof machine !== 'string' || machine.length === 0
? 'unknown'
: ((machine = machine.toLowerCase()) && (machineLookup[machine as Machine] ?? machine)) as Machine
}
const osLookup: Record<Lowercase<string>, OS> = {
// @ts-expect-error __proto__ makes the object null-prototyped and sets it in dictionary mode
__proto__: null,
windows: 'win32',
}
let cachedPlatformMetrics: null | PlatformMetrics = null
/**
* @param opts - Options object
* @returns platform metrics
*/
export async function getPlatformMetrics (opts: GetPlatformMetricsOptions = {}): Promise<PlatformMetrics> {
const {
g = globalThis,
runtime = jsRuntime,
useCache = true
} = opts
if (useCache && cachedPlatformMetrics !== null) {
return cachedPlatformMetrics
}
const userAgent = (g as unknown as { navigator?: { userAgent: string } }).navigator?.userAgent ?? ''
let cpuCores = -1
let cpuModel = 'unknown'
let cpuSpeed = -1
let osKernel = 'unknown'
let osType: OS = 'unknown'
let cpuMachine: Machine = 'unknown'
let priority: null | number = -1
let memoryTotal = -1
let memoryFree = -1
const nodeOs = await loadNodeOS(runtime, g)
try {
osType = normalizeOSType(nodeOs.platform())
cpuMachine = normalizeMachine(nodeOs.machine())
osKernel = nodeOs.release()
memoryTotal = nodeOs.totalmem()
memoryFree = nodeOs.freemem()
priority = nodeOs.getPriority()
cpuCores = nodeOs.cpus().length
if (cpuCores > 0) {
cpuModel = (nodeOs as unknown as { cpus: () => [{ model: string }, ...{ model: string }[]] }).cpus()[0].model
cpuSpeed = (nodeOs as unknown as { cpus: () => [{ speed: number }, ...{ speed: number }[]] }).cpus()[0].speed
}
} catch { /* ignore */ }
return (cachedPlatformMetrics = {
cpuCores,
cpuMachine,
cpuModel,
cpuSpeed,
memoryFree,
memoryTotal,
osKernel,
osType,
priority,
runtime,
userAgent
})
}
/**
* @param os - a value to normalize
* @returns normalized OS
*/
export function normalizeOSType (os?: unknown): OS {
return typeof os !== 'string' || os.length === 0
? 'unknown'
: ((os = os.toLowerCase()) && (osLookup[os as OS] ?? os)) as OS
}