(path)
| 46 | * @returns {Set<string>} placeholder kinds present |
| 47 | */ |
| 48 | const getPresentKinds = (path) => { |
| 49 | const cached = presentKindsCache.get(path); |
| 50 | if (cached !== undefined) return cached; |
| 51 | /** @type {Set<string>} */ |
| 52 | const kinds = new Set(); |
| 53 | // `RegExp.exec` loop rather than `String.matchAll` (Node.js 12+) so this |
| 54 | // stays compatible with the supported Node.js 10 range. |
| 55 | REGEXP.lastIndex = 0; |
| 56 | /** @type {RegExpExecArray | null} */ |
| 57 | let m; |
| 58 | while ((m = REGEXP.exec(path)) !== null) { |
| 59 | const content = /** @type {string} */ (m[1]); |
| 60 | if (content.length + 2 === m[0].length) { |
| 61 | const cm = /^(\w+)(?::\w+)?(?::\w+)?$/.exec(content); |
| 62 | if (cm) kinds.add(cm[1]); |
| 63 | } |
| 64 | } |
| 65 | if (presentKindsCache.size >= PRESENT_KINDS_CACHE_MAX) { |
| 66 | presentKindsCache.clear(); |
| 67 | } |
| 68 | presentKindsCache.set(path, kinds); |
| 69 | return kinds; |
| 70 | }; |
| 71 | |
| 72 | /** @type {PathData["prepareId"]} */ |
| 73 | const prepareId = (id) => { |
no test coverage detected