@plebeiantech/lat.md 0.12.3-fork.17 → 0.12.3-fork.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/src/cli/agent-invocation.d.ts +6 -0
- package/dist/src/cli/agent-invocation.js +23 -0
- package/dist/src/cli/fork-instructions.js +1 -1
- package/dist/src/cli/fork-scaffold.js +2 -2
- package/dist/src/cli/graph.d.ts +1 -1
- package/dist/src/cli/hook.js +11 -11
- package/dist/src/cli/index.js +41 -59
- package/dist/src/cli/init-preferences.js +5 -4
- package/dist/src/cli/init.d.ts +1 -1
- package/dist/src/cli/init.js +54 -45
- package/dist/src/cli/reindex.d.ts +1 -1
- package/dist/src/cli/reindex.js +2 -2
- package/dist/src/cli/search.d.ts +4 -4
- package/dist/src/cli/search.js +41 -28
- package/dist/src/cli/ui-build-server.d.ts +1 -1
- package/dist/src/cli/ui-build.d.ts +1 -1
- package/dist/src/cli/ui.d.ts +1 -1
- package/dist/src/fork/antigravity-hook.js +6 -6
- package/dist/src/fork/antigravity-init.d.ts +2 -2
- package/dist/src/fork/antigravity-init.js +2 -2
- package/dist/src/graph-export.js +7 -7
- package/dist/src/knowledge/index.js +2 -2
- package/dist/src/mcp/server.js +8 -8
- package/dist/src/search/cache.d.ts +1 -1
- package/dist/src/search/cache.js +40 -7
- package/dist/src/search/chunks.d.ts +2 -2
- package/dist/src/search/db.d.ts +5 -4
- package/dist/src/search/db.js +36 -40
- package/dist/src/search/embedder.js +1 -1
- package/dist/src/search/index.d.ts +1 -1
- package/dist/src/search/index.js +2 -2
- package/dist/src/search/lock.d.ts +4 -1
- package/dist/src/search/lock.js +30 -8
- package/dist/src/search/query.d.ts +5 -2
- package/dist/src/search/query.js +55 -38
- package/dist/src/search/search.d.ts +3 -1
- package/dist/src/search/search.js +21 -12
- package/dist/src/search/types.d.ts +2 -18
- package/dist/src/view/client/assets/{GraphView-BWlRdQM4.js → GraphView-Dij8mAA_.js} +1 -1
- package/dist/src/view/client/assets/{MarkdownEditor-MW-Ck1O0.js → MarkdownEditor-88Wbt0M1.js} +1 -1
- package/dist/src/view/client/assets/{abnfDiagram-VCTEODGH-Bn3RshMV.js → abnfDiagram-VCTEODGH-y0DlYa8E.js} +1 -1
- package/dist/src/view/client/assets/{arc-En9tdFQF.js → arc-FlMu8dnO.js} +1 -1
- package/dist/src/view/client/assets/{architectureDiagram-5GKGNRK7-B-9J1VAM.js → architectureDiagram-5GKGNRK7-DA_uWZW1.js} +1 -1
- package/dist/src/view/client/assets/{blockDiagram-I7D4REHJ-QlznwalP.js → blockDiagram-I7D4REHJ-BHQ5LU85.js} +1 -1
- package/dist/src/view/client/assets/{c4Diagram-7LVT6UL2-Bp2y8B4_.js → c4Diagram-7LVT6UL2-BRucKCt2.js} +1 -1
- package/dist/src/view/client/assets/channel-BgDNA_Ay.js +1 -0
- package/dist/src/view/client/assets/{chunk-2Q5K7J3B-CnBKL-lm.js → chunk-2Q5K7J3B-BJPcFivt.js} +1 -1
- package/dist/src/view/client/assets/{chunk-5VM5RSS4-LLYMi_n6.js → chunk-5VM5RSS4-v2q99bGz.js} +1 -1
- package/dist/src/view/client/assets/{chunk-F27PBJKO-VIeO7VF0.js → chunk-F27PBJKO-CcHOuJCs.js} +1 -1
- package/dist/src/view/client/assets/{chunk-IMKFNOWR-D5i67DVD.js → chunk-IMKFNOWR-DNxYuJNq.js} +1 -1
- package/dist/src/view/client/assets/{chunk-JWPE2WC7-D4qAtoL3.js → chunk-JWPE2WC7-C0eHKvLW.js} +1 -1
- package/dist/src/view/client/assets/{chunk-POPQ4Y6H-BMzOyiW_.js → chunk-POPQ4Y6H-57CWp2Ve.js} +1 -1
- package/dist/src/view/client/assets/{chunk-SVP7TREG-DWy5nbfp.js → chunk-SVP7TREG-BqcoxIJw.js} +1 -1
- package/dist/src/view/client/assets/{chunk-TICWLB2K-CVqCANFB.js → chunk-TICWLB2K-DRUJR5zH.js} +1 -1
- package/dist/src/view/client/assets/{chunk-XXDRQBXY-Bp23h6Tf.js → chunk-XXDRQBXY-Dez0oRoM.js} +1 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-CFZ_Sgh5.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-CFZ_Sgh5.js +1 -0
- package/dist/src/view/client/assets/{cose-bilkent-JH36ORCC-BCw7fCC2.js → cose-bilkent-JH36ORCC-BHtud6Hg.js} +1 -1
- package/dist/src/view/client/assets/{cynefin-OW5HDTMX--lYN4N9m.js → cynefin-OW5HDTMX-BjBW8VGk.js} +1 -1
- package/dist/src/view/client/assets/{cynefinDiagram-5FMLGOSQ-9sK5EV7v.js → cynefinDiagram-5FMLGOSQ-DwGuD7oF.js} +1 -1
- package/dist/src/view/client/assets/{dagre-GXQ25YYZ-CoMdEFCq.js → dagre-GXQ25YYZ-C5zSlGK9.js} +1 -1
- package/dist/src/view/client/assets/{diagram-S7CK7UJ4-D13dyWdd.js → diagram-S7CK7UJ4-C_NhA3bj.js} +1 -1
- package/dist/src/view/client/assets/{diagram-UQ7AKVKN-PdwLPPPA.js → diagram-UQ7AKVKN-az7QPYNb.js} +1 -1
- package/dist/src/view/client/assets/{diagram-VSXAHHWV-CtWWa_A7.js → diagram-VSXAHHWV-BRvDuM8_.js} +1 -1
- package/dist/src/view/client/assets/{diagram-VX7I27RA-BeCYcSU-.js → diagram-VX7I27RA-BWLgF6S-.js} +1 -1
- package/dist/src/view/client/assets/{diagram-Z3DM3KII-DiWabOBM.js → diagram-Z3DM3KII-DV3d6mL5.js} +1 -1
- package/dist/src/view/client/assets/{ebnfDiagram-PWID7BFC-CZQ3MD_K.js → ebnfDiagram-PWID7BFC-yUXrEAvK.js} +1 -1
- package/dist/src/view/client/assets/{erDiagram-RLTQ6QDP-B1AhXIrP.js → erDiagram-RLTQ6QDP-D35FN1Pt.js} +1 -1
- package/dist/src/view/client/assets/{flowDiagram-HODETNUW-Bhr0JM6P.js → flowDiagram-HODETNUW-BciZqsjT.js} +1 -1
- package/dist/src/view/client/assets/{ganttDiagram-EL5Y4UJY-CbP8iAkg.js → ganttDiagram-EL5Y4UJY-BysPGgXS.js} +1 -1
- package/dist/src/view/client/assets/{gitGraphDiagram-WWUBYQGX-B9uuGdLF.js → gitGraphDiagram-WWUBYQGX-C3DdJ5xG.js} +1 -1
- package/dist/src/view/client/assets/index-CJokoRSp.js +13 -0
- package/dist/src/view/client/assets/{infoDiagram-27XIBGKW-BrfwQ_Cq.js → infoDiagram-27XIBGKW-D3HZrDRb.js} +1 -1
- package/dist/src/view/client/assets/{ishikawaDiagram-5VMMS53U-CHtJ36re.js → ishikawaDiagram-5VMMS53U-BXyVIXTU.js} +1 -1
- package/dist/src/view/client/assets/{journeyDiagram-3NMN7TZE-BChcgX1s.js → journeyDiagram-3NMN7TZE-D4-1NxVU.js} +1 -1
- package/dist/src/view/client/assets/{kanban-definition-UXKFOSKX-BnwFsKiB.js → kanban-definition-UXKFOSKX-4Gu_5yBA.js} +1 -1
- package/dist/src/view/client/assets/{layout-Dnd0pLdb.js → layout-Jf1K3TMM.js} +1 -1
- package/dist/src/view/client/assets/{linear-CFhW2ozn.js → linear-DWfwzUT_.js} +1 -1
- package/dist/src/view/client/assets/{mermaid.core--OP6lXtW.js → mermaid.core-DMx_DAl8.js} +5 -5
- package/dist/src/view/client/assets/{mindmap-definition-YA3MSWOX-D51y2zbm.js → mindmap-definition-YA3MSWOX-8pxY_RWi.js} +1 -1
- package/dist/src/view/client/assets/{pegDiagram-XKGWAZYB--zyQJDvI.js → pegDiagram-XKGWAZYB-DNAw_O5t.js} +1 -1
- package/dist/src/view/client/assets/{pieDiagram-E7YTZNPT-Cj8mvpJy.js → pieDiagram-E7YTZNPT-uuvRCDkC.js} +1 -1
- package/dist/src/view/client/assets/{quadrantDiagram-AXDQQJYC-qvhJrnBf.js → quadrantDiagram-AXDQQJYC-BER2O4Aq.js} +1 -1
- package/dist/src/view/client/assets/{railroadDiagram-O6MQD6OU-CtWvxpSo.js → railroadDiagram-O6MQD6OU-CxEsJ_0n.js} +1 -1
- package/dist/src/view/client/assets/{requirementDiagram-BXWQKSXE-CBxen_KG.js → requirementDiagram-BXWQKSXE-yS9rspca.js} +1 -1
- package/dist/src/view/client/assets/{sankeyDiagram-P5KCCOFB-B_fUkmfc.js → sankeyDiagram-P5KCCOFB-Bqt70a2j.js} +1 -1
- package/dist/src/view/client/assets/{sequenceDiagram-WJ2MYXX4-Dclv4p68.js → sequenceDiagram-WJ2MYXX4-BvOOEJNr.js} +1 -1
- package/dist/src/view/client/assets/{sizeCapture-INFHLROL-GfG0sMTZ.js → sizeCapture-INFHLROL-CvO_Pjjo.js} +1 -1
- package/dist/src/view/client/assets/{stateDiagram-D77RDMKH-YQWPnzxU.js → stateDiagram-D77RDMKH-KLmVOZkq.js} +1 -1
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-KCS8Mdzu.js +1 -0
- package/dist/src/view/client/assets/{swimlanes-42K2YHIH-5yiCveVS.js → swimlanes-42K2YHIH-DC1r4_sq.js} +1 -1
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-B2TcAwis.js +8 -0
- package/dist/src/view/client/assets/{timeline-definition-24CTP7MA-BvAbB5Zs.js → timeline-definition-24CTP7MA-ChXLOuBL.js} +1 -1
- package/dist/src/view/client/assets/{vennDiagram-4TSXK5OY-guC-r60n.js → vennDiagram-4TSXK5OY-D9_h25-Y.js} +1 -1
- package/dist/src/view/client/assets/{wardleyDiagram-VM6X3IG4-C0yXcU2x.js → wardleyDiagram-VM6X3IG4-CsQJGGW0.js} +1 -1
- package/dist/src/view/client/assets/{xychartDiagram-S5SC5T6Z-RPmkPNfK.js → xychartDiagram-S5SC5T6Z-DGMuPMlm.js} +1 -1
- package/dist/src/view/client/index.html +1 -1
- package/dist/src/view/diagnostics.d.ts +2 -2
- package/dist/src/view/diagnostics.js +5 -5
- package/dist/src/view/external-document-tree.js +1 -1
- package/dist/src/view/git-diff.js +1 -1
- package/dist/src/view/git.js +1 -1
- package/dist/src/view/graph.d.ts +2 -2
- package/dist/src/view/graph.js +2 -2
- package/dist/src/view/markdown.js +1 -1
- package/dist/src/view/preindexed-search.d.ts +1 -1
- package/dist/src/view/protocol.d.ts +2 -18
- package/dist/src/view/publication.d.ts +2 -0
- package/dist/src/view/publication.js +78 -0
- package/dist/src/view/references.d.ts +3 -3
- package/dist/src/view/references.js +3 -3
- package/dist/src/view/repository.d.ts +6 -6
- package/dist/src/view/repository.js +28 -14
- package/dist/src/view/request-security.d.ts +5 -0
- package/dist/src/view/request-security.js +46 -0
- package/dist/src/view/search-result.d.ts +1 -1
- package/dist/src/view/search-result.js +1 -1
- package/dist/src/view/search.d.ts +1 -1
- package/dist/src/view/server-build.d.ts +2 -2
- package/dist/src/view/server-build.js +2 -2
- package/dist/src/view/server-deployment.d.ts +1 -2
- package/dist/src/view/server-deployment.js +6 -46
- package/dist/src/view/server-index-worker.d.ts +1 -1
- package/dist/src/view/server.d.ts +1 -1
- package/dist/src/view/server.js +13 -3
- package/dist/src/view/source-target.js +2 -2
- package/dist/src/view/static-build.d.ts +1 -1
- package/dist/src/view/static-build.js +49 -17
- package/dist/src/view/store.d.ts +4 -2
- package/dist/src/view/store.js +31 -19
- package/dist/src/view/table-of-contents.d.ts +1 -1
- package/dist/src/view/table-of-contents.js +1 -1
- package/dist/src/view/vercel-server-build.d.ts +1 -1
- package/package.json +19 -29
- package/templates/AGENTS.md +2 -2
- package/templates/cursor-rules.md +2 -2
- package/templates/opencode-plugin.ts +9 -9
- package/templates/pi-extension.ts +11 -11
- package/templates/skill/SKILL.md +2 -1
- package/dist/src/cli/check-context.d.ts +0 -56
- package/dist/src/cli/check-context.js +0 -215
- package/dist/src/cli/check-coverage.d.ts +0 -2
- package/dist/src/cli/check-coverage.js +0 -75
- package/dist/src/cli/check-frontmatter.d.ts +0 -12
- package/dist/src/cli/check-frontmatter.js +0 -44
- package/dist/src/cli/check-mode.d.ts +0 -21
- package/dist/src/cli/check-mode.js +0 -394
- package/dist/src/cli/check-status.d.ts +0 -74
- package/dist/src/cli/check-status.js +0 -217
- package/dist/src/cli/check.d.ts +0 -52
- package/dist/src/cli/check.js +0 -834
- package/dist/src/cli/context.d.ts +0 -11
- package/dist/src/cli/context.js +0 -58
- package/dist/src/cli/expand.d.ts +0 -7
- package/dist/src/cli/expand.js +0 -141
- package/dist/src/cli/external.d.ts +0 -11
- package/dist/src/cli/external.js +0 -185
- package/dist/src/cli/gen-index.d.ts +0 -45
- package/dist/src/cli/gen-index.js +0 -235
- package/dist/src/cli/link-scheme.d.ts +0 -54
- package/dist/src/cli/link-scheme.js +0 -101
- package/dist/src/cli/locate.d.ts +0 -2
- package/dist/src/cli/locate.js +0 -18
- package/dist/src/cli/refs.d.ts +0 -23
- package/dist/src/cli/refs.js +0 -274
- package/dist/src/cli/section.d.ts +0 -45
- package/dist/src/cli/section.js +0 -328
- package/dist/src/cli/select-menu.d.ts +0 -13
- package/dist/src/cli/select-menu.js +0 -100
- package/dist/src/code-refs.d.ts +0 -29
- package/dist/src/code-refs.js +0 -479
- package/dist/src/config.d.ts +0 -29
- package/dist/src/config.js +0 -83
- package/dist/src/context.d.ts +0 -26
- package/dist/src/context.js +0 -11
- package/dist/src/document-formats.d.ts +0 -7
- package/dist/src/document-formats.js +0 -39
- package/dist/src/extensions/alert-marker.d.ts +0 -25
- package/dist/src/extensions/alert-marker.js +0 -55
- package/dist/src/extensions/wiki-link/from-markdown.d.ts +0 -5
- package/dist/src/extensions/wiki-link/from-markdown.js +0 -34
- package/dist/src/extensions/wiki-link/index.d.ts +0 -4
- package/dist/src/extensions/wiki-link/index.js +0 -3
- package/dist/src/extensions/wiki-link/syntax.d.ts +0 -14
- package/dist/src/extensions/wiki-link/syntax.js +0 -121
- package/dist/src/extensions/wiki-link/to-markdown.d.ts +0 -5
- package/dist/src/extensions/wiki-link/to-markdown.js +0 -28
- package/dist/src/extensions/wiki-link/types.d.ts +0 -34
- package/dist/src/extensions/wiki-link/types.js +0 -1
- package/dist/src/external-documents.d.ts +0 -56
- package/dist/src/external-documents.js +0 -404
- package/dist/src/external-sources.d.ts +0 -136
- package/dist/src/external-sources.js +0 -1098
- package/dist/src/fork/frontmatter-fields.d.ts +0 -36
- package/dist/src/fork/frontmatter-fields.js +0 -23
- package/dist/src/format.d.ts +0 -16
- package/dist/src/format.js +0 -76
- package/dist/src/init-version.d.ts +0 -10
- package/dist/src/init-version.js +0 -49
- package/dist/src/lattice-model.d.ts +0 -84
- package/dist/src/lattice-model.js +0 -467
- package/dist/src/lattice.d.ts +0 -14
- package/dist/src/lattice.js +0 -353
- package/dist/src/markdown-analysis-cache.d.ts +0 -20
- package/dist/src/markdown-analysis-cache.js +0 -139
- package/dist/src/markdown-analysis-worker.d.ts +0 -16
- package/dist/src/markdown-analysis-worker.js +0 -33
- package/dist/src/markdown-analysis.d.ts +0 -61
- package/dist/src/markdown-analysis.js +0 -169
- package/dist/src/markdown-analyzer-loader.d.ts +0 -4
- package/dist/src/markdown-analyzer-loader.js +0 -13
- package/dist/src/markdown-validation.d.ts +0 -25
- package/dist/src/markdown-validation.js +0 -104
- package/dist/src/parser-cache.d.ts +0 -17
- package/dist/src/parser-cache.js +0 -65
- package/dist/src/parser-import.d.ts +0 -8
- package/dist/src/parser-import.js +0 -1
- package/dist/src/parser.d.ts +0 -3
- package/dist/src/parser.js +0 -93
- package/dist/src/path.d.ts +0 -2
- package/dist/src/path.js +0 -4
- package/dist/src/profiler.d.ts +0 -16
- package/dist/src/profiler.js +0 -81
- package/dist/src/project-analysis.d.ts +0 -59
- package/dist/src/project-analysis.js +0 -233
- package/dist/src/project-discovery.d.ts +0 -6
- package/dist/src/project-discovery.js +0 -30
- package/dist/src/repository-path.d.ts +0 -11
- package/dist/src/repository-path.js +0 -52
- package/dist/src/source-formats.d.ts +0 -7
- package/dist/src/source-formats.js +0 -30
- package/dist/src/source-parser.d.ts +0 -67
- package/dist/src/source-parser.js +0 -1749
- package/dist/src/untrusted.d.ts +0 -18
- package/dist/src/untrusted.js +0 -93
- package/dist/src/view/client/assets/channel-uy0fFvcW.js +0 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-DbSEqjA5.js +0 -1
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-DbSEqjA5.js +0 -1
- package/dist/src/view/client/assets/index-nBmbYfun.js +0 -13
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-gUj6Hzgl.js +0 -1
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-DR7JhrxL.js +0 -8
- package/dist/src/walk.d.ts +0 -20
- package/dist/src/walk.js +0 -121
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { performance } from 'node:perf_hooks';
|
|
2
|
-
import { relative } from 'node:path';
|
|
3
|
-
import { visit } from 'unist-util-visit';
|
|
4
|
-
import { extractLinks, extractRefs, parseFrontmatter, parseSections, } from './lattice.js';
|
|
5
|
-
import { parse } from './parser.js';
|
|
6
|
-
import { toPosix } from './path.js';
|
|
7
|
-
import { analyzeLocalMarkdownDiagnostics, } from './markdown-validation.js';
|
|
8
|
-
function extractBlocks(tree) {
|
|
9
|
-
const block = (node) => {
|
|
10
|
-
if (node.position?.start.offset === undefined ||
|
|
11
|
-
node.position?.end.offset === undefined)
|
|
12
|
-
return;
|
|
13
|
-
return {
|
|
14
|
-
type: node.type,
|
|
15
|
-
start: node.position.start.offset,
|
|
16
|
-
end: node.position.end.offset,
|
|
17
|
-
startLine: node.position.start.line,
|
|
18
|
-
endLine: node.position.end.line,
|
|
19
|
-
...('lang' in node && node.lang ? { language: node.lang } : {}),
|
|
20
|
-
children: [
|
|
21
|
-
'list',
|
|
22
|
-
'listItem',
|
|
23
|
-
'blockquote',
|
|
24
|
-
'table',
|
|
25
|
-
'tableRow',
|
|
26
|
-
].includes(node.type)
|
|
27
|
-
? ('children' in node ? node.children : [])
|
|
28
|
-
.map(block)
|
|
29
|
-
.filter((item) => !!item)
|
|
30
|
-
: [],
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
return tree.children
|
|
34
|
-
.map(block)
|
|
35
|
-
.filter((item) => !!item);
|
|
36
|
-
}
|
|
37
|
-
function elapsed(work) {
|
|
38
|
-
const start = performance.now();
|
|
39
|
-
return [work(), performance.now() - start];
|
|
40
|
-
}
|
|
41
|
-
function inlineText(node) {
|
|
42
|
-
if (node.type === 'wikiLink')
|
|
43
|
-
return node.data.alias ?? node.value;
|
|
44
|
-
if ('value' in node && typeof node.value === 'string')
|
|
45
|
-
return node.value;
|
|
46
|
-
if (node.type === 'image')
|
|
47
|
-
return node.alt ?? '';
|
|
48
|
-
if (!('children' in node) || !Array.isArray(node.children))
|
|
49
|
-
return '';
|
|
50
|
-
return node.children
|
|
51
|
-
.map((child) => inlineText(child))
|
|
52
|
-
.join('');
|
|
53
|
-
}
|
|
54
|
-
function extractParagraphs(content, tree) {
|
|
55
|
-
const result = [];
|
|
56
|
-
visit(tree, 'paragraph', (node) => {
|
|
57
|
-
const startLine = node.position?.start.line;
|
|
58
|
-
const endLine = node.position?.end.line;
|
|
59
|
-
if (!startLine || !endLine)
|
|
60
|
-
return;
|
|
61
|
-
const text = inlineText(node).replace(/\s+/g, ' ').trim();
|
|
62
|
-
const startOffset = node.position?.start.offset;
|
|
63
|
-
const endOffset = node.position?.end.offset;
|
|
64
|
-
result.push({
|
|
65
|
-
markdown: startOffset === undefined || endOffset === undefined
|
|
66
|
-
? text
|
|
67
|
-
: content.slice(startOffset, endOffset),
|
|
68
|
-
startLine,
|
|
69
|
-
endLine,
|
|
70
|
-
text,
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
function extractHeadingTitles(tree) {
|
|
76
|
-
const titles = [];
|
|
77
|
-
visit(tree, 'heading', (node) => {
|
|
78
|
-
titles.push(inlineText(node));
|
|
79
|
-
});
|
|
80
|
-
return titles;
|
|
81
|
-
}
|
|
82
|
-
function extractDestinationLinks(tree) {
|
|
83
|
-
const definitions = new Map();
|
|
84
|
-
visit(tree, 'definition', (node) => {
|
|
85
|
-
definitions.set(node.identifier.toLowerCase(), node.url);
|
|
86
|
-
});
|
|
87
|
-
const links = [];
|
|
88
|
-
visit(tree, (node) => {
|
|
89
|
-
if (node.type !== 'link' &&
|
|
90
|
-
node.type !== 'image' &&
|
|
91
|
-
node.type !== 'linkReference' &&
|
|
92
|
-
node.type !== 'imageReference') {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const line = node.position?.start.line;
|
|
96
|
-
if (!line)
|
|
97
|
-
return;
|
|
98
|
-
const url = node.type === 'link' || node.type === 'image'
|
|
99
|
-
? node.url
|
|
100
|
-
: definitions.get(node.identifier.toLowerCase());
|
|
101
|
-
if (!url)
|
|
102
|
-
return;
|
|
103
|
-
links.push({
|
|
104
|
-
kind: node.type === 'image' || node.type === 'imageReference'
|
|
105
|
-
? 'image'
|
|
106
|
-
: 'link',
|
|
107
|
-
line,
|
|
108
|
-
url,
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
return links;
|
|
112
|
-
}
|
|
113
|
-
function extractIndexEntries(content) {
|
|
114
|
-
const names = new Set();
|
|
115
|
-
const pattern = /^- \[\[([^\]]+?)(?:\|[^\]]+)?\]\]/gm;
|
|
116
|
-
let match;
|
|
117
|
-
while ((match = pattern.exec(content)) !== null)
|
|
118
|
-
names.add(match[1]);
|
|
119
|
-
return [...names];
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Parse and analyze one Markdown document. The syntax tree is deliberately
|
|
123
|
-
* confined to this call so callers and workers only exchange serializable facts.
|
|
124
|
-
*/
|
|
125
|
-
export function analyzeMarkdownFile(absolutePath, content, latDir, projectRoot) {
|
|
126
|
-
const [tree, parseMs] = elapsed(() => parse(content));
|
|
127
|
-
const [sections, sectionsMs] = elapsed(() => parseSections(absolutePath, content, projectRoot, tree));
|
|
128
|
-
const [wikiRefs, refsMs] = elapsed(() => extractRefs(absolutePath, content, projectRoot, tree, sections));
|
|
129
|
-
const [validationLinks, linksMs] = elapsed(() => extractLinks(content, tree));
|
|
130
|
-
const [[paragraphs, markdownLinks, headingTitles], paragraphsMs] = elapsed(() => [
|
|
131
|
-
extractParagraphs(content, tree),
|
|
132
|
-
extractDestinationLinks(tree),
|
|
133
|
-
extractHeadingTitles(tree),
|
|
134
|
-
]);
|
|
135
|
-
const [frontmatter, frontmatterMs] = elapsed(() => parseFrontmatter(content));
|
|
136
|
-
const [indexEntries, indexEntriesMs] = elapsed(() => extractIndexEntries(content));
|
|
137
|
-
const [diagnostics, diagnosticsMs] = elapsed(() => analyzeLocalMarkdownDiagnostics(validationLinks, sections));
|
|
138
|
-
return {
|
|
139
|
-
absolutePath,
|
|
140
|
-
content,
|
|
141
|
-
path: toPosix(relative(latDir, absolutePath)),
|
|
142
|
-
projectPath: toPosix(relative(projectRoot, absolutePath)),
|
|
143
|
-
frontmatter,
|
|
144
|
-
sections,
|
|
145
|
-
headingTitles,
|
|
146
|
-
wikiRefs,
|
|
147
|
-
paragraphs,
|
|
148
|
-
blocks: extractBlocks(tree),
|
|
149
|
-
markdownLinks,
|
|
150
|
-
validationLinks,
|
|
151
|
-
indexEntries,
|
|
152
|
-
diagnostics,
|
|
153
|
-
timings: {
|
|
154
|
-
readMs: 0,
|
|
155
|
-
hashMs: 0,
|
|
156
|
-
cacheReadMs: 0,
|
|
157
|
-
cacheWriteMs: 0,
|
|
158
|
-
cacheStatus: 'disabled',
|
|
159
|
-
parseMs,
|
|
160
|
-
sectionsMs,
|
|
161
|
-
refsMs,
|
|
162
|
-
linksMs,
|
|
163
|
-
paragraphsMs,
|
|
164
|
-
frontmatterMs,
|
|
165
|
-
indexEntriesMs,
|
|
166
|
-
diagnosticsMs,
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { analyzeMarkdownFile } from './markdown-analysis.js';
|
|
2
|
-
import type { ParserImportObserver } from './parser-import.js';
|
|
3
|
-
/** Load the Markdown analyzer at the cache-miss boundary and report its cost. */
|
|
4
|
-
export declare function loadMarkdownAnalyzer(onParserImport?: ParserImportObserver, detail?: string): Promise<typeof analyzeMarkdownFile>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { performance } from 'node:perf_hooks';
|
|
2
|
-
/** Load the Markdown analyzer at the cache-miss boundary and report its cost. */
|
|
3
|
-
export async function loadMarkdownAnalyzer(onParserImport, detail) {
|
|
4
|
-
const started = performance.now();
|
|
5
|
-
const module = await import('./markdown-analysis.js');
|
|
6
|
-
onParserImport?.({
|
|
7
|
-
parser: 'Markdown analyzer',
|
|
8
|
-
imported: true,
|
|
9
|
-
durationMs: performance.now() - started,
|
|
10
|
-
detail,
|
|
11
|
-
});
|
|
12
|
-
return module.analyzeMarkdownFile;
|
|
13
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { type MdLink, type Section } from './lattice-model.js';
|
|
2
|
-
export declare const MAX_SECTION_SUMMARY_LENGTH = 250;
|
|
3
|
-
export type LocalMarkdownDiagnostic = {
|
|
4
|
-
rule: 'markdown-reference-definition' | 'markdown-path-separator' | 'section-leading-paragraph';
|
|
5
|
-
line: number;
|
|
6
|
-
target: string;
|
|
7
|
-
message: string;
|
|
8
|
-
anchor?: string;
|
|
9
|
-
marker?: 'target' | 'line' | 'heading';
|
|
10
|
-
};
|
|
11
|
-
export type LocalMarkdownTarget = {
|
|
12
|
-
kind: 'target';
|
|
13
|
-
/** Decoded on-disk path, or null for a fragment in the current file. */
|
|
14
|
-
path: string | null;
|
|
15
|
-
/** Decoded fragment without `#`, or null when none was authored. */
|
|
16
|
-
fragment: string | null;
|
|
17
|
-
} | {
|
|
18
|
-
kind: 'invalid-backslash';
|
|
19
|
-
};
|
|
20
|
-
/** Parse a local Markdown destination without confusing escaped #/? in paths. */
|
|
21
|
-
export declare function parseLocalMarkdownTarget(url: string): LocalMarkdownTarget | null;
|
|
22
|
-
/** Count summary text while excluding `[[...]]` markers and link content. */
|
|
23
|
-
export declare function sectionSummaryLength(body: string): number;
|
|
24
|
-
/** Validate rules that need no facts outside one parsed Markdown file. */
|
|
25
|
-
export declare function analyzeLocalMarkdownDiagnostics(links: readonly MdLink[], sections: readonly Section[]): LocalMarkdownDiagnostic[];
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { flattenSections } from './lattice-model.js';
|
|
2
|
-
export const MAX_SECTION_SUMMARY_LENGTH = 250;
|
|
3
|
-
function decodeLinkPart(value) {
|
|
4
|
-
try {
|
|
5
|
-
return decodeURIComponent(value);
|
|
6
|
-
}
|
|
7
|
-
catch {
|
|
8
|
-
return value;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
/** Parse a local Markdown destination without confusing escaped #/? in paths. */
|
|
12
|
-
export function parseLocalMarkdownTarget(url) {
|
|
13
|
-
const value = url.trim();
|
|
14
|
-
if (value.startsWith('/'))
|
|
15
|
-
return null;
|
|
16
|
-
const windowsDrivePath = /^[a-zA-Z]:\\/.test(value);
|
|
17
|
-
if (!windowsDrivePath && /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value)) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
// Split before decoding: `%23` and `%3F` decode to `#` and `?`, which would
|
|
21
|
-
// then truncate a filename that legitimately contains them.
|
|
22
|
-
const queryAt = value.indexOf('?');
|
|
23
|
-
const fragmentAt = value.indexOf('#');
|
|
24
|
-
const pathEnd = Math.min(queryAt === -1 ? value.length : queryAt, fragmentAt === -1 ? value.length : fragmentAt);
|
|
25
|
-
const rawPath = value.slice(0, pathEnd);
|
|
26
|
-
const path = rawPath === '' ? null : decodeLinkPart(rawPath);
|
|
27
|
-
const fragment = fragmentAt === -1 ? null : decodeLinkPart(value.slice(fragmentAt + 1));
|
|
28
|
-
if (rawPath === '' && fragment === null)
|
|
29
|
-
return null;
|
|
30
|
-
if (path?.includes('\\'))
|
|
31
|
-
return { kind: 'invalid-backslash' };
|
|
32
|
-
return { kind: 'target', path, fragment };
|
|
33
|
-
}
|
|
34
|
-
/** Count summary text while excluding `[[...]]` markers and link content. */
|
|
35
|
-
export function sectionSummaryLength(body) {
|
|
36
|
-
return body.replace(/\[\[[^\]]*\]\]/g, '').length;
|
|
37
|
-
}
|
|
38
|
-
/** Validate rules that need no facts outside one parsed Markdown file. */
|
|
39
|
-
export function analyzeLocalMarkdownDiagnostics(links, sections) {
|
|
40
|
-
const diagnostics = [];
|
|
41
|
-
for (const link of links) {
|
|
42
|
-
if ('identifier' in link) {
|
|
43
|
-
const kind = link.kind === 'imageReference' ? 'image' : 'link';
|
|
44
|
-
const renderedKind = kind === 'image' ? 'an image' : 'a link';
|
|
45
|
-
const escapedSource = link.source.replace('[', '\\[');
|
|
46
|
-
diagnostics.push({
|
|
47
|
-
rule: 'markdown-reference-definition',
|
|
48
|
-
line: link.line,
|
|
49
|
-
target: link.identifier,
|
|
50
|
-
message: link.style === 'definition'
|
|
51
|
-
? `malformed reference definition (${link.source}) — ` +
|
|
52
|
-
`write it as "[${link.identifier}]: <destination>" on its own line, ` +
|
|
53
|
-
`or escape the opening bracket as "${escapedSource}" to keep it as literal text`
|
|
54
|
-
: link.style === 'shortcut'
|
|
55
|
-
? `undefined shortcut ${kind} reference (${link.source}) — ` +
|
|
56
|
-
`add a definition "[${link.identifier}]: <destination>" to make it ${renderedKind}, ` +
|
|
57
|
-
`or escape the opening bracket as "${escapedSource}" to keep it as literal text`
|
|
58
|
-
: `undefined ${kind} reference (${link.source}) — definition "[${link.identifier}]" not found`,
|
|
59
|
-
marker: 'line',
|
|
60
|
-
});
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (parseLocalMarkdownTarget(link.url)?.kind === 'invalid-backslash') {
|
|
64
|
-
const kind = link.kind === 'image' ? 'image' : 'link';
|
|
65
|
-
diagnostics.push({
|
|
66
|
-
rule: 'markdown-path-separator',
|
|
67
|
-
line: link.line,
|
|
68
|
-
target: link.url,
|
|
69
|
-
message: `invalid ${kind} (${link.url}) — backslashes are not path ` +
|
|
70
|
-
'separators in Markdown; use "/" instead',
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
for (const section of flattenSections([...sections])) {
|
|
75
|
-
if (!section.firstParagraph) {
|
|
76
|
-
diagnostics.push({
|
|
77
|
-
rule: 'section-leading-paragraph',
|
|
78
|
-
line: section.startLine,
|
|
79
|
-
target: section.id,
|
|
80
|
-
message: `section "${section.id}" has no leading paragraph. ` +
|
|
81
|
-
`Every section must start with a brief overview (≤${MAX_SECTION_SUMMARY_LENGTH} chars) ` +
|
|
82
|
-
`summarizing what it documents — this powers search snippets and command output.`,
|
|
83
|
-
anchor: section.githubSlug,
|
|
84
|
-
marker: 'heading',
|
|
85
|
-
});
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const length = sectionSummaryLength(section.firstParagraph);
|
|
89
|
-
if (length > MAX_SECTION_SUMMARY_LENGTH) {
|
|
90
|
-
diagnostics.push({
|
|
91
|
-
rule: 'section-leading-paragraph',
|
|
92
|
-
line: section.startLine,
|
|
93
|
-
target: section.id,
|
|
94
|
-
message: `section "${section.id}" leading paragraph is ${length} characters ` +
|
|
95
|
-
`(max ${MAX_SECTION_SUMMARY_LENGTH}, excluding [[wiki links]]). ` +
|
|
96
|
-
`Keep the first paragraph brief — it serves as the section's summary ` +
|
|
97
|
-
`in search results and command output. Use subsequent paragraphs for details.`,
|
|
98
|
-
anchor: section.githubSlug,
|
|
99
|
-
marker: 'heading',
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return diagnostics;
|
|
104
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** Version of persistent parser outputs and their shared on-disk contract. */
|
|
2
|
-
export declare const PARSER_CACHE_VERSION = 3;
|
|
3
|
-
export type ParsedCacheEntry = {
|
|
4
|
-
version: number;
|
|
5
|
-
contentHash: string;
|
|
6
|
-
value: unknown;
|
|
7
|
-
};
|
|
8
|
-
/** Hash complete parser input bytes for cache invalidation. */
|
|
9
|
-
export declare function hashParserContent(content: string): string;
|
|
10
|
-
/** Normalize an on-disk file into its project-relative parser identity. */
|
|
11
|
-
export declare function parserCacheIdentity(absolutePath: string, projectRoot: string): string;
|
|
12
|
-
/** Return the collision-safe, short-name-sharded cache path for an identity. */
|
|
13
|
-
export declare function parsedCachePath(latDir: string, identity: string): string;
|
|
14
|
-
/** Read and decode a cache entry, treating every malformed state as a miss. */
|
|
15
|
-
export declare function readParsedCache(path: string): Promise<ParsedCacheEntry | null>;
|
|
16
|
-
/** Atomically publish one disposable parser cache entry. */
|
|
17
|
-
export declare function writeParsedCache(path: string, contentHash: string, value: unknown): Promise<void>;
|
package/dist/src/parser-cache.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
-
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { basename, dirname, extname, join, relative } from 'node:path';
|
|
4
|
-
import { toPosix } from './path.js';
|
|
5
|
-
/** Version of persistent parser outputs and their shared on-disk contract. */
|
|
6
|
-
export const PARSER_CACHE_VERSION = 3;
|
|
7
|
-
/** Hash complete parser input bytes for cache invalidation. */
|
|
8
|
-
export function hashParserContent(content) {
|
|
9
|
-
return createHash('sha1').update(content).digest('hex');
|
|
10
|
-
}
|
|
11
|
-
/** Normalize an on-disk file into its project-relative parser identity. */
|
|
12
|
-
export function parserCacheIdentity(absolutePath, projectRoot) {
|
|
13
|
-
return toPosix(relative(projectRoot, absolutePath)).normalize('NFC');
|
|
14
|
-
}
|
|
15
|
-
function readablePath(identity) {
|
|
16
|
-
const normalized = identity
|
|
17
|
-
.replace(/[^a-zA-Z0-9_-]+/g, '_')
|
|
18
|
-
.replace(/^_+|_+$/g, '')
|
|
19
|
-
.toLowerCase();
|
|
20
|
-
return (normalized || 'parsed').slice(-120);
|
|
21
|
-
}
|
|
22
|
-
function cacheShard(identity) {
|
|
23
|
-
const shortName = basename(identity);
|
|
24
|
-
const stem = shortName.slice(0, shortName.length - extname(shortName).length);
|
|
25
|
-
const firstTwo = [...stem.toLowerCase()].slice(0, 2).join('');
|
|
26
|
-
return firstTwo.replace(/[^a-z0-9]/g, '_') || '_';
|
|
27
|
-
}
|
|
28
|
-
/** Return the collision-safe, short-name-sharded cache path for an identity. */
|
|
29
|
-
export function parsedCachePath(latDir, identity) {
|
|
30
|
-
const normalizedIdentity = toPosix(identity).normalize('NFC');
|
|
31
|
-
const digest = hashParserContent(normalizedIdentity);
|
|
32
|
-
return join(latDir, '.cache', 'parsed', cacheShard(normalizedIdentity), `${digest}_${readablePath(normalizedIdentity)}`);
|
|
33
|
-
}
|
|
34
|
-
/** Read and decode a cache entry, treating every malformed state as a miss. */
|
|
35
|
-
export async function readParsedCache(path) {
|
|
36
|
-
try {
|
|
37
|
-
const serialized = await readFile(path, 'utf8');
|
|
38
|
-
const newline = serialized.indexOf('\n');
|
|
39
|
-
if (newline < 0)
|
|
40
|
-
return null;
|
|
41
|
-
const match = /^v(\d+):([a-f0-9]{40})$/.exec(serialized.slice(0, newline).trim());
|
|
42
|
-
if (!match)
|
|
43
|
-
return null;
|
|
44
|
-
return {
|
|
45
|
-
version: Number(match[1]),
|
|
46
|
-
contentHash: match[2],
|
|
47
|
-
value: JSON.parse(serialized.slice(newline + 1)),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/** Atomically publish one disposable parser cache entry. */
|
|
55
|
-
export async function writeParsedCache(path, contentHash, value) {
|
|
56
|
-
await mkdir(dirname(path), { recursive: true });
|
|
57
|
-
const temp = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
58
|
-
try {
|
|
59
|
-
await writeFile(temp, `v${PARSER_CACHE_VERSION}:${contentHash}\n${JSON.stringify(value)}\n`);
|
|
60
|
-
await rename(temp, path);
|
|
61
|
-
}
|
|
62
|
-
finally {
|
|
63
|
-
await rm(temp, { force: true }).catch(() => { });
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/** One observable decision to load or skip a lazily imported parser module. */
|
|
2
|
-
export type ParserImportEvent = {
|
|
3
|
-
parser: 'AsciiDoc parser' | 'Markdown analyzer' | 'reStructuredText parser';
|
|
4
|
-
imported: boolean;
|
|
5
|
-
durationMs: number;
|
|
6
|
-
detail?: string;
|
|
7
|
-
};
|
|
8
|
-
export type ParserImportObserver = (event: ParserImportEvent) => void;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/src/parser.d.ts
DELETED
package/dist/src/parser.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { unified } from 'unified';
|
|
2
|
-
import remarkParse from 'remark-parse';
|
|
3
|
-
import remarkStringify from 'remark-stringify';
|
|
4
|
-
import remarkFrontmatter from 'remark-frontmatter';
|
|
5
|
-
import remarkMath from 'remark-math';
|
|
6
|
-
import { gfmAutolinkLiteralFromMarkdown } from 'mdast-util-gfm-autolink-literal';
|
|
7
|
-
import { gfmFootnoteFromMarkdown, gfmFootnoteToMarkdown, } from 'mdast-util-gfm-footnote';
|
|
8
|
-
import { gfmStrikethroughFromMarkdown, gfmStrikethroughToMarkdown, } from 'mdast-util-gfm-strikethrough';
|
|
9
|
-
import { gfmTableFromMarkdown, gfmTableToMarkdown } from 'mdast-util-gfm-table';
|
|
10
|
-
import { gfmTaskListItemFromMarkdown, gfmTaskListItemToMarkdown, } from 'mdast-util-gfm-task-list-item';
|
|
11
|
-
import { gfmAutolinkLiteral } from 'micromark-extension-gfm-autolink-literal';
|
|
12
|
-
import { gfmFootnote } from 'micromark-extension-gfm-footnote';
|
|
13
|
-
import { gfmStrikethrough } from 'micromark-extension-gfm-strikethrough';
|
|
14
|
-
import { gfmTable } from 'micromark-extension-gfm-table';
|
|
15
|
-
import { gfmTaskListItem } from 'micromark-extension-gfm-task-list-item';
|
|
16
|
-
import { visit } from 'unist-util-visit';
|
|
17
|
-
import { alertMarkerToMarkdown, markAlertMarkers, } from './extensions/alert-marker.js';
|
|
18
|
-
import { wikiLinkSyntax, wikiLinkFromMarkdown, wikiLinkToMarkdown, } from './extensions/wiki-link/index.js';
|
|
19
|
-
const processor = unified()
|
|
20
|
-
.use(remarkParse)
|
|
21
|
-
.use(remarkFrontmatter)
|
|
22
|
-
.use(remarkMath)
|
|
23
|
-
.use(remarkStringify)
|
|
24
|
-
.data('micromarkExtensions', [
|
|
25
|
-
gfmAutolinkLiteral(),
|
|
26
|
-
gfmFootnote(),
|
|
27
|
-
gfmStrikethrough(),
|
|
28
|
-
gfmTable(),
|
|
29
|
-
gfmTaskListItem(),
|
|
30
|
-
wikiLinkSyntax(),
|
|
31
|
-
])
|
|
32
|
-
.data('fromMarkdownExtensions', [
|
|
33
|
-
gfmAutolinkLiteralFromMarkdown(),
|
|
34
|
-
gfmFootnoteFromMarkdown(),
|
|
35
|
-
gfmStrikethroughFromMarkdown(),
|
|
36
|
-
gfmTableFromMarkdown(),
|
|
37
|
-
gfmTaskListItemFromMarkdown(),
|
|
38
|
-
wikiLinkFromMarkdown(),
|
|
39
|
-
])
|
|
40
|
-
.data('toMarkdownExtensions', [
|
|
41
|
-
alertMarkerToMarkdown(),
|
|
42
|
-
gfmFootnoteToMarkdown(),
|
|
43
|
-
gfmStrikethroughToMarkdown(),
|
|
44
|
-
gfmTableToMarkdown(),
|
|
45
|
-
gfmTaskListItemToMarkdown(),
|
|
46
|
-
wikiLinkToMarkdown(),
|
|
47
|
-
]);
|
|
48
|
-
const BARE_AUTOLINK_DATA_KEY = 'latBareAutolink';
|
|
49
|
-
function bareAutolinkText(node) {
|
|
50
|
-
if (node.children.length !== 1 || node.children[0].type !== 'text') {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
const text = node.children[0].value;
|
|
54
|
-
if (node.url !== text &&
|
|
55
|
-
node.url !== `http://${text}` &&
|
|
56
|
-
node.url !== `mailto:${text}`) {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
return text;
|
|
60
|
-
}
|
|
61
|
-
export function parse(markdown) {
|
|
62
|
-
const tree = processor.parse(markdown);
|
|
63
|
-
markAlertMarkers(tree);
|
|
64
|
-
visit(tree, 'link', (node) => {
|
|
65
|
-
const text = bareAutolinkText(node);
|
|
66
|
-
const sourceLength = node.position?.end.offset !== undefined &&
|
|
67
|
-
node.position.start.offset !== undefined
|
|
68
|
-
? node.position.end.offset - node.position.start.offset
|
|
69
|
-
: null;
|
|
70
|
-
if (text === null || sourceLength !== text.length)
|
|
71
|
-
return;
|
|
72
|
-
node.data = {
|
|
73
|
-
...node.data,
|
|
74
|
-
[BARE_AUTOLINK_DATA_KEY]: true,
|
|
75
|
-
};
|
|
76
|
-
});
|
|
77
|
-
return tree;
|
|
78
|
-
}
|
|
79
|
-
export function toMarkdown(tree) {
|
|
80
|
-
const serializable = structuredClone(tree);
|
|
81
|
-
visit(serializable, 'link', (node, index, parent) => {
|
|
82
|
-
if (index === undefined ||
|
|
83
|
-
!parent ||
|
|
84
|
-
node.data?.[BARE_AUTOLINK_DATA_KEY] !== true) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
const text = bareAutolinkText(node);
|
|
88
|
-
if (text === null)
|
|
89
|
-
return;
|
|
90
|
-
parent.children[index] = { type: 'text', value: text };
|
|
91
|
-
});
|
|
92
|
-
return processor.stringify(serializable);
|
|
93
|
-
}
|
package/dist/src/path.d.ts
DELETED
package/dist/src/path.js
DELETED
package/dist/src/profiler.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export type Profiler = {
|
|
2
|
-
time<T>(label: string, work: () => Promise<T>, detail?: string): Promise<T>;
|
|
3
|
-
timeSync<T>(label: string, work: () => T, detail?: string): T;
|
|
4
|
-
record(label: string, durationMs: number, detail?: string): void;
|
|
5
|
-
};
|
|
6
|
-
export declare class TimingProfiler implements Profiler {
|
|
7
|
-
private readonly root;
|
|
8
|
-
private readonly activeNode;
|
|
9
|
-
private node;
|
|
10
|
-
time<T>(label: string, work: () => Promise<T>, detail?: string): Promise<T>;
|
|
11
|
-
timeSync<T>(label: string, work: () => T, detail?: string): T;
|
|
12
|
-
record(label: string, durationMs: number, detail?: string): void;
|
|
13
|
-
private recordNode;
|
|
14
|
-
format(totalMs: number): string[];
|
|
15
|
-
private formatNode;
|
|
16
|
-
}
|
package/dist/src/profiler.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { performance } from 'node:perf_hooks';
|
|
3
|
-
export class TimingProfiler {
|
|
4
|
-
root = {
|
|
5
|
-
label: '',
|
|
6
|
-
calls: 0,
|
|
7
|
-
totalMs: 0,
|
|
8
|
-
maxMs: 0,
|
|
9
|
-
children: new Map(),
|
|
10
|
-
};
|
|
11
|
-
activeNode = new AsyncLocalStorage();
|
|
12
|
-
node(label) {
|
|
13
|
-
const parent = this.activeNode.getStore() ?? this.root;
|
|
14
|
-
let node = parent.children.get(label);
|
|
15
|
-
if (!node) {
|
|
16
|
-
node = {
|
|
17
|
-
label,
|
|
18
|
-
calls: 0,
|
|
19
|
-
totalMs: 0,
|
|
20
|
-
maxMs: 0,
|
|
21
|
-
children: new Map(),
|
|
22
|
-
};
|
|
23
|
-
parent.children.set(label, node);
|
|
24
|
-
}
|
|
25
|
-
return node;
|
|
26
|
-
}
|
|
27
|
-
async time(label, work, detail) {
|
|
28
|
-
const node = this.node(label);
|
|
29
|
-
const start = performance.now();
|
|
30
|
-
try {
|
|
31
|
-
return await this.activeNode.run(node, work);
|
|
32
|
-
}
|
|
33
|
-
finally {
|
|
34
|
-
this.recordNode(node, performance.now() - start, detail);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
timeSync(label, work, detail) {
|
|
38
|
-
const node = this.node(label);
|
|
39
|
-
const start = performance.now();
|
|
40
|
-
try {
|
|
41
|
-
return this.activeNode.run(node, work);
|
|
42
|
-
}
|
|
43
|
-
finally {
|
|
44
|
-
this.recordNode(node, performance.now() - start, detail);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
record(label, durationMs, detail) {
|
|
48
|
-
this.recordNode(this.node(label), durationMs, detail);
|
|
49
|
-
}
|
|
50
|
-
recordNode(node, durationMs, detail) {
|
|
51
|
-
node.calls++;
|
|
52
|
-
node.totalMs += durationMs;
|
|
53
|
-
if (durationMs > node.maxMs) {
|
|
54
|
-
node.maxMs = durationMs;
|
|
55
|
-
node.maxDetail = detail;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
format(totalMs) {
|
|
59
|
-
const lines = [`Profile (${totalMs.toFixed(1)}ms total):`];
|
|
60
|
-
for (const node of this.root.children.values()) {
|
|
61
|
-
this.formatNode(node, 1, lines);
|
|
62
|
-
}
|
|
63
|
-
return lines;
|
|
64
|
-
}
|
|
65
|
-
formatNode(node, depth, lines) {
|
|
66
|
-
const indent = ' '.repeat(depth);
|
|
67
|
-
let summary = `${indent}${node.label}: ${node.totalMs.toFixed(1)}ms`;
|
|
68
|
-
if (node.calls > 1) {
|
|
69
|
-
summary +=
|
|
70
|
-
` total across ${node.calls} calls` +
|
|
71
|
-
` (${(node.totalMs / node.calls).toFixed(1)}ms avg,` +
|
|
72
|
-
` ${node.maxMs.toFixed(1)}ms max` +
|
|
73
|
-
(node.maxDetail ? `: ${node.maxDetail}` : '') +
|
|
74
|
-
')';
|
|
75
|
-
}
|
|
76
|
-
lines.push(summary);
|
|
77
|
-
for (const child of node.children.values()) {
|
|
78
|
-
this.formatNode(child, depth + 1, lines);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|