-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.ts
More file actions
145 lines (138 loc) · 5.12 KB
/
util.ts
File metadata and controls
145 lines (138 loc) · 5.12 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* @fileoverview Smol detection + lazy-loader for `node:smol-util`.
*
* Two responsibilities:
*
* 1. `isSmol()` — memoized boolean detector for socket-btm's smol
* Node binary. Mirrors `isSeaBinary()` from `src/sea.ts`. Probes
* via `node:module.isBuiltin('node:smol-util')` since only the
* smol binary registers any `node:smol-*` builtins.
*
* 2. `getSmolUtil()` — lazy-loader for the `node:smol-util` binding,
* which provides native `uncurryThis` and `applyBind` (single
* V8 dispatch via `args.Data()` + `v8::Function::Call`, skipping
* the BoundFunction adapter + `Function.prototype.call` trampoline
* that the JS form `bind.bind(call)(fn)` hits twice per invocation).
* ~2x faster on hot uncurried-call sites.
*
* `getSmolUtil()` returns `undefined` on stock Node + non-Node
* runtimes. Result is cached across calls; the lazy-loader follows
* the same shape as `src/node/fs.ts` etc.
*
* @see https://github.com/SocketDev/socket-btm — socket-btm builds
* the smol binary that exposes the `node:smol-util` binding.
*/
// ─── isSmol ────────────────────────────────────────────────────────────
/**
* Cached smol-binary detection result.
*/
let _isSmol: boolean | undefined
/**
* Detect if the current process is running on socket-btm's smol Node
* binary. Memoized on first call.
*
* Defensive across runtimes: returns `false` on stock Node, browsers
* (no `node:module`), Deno / Bun (different module resolution), and
* worker threads (each has its own builtin table).
*
* @example
* ```ts
* import { isSmol } from '@socketsecurity/lib/smol/util'
*
* if (isSmol()) {
* // running on the smol binary; native fast paths available
* }
* ```
*/
export function isSmol(): boolean {
if (_isSmol === undefined) {
try {
// eslint-disable-next-line n/prefer-node-protocol
const mod = require('node:module') as {
isBuiltin?: (name: string) => boolean
}
_isSmol =
typeof mod.isBuiltin === 'function' && mod.isBuiltin('node:smol-util')
} catch {
// Not Node, or `node:module` unavailable.
_isSmol = false
}
}
return _isSmol ?? false
}
// ─── getSmolUtil ───────────────────────────────────────────────────────
/**
* Surface of `node:smol-util`. See socket-btm's
* additions/source-patched/lib/smol-util.js for the canonical shape.
*/
export interface SmolUtilBinding {
/**
* Native equivalent of `Function.prototype.bind.bind(apply)(fn)`.
*/
applyBind: <T, A extends readonly unknown[], R>(
fn: (this: T, ...args: A) => R,
) => (self: T, args: A) => R
/**
* Native equivalent of:
* `(self, args) => { try { return fn.apply(self, args) } catch {} }`.
* Returns a function that swallows synchronous throws and returns
* `undefined`. Avoids JS-level throw construction on the swallow
* path — useful for logger sinks, debug hooks, abort handlers, etc.
*/
applySafe: <T, A extends readonly unknown[], R>(
fn: (this: T, ...args: A) => R,
) => (self: T, args: A) => R | undefined
/**
* Native equivalent of:
* `(...newArgs) => fn.call(thisArg, ...presetArgs, ...newArgs)`.
* Same shape as `Function.prototype.bind` but with a single C++
* dispatch instead of going through V8's BoundFunction adapter.
* Useful where `bind` would be hot — captured callbacks fed to
* `setImmediate`/`setTimeout`/promise continuations.
*/
bindCall: <T, P extends readonly unknown[], A extends readonly unknown[], R>(
fn: (this: T, ...args: [...P, ...A]) => R,
thisArg: T,
...presetArgs: P
) => (...newArgs: A) => R
/**
* Native equivalent of `Function.prototype.bind.bind(call)(fn)`.
* Single C++ dispatch via `args.Data()` + `v8::Function::Call`.
*/
uncurryThis: <T, A extends readonly unknown[], R>(
fn: (this: T, ...args: A) => R,
) => (self: T, ...args: A) => R
/**
* Native equivalent of:
* `try { return new WeakRef(target) } catch { return undefined }`.
* Returns `undefined` for non-Object, non-Symbol inputs that would
* make the constructor throw. The Safe suffix follows the project's
* non-throwing-wrapper convention.
*/
weakRefSafe: <T extends object | symbol>(target: T) => WeakRef<T> | undefined
}
/**
* Cached `node:smol-util` binding. `null` = probed and unavailable;
* `undefined` = not yet probed. JS truthiness collapses both to "no
* binding" at the call site.
*/
let _smolUtil: SmolUtilBinding | null | undefined
/**
* Returns `node:smol-util` when running on the smol Node binary,
* otherwise `undefined`. Result is cached across calls.
*/
/*@__NO_SIDE_EFFECTS__*/
export function getSmolUtil(): SmolUtilBinding | undefined {
if (_smolUtil === undefined) {
if (isSmol()) {
try {
_smolUtil = require('node:smol-util') as SmolUtilBinding
} catch {
_smolUtil = null
}
} else {
_smolUtil = null
}
}
return _smolUtil ?? undefined
}