@kgdiff/viewer 0.0.0-stage → 0.2.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.
Files changed (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -2
  3. package/dist/compute-loader.d.ts +13 -0
  4. package/dist/compute-loader.d.ts.map +1 -0
  5. package/dist/compute-loader.js +46 -0
  6. package/dist/compute-loader.js.map +1 -0
  7. package/dist/compute.d.ts +8 -0
  8. package/dist/compute.d.ts.map +1 -0
  9. package/dist/compute.js +8 -0
  10. package/dist/compute.js.map +1 -0
  11. package/dist/controller.d.ts +199 -0
  12. package/dist/controller.d.ts.map +1 -0
  13. package/dist/controller.js +1254 -0
  14. package/dist/controller.js.map +1 -0
  15. package/dist/dom.d.ts +32 -0
  16. package/dist/dom.d.ts.map +1 -0
  17. package/dist/dom.js +105 -0
  18. package/dist/dom.js.map +1 -0
  19. package/dist/element.d.ts +43 -0
  20. package/dist/element.d.ts.map +1 -0
  21. package/dist/element.js +656 -0
  22. package/dist/element.js.map +1 -0
  23. package/dist/framing.d.ts +45 -0
  24. package/dist/framing.d.ts.map +1 -0
  25. package/dist/framing.js +107 -0
  26. package/dist/framing.js.map +1 -0
  27. package/dist/hash-sync.d.ts +18 -0
  28. package/dist/hash-sync.d.ts.map +1 -0
  29. package/dist/hash-sync.js +45 -0
  30. package/dist/hash-sync.js.map +1 -0
  31. package/dist/i18n.d.ts +222 -0
  32. package/dist/i18n.d.ts.map +1 -0
  33. package/dist/i18n.js +434 -0
  34. package/dist/i18n.js.map +1 -0
  35. package/dist/icons.d.ts +37 -0
  36. package/dist/icons.d.ts.map +1 -0
  37. package/dist/icons.js +36 -0
  38. package/dist/icons.js.map +1 -0
  39. package/dist/index.d.ts +151 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +41 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/keyboard.d.ts +64 -0
  44. package/dist/keyboard.d.ts.map +1 -0
  45. package/dist/keyboard.js +95 -0
  46. package/dist/keyboard.js.map +1 -0
  47. package/dist/list-model.d.ts +35 -0
  48. package/dist/list-model.d.ts.map +1 -0
  49. package/dist/list-model.js +70 -0
  50. package/dist/list-model.js.map +1 -0
  51. package/dist/payload.d.ts +10 -0
  52. package/dist/payload.d.ts.map +1 -0
  53. package/dist/payload.js +138 -0
  54. package/dist/payload.js.map +1 -0
  55. package/dist/pipeline.d.ts +31 -0
  56. package/dist/pipeline.d.ts.map +1 -0
  57. package/dist/pipeline.js +122 -0
  58. package/dist/pipeline.js.map +1 -0
  59. package/dist/prefs.d.ts +18 -0
  60. package/dist/prefs.d.ts.map +1 -0
  61. package/dist/prefs.js +38 -0
  62. package/dist/prefs.js.map +1 -0
  63. package/dist/registry.d.ts +3 -0
  64. package/dist/registry.d.ts.map +1 -0
  65. package/dist/registry.js +3 -0
  66. package/dist/registry.js.map +1 -0
  67. package/dist/renderer-port.d.ts +14 -0
  68. package/dist/renderer-port.d.ts.map +1 -0
  69. package/dist/renderer-port.js +16 -0
  70. package/dist/renderer-port.js.map +1 -0
  71. package/dist/replay.d.ts +55 -0
  72. package/dist/replay.d.ts.map +1 -0
  73. package/dist/replay.js +147 -0
  74. package/dist/replay.js.map +1 -0
  75. package/dist/review-store.d.ts +30 -0
  76. package/dist/review-store.d.ts.map +1 -0
  77. package/dist/review-store.js +120 -0
  78. package/dist/review-store.js.map +1 -0
  79. package/dist/search.d.ts +25 -0
  80. package/dist/search.d.ts.map +1 -0
  81. package/dist/search.js +90 -0
  82. package/dist/search.js.map +1 -0
  83. package/dist/standalone/kgdiff-viewer-compute.js +1 -0
  84. package/dist/standalone/kgdiff-viewer.js +5 -0
  85. package/dist/standalone-compute.d.ts +2 -0
  86. package/dist/standalone-compute.d.ts.map +1 -0
  87. package/dist/standalone-compute.js +8 -0
  88. package/dist/standalone-compute.js.map +1 -0
  89. package/dist/standalone.d.ts +2 -0
  90. package/dist/standalone.d.ts.map +1 -0
  91. package/dist/standalone.js +18 -0
  92. package/dist/standalone.js.map +1 -0
  93. package/dist/styles.d.ts +11 -0
  94. package/dist/styles.d.ts.map +1 -0
  95. package/dist/styles.js +622 -0
  96. package/dist/styles.js.map +1 -0
  97. package/dist/text-diff.d.ts +44 -0
  98. package/dist/text-diff.d.ts.map +1 -0
  99. package/dist/text-diff.js +261 -0
  100. package/dist/text-diff.js.map +1 -0
  101. package/dist/ui/context.d.ts +32 -0
  102. package/dist/ui/context.d.ts.map +1 -0
  103. package/dist/ui/context.js +49 -0
  104. package/dist/ui/context.js.map +1 -0
  105. package/dist/ui/detail.d.ts +9 -0
  106. package/dist/ui/detail.d.ts.map +1 -0
  107. package/dist/ui/detail.js +609 -0
  108. package/dist/ui/detail.js.map +1 -0
  109. package/dist/ui/header.d.ts +14 -0
  110. package/dist/ui/header.d.ts.map +1 -0
  111. package/dist/ui/header.js +195 -0
  112. package/dist/ui/header.js.map +1 -0
  113. package/dist/ui/popovers.d.ts +20 -0
  114. package/dist/ui/popovers.d.ts.map +1 -0
  115. package/dist/ui/popovers.js +180 -0
  116. package/dist/ui/popovers.js.map +1 -0
  117. package/dist/ui/sidebar.d.ts +25 -0
  118. package/dist/ui/sidebar.d.ts.map +1 -0
  119. package/dist/ui/sidebar.js +609 -0
  120. package/dist/ui/sidebar.js.map +1 -0
  121. package/dist/ui/stage.d.ts +18 -0
  122. package/dist/ui/stage.d.ts.map +1 -0
  123. package/dist/ui/stage.js +664 -0
  124. package/dist/ui/stage.js.map +1 -0
  125. package/package.json +58 -3
  126. package/src/compute-loader.ts +58 -0
  127. package/src/compute.ts +7 -0
  128. package/src/controller.ts +1393 -0
  129. package/src/dom.ts +131 -0
  130. package/src/element.ts +697 -0
  131. package/src/framing.ts +150 -0
  132. package/src/hash-sync.ts +54 -0
  133. package/src/i18n.ts +467 -0
  134. package/src/icons.ts +48 -0
  135. package/src/index.ts +171 -0
  136. package/src/keyboard.ts +128 -0
  137. package/src/list-model.ts +86 -0
  138. package/src/payload.ts +165 -0
  139. package/src/pipeline.ts +179 -0
  140. package/src/prefs.ts +55 -0
  141. package/src/registry.ts +2 -0
  142. package/src/renderer-port.ts +31 -0
  143. package/src/replay.ts +163 -0
  144. package/src/review-store.ts +125 -0
  145. package/src/search.ts +113 -0
  146. package/src/standalone-compute.ts +8 -0
  147. package/src/standalone.ts +18 -0
  148. package/src/styles.ts +633 -0
  149. package/src/text-diff.ts +263 -0
  150. package/src/ui/context.ts +70 -0
  151. package/src/ui/detail.ts +929 -0
  152. package/src/ui/header.ts +278 -0
  153. package/src/ui/popovers.ts +251 -0
  154. package/src/ui/sidebar.ts +752 -0
  155. package/src/ui/stage.ts +853 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Load pipeline: sources → (parse) → diff → layout, or a precomputed report → diff + layout.
3
+ * Each step is announced through `onStep`, which the controller awaits so the loading state
4
+ * can paint between the (synchronous, CPU-bound) steps.
5
+ */
6
+ import { type DiffResult, type GraphMeta } from '@kgdiff/core';
7
+ import { type LayoutOptions, type LayoutResult } from '@kgdiff/layout';
8
+ import type { LoadOptions, ReportPayload } from './index.js';
9
+ export type LoadStep = 'parse' | 'match' | 'layout' | 'scene';
10
+ export interface LoadedDiff {
11
+ readonly diff: DiffResult;
12
+ readonly layout: LayoutResult;
13
+ /** Options to reuse when the layout is extended. */
14
+ readonly layoutOptions: LayoutOptions | undefined;
15
+ readonly names: {
16
+ readonly before: string;
17
+ readonly after: string;
18
+ };
19
+ readonly versions: {
20
+ readonly before?: string;
21
+ readonly after?: string;
22
+ };
23
+ readonly title?: string;
24
+ /** Initial view preferences from a report. */
25
+ readonly view?: ReportPayload['view'];
26
+ }
27
+ /** Display name of a version: explicit name, graph name, file name, else the side. */
28
+ export declare function versionName(meta: GraphMeta, side: 'before' | 'after', explicit?: string, filename?: string): string;
29
+ export declare function runLoad(options: LoadOptions, onStep: (step: LoadStep) => Promise<void>): Promise<LoadedDiff>;
30
+ export declare function readPayload(payload: ReportPayload, onStep: (step: LoadStep) => Promise<void>): Promise<LoadedDiff>;
31
+ //# sourceMappingURL=pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,SAAS,EAIf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAkB,MAAM,gBAAgB,CAAC;AAGvF,OAAO,KAAK,EAAe,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG1E,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACvC;AAuED,sFAAsF;AACtF,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,QAAQ,GAAG,OAAO,EACxB,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAQR;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GACxC,OAAO,CAAC,UAAU,CAAC,CA8BrB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GACxC,OAAO,CAAC,UAAU,CAAC,CAqBrB"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Load pipeline: sources → (parse) → diff → layout, or a precomputed report → diff + layout.
3
+ * Each step is announced through `onStep`, which the controller awaits so the loading state
4
+ * can paint between the (synchronous, CPU-bound) steps.
5
+ */
6
+ import { diffFromJSON, isKGraph, KgdiffError, } from '@kgdiff/core';
7
+ import { layoutFromJSON } from '@kgdiff/layout';
8
+ import { loadCompute } from './compute-loader.js';
9
+ import { translate } from './i18n.js';
10
+ import { sanitizeView } from './prefs.js';
11
+ function isTextSource(source) {
12
+ return typeof source.text === 'string';
13
+ }
14
+ function isGraphInput(value) {
15
+ if (typeof value !== 'object' || value === null)
16
+ return false;
17
+ const v = value;
18
+ return Array.isArray(v.nodes) && (v.edges === undefined || Array.isArray(v.edges));
19
+ }
20
+ let formatsPromise = null;
21
+ /** Loaded lazily so the standalone bundle (reports) never pays for the parsers. */
22
+ function loadFormats() {
23
+ formatsPromise ??= import('@kgdiff/formats').catch((error) => {
24
+ formatsPromise = null;
25
+ throw new KgdiffError('invalid-input', translate('en', 'error.formats'), {
26
+ cause: error instanceof Error ? error.message : String(error),
27
+ });
28
+ });
29
+ return formatsPromise;
30
+ }
31
+ async function resolveSource(source, side) {
32
+ if (typeof source !== 'object' || source === null) {
33
+ throw new KgdiffError('invalid-input', `load(): \`${side}\` must be a GraphInput, a KGraph or { text, filename }.`);
34
+ }
35
+ if (isTextSource(source)) {
36
+ const { parseGraph } = await loadFormats();
37
+ const parsed = parseGraph(source.text, {
38
+ ...source.parse,
39
+ ...(source.filename !== undefined ? { filename: source.filename } : {}),
40
+ });
41
+ return {
42
+ graph: parsed.graph,
43
+ meta: parsed.graph.meta ?? {},
44
+ ...(source.filename !== undefined ? { filename: source.filename } : {}),
45
+ };
46
+ }
47
+ if (isKGraph(source))
48
+ return { graph: source, meta: source.meta };
49
+ if (isGraphInput(source))
50
+ return { graph: source, meta: source.meta ?? {} };
51
+ throw new KgdiffError('invalid-input', `load(): \`${side}\` must be a GraphInput ({ nodes, edges }), a KGraph or { text, filename }.`);
52
+ }
53
+ function baseName(path) {
54
+ const clean = path.split(/[?#]/)[0] ?? path;
55
+ return clean.slice(Math.max(clean.lastIndexOf('/'), clean.lastIndexOf('\\')) + 1) || path;
56
+ }
57
+ function str(value) {
58
+ return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
59
+ }
60
+ /** Display name of a version: explicit name, graph name, file name, else the side. */
61
+ export function versionName(meta, side, explicit, filename) {
62
+ return (str(explicit) ??
63
+ str(meta.name) ??
64
+ (filename ? baseName(filename) : undefined) ??
65
+ (str(meta.source) ? baseName(meta.source) : undefined) ??
66
+ side);
67
+ }
68
+ export async function runLoad(options, onStep) {
69
+ if (typeof options !== 'object' || options === null) {
70
+ throw new KgdiffError('invalid-input', 'load() expects { before, after, … }.');
71
+ }
72
+ const { before, after } = options;
73
+ if (before === undefined || after === undefined) {
74
+ throw new KgdiffError('invalid-input', 'load() needs both `before` and `after`.');
75
+ }
76
+ const computing = loadCompute();
77
+ if (isTextSource(before) || isTextSource(after))
78
+ await onStep('parse');
79
+ const b = await resolveSource(before, 'before');
80
+ const a = await resolveSource(after, 'after');
81
+ const compute = await computing;
82
+ await onStep('match');
83
+ const diff = compute.diff(b.graph, a.graph, options.diff);
84
+ await onStep('layout');
85
+ const layout = compute.layoutDiff(diff, options.layout);
86
+ const vb = str(diff.before.meta.version);
87
+ const va = str(diff.after.meta.version);
88
+ return {
89
+ diff,
90
+ layout,
91
+ layoutOptions: options.layout,
92
+ names: {
93
+ before: versionName(b.meta, 'before', options.names?.before, b.filename),
94
+ after: versionName(a.meta, 'after', options.names?.after, a.filename),
95
+ },
96
+ versions: { ...(vb ? { before: vb } : {}), ...(va ? { after: va } : {}) },
97
+ ...(str(options.title) ? { title: str(options.title) } : {}),
98
+ };
99
+ }
100
+ export async function readPayload(payload, onStep) {
101
+ await onStep('match');
102
+ const diff = diffFromJSON(payload.diff);
103
+ await onStep('layout');
104
+ const layout = layoutFromJSON(payload.layout);
105
+ const vb = str(diff.before.meta.version);
106
+ const va = str(diff.after.meta.version);
107
+ const meta = payload.meta;
108
+ const view = sanitizeView(payload.view);
109
+ return {
110
+ diff,
111
+ layout,
112
+ layoutOptions: undefined,
113
+ names: {
114
+ before: versionName(diff.before.meta, 'before', meta?.before?.name),
115
+ after: versionName(diff.after.meta, 'after', meta?.after?.name),
116
+ },
117
+ versions: { ...(vb ? { before: vb } : {}), ...(va ? { after: va } : {}) },
118
+ ...(str(meta?.title) ? { title: str(meta?.title) } : {}),
119
+ ...(view ? { view } : {}),
120
+ };
121
+ }
122
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The one place viewer preferences are validated: attributes, properties and a report's `view`
3
+ * all go through these. Invalid values never reach the controller (they fall back, with a
4
+ * console warning for payloads, which come from files rather than code).
5
+ */
6
+ import type { Locale } from '@kgdiff/core';
7
+ import type { PaletteName } from '@kgdiff/scene';
8
+ import type { ReportPayload, ThemePreference, ViewerMode } from './index.js';
9
+ export declare const THEME_PREFERENCES: readonly ThemePreference[];
10
+ export declare function toMode(value: unknown): ViewerMode | null;
11
+ export declare function toTheme(value: unknown): ThemePreference | null;
12
+ export declare function toPalette(value: unknown): PaletteName | null;
13
+ export declare function toLocale(value: unknown): Locale | null;
14
+ type View = NonNullable<ReportPayload['view']>;
15
+ /** Keep only the valid fields of a report's `view` (warning about the rest). */
16
+ export declare function sanitizeView(view: unknown): View | undefined;
17
+ export {};
18
+ //# sourceMappingURL=prefs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefs.d.ts","sourceRoot":"","sources":["../src/prefs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7E,eAAO,MAAM,iBAAiB,4BAAS,CAAC;AAExC,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAExD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAE9D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAE5D;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEtD;AAED,KAAK,IAAI,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/C,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAmB5D"}
package/dist/prefs.js ADDED
@@ -0,0 +1,38 @@
1
+ import { normalizeLocale } from './i18n.js';
2
+ const MODES = ['overlay', 'swipe', 'replay', 'changes'];
3
+ const THEMES = ['auto', 'light', 'dark'];
4
+ const PALETTES = ['default', 'colorblind'];
5
+ export const THEME_PREFERENCES = THEMES;
6
+ export function toMode(value) {
7
+ return MODES.includes(value) ? value : null;
8
+ }
9
+ export function toTheme(value) {
10
+ return THEMES.includes(value) ? value : null;
11
+ }
12
+ export function toPalette(value) {
13
+ return PALETTES.includes(value) ? value : null;
14
+ }
15
+ export function toLocale(value) {
16
+ return typeof value === 'string' ? normalizeLocale(value) : null;
17
+ }
18
+ /** Keep only the valid fields of a report's `view` (warning about the rest). */
19
+ export function sanitizeView(view) {
20
+ if (typeof view !== 'object' || view === null)
21
+ return undefined;
22
+ const v = view;
23
+ const mode = toMode(v.mode);
24
+ const theme = toTheme(v.theme);
25
+ const palette = toPalette(v.palette);
26
+ const locale = toLocale(v.locale);
27
+ const dropped = ['mode', 'theme', 'palette', 'locale'].filter((k) => v[k] !== undefined && { mode, theme, palette, locale }[k] === null);
28
+ if (dropped.length > 0 && typeof console !== 'undefined') {
29
+ console.warn(`[kgdiff] ignoring invalid report view preferences: ${dropped.join(', ')}`);
30
+ }
31
+ return {
32
+ ...(mode ? { mode } : {}),
33
+ ...(theme ? { theme } : {}),
34
+ ...(palette ? { palette } : {}),
35
+ ...(locale ? { locale } : {}),
36
+ };
37
+ }
38
+ //# sourceMappingURL=prefs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefs.js","sourceRoot":"","sources":["../src/prefs.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,MAAM,KAAK,GAA0B,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC/E,MAAM,MAAM,GAA+B,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACrE,MAAM,QAAQ,GAA2B,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAEnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAExC,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAmB,CAAC,CAAC,CAAC,CAAE,KAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAwB,CAAC,CAAC,CAAC,CAAE,KAAyB,CAAC,CAAC,CAAC,IAAI,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,QAAQ,CAAC,QAAQ,CAAC,KAAoB,CAAC,CAAC,CAAC,CAAE,KAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC;AAID,gFAAgF;AAChF,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,OAAO,GAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAW,CAAC,MAAM,CACtE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAC1E,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,sDAAsD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO;QACL,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Tag names `<kgdiff-viewer>` is registered under (lower case), for payload targeting. */
2
+ export declare const viewerTags: Set<string>;
3
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,eAAO,MAAM,UAAU,aAAoB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Tag names `<kgdiff-viewer>` is registered under (lower case), for payload targeting. */
2
+ export const viewerTags = new Set();
3
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The seam between the viewer and `@kgdiff/renderer`. The controller only talks to the
3
+ * `Renderer` / `Minimap` interfaces, and tests swap in a recording mock (there is no canvas in
4
+ * happy-dom) with `setRenderBackend`.
5
+ */
6
+ import { type Minimap, type MinimapOptions, type Renderer, type RendererOptions } from '@kgdiff/renderer';
7
+ export interface RenderBackend {
8
+ createRenderer(container: HTMLElement, options: RendererOptions): Renderer;
9
+ createMinimap(container: HTMLElement, renderer: Renderer, options?: MinimapOptions): Minimap;
10
+ }
11
+ export declare function renderBackend(): RenderBackend;
12
+ /** Replace the rendering backend (tests). `null` restores the canvas renderer. */
13
+ export declare function setRenderBackend(next: RenderBackend | null): void;
14
+ //# sourceMappingURL=renderer-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer-port.d.ts","sourceRoot":"","sources":["../src/renderer-port.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,GAAG,QAAQ,CAAC;IAC3E,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;CAC9F;AAMD,wBAAgB,aAAa,IAAI,aAAa,CAE7C;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEjE"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The seam between the viewer and `@kgdiff/renderer`. The controller only talks to the
3
+ * `Renderer` / `Minimap` interfaces, and tests swap in a recording mock (there is no canvas in
4
+ * happy-dom) with `setRenderBackend`.
5
+ */
6
+ import { createMinimap, createRenderer, } from '@kgdiff/renderer';
7
+ const defaultBackend = { createRenderer, createMinimap };
8
+ let backend = defaultBackend;
9
+ export function renderBackend() {
10
+ return backend;
11
+ }
12
+ /** Replace the rendering backend (tests). `null` restores the canvas renderer. */
13
+ export function setRenderBackend(next) {
14
+ backend = next ?? defaultBackend;
15
+ }
16
+ //# sourceMappingURL=renderer-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer-port.js","sourceRoot":"","sources":["../src/renderer-port.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GAKf,MAAM,kBAAkB,CAAC;AAO1B,MAAM,cAAc,GAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAExE,IAAI,OAAO,GAAkB,cAAc,CAAC;AAE5C,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,OAAO,GAAG,IAAI,IAAI,cAAc,CAAC;AACnC,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Replay clock: pure time arithmetic over a scene `Timeline` (no timers). The controller
3
+ * advances it from its animation-frame loop.
4
+ */
5
+ import type { Timeline } from '@kgdiff/scene';
6
+ export declare const SPEEDS: readonly [0.5, 1, 2, 4];
7
+ export type ReplaySpeed = (typeof SPEEDS)[number];
8
+ /** A frame gap longer than this (tab in background, debugger) advances at most this much. */
9
+ export declare const MAX_FRAME_MS = 100;
10
+ export declare class ReplayClock {
11
+ #private;
12
+ readonly timeline: Timeline;
13
+ constructor(timeline: Timeline);
14
+ get t(): number;
15
+ get duration(): number;
16
+ get speed(): ReplaySpeed;
17
+ get playing(): boolean;
18
+ /** At the end and not playing. */
19
+ get finished(): boolean;
20
+ /** Normalized position in [0, 1]. */
21
+ get progress(): number;
22
+ setSpeed(speed: number): void;
23
+ /** Next speed in `SPEEDS`, wrapping around. */
24
+ cycleSpeed(): ReplaySpeed;
25
+ /** Start playing; a finished replay restarts from 0. No-op for an empty timeline. */
26
+ play(): void;
27
+ pause(): void;
28
+ seek(t: number): void;
29
+ /**
30
+ * Advance by a real-time delta (ms, capped at `MAX_FRAME_MS`) scaled by the speed. Stops at
31
+ * the end. Returns whether time moved.
32
+ */
33
+ advance(dt: number): boolean;
34
+ /**
35
+ * Seek to the next (+1) / previous (−1) stop: the end of a hunk window (`hunks` timelines) or
36
+ * of a chapter (`chapters`). Backwards from the first stop goes to 0. Pauses playback.
37
+ */
38
+ step(direction: 1 | -1): void;
39
+ /** End of hunk `h`'s window (where selecting it in the list seeks to), or null. */
40
+ windowEnd(h: number): number | null;
41
+ /** Number of windows that have started (strictly before `t`): the `3` in `3 / 23`. */
42
+ position(t?: number): number;
43
+ get total(): number;
44
+ /**
45
+ * What the camera follows at `t`: in `hunks` mode the hunk whose window contains `t` (the latest
46
+ * started), in `chapters` mode the chapter containing `t`. `-1` between windows.
47
+ */
48
+ activeTarget(t?: number): {
49
+ readonly kind: 'hunk' | 'chapter';
50
+ readonly index: number;
51
+ };
52
+ /** The hunk whose window is playing at `t` (latest started), or -1. */
53
+ activeHunk(t?: number): number;
54
+ }
55
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,MAAM,YAAI,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU,CAAC;AAC9C,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAIlD,6FAA6F;AAC7F,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC,qBAAa,WAAW;;IAQV,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAAvC,YAAqB,QAAQ,EAAE,QAAQ,EAOtC;IAED,IAAI,CAAC,IAAI,MAAM,CAEd;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,KAAK,IAAI,WAAW,CAEvB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,kCAAkC;IAClC,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,qCAAqC;IACrC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG5B;IAED,+CAA+C;IAC/C,UAAU,IAAI,WAAW,CAIxB;IAED,qFAAqF;IACrF,IAAI,IAAI,IAAI,CAIX;IAED,KAAK,IAAI,IAAI,CAEZ;IAED,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAEpB;IAED;;;OAGG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAM3B;IAED;;;OAGG;IACH,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAc5B;IAED,mFAAmF;IACnF,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlC;IAED,sFAAsF;IACtF,QAAQ,CAAC,CAAC,SAAa,GAAG,MAAM,CAS/B;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;OAGG;IACH,YAAY,CAAC,CAAC,SAAa,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAM1F;IAED,uEAAuE;IACvE,UAAU,CAAC,CAAC,SAAa,GAAG,MAAM,CAUjC;CACF"}
package/dist/replay.js ADDED
@@ -0,0 +1,147 @@
1
+ export const SPEEDS = [0.5, 1, 2, 4];
2
+ /** Times closer than this (ms) count as equal when stepping. */
3
+ const EPS = 0.5;
4
+ /** A frame gap longer than this (tab in background, debugger) advances at most this much. */
5
+ export const MAX_FRAME_MS = 100;
6
+ export class ReplayClock {
7
+ timeline;
8
+ #time = 0;
9
+ #rate = 1;
10
+ #running = false;
11
+ /** Sorted, distinct stop times for stepping (window or chapter ends). */
12
+ #stops;
13
+ #starts;
14
+ constructor(timeline) {
15
+ this.timeline = timeline;
16
+ const ends = timeline.mode === 'chapters'
17
+ ? timeline.chapters.map((c) => c.end)
18
+ : timeline.windows.map((w) => w.end);
19
+ this.#stops = [...new Set(ends)].sort((a, b) => a - b);
20
+ this.#starts = Float64Array.from(timeline.windows.map((w) => w.start)).sort();
21
+ }
22
+ get t() {
23
+ return this.#time;
24
+ }
25
+ get duration() {
26
+ return this.timeline.duration;
27
+ }
28
+ get speed() {
29
+ return this.#rate;
30
+ }
31
+ get playing() {
32
+ return this.#running;
33
+ }
34
+ /** At the end and not playing. */
35
+ get finished() {
36
+ return !this.#running && this.duration > 0 && this.#time >= this.duration;
37
+ }
38
+ /** Normalized position in [0, 1]. */
39
+ get progress() {
40
+ return this.duration > 0 ? this.#time / this.duration : 0;
41
+ }
42
+ setSpeed(speed) {
43
+ const s = SPEEDS.find((x) => x === speed);
44
+ if (s !== undefined)
45
+ this.#rate = s;
46
+ }
47
+ /** Next speed in `SPEEDS`, wrapping around. */
48
+ cycleSpeed() {
49
+ const i = SPEEDS.indexOf(this.#rate);
50
+ this.#rate = SPEEDS[(i + 1) % SPEEDS.length];
51
+ return this.#rate;
52
+ }
53
+ /** Start playing; a finished replay restarts from 0. No-op for an empty timeline. */
54
+ play() {
55
+ if (this.duration <= 0)
56
+ return;
57
+ if (this.#time >= this.duration)
58
+ this.#time = 0;
59
+ this.#running = true;
60
+ }
61
+ pause() {
62
+ this.#running = false;
63
+ }
64
+ seek(t) {
65
+ this.#time = Number.isFinite(t) ? Math.min(this.duration, Math.max(0, t)) : 0;
66
+ }
67
+ /**
68
+ * Advance by a real-time delta (ms, capped at `MAX_FRAME_MS`) scaled by the speed. Stops at
69
+ * the end. Returns whether time moved.
70
+ */
71
+ advance(dt) {
72
+ if (!this.#running || !(dt > 0))
73
+ return false;
74
+ const before = this.#time;
75
+ this.#time = Math.min(this.duration, this.#time + Math.min(dt, MAX_FRAME_MS) * this.#rate);
76
+ if (this.#time >= this.duration)
77
+ this.#running = false;
78
+ return this.#time !== before;
79
+ }
80
+ /**
81
+ * Seek to the next (+1) / previous (−1) stop: the end of a hunk window (`hunks` timelines) or
82
+ * of a chapter (`chapters`). Backwards from the first stop goes to 0. Pauses playback.
83
+ */
84
+ step(direction) {
85
+ this.#running = false;
86
+ const t = this.#time;
87
+ if (direction > 0) {
88
+ const next = this.#stops.find((s) => s > t + EPS);
89
+ this.#time = next ?? this.duration;
90
+ }
91
+ else {
92
+ let prev = 0;
93
+ for (const s of this.#stops) {
94
+ if (s < t - EPS)
95
+ prev = s;
96
+ else
97
+ break;
98
+ }
99
+ this.#time = prev;
100
+ }
101
+ }
102
+ /** End of hunk `h`'s window (where selecting it in the list seeks to), or null. */
103
+ windowEnd(h) {
104
+ const w = this.timeline.windows.find((x) => x.hunk === h);
105
+ return w === undefined ? null : w.end;
106
+ }
107
+ /** Number of windows that have started (strictly before `t`): the `3` in `3 / 23`. */
108
+ position(t = this.#time) {
109
+ let lo = 0;
110
+ let hi = this.#starts.length;
111
+ while (lo < hi) {
112
+ const mid = (lo + hi) >> 1;
113
+ if (this.#starts[mid] < t)
114
+ lo = mid + 1;
115
+ else
116
+ hi = mid;
117
+ }
118
+ return lo;
119
+ }
120
+ get total() {
121
+ return this.timeline.windows.length;
122
+ }
123
+ /**
124
+ * What the camera follows at `t`: in `hunks` mode the hunk whose window contains `t` (the latest
125
+ * started), in `chapters` mode the chapter containing `t`. `-1` between windows.
126
+ */
127
+ activeTarget(t = this.#time) {
128
+ if (this.timeline.mode === 'chapters') {
129
+ const c = this.timeline.chapters.findIndex((x) => t >= x.start && t < x.end);
130
+ return { kind: 'chapter', index: c };
131
+ }
132
+ return { kind: 'hunk', index: this.activeHunk(t) };
133
+ }
134
+ /** The hunk whose window is playing at `t` (latest started), or -1. */
135
+ activeHunk(t = this.#time) {
136
+ let best = -1;
137
+ let bestStart = Number.NEGATIVE_INFINITY;
138
+ for (const w of this.timeline.windows) {
139
+ if (t >= w.start && t < w.end && w.start >= bestStart) {
140
+ best = w.hunk;
141
+ bestStart = w.start;
142
+ }
143
+ }
144
+ return best;
145
+ }
146
+ }
147
+ //# sourceMappingURL=replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Review progress: which hunks were marked reviewed, persisted in `localStorage` per diff
3
+ * (`kgdiff:review:<base hash>→<target hash>`). Storage failures (private mode, quota, sandboxed
4
+ * iframes) never break the viewer: the state simply stays in memory.
5
+ */
6
+ import type { ReviewState } from './index.js';
7
+ export declare const STORAGE_PREFIX = "kgdiff:review:";
8
+ export type StorageLike = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
9
+ export declare function reviewKey(baseHash: string, targetHash: string): string;
10
+ /** `window.localStorage`, or null when unavailable / blocked. */
11
+ export declare function defaultStorage(): StorageLike | null;
12
+ export declare class ReviewStore {
13
+ #private;
14
+ /**
15
+ * @param key storage key (`reviewKey`), or null to keep the state in memory only.
16
+ * @param valid hunk ids of the current diff; stored ids it does not have are preserved.
17
+ */
18
+ constructor(storage: StorageLike | null, key: string | null, valid: readonly string[]);
19
+ /**
20
+ * Re-read storage after a `storage` event for `key` (null: everything changed). Returns
21
+ * whether the visible state changed.
22
+ */
23
+ reload(key: string | null): boolean;
24
+ has(id: string): boolean;
25
+ get size(): number;
26
+ /** Returns true when the state changed. Unknown ids are ignored. */
27
+ setReviewed(id: string, reviewed: boolean): boolean;
28
+ state(): ReviewState;
29
+ }
30
+ //# sourceMappingURL=review-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-store.d.ts","sourceRoot":"","sources":["../src/review-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;AAE9E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,iEAAiE;AACjE,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAMnD;AAED,qBAAa,WAAW;;IAUtB;;;OAGG;IACH,YAAY,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAMpF;IAeD;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAKlC;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEvB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,oEAAoE;IACpE,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAYlD;IAED,KAAK,IAAI,WAAW,CAEnB;CA6BF"}