@kgdiff/viewer 0.4.0 → 0.6.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 (257) hide show
  1. package/README.md +43 -16
  2. package/custom-elements.json +2347 -0
  3. package/dist/bind.d.ts +41 -0
  4. package/dist/bind.d.ts.map +1 -0
  5. package/dist/bind.js +47 -0
  6. package/dist/bind.js.map +1 -0
  7. package/dist/context.d.ts +42 -0
  8. package/dist/context.d.ts.map +1 -0
  9. package/dist/context.js +87 -0
  10. package/dist/context.js.map +1 -0
  11. package/dist/controller.d.ts +26 -237
  12. package/dist/controller.d.ts.map +1 -1
  13. package/dist/controller.js +33 -1484
  14. package/dist/controller.js.map +1 -1
  15. package/dist/dom.d.ts +10 -0
  16. package/dist/dom.d.ts.map +1 -1
  17. package/dist/dom.js +29 -0
  18. package/dist/dom.js.map +1 -1
  19. package/dist/element.d.ts +51 -42
  20. package/dist/element.d.ts.map +1 -1
  21. package/dist/element.js +381 -602
  22. package/dist/element.js.map +1 -1
  23. package/dist/elements/actions.d.ts +27 -0
  24. package/dist/elements/actions.d.ts.map +1 -0
  25. package/dist/elements/actions.js +81 -0
  26. package/dist/elements/actions.js.map +1 -0
  27. package/dist/elements/bound.d.ts +63 -0
  28. package/dist/elements/bound.d.ts.map +1 -0
  29. package/dist/elements/bound.js +213 -0
  30. package/dist/elements/bound.js.map +1 -0
  31. package/dist/elements/change-detail.d.ts +25 -0
  32. package/dist/elements/change-detail.d.ts.map +1 -0
  33. package/dist/elements/change-detail.js +19 -0
  34. package/dist/elements/change-detail.js.map +1 -0
  35. package/dist/elements/change-list.d.ts +27 -0
  36. package/dist/elements/change-list.d.ts.map +1 -0
  37. package/dist/elements/change-list.js +29 -0
  38. package/dist/elements/change-list.js.map +1 -0
  39. package/dist/elements/filters.d.ts +25 -0
  40. package/dist/elements/filters.d.ts.map +1 -0
  41. package/dist/elements/filters.js +19 -0
  42. package/dist/elements/filters.js.map +1 -0
  43. package/dist/elements/legend.d.ts +40 -0
  44. package/dist/elements/legend.d.ts.map +1 -0
  45. package/dist/elements/legend.js +87 -0
  46. package/dist/elements/legend.js.map +1 -0
  47. package/dist/elements/minimap.d.ts +38 -0
  48. package/dist/elements/minimap.d.ts.map +1 -0
  49. package/dist/elements/minimap.js +59 -0
  50. package/dist/elements/minimap.js.map +1 -0
  51. package/dist/elements/root.d.ts +40 -0
  52. package/dist/elements/root.d.ts.map +1 -0
  53. package/dist/elements/root.js +67 -0
  54. package/dist/elements/root.js.map +1 -0
  55. package/dist/elements/search.d.ts +29 -0
  56. package/dist/elements/search.d.ts.map +1 -0
  57. package/dist/elements/search.js +23 -0
  58. package/dist/elements/search.js.map +1 -0
  59. package/dist/elements/stage-context.d.ts +31 -0
  60. package/dist/elements/stage-context.d.ts.map +1 -0
  61. package/dist/elements/stage-context.js +4 -0
  62. package/dist/elements/stage-context.js.map +1 -0
  63. package/dist/elements/stage.d.ts +65 -0
  64. package/dist/elements/stage.d.ts.map +1 -0
  65. package/dist/elements/stage.js +259 -0
  66. package/dist/elements/stage.js.map +1 -0
  67. package/dist/elements/title.d.ts +25 -0
  68. package/dist/elements/title.d.ts.map +1 -0
  69. package/dist/elements/title.js +19 -0
  70. package/dist/elements/title.js.map +1 -0
  71. package/dist/elements/transport.d.ts +29 -0
  72. package/dist/elements/transport.d.ts.map +1 -0
  73. package/dist/elements/transport.js +24 -0
  74. package/dist/elements/transport.js.map +1 -0
  75. package/dist/elements/view-bound.d.ts +39 -0
  76. package/dist/elements/view-bound.d.ts.map +1 -0
  77. package/dist/elements/view-bound.js +88 -0
  78. package/dist/elements/view-bound.js.map +1 -0
  79. package/dist/elements/view-dock.d.ts +28 -0
  80. package/dist/elements/view-dock.d.ts.map +1 -0
  81. package/dist/elements/view-dock.js +28 -0
  82. package/dist/elements/view-dock.js.map +1 -0
  83. package/dist/elements/zoom.d.ts +28 -0
  84. package/dist/elements/zoom.d.ts.map +1 -0
  85. package/dist/elements/zoom.js +22 -0
  86. package/dist/elements/zoom.js.map +1 -0
  87. package/dist/i18n.d.ts +10 -0
  88. package/dist/i18n.d.ts.map +1 -1
  89. package/dist/i18n.js +20 -0
  90. package/dist/i18n.js.map +1 -1
  91. package/dist/icons.d.ts +1 -0
  92. package/dist/icons.d.ts.map +1 -1
  93. package/dist/icons.js +1 -0
  94. package/dist/icons.js.map +1 -1
  95. package/dist/index.d.ts +331 -36
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +13 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/keyboard.d.ts +39 -2
  100. package/dist/keyboard.d.ts.map +1 -1
  101. package/dist/keyboard.js +145 -62
  102. package/dist/keyboard.js.map +1 -1
  103. package/dist/layout-store.d.ts +26 -0
  104. package/dist/layout-store.d.ts.map +1 -0
  105. package/dist/layout-store.js +46 -0
  106. package/dist/layout-store.js.map +1 -0
  107. package/dist/panel-levels.d.ts +18 -0
  108. package/dist/panel-levels.d.ts.map +1 -0
  109. package/dist/panel-levels.js +41 -0
  110. package/dist/panel-levels.js.map +1 -0
  111. package/dist/panels.d.ts +28 -0
  112. package/dist/panels.d.ts.map +1 -0
  113. package/dist/panels.js +73 -0
  114. package/dist/panels.js.map +1 -0
  115. package/dist/pipeline.d.ts.map +1 -1
  116. package/dist/pipeline.js +3 -2
  117. package/dist/pipeline.js.map +1 -1
  118. package/dist/prefs.d.ts +5 -2
  119. package/dist/prefs.d.ts.map +1 -1
  120. package/dist/prefs.js +12 -3
  121. package/dist/prefs.js.map +1 -1
  122. package/dist/react.d.ts +460 -0
  123. package/dist/react.d.ts.map +1 -0
  124. package/dist/react.js +2 -0
  125. package/dist/react.js.map +1 -0
  126. package/dist/root-element.d.ts +122 -0
  127. package/dist/root-element.d.ts.map +1 -0
  128. package/dist/root-element.js +541 -0
  129. package/dist/root-element.js.map +1 -0
  130. package/dist/root.d.ts +54 -0
  131. package/dist/root.d.ts.map +1 -0
  132. package/dist/root.js +288 -0
  133. package/dist/root.js.map +1 -0
  134. package/dist/schedule.d.ts +22 -0
  135. package/dist/schedule.d.ts.map +1 -0
  136. package/dist/schedule.js +41 -0
  137. package/dist/schedule.js.map +1 -0
  138. package/dist/session.d.ts +269 -0
  139. package/dist/session.d.ts.map +1 -0
  140. package/dist/session.js +1237 -0
  141. package/dist/session.js.map +1 -0
  142. package/dist/standalone/kgdiff-viewer-compute.js +1 -1
  143. package/dist/standalone/kgdiff-viewer.js +4 -4
  144. package/dist/styles.d.ts +17 -6
  145. package/dist/styles.d.ts.map +1 -1
  146. package/dist/styles.js +367 -258
  147. package/dist/styles.js.map +1 -1
  148. package/dist/theme.d.ts +32 -0
  149. package/dist/theme.d.ts.map +1 -0
  150. package/dist/theme.js +152 -0
  151. package/dist/theme.js.map +1 -0
  152. package/dist/topics.d.ts +8 -0
  153. package/dist/topics.d.ts.map +1 -0
  154. package/dist/topics.js +18 -0
  155. package/dist/topics.js.map +1 -0
  156. package/dist/ui/change-list.d.ts +18 -0
  157. package/dist/ui/change-list.d.ts.map +1 -0
  158. package/dist/ui/change-list.js +331 -0
  159. package/dist/ui/change-list.js.map +1 -0
  160. package/dist/ui/context.d.ts +34 -7
  161. package/dist/ui/context.d.ts.map +1 -1
  162. package/dist/ui/context.js.map +1 -1
  163. package/dist/ui/filters.d.ts +9 -0
  164. package/dist/ui/filters.d.ts.map +1 -0
  165. package/dist/ui/filters.js +68 -0
  166. package/dist/ui/filters.js.map +1 -0
  167. package/dist/ui/header.d.ts +41 -3
  168. package/dist/ui/header.d.ts.map +1 -1
  169. package/dist/ui/header.js +101 -36
  170. package/dist/ui/header.js.map +1 -1
  171. package/dist/ui/legend.d.ts +15 -0
  172. package/dist/ui/legend.d.ts.map +1 -0
  173. package/dist/ui/legend.js +68 -0
  174. package/dist/ui/legend.js.map +1 -0
  175. package/dist/ui/popovers.d.ts +3 -1
  176. package/dist/ui/popovers.d.ts.map +1 -1
  177. package/dist/ui/popovers.js +62 -23
  178. package/dist/ui/popovers.js.map +1 -1
  179. package/dist/ui/search.d.ts +13 -0
  180. package/dist/ui/search.d.ts.map +1 -0
  181. package/dist/ui/search.js +192 -0
  182. package/dist/ui/search.js.map +1 -0
  183. package/dist/ui/sidebar.d.ts +32 -17
  184. package/dist/ui/sidebar.d.ts.map +1 -1
  185. package/dist/ui/sidebar.js +327 -519
  186. package/dist/ui/sidebar.js.map +1 -1
  187. package/dist/ui/stage.d.ts +56 -1
  188. package/dist/ui/stage.d.ts.map +1 -1
  189. package/dist/ui/stage.js +244 -256
  190. package/dist/ui/stage.js.map +1 -1
  191. package/dist/ui/swatch.js +1 -1
  192. package/dist/ui/swatch.js.map +1 -1
  193. package/dist/ui/transport.d.ts +12 -0
  194. package/dist/ui/transport.d.ts.map +1 -0
  195. package/dist/ui/transport.js +198 -0
  196. package/dist/ui/transport.js.map +1 -0
  197. package/dist/ui/zoom.d.ts +15 -0
  198. package/dist/ui/zoom.d.ts.map +1 -0
  199. package/dist/ui/zoom.js +30 -0
  200. package/dist/ui/zoom.js.map +1 -0
  201. package/dist/view.d.ts +94 -0
  202. package/dist/view.d.ts.map +1 -0
  203. package/dist/view.js +441 -0
  204. package/dist/view.js.map +1 -0
  205. package/package.json +95 -12
  206. package/src/bind.ts +80 -0
  207. package/src/context.ts +106 -0
  208. package/src/controller.ts +52 -1630
  209. package/src/dom.ts +30 -0
  210. package/src/element.ts +386 -619
  211. package/src/elements/actions.ts +94 -0
  212. package/src/elements/bound.ts +247 -0
  213. package/src/elements/change-detail.ts +34 -0
  214. package/src/elements/change-list.ts +51 -0
  215. package/src/elements/filters.ts +34 -0
  216. package/src/elements/legend.ts +103 -0
  217. package/src/elements/minimap.ts +75 -0
  218. package/src/elements/root.ts +86 -0
  219. package/src/elements/search.ts +38 -0
  220. package/src/elements/stage-context.ts +34 -0
  221. package/src/elements/stage.ts +285 -0
  222. package/src/elements/title.ts +34 -0
  223. package/src/elements/transport.ts +39 -0
  224. package/src/elements/view-bound.ts +118 -0
  225. package/src/elements/view-dock.ts +43 -0
  226. package/src/elements/zoom.ts +38 -0
  227. package/src/i18n.ts +20 -0
  228. package/src/icons.ts +1 -0
  229. package/src/index.ts +350 -35
  230. package/src/keyboard.ts +188 -61
  231. package/src/layout-store.ts +71 -0
  232. package/src/panel-levels.ts +53 -0
  233. package/src/panels.ts +81 -0
  234. package/src/pipeline.ts +4 -1
  235. package/src/prefs.ts +12 -4
  236. package/src/react.ts +459 -0
  237. package/src/root-element.ts +624 -0
  238. package/src/root.ts +335 -0
  239. package/src/schedule.ts +43 -0
  240. package/src/session.ts +1375 -0
  241. package/src/styles.ts +396 -263
  242. package/src/theme.ts +170 -0
  243. package/src/topics.ts +37 -0
  244. package/src/ui/change-list.ts +405 -0
  245. package/src/ui/context.ts +36 -7
  246. package/src/ui/filters.ts +79 -0
  247. package/src/ui/header.ts +129 -58
  248. package/src/ui/legend.ts +112 -0
  249. package/src/ui/popovers.ts +68 -25
  250. package/src/ui/search.ts +225 -0
  251. package/src/ui/sidebar.ts +362 -639
  252. package/src/ui/stage.ts +267 -331
  253. package/src/ui/swatch.ts +1 -1
  254. package/src/ui/transport.ts +240 -0
  255. package/src/ui/zoom.ts +45 -0
  256. package/src/view.ts +516 -0
  257. package/vscode.html-custom-data.json +726 -0
package/src/bind.ts ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * How regions and elements find the root whose session they show (RFC 0001 §2): the context
3
+ * the root provides (`kgdiff.viewer/1`), what it provides, and the binding helpers. Type-only
4
+ * imports of the session: an element's subpath does not pull the session in through here.
5
+ */
6
+ import { createContext, requestContext } from './context.js';
7
+ import type { Keymap } from './keyboard.js';
8
+ import type { DiffSession, Topic } from './session.js';
9
+ import type { FocusTarget, UiActions, UiContext } from './ui/context.js';
10
+
11
+ /** Something the root renders: a region, or the layout itself. */
12
+ export interface Region {
13
+ update(topics: ReadonlySet<Topic>): void;
14
+ }
15
+
16
+ /** What a root provides to the regions that bind to it. */
17
+ export interface ViewerContext {
18
+ readonly controller: DiffSession;
19
+ readonly actions: UiActions;
20
+ /** The element the root's events are dispatched on and its tokens are set on. */
21
+ readonly host: HTMLElement;
22
+ /** Render `region` on every notification (in binding order); returns the detach. */
23
+ attach(region: Region): () => void;
24
+ target(name: FocusTarget, focus: () => void, available?: () => boolean): () => void;
25
+ focus(name: FocusTarget): boolean;
26
+ /** The keys bound over the default map (the root's `keymap`), or null for the default. */
27
+ readonly keymap: Keymap | null;
28
+ /** The keyboard map, for a key event that reached the root. */
29
+ handleKey(e: KeyboardEvent): void;
30
+ /** A key pressed in an element bound with `for` (outside the root): the root's rules apply. */
31
+ forwardKey(e: KeyboardEvent): void;
32
+ /** The root's token set as a sheet of `doc` (for elements outside the root's subtree). */
33
+ tokens(doc: Document): CSSStyleSheet;
34
+ /** The pointer entered or left the graph (holds a looping replay with `pause-on-hover`). */
35
+ hover(over: boolean): void;
36
+ }
37
+
38
+ export const viewerContext = createContext<ViewerContext>('kgdiff.viewer/1');
39
+
40
+ /** Key events an element forwarded to its root: they belong to that root alone. */
41
+ const forwarded = new WeakSet<Event>();
42
+
43
+ /** Forward `e` to `ctx`'s root; no other root acts on it, whether it was handled or not. */
44
+ export function forwardKey(ctx: ViewerContext, e: KeyboardEvent): void {
45
+ forwarded.add(e);
46
+ ctx.forwardKey(e);
47
+ }
48
+
49
+ /** Whether `e` was forwarded to a root by an element bound with `for`. */
50
+ export function wasForwarded(e: Event): boolean {
51
+ return forwarded.has(e);
52
+ }
53
+
54
+ /** The UI context of a region placed in `root` (its shadow tree), bound to `ctx`. */
55
+ export function uiContext(ctx: ViewerContext, root: ShadowRoot): UiContext {
56
+ return {
57
+ ...ctx.actions,
58
+ controller: ctx.controller,
59
+ root,
60
+ target: (name, focus, available) => ctx.target(name, focus, available),
61
+ focus: (name) => ctx.focus(name),
62
+ keymap: () => ctx.keymap,
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Bind a region to the root nearest `anchor` (an element where the region is placed): `make`
68
+ * builds it once the root answers, and the root renders it from then on.
69
+ */
70
+ export function bindRegion<R extends Region>(anchor: Element, make: (ui: UiContext) => R): R {
71
+ const bound: { region?: R } = {};
72
+ requestContext(anchor, viewerContext, (ctx) => {
73
+ if (bound.region) return;
74
+ bound.region = make(uiContext(ctx, anchor.getRootNode() as ShadowRoot));
75
+ ctx.attach(bound.region);
76
+ });
77
+ // The default layout binds its regions to the root it owns, which answers at once.
78
+ if (!bound.region) throw new Error('[kgdiff] a region found no root to bind to.');
79
+ return bound.region;
80
+ }
package/src/context.ts ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The Web Components community context protocol
3
+ * (https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md),
4
+ * without dependencies: how the viewer's regions find the root whose session they show
5
+ * (RFC 0001 §2).
6
+ *
7
+ * A consumer dispatches a `context-request` event (bubbling, composed: it crosses shadow roots
8
+ * on its way up); the nearest provider of that context answers through the callback and stops
9
+ * the event. Requests nobody answered reach `document`, where they wait; a provider that
10
+ * connects later announces itself with `context-provider` and the waiting requests are sent
11
+ * again, so definition and connection order do not matter. A consumer outside the provider's
12
+ * subtree sends its request through an element inside it (`via`: the root named by `for`).
13
+ */
14
+
15
+ export interface Context<T> {
16
+ /**
17
+ * `Symbol.for(name)`: equal across copies of the library on one page (an IIFE report bundle
18
+ * next to an ESM build), so a component of one copy finds the root of another. The name is
19
+ * versioned when the provided value changes incompatibly.
20
+ */
21
+ readonly key: symbol;
22
+ /** Carries the value type only. */
23
+ readonly __value?: T;
24
+ }
25
+
26
+ export const createContext = <T>(name: string): Context<T> => ({ key: Symbol.for(name) });
27
+
28
+ export class ContextRequestEvent<T> extends Event {
29
+ constructor(
30
+ readonly context: Context<T>,
31
+ /** The consumer, which may differ from the element the event is dispatched on (`via`). */
32
+ readonly consumer: Element,
33
+ readonly callback: (value: T) => void,
34
+ ) {
35
+ super('context-request', { bubbles: true, composed: true });
36
+ }
37
+ }
38
+
39
+ export class ContextProviderEvent<T> extends Event {
40
+ constructor(readonly context: Context<T>) {
41
+ super('context-provider', { bubbles: true, composed: true });
42
+ }
43
+ }
44
+
45
+ interface Waiting {
46
+ readonly context: Context<unknown>;
47
+ readonly consumer: Element;
48
+ readonly via: EventTarget;
49
+ readonly callback: (value: unknown) => void;
50
+ }
51
+
52
+ const waiting = new Set<Waiting>();
53
+ let collecting = false;
54
+
55
+ /** Keep the requests nobody answered, and send them again when a provider connects. */
56
+ function collect(): void {
57
+ if (collecting || typeof document === 'undefined') return;
58
+ collecting = true;
59
+ document.addEventListener('context-request', (e) => {
60
+ // Consumers that left the document since they asked are forgotten, closures and all.
61
+ for (const w of waiting) if (!w.consumer.isConnected) waiting.delete(w);
62
+ const r = e as ContextRequestEvent<unknown>;
63
+ waiting.add({
64
+ context: r.context,
65
+ consumer: r.consumer,
66
+ via: e.composedPath()[0] ?? r.consumer,
67
+ callback: r.callback,
68
+ });
69
+ });
70
+ document.addEventListener('context-provider', (e) => {
71
+ const key = (e as ContextProviderEvent<unknown>).context.key;
72
+ for (const w of [...waiting]) {
73
+ if (w.context.key !== key) continue;
74
+ waiting.delete(w);
75
+ // Unanswered again: it waits again on its way through `document`.
76
+ if (w.consumer.isConnected) {
77
+ w.via.dispatchEvent(new ContextRequestEvent(w.context, w.consumer, w.callback));
78
+ }
79
+ }
80
+ });
81
+ }
82
+
83
+ /** Ask for `context` for `consumer`, through `via` (an element of the provider's subtree). */
84
+ export function requestContext<T>(
85
+ consumer: Element,
86
+ context: Context<T>,
87
+ callback: (value: T) => void,
88
+ via: Element | null = null,
89
+ ): void {
90
+ collect();
91
+ (via ?? consumer).dispatchEvent(new ContextRequestEvent(context, consumer, callback));
92
+ }
93
+
94
+ /** Answer requests for `context` reaching `host`; returns the function that stops answering. */
95
+ export function provideContext<T>(host: Element, context: Context<T>, value: () => T): () => void {
96
+ collect();
97
+ const answer = (e: Event): void => {
98
+ const r = e as ContextRequestEvent<T>;
99
+ if (r.context?.key !== context.key) return;
100
+ e.stopPropagation();
101
+ r.callback(value());
102
+ };
103
+ host.addEventListener('context-request', answer);
104
+ host.dispatchEvent(new ContextProviderEvent(context));
105
+ return () => host.removeEventListener('context-request', answer);
106
+ }