@knpkv/rly 0.14.0 → 0.16.0
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 +90 -3
- package/dist/{Dialog-B9Ub_gMT.js → Dialog-CU66FqWD.js} +325 -257
- package/dist/Dialog-CU66FqWD.js.map +1 -0
- package/dist/{PortalProvider-CN_81Fy3.js → PortalProvider-op07u8na.js} +20 -18
- package/dist/PortalProvider-op07u8na.js.map +1 -0
- package/dist/components.css +2 -2
- package/dist/diff/bounded/index.js.map +1 -1
- package/dist/diff/index.js.map +1 -1
- package/dist/diff/patch/index.js.map +1 -1
- package/dist/dts/foundations/Icon.d.ts +1 -1
- package/dist/dts/foundations/Icon.d.ts.map +1 -1
- package/dist/dts/internal/composedFocus.d.ts +11 -0
- package/dist/dts/internal/composedFocus.d.ts.map +1 -0
- package/dist/dts/internal/relaySummon.d.ts +50 -0
- package/dist/dts/internal/relaySummon.d.ts.map +1 -0
- package/dist/dts/patterns/RelayComposer.d.ts +65 -0
- package/dist/dts/patterns/RelayComposer.d.ts.map +1 -0
- package/dist/dts/patterns/RelayDecision.d.ts +75 -0
- package/dist/dts/patterns/RelayDecision.d.ts.map +1 -0
- package/dist/dts/patterns/RelayDock.d.ts.map +1 -1
- package/dist/dts/patterns/RelayFindings.d.ts +83 -0
- package/dist/dts/patterns/RelayFindings.d.ts.map +1 -0
- package/dist/dts/patterns/RelayLauncher.d.ts +32 -1
- package/dist/dts/patterns/RelayLauncher.d.ts.map +1 -1
- package/dist/dts/patterns/RelayPanel.d.ts +91 -0
- package/dist/dts/patterns/RelayPanel.d.ts.map +1 -0
- package/dist/dts/patterns/RelaySetup.d.ts +58 -0
- package/dist/dts/patterns/RelaySetup.d.ts.map +1 -0
- package/dist/dts/patterns/RelayTranscript.d.ts +68 -0
- package/dist/dts/patterns/RelayTranscript.d.ts.map +1 -0
- package/dist/dts/patterns/index.d.ts +14 -2
- package/dist/dts/patterns/index.d.ts.map +1 -1
- package/dist/dts/tokens/fonts.d.ts +13 -0
- package/dist/dts/tokens/fonts.d.ts.map +1 -0
- package/dist/dts/tokens/index.d.ts +2 -0
- package/dist/dts/tokens/index.d.ts.map +1 -1
- package/dist/fonts.css +7 -2
- package/dist/foundations/index.js +1 -1
- package/dist/index.js +6 -6
- package/dist/patterns/index.js +2 -2
- package/dist/patterns-B3WbiVEp.js +4981 -0
- package/dist/patterns-B3WbiVEp.js.map +1 -0
- package/dist/primitives/index.js +3 -3
- package/dist/{primitives-Bd6WhE78.js → primitives-DgQybTyq.js} +254 -322
- package/dist/primitives-DgQybTyq.js.map +1 -0
- package/dist/tokens/index.js +2 -2
- package/dist/{tokens-B075JP3Z.js → tokens-Cf0jXIRg.js} +14 -8
- package/dist/tokens-Cf0jXIRg.js.map +1 -0
- package/dist/workbench-CHCnYW3G.js.map +1 -1
- package/package.json +1 -1
- package/registry/components.json +558 -1
- package/registry/search.json +162 -0
- package/dist/Dialog-B9Ub_gMT.js.map +0 -1
- package/dist/PortalProvider-CN_81Fy3.js.map +0 -1
- package/dist/patterns-ChmGSFqO.js +0 -3768
- package/dist/patterns-ChmGSFqO.js.map +0 -1
- package/dist/primitives-Bd6WhE78.js.map +0 -1
- package/dist/tokens-B075JP3Z.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","styles","useNarrowerThan","Fragment$1","BoundedDiffCodeView_module_default","invalid","HUNK","HEADER","unquote","path","source","bytes","encoder","escapes","offset","match","literal","byte","code","trailing","headerPaths","candidates","index","header","left","right","destination","defaultPrefixes","prefixes","selected","oldPath","newPath","moved","unmarkedBinary","paths","binaryPaths","summary","body","selections","status","parsePatch","text","records","lines","line","files","currentPaths","movedSource","movedDestination","fileMode","oldMode","newMode","binary","binarySummary","hunks","oldEnd","newEnd","oldEof","newEof","oldCoordinates","newCoordinates","mode","value","kind","payload","readBinary","parsed","readHunk","record","hunk","markerStatus","start","chunks","first","lead","length","oldStart","newStart","oldCount","newCount","oldOffset","newOffset","oldNo","newNo","marker","previous","pathsOf","file","findFile","patch","pairRows","rows","deleted","added","next","PatchDiffView","narrow","measureRef","shown","cell","number","side","wrap","id","annotation","content","renderAnnotation","Fragment","row","rowIndex","lineIndex","hunkIndex"],"sources":["../../../src/diff/bounded/BoundedDiffCodeView.module.css","../../../src/diff/patch/parse.ts","../../../src/diff/patch/PatchDiffView.tsx"],"sourcesContent":[".root {\n overflow: hidden;\n border: 1px solid var(--rly-color-border-1);\n border-radius: var(--rly-radius-field);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n}\n\n.file + .file {\n border-top: 1px solid var(--rly-color-border-1);\n}\n\n.noChanges {\n margin: 0;\n padding: var(--rly-space-16);\n color: var(--rly-color-text-2);\n font: var(--rly-type-body-weight) var(--rly-type-body-size) / var(--rly-type-body-line-height)\n var(--rly-type-body-font);\n}\n\n.fileName {\n margin: 0;\n padding: var(--rly-space-12) var(--rly-space-16);\n border-bottom: 1px solid var(--rly-color-border-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.scroller {\n max-height: min(70vh, 56rem);\n overflow: auto;\n}\n\n.table {\n width: 100%;\n border-spacing: 0;\n border-collapse: collapse;\n font-family: var(--rly-font-mono);\n font-size: 0.78rem;\n line-height: 1.55;\n}\n\n.table td {\n min-width: 0;\n padding: 0;\n vertical-align: top;\n}\n\n.hunk td {\n padding: var(--rly-space-4) var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-1);\n background: var(--rly-color-surface-2);\n color: var(--rly-color-text-2);\n}\n\n.lineNumber {\n width: 3.25rem;\n /* Room either side of the number, so the column rule reads as one rule, not a box per line. */\n padding-inline: var(--rly-space-8) var(--rly-space-6) !important;\n border-right: 1px solid var(--rly-color-border-1);\n color: var(--rly-color-text-3);\n text-align: right;\n user-select: none;\n}\n\n.marker {\n width: 1.5rem;\n color: var(--rly-color-text-3);\n text-align: center;\n user-select: none;\n}\n\n.code,\n.wrappedCode {\n display: block;\n min-height: 1.55em;\n padding-inline: var(--rly-space-12);\n white-space: pre;\n}\n\n.wrappedCode {\n white-space: pre-wrap;\n overflow-wrap: break-word;\n}\n\n/*\n * In an auto-sized table a long token would widen its column rather than wrap. Capping the wrapped\n * code cell at zero and letting it take the remaining width bounds it to the viewport, so\n * break-word can wrap a 200-character string; unwrapped views keep their horizontal scroll.\n */\n.table td:has(> .wrappedCode) {\n inline-size: 100%;\n max-inline-size: 0;\n}\n\n.deletion > td,\n.change .deletionCode {\n background: var(--rly-color-blocked-tint);\n}\n\n.addition > td,\n.change .additionCode {\n background: var(--rly-color-success-tint);\n}\n\n.deletion .lineNumber,\n.addition .lineNumber,\n.deletion .marker,\n.addition .marker {\n color: var(--rly-color-text-2);\n}\n\n.context > td {\n background: var(--rly-color-surface-1);\n}\n\n.deletionCode,\n.additionCode {\n width: 50%;\n border-right: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > td {\n background: var(--rly-color-surface-2);\n border-block: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > .annotationCell {\n padding: var(--rly-space-8);\n}\n\n.annotation {\n background: var(--rly-color-held-tint);\n border: 1px solid color-mix(in oklab, var(--rly-color-held-ink) 35%, transparent);\n border-radius: var(--rly-radius-tag);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n padding: var(--rly-space-8) var(--rly-space-12);\n}\n\n.annotation:focus-visible,\n[data-rly-diff-line]:focus-visible {\n outline: var(--rly-focus-ring-width) solid var(--rly-color-focus);\n outline-offset: var(--rly-focus-ring-offset);\n}\n\n@media (forced-colors: active) {\n .annotation,\n [data-rly-diff-line]:focus-visible {\n forced-color-adjust: auto;\n }\n}\n\n/*\n * Forced colours drop the add/remove tints. Split cells have no marker column, so a changed cell\n * gets its sign drawn before the code (hidden from assistive technology, which reads the column).\n */\n@media (forced-colors: active) {\n .change .deletionCode > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n }\n .change .additionCode > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n }\n}\n\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .deletionCode\n > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n}\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .additionCode\n > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n}\n","/**\n * A `git diff` parsed into files, hunks and numbered lines.\n *\n * Only what the renderer and the anchoring need: which files changed and how, and for\n * every line in a hunk its number on the old and the new side. Status, mode and body\n * evidence must agree; index and similarity values are not used for line anchoring.\n */\n\n/** A malformed patch cannot supply trustworthy source line positions. */\nexport interface PatchInvalid {\n readonly _tag: \"PatchInvalid\"\n readonly reason: string\n}\n\n/** What `parsePatch` returns: either a patch, or the reason it could not be trusted. */\nexport type ParseResult = { readonly _tag: \"Patch\"; readonly patch: Patch } | PatchInvalid\n\nconst invalid = (reason: string): PatchInvalid => ({ _tag: \"PatchInvalid\", reason })\n\ntype UnquotedPath = { readonly _tag: \"Path\"; readonly path: string } | PatchInvalid\nexport type LineKind = \"context\" | \"add\" | \"del\"\n\nexport interface DiffLine {\n readonly kind: LineKind\n readonly text: string\n /** Git EOF marker on this record: old side for deletions, new for additions, both for context. */\n readonly noNewline?: boolean\n /** Line number in the old file; absent on added lines. */\n readonly oldNo?: number\n /** Line number in the new file; absent on deleted lines. */\n readonly newNo?: number\n}\n\nexport interface Hunk {\n readonly header: string\n readonly oldStart: number\n readonly newStart: number\n readonly lines: ReadonlyArray<DiffLine>\n}\n\nexport type FileStatus = \"added\" | \"deleted\" | \"modified\" | \"renamed\" | \"copied\"\n\nexport interface FileDiff {\n /** The path a guide refers to: the new path, or the old one when the file was deleted. */\n readonly path: string\n readonly oldPath: string\n readonly newPath: string\n readonly status: FileStatus\n readonly binary: boolean\n /** Explicit mode headers only; an absent side or unreported mode stays absent. */\n readonly oldMode?: string\n readonly newMode?: string\n readonly hunks: ReadonlyArray<Hunk>\n}\n\nexport interface Patch {\n readonly files: ReadonlyArray<FileDiff>\n}\n\nconst HUNK = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@(.*)$/\nconst HEADER = \"diff --git \"\n\n/** Exact Git producer prefixes. Use two empty strings for --no-prefix, including paths resembling a/ and b/. */\nexport interface PatchPrefixes {\n readonly source: string\n readonly destination: string\n}\n\nconst unquote = (path: string): UnquotedPath => {\n if (path.includes(\"\\u0000\")) return invalid(\"Git paths cannot contain NUL\")\n if (!path.startsWith(\"\\\"\")) return { _tag: \"Path\", path }\n if (!path.endsWith(\"\\\"\")) return invalid(\"Unclosed quoted path\")\n const source = path.slice(1, -1)\n const bytes: Array<number> = []\n const encoder = new TextEncoder()\n const escapes = new Map([\n [\"a\", 7],\n [\"b\", 8],\n [\"t\", 9],\n [\"n\", 10],\n [\"v\", 11],\n [\"f\", 12],\n [\"r\", 13],\n [\"\\\"\", 34],\n [\"\\\\\", 92]\n ])\n let offset = 0\n for (const match of source.matchAll(/\\\\([0-7]{3}|.)/gs)) {\n const literal = source.slice(offset, match.index)\n if (literal.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(literal)) bytes.push(byte)\n const code = match[1] ?? \"\"\n const byte = /^[0-7]{3}$/.test(code) ? parseInt(code, 8) : escapes.get(code)\n if (byte === undefined || byte === 0 || byte > 255) return invalid(\"Invalid quoted path escape\")\n bytes.push(byte)\n offset = match.index + match[0].length\n }\n const trailing = source.slice(offset)\n if (trailing.includes(\"\\\\\")) return invalid(\"Dangling quoted path escape\")\n if (trailing.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(trailing)) bytes.push(byte)\n try {\n return {\n _tag: \"Path\",\n path: new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(new Uint8Array(bytes))\n }\n } catch {\n return invalid(\"Quoted Git path is not valid UTF-8\")\n }\n}\n\n/** Resolve header boundaries against file markers; spaces in unquoted filenames are legal Git output. */\nconst headerPaths = (\n header: string,\n source: string | undefined,\n destination: string | undefined,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n unmarkedBinary = false\n): { readonly _tag: \"Paths\"; readonly oldPath: string; readonly newPath: string } | PatchInvalid => {\n const candidates: Array<{ readonly oldPath: string; readonly newPath: string }> = []\n for (let index = 0; index < header.length; index++) {\n if (header[index] !== \" \") continue\n const left = unquote(header.slice(0, index))\n const right = unquote(header.slice(index + 1))\n if (left._tag === \"PatchInvalid\" || right._tag === \"PatchInvalid\") continue\n if (left.path === \"\" || right.path === \"\") continue\n if (source !== undefined && source !== \"/dev/null\" && source !== left.path) continue\n if (destination !== undefined && destination !== \"/dev/null\" && destination !== right.path) continue\n const defaultPrefixes = prefixes === undefined && left.path.startsWith(\"a/\") && right.path.startsWith(\"b/\")\n const selected = prefixes ?? (defaultPrefixes\n ? { source: \"a/\", destination: \"b/\" }\n : { source: \"\", destination: \"\" })\n if (!left.path.startsWith(selected.source) || !right.path.startsWith(selected.destination)) continue\n const oldPath = left.path.slice(selected.source.length)\n const newPath = right.path.slice(selected.destination.length)\n if (oldPath === \"\" || newPath === \"\") continue\n if (moved !== undefined && (oldPath !== moved.source || newPath !== moved.destination)) continue\n if (\n moved === undefined && source === undefined && destination === undefined && oldPath !== newPath &&\n !(unmarkedBinary && (defaultPrefixes || prefixes !== undefined))\n ) continue\n candidates.push({ oldPath, newPath })\n }\n const paths = candidates[0]\n return candidates.length === 1 && paths !== undefined\n ? { _tag: \"Paths\", ...paths }\n : invalid(\"Inconsistent or ambiguous Git file headers; custom prefixes must be supplied explicitly\")\n}\n\n/** Match every possible summary separator against the authoritative header, including quoted and spaced paths. */\nconst binaryPaths = (\n header: string,\n summary: string,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n status: FileStatus\n): ReturnType<typeof headerPaths> => {\n if (!summary.endsWith(\" differ\")) return invalid(\"Incomplete binary summary\")\n const body = summary.slice(\"Binary files \".length, -\" differ\".length)\n // Auto mode tries Git's standard prefixes before an unprefixed producer.\n // Otherwise a filename ending in \" and\" can fabricate a second no-prefix interpretation.\n const selections = prefixes === undefined\n ? [{ source: \"a/\", destination: \"b/\" }, { source: \"\", destination: \"\" }]\n : [prefixes]\n for (const selected of selections) {\n const candidates: Array<Extract<ReturnType<typeof headerPaths>, { readonly _tag: \"Paths\" }>> = []\n for (const match of body.matchAll(/(?= and )/g)) {\n const source = unquote(body.slice(0, match.index))\n const destination = unquote(body.slice(match.index + \" and \".length))\n if (source._tag === \"PatchInvalid\" || destination._tag === \"PatchInvalid\") continue\n if ((source.path === \"/dev/null\") !== (status === \"added\")) continue\n if ((destination.path === \"/dev/null\") !== (status === \"deleted\")) continue\n const paths = headerPaths(header, source.path, destination.path, selected, moved)\n if (paths._tag === \"Paths\") candidates.push(paths)\n }\n const paths = candidates[0]\n if (candidates.length === 1 && paths !== undefined) return paths\n if (candidates.length > 1) return invalid(\"Ambiguous binary summary paths\")\n }\n return invalid(\"Binary summary paths disagree with Git headers\")\n}\n\n/** Infer default a/b prefixes when present; pass explicit empty prefixes for unambiguous --no-prefix parsing. */\nexport const parsePatch = (text: string, prefixes?: PatchPrefixes): ParseResult => {\n if (text !== \"\" && !text.endsWith(\"\\n\")) return invalid(\"Unterminated patch record\")\n // A CR on a Git header identifies transport line endings; body-only CR belongs to the source.\n const records = text.split(\"\\n\")\n const converted = records.some((line) => line.startsWith(HEADER) && line.endsWith(\"\\r\"))\n const lines = converted ? records.map((line) => line.endsWith(\"\\r\") ? line.slice(0, -1) : line) : records\n const files: Array<FileDiff> = []\n const currentPaths = new Set<string>()\n let index = 0\n\n while (index < lines.length) {\n const line = lines[index] ?? \"\"\n if (!line.startsWith(HEADER)) {\n index += 1\n continue\n }\n const header = line.slice(HEADER.length)\n let source: string | undefined\n let destination: string | undefined\n let movedSource: string | undefined\n let movedDestination: string | undefined\n let status: FileStatus = \"modified\"\n let fileMode: string | undefined\n let oldMode: string | undefined\n let newMode: string | undefined\n let binary = false\n let binarySummary: string | undefined\n const hunks: Array<Hunk> = []\n let oldEnd = 0\n let newEnd = 0\n let oldEof = false\n let newEof = false\n const oldCoordinates = new Set<number>()\n const newCoordinates = new Set<number>()\n index += 1\n\n while (index < lines.length && !(lines[index] ?? \"\").startsWith(HEADER)) {\n const line = lines[index] ?? \"\"\n if (/^(new file|deleted file|old|new) mode/.test(line)) {\n const mode = /^(new file|deleted file|old|new) mode ([0-7]{6})$/.exec(line)\n if (mode === null) return invalid(\"Invalid file mode header\")\n const value = mode[2]\n if (mode[1] === \"old\") {\n if (oldMode !== undefined && oldMode !== value) return invalid(\"Conflicting old modes\")\n oldMode = value\n } else if (mode[1] === \"new\") {\n if (newMode !== undefined && newMode !== value) return invalid(\"Conflicting new modes\")\n newMode = value\n } else {\n const kind = mode[1] === \"new file\" ? \"added\" : \"deleted\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n if (fileMode !== undefined && fileMode !== value) return invalid(\"Conflicting file modes\")\n status = kind\n fileMode = value\n }\n } else if (/^(rename|copy) (from|to) /.test(line)) {\n const kind = line.startsWith(\"copy \") ? \"copied\" : \"renamed\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n status = kind\n const path = unquote(line.replace(/^(rename|copy) (from|to) /, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (/^(rename|copy) from /.test(line)) {\n if (movedSource !== undefined && movedSource !== path.path) return invalid(\"Conflicting move source paths\")\n movedSource = path.path\n } else {\n if (movedDestination !== undefined && movedDestination !== path.path) {\n return invalid(\"Conflicting move destination paths\")\n }\n movedDestination = path.path\n }\n } else if (line.startsWith(\"GIT binary patch\")) {\n if (line !== \"GIT binary patch\") return invalid(\"Invalid binary patch marker\")\n const payload = readBinary(lines, index + 1)\n if (payload._tag === \"PatchInvalid\") return payload\n binary = true\n index = payload.next\n continue\n } else if (line.startsWith(\"Binary files \")) {\n if (binarySummary !== undefined && binarySummary !== line) return invalid(\"Conflicting binary summaries\")\n binarySummary = line\n binary = true\n } else if (line.startsWith(\"--- \") || line.startsWith(\"+++ \")) {\n const path = unquote(line.slice(4).replace(/\\t$/, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (line.startsWith(\"--- \")) {\n if (source !== undefined && source !== path.path) return invalid(\"Conflicting source file markers\")\n source = path.path\n } else {\n if (destination !== undefined && destination !== path.path) {\n return invalid(\"Conflicting destination file markers\")\n }\n destination = path.path\n }\n } else if (HUNK.test(line)) {\n if (source === undefined || destination === undefined) return invalid(\"Text hunks require paired file markers\")\n const parsed = readHunk(lines, index)\n if (parsed._tag === \"PatchInvalid\") return parsed\n if (!parsed.hunk.lines.some((record) => record.kind === \"add\" || record.kind === \"del\")) {\n return invalid(\"Text hunk has no change evidence\")\n }\n if (parsed.oldOffset < oldEnd || parsed.newOffset < newEnd) return invalid(\"Hunk ranges move backwards\")\n oldEnd = parsed.oldEnd\n newEnd = parsed.newEnd\n for (const record of parsed.hunk.lines) {\n if ((oldEof && record.oldNo !== undefined) || (newEof && record.newNo !== undefined)) {\n return invalid(\"Patch records follow an EOF marker on the same side\")\n }\n if (record.noNewline === true) {\n oldEof ||= record.oldNo !== undefined\n newEof ||= record.newNo !== undefined\n }\n if (\n (record.oldNo !== undefined && oldCoordinates.has(record.oldNo)) ||\n (record.newNo !== undefined && newCoordinates.has(record.newNo))\n ) return invalid(`Overlapping hunk at line ${index + 1}`)\n if (record.oldNo !== undefined) oldCoordinates.add(record.oldNo)\n if (record.newNo !== undefined) newCoordinates.add(record.newNo)\n }\n hunks.push(parsed.hunk)\n index = parsed.next\n continue\n } else if (/^(?:@@|[+\\- \\\\])/.test(line)) {\n return invalid(`Unexpected patch body at line ${index + 1}`)\n }\n index += 1\n }\n if ((source === undefined) !== (destination === undefined)) return invalid(\"Unpaired file markers\")\n if ((movedSource === undefined) !== (movedDestination === undefined)) {\n return invalid(\"Unpaired rename or copy headers\")\n }\n if ((oldMode === undefined) !== (newMode === undefined)) return invalid(\"Unpaired mode transition\")\n if (fileMode !== undefined && oldMode !== undefined) return invalid(\"Conflicting file mode headers\")\n if (oldMode !== undefined && (source === \"/dev/null\" || destination === \"/dev/null\")) {\n return invalid(\"Mode transition requires both file sides\")\n }\n if (binary && source !== undefined) return invalid(\"Mixed binary and text bodies\")\n if (source !== undefined && hunks.length === 0) return invalid(\"Text markers require hunks\")\n if (source === \"/dev/null\" && destination === \"/dev/null\") return invalid(\"Both file sides are absent\")\n if (\n hunks.some((hunk) =>\n hunk.lines.some((line) =>\n (source === \"/dev/null\" && line.oldNo !== undefined) ||\n (destination === \"/dev/null\" && line.newNo !== undefined)\n )\n )\n ) return invalid(\"Absent file side contains text lines\")\n if (source !== undefined) {\n const markerStatus = source === \"/dev/null\" ? \"added\" : destination === \"/dev/null\" ? \"deleted\" : \"modified\"\n if (\n (status === \"added\" || status === \"deleted\" || markerStatus !== \"modified\") &&\n status !== \"modified\" && status !== markerStatus\n ) return invalid(\"File status disagrees with file markers\")\n if (markerStatus !== \"modified\") status = markerStatus\n }\n if (\n hunks.length === 0 && !binary && movedSource === undefined && fileMode === undefined &&\n (oldMode === undefined || oldMode === newMode)\n ) return invalid(\"File block has no change evidence\")\n const moved = movedSource === undefined || movedDestination === undefined\n ? undefined\n : { source: movedSource, destination: movedDestination }\n const paths = binarySummary === undefined\n ? headerPaths(header, source, destination, prefixes, moved, binary)\n : binaryPaths(header, binarySummary, prefixes, moved, status)\n if (paths._tag === \"PatchInvalid\") return paths\n if (\n binary && source === undefined && moved === undefined && status !== \"modified\" && paths.oldPath !== paths.newPath\n ) {\n return invalid(\"Binary addition or deletion has conflicting header paths\")\n }\n const path = status === \"deleted\" ? paths.oldPath : paths.newPath\n if (currentPaths.has(path)) return invalid(\"Duplicate canonical current file path\")\n currentPaths.add(path)\n files.push({\n path,\n oldPath: paths.oldPath,\n newPath: paths.newPath,\n status,\n binary,\n ...(status === \"deleted\" && fileMode !== undefined\n ? { oldMode: fileMode }\n : oldMode === undefined\n ? {}\n : { oldMode }),\n ...(status === \"added\" && fileMode !== undefined\n ? { newMode: fileMode }\n : newMode === undefined\n ? {}\n : { newMode }),\n hunks\n })\n }\n if (files.length === 0 && text.trim() !== \"\") return invalid(\"Expected a git unified diff\")\n return { _tag: \"Patch\", patch: { files } }\n}\n\n/** Validate Git's literal/delta record framing without inflating or applying binary content. */\nconst readBinary = (\n lines: ReadonlyArray<string>,\n start: number\n): { readonly _tag: \"Binary\"; readonly next: number } | PatchInvalid => {\n let index = start\n let chunks = 0\n do {\n const header = /^(literal|delta) (\\d+)$/.exec(lines[index] ?? \"\")\n if (header === null || !Number.isSafeInteger(Number(header[2]))) return invalid(\"Invalid binary chunk header\")\n index += 1\n const first = index\n while (index < lines.length && lines[index] !== \"\") {\n const line = lines[index] ?? \"\"\n const lead = line.charCodeAt(0)\n const length = lead >= 65 && lead <= 90 ? lead - 64 : lead >= 97 && lead <= 122 ? lead - 70 : 0\n if (\n length === 0 || line.length !== 1 + Math.ceil(length / 4) * 5 ||\n !/^[0-9A-Za-z!#$%&()*+;<=>?@^_`{|}~-]+$/.test(line.slice(1))\n ) return invalid(\"Invalid binary chunk data\")\n index += 1\n }\n // A final split sentinel is not the blank record that terminates a Git payload.\n if (index === first || index >= lines.length - 1) return invalid(\"Incomplete binary chunk\")\n index += 1\n chunks += 1\n } while (chunks < 2 && /^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\"))\n if (/^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\")) return invalid(\"Surplus binary chunk\")\n return { _tag: \"Binary\", next: index }\n}\n\nconst readHunk = (\n lines: ReadonlyArray<string>,\n start: number\n): {\n readonly _tag: \"Hunk\"\n readonly hunk: Hunk\n readonly next: number\n readonly oldOffset: number\n readonly newOffset: number\n readonly oldEnd: number\n readonly newEnd: number\n} | PatchInvalid => {\n const match = HUNK.exec(lines[start] ?? \"\")\n if (match === null) return invalid(`not a hunk header at line ${start + 1}`)\n const oldStart = Number(match[1])\n const newStart = Number(match[3])\n let oldCount = match[2] === undefined ? 1 : Number(match[2])\n let newCount = match[4] === undefined ? 1 : Number(match[4])\n if (![oldStart, newStart, oldCount, newCount].every(Number.isSafeInteger)) return invalid(\"Unsafe hunk integers\")\n if (oldCount === 0 && newCount === 0) return invalid(\"Empty hunk\")\n if (\n (oldCount > 0 && !Number.isSafeInteger(oldStart + (oldCount - 1))) ||\n (newCount > 0 && !Number.isSafeInteger(newStart + (newCount - 1)))\n ) return invalid(\"Hunk coordinates overflow\")\n // Half-open zero-based ranges: empty Git ranges anchor after the named line.\n const oldOffset = oldStart - (oldCount === 0 ? 0 : 1)\n const newOffset = newStart - (newCount === 0 ? 0 : 1)\n const oldEnd = oldOffset + oldCount\n const newEnd = newOffset + newCount\n let oldNo = oldStart\n let newNo = newStart\n const body: Array<DiffLine> = []\n let index = start + 1\n\n while (index < lines.length && (oldCount > 0 || newCount > 0)) {\n const line = lines[index] ?? \"\"\n const marker = line[0]\n const text = line.slice(1)\n if (marker === \"+\") {\n body.push({ kind: \"add\", text, newNo })\n newNo += 1\n newCount -= 1\n } else if (marker === \"-\") {\n body.push({ kind: \"del\", text, oldNo })\n oldNo += 1\n oldCount -= 1\n } else if (marker === \" \") {\n body.push({ kind: \"context\", text, oldNo, newNo })\n oldNo += 1\n newNo += 1\n oldCount -= 1\n newCount -= 1\n } else {\n break\n }\n index += 1\n // A marker belongs to exactly one preceding body record and consumes no coordinate.\n if ((lines[index] ?? \"\").startsWith(\"\\\\\")) {\n if (lines[index] !== \"\\\\") return invalid(`Invalid newline marker at line ${index + 1}`)\n const previous = body[body.length - 1]\n if (previous !== undefined) body[body.length - 1] = { ...previous, noNewline: true }\n index += 1\n }\n }\n if (oldCount !== 0 || newCount !== 0) return invalid(`Incomplete hunk at line ${start + 1}`)\n\n return {\n _tag: \"Hunk\",\n oldOffset,\n newOffset,\n oldEnd,\n newEnd,\n hunk: { header: match[5]?.trim() ?? \"\", oldStart, newStart, lines: body },\n next: index\n }\n}\n\n/** Changed-file paths: the current name first, then the source of a rename or modified comparison. */\nexport const pathsOf = (file: FileDiff): ReadonlyArray<string> =>\n file.status === \"renamed\" || (file.status === \"modified\" && file.oldPath !== file.newPath)\n ? [file.newPath, file.oldPath]\n : [file.path]\n\nexport const findFile = (patch: Patch, path: string): FileDiff | undefined =>\n patch.files.find((file) => file.path === path) ?? patch.files.find((file) => pathsOf(file).includes(path))\n","import { Fragment, type ReactElement, type ReactNode } from \"react\"\nimport styles from \"../bounded/BoundedDiffCodeView.module.css\"\nimport { RLY_SPLIT_DIFF_MIN_WIDTH, useNarrowerThan } from \"../../internal/useNarrowerThan.js\"\nimport type { DiffLine, FileDiff, Hunk } from \"./parse.js\"\n\nexport { findFile, parsePatch, pathsOf } from \"./parse.js\"\nexport type {\n DiffLine,\n FileDiff,\n FileStatus,\n Hunk,\n LineKind,\n ParseResult,\n Patch,\n PatchInvalid,\n PatchPrefixes\n} from \"./parse.js\"\n\nexport interface PatchDiffViewProps {\n readonly file: FileDiff\n /** Unique prefix for stable source-line links within the document. */\n readonly id: string\n readonly mode?: \"split\" | \"stacked\"\n readonly wrap?: boolean\n /** Called once for each visible side and line; consumers own annotation identity and content. */\n readonly renderAnnotation?: (side: \"old\" | \"new\", line: number) => ReactNode\n}\n\ninterface Row {\n readonly left: DiffLine | undefined\n readonly right: DiffLine | undefined\n}\n\n/** Pair consecutive deletions and additions without renumbering sparse patch hunks. */\nexport const pairRows = (hunk: Hunk): ReadonlyArray<Row> => {\n const rows: Array<Row> = []\n let index = 0\n while (index < hunk.lines.length) {\n const line = hunk.lines[index]\n if (line === undefined) break\n if (line.kind === \"context\") {\n rows.push({ left: line, right: line })\n index++\n continue\n }\n const deleted: Array<DiffLine> = []\n const added: Array<DiffLine> = []\n while (hunk.lines[index]?.kind === \"del\") {\n const next = hunk.lines[index++]\n if (next !== undefined) deleted.push(next)\n }\n while (hunk.lines[index]?.kind === \"add\") {\n const next = hunk.lines[index++]\n if (next !== undefined) added.push(next)\n }\n for (let offset = 0; offset < Math.max(deleted.length, added.length); offset++) {\n const left = deleted[offset]\n const right = added[offset]\n rows.push({ left, right })\n }\n }\n return rows\n}\n\n/** Render a patch as an accessible, server-renderable table. Source omissions stay omitted. */\nexport const PatchDiffView = ({\n file,\n id,\n mode = \"split\",\n renderAnnotation,\n wrap = false\n}: PatchDiffViewProps): ReactElement => {\n // A split view stacks in a narrow container, so neither side is clipped to a sliver.\n const [narrow, measureRef] = useNarrowerThan<HTMLDivElement>(RLY_SPLIT_DIFF_MIN_WIDTH)\n const shown = mode === \"split\" && narrow ? \"stacked\" : mode\n const cell = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n return (\n <>\n <td className={styles.lineNumber}>{number}</td>\n <td className={side === \"old\" ? styles.deletionCode : styles.additionCode}>\n {line === undefined ? null : (\n <>\n <code className={wrap ? styles.wrappedCode : styles.code} id={`${id}-${side}-${number}`} tabIndex={-1}>\n {line.text || \" \"}\n </code>\n {line.noNewline === true ? (\n <small aria-label={`${side === \"old\" ? \"Before\" : \"After\"}: no newline`}>\n No newline at end of file\n </small>\n ) : null}\n </>\n )}\n </td>\n </>\n )\n }\n const annotation = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n const content = number === undefined ? undefined : renderAnnotation?.(side, number)\n return content == null ? null : (\n <tr className={styles.annotationRow}>\n <td className={styles.annotationCell} colSpan={4}>\n {content}\n </td>\n </tr>\n )\n }\n return (\n <div className={styles.root} data-rly-patch-diff=\"\" data-rly-diff-mode={shown} ref={measureRef}>\n {file.oldMode === undefined && file.newMode === undefined ? null : (\n <p className={styles.noChanges}>\n {file.oldMode === undefined\n ? `Mode added: ${file.newMode}`\n : file.newMode === undefined\n ? `Mode removed: ${file.oldMode}`\n : `Mode: ${file.oldMode} → ${file.newMode}`}\n </p>\n )}\n {file.binary || file.hunks.length === 0 ? (\n <p className={styles.noChanges}>{file.binary ? \"Binary file.\" : \"No content change.\"}</p>\n ) : (\n <div style={{ overflowX: \"auto\" }} role=\"region\" aria-label={`Changes in ${file.path}`} tabIndex={0}>\n <table className={styles.table} aria-label={`Changes in ${file.path}`}>\n <thead>\n <tr>\n {shown === \"split\" ? (\n <>\n <th colSpan={2} scope=\"colgroup\">\n Before\n </th>\n <th colSpan={2} scope=\"colgroup\">\n After\n </th>\n </>\n ) : (\n <>\n <th scope=\"col\">Before</th>\n <th scope=\"col\">After</th>\n <th colSpan={2} scope=\"colgroup\">\n Change\n </th>\n </>\n )}\n </tr>\n </thead>\n <tbody>\n {file.hunks.map((hunk, hunkIndex) => (\n <Fragment key={hunkIndex}>\n <tr className={styles.hunk}>\n <td colSpan={4}>\n @@ {hunk.oldStart} → {hunk.newStart} {hunk.header}\n </td>\n </tr>\n {shown === \"split\"\n ? pairRows(hunk).map((row, rowIndex) => (\n <Fragment key={rowIndex}>\n <tr className={row.left?.kind === \"context\" ? styles.context : styles.change}>\n {cell(row.left, \"old\")}\n {cell(row.right, \"new\")}\n </tr>\n {annotation(row.left, \"old\")}\n {annotation(row.right, \"new\")}\n </Fragment>\n ))\n : hunk.lines.map((line, lineIndex) => (\n <Fragment key={lineIndex}>\n <tr\n className={\n line.kind === \"add\"\n ? styles.addition\n : line.kind === \"del\"\n ? styles.deletion\n : styles.context\n }\n >\n <td className={styles.lineNumber}>\n <span id={line.oldNo === undefined ? undefined : `${id}-old-${line.oldNo}`} tabIndex={-1}>\n {line.oldNo}\n </span>\n </td>\n <td className={styles.lineNumber}>\n <span id={line.newNo === undefined ? undefined : `${id}-new-${line.newNo}`} tabIndex={-1}>\n {line.newNo}\n </span>\n </td>\n <td className={styles.marker}>\n {line.kind === \"add\" ? \"+\" : line.kind === \"del\" ? \"−\" : \" \"}\n </td>\n <td>\n <code className={wrap ? styles.wrappedCode : styles.code}>{line.text || \" \"}</code>\n {line.noNewline === true ? (\n <small\n aria-label={\n line.kind === \"del\"\n ? \"Before: no newline\"\n : line.kind === \"add\"\n ? \"After: no newline\"\n : \"Before: no newline; After: no newline\"\n }\n >\n No newline at end of file\n </small>\n ) : null}\n </td>\n </tr>\n {annotation(line, \"old\")}\n {annotation(line, \"new\")}\n </Fragment>\n ))}\n </Fragment>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","styles","useNarrowerThan","Fragment$1","BoundedDiffCodeView_module_default","invalid","HUNK","HEADER","unquote","path","source","bytes","encoder","escapes","offset","match","literal","byte","code","trailing","headerPaths","candidates","index","header","left","right","destination","defaultPrefixes","prefixes","selected","oldPath","newPath","moved","unmarkedBinary","paths","binaryPaths","summary","body","selections","status","parsePatch","text","records","lines","line","files","currentPaths","movedSource","movedDestination","fileMode","oldMode","newMode","binary","binarySummary","hunks","oldEnd","newEnd","oldEof","newEof","oldCoordinates","newCoordinates","mode","value","kind","payload","readBinary","parsed","readHunk","record","hunk","markerStatus","start","chunks","first","lead","length","oldStart","newStart","oldCount","newCount","oldOffset","newOffset","oldNo","newNo","marker","previous","pathsOf","file","findFile","patch","pairRows","rows","deleted","added","next","PatchDiffView","narrow","measureRef","shown","cell","number","side","wrap","id","annotation","content","renderAnnotation","Fragment","row","rowIndex","lineIndex","hunkIndex"],"sources":["../../../src/diff/bounded/BoundedDiffCodeView.module.css","../../../src/diff/patch/parse.ts","../../../src/diff/patch/PatchDiffView.tsx"],"sourcesContent":["/* Code reads left to right whatever the page's direction; isolated so it never mirrors with an RTL host. */\n.root {\n direction: ltr;\n unicode-bidi: isolate;\n min-inline-size: 0;\n overflow: clip;\n border: 1px solid var(--rly-color-border-1);\n border-radius: var(--rly-radius-field);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n}\n\n.file + .file {\n border-block-start: 1px solid var(--rly-color-border-1);\n}\n\n.noChanges {\n margin: 0;\n padding: var(--rly-space-16);\n color: var(--rly-color-text-2);\n font: var(--rly-type-body-weight) var(--rly-type-body-size) / var(--rly-type-body-line-height)\n var(--rly-type-body-font);\n}\n\n.fileName {\n margin: 0;\n padding: var(--rly-space-12) var(--rly-space-16);\n border-block-end: 1px solid var(--rly-color-border-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.scroller {\n max-height: min(70vh, 56rem);\n overflow: auto;\n}\n\n.table {\n width: 100%;\n border-spacing: 0;\n border-collapse: collapse;\n font-family: var(--rly-font-mono);\n font-size: 0.78rem;\n line-height: 1.55;\n}\n\n.table td {\n min-width: 0;\n padding: 0;\n vertical-align: top;\n}\n\n.hunk td {\n padding: var(--rly-space-4) var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-1);\n background: var(--rly-color-surface-2);\n color: var(--rly-color-text-2);\n}\n\n.lineNumber {\n width: 3.25rem;\n /* Room either side of the number, so the column rule reads as one rule, not a box per line. */\n padding-inline: var(--rly-space-8) var(--rly-space-6) !important;\n border-inline-end: 1px solid var(--rly-color-border-1);\n color: var(--rly-color-text-3);\n text-align: end;\n user-select: none;\n}\n\n.marker {\n width: 1.5rem;\n color: var(--rly-color-text-3);\n text-align: center;\n user-select: none;\n}\n\n.code,\n.wrappedCode {\n display: block;\n min-height: 1.55em;\n padding-inline: var(--rly-space-12);\n white-space: pre;\n}\n\n.wrappedCode {\n white-space: pre-wrap;\n overflow-wrap: break-word;\n}\n\n/*\n * In an auto-sized table a long token would widen its column rather than wrap. Capping the wrapped\n * code cell at zero and letting it take the remaining width bounds it to the viewport, so\n * break-word can wrap a 200-character string; unwrapped views keep their horizontal scroll.\n */\n.table td:has(> .wrappedCode) {\n inline-size: 100%;\n max-inline-size: 0;\n}\n\n.deletion > td,\n.change .deletionCode {\n background: var(--rly-color-blocked-tint);\n}\n\n.addition > td,\n.change .additionCode {\n background: var(--rly-color-success-tint);\n}\n\n.deletion .lineNumber,\n.addition .lineNumber,\n.deletion .marker,\n.addition .marker {\n color: var(--rly-color-text-2);\n}\n\n.context > td {\n background: var(--rly-color-surface-1);\n}\n\n.deletionCode,\n.additionCode {\n width: 50%;\n border-inline-end: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > td {\n background: var(--rly-color-surface-2);\n border-block: 1px solid var(--rly-color-border-1);\n}\n\n.annotationRow > .annotationCell {\n padding: var(--rly-space-8);\n}\n\n.annotation {\n background: var(--rly-color-held-tint);\n border: 1px solid color-mix(in oklab, var(--rly-color-held-ink) 35%, transparent);\n border-radius: var(--rly-radius-tag);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n padding: var(--rly-space-8) var(--rly-space-12);\n}\n\n.annotation:focus-visible,\n[data-rly-diff-line]:focus-visible {\n outline: var(--rly-focus-ring-width) solid var(--rly-color-focus);\n outline-offset: var(--rly-focus-ring-offset);\n}\n\n@media (forced-colors: active) {\n .annotation,\n [data-rly-diff-line]:focus-visible {\n forced-color-adjust: auto;\n }\n}\n\n/*\n * Forced colours drop the add/remove tints. Split cells have no marker column, so a changed cell\n * gets its sign drawn before the code (hidden from assistive technology, which reads the column).\n */\n@media (forced-colors: active) {\n .change .deletionCode > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n }\n .change .additionCode > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n }\n}\n\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .deletionCode\n > :is(.code, .wrappedCode)::before {\n content: \"− \" / \"\";\n}\n:where([data-forced-colors=\"active\"], [data-rly-forced-colors=\"active\"])\n .change\n .additionCode\n > :is(.code, .wrappedCode)::before {\n content: \"+ \" / \"\";\n}\n","/**\n * A `git diff` parsed into files, hunks and numbered lines.\n *\n * Only what the renderer and the anchoring need: which files changed and how, and for\n * every line in a hunk its number on the old and the new side. Status, mode and body\n * evidence must agree; index and similarity values are not used for line anchoring.\n */\n\n/** A malformed patch cannot supply trustworthy source line positions. */\nexport interface PatchInvalid {\n readonly _tag: \"PatchInvalid\"\n readonly reason: string\n}\n\n/** What `parsePatch` returns: either a patch, or the reason it could not be trusted. */\nexport type ParseResult = { readonly _tag: \"Patch\"; readonly patch: Patch } | PatchInvalid\n\nconst invalid = (reason: string): PatchInvalid => ({ _tag: \"PatchInvalid\", reason })\n\ntype UnquotedPath = { readonly _tag: \"Path\"; readonly path: string } | PatchInvalid\nexport type LineKind = \"context\" | \"add\" | \"del\"\n\nexport interface DiffLine {\n readonly kind: LineKind\n readonly text: string\n /** Git EOF marker on this record: old side for deletions, new for additions, both for context. */\n readonly noNewline?: boolean\n /** Line number in the old file; absent on added lines. */\n readonly oldNo?: number\n /** Line number in the new file; absent on deleted lines. */\n readonly newNo?: number\n}\n\nexport interface Hunk {\n readonly header: string\n readonly oldStart: number\n readonly newStart: number\n readonly lines: ReadonlyArray<DiffLine>\n}\n\nexport type FileStatus = \"added\" | \"deleted\" | \"modified\" | \"renamed\" | \"copied\"\n\nexport interface FileDiff {\n /** The path a guide refers to: the new path, or the old one when the file was deleted. */\n readonly path: string\n readonly oldPath: string\n readonly newPath: string\n readonly status: FileStatus\n readonly binary: boolean\n /** Explicit mode headers only; an absent side or unreported mode stays absent. */\n readonly oldMode?: string\n readonly newMode?: string\n readonly hunks: ReadonlyArray<Hunk>\n}\n\nexport interface Patch {\n readonly files: ReadonlyArray<FileDiff>\n}\n\nconst HUNK = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@(.*)$/\nconst HEADER = \"diff --git \"\n\n/** Exact Git producer prefixes. Use two empty strings for --no-prefix, including paths resembling a/ and b/. */\nexport interface PatchPrefixes {\n readonly source: string\n readonly destination: string\n}\n\nconst unquote = (path: string): UnquotedPath => {\n if (path.includes(\"\\u0000\")) return invalid(\"Git paths cannot contain NUL\")\n if (!path.startsWith(\"\\\"\")) return { _tag: \"Path\", path }\n if (!path.endsWith(\"\\\"\")) return invalid(\"Unclosed quoted path\")\n const source = path.slice(1, -1)\n const bytes: Array<number> = []\n const encoder = new TextEncoder()\n const escapes = new Map([\n [\"a\", 7],\n [\"b\", 8],\n [\"t\", 9],\n [\"n\", 10],\n [\"v\", 11],\n [\"f\", 12],\n [\"r\", 13],\n [\"\\\"\", 34],\n [\"\\\\\", 92]\n ])\n let offset = 0\n for (const match of source.matchAll(/\\\\([0-7]{3}|.)/gs)) {\n const literal = source.slice(offset, match.index)\n if (literal.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(literal)) bytes.push(byte)\n const code = match[1] ?? \"\"\n const byte = /^[0-7]{3}$/.test(code) ? parseInt(code, 8) : escapes.get(code)\n if (byte === undefined || byte === 0 || byte > 255) return invalid(\"Invalid quoted path escape\")\n bytes.push(byte)\n offset = match.index + match[0].length\n }\n const trailing = source.slice(offset)\n if (trailing.includes(\"\\\\\")) return invalid(\"Dangling quoted path escape\")\n if (trailing.includes(\"\\\"\")) return invalid(\"Unescaped quote in quoted path\")\n for (const byte of encoder.encode(trailing)) bytes.push(byte)\n try {\n return {\n _tag: \"Path\",\n path: new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true }).decode(new Uint8Array(bytes))\n }\n } catch {\n return invalid(\"Quoted Git path is not valid UTF-8\")\n }\n}\n\n/** Resolve header boundaries against file markers; spaces in unquoted filenames are legal Git output. */\nconst headerPaths = (\n header: string,\n source: string | undefined,\n destination: string | undefined,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n unmarkedBinary = false\n): { readonly _tag: \"Paths\"; readonly oldPath: string; readonly newPath: string } | PatchInvalid => {\n const candidates: Array<{ readonly oldPath: string; readonly newPath: string }> = []\n for (let index = 0; index < header.length; index++) {\n if (header[index] !== \" \") continue\n const left = unquote(header.slice(0, index))\n const right = unquote(header.slice(index + 1))\n if (left._tag === \"PatchInvalid\" || right._tag === \"PatchInvalid\") continue\n if (left.path === \"\" || right.path === \"\") continue\n if (source !== undefined && source !== \"/dev/null\" && source !== left.path) continue\n if (destination !== undefined && destination !== \"/dev/null\" && destination !== right.path) continue\n const defaultPrefixes = prefixes === undefined && left.path.startsWith(\"a/\") && right.path.startsWith(\"b/\")\n const selected = prefixes ?? (defaultPrefixes\n ? { source: \"a/\", destination: \"b/\" }\n : { source: \"\", destination: \"\" })\n if (!left.path.startsWith(selected.source) || !right.path.startsWith(selected.destination)) continue\n const oldPath = left.path.slice(selected.source.length)\n const newPath = right.path.slice(selected.destination.length)\n if (oldPath === \"\" || newPath === \"\") continue\n if (moved !== undefined && (oldPath !== moved.source || newPath !== moved.destination)) continue\n if (\n moved === undefined && source === undefined && destination === undefined && oldPath !== newPath &&\n !(unmarkedBinary && (defaultPrefixes || prefixes !== undefined))\n ) continue\n candidates.push({ oldPath, newPath })\n }\n const paths = candidates[0]\n return candidates.length === 1 && paths !== undefined\n ? { _tag: \"Paths\", ...paths }\n : invalid(\"Inconsistent or ambiguous Git file headers; custom prefixes must be supplied explicitly\")\n}\n\n/** Match every possible summary separator against the authoritative header, including quoted and spaced paths. */\nconst binaryPaths = (\n header: string,\n summary: string,\n prefixes: PatchPrefixes | undefined,\n moved: { readonly source: string; readonly destination: string } | undefined,\n status: FileStatus\n): ReturnType<typeof headerPaths> => {\n if (!summary.endsWith(\" differ\")) return invalid(\"Incomplete binary summary\")\n const body = summary.slice(\"Binary files \".length, -\" differ\".length)\n // Auto mode tries Git's standard prefixes before an unprefixed producer.\n // Otherwise a filename ending in \" and\" can fabricate a second no-prefix interpretation.\n const selections = prefixes === undefined\n ? [{ source: \"a/\", destination: \"b/\" }, { source: \"\", destination: \"\" }]\n : [prefixes]\n for (const selected of selections) {\n const candidates: Array<Extract<ReturnType<typeof headerPaths>, { readonly _tag: \"Paths\" }>> = []\n for (const match of body.matchAll(/(?= and )/g)) {\n const source = unquote(body.slice(0, match.index))\n const destination = unquote(body.slice(match.index + \" and \".length))\n if (source._tag === \"PatchInvalid\" || destination._tag === \"PatchInvalid\") continue\n if ((source.path === \"/dev/null\") !== (status === \"added\")) continue\n if ((destination.path === \"/dev/null\") !== (status === \"deleted\")) continue\n const paths = headerPaths(header, source.path, destination.path, selected, moved)\n if (paths._tag === \"Paths\") candidates.push(paths)\n }\n const paths = candidates[0]\n if (candidates.length === 1 && paths !== undefined) return paths\n if (candidates.length > 1) return invalid(\"Ambiguous binary summary paths\")\n }\n return invalid(\"Binary summary paths disagree with Git headers\")\n}\n\n/** Infer default a/b prefixes when present; pass explicit empty prefixes for unambiguous --no-prefix parsing. */\nexport const parsePatch = (text: string, prefixes?: PatchPrefixes): ParseResult => {\n if (text !== \"\" && !text.endsWith(\"\\n\")) return invalid(\"Unterminated patch record\")\n // A CR on a Git header identifies transport line endings; body-only CR belongs to the source.\n const records = text.split(\"\\n\")\n const converted = records.some((line) => line.startsWith(HEADER) && line.endsWith(\"\\r\"))\n const lines = converted ? records.map((line) => line.endsWith(\"\\r\") ? line.slice(0, -1) : line) : records\n const files: Array<FileDiff> = []\n const currentPaths = new Set<string>()\n let index = 0\n\n while (index < lines.length) {\n const line = lines[index] ?? \"\"\n if (!line.startsWith(HEADER)) {\n index += 1\n continue\n }\n const header = line.slice(HEADER.length)\n let source: string | undefined\n let destination: string | undefined\n let movedSource: string | undefined\n let movedDestination: string | undefined\n let status: FileStatus = \"modified\"\n let fileMode: string | undefined\n let oldMode: string | undefined\n let newMode: string | undefined\n let binary = false\n let binarySummary: string | undefined\n const hunks: Array<Hunk> = []\n let oldEnd = 0\n let newEnd = 0\n let oldEof = false\n let newEof = false\n const oldCoordinates = new Set<number>()\n const newCoordinates = new Set<number>()\n index += 1\n\n while (index < lines.length && !(lines[index] ?? \"\").startsWith(HEADER)) {\n const line = lines[index] ?? \"\"\n if (/^(new file|deleted file|old|new) mode/.test(line)) {\n const mode = /^(new file|deleted file|old|new) mode ([0-7]{6})$/.exec(line)\n if (mode === null) return invalid(\"Invalid file mode header\")\n const value = mode[2]\n if (mode[1] === \"old\") {\n if (oldMode !== undefined && oldMode !== value) return invalid(\"Conflicting old modes\")\n oldMode = value\n } else if (mode[1] === \"new\") {\n if (newMode !== undefined && newMode !== value) return invalid(\"Conflicting new modes\")\n newMode = value\n } else {\n const kind = mode[1] === \"new file\" ? \"added\" : \"deleted\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n if (fileMode !== undefined && fileMode !== value) return invalid(\"Conflicting file modes\")\n status = kind\n fileMode = value\n }\n } else if (/^(rename|copy) (from|to) /.test(line)) {\n const kind = line.startsWith(\"copy \") ? \"copied\" : \"renamed\"\n if (status !== \"modified\" && status !== kind) return invalid(\"Conflicting file status headers\")\n status = kind\n const path = unquote(line.replace(/^(rename|copy) (from|to) /, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (/^(rename|copy) from /.test(line)) {\n if (movedSource !== undefined && movedSource !== path.path) return invalid(\"Conflicting move source paths\")\n movedSource = path.path\n } else {\n if (movedDestination !== undefined && movedDestination !== path.path) {\n return invalid(\"Conflicting move destination paths\")\n }\n movedDestination = path.path\n }\n } else if (line.startsWith(\"GIT binary patch\")) {\n if (line !== \"GIT binary patch\") return invalid(\"Invalid binary patch marker\")\n const payload = readBinary(lines, index + 1)\n if (payload._tag === \"PatchInvalid\") return payload\n binary = true\n index = payload.next\n continue\n } else if (line.startsWith(\"Binary files \")) {\n if (binarySummary !== undefined && binarySummary !== line) return invalid(\"Conflicting binary summaries\")\n binarySummary = line\n binary = true\n } else if (line.startsWith(\"--- \") || line.startsWith(\"+++ \")) {\n const path = unquote(line.slice(4).replace(/\\t$/, \"\"))\n if (path._tag === \"PatchInvalid\") return path\n if (line.startsWith(\"--- \")) {\n if (source !== undefined && source !== path.path) return invalid(\"Conflicting source file markers\")\n source = path.path\n } else {\n if (destination !== undefined && destination !== path.path) {\n return invalid(\"Conflicting destination file markers\")\n }\n destination = path.path\n }\n } else if (HUNK.test(line)) {\n if (source === undefined || destination === undefined) return invalid(\"Text hunks require paired file markers\")\n const parsed = readHunk(lines, index)\n if (parsed._tag === \"PatchInvalid\") return parsed\n if (!parsed.hunk.lines.some((record) => record.kind === \"add\" || record.kind === \"del\")) {\n return invalid(\"Text hunk has no change evidence\")\n }\n if (parsed.oldOffset < oldEnd || parsed.newOffset < newEnd) return invalid(\"Hunk ranges move backwards\")\n oldEnd = parsed.oldEnd\n newEnd = parsed.newEnd\n for (const record of parsed.hunk.lines) {\n if ((oldEof && record.oldNo !== undefined) || (newEof && record.newNo !== undefined)) {\n return invalid(\"Patch records follow an EOF marker on the same side\")\n }\n if (record.noNewline === true) {\n oldEof ||= record.oldNo !== undefined\n newEof ||= record.newNo !== undefined\n }\n if (\n (record.oldNo !== undefined && oldCoordinates.has(record.oldNo)) ||\n (record.newNo !== undefined && newCoordinates.has(record.newNo))\n ) return invalid(`Overlapping hunk at line ${index + 1}`)\n if (record.oldNo !== undefined) oldCoordinates.add(record.oldNo)\n if (record.newNo !== undefined) newCoordinates.add(record.newNo)\n }\n hunks.push(parsed.hunk)\n index = parsed.next\n continue\n } else if (/^(?:@@|[+\\- \\\\])/.test(line)) {\n return invalid(`Unexpected patch body at line ${index + 1}`)\n }\n index += 1\n }\n if ((source === undefined) !== (destination === undefined)) return invalid(\"Unpaired file markers\")\n if ((movedSource === undefined) !== (movedDestination === undefined)) {\n return invalid(\"Unpaired rename or copy headers\")\n }\n if ((oldMode === undefined) !== (newMode === undefined)) return invalid(\"Unpaired mode transition\")\n if (fileMode !== undefined && oldMode !== undefined) return invalid(\"Conflicting file mode headers\")\n if (oldMode !== undefined && (source === \"/dev/null\" || destination === \"/dev/null\")) {\n return invalid(\"Mode transition requires both file sides\")\n }\n if (binary && source !== undefined) return invalid(\"Mixed binary and text bodies\")\n if (source !== undefined && hunks.length === 0) return invalid(\"Text markers require hunks\")\n if (source === \"/dev/null\" && destination === \"/dev/null\") return invalid(\"Both file sides are absent\")\n if (\n hunks.some((hunk) =>\n hunk.lines.some((line) =>\n (source === \"/dev/null\" && line.oldNo !== undefined) ||\n (destination === \"/dev/null\" && line.newNo !== undefined)\n )\n )\n ) return invalid(\"Absent file side contains text lines\")\n if (source !== undefined) {\n const markerStatus = source === \"/dev/null\" ? \"added\" : destination === \"/dev/null\" ? \"deleted\" : \"modified\"\n if (\n (status === \"added\" || status === \"deleted\" || markerStatus !== \"modified\") &&\n status !== \"modified\" && status !== markerStatus\n ) return invalid(\"File status disagrees with file markers\")\n if (markerStatus !== \"modified\") status = markerStatus\n }\n if (\n hunks.length === 0 && !binary && movedSource === undefined && fileMode === undefined &&\n (oldMode === undefined || oldMode === newMode)\n ) return invalid(\"File block has no change evidence\")\n const moved = movedSource === undefined || movedDestination === undefined\n ? undefined\n : { source: movedSource, destination: movedDestination }\n const paths = binarySummary === undefined\n ? headerPaths(header, source, destination, prefixes, moved, binary)\n : binaryPaths(header, binarySummary, prefixes, moved, status)\n if (paths._tag === \"PatchInvalid\") return paths\n if (\n binary && source === undefined && moved === undefined && status !== \"modified\" && paths.oldPath !== paths.newPath\n ) {\n return invalid(\"Binary addition or deletion has conflicting header paths\")\n }\n const path = status === \"deleted\" ? paths.oldPath : paths.newPath\n if (currentPaths.has(path)) return invalid(\"Duplicate canonical current file path\")\n currentPaths.add(path)\n files.push({\n path,\n oldPath: paths.oldPath,\n newPath: paths.newPath,\n status,\n binary,\n ...(status === \"deleted\" && fileMode !== undefined\n ? { oldMode: fileMode }\n : oldMode === undefined\n ? {}\n : { oldMode }),\n ...(status === \"added\" && fileMode !== undefined\n ? { newMode: fileMode }\n : newMode === undefined\n ? {}\n : { newMode }),\n hunks\n })\n }\n if (files.length === 0 && text.trim() !== \"\") return invalid(\"Expected a git unified diff\")\n return { _tag: \"Patch\", patch: { files } }\n}\n\n/** Validate Git's literal/delta record framing without inflating or applying binary content. */\nconst readBinary = (\n lines: ReadonlyArray<string>,\n start: number\n): { readonly _tag: \"Binary\"; readonly next: number } | PatchInvalid => {\n let index = start\n let chunks = 0\n do {\n const header = /^(literal|delta) (\\d+)$/.exec(lines[index] ?? \"\")\n if (header === null || !Number.isSafeInteger(Number(header[2]))) return invalid(\"Invalid binary chunk header\")\n index += 1\n const first = index\n while (index < lines.length && lines[index] !== \"\") {\n const line = lines[index] ?? \"\"\n const lead = line.charCodeAt(0)\n const length = lead >= 65 && lead <= 90 ? lead - 64 : lead >= 97 && lead <= 122 ? lead - 70 : 0\n if (\n length === 0 || line.length !== 1 + Math.ceil(length / 4) * 5 ||\n !/^[0-9A-Za-z!#$%&()*+;<=>?@^_`{|}~-]+$/.test(line.slice(1))\n ) return invalid(\"Invalid binary chunk data\")\n index += 1\n }\n // A final split sentinel is not the blank record that terminates a Git payload.\n if (index === first || index >= lines.length - 1) return invalid(\"Incomplete binary chunk\")\n index += 1\n chunks += 1\n } while (chunks < 2 && /^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\"))\n if (/^(literal|delta)(?:\\s|$)/.test(lines[index] ?? \"\")) return invalid(\"Surplus binary chunk\")\n return { _tag: \"Binary\", next: index }\n}\n\nconst readHunk = (\n lines: ReadonlyArray<string>,\n start: number\n): {\n readonly _tag: \"Hunk\"\n readonly hunk: Hunk\n readonly next: number\n readonly oldOffset: number\n readonly newOffset: number\n readonly oldEnd: number\n readonly newEnd: number\n} | PatchInvalid => {\n const match = HUNK.exec(lines[start] ?? \"\")\n if (match === null) return invalid(`not a hunk header at line ${start + 1}`)\n const oldStart = Number(match[1])\n const newStart = Number(match[3])\n let oldCount = match[2] === undefined ? 1 : Number(match[2])\n let newCount = match[4] === undefined ? 1 : Number(match[4])\n if (![oldStart, newStart, oldCount, newCount].every(Number.isSafeInteger)) return invalid(\"Unsafe hunk integers\")\n if (oldCount === 0 && newCount === 0) return invalid(\"Empty hunk\")\n if (\n (oldCount > 0 && !Number.isSafeInteger(oldStart + (oldCount - 1))) ||\n (newCount > 0 && !Number.isSafeInteger(newStart + (newCount - 1)))\n ) return invalid(\"Hunk coordinates overflow\")\n // Half-open zero-based ranges: empty Git ranges anchor after the named line.\n const oldOffset = oldStart - (oldCount === 0 ? 0 : 1)\n const newOffset = newStart - (newCount === 0 ? 0 : 1)\n const oldEnd = oldOffset + oldCount\n const newEnd = newOffset + newCount\n let oldNo = oldStart\n let newNo = newStart\n const body: Array<DiffLine> = []\n let index = start + 1\n\n while (index < lines.length && (oldCount > 0 || newCount > 0)) {\n const line = lines[index] ?? \"\"\n const marker = line[0]\n const text = line.slice(1)\n if (marker === \"+\") {\n body.push({ kind: \"add\", text, newNo })\n newNo += 1\n newCount -= 1\n } else if (marker === \"-\") {\n body.push({ kind: \"del\", text, oldNo })\n oldNo += 1\n oldCount -= 1\n } else if (marker === \" \") {\n body.push({ kind: \"context\", text, oldNo, newNo })\n oldNo += 1\n newNo += 1\n oldCount -= 1\n newCount -= 1\n } else {\n break\n }\n index += 1\n // A marker belongs to exactly one preceding body record and consumes no coordinate.\n if ((lines[index] ?? \"\").startsWith(\"\\\\\")) {\n if (lines[index] !== \"\\\\") return invalid(`Invalid newline marker at line ${index + 1}`)\n const previous = body[body.length - 1]\n if (previous !== undefined) body[body.length - 1] = { ...previous, noNewline: true }\n index += 1\n }\n }\n if (oldCount !== 0 || newCount !== 0) return invalid(`Incomplete hunk at line ${start + 1}`)\n\n return {\n _tag: \"Hunk\",\n oldOffset,\n newOffset,\n oldEnd,\n newEnd,\n hunk: { header: match[5]?.trim() ?? \"\", oldStart, newStart, lines: body },\n next: index\n }\n}\n\n/** Changed-file paths: the current name first, then the source of a rename or modified comparison. */\nexport const pathsOf = (file: FileDiff): ReadonlyArray<string> =>\n file.status === \"renamed\" || (file.status === \"modified\" && file.oldPath !== file.newPath)\n ? [file.newPath, file.oldPath]\n : [file.path]\n\nexport const findFile = (patch: Patch, path: string): FileDiff | undefined =>\n patch.files.find((file) => file.path === path) ?? patch.files.find((file) => pathsOf(file).includes(path))\n","import { Fragment, type ReactElement, type ReactNode } from \"react\"\nimport styles from \"../bounded/BoundedDiffCodeView.module.css\"\nimport { RLY_SPLIT_DIFF_MIN_WIDTH, useNarrowerThan } from \"../../internal/useNarrowerThan.js\"\nimport type { DiffLine, FileDiff, Hunk } from \"./parse.js\"\n\nexport { findFile, parsePatch, pathsOf } from \"./parse.js\"\nexport type {\n DiffLine,\n FileDiff,\n FileStatus,\n Hunk,\n LineKind,\n ParseResult,\n Patch,\n PatchInvalid,\n PatchPrefixes\n} from \"./parse.js\"\n\nexport interface PatchDiffViewProps {\n readonly file: FileDiff\n /** Unique prefix for stable source-line links within the document. */\n readonly id: string\n readonly mode?: \"split\" | \"stacked\"\n readonly wrap?: boolean\n /** Called once for each visible side and line; consumers own annotation identity and content. */\n readonly renderAnnotation?: (side: \"old\" | \"new\", line: number) => ReactNode\n}\n\ninterface Row {\n readonly left: DiffLine | undefined\n readonly right: DiffLine | undefined\n}\n\n/** Pair consecutive deletions and additions without renumbering sparse patch hunks. */\nexport const pairRows = (hunk: Hunk): ReadonlyArray<Row> => {\n const rows: Array<Row> = []\n let index = 0\n while (index < hunk.lines.length) {\n const line = hunk.lines[index]\n if (line === undefined) break\n if (line.kind === \"context\") {\n rows.push({ left: line, right: line })\n index++\n continue\n }\n const deleted: Array<DiffLine> = []\n const added: Array<DiffLine> = []\n while (hunk.lines[index]?.kind === \"del\") {\n const next = hunk.lines[index++]\n if (next !== undefined) deleted.push(next)\n }\n while (hunk.lines[index]?.kind === \"add\") {\n const next = hunk.lines[index++]\n if (next !== undefined) added.push(next)\n }\n for (let offset = 0; offset < Math.max(deleted.length, added.length); offset++) {\n const left = deleted[offset]\n const right = added[offset]\n rows.push({ left, right })\n }\n }\n return rows\n}\n\n/** Render a patch as an accessible, server-renderable table. Source omissions stay omitted. */\nexport const PatchDiffView = ({\n file,\n id,\n mode = \"split\",\n renderAnnotation,\n wrap = false\n}: PatchDiffViewProps): ReactElement => {\n // A split view stacks in a narrow container, so neither side is clipped to a sliver.\n const [narrow, measureRef] = useNarrowerThan<HTMLDivElement>(RLY_SPLIT_DIFF_MIN_WIDTH)\n const shown = mode === \"split\" && narrow ? \"stacked\" : mode\n const cell = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n return (\n <>\n <td className={styles.lineNumber}>{number}</td>\n <td className={side === \"old\" ? styles.deletionCode : styles.additionCode}>\n {line === undefined ? null : (\n <>\n <code className={wrap ? styles.wrappedCode : styles.code} id={`${id}-${side}-${number}`} tabIndex={-1}>\n {line.text || \" \"}\n </code>\n {line.noNewline === true ? (\n <small aria-label={`${side === \"old\" ? \"Before\" : \"After\"}: no newline`}>\n No newline at end of file\n </small>\n ) : null}\n </>\n )}\n </td>\n </>\n )\n }\n const annotation = (line: DiffLine | undefined, side: \"old\" | \"new\") => {\n const number = side === \"old\" ? line?.oldNo : line?.newNo\n const content = number === undefined ? undefined : renderAnnotation?.(side, number)\n return content == null ? null : (\n <tr className={styles.annotationRow}>\n <td className={styles.annotationCell} colSpan={4}>\n {content}\n </td>\n </tr>\n )\n }\n return (\n <div className={styles.root} data-rly-patch-diff=\"\" data-rly-diff-mode={shown} ref={measureRef}>\n {file.oldMode === undefined && file.newMode === undefined ? null : (\n <p className={styles.noChanges}>\n {file.oldMode === undefined\n ? `Mode added: ${file.newMode}`\n : file.newMode === undefined\n ? `Mode removed: ${file.oldMode}`\n : `Mode: ${file.oldMode} → ${file.newMode}`}\n </p>\n )}\n {file.binary || file.hunks.length === 0 ? (\n <p className={styles.noChanges}>{file.binary ? \"Binary file.\" : \"No content change.\"}</p>\n ) : (\n <div style={{ overflowX: \"auto\" }} role=\"region\" aria-label={`Changes in ${file.path}`} tabIndex={0}>\n <table className={styles.table} aria-label={`Changes in ${file.path}`}>\n <thead>\n <tr>\n {shown === \"split\" ? (\n <>\n <th colSpan={2} scope=\"colgroup\">\n Before\n </th>\n <th colSpan={2} scope=\"colgroup\">\n After\n </th>\n </>\n ) : (\n <>\n <th scope=\"col\">Before</th>\n <th scope=\"col\">After</th>\n <th colSpan={2} scope=\"colgroup\">\n Change\n </th>\n </>\n )}\n </tr>\n </thead>\n <tbody>\n {file.hunks.map((hunk, hunkIndex) => (\n <Fragment key={hunkIndex}>\n <tr className={styles.hunk}>\n <td colSpan={4}>\n @@ {hunk.oldStart} → {hunk.newStart} {hunk.header}\n </td>\n </tr>\n {shown === \"split\"\n ? pairRows(hunk).map((row, rowIndex) => (\n <Fragment key={rowIndex}>\n <tr className={row.left?.kind === \"context\" ? styles.context : styles.change}>\n {cell(row.left, \"old\")}\n {cell(row.right, \"new\")}\n </tr>\n {annotation(row.left, \"old\")}\n {annotation(row.right, \"new\")}\n </Fragment>\n ))\n : hunk.lines.map((line, lineIndex) => (\n <Fragment key={lineIndex}>\n <tr\n className={\n line.kind === \"add\"\n ? styles.addition\n : line.kind === \"del\"\n ? styles.deletion\n : styles.context\n }\n >\n <td className={styles.lineNumber}>\n <span id={line.oldNo === undefined ? undefined : `${id}-old-${line.oldNo}`} tabIndex={-1}>\n {line.oldNo}\n </span>\n </td>\n <td className={styles.lineNumber}>\n <span id={line.newNo === undefined ? undefined : `${id}-new-${line.newNo}`} tabIndex={-1}>\n {line.newNo}\n </span>\n </td>\n <td className={styles.marker}>\n {line.kind === \"add\" ? \"+\" : line.kind === \"del\" ? \"−\" : \" \"}\n </td>\n <td>\n <code className={wrap ? styles.wrappedCode : styles.code}>{line.text || \" \"}</code>\n {line.noNewline === true ? (\n <small\n aria-label={\n line.kind === \"del\"\n ? \"Before: no newline\"\n : line.kind === \"add\"\n ? \"After: no newline\"\n : \"Before: no newline; After: no newline\"\n }\n >\n No newline at end of file\n </small>\n ) : null}\n </td>\n </tr>\n {annotation(line, \"old\")}\n {annotation(line, \"new\")}\n </Fragment>\n ))}\n </Fragment>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
/** Stable, presentation-only glyph names supported by rly. */
|
|
3
|
-
export declare const RLY_ICON_NAMES: readonly ["arrow-down", "arrow-left", "arrow-right", "arrow-up", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "alert", "clock", "external-link", "file", "link", "loader", "menu", "minus", "plus", "search", "user", "close"];
|
|
3
|
+
export declare const RLY_ICON_NAMES: readonly ["arrow-down", "arrow-left", "arrow-right", "arrow-up", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "alert", "clock", "external-link", "file", "link", "loader", "menu", "minus", "plus", "search", "user", "close", "pin"];
|
|
4
4
|
/** A stable glyph name owned by rly rather than its icon implementation. */
|
|
5
5
|
export type RlyIconName = (typeof RLY_ICON_NAMES)[number];
|
|
6
6
|
/** Machine-readable icon size variants. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/foundations/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAY,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/foundations/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAY,MAAM,OAAO,CAAA;AA6BlE,8DAA8D;AAC9D,eAAO,MAAM,cAAc,kQAuBzB,CAAA;AAEF,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzD,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB;;QAE1B,KAAK;YAAI,MAAM;YAAM,OAAO;;QAC5B,OAAO;YAAI,MAAM;YAAM,OAAO;;QAC9B,KAAK;YAAI,MAAM;YAAM,OAAO;;;CAe/B,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,yBAAyB;;CAE2D,CAAA;AAEjG,uCAAuC;AACvC,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,iBAAiB,CAAC,IAAI,CAAA;AA6B7D,UAAU,eAAe;IACvB,kDAAkD;IAClD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAC5B;AAED,UAAU,mBAAmB;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CACvB;AAED,UAAU,oBAAoB;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAA;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,wDAAwD;AACxD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,CAAC,mBAAmB,GAAG,oBAAoB,CAAC,CAAA;AAKtF,yFAAyF;AACzF,eAAO,MAAM,IAAI,UAAW,SAAS,KAAG,YAuBvC,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface ShadowRootHost extends Node {
|
|
2
|
+
readonly host: Element;
|
|
3
|
+
}
|
|
4
|
+
export declare const hasShadowRootHost: (value: Node) => value is ShadowRootHost;
|
|
5
|
+
export declare const activeElementFor: (panel: HTMLElement) => Element | null;
|
|
6
|
+
export declare const composedParentFor: (node: Node, composedParents?: ReadonlyMap<Node, Node | null>) => Element | null;
|
|
7
|
+
export declare const isWithinComposedElement: (ancestor: Element, descendant: Node | null, composedParents?: ReadonlyMap<Node, Node | null>) => boolean;
|
|
8
|
+
export declare const isWithinPanel: (panel: HTMLElement, active: Element | null) => boolean;
|
|
9
|
+
export declare const focusRestoreTarget: (ownerDocument: Document) => HTMLElement | null;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=composedFocus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composedFocus.d.ts","sourceRoot":"","sources":["../../../src/internal/composedFocus.ts"],"names":[],"mappings":"AAMA,UAAU,cAAe,SAAQ,IAAI;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED,eAAO,MAAM,iBAAiB,UAAW,IAAI,KAAG,KAAK,IAAI,cACC,CAAA;AAS1D,eAAO,MAAM,gBAAgB,UAAW,WAAW,KAAG,OAAO,GAAG,IAG/D,CAAA;AAgBD,eAAO,MAAM,iBAAiB,SAAU,IAAI,oBAAoB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,KAAG,OAAO,GAAG,IAO1G,CAAA;AAED,eAAO,MAAM,uBAAuB,aACxB,OAAO,cACL,IAAI,GAAG,IAAI,oBACL,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,KAC/C,OAaF,CAAA;AAED,eAAO,MAAM,aAAa,UAAW,WAAW,UAAU,OAAO,GAAG,IAAI,KAAG,OACnC,CAAA;AAQxC,eAAO,MAAM,kBAAkB,kBAAmB,QAAQ,KAAG,WAAW,GAAG,IAG1E,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** A key the summon machine listens for: the bound chord (Ctrl/⌘+J) or Escape. */
|
|
2
|
+
export type RelaySummonKey = "chord" | "escape";
|
|
3
|
+
/** What the machine needs to know at the moment a key arrives. */
|
|
4
|
+
export interface RelaySummonContext {
|
|
5
|
+
readonly open: boolean;
|
|
6
|
+
/** Focus is inside the Relay region. */
|
|
7
|
+
readonly focusInRelay: boolean;
|
|
8
|
+
/** Relay is a full-screen dialog (phone), where the chord and Escape both close it. */
|
|
9
|
+
readonly fullscreen: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* What a key does (Relay UX decision): closed → Open (focus the composer); open with focus on the page →
|
|
13
|
+
* FocusComposer; open with focus in Relay → ReturnFocus (back to where you were, Relay stays open);
|
|
14
|
+
* full screen, the chord closes. Escape closes when focus is in Relay or Relay is full screen, and is
|
|
15
|
+
* left to the page otherwise. Ignore means the event is not handled and must not be prevented.
|
|
16
|
+
*/
|
|
17
|
+
export type RelaySummonEffect = "Open" | "FocusComposer" | "ReturnFocus" | "Close" | "Ignore";
|
|
18
|
+
export declare const relaySummonTransition: (context: RelaySummonContext, key: RelaySummonKey) => RelaySummonEffect;
|
|
19
|
+
/** The parts of a keyboard event the summon reads. */
|
|
20
|
+
export interface RelaySummonKeyEvent {
|
|
21
|
+
readonly altKey: boolean;
|
|
22
|
+
readonly code: string;
|
|
23
|
+
readonly ctrlKey: boolean;
|
|
24
|
+
readonly isComposing: boolean;
|
|
25
|
+
readonly key: string;
|
|
26
|
+
/** Deprecated, but 229 is still how some browsers mark a key that belongs to an IME. */
|
|
27
|
+
readonly keyCode: number;
|
|
28
|
+
readonly metaKey: boolean;
|
|
29
|
+
readonly repeat: boolean;
|
|
30
|
+
readonly shiftKey: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** A key that belongs to an IME composition; Escape there cancels the composition, never Relay. */
|
|
33
|
+
export declare const isImeKey: (event: RelaySummonKeyEvent) => boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether an event is exactly the shortcut's ARIA keys ("Control+J", "Meta+J"): the named modifiers and
|
|
36
|
+
* no others, so Ctrl+Shift+J, Alt chords, an IME composition or a held key's repeats never match. A
|
|
37
|
+
* Latin layout matches the letter the user sees (Dvorak, AZERTY); a non-Latin one (Russian, Greek), where
|
|
38
|
+
* the key is no ASCII letter, matches the physical key instead.
|
|
39
|
+
*/
|
|
40
|
+
export declare const matchesShortcutKeys: (keys: string, event: RelaySummonKeyEvent) => boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a key event belongs to a layer nested in or opened from Relay: a dialog, a listbox or menu
|
|
43
|
+
* while it is an open popup (Radix's data-state, or the target of an expanded aria-controls), or an
|
|
44
|
+
* expanded popup controller inside Relay that keeps focus while its popup is open (a combobox). It reads
|
|
45
|
+
* the event's composed path up to Relay's region, so layers inside shadow roots and layers portaled out
|
|
46
|
+
* of Relay (whose path never reaches the region) count. Relay's own surface, marked
|
|
47
|
+
* data-rly-relay-surface (the full-screen dialog), and always-rendered lists never count.
|
|
48
|
+
*/
|
|
49
|
+
export declare const hasNestedLayer: (region: HTMLElement | null, path: ReadonlyArray<EventTarget>) => boolean;
|
|
50
|
+
//# sourceMappingURL=relaySummon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relaySummon.d.ts","sourceRoot":"","sources":["../../../src/internal/relaySummon.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE/C,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,wCAAwC;IACxC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,uFAAuF;IACvF,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAC7B;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,eAAe,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE7F,eAAO,MAAM,qBAAqB,YAAa,kBAAkB,OAAO,cAAc,KAAG,iBAKxF,CAAA;AAED,sDAAsD;AACtD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,mGAAmG;AACnG,eAAO,MAAM,QAAQ,UAAW,mBAAmB,KAAG,OAAqD,CAAA;AAI3G;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,SAAU,MAAM,SAAS,mBAAmB,KAAG,OAe9E,CAAA;AAKD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,WAAY,WAAW,GAAG,IAAI,QAAQ,aAAa,CAAC,WAAW,CAAC,KAAG,OAU7F,CAAA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode, Ref } from "react";
|
|
2
|
+
/** Something the message is about, shown as a removable chip ("patch-reader.ts lines 14 to 19"). */
|
|
3
|
+
export interface RlyRelayContextRef {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
}
|
|
7
|
+
/** One accepted-message request: the text and the client request id a retry must reuse. */
|
|
8
|
+
export interface RlyRelaySubmission {
|
|
9
|
+
readonly requestId: string;
|
|
10
|
+
readonly text: string;
|
|
11
|
+
}
|
|
12
|
+
/** Inputs for the composer. */
|
|
13
|
+
export interface RelayComposerProps {
|
|
14
|
+
/** Why Send is unavailable (a run in flight); shown, and announced with Send. */
|
|
15
|
+
readonly busyReason?: string | undefined;
|
|
16
|
+
readonly contextRefs?: ReadonlyArray<RlyRelayContextRef>;
|
|
17
|
+
/** The textarea's name, "Message Relay" unless the host names it. */
|
|
18
|
+
readonly label?: string;
|
|
19
|
+
readonly onRemoveContextRef?: (id: string) => void;
|
|
20
|
+
/** Called with Ctrl/⌘+Enter or Send when there is text and nothing blocks it. */
|
|
21
|
+
readonly onSend: () => void;
|
|
22
|
+
/** Stop the run; pass it only while a run is in flight and the session offers cancel. */
|
|
23
|
+
readonly onStop?: (() => void) | undefined;
|
|
24
|
+
readonly onValueChange: (value: string) => void;
|
|
25
|
+
readonly placeholder?: string;
|
|
26
|
+
/** One run preset control, usually a menu trigger ("Thorough review, Codex"). */
|
|
27
|
+
readonly preset?: ReactNode;
|
|
28
|
+
/** The textarea, for useRelaySummon's composerRef. */
|
|
29
|
+
readonly ref?: Ref<HTMLTextAreaElement>;
|
|
30
|
+
readonly value: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Relay's message box (Relay UX decision). It grows with its text up to min(12 lines, 40% of the
|
|
34
|
+
* viewport), then scrolls. Enter is a newline and Ctrl/⌘+Enter sends, said as visible text beside Send;
|
|
35
|
+
* an IME composition never sends. While `busyReason` is set, Send stays focusable (aria-disabled) so
|
|
36
|
+
* its reason is heard, and pressing it does nothing. Keep the value with `useRelayDraft`, keyed by the
|
|
37
|
+
* object Relay is about, so it survives closing, reopening and resizing.
|
|
38
|
+
*/
|
|
39
|
+
export declare const RelayComposer: ({ busyReason, contextRefs, label, onRemoveContextRef, onSend, onStop, onValueChange, placeholder, preset, ref, value }: RelayComposerProps) => ReactElement;
|
|
40
|
+
/** A per-object draft: the value for the composer and the submission a send makes. */
|
|
41
|
+
export interface RlyRelayDraft {
|
|
42
|
+
/** The request with this id was accepted: clear the draft, unless the user has typed since. */
|
|
43
|
+
readonly accepted: (requestId: string) => void;
|
|
44
|
+
readonly onValueChange: (value: string) => void;
|
|
45
|
+
/** The current text with a request id that stays the same until the text changes or is accepted. */
|
|
46
|
+
readonly submission: () => RlyRelaySubmission;
|
|
47
|
+
readonly value: string;
|
|
48
|
+
}
|
|
49
|
+
/** Storage a draft may survive a reload in; session storage, never local storage (drafts may be sensitive). */
|
|
50
|
+
export type RlyRelayDraftStorage = Pick<Storage, "getItem" | "removeItem" | "setItem">;
|
|
51
|
+
/** Inputs for {@link useRelayDraft}. */
|
|
52
|
+
export interface UseRelayDraftOptions {
|
|
53
|
+
/** Mints a client request id (the host's own, e.g. a UUID from its runtime); rly owns no id source. */
|
|
54
|
+
readonly newRequestId: () => string;
|
|
55
|
+
/** Opt in to surviving a reload; read lazily, and any refusal keeps the draft in memory only. */
|
|
56
|
+
readonly storage?: () => RlyRelayDraftStorage;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The composer's draft for one object (the JSON ObjectRef, so PR A's draft can never send as PR B's).
|
|
60
|
+
* It lives in memory for the page, so closing, reopening or resizing Relay keeps it; with `storage`
|
|
61
|
+
* (session storage) it also survives a reload. A send reuses one request id until the text is edited,
|
|
62
|
+
* so a retry after an uncertain outcome is deduplicated and an edited message is a new one.
|
|
63
|
+
*/
|
|
64
|
+
export declare const useRelayDraft: (objectKey: string, options: UseRelayDraftOptions) => RlyRelayDraft;
|
|
65
|
+
//# sourceMappingURL=RelayComposer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RelayComposer.d.ts","sourceRoot":"","sources":["../../../src/patterns/RelayComposer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,YAAY,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAY3G,oGAAoG;AACpG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,2FAA2F;AAC3F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,+BAA+B;AAC/B,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAA;IACxD,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAA;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAOD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,2HAYvB,kBAAkB,KAAG,YAuGvB,CAAA;AAOD,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC5B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,oGAAoG;IACpG,QAAQ,CAAC,UAAU,EAAE,MAAM,kBAAkB,CAAA;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,+GAA+G;AAC/G,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC,CAAA;AAEtF,wCAAwC;AACxC,MAAM,WAAW,oBAAoB;IACnC,uGAAuG;IACvG,QAAQ,CAAC,YAAY,EAAE,MAAM,MAAM,CAAA;IACnC,iGAAiG;IACjG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,oBAAoB,CAAA;CAC9C;AAqDD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,cAAe,MAAM,WAAW,oBAAoB,KAAG,aAsDhF,CAAA"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
/** The words for one write, written by the host for its action (no English conjugation in rly). */
|
|
3
|
+
export interface RlyRelayDecisionCopy {
|
|
4
|
+
/** The question, future tense: "Post this comment on infra-core #12?" */
|
|
5
|
+
readonly ask: string;
|
|
6
|
+
/** The confirm button: "Post comment". */
|
|
7
|
+
readonly confirm: string;
|
|
8
|
+
/** The decline button: "Don't post". */
|
|
9
|
+
readonly decline: string;
|
|
10
|
+
/** While the confirmed write runs: "Posting…". */
|
|
11
|
+
readonly working: string;
|
|
12
|
+
/** Once the write finished with a receipt, past tense: "Posted". */
|
|
13
|
+
readonly done: string;
|
|
14
|
+
/** What can be undone and where, only when the host knows it: "You can delete it in CodeCommit later." */
|
|
15
|
+
readonly reversible?: string;
|
|
16
|
+
}
|
|
17
|
+
/** One fact about where the write goes ("Pull request", "infra-core #12"); shown only as given. */
|
|
18
|
+
export interface RlyRelayDecisionTarget {
|
|
19
|
+
readonly label: string;
|
|
20
|
+
readonly value: string;
|
|
21
|
+
}
|
|
22
|
+
/** A write's display-safe receipt; the link, when present, opens what was written. */
|
|
23
|
+
export interface RlyRelayDecisionReceipt {
|
|
24
|
+
readonly href?: string;
|
|
25
|
+
readonly summary: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Where the decision is. Confirmed means authorized and now writing, never that it was written; only
|
|
29
|
+
* Done (the tool finished with a receipt) is past tense. Failed never claims nothing was written, and
|
|
30
|
+
* carries a receipt when the host has one.
|
|
31
|
+
*/
|
|
32
|
+
export type RlyRelayDecisionState = {
|
|
33
|
+
readonly _tag: "Pending";
|
|
34
|
+
} | {
|
|
35
|
+
readonly _tag: "Confirmed";
|
|
36
|
+
} | {
|
|
37
|
+
readonly _tag: "Done";
|
|
38
|
+
readonly receipt: RlyRelayDecisionReceipt;
|
|
39
|
+
} | {
|
|
40
|
+
readonly _tag: "Failed";
|
|
41
|
+
readonly cause: string;
|
|
42
|
+
readonly receipt?: RlyRelayDecisionReceipt;
|
|
43
|
+
} | {
|
|
44
|
+
readonly _tag: "Declined";
|
|
45
|
+
} | {
|
|
46
|
+
readonly _tag: "Expired";
|
|
47
|
+
};
|
|
48
|
+
/** Inputs for one decision. */
|
|
49
|
+
export interface RelayDecisionProps {
|
|
50
|
+
/** The exact text that would be written. */
|
|
51
|
+
readonly body: string;
|
|
52
|
+
readonly copy: RlyRelayDecisionCopy;
|
|
53
|
+
/** The call this decision belongs to; a decision is announced once per id, across remounts. */
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly onConfirm: () => void;
|
|
56
|
+
readonly onDecline: () => void;
|
|
57
|
+
readonly state: RlyRelayDecisionState;
|
|
58
|
+
/**
|
|
59
|
+
* Where it goes, at least one fact and only what the action really pins (a PR comment names the PR,
|
|
60
|
+
* not a line). A write with no stated destination cannot be confirmed.
|
|
61
|
+
*/
|
|
62
|
+
readonly target: readonly [RlyRelayDecisionTarget, ...ReadonlyArray<RlyRelayDecisionTarget>];
|
|
63
|
+
/** "danger" for a destructive write (delete, force-merge), so it never looks like a comment. */
|
|
64
|
+
readonly tone?: "default" | "danger";
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Ask before one Relay write (Relay UX decision): the question, exactly where the write goes and the
|
|
68
|
+
* exact text (in its own scroll when long), then Confirm or Don't, for this one call only, never
|
|
69
|
+
* "allow all". The first press is latched until the host moves the state on, so a double click or a
|
|
70
|
+
* held key cannot confirm twice. Pending, declined and expired are announced once per call, politely,
|
|
71
|
+
* without moving focus; once the reader answers, focus moves to the outcome, where the receipt link is
|
|
72
|
+
* the next stop. "Posting…" after confirming; past tense only with a receipt.
|
|
73
|
+
*/
|
|
74
|
+
export declare const RelayDecision: ({ body, copy, id, onConfirm, onDecline, state, target, tone }: RelayDecisionProps) => ReactElement;
|
|
75
|
+
//# sourceMappingURL=RelayDecision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RelayDecision.d.ts","sourceRoot":"","sources":["../../../src/patterns/RelayDecision.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAUzC,mGAAmG;AACnG,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,0GAA0G;IAC1G,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,mGAAmG;AACnG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,sFAAsF;AACtF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,uBAAuB,CAAA;CAAE,GAC/F;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAA;AAEhC,+BAA+B;AAC/B,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAA;IACnC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAA;IACrC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,sBAAsB,EAAE,GAAG,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAC5F,gGAAgG;IAChG,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CACrC;AAkBD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,kEASvB,kBAAkB,KAAG,YAwGvB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RelayDock.d.ts","sourceRoot":"","sources":["../../../src/patterns/RelayDock.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAE1B,KAAK,YAAY,EACjB,KAAK,SAAS,EAQf,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"RelayDock.d.ts","sourceRoot":"","sources":["../../../src/patterns/RelayDock.tsx"],"names":[],"mappings":"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"}
|