@party-stack/ontology-devtools 0.6.1 → 0.7.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 (130) hide show
  1. package/README.md +195 -0
  2. package/lib/DisclosureSummary.d.ts +7 -0
  3. package/lib/DisclosureSummary.d.ts.map +1 -0
  4. package/lib/DisclosureSummary.js +20 -0
  5. package/lib/DisclosureSummary.js.map +1 -0
  6. package/lib/NativeQueryCode.d.ts +7 -0
  7. package/lib/NativeQueryCode.d.ts.map +1 -0
  8. package/lib/NativeQueryCode.js +35 -0
  9. package/lib/NativeQueryCode.js.map +1 -0
  10. package/lib/OntologyDevtools.d.ts +11 -49
  11. package/lib/OntologyDevtools.d.ts.map +1 -1
  12. package/lib/OntologyDevtools.js +310 -626
  13. package/lib/OntologyDevtools.js.map +1 -1
  14. package/lib/OntologyIcons.d.ts +14 -0
  15. package/lib/OntologyIcons.d.ts.map +1 -0
  16. package/lib/OntologyIcons.js +22 -0
  17. package/lib/OntologyIcons.js.map +1 -0
  18. package/lib/PanelBoundary.d.ts +10 -0
  19. package/lib/PanelBoundary.d.ts.map +1 -0
  20. package/lib/PanelBoundary.js +67 -0
  21. package/lib/PanelBoundary.js.map +1 -0
  22. package/lib/Pinned.d.ts +14 -0
  23. package/lib/Pinned.d.ts.map +1 -0
  24. package/lib/Pinned.js +142 -0
  25. package/lib/Pinned.js.map +1 -0
  26. package/lib/PinnedFamily.d.ts +13 -0
  27. package/lib/PinnedFamily.d.ts.map +1 -0
  28. package/lib/PinnedFamily.js +105 -0
  29. package/lib/PinnedFamily.js.map +1 -0
  30. package/lib/Queries.d.ts +12 -0
  31. package/lib/Queries.d.ts.map +1 -0
  32. package/lib/Queries.js +147 -0
  33. package/lib/Queries.js.map +1 -0
  34. package/lib/QueryOwners.d.ts +7 -0
  35. package/lib/QueryOwners.d.ts.map +1 -0
  36. package/lib/QueryOwners.js +46 -0
  37. package/lib/QueryOwners.js.map +1 -0
  38. package/lib/QueryPills.d.ts +17 -0
  39. package/lib/QueryPills.d.ts.map +1 -0
  40. package/lib/QueryPills.js +37 -0
  41. package/lib/QueryPills.js.map +1 -0
  42. package/lib/QueryPushdown.d.ts +26 -0
  43. package/lib/QueryPushdown.d.ts.map +1 -0
  44. package/lib/QueryPushdown.js +380 -0
  45. package/lib/QueryPushdown.js.map +1 -0
  46. package/lib/QueryTokens.d.ts +25 -0
  47. package/lib/QueryTokens.d.ts.map +1 -0
  48. package/lib/QueryTokens.js +49 -0
  49. package/lib/QueryTokens.js.map +1 -0
  50. package/lib/QueryView.d.ts +37 -0
  51. package/lib/QueryView.d.ts.map +1 -0
  52. package/lib/QueryView.js +547 -0
  53. package/lib/QueryView.js.map +1 -0
  54. package/lib/SchemaView.d.ts +8 -0
  55. package/lib/SchemaView.d.ts.map +1 -0
  56. package/lib/SchemaView.js +213 -0
  57. package/lib/SchemaView.js.map +1 -0
  58. package/lib/Storage.d.ts +17 -0
  59. package/lib/Storage.d.ts.map +1 -0
  60. package/lib/Storage.js +205 -0
  61. package/lib/Storage.js.map +1 -0
  62. package/lib/Tracing.d.ts +7 -0
  63. package/lib/Tracing.d.ts.map +1 -0
  64. package/lib/Tracing.js +344 -0
  65. package/lib/Tracing.js.map +1 -0
  66. package/lib/attribution/Highlight.d.ts +9 -0
  67. package/lib/attribution/Highlight.d.ts.map +1 -0
  68. package/lib/attribution/Highlight.js +73 -0
  69. package/lib/attribution/Highlight.js.map +1 -0
  70. package/lib/attribution/index.d.ts +12 -0
  71. package/lib/attribution/index.d.ts.map +1 -0
  72. package/lib/attribution/index.js +31 -0
  73. package/lib/attribution/index.js.map +1 -0
  74. package/lib/attribution/registry.d.ts +16 -0
  75. package/lib/attribution/registry.d.ts.map +1 -0
  76. package/lib/attribution/registry.js +31 -0
  77. package/lib/attribution/registry.js.map +1 -0
  78. package/lib/attribution/tanstack.d.ts +11 -0
  79. package/lib/attribution/tanstack.d.ts.map +1 -0
  80. package/lib/attribution/tanstack.js +81 -0
  81. package/lib/attribution/tanstack.js.map +1 -0
  82. package/lib/chrome.d.ts +9 -0
  83. package/lib/chrome.d.ts.map +1 -0
  84. package/lib/chrome.js +41 -0
  85. package/lib/chrome.js.map +1 -0
  86. package/lib/diagnostics.d.ts +15 -0
  87. package/lib/diagnostics.d.ts.map +1 -0
  88. package/lib/diagnostics.js +31 -0
  89. package/lib/diagnostics.js.map +1 -0
  90. package/lib/index.d.ts +4 -2
  91. package/lib/index.js +3 -2
  92. package/lib/plugin.d.ts +11 -0
  93. package/lib/plugin.d.ts.map +1 -0
  94. package/lib/plugin.js +62 -0
  95. package/lib/plugin.js.map +1 -0
  96. package/lib/queryIR.d.ts +9 -0
  97. package/lib/queryIR.d.ts.map +1 -0
  98. package/lib/queryIR.js +69 -0
  99. package/lib/queryIR.js.map +1 -0
  100. package/lib/replicationActivity.d.ts +52 -0
  101. package/lib/replicationActivity.d.ts.map +1 -0
  102. package/lib/replicationActivity.js +54 -0
  103. package/lib/replicationActivity.js.map +1 -0
  104. package/lib/schemaLayout.d.ts +35 -0
  105. package/lib/schemaLayout.d.ts.map +1 -0
  106. package/lib/schemaLayout.js +75 -0
  107. package/lib/schemaLayout.js.map +1 -0
  108. package/lib/styles.js +6 -0
  109. package/lib/styles.js.map +1 -0
  110. package/lib/traceTimeline.d.ts +15 -0
  111. package/lib/traceTimeline.d.ts.map +1 -0
  112. package/lib/traceTimeline.js +36 -0
  113. package/lib/traceTimeline.js.map +1 -0
  114. package/lib/traceWaterfall.d.ts +25 -0
  115. package/lib/traceWaterfall.d.ts.map +1 -0
  116. package/lib/traceWaterfall.js +70 -0
  117. package/lib/traceWaterfall.js.map +1 -0
  118. package/lib/typeDisplayName.d.ts +5 -0
  119. package/lib/typeDisplayName.d.ts.map +1 -0
  120. package/lib/typeDisplayName.js +28 -0
  121. package/lib/typeDisplayName.js.map +1 -0
  122. package/lib/types.d.ts +17 -0
  123. package/lib/types.d.ts.map +1 -0
  124. package/lib/types.js +1 -0
  125. package/lib/vite/index.d.ts +18 -0
  126. package/lib/vite/index.d.ts.map +1 -0
  127. package/lib/vite/index.js +148 -0
  128. package/lib/vite/index.js.map +1 -0
  129. package/package.json +26 -9
  130. package/lib/styles.css +0 -2
@@ -0,0 +1,67 @@
1
+ import styles_default from "./styles.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useLayoutEffect, useRef, useState } from "react";
4
+ import { createPortal } from "react-dom";
5
+ //#region src/PanelBoundary.tsx
6
+ const PanelPortal = createContext(null);
7
+ const usePanelPortal = () => useContext(PanelPortal);
8
+ /** Keep panel and overlay styles private, while overlays can escape the shell's clipping. */
9
+ function PanelBoundary({ children, theme }) {
10
+ const host = useRef(null);
11
+ const overlayElement = useRef(null);
12
+ const [roots, setRoots] = useState();
13
+ useLayoutEffect(() => {
14
+ const element = host.current;
15
+ const document = element.ownerDocument;
16
+ const panel = element.shadowRoot ?? element.attachShadow({ mode: "open" });
17
+ const panelStyle = document.createElement("style");
18
+ panelStyle.textContent = styles_default;
19
+ panel.append(panelStyle);
20
+ const overlayHost = document.createElement("div");
21
+ overlayHost.dataset.psDevtools = "overlays";
22
+ overlayHost.style.cssText = "all: initial; display: contents;";
23
+ const overlayRoot = overlayHost.attachShadow({ mode: "open" });
24
+ const overlayStyle = document.createElement("style");
25
+ overlayStyle.textContent = styles_default;
26
+ const overlays = document.createElement("div");
27
+ overlays.style.cssText = "all: initial; display: contents; font: 13px/1.5 Inter, ui-sans-serif, system-ui, sans-serif;";
28
+ overlayRoot.append(overlayStyle, overlays);
29
+ document.body.append(overlayHost);
30
+ overlayElement.current = overlays;
31
+ setRoots({
32
+ panel,
33
+ overlays
34
+ });
35
+ return () => {
36
+ panelStyle.remove();
37
+ overlayHost.remove();
38
+ overlayElement.current = null;
39
+ };
40
+ }, []);
41
+ useLayoutEffect(() => {
42
+ const overlays = overlayElement.current;
43
+ if (!overlays) return;
44
+ overlays.className = `ps-devtools ps-theme-${theme}`;
45
+ overlays.style.colorScheme = theme;
46
+ }, [roots, theme]);
47
+ return /* @__PURE__ */ jsx("div", {
48
+ "data-ps-devtools": "panel",
49
+ ref: host,
50
+ style: {
51
+ all: "initial",
52
+ display: "block",
53
+ width: "100%",
54
+ height: "100%",
55
+ minHeight: 0,
56
+ colorScheme: theme
57
+ },
58
+ children: roots && createPortal(/* @__PURE__ */ jsx(PanelPortal.Provider, {
59
+ value: roots.overlays,
60
+ children
61
+ }), roots.panel)
62
+ });
63
+ }
64
+ //#endregion
65
+ export { PanelBoundary, usePanelPortal };
66
+
67
+ //# sourceMappingURL=PanelBoundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelBoundary.js","names":["styles"],"sources":["../src/PanelBoundary.tsx"],"sourcesContent":["import { createContext, useContext, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport styles from \"./styles.css?inline\";\n\nconst PanelPortal = createContext<HTMLElement | null>(null);\nexport const usePanelPortal = () => useContext(PanelPortal);\n\ninterface Roots {\n panel: ShadowRoot;\n overlays: HTMLElement;\n}\n\n/** Keep panel and overlay styles private, while overlays can escape the shell's clipping. */\nexport function PanelBoundary({ children, theme }: { children: ReactNode; theme: \"light\" | \"dark\" }) {\n const host = useRef<HTMLDivElement>(null);\n const overlayElement = useRef<HTMLElement | null>(null);\n const [roots, setRoots] = useState<Roots>();\n useLayoutEffect(() => {\n const element = host.current!;\n const document = element.ownerDocument;\n const panel = element.shadowRoot ?? element.attachShadow({ mode: \"open\" });\n const panelStyle = document.createElement(\"style\");\n panelStyle.textContent = styles;\n panel.append(panelStyle);\n\n const overlayHost = document.createElement(\"div\");\n overlayHost.dataset.psDevtools = \"overlays\";\n overlayHost.style.cssText = \"all: initial; display: contents;\";\n const overlayRoot = overlayHost.attachShadow({ mode: \"open\" });\n const overlayStyle = document.createElement(\"style\");\n overlayStyle.textContent = styles;\n const overlays = document.createElement(\"div\");\n overlays.style.cssText =\n \"all: initial; display: contents; font: 13px/1.5 Inter, ui-sans-serif, system-ui, sans-serif;\";\n overlayRoot.append(overlayStyle, overlays);\n document.body.append(overlayHost);\n overlayElement.current = overlays;\n setRoots({ panel, overlays });\n return () => {\n panelStyle.remove();\n overlayHost.remove();\n overlayElement.current = null;\n };\n }, []);\n useLayoutEffect(() => {\n const overlays = overlayElement.current;\n if (!overlays) return;\n overlays.className = `ps-devtools ps-theme-${theme}`;\n overlays.style.colorScheme = theme;\n }, [roots, theme]);\n return (\n <div\n data-ps-devtools=\"panel\"\n ref={host}\n style={{\n all: \"initial\",\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n minHeight: 0,\n colorScheme: theme,\n }}\n >\n {roots &&\n createPortal(\n <PanelPortal.Provider value={roots.overlays}>{children}</PanelPortal.Provider>,\n roots.panel\n )}\n </div>\n );\n}\n"],"mappings":";;;;;AAIA,MAAM,cAAc,cAAkC,IAAI;AAC1D,MAAa,uBAAuB,WAAW,WAAW;;AAQ1D,SAAgB,cAAc,EAAE,UAAU,SAA2D;CACjG,MAAM,OAAO,OAAuB,IAAI;CACxC,MAAM,iBAAiB,OAA2B,IAAI;CACtD,MAAM,CAAC,OAAO,YAAY,SAAgB;CAC1C,sBAAsB;EAClB,MAAM,UAAU,KAAK;EACrB,MAAM,WAAW,QAAQ;EACzB,MAAM,QAAQ,QAAQ,cAAc,QAAQ,aAAa,EAAE,MAAM,OAAO,CAAC;EACzE,MAAM,aAAa,SAAS,cAAc,OAAO;EACjD,WAAW,cAAcA;EACzB,MAAM,OAAO,UAAU;EAEvB,MAAM,cAAc,SAAS,cAAc,KAAK;EAChD,YAAY,QAAQ,aAAa;EACjC,YAAY,MAAM,UAAU;EAC5B,MAAM,cAAc,YAAY,aAAa,EAAE,MAAM,OAAO,CAAC;EAC7D,MAAM,eAAe,SAAS,cAAc,OAAO;EACnD,aAAa,cAAcA;EAC3B,MAAM,WAAW,SAAS,cAAc,KAAK;EAC7C,SAAS,MAAM,UACX;EACJ,YAAY,OAAO,cAAc,QAAQ;EACzC,SAAS,KAAK,OAAO,WAAW;EAChC,eAAe,UAAU;EACzB,SAAS;GAAE;GAAO;EAAS,CAAC;EAC5B,aAAa;GACT,WAAW,OAAO;GAClB,YAAY,OAAO;GACnB,eAAe,UAAU;EAC7B;CACJ,GAAG,CAAC,CAAC;CACL,sBAAsB;EAClB,MAAM,WAAW,eAAe;EAChC,IAAI,CAAC,UAAU;EACf,SAAS,YAAY,wBAAwB;EAC7C,SAAS,MAAM,cAAc;CACjC,GAAG,CAAC,OAAO,KAAK,CAAC;CACjB,OACI,oBAAC,OAAD;EACI,oBAAiB;EACjB,KAAK;EACL,OAAO;GACH,KAAK;GACL,SAAS;GACT,OAAO;GACP,QAAQ;GACR,WAAW;GACX,aAAa;EACjB;EAEC,UAAA,SACG,aACI,oBAAC,YAAY,UAAb;GAAsB,OAAO,MAAM;GAAW;EAA+B,CAAA,GAC7E,MAAM,KACV;CACH,CAAA;AAEb"}
@@ -0,0 +1,14 @@
1
+ import { LiveOntology, OntologyIR, PinStatus } from "@party-stack/ontology";
2
+ //#region src/Pinned.d.ts
3
+ export declare function Pinned({ ontology }: {
4
+ ontology: LiveOntology;
5
+ }): import("react").JSX.Element;
6
+ export declare function PinnedContent({ ir, status, loading, error, title }: {
7
+ ir: OntologyIR;
8
+ status?: PinStatus;
9
+ loading?: boolean;
10
+ error?: unknown;
11
+ title?: string;
12
+ }): import("react").JSX.Element;
13
+ //#endregion
14
+ //# sourceMappingURL=Pinned.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pinned.d.ts","names":[],"sources":["../src/Pinned.tsx"],"mappings":";;wBASgB,SAAS;EAAc,UAAU;oBAAc,IAAA;wBAgE/C,gBACZ,IACA,QACA,SACA,OACA;EAEA,IAAI;EACJ,SAAS;EACT;EACA;EACA;oBACH,IAAA"}
package/lib/Pinned.js ADDED
@@ -0,0 +1,142 @@
1
+ import { DisclosureSummary } from "./DisclosureSummary.js";
2
+ import { QueryDocumentView, QueryExpression } from "./QueryView.js";
3
+ import { PinnedFamily, groupPinDownloads } from "./PinnedFamily.js";
4
+ import { CircleAlert, CircleCheck, LoaderCircle, Paperclip, Pin } from "lucide-react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { Suspense, useEffect, useState } from "react";
7
+ import { useLiveSuspenseQuery } from "@tanstack/react-db";
8
+ import { PartyStackLogomark } from "@party-stack/design-system/brand";
9
+ //#region src/Pinned.tsx
10
+ function Pinned({ ontology }) {
11
+ return /* @__PURE__ */ jsx("div", {
12
+ className: "ps-pinned-inventory",
13
+ children: /* @__PURE__ */ jsx(Suspense, {
14
+ fallback: /* @__PURE__ */ jsx(PinnedContent, {
15
+ ir: ontology.ir,
16
+ loading: true
17
+ }),
18
+ children: /* @__PURE__ */ jsx(PinInventory, { ontology })
19
+ })
20
+ });
21
+ }
22
+ function PinInventory({ ontology }) {
23
+ const { pins } = ontology;
24
+ const { data: downloads } = useLiveSuspenseQuery((q) => q.from({ pin: pins.collection }).orderBy(({ pin }) => pin.name, "asc").orderBy(({ pin }) => pin.id, "asc"));
25
+ const [snapshot, setSnapshot] = useState();
26
+ useEffect(() => {
27
+ let active = true;
28
+ let unsubscribe = () => {};
29
+ const onError = (error) => {
30
+ if (active) setSnapshot({
31
+ pins,
32
+ error
33
+ });
34
+ };
35
+ try {
36
+ unsubscribe = pins.subscribe((status) => {
37
+ if (active) setSnapshot({
38
+ pins,
39
+ status
40
+ });
41
+ }, onError);
42
+ } catch (error) {
43
+ onError(error);
44
+ }
45
+ return () => {
46
+ active = false;
47
+ unsubscribe();
48
+ };
49
+ }, [pins]);
50
+ const current = snapshot?.pins === pins ? snapshot : void 0;
51
+ if (!downloads.length) return /* @__PURE__ */ jsx(PinnedContent, {
52
+ ir: ontology.ir,
53
+ status: current?.status,
54
+ loading: !current,
55
+ error: current?.error
56
+ });
57
+ return /* @__PURE__ */ jsxs(Fragment, { children: [groupPinDownloads(downloads).map((family) => /* @__PURE__ */ jsx(PinnedFamily, {
58
+ family,
59
+ ir: ontology.ir,
60
+ remove: ontology.pins.remove
61
+ }, family.name)), current?.status && /* @__PURE__ */ jsx(PinnedContent, {
62
+ ir: ontology.ir,
63
+ status: current.status,
64
+ title: "Legacy application download"
65
+ })] });
66
+ }
67
+ function PinnedContent({ ir, status, loading = false, error, title = "Pinned graph" }) {
68
+ if (loading) return /* @__PURE__ */ jsx("div", {
69
+ className: "ps-pinned-empty",
70
+ children: /* @__PURE__ */ jsx("output", {
71
+ "aria-label": "Reading pinned graph",
72
+ children: /* @__PURE__ */ jsx("span", {
73
+ className: "ps-pinned-logo",
74
+ children: /* @__PURE__ */ jsx(PartyStackLogomark, {})
75
+ })
76
+ })
77
+ });
78
+ const failure = error instanceof Error ? error.message : typeof error === "string" ? error : error ? "Could not read the pinned graph." : status?.error?.message;
79
+ if (!status) return /* @__PURE__ */ jsxs("div", {
80
+ className: "ps-pinned-empty",
81
+ children: [/* @__PURE__ */ jsx(Pin, {
82
+ size: 24,
83
+ "aria-hidden": true
84
+ }), /* @__PURE__ */ jsx("p", {
85
+ role: failure ? "alert" : void 0,
86
+ children: failure ?? "No pinned graph."
87
+ })]
88
+ });
89
+ const state = failure ? "error" : status.ready ? "ready" : "loading";
90
+ const Icon = failure ? CircleAlert : status.ready ? CircleCheck : LoaderCircle;
91
+ return /* @__PURE__ */ jsxs("div", {
92
+ className: "ps-diagnostics-screen ps-pinned-screen",
93
+ "aria-label": "Pinned inspector",
94
+ children: [
95
+ /* @__PURE__ */ jsx("header", {
96
+ className: "ps-pinned-header",
97
+ children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", { children: title }), /* @__PURE__ */ jsxs("div", {
98
+ className: "ps-pinned-meta",
99
+ children: [/* @__PURE__ */ jsxs("output", {
100
+ className: "ps-pinned-status",
101
+ "data-state": state,
102
+ children: [/* @__PURE__ */ jsx(Icon, {
103
+ size: 15,
104
+ "aria-hidden": true
105
+ }), failure ? "Download interrupted" : status.ready ? "Available offline" : "Loading pinned graph…"]
106
+ }), /* @__PURE__ */ jsxs("span", {
107
+ className: "ps-pinned-attachments",
108
+ children: [/* @__PURE__ */ jsx(Paperclip, {
109
+ size: 14,
110
+ "aria-hidden": true
111
+ }), status.attachments === "all" ? "Includes attachment bytes" : "Objects only"]
112
+ })]
113
+ })] })
114
+ }),
115
+ failure && /* @__PURE__ */ jsx("p", {
116
+ className: "ps-replication-error",
117
+ role: "alert",
118
+ children: failure
119
+ }),
120
+ status.previousGraphRetained && /* @__PURE__ */ jsx("p", {
121
+ className: "ps-pinned-retained",
122
+ children: "The previous graph is retained until this replacement is ready."
123
+ }),
124
+ status.inputs && Object.keys(status.inputs).length > 0 && /* @__PURE__ */ jsxs("details", {
125
+ className: "ps-pinned-inputs",
126
+ children: [/* @__PURE__ */ jsx(DisclosureSummary, { children: "Inputs" }), /* @__PURE__ */ jsx(QueryExpression, { expression: {
127
+ kind: "literal",
128
+ value: { value: status.inputs }
129
+ } })]
130
+ }),
131
+ /* @__PURE__ */ jsx(QueryDocumentView, {
132
+ query: status.query,
133
+ ir,
134
+ showFields: false
135
+ })
136
+ ]
137
+ });
138
+ }
139
+ //#endregion
140
+ export { Pinned, PinnedContent };
141
+
142
+ //# sourceMappingURL=Pinned.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pinned.js","names":[],"sources":["../src/Pinned.tsx"],"sourcesContent":["import { PartyStackLogomark } from \"@party-stack/design-system/brand\";\nimport { useLiveSuspenseQuery } from \"@tanstack/react-db\";\nimport { CircleAlert, CircleCheck, LoaderCircle, Paperclip, Pin } from \"lucide-react\";\nimport { Suspense, useEffect, useState } from \"react\";\nimport { DisclosureSummary } from \"./DisclosureSummary.js\";\nimport { PinnedFamily, groupPinDownloads } from \"./PinnedFamily.js\";\nimport { QueryDocumentView, QueryExpression } from \"./QueryView.js\";\nimport type { LiveOntology, OntologyIR, PinStatus } from \"@party-stack/ontology\";\n\nexport function Pinned({ ontology }: { ontology: LiveOntology }) {\n return (\n <div className=\"ps-pinned-inventory\">\n <Suspense fallback={<PinnedContent ir={ontology.ir} loading />}>\n <PinInventory ontology={ontology} />\n </Suspense>\n </div>\n );\n}\n\nfunction PinInventory({ ontology }: { ontology: LiveOntology }) {\n const { pins } = ontology;\n const { data: downloads } = useLiveSuspenseQuery((q) =>\n q\n .from({ pin: pins.collection })\n .orderBy(({ pin }) => pin.name, \"asc\")\n .orderBy(({ pin }) => pin.id, \"asc\")\n );\n const [snapshot, setSnapshot] = useState<{ pins: typeof pins; status?: PinStatus; error?: unknown }>();\n useEffect(() => {\n let active = true;\n let unsubscribe = () => {};\n const onError = (error: unknown) => {\n if (active) setSnapshot({ pins, error });\n };\n try {\n unsubscribe = pins.subscribe((status) => {\n if (active) setSnapshot({ pins, status });\n }, onError);\n } catch (error) {\n onError(error);\n }\n return () => {\n active = false;\n unsubscribe();\n };\n }, [pins]);\n const current = snapshot?.pins === pins ? snapshot : undefined;\n if (!downloads.length)\n return (\n <PinnedContent\n ir={ontology.ir}\n status={current?.status}\n loading={!current}\n error={current?.error}\n />\n );\n return (\n <>\n {groupPinDownloads(downloads).map((family) => (\n <PinnedFamily\n key={family.name}\n family={family}\n ir={ontology.ir}\n remove={ontology.pins.remove}\n />\n ))}\n {current?.status && (\n <PinnedContent ir={ontology.ir} status={current.status} title=\"Legacy application download\" />\n )}\n </>\n );\n}\n\nexport function PinnedContent({\n ir,\n status,\n loading = false,\n error,\n title = \"Pinned graph\",\n}: {\n ir: OntologyIR;\n status?: PinStatus;\n loading?: boolean;\n error?: unknown;\n title?: string;\n}) {\n if (loading)\n return (\n <div className=\"ps-pinned-empty\">\n <output aria-label=\"Reading pinned graph\">\n <span className=\"ps-pinned-logo\">\n <PartyStackLogomark />\n </span>\n </output>\n </div>\n );\n const failure =\n error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : error\n ? \"Could not read the pinned graph.\"\n : status?.error?.message;\n if (!status)\n return (\n <div className=\"ps-pinned-empty\">\n <Pin size={24} aria-hidden />\n <p role={failure ? \"alert\" : undefined}>{failure ?? \"No pinned graph.\"}</p>\n </div>\n );\n const state = failure ? \"error\" : status.ready ? \"ready\" : \"loading\";\n const Icon = failure ? CircleAlert : status.ready ? CircleCheck : LoaderCircle;\n return (\n <div className=\"ps-diagnostics-screen ps-pinned-screen\" aria-label=\"Pinned inspector\">\n <header className=\"ps-pinned-header\">\n <div>\n <h2>{title}</h2>\n <div className=\"ps-pinned-meta\">\n <output className=\"ps-pinned-status\" data-state={state}>\n <Icon size={15} aria-hidden />\n {failure\n ? \"Download interrupted\"\n : status.ready\n ? \"Available offline\"\n : \"Loading pinned graph…\"}\n </output>\n <span className=\"ps-pinned-attachments\">\n <Paperclip size={14} aria-hidden />\n {status.attachments === \"all\" ? \"Includes attachment bytes\" : \"Objects only\"}\n </span>\n </div>\n </div>\n </header>\n {failure && (\n <p className=\"ps-replication-error\" role=\"alert\">\n {failure}\n </p>\n )}\n {status.previousGraphRetained && (\n <p className=\"ps-pinned-retained\">\n The previous graph is retained until this replacement is ready.\n </p>\n )}\n {status.inputs && Object.keys(status.inputs).length > 0 && (\n <details className=\"ps-pinned-inputs\">\n <DisclosureSummary>Inputs</DisclosureSummary>\n <QueryExpression expression={{ kind: \"literal\", value: { value: status.inputs } }} />\n </details>\n )}\n <QueryDocumentView query={status.query} ir={ir} showFields={false} />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { OntologyIR, PinRecord } from "@party-stack/ontology";
2
+ //#region src/PinnedFamily.d.ts
3
+ export declare function groupPinDownloads(pins: readonly PinRecord[]): {
4
+ name: string;
5
+ revisions: Map<string, PinRecord[]>;
6
+ }[];
7
+ export declare function PinnedFamily({ family, ir, remove }: {
8
+ family: ReturnType<typeof groupPinDownloads>[number];
9
+ ir: OntologyIR;
10
+ remove: (id: string) => Promise<void>;
11
+ }): import("react").JSX.Element;
12
+ //#endregion
13
+ //# sourceMappingURL=PinnedFamily.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PinnedFamily.d.ts","names":[],"sources":["../src/PinnedFamily.tsx"],"mappings":";;wBAKgB,kBAAkB,eAAe;EACJ;EAAmB,WAAA,YAAY;;wBAc5D,eACZ,QACA,IACA;EAEA,QAAQ,kBAAkB;EAC1B,IAAI;EACJ,SAAS,eAAe;oBAC3B,IAAA"}
@@ -0,0 +1,105 @@
1
+ import { QueryDocumentView, QueryExpression } from "./QueryView.js";
2
+ import { CircleAlert, CircleCheck, LoaderCircle, Paperclip } from "lucide-react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { useState } from "react";
5
+ //#region src/PinnedFamily.tsx
6
+ function groupPinDownloads(pins) {
7
+ const families = /* @__PURE__ */ new Map();
8
+ for (const pin of pins) {
9
+ let family = families.get(pin.name);
10
+ if (!family) {
11
+ family = {
12
+ name: pin.name,
13
+ revisions: /* @__PURE__ */ new Map()
14
+ };
15
+ families.set(pin.name, family);
16
+ }
17
+ const downloads = family.revisions.get(pin.definition);
18
+ if (downloads) downloads.push(pin);
19
+ else family.revisions.set(pin.definition, [pin]);
20
+ }
21
+ return [...families.values()];
22
+ }
23
+ function PinnedFamily({ family, ir, remove }) {
24
+ return /* @__PURE__ */ jsxs("section", {
25
+ className: "ps-diagnostics-screen ps-pinned-screen ps-pinned-family",
26
+ "aria-label": family.name,
27
+ children: [/* @__PURE__ */ jsx("header", {
28
+ className: "ps-pinned-header",
29
+ children: /* @__PURE__ */ jsx("h2", { children: family.name })
30
+ }), [...family.revisions].map(([definition, pins]) => /* @__PURE__ */ jsxs("div", {
31
+ className: "ps-pin-revision",
32
+ children: [
33
+ /* @__PURE__ */ jsxs("div", {
34
+ className: "ps-pinned-meta",
35
+ children: [family.revisions.size > 1 && /* @__PURE__ */ jsxs("code", {
36
+ title: definition,
37
+ children: ["Revision ", definition.slice(0, 8)]
38
+ }), /* @__PURE__ */ jsxs("span", {
39
+ className: "ps-pinned-attachments",
40
+ children: [/* @__PURE__ */ jsx(Paperclip, {
41
+ size: 14,
42
+ "aria-hidden": true
43
+ }), pins[0].attachments === "all" ? "Includes attachment bytes" : "Objects only"]
44
+ })]
45
+ }),
46
+ /* @__PURE__ */ jsx("div", {
47
+ className: "ps-pin-downloads",
48
+ children: pins.map((pin) => /* @__PURE__ */ jsx(PinDownload, {
49
+ pin,
50
+ remove
51
+ }, pin.id))
52
+ }),
53
+ /* @__PURE__ */ jsx(QueryDocumentView, {
54
+ query: pins[0].query,
55
+ ir,
56
+ showFields: false
57
+ })
58
+ ]
59
+ }, definition))]
60
+ });
61
+ }
62
+ function PinDownload({ pin, remove }) {
63
+ const [failure, setFailure] = useState();
64
+ const error = failure ?? pin.error?.message;
65
+ const state = error ? "error" : pin.ready ? "ready" : "loading";
66
+ const Icon = error ? CircleAlert : pin.ready ? CircleCheck : LoaderCircle;
67
+ return /* @__PURE__ */ jsxs("div", {
68
+ className: "ps-pin-download",
69
+ "data-pin-id": pin.id,
70
+ children: [
71
+ /* @__PURE__ */ jsxs("div", {
72
+ className: "ps-pin-inputs",
73
+ children: [Object.keys(pin.inputs).length ? /* @__PURE__ */ jsx(QueryExpression, { expression: {
74
+ kind: "literal",
75
+ value: { value: pin.inputs }
76
+ } }) : /* @__PURE__ */ jsx("span", { children: "No inputs" }), error && /* @__PURE__ */ jsx("p", {
77
+ role: "alert",
78
+ className: "ps-replication-error",
79
+ children: error
80
+ })]
81
+ }),
82
+ /* @__PURE__ */ jsxs("output", {
83
+ className: "ps-pinned-status",
84
+ "data-state": state,
85
+ children: [/* @__PURE__ */ jsx(Icon, {
86
+ size: 15,
87
+ "aria-hidden": true
88
+ }), error ? "Interrupted" : pin.ready ? "Available offline" : "Downloading…"]
89
+ }),
90
+ /* @__PURE__ */ jsx("button", {
91
+ type: "button",
92
+ className: "ps-pinned-remove",
93
+ onClick: () => {
94
+ setFailure(void 0);
95
+ remove(pin.id).catch((error) => setFailure(error instanceof Error ? error.message : "Could not remove download."));
96
+ },
97
+ children: pin.ready || error ? "Remove" : "Cancel"
98
+ })
99
+ ]
100
+ });
101
+ }
102
+ //#endregion
103
+ export { PinnedFamily, groupPinDownloads };
104
+
105
+ //# sourceMappingURL=PinnedFamily.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PinnedFamily.js","names":[],"sources":["../src/PinnedFamily.tsx"],"sourcesContent":["import { CircleAlert, CircleCheck, LoaderCircle, Paperclip } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { QueryDocumentView, QueryExpression } from \"./QueryView.js\";\nimport type { OntologyIR, PinRecord } from \"@party-stack/ontology\";\n\nexport function groupPinDownloads(pins: readonly PinRecord[]) {\n const families = new Map<string, { name: string; revisions: Map<string, PinRecord[]> }>();\n for (const pin of pins) {\n let family = families.get(pin.name);\n if (!family) {\n family = { name: pin.name, revisions: new Map() };\n families.set(pin.name, family);\n }\n const downloads = family.revisions.get(pin.definition);\n if (downloads) downloads.push(pin);\n else family.revisions.set(pin.definition, [pin]);\n }\n return [...families.values()];\n}\n\nexport function PinnedFamily({\n family,\n ir,\n remove,\n}: {\n family: ReturnType<typeof groupPinDownloads>[number];\n ir: OntologyIR;\n remove: (id: string) => Promise<void>;\n}) {\n return (\n <section className=\"ps-diagnostics-screen ps-pinned-screen ps-pinned-family\" aria-label={family.name}>\n <header className=\"ps-pinned-header\">\n <h2>{family.name}</h2>\n </header>\n {[...family.revisions].map(([definition, pins]) => (\n <div className=\"ps-pin-revision\" key={definition}>\n <div className=\"ps-pinned-meta\">\n {family.revisions.size > 1 && (\n <code title={definition}>Revision {definition.slice(0, 8)}</code>\n )}\n <span className=\"ps-pinned-attachments\">\n <Paperclip size={14} aria-hidden />\n {pins[0]!.attachments === \"all\" ? \"Includes attachment bytes\" : \"Objects only\"}\n </span>\n </div>\n <div className=\"ps-pin-downloads\">\n {pins.map((pin) => (\n <PinDownload key={pin.id} pin={pin} remove={remove} />\n ))}\n </div>\n <QueryDocumentView query={pins[0]!.query} ir={ir} showFields={false} />\n </div>\n ))}\n </section>\n );\n}\n\nfunction PinDownload({ pin, remove }: { pin: PinRecord; remove: (id: string) => Promise<void> }) {\n const [failure, setFailure] = useState<string>();\n const error = failure ?? pin.error?.message;\n const state = error ? \"error\" : pin.ready ? \"ready\" : \"loading\";\n const Icon = error ? CircleAlert : pin.ready ? CircleCheck : LoaderCircle;\n return (\n <div className=\"ps-pin-download\" data-pin-id={pin.id}>\n <div className=\"ps-pin-inputs\">\n {Object.keys(pin.inputs).length ? (\n <QueryExpression expression={{ kind: \"literal\", value: { value: pin.inputs } }} />\n ) : (\n <span>No inputs</span>\n )}\n {error && (\n <p role=\"alert\" className=\"ps-replication-error\">\n {error}\n </p>\n )}\n </div>\n <output className=\"ps-pinned-status\" data-state={state}>\n <Icon size={15} aria-hidden />\n {error ? \"Interrupted\" : pin.ready ? \"Available offline\" : \"Downloading…\"}\n </output>\n <button\n type=\"button\"\n className=\"ps-pinned-remove\"\n onClick={() => {\n setFailure(undefined);\n void remove(pin.id).catch((error: unknown) =>\n setFailure(error instanceof Error ? error.message : \"Could not remove download.\")\n );\n }}\n >\n {pin.ready || error ? \"Remove\" : \"Cancel\"}\n </button>\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,SAAgB,kBAAkB,MAA4B;CAC1D,MAAM,2BAAW,IAAI,IAAmE;CACxF,KAAK,MAAM,OAAO,MAAM;EACpB,IAAI,SAAS,SAAS,IAAI,IAAI,IAAI;EAClC,IAAI,CAAC,QAAQ;GACT,SAAS;IAAE,MAAM,IAAI;IAAM,2BAAW,IAAI,IAAI;GAAE;GAChD,SAAS,IAAI,IAAI,MAAM,MAAM;EACjC;EACA,MAAM,YAAY,OAAO,UAAU,IAAI,IAAI,UAAU;EACrD,IAAI,WAAW,UAAU,KAAK,GAAG;OAC5B,OAAO,UAAU,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC;CACnD;CACA,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAChC;AAEA,SAAgB,aAAa,EACzB,QACA,IACA,UAKD;CACC,OACI,qBAAC,WAAD;EAAS,WAAU;EAA0D,cAAY,OAAO;EAAhG,UAAA,CACI,oBAAC,UAAD;GAAQ,WAAU;GACd,UAAA,oBAAC,MAAD,EAAA,UAAK,OAAO,KAAS,CAAA;EACjB,CAAA,GACP,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC,KAAK,CAAC,YAAY,UACrC,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACI,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACK,OAAO,UAAU,OAAO,KACrB,qBAAC,QAAD;MAAM,OAAO;MAAb,UAAA,CAAyB,aAAU,WAAW,MAAM,GAAG,CAAC,CAAQ;KAEpE,CAAA,GAAA,qBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACI,oBAAC,WAAD;OAAW,MAAM;OAAI,eAAA;MAAa,CAAA,GACjC,KAAK,EAAE,CAAE,gBAAgB,QAAQ,8BAA8B,cAC9D;KACL,CAAA,CAAA;;IACL,oBAAC,OAAD;KAAK,WAAU;KACV,UAAA,KAAK,KAAK,QACP,oBAAC,aAAD;MAA+B;MAAa;KAAS,GAAnC,IAAI,EAA+B,CACxD;IACA,CAAA;IACL,oBAAC,mBAAD;KAAmB,OAAO,KAAK,EAAE,CAAE;KAAW;KAAI,YAAY;IAAQ,CAAA;GACrE;EAhBiC,GAAA,UAgBjC,CACR,CACI;;AAEjB;AAEA,SAAS,YAAY,EAAE,KAAK,UAAqE;CAC7F,MAAM,CAAC,SAAS,cAAc,SAAiB;CAC/C,MAAM,QAAQ,WAAW,IAAI,OAAO;CACpC,MAAM,QAAQ,QAAQ,UAAU,IAAI,QAAQ,UAAU;CACtD,MAAM,OAAO,QAAQ,cAAc,IAAI,QAAQ,cAAc;CAC7D,OACI,qBAAC,OAAD;EAAK,WAAU;EAAkB,eAAa,IAAI;EAAlD,UAAA;GACI,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACK,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC,SACrB,oBAAC,iBAAD,EAAiB,YAAY;KAAE,MAAM;KAAW,OAAO,EAAE,OAAO,IAAI,OAAO;IAAE,EAAI,CAAA,IAEjF,oBAAC,QAAD,EAAA,UAAM,YAAe,CAAA,GAExB,SACG,oBAAC,KAAD;KAAG,MAAK;KAAQ,WAAU;KACrB,UAAA;IACF,CAAA,CAEN;;GACL,qBAAC,UAAD;IAAQ,WAAU;IAAmB,cAAY;IAAjD,UAAA,CACI,oBAAC,MAAD;KAAM,MAAM;KAAI,eAAA;IAAa,CAAA,GAC5B,QAAQ,gBAAgB,IAAI,QAAQ,sBAAsB,cACvD;;GACR,oBAAC,UAAD;IACI,MAAK;IACL,WAAU;IACV,eAAe;KACX,WAAW,KAAA,CAAS;KACpB,OAAY,IAAI,EAAE,CAAC,CAAC,OAAO,UACvB,WAAW,iBAAiB,QAAQ,MAAM,UAAU,4BAA4B,CACpF;IACJ;IAEC,UAAA,IAAI,SAAS,QAAQ,WAAW;GAC7B,CAAA;EACP;;AAEb"}
@@ -0,0 +1,12 @@
1
+ import { ReplicationLoad } from "./replicationActivity.js";
2
+ import { LiveOntology } from "@party-stack/ontology";
3
+ //#region src/Queries.d.ts
4
+ export declare function QueryLoadStats({ load, replicaName }: {
5
+ load?: ReplicationLoad;
6
+ replicaName?: string;
7
+ }): import("react").JSX.Element | null;
8
+ export declare function Queries({ ontology }: {
9
+ ontology: LiveOntology;
10
+ }): import("react").JSX.Element;
11
+ //#endregion
12
+ //# sourceMappingURL=Queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Queries.d.ts","names":[],"sources":["../src/Queries.tsx"],"mappings":";;;wBAcgB,iBACZ,MACA;EAEA,OAAO;EACP;oBACH,IAAA;wBA4Be,UAAU;EAAc,UAAU;oBAAc,IAAA"}
package/lib/Queries.js ADDED
@@ -0,0 +1,147 @@
1
+ import { DemandHighlight, revealDemandOwners } from "./attribution/Highlight.js";
2
+ import { attributionRevision, subscribeAttribution } from "./attribution/registry.js";
3
+ import { demandId, queryLoads } from "./replicationActivity.js";
4
+ import { demandOwners, demandRequests } from "./attribution/tanstack.js";
5
+ import { useReplicaStatus } from "./diagnostics.js";
6
+ import { QueryOwners } from "./QueryOwners.js";
7
+ import { QueryPills } from "./QueryPills.js";
8
+ import { QueryPushdown, RequestedQuery } from "./QueryPushdown.js";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { useState, useSyncExternalStore } from "react";
11
+ //#region src/Queries.tsx
12
+ const noOwners = [];
13
+ const serverRevision = () => 0;
14
+ function QueryLoadStats({ load, replicaName = "replica" }) {
15
+ if (!load) return null;
16
+ if (load.outcome === "running") return /* @__PURE__ */ jsx(Fragment, { children: "Request in progress…" });
17
+ if (load.outcome === "interrupted") return /* @__PURE__ */ jsx(Fragment, { children: "Request cancelled" });
18
+ if (load.outcome === "failure") return /* @__PURE__ */ jsx(Fragment, { children: "Request failed" });
19
+ if (load.rows === void 0) return null;
20
+ const fetched = load.fetchedRows;
21
+ if (fetched === void 0 || fetched === load.rows) return /* @__PURE__ */ jsxs(Fragment, { children: [
22
+ "Loaded ",
23
+ /* @__PURE__ */ jsx("b", { children: load.rows.toLocaleString() }),
24
+ " ",
25
+ load.rows === 1 ? "row" : "rows"
26
+ ] });
27
+ const processing = [(load.pushdown?.rechecksFilter || load.pushdown?.predicates.some((term) => term.execution !== "source")) && "filtering", (load.pushdown?.pagination === "adapter" || load.pushdown?.pagination === "engine") && "pagination"].filter((step) => typeof step === "string");
28
+ return /* @__PURE__ */ jsxs("span", {
29
+ className: "ps-query-row-flow",
30
+ "data-reduced": load.rows < fetched || void 0,
31
+ children: [
32
+ "Loaded ",
33
+ /* @__PURE__ */ jsx("b", { children: fetched.toLocaleString() }),
34
+ " ",
35
+ fetched === 1 ? "row" : "rows",
36
+ ";",
37
+ " ",
38
+ /* @__PURE__ */ jsx("b", { children: load.rows.toLocaleString() }),
39
+ " sent to ",
40
+ replicaName,
41
+ processing.length ? ` after adapter ${processing.join(" and ")}.` : " after adapter processing."
42
+ ]
43
+ });
44
+ }
45
+ function Queries({ ontology }) {
46
+ useSyncExternalStore(subscribeAttribution, attributionRevision, serverRevision);
47
+ const [highlighted, highlight] = useState();
48
+ const { status, error } = useReplicaStatus(ontology.diagnostics);
49
+ const { status: parentStatus, error: parentError } = useReplicaStatus(ontology.diagnostics?.parent);
50
+ const loads = ontology.diagnostics?.parent ? parentStatus?.loads : status?.loads;
51
+ const parentReplica = ontology.diagnostics?.parent ? ontology.diagnostics.parent.location ?? ontology.diagnostics.parent.label ?? "Host" : void 0;
52
+ const upstreamDemands = new Map((ontology.diagnostics?.parent ? parentStatus : status)?.demands.map((demand) => [demandId(demand), demand]));
53
+ const demands = status?.demands.slice().sort((a, b) => Number(Boolean(b.query?.where)) - Number(Boolean(a.query?.where)) || a.objectType.localeCompare(b.objectType)) ?? [];
54
+ const ownersByDemand = new Map(demands.map((demand) => [demandId(demand), demandOwners(demand, Object.values(ontology.objects))]));
55
+ return /* @__PURE__ */ jsxs("div", {
56
+ className: "ps-diagnostics-screen",
57
+ "aria-label": "Queries inspector",
58
+ children: [
59
+ error && /* @__PURE__ */ jsxs("p", {
60
+ className: "ps-replication-error",
61
+ role: "alert",
62
+ children: [error, " · displayed queries may be stale"]
63
+ }),
64
+ /* @__PURE__ */ jsxs("div", {
65
+ className: "ps-query-list",
66
+ "aria-label": "Active queries",
67
+ children: [demands.map((demand) => {
68
+ const object = ontology.ir.objectTypes.find((type) => type.name === demand.objectType);
69
+ const history = queryLoads(demand, loads ?? []);
70
+ const latest = history.at(-1);
71
+ const previousLoad = history.filter((load) => load.outcome === "success").at(-1);
72
+ const displayedLoad = latest?.outcome === "running" ? previousLoad ?? latest : latest;
73
+ const sourceName = (loads ?? []).filter((load) => load.subset?.objectType === demand.objectType && load.pushdown).at(-1)?.pushdown?.source;
74
+ const key = demandId(demand);
75
+ const upstreamDemand = upstreamDemands.get(key);
76
+ const coveredBy = upstreamDemand?.installed === upstreamDemand?.revision ? upstreamDemand?.coveredBy : void 0;
77
+ const checking = latest?.outcome === "running" || Boolean(upstreamDemand && upstreamDemand.installed !== upstreamDemand.revision);
78
+ const owners = ownersByDemand.get(key) ?? noOwners;
79
+ const requests = demandRequests(demand, Object.values(ontology.objects));
80
+ return /* @__PURE__ */ jsxs("article", {
81
+ className: "ps-query-card",
82
+ "data-attributed": owners.length > 0 || void 0,
83
+ "aria-busy": checking || void 0,
84
+ onPointerEnter: () => highlight(key),
85
+ onPointerLeave: () => highlight(void 0),
86
+ children: [/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsx("span", {
87
+ className: "ps-query-refreshing",
88
+ "data-refreshing": checking,
89
+ "aria-hidden": !checking,
90
+ children: "Refreshing…"
91
+ }), /* @__PURE__ */ jsxs(QueryTarget, {
92
+ owners,
93
+ label: `Show components for ${object?.pluralDisplayName ?? demand.objectType} query`,
94
+ onHighlight: () => highlight(key),
95
+ onClear: () => highlight(void 0),
96
+ children: [/* @__PURE__ */ jsx(QueryOwners, { owners }), requests.length ? requests.map((request, index) => /* @__PURE__ */ jsx(RequestedQuery, {
97
+ request,
98
+ demand,
99
+ object
100
+ }, index)) : /* @__PURE__ */ jsx(QueryPills, {
101
+ query: demand.query,
102
+ object,
103
+ objectType: demand.objectType
104
+ })]
105
+ })] }), /* @__PURE__ */ jsx(QueryPushdown, {
106
+ requests,
107
+ demand,
108
+ load: latest,
109
+ previousLoad,
110
+ sourceName,
111
+ checking,
112
+ object,
113
+ loadError: parentError,
114
+ parentReplica,
115
+ coveredBy,
116
+ coverageProof: coveredBy ? upstreamDemand?.coverageProof : void 0,
117
+ loadStats: /* @__PURE__ */ jsx(QueryLoadStats, {
118
+ load: displayedLoad,
119
+ replicaName: parentReplica ? `${parentReplica} replica` : "tab replica"
120
+ })
121
+ }, ontology.replica?.sourceId)]
122
+ }, key);
123
+ }), !demands.length && /* @__PURE__ */ jsx("p", {
124
+ className: "ps-replication-empty",
125
+ children: status ? "No active queries." : "Reading queries…"
126
+ })]
127
+ }),
128
+ /* @__PURE__ */ jsx(DemandHighlight, { owners: highlighted ? ownersByDemand.get(highlighted) ?? noOwners : noOwners })
129
+ ]
130
+ });
131
+ }
132
+ function QueryTarget({ owners, label, onHighlight, onClear, children }) {
133
+ if (!owners.length) return children;
134
+ return /* @__PURE__ */ jsx("button", {
135
+ type: "button",
136
+ className: "ps-query-component-target",
137
+ "aria-label": label,
138
+ onFocus: onHighlight,
139
+ onBlur: onClear,
140
+ onClick: () => revealDemandOwners(owners),
141
+ children
142
+ });
143
+ }
144
+ //#endregion
145
+ export { Queries, QueryLoadStats };
146
+
147
+ //# sourceMappingURL=Queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Queries.js","names":[],"sources":["../src/Queries.tsx"],"sourcesContent":["import { useState, useSyncExternalStore, type ReactNode } from \"react\";\nimport { DemandHighlight, revealDemandOwners } from \"./attribution/Highlight.js\";\nimport { attributionRevision, subscribeAttribution, type DemandOwner } from \"./attribution/registry.js\";\nimport { demandOwners, demandRequests } from \"./attribution/tanstack.js\";\nimport { useReplicaStatus } from \"./diagnostics.js\";\nimport { QueryOwners } from \"./QueryOwners.js\";\nimport { QueryPills } from \"./QueryPills.js\";\nimport { QueryPushdown, RequestedQuery } from \"./QueryPushdown.js\";\nimport { demandId, queryLoads, type ReplicationLoad } from \"./replicationActivity.js\";\nimport type { LiveOntology } from \"@party-stack/ontology\";\n\nconst noOwners: readonly DemandOwner[] = [];\nconst serverRevision = () => 0;\n\nexport function QueryLoadStats({\n load,\n replicaName = \"replica\",\n}: {\n load?: ReplicationLoad;\n replicaName?: string;\n}) {\n if (!load) return null;\n if (load.outcome === \"running\") return <>Request in progress…</>;\n if (load.outcome === \"interrupted\") return <>Request cancelled</>;\n if (load.outcome === \"failure\") return <>Request failed</>;\n if (load.rows === undefined) return null;\n const fetched = load.fetchedRows;\n if (fetched === undefined || fetched === load.rows)\n return (\n <>\n Loaded <b>{load.rows.toLocaleString()}</b> {load.rows === 1 ? \"row\" : \"rows\"}\n </>\n );\n const processing = [\n (load.pushdown?.rechecksFilter ||\n load.pushdown?.predicates.some((term) => term.execution !== \"source\")) &&\n \"filtering\",\n (load.pushdown?.pagination === \"adapter\" || load.pushdown?.pagination === \"engine\") && \"pagination\",\n ].filter((step): step is string => typeof step === \"string\");\n return (\n <span className=\"ps-query-row-flow\" data-reduced={load.rows < fetched || undefined}>\n Loaded <b>{fetched.toLocaleString()}</b> {fetched === 1 ? \"row\" : \"rows\"};{\" \"}\n <b>{load.rows.toLocaleString()}</b> sent to {replicaName}\n {processing.length ? ` after adapter ${processing.join(\" and \")}.` : \" after adapter processing.\"}\n </span>\n );\n}\n\nexport function Queries({ ontology }: { ontology: LiveOntology }) {\n useSyncExternalStore(subscribeAttribution, attributionRevision, serverRevision);\n const [highlighted, highlight] = useState<string>();\n const { status, error } = useReplicaStatus(ontology.diagnostics);\n // Queries remain local; only the correlated load telemetry comes from the exposed upstream owner.\n const { status: parentStatus, error: parentError } = useReplicaStatus(ontology.diagnostics?.parent);\n const loads = ontology.diagnostics?.parent ? parentStatus?.loads : status?.loads;\n const parentReplica = ontology.diagnostics?.parent\n ? (ontology.diagnostics.parent.location ?? ontology.diagnostics.parent.label ?? \"Host\")\n : undefined;\n const upstreamDemands = new Map(\n (ontology.diagnostics?.parent ? parentStatus : status)?.demands.map((demand) => [\n demandId(demand),\n demand,\n ])\n );\n const demands =\n status?.demands\n .slice()\n .sort(\n (a, b) =>\n Number(Boolean(b.query?.where)) - Number(Boolean(a.query?.where)) ||\n a.objectType.localeCompare(b.objectType)\n ) ?? [];\n const ownersByDemand = new Map(\n demands.map((demand) => [demandId(demand), demandOwners(demand, Object.values(ontology.objects))])\n );\n return (\n <div className=\"ps-diagnostics-screen\" aria-label=\"Queries inspector\">\n {error && (\n <p className=\"ps-replication-error\" role=\"alert\">\n {error} · displayed queries may be stale\n </p>\n )}\n <div className=\"ps-query-list\" aria-label=\"Active queries\">\n {demands.map((demand) => {\n const object = ontology.ir.objectTypes.find((type) => type.name === demand.objectType);\n const history = queryLoads(demand, loads ?? []);\n const latest = history.at(-1);\n const previousLoad = history.filter((load) => load.outcome === \"success\").at(-1);\n const displayedLoad = latest?.outcome === \"running\" ? (previousLoad ?? latest) : latest;\n const sourceName = (loads ?? [])\n .filter((load) => load.subset?.objectType === demand.objectType && load.pushdown)\n .at(-1)?.pushdown?.source;\n const key = demandId(demand);\n const upstreamDemand = upstreamDemands.get(key);\n const coveredBy =\n upstreamDemand?.installed === upstreamDemand?.revision\n ? upstreamDemand?.coveredBy\n : undefined;\n const checking =\n latest?.outcome === \"running\" ||\n Boolean(upstreamDemand && upstreamDemand.installed !== upstreamDemand.revision);\n const owners = ownersByDemand.get(key) ?? noOwners;\n const requests = demandRequests(demand, Object.values(ontology.objects));\n return (\n <article\n className=\"ps-query-card\"\n key={key}\n data-attributed={owners.length > 0 || undefined}\n aria-busy={checking || undefined}\n onPointerEnter={() => highlight(key)}\n onPointerLeave={() => highlight(undefined)}\n >\n <header>\n <span\n className=\"ps-query-refreshing\"\n data-refreshing={checking}\n aria-hidden={!checking}\n >\n Refreshing…\n </span>\n <QueryTarget\n owners={owners}\n label={`Show components for ${object?.pluralDisplayName ?? demand.objectType} query`}\n onHighlight={() => highlight(key)}\n onClear={() => highlight(undefined)}\n >\n <QueryOwners owners={owners} />\n {requests.length ? (\n requests.map((request, index) => (\n <RequestedQuery\n key={index}\n request={request}\n demand={demand}\n object={object}\n />\n ))\n ) : (\n <QueryPills\n query={demand.query}\n object={object}\n objectType={demand.objectType}\n />\n )}\n </QueryTarget>\n </header>\n <QueryPushdown\n key={ontology.replica?.sourceId}\n requests={requests}\n demand={demand}\n load={latest}\n previousLoad={previousLoad}\n sourceName={sourceName}\n checking={checking}\n object={object}\n loadError={parentError}\n parentReplica={parentReplica}\n coveredBy={coveredBy}\n coverageProof={coveredBy ? upstreamDemand?.coverageProof : undefined}\n loadStats={\n <QueryLoadStats\n load={displayedLoad}\n replicaName={\n parentReplica ? `${parentReplica} replica` : \"tab replica\"\n }\n />\n }\n />\n </article>\n );\n })}\n {!demands.length && (\n <p className=\"ps-replication-empty\">\n {status ? \"No active queries.\" : \"Reading queries…\"}\n </p>\n )}\n </div>\n <DemandHighlight\n owners={highlighted ? (ownersByDemand.get(highlighted) ?? noOwners) : noOwners}\n />\n </div>\n );\n}\n\nfunction QueryTarget({\n owners,\n label,\n onHighlight,\n onClear,\n children,\n}: {\n owners: readonly DemandOwner[];\n label: string;\n onHighlight: () => void;\n onClear: () => void;\n children: ReactNode;\n}) {\n if (!owners.length) return children;\n return (\n <button\n type=\"button\"\n className=\"ps-query-component-target\"\n aria-label={label}\n onFocus={onHighlight}\n onBlur={onClear}\n onClick={() => revealDemandOwners(owners)}\n >\n {children}\n </button>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { DemandOwner } from "./attribution/registry.js";
2
+ //#region src/QueryOwners.d.ts
3
+ export declare function QueryOwners({ owners }: {
4
+ owners: readonly DemandOwner[];
5
+ }): import("react").JSX.Element | null;
6
+ //#endregion
7
+ //# sourceMappingURL=QueryOwners.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryOwners.d.ts","names":[],"sources":["../src/QueryOwners.tsx"],"mappings":";;wBAEgB,cAAc;EAAY,iBAAiB;oBAAe,IAAA"}