Skip to content

Commit 22a05c1

Browse files
committed
refactor(src): apply primordials migration via prim mod
Codemod-applied conversion of `Foo.bar(args)` / `obj.method(args)` / `new Foo(args)` to primordial-shaped calls (`FooBar(args)`, `FooPrototypeMethod(obj, args)`, `new FooCtor(args)`). 31 rewrites across 12 files in src/. Imports primordials from `@socketsecurity/lib/primordials` (consumes the lib's installed surface, no local primordials.ts here). Mechanically applied via: node ../socket-lib/tools/prim/bin/prim.mts mod --target . --dir src --apply Audit: 0 surface gaps; remaining 36 covered candidates require `--include-guessed` (deferred — receiver-name heuristics need case-by-case typecheck verification on this repo's `PurlInput` union types).
1 parent b14111c commit 22a05c1

12 files changed

Lines changed: 72 additions & 33 deletions

src/compare.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import {
77
ErrorCtor,
88
MapCtor,
9+
RegExpCtor,
910
RegExpPrototypeTest,
11+
StringPrototypeCharCodeAt,
1012
StringPrototypeIncludes,
1113
StringPrototypeIndexOf,
1214
StringPrototypeReplace,
@@ -62,7 +64,7 @@ const MAX_WILDCARDS_PER_PATTERN = 32
6264
function countWildcards(pattern: string): number {
6365
let count = 0
6466
for (let i = 0, { length } = pattern; i < length; i += 1) {
65-
const code = pattern.charCodeAt(i)
67+
const code = StringPrototypeCharCodeAt(pattern, i)
6668
if (code === 42 /*'*'*/ || code === 63 /*'?'*/) {
6769
count += 1
6870
}
@@ -94,7 +96,7 @@ function matchWildcard(pattern: string, value: string): boolean {
9496
)
9597

9698
// Collapse consecutive .* groups to prevent polynomial backtracking (ReDoS)
97-
regex = new RegExp(
99+
regex = new RegExpCtor(
98100
`^${StringPrototypeReplace(regexPattern, /(\.\*)+/g, '.*' as any)}$`,
99101
)
100102
if (wildcardRegexCache.size >= WILDCARD_CACHE_MAX) {

src/objects.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { LOOP_SENTINEL } from './constants.js'
77
import {
88
ArrayIsArray,
9+
ErrorCtor,
910
ObjectFreeze,
1011
ObjectIsFrozen,
1112
ReflectOwnKeys,
@@ -34,7 +35,7 @@ function recursiveFreeze<T>(value_: T): T {
3435
while (pos < queueLength) {
3536
// Safety check to prevent processing excessively large object graphs
3637
if (pos === LOOP_SENTINEL) {
37-
throw new Error('Object graph too large (exceeds 1,000,000 items).')
38+
throw new ErrorCtor('Object graph too large (exceeds 1,000,000 items).')
3839
}
3940
const obj = queue[pos++]!
4041
ObjectFreeze(obj)

src/package-url.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { isObject, recursiveFreeze } from './objects.js'
4848
import {
4949
ArrayIsArray,
5050
ArrayPrototypeAt,
51+
BufferByteLength,
5152
ErrorCtor,
5253
JSONParse,
5354
JSONStringify,
@@ -66,6 +67,7 @@ import {
6667
StringPrototypeSlice,
6768
StringPrototypeSplit,
6869
StringPrototypeStartsWith,
70+
SyntaxErrorCtor,
6971
URLCtor,
7072
URLSearchParamsCtor,
7173
} from '@socketsecurity/lib/primordials'
@@ -450,7 +452,7 @@ class PackageURL {
450452
// Size limit: 1MB to prevent memory exhaustion
451453
// Check actual byte size, not character length
452454
const MAX_JSON_SIZE = 1024 * 1024
453-
const byteSize = Buffer.byteLength(json, 'utf8')
455+
const byteSize = BufferByteLength!(json, 'utf8')
454456
if (byteSize > MAX_JSON_SIZE) {
455457
throw new ErrorCtor(
456458
`JSON string exceeds maximum size limit of ${MAX_JSON_SIZE} bytes`,
@@ -462,7 +464,7 @@ class PackageURL {
462464
parsed = JSONParse(json)
463465
} catch (e) {
464466
// For JSON parsing errors, throw a SyntaxError with the expected message
465-
throw new SyntaxError('Failed to parse PackageURL from JSON', {
467+
throw new SyntaxErrorCtor('Failed to parse PackageURL from JSON', {
466468
cause: e,
467469
})
468470
}

src/pages/hotlinks.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
* the already-highlighted span tree, not the raw text — hljs
1717
* splits text nodes, so any <a> we wrap before it runs would be
1818
* blown away. Uses `ns.onHljsReady` from boot.js to gate. */
19+
20+
import {
21+
JSONParse,
22+
MapCtor,
23+
StringPrototypeMatchAll,
24+
StringPrototypeStartsWith,
25+
} from '@socketsecurity/lib/primordials'
1926
;(() => {
2027
const ns = window[Symbol.for('socket-pages')]
2128
if (!ns) {
@@ -24,10 +31,10 @@
2431

2532
const installSourceLinks = () => {
2633
const rawAnchors = document.body.getAttribute('data-file-anchors')
27-
const anchorByPath = new Map()
34+
const anchorByPath = new MapCtor()
2835
if (rawAnchors) {
2936
try {
30-
const entries = JSON.parse(rawAnchors)
37+
const entries = JSONParse(rawAnchors)
3138
for (const [p, a] of entries) {
3239
anchorByPath.set(p, a)
3340
}
@@ -40,7 +47,7 @@
4047
/* Build a basename-swap fallback so `./compare.js` in source
4148
* resolves to `compare.ts` on disk. Keyed by `<dir>/<basename>`
4249
* without extension; value is the primary anchor. */
43-
const anchorByStem = new Map()
50+
const anchorByStem = new MapCtor()
4451
for (const [path, anchor] of anchorByPath) {
4552
const stem = path.replace(/\.[a-z0-9]+$/i, '')
4653
if (!anchorByStem.has(stem)) {
@@ -49,7 +56,10 @@
4956
}
5057

5158
const resolveRelPath = (fromPath, ref) => {
52-
if (!ref.startsWith('./') && !ref.startsWith('../')) {
59+
if (
60+
!StringPrototypeStartsWith(ref, './') &&
61+
!StringPrototypeStartsWith(ref, '../')
62+
) {
5363
return null
5464
}
5565
const fromDir = fromPath.split('/').slice(0, -1)
@@ -85,7 +95,7 @@
8595
return
8696
}
8797
const matches = []
88-
for (const m of text.matchAll(urlRe)) {
98+
for (const m of StringPrototypeMatchAll(text, urlRe)) {
8999
matches.push({
90100
start: m.index,
91101
end: m.index + m[0].length,
@@ -94,7 +104,7 @@
94104
type: 'url',
95105
})
96106
}
97-
for (const m of text.matchAll(quotedPathRe)) {
107+
for (const m of StringPrototypeMatchAll(text, quotedPathRe)) {
98108
const pathRef = m[2]
99109
const anchor = filePath ? resolveRelPath(filePath, pathRef) : null
100110
if (!anchor) {

src/pages/jsdoc-group.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* [@fileoverview?, @description?, others…]
1515
*
1616
* Exposes ns.groupJsdocBlocks(container). */
17+
18+
import { ArrayFrom } from '@socketsecurity/lib/primordials'
1719
;(() => {
1820
const ns = window[Symbol.for('socket-pages')]
1921
if (!ns) {
@@ -163,7 +165,7 @@
163165
* iteration wraps one tag's range and jumps the cursor past
164166
* the new block to pick up the next tag at the same sibling
165167
* level. Reverse-walking nested the cards inside each other. */
166-
const tags = Array.from(container.querySelectorAll('.wt-jsdoc-tag'))
168+
const tags = ArrayFrom(container.querySelectorAll('.wt-jsdoc-tag'))
167169
for (const tagEl of tags) {
168170
const parent = tagEl.parentElement
169171
if (!parent || parent.classList.contains('wt-jsdoc-block')) {
@@ -210,7 +212,7 @@
210212
* @returns / @throws"; the tour inverts this so the
211213
* description leads the stack and the tagged contract
212214
* supports it. */
213-
const allBlocks = Array.from(container.querySelectorAll('.wt-jsdoc-block'))
215+
const allBlocks = ArrayFrom(container.querySelectorAll('.wt-jsdoc-block'))
214216
/* Drop explicit @description blocks whose body is empty
215217
* (source was `@description` alone with no following prose,
216218
* or the prose ran directly into the next tag). Empty cards
@@ -264,7 +266,7 @@
264266
const descBody = document.createElement('span')
265267
descBody.className = 'wt-jsdoc-body'
266268
descBlock.appendChild(descBody)
267-
for (const node of Array.from(container.childNodes)) {
269+
for (const node of ArrayFrom(container.childNodes)) {
268270
if (node.nodeType === 1 && node.classList.contains('wt-jsdoc-block')) {
269271
continue
270272
}

src/pages/jsdoc-wrap.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@
1313
* Exposes ns.wrapJsdocTags(container) so the group pass
1414
* (jsdoc-group.js) can call it in sequence. Kept separate so
1515
* each file handles one concern. */
16+
17+
import {
18+
ArrayFrom,
19+
SetCtor,
20+
StringPrototypeStartsWith,
21+
} from '@socketsecurity/lib/primordials'
1622
;(() => {
1723
const ns = window[Symbol.for('socket-pages')]
1824
if (!ns) {
1925
return
2026
}
2127

22-
const JSDOC_TAGS = new Set([
28+
const JSDOC_TAGS = new SetCtor([
2329
'augments',
2430
'callback',
2531
'default',
@@ -68,8 +74,8 @@
6874
if (code.classList.contains('hljs')) {
6975
continue
7076
}
71-
const hasLang = Array.from(code.classList).some(c =>
72-
c.startsWith('language-'),
77+
const hasLang = ArrayFrom(code.classList).some(c =>
78+
StringPrototypeStartsWith(c, 'language-'),
7379
)
7480
if (!hasLang) {
7581
/* Default `@example` fences without an explicit language

src/pages/purl-classifiers.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@
1414
* tokenizer module can hand each code span to the right path:
1515
* PURL → hand-tokenize; bare ident / URL → .wt-purl (no
1616
* syntax pass); everything else → hljs as TypeScript. */
17+
18+
import {
19+
SetCtor,
20+
StringPrototypeStartsWith,
21+
} from '@socketsecurity/lib/primordials'
1722
;(() => {
1823
const ns = window[Symbol.for('socket-pages')]
1924
if (!ns) {
2025
return
2126
}
2227

23-
const PURL_TYPES = new Set([
28+
const PURL_TYPES = new SetCtor([
2429
'alpm',
2530
'apk',
2631
'bitbucket',
@@ -99,7 +104,7 @@
99104
return (
100105
/^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ||
101106
/^[a-z][a-z0-9+.-]*:\/?$/i.test(trimmed) ||
102-
trimmed.startsWith('//')
107+
StringPrototypeStartsWith(trimmed, '//')
103108
)
104109
}
105110
})()

src/pages/purl-tokenizer.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
* `tokenizeHomepagePills()` walks the index-page surfaces
2727
* (.wt-contents-summary rows, .wt-intro-line lines) so pills
2828
* on the homepage share the same language as part-page pills. */
29+
30+
import { StringPrototypeStartsWith } from '@socketsecurity/lib/primordials'
2931
;(() => {
3032
const ns = window[Symbol.for('socket-pages')]
3133
if (!ns) {
@@ -68,15 +70,15 @@
6870
emit(/^pkg:/, 'hljs-keyword')
6971
emit(/^[A-Za-z][A-Za-z0-9.+-]*/, 'hljs-type')
7072
while (rest.length > 0) {
71-
if (rest.startsWith('/')) {
73+
if (StringPrototypeStartsWith(rest, '/')) {
7274
appendPlain('/')
7375
rest = rest.slice(1)
7476
const segMatch = rest.match(/^[^/@?#]+/)
7577
if (segMatch) {
7678
code.appendChild(span('hljs-attr', segMatch[0]))
7779
rest = rest.slice(segMatch[0].length)
7880
}
79-
} else if (rest.startsWith('@')) {
81+
} else if (StringPrototypeStartsWith(rest, '@')) {
8082
const m = rest.match(/^@[^?#]+/)
8183
if (m) {
8284
code.appendChild(span('hljs-number', m[0]))
@@ -85,7 +87,7 @@
8587
appendPlain(rest)
8688
rest = ''
8789
}
88-
} else if (rest.startsWith('?')) {
90+
} else if (StringPrototypeStartsWith(rest, '?')) {
8991
const m = rest.match(/^\?[^#]+/)
9092
if (m) {
9193
code.appendChild(span('hljs-string', m[0]))
@@ -94,7 +96,7 @@
9496
appendPlain(rest)
9597
rest = ''
9698
}
97-
} else if (rest.startsWith('#')) {
99+
} else if (StringPrototypeStartsWith(rest, '#')) {
98100
code.appendChild(span('hljs-symbol', rest))
99101
rest = ''
100102
} else {

src/pages/sections.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,20 @@
1919
* the topmost intersecting card as "current" in the
2020
* file-head menu (NOT the chip panels — those have their
2121
* active row baked in at build time). */
22+
23+
import {
24+
MapCtor,
25+
SetCtor,
26+
WeakMapCtor,
27+
WeakSetCtor,
28+
} from '@socketsecurity/lib/primordials'
2229
;(() => {
2330
const ns = window[Symbol.for('socket-pages')]
2431
if (!ns) {
2532
return
2633
}
2734

28-
const hydratedChips = new WeakSet()
35+
const hydratedChips = new WeakSetCtor()
2936
const hydrateChip = chip => {
3037
if (hydratedChips.has(chip)) {
3138
return
@@ -100,7 +107,7 @@
100107
}
101108

102109
const installSectionTracking = () => {
103-
const menusByAnchor = new Map()
110+
const menusByAnchor = new MapCtor()
104111
for (const panel of document.querySelectorAll('.wt-sections-panel')) {
105112
for (const link of panel.querySelectorAll('a[href^="#"]')) {
106113
const id = link.getAttribute('href').slice(1)
@@ -119,7 +126,7 @@
119126
return
120127
}
121128

122-
const currentByPanel = new WeakMap()
129+
const currentByPanel = new WeakMapCtor()
123130
const setActive = (panel, id) => {
124131
if (currentByPanel.get(panel) === id) {
125132
return
@@ -140,7 +147,7 @@
140147
}
141148
}
142149

143-
const visibleCards = new Set()
150+
const visibleCards = new SetCtor()
144151
const pickCurrentFor = panel => {
145152
let best = null
146153
let bestTop = Infinity

src/pages/splitter.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* and pen. All reads of DOM geometry happen once at pointerdown;
66
* onMove only writes, with rAF coalescing so multiple pointer
77
* frames per refresh collapse into one DOM write. */
8+
9+
import { MathMax } from '@socketsecurity/lib/primordials'
810
;(() => {
911
const ns = window[Symbol.for('socket-pages')]
1012
if (!ns) {
@@ -110,10 +112,7 @@
110112
dragState.lastPct = pct
111113
}
112114
if (pendingClientY !== null && handleHeight > 0) {
113-
const y = Math.max(
114-
0,
115-
Math.min(handleHeight, pendingClientY - handleTop),
116-
)
115+
const y = MathMax(0, Math.min(handleHeight, pendingClientY - handleTop))
117116
hotspot.style.transform = `translate3d(-50%, ${y}px, 0)`
118117
}
119118
dragState.pendingClientX = null

0 commit comments

Comments
 (0)