-
-
Notifications
You must be signed in to change notification settings - Fork 427
feat(core/inlines): support [[[SPEC#id]]] for cross-spec section links #5146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
c08bf0b
feat(inlines): support [[[SPEC#id]]] for cross-spec section links
marcoscaceres 02aa35f
fix(inlines): prevent [[[#id#invalid]]] double-hash from matching
marcoscaceres 1d9f970
feat(inlines): heading text expansion + alias support for [[[SPEC#id]]]
marcoscaceres 8ca5c91
fix(data-cite): remove dead code, avoid double toCiteDetails, use loc…
marcoscaceres d764134
test(inlines): add tests for [[[SPEC#id|alias]]] and [[[#id|alias]]] …
marcoscaceres dd27a1f
test(inlines): add test for [[[SPEC|text]]] alias syntax without frag…
Copilot cce9c48
fix(data-cite): only apply data-lt alias when element is empty to avo…
Copilot 093f929
fix(data-cite): remove premature heading API, cite sibling, and netwo…
Copilot 1d6765c
fix(data-cite): capture originalKey before toCiteDetails pre-computation
marcoscaceres 07265b9
docs(inlines): update inlineExpansion comment to list all supported p…
Copilot 3fdfb90
fix(data-cite): preserve empty-string enum values in data-lt expansion
marcoscaceres ae537ad
test(inlines): add coverage for normative/informative cross-spec links
marcoscaceres 0b94b49
test(inlines): add coverage for normative/informative cross-spec link…
marcoscaceres ac1f5a7
fix(inlines): fix failing CI test for !SPEC#id normative classification
Copilot 48dbbee
refactor(core/inlines): simplify expansion regex, validate in handler
marcoscaceres 2dbb150
fix(core/inlines): add param type for inlineRefMatches
marcoscaceres c6946f2
refactor(core/inlines): improve expansion regex naming and docs
marcoscaceres 981e9cc
fix(core/inlines): fix return type, expand hint, fix stale comment
marcoscaceres 4cf941f
fix(core/inlines): update regex comment to reflect all supported forms
marcoscaceres 3ed328b
fix(core/inlines): handle prefixed in-document refs correctly
marcoscaceres 750568d
fix(core/issues-notes): validate GitHub label color, use html templat…
marcoscaceres a294508
fix(core/inlines): use data-cite-section to prevent dfn-index misclas…
Copilot ced1700
chore: format with prettier
marcoscaceres 5f72387
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres 91f9cda
feat(core/data-cite): resolve heading titles via headings API
marcoscaceres 7264147
refactor: review fixes for headings integration
marcoscaceres becfb11
fix: address Copilot review feedback
marcoscaceres 9a348c6
feat(core/inlines): support \ escape for [[[...]]] expansions
marcoscaceres 4192973
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres 8c9bf79
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres 03e52be
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres 2cc173f
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres 2ff1bd3
fix(core/data-cite): cache headings in IndexedDB, warn on errors, use…
marcoscaceres 869b7d6
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres 01e0ed8
refactor(core): extract headings API into core/headings module
marcoscaceres 3dedc6c
fix(core/headings-db): deduplicate typedef, fix cold-start cache bust
marcoscaceres 05fa420
rename: headings → xref-headings (and xref-headings-db)
marcoscaceres 9d34d20
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres bc55a47
fix(ci): revert accidentally committed builds/ artifacts
Copilot 7038942
fix(core/xref-headings-db): update typedef import after module rename
Copilot 5f2fe62
refactor: code quality pass - simplify specPart, remove elemHeadingKe…
Copilot 6c2004d
feat: make xref-headings a proper plugin; use split('#') in inlines; …
Copilot 3568df3
refactor: consolidate duplicate typeof check in xref-headings run()
Copilot 1b27917
refactor(dfn-index): remove redundant citeSection guard - existing ch…
Copilot 8aa424c
refactor: use citeFrag instead of citeSection, move headingApiUrl int…
Copilot b09c8f8
fix(dfn-index): restore citeFrag guard and exclude [[[SPEC#id]]] sect…
Copilot 3cb371f
fix(xref-headings): remove skipCache coupling to API URL; use beforeE…
Copilot bb2a4a5
refactor: address review feedback on inlines and xref-headings
marcoscaceres f7a04da
fix(inlines): simplify warning hint to wiki link; convert prod API te…
Copilot f474be0
fix(tests): use explicit bdi.secno assertion instead of optional chai…
Copilot 2c13263
Merge branch 'main' into feat/inlines-cross-spec
marcoscaceres ff74aa7
refactor(xref-headings): add typedef, move run() to top, extract getA…
Copilot fc3c4ee
style(xref-headings): restore multi-line formatting in map callback
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| // @ts-check | ||
| import { idb } from "./import-maps.js"; | ||
|
|
||
| /** | ||
| * @typedef {import("./xref-headings.js").HeadingInfo} HeadingInfo | ||
| * @typedef {{ query: { spec: string, id: string }, result: HeadingInfo }} HeadingEntry | ||
| * @typedef {import("idb").DBSchema & { headings: { key: string, value: HeadingEntry } }} HeadingsDb | ||
| */ | ||
|
|
||
| const STORE_NAME = "headings"; | ||
| const CACHE_MAX_AGE = 24 * 60 * 60 * 1000; // 24 hours | ||
|
|
||
| async function getDb() { | ||
| /** @type {import("idb").IDBPDatabase<HeadingsDb>} */ | ||
| const db = await idb.openDB("respec-headings", 1, { | ||
| upgrade(db) { | ||
| [...db.objectStoreNames].forEach(s => db.deleteObjectStore(s)); | ||
| db.createObjectStore(STORE_NAME); | ||
| }, | ||
| }); | ||
| return db; | ||
| } | ||
|
|
||
| /** @param {{ spec: string, id: string }[]} queries */ | ||
| export async function resolveHeadingsCache(queries) { | ||
| /** @type {Map<string, HeadingInfo>} */ | ||
| const cachedData = new Map(); | ||
|
|
||
| if (shouldBustCache()) { | ||
| await clearHeadingsData(); | ||
| return cachedData; | ||
| } | ||
|
|
||
| try { | ||
| const db = await getDb(); | ||
| const tx = db.transaction(STORE_NAME); | ||
| for (const query of queries) { | ||
| const key = `${query.spec}#${query.id}`; | ||
| const entry = await tx.store.get(key); | ||
| if (entry) { | ||
| cachedData.set(key, entry.result); | ||
| } | ||
| } | ||
| } catch (err) { | ||
| console.error(err); | ||
| } | ||
| return cachedData; | ||
| } | ||
|
|
||
| /** | ||
| * @param {{ spec: string, id: string }[]} queries | ||
| * @param {Map<string, HeadingInfo>} results | ||
| */ | ||
| export async function cacheHeadingsData(queries, results) { | ||
| try { | ||
| const db = await getDb(); | ||
| const tx = db.transaction(STORE_NAME, "readwrite"); | ||
| for (const query of queries) { | ||
| const key = `${query.spec}#${query.id}`; | ||
| const result = results.get(key); | ||
| if (result) { | ||
| tx.objectStore(STORE_NAME).put({ query, result }, key); | ||
| } | ||
| } | ||
| await tx.done; | ||
| localStorage.setItem("HEADINGS:LAST_CACHED", Date.now().toString()); | ||
| } catch (e) { | ||
| console.error(e); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Returns true when the cached headings data has exceeded CACHE_MAX_AGE and | ||
| * should be discarded. Returns false when no timestamp exists (cold start). | ||
| */ | ||
| function shouldBustCache() { | ||
| const lastCached = parseInt( | ||
| localStorage.getItem("HEADINGS:LAST_CACHED") ?? "", | ||
| 10 | ||
| ); | ||
| if (isNaN(lastCached)) return false; | ||
| return Date.now() - lastCached > CACHE_MAX_AGE; | ||
| } | ||
|
|
||
| /** Clears all cached headings data and removes the last-cached timestamp. */ | ||
| export async function clearHeadingsData() { | ||
| try { | ||
| const db = await getDb(); | ||
| await db.clear(STORE_NAME); | ||
| localStorage.removeItem("HEADINGS:LAST_CACHED"); | ||
| } catch (e) { | ||
| console.error(e); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.