@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
@@ -1,234 +1,24 @@
1
- import './styles.css';
2
- /* empty css */
1
+ import { DisclosureSummary } from "./DisclosureSummary.js";
2
+ import { ObjectTypeIcon, OntologyIcon } from "./OntologyIcons.js";
3
+ import { PanelBoundary, usePanelPortal } from "./PanelBoundary.js";
4
+ import { layoutSchema } from "./schemaLayout.js";
5
+ import { typeDisplayName } from "./typeDisplayName.js";
6
+ import { SchemaView } from "./SchemaView.js";
7
+ import { Pinned } from "./Pinned.js";
8
+ import { Queries } from "./Queries.js";
9
+ import { Storage } from "./Storage.js";
10
+ import { Tracing } from "./Tracing.js";
11
+ import { Boxes, CalendarDays, ChartNoAxesGantt, Check, ChevronDown, ChevronUp, ChevronsUpDown, CircleCheck, CircleQuestionMark, Clock, Columns3, Grid2X2, GripVertical, HardDrive, Hash, Link, List, Map, MapPin, Paperclip, Pin, RefreshCw, Search, Send, SquareCode, Trash2, Waypoints } from "lucide-react";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ import { memo, useDeferredValue, useEffect, useMemo, useState } from "react";
3
14
  import { Dialog } from "@base-ui/react/dialog";
4
15
  import { Menu } from "@base-ui/react/menu";
5
16
  import { Tabs } from "@base-ui/react/tabs";
6
17
  import { Tooltip } from "@base-ui/react/tooltip";
7
- import { Graph, layout } from "@dagrejs/dagre";
8
18
  import NumberFlow from "@number-flow/react";
9
- import { LucideIcon } from "@party-stack/icons-lucide/react";
10
- import { createReactPlugin } from "@tanstack/devtools-utils/react";
11
- import { useLiveInfiniteQuery, useLiveQuery } from "@tanstack/react-db";
19
+ import { DbProvider, useLiveInfiniteQuery, useLiveQuery } from "@tanstack/react-db";
12
20
  import { columnOrderingFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, createColumnHelper, flexRender, rowSortingFeature, tableFeatures, useTable } from "@tanstack/react-table";
13
- import { CalendarDays, Check, ChevronDown, ChevronUp, ChevronsUpDown, CircleCheck, CircleQuestionMark, Clock, Columns3, Database, Grid2X2, GripVertical, Hash, Inbox, Link, List, Map as Map$1, MapPin, Paperclip, RefreshCw, Share2, SquareCode, Trash2 } from "lucide-react";
14
- import { useEffect, useId, useMemo, useState } from "react";
15
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
16
21
  //#region src/OntologyDevtools.tsx
17
- function OntologyIcon({ className, color, name }) {
18
- return /* @__PURE__ */ jsx(LucideIcon, {
19
- "aria-hidden": "true",
20
- className,
21
- name,
22
- style: color ? { color } : void 0
23
- });
24
- }
25
- function ObjectTypeIcon({ className, objectType }) {
26
- return /* @__PURE__ */ jsx(OntologyIcon, {
27
- className,
28
- color: objectType.color,
29
- name: objectType.icon?.name ?? "database"
30
- });
31
- }
32
- function PartyStackLogo({ theme }) {
33
- const id = useId().replaceAll(":", "");
34
- const gradientId = `ps-ball-${id}`;
35
- const shadowId = `ps-shadow-${id}`;
36
- return /* @__PURE__ */ jsxs("svg", {
37
- "aria-hidden": "true",
38
- style: {
39
- display: "block",
40
- height: "100%",
41
- width: "100%"
42
- },
43
- viewBox: "0 0 1200 300",
44
- children: [
45
- /* @__PURE__ */ jsxs("defs", { children: [/* @__PURE__ */ jsxs("radialGradient", {
46
- cx: "69%",
47
- cy: "24%",
48
- id: gradientId,
49
- r: "82%",
50
- children: [
51
- /* @__PURE__ */ jsx("stop", {
52
- offset: "0",
53
- stopColor: "#fff"
54
- }),
55
- /* @__PURE__ */ jsx("stop", {
56
- offset: ".38",
57
- stopColor: "#fff"
58
- }),
59
- /* @__PURE__ */ jsx("stop", {
60
- offset: ".62",
61
- stopColor: "#f8f7f3"
62
- }),
63
- /* @__PURE__ */ jsx("stop", {
64
- offset: ".82",
65
- stopColor: "#e1dfda"
66
- }),
67
- /* @__PURE__ */ jsx("stop", {
68
- offset: "1",
69
- stopColor: "#b7b3ad"
70
- })
71
- ]
72
- }), /* @__PURE__ */ jsx("filter", {
73
- height: "170%",
74
- id: shadowId,
75
- width: "160%",
76
- x: "-30%",
77
- y: "-30%",
78
- children: /* @__PURE__ */ jsx("feDropShadow", {
79
- dx: "3",
80
- dy: "6",
81
- floodColor: "#681611",
82
- floodOpacity: ".28",
83
- stdDeviation: "5"
84
- })
85
- })] }),
86
- /* @__PURE__ */ jsxs("g", {
87
- transform: "translate(22 22) scale(.5)",
88
- children: [/* @__PURE__ */ jsx("path", {
89
- d: "M96 64h184c81 0 136 55 136 136s-55 136-136 136h-56v112H96V64Z",
90
- fill: "#e83b32"
91
- }), /* @__PURE__ */ jsxs("g", {
92
- filter: `url(#${shadowId})`,
93
- children: [/* @__PURE__ */ jsx("circle", {
94
- cx: "258",
95
- cy: "200",
96
- fill: `url(#${gradientId})`,
97
- r: "60"
98
- }), /* @__PURE__ */ jsx("ellipse", {
99
- cx: "279",
100
- cy: "177",
101
- fill: "#fff",
102
- opacity: ".92",
103
- rx: "8.5",
104
- ry: "10.5"
105
- })]
106
- })]
107
- }),
108
- /* @__PURE__ */ jsx("text", {
109
- fill: theme === "dark" ? "#f7f5f0" : "#171717",
110
- fontFamily: "Avenir Next, Avenir, Helvetica Neue, Arial, sans-serif",
111
- fontSize: "124",
112
- fontWeight: "700",
113
- letterSpacing: "-3",
114
- x: "310",
115
- y: "196",
116
- children: "Party Stack"
117
- })
118
- ]
119
- });
120
- }
121
- function PartyStackLogomark() {
122
- const id = useId().replaceAll(":", "");
123
- const gradientId = `ps-mark-ball-${id}`;
124
- const shadowId = `ps-mark-shadow-${id}`;
125
- return /* @__PURE__ */ jsxs("svg", {
126
- "aria-hidden": "true",
127
- style: {
128
- display: "block",
129
- height: "100%",
130
- width: "100%"
131
- },
132
- viewBox: "0 0 512 512",
133
- children: [
134
- /* @__PURE__ */ jsxs("defs", { children: [/* @__PURE__ */ jsxs("radialGradient", {
135
- cx: "69%",
136
- cy: "24%",
137
- id: gradientId,
138
- r: "82%",
139
- children: [
140
- /* @__PURE__ */ jsx("stop", {
141
- offset: "0",
142
- stopColor: "#fff"
143
- }),
144
- /* @__PURE__ */ jsx("stop", {
145
- offset: ".38",
146
- stopColor: "#fff"
147
- }),
148
- /* @__PURE__ */ jsx("stop", {
149
- offset: ".62",
150
- stopColor: "#f8f7f3"
151
- }),
152
- /* @__PURE__ */ jsx("stop", {
153
- offset: ".82",
154
- stopColor: "#e1dfda"
155
- }),
156
- /* @__PURE__ */ jsx("stop", {
157
- offset: "1",
158
- stopColor: "#b7b3ad"
159
- })
160
- ]
161
- }), /* @__PURE__ */ jsx("filter", {
162
- height: "170%",
163
- id: shadowId,
164
- width: "160%",
165
- x: "-30%",
166
- y: "-30%",
167
- children: /* @__PURE__ */ jsx("feDropShadow", {
168
- dx: "3",
169
- dy: "6",
170
- floodColor: "#681611",
171
- floodOpacity: ".28",
172
- stdDeviation: "5"
173
- })
174
- })] }),
175
- /* @__PURE__ */ jsx("path", {
176
- d: "M96 64h184c81 0 136 55 136 136s-55 136-136 136h-56v112H96V64Z",
177
- fill: "#e83b32"
178
- }),
179
- /* @__PURE__ */ jsxs("g", {
180
- filter: `url(#${shadowId})`,
181
- children: [/* @__PURE__ */ jsx("circle", {
182
- cx: "258",
183
- cy: "200",
184
- fill: `url(#${gradientId})`,
185
- r: "60"
186
- }), /* @__PURE__ */ jsx("ellipse", {
187
- cx: "279",
188
- cy: "177",
189
- fill: "#fff",
190
- opacity: ".92",
191
- rx: "8.5",
192
- ry: "10.5"
193
- })]
194
- })
195
- ]
196
- });
197
- }
198
- function OntologyDevtoolsPluginName({ theme }) {
199
- return /* @__PURE__ */ jsx("div", {
200
- style: {
201
- height: 30,
202
- width: 120
203
- },
204
- children: /* @__PURE__ */ jsx(PartyStackLogo, { theme })
205
- });
206
- }
207
- function OntologyDevtoolsTrigger({ theme }) {
208
- const dark = theme === "dark";
209
- return /* @__PURE__ */ jsx("div", {
210
- "aria-label": "Open Ontology devtools",
211
- style: {
212
- alignItems: "center",
213
- background: dark ? "linear-gradient(145deg, #2d2d31, #171719)" : "linear-gradient(145deg, #fff, #f5f5f4)",
214
- border: dark ? "1px solid rgba(255,255,255,.16)" : "1px solid rgba(23,23,23,.14)",
215
- borderRadius: "999px",
216
- boxSizing: "border-box",
217
- boxShadow: dark ? "0 10px 30px rgba(0,0,0,.34), 0 0 0 4px rgba(232,59,50,.11)" : "0 10px 28px rgba(28,25,23,.16), 0 0 0 4px rgba(232,59,50,.09)",
218
- cursor: "pointer",
219
- display: "flex",
220
- height: 48,
221
- justifyContent: "center",
222
- padding: 8,
223
- width: 48
224
- },
225
- title: "Open Ontology devtools",
226
- children: /* @__PURE__ */ jsx(PartyStackLogomark, {})
227
- });
228
- }
229
- function ontologyDevtoolsTrigger(_element, { theme }) {
230
- return /* @__PURE__ */ jsx(OntologyDevtoolsTrigger, { theme });
231
- }
232
22
  function OutboxPanel({ children, theme }) {
233
23
  return /* @__PURE__ */ jsx("div", {
234
24
  className: `ps-outbox-root ps-theme-${theme}`,
@@ -244,8 +34,9 @@ function statusClass(entry) {
244
34
  function statusLabel(entry) {
245
35
  switch (entry.status) {
246
36
  case "queued": return "Waiting";
247
- case "executing": return "Running";
248
- case "failed": return "Failed";
37
+ case "sending": return entry.attemptStage === "forwarding" ? "Forwarding" : "Sending";
38
+ case "acknowledged": return entry.attemptStage === "forwarding" ? "Accepted by parent" : "Reconciling";
39
+ case "blocked": return entry.lastError?.actionOutcome === "unknown" ? "Outcome unknown" : "Blocked";
249
40
  }
250
41
  }
251
42
  const relativeTime = new Intl.RelativeTimeFormat(void 0, { numeric: "auto" });
@@ -276,16 +67,23 @@ function cardClass(entry) {
276
67
  function OutboxEntryCard({ entry, outbox, now }) {
277
68
  const [pending, setPending] = useState();
278
69
  const [actionError, setActionError] = useState();
70
+ const [confirmation, setConfirmation] = useState();
71
+ const busy = entry.status === "sending" || entry.status === "acknowledged";
72
+ const choose = (action) => {
73
+ if (action === "retry" ? entry.retryRequiresAcknowledgement : entry.lastError?.actionOutcome === "unknown") setConfirmation(action);
74
+ else run(action);
75
+ };
279
76
  const run = async (action) => {
280
77
  setPending(action);
281
78
  setActionError(void 0);
282
79
  try {
283
- if (action === "retry") await outbox.retry(entry.id);
284
- else await outbox.remove(entry.id);
80
+ if (action === "retry") await outbox.retry(entry.id, { allowUnknownOutcome: confirmation === "retry" });
81
+ else await outbox.remove(entry.id, { allowUnknownOutcome: confirmation === "remove" });
285
82
  } catch (error) {
286
83
  setActionError(error instanceof Error ? error.message : String(error));
287
84
  } finally {
288
85
  setPending(void 0);
86
+ setConfirmation(void 0);
289
87
  }
290
88
  };
291
89
  return /* @__PURE__ */ jsxs("article", {
@@ -304,11 +102,11 @@ function OutboxEntryCard({ entry, outbox, now }) {
304
102
  /* @__PURE__ */ jsxs("div", {
305
103
  className: "ps-outbox-meta",
306
104
  children: [
307
- /* @__PURE__ */ jsxs("span", { children: [
308
- /* @__PURE__ */ jsx("strong", { children: entry.attempts }),
309
- " ",
310
- entry.attempts === 1 ? "attempt" : "attempts"
311
- ] }),
105
+ /* @__PURE__ */ jsx("span", {
106
+ className: "ps-outbox-attempts",
107
+ title: entry.attemptStage === "forwarding" ? entry.status === "acknowledged" ? "Accepted by the parent; waiting for its replicated action state." : `${entry.attempts} forwarding attempts; upstream execution has not been observed yet.` : "Attempts to execute at this replica's upstream.",
108
+ children: entry.attemptStage === "forwarding" ? entry.status === "acknowledged" ? "Parent accepted" : "Forwarding" : /* @__PURE__ */ jsxs(Fragment, { children: ["Attempts: ", /* @__PURE__ */ jsx("strong", { children: entry.attempts })] })
109
+ }),
312
110
  /* @__PURE__ */ jsx("span", {
313
111
  "aria-hidden": "true",
314
112
  className: "ps-outbox-meta-divider"
@@ -324,34 +122,73 @@ function OutboxEntryCard({ entry, outbox, now }) {
324
122
  }) : null
325
123
  ]
326
124
  }),
327
- entry.lastError ? /* @__PURE__ */ jsx("div", {
125
+ entry.lastError ? /* @__PURE__ */ jsxs("div", {
328
126
  className: "ps-outbox-error",
329
- children: entry.lastError.message
127
+ role: "alert",
128
+ children: [
129
+ /* @__PURE__ */ jsx("strong", { children: entry.lastError.kind }),
130
+ /* @__PURE__ */ jsx("div", { children: entry.lastError.message }),
131
+ entry.lastError.actionOutcome === "unknown" ? /* @__PURE__ */ jsx("p", { children: "The previous attempt may have committed. No definitive result has been received." }) : null,
132
+ entry.lastError.issues?.length ? /* @__PURE__ */ jsx("ul", { children: entry.lastError.issues.map((issue, index) => /* @__PURE__ */ jsxs("li", { children: [
133
+ /* @__PURE__ */ jsx("code", { children: issue.path?.join(".") || "Submission" }),
134
+ ": ",
135
+ issue.message,
136
+ " ",
137
+ /* @__PURE__ */ jsxs("code", { children: [
138
+ "(",
139
+ issue.code,
140
+ ")"
141
+ ] })
142
+ ] }, index)) }) : null
143
+ ]
330
144
  }) : null,
331
145
  /* @__PURE__ */ jsxs("details", {
332
146
  className: "ps-outbox-details",
333
- children: [/* @__PURE__ */ jsx("summary", { children: "Parameters" }), /* @__PURE__ */ jsx("pre", { children: JSON.stringify(entry.request.parameters, null, 2) })]
147
+ children: [/* @__PURE__ */ jsx(DisclosureSummary, { children: "Parameters" }), /* @__PURE__ */ jsx("pre", { children: JSON.stringify(entry.request.parameters, null, 2) })]
334
148
  }),
335
149
  /* @__PURE__ */ jsxs("div", {
336
150
  className: "ps-outbox-actions",
337
151
  children: [/* @__PURE__ */ jsxs("button", {
338
152
  className: "ps-button ps-button-primary",
339
153
  type: "button",
340
- disabled: !entry.retryable || entry.status === "executing" || pending !== void 0,
154
+ disabled: busy || pending !== void 0,
341
155
  onClick: () => {
342
- run("retry");
156
+ choose("retry");
343
157
  },
344
158
  children: [/* @__PURE__ */ jsx(RefreshCw, { "aria-hidden": "true" }), pending === "retry" ? "Retrying…" : "Retry"]
345
159
  }), /* @__PURE__ */ jsxs("button", {
346
160
  className: "ps-button ps-button-danger",
347
161
  type: "button",
348
- disabled: entry.status === "executing" || pending !== void 0,
162
+ disabled: busy || pending !== void 0,
349
163
  onClick: () => {
350
- run("remove");
164
+ choose("remove");
351
165
  },
352
166
  children: [/* @__PURE__ */ jsx(Trash2, { "aria-hidden": "true" }), pending === "remove" ? "Removing…" : "Remove"]
353
167
  })]
354
168
  }),
169
+ confirmation ? /* @__PURE__ */ jsxs("div", {
170
+ className: "ps-outbox-error",
171
+ role: "alert",
172
+ children: [
173
+ /* @__PURE__ */ jsx("p", { children: confirmation === "retry" ? "Retrying may execute the action again." : "Discarding removes local intent; it does not cancel a remote execution." }),
174
+ /* @__PURE__ */ jsx("button", {
175
+ className: "ps-button",
176
+ type: "button",
177
+ disabled: pending !== void 0,
178
+ onClick: () => setConfirmation(void 0),
179
+ children: "Cancel"
180
+ }),
181
+ /* @__PURE__ */ jsx("button", {
182
+ className: "ps-button ps-button-danger",
183
+ type: "button",
184
+ disabled: pending !== void 0,
185
+ onClick: () => {
186
+ run(confirmation);
187
+ },
188
+ children: confirmation === "retry" ? "Retry anyway" : "Discard local action"
189
+ })
190
+ ]
191
+ }) : null,
355
192
  actionError ? /* @__PURE__ */ jsx("div", {
356
193
  className: "ps-outbox-action-error",
357
194
  children: actionError
@@ -395,7 +232,7 @@ function OutboxRows({ outbox, theme }) {
395
232
  }
396
233
  function getOutboxActivity(entries) {
397
234
  if (entries.length === 0) return "idle";
398
- if (entries.reduce((first, entry) => entry.sequence < first.sequence ? entry : first).status === "failed") return "paused";
235
+ if (entries.reduce((first, entry) => entry.sequence < first.sequence ? entry : first).status === "blocked") return "paused";
399
236
  return "draining";
400
237
  }
401
238
  function outboxActivityLabel(activity) {
@@ -407,26 +244,46 @@ function outboxActivityLabel(activity) {
407
244
  }
408
245
  function outboxBadgeClass(activity) {
409
246
  switch (activity) {
410
- case "idle": return "ps:bg-zinc-500/15 ps:text-zinc-400";
247
+ case "idle": return "ps:bg-[var(--ps-raised)] ps:text-[var(--ps-muted)]";
411
248
  case "draining": return "ps:bg-sky-500/20 ps:text-sky-300";
412
249
  case "paused": return "ps:bg-red-500/20 ps:text-red-300";
413
250
  }
414
251
  }
415
252
  const ontologyViews = [
253
+ {
254
+ id: "objects",
255
+ label: "Objects",
256
+ icon: Boxes
257
+ },
416
258
  {
417
259
  id: "outbox",
418
260
  label: "Outbox",
419
- icon: Inbox
261
+ icon: Send
262
+ },
263
+ {
264
+ id: "queries",
265
+ label: "Queries",
266
+ icon: Search
267
+ },
268
+ {
269
+ id: "pinned",
270
+ label: "Pinned",
271
+ icon: Pin
272
+ },
273
+ {
274
+ id: "tracing",
275
+ label: "Tracing",
276
+ icon: ChartNoAxesGantt
420
277
  },
421
278
  {
422
279
  id: "schema",
423
280
  label: "Schema",
424
- icon: Share2
281
+ icon: Waypoints
425
282
  },
426
283
  {
427
- id: "objects",
428
- label: "Objects",
429
- icon: Database
284
+ id: "storage",
285
+ label: "Storage",
286
+ icon: HardDrive
430
287
  }
431
288
  ];
432
289
  function formatObjectValue(value) {
@@ -452,28 +309,6 @@ function resolvedType(ir, type) {
452
309
  const referenced = ir.types.find((candidate) => candidate.name === type.value.name)?.type;
453
310
  return referenced ? resolvedType(ir, referenced) : type;
454
311
  }
455
- function typeDisplayName(type) {
456
- switch (type.kind) {
457
- case "ref": return type.value.name;
458
- case "optional": return `${typeDisplayName(type.value.type)} (optional)`;
459
- case "list": return `List of ${typeDisplayName(type.value.elementType)}`;
460
- case "map": return `Map of ${typeDisplayName(type.value.valueType)}`;
461
- case "objectReference": return `${type.value.objectType} reference`;
462
- case "string": return "String";
463
- case "boolean": return "Boolean";
464
- case "integer": return "Integer";
465
- case "float": return "Float";
466
- case "double": return "Double";
467
- case "date": return "Date";
468
- case "timestamp": return "Timestamp";
469
- case "geopoint": return "Geopoint";
470
- case "struct": return "Struct";
471
- case "union": return "Union";
472
- case "result": return "Result";
473
- case "attachment": return "Attachment";
474
- case "unknown": return "Unknown";
475
- }
476
- }
477
312
  function typeIcon(type) {
478
313
  switch (type.kind) {
479
314
  case "ref": return Link;
@@ -490,24 +325,29 @@ function typeIcon(type) {
490
325
  case "timestamp": return Clock;
491
326
  case "geopoint": return MapPin;
492
327
  case "attachment": return Paperclip;
328
+ case "encrypted": return SquareCode;
493
329
  case "struct":
494
330
  case "union":
495
- case "result": return Map$1;
331
+ case "result": return Map;
496
332
  case "unknown": return CircleQuestionMark;
497
333
  }
498
334
  }
499
335
  function DevtoolsTooltip({ children, label }) {
336
+ const portal = usePanelPortal();
500
337
  return /* @__PURE__ */ jsxs(Tooltip.Root, { children: [/* @__PURE__ */ jsx(Tooltip.Trigger, {
501
338
  render: /* @__PURE__ */ jsx("span", { className: "ps:inline-flex ps:items-center" }),
502
339
  children
503
- }), /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
504
- className: "ps:z-[100001]",
505
- sideOffset: 6,
506
- children: /* @__PURE__ */ jsx(Tooltip.Popup, {
507
- className: "ps:max-w-64 ps:rounded-md ps:border ps:border-zinc-700 ps:bg-zinc-900 ps:px-2.5 ps:py-1.5 ps:text-[11px] ps:text-zinc-200 ps:shadow-xl",
508
- children: label
340
+ }), /* @__PURE__ */ jsx(Tooltip.Portal, {
341
+ container: portal,
342
+ children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
343
+ className: "ps:z-[100001]",
344
+ sideOffset: 6,
345
+ children: /* @__PURE__ */ jsx(Tooltip.Popup, {
346
+ className: "ps:max-w-64 ps:rounded-md ps:border ps:border-[var(--ps-border)] ps:bg-[var(--ps-raised)] ps:px-2.5 ps:py-1.5 ps:text-[11px] ps:text-[var(--ps-text)] ps:shadow-xl",
347
+ children: label
348
+ })
509
349
  })
510
- }) })] });
350
+ })] });
511
351
  }
512
352
  function TypeIndicator({ type }) {
513
353
  const Icon = typeIcon(type);
@@ -515,7 +355,7 @@ function TypeIndicator({ type }) {
515
355
  label: typeDisplayName(type),
516
356
  children: /* @__PURE__ */ jsx(Icon, {
517
357
  "aria-hidden": true,
518
- className: "ps:size-3.5 ps:text-zinc-500"
358
+ className: "ps:size-3.5 ps:text-[var(--ps-muted)]"
519
359
  })
520
360
  });
521
361
  }
@@ -529,7 +369,7 @@ function GeopointPreview({ value }) {
529
369
  return /* @__PURE__ */ jsx(DevtoolsTooltip, {
530
370
  label: /* @__PURE__ */ jsxs("svg", {
531
371
  "aria-label": `Map preview for ${label}`,
532
- className: "ps:block ps:rounded ps:border ps:border-zinc-700",
372
+ className: "ps:block ps:rounded ps:border ps:border-[var(--ps-border)]",
533
373
  height: "72",
534
374
  role: "img",
535
375
  viewBox: "0 0 360 180",
@@ -588,6 +428,7 @@ function isAttachment(value) {
588
428
  return typeof value === "object" && value !== null && "id" in value && typeof value.id === "string";
589
429
  }
590
430
  function AttachmentPreview({ attachment, ontology }) {
431
+ const portal = usePanelPortal();
591
432
  const [preview, setPreview] = useState();
592
433
  useEffect(() => {
593
434
  let cancelled = false;
@@ -613,7 +454,7 @@ function AttachmentPreview({ attachment, ontology }) {
613
454
  className: "ps:inline-flex ps:max-w-40 ps:items-center ps:gap-1.5 ps:truncate",
614
455
  children: [/* @__PURE__ */ jsx(Paperclip, {
615
456
  "aria-hidden": true,
616
- className: "ps:size-3.5 ps:flex-none ps:text-zinc-500"
457
+ className: "ps:size-3.5 ps:flex-none ps:text-[var(--ps-muted)]"
617
458
  }), /* @__PURE__ */ jsx("span", {
618
459
  className: "ps:truncate",
619
460
  children: label
@@ -622,35 +463,38 @@ function AttachmentPreview({ attachment, ontology }) {
622
463
  });
623
464
  return /* @__PURE__ */ jsxs(Dialog.Root, { children: [/* @__PURE__ */ jsx(Dialog.Trigger, {
624
465
  "aria-label": `Open ${label}`,
625
- className: "ps:block ps:overflow-hidden ps:rounded-md ps:border ps:border-zinc-700 ps:bg-transparent ps:p-0 ps:hover:border-rose-400",
466
+ className: "ps:block ps:overflow-hidden ps:rounded-md ps:border ps:border-[var(--ps-border)] ps:bg-transparent ps:p-0 ps:hover:border-[var(--ps-accent)]",
626
467
  children: /* @__PURE__ */ jsx("img", {
627
468
  alt: label,
628
- className: "ps:size-10 ps:object-cover",
469
+ className: "ps:block ps:size-7 ps:object-cover",
629
470
  src: preview.src
630
471
  })
631
- }), /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "ps:fixed ps:inset-0 ps:z-[100002] ps:bg-black/75 ps:backdrop-blur-sm" }), /* @__PURE__ */ jsx(Dialog.Viewport, {
632
- className: "ps:fixed ps:inset-0 ps:z-[100003] ps:grid ps:place-items-center ps:p-8",
633
- children: /* @__PURE__ */ jsxs(Dialog.Popup, {
634
- className: "ps:relative ps:max-h-full ps:max-w-4xl ps:rounded-xl ps:border ps:border-zinc-700 ps:bg-zinc-950 ps:p-3 ps:shadow-2xl",
635
- children: [
636
- /* @__PURE__ */ jsx(Dialog.Title, {
637
- className: "ps:sr-only",
638
- children: label
639
- }),
640
- /* @__PURE__ */ jsx("img", {
641
- alt: label,
642
- className: "ps:max-h-[80vh] ps:max-w-[80vw] ps:rounded-lg ps:object-contain",
643
- src: preview.src
644
- }),
645
- /* @__PURE__ */ jsx(Dialog.Close, {
646
- className: "ps:absolute ps:top-4 ps:right-4 ps:rounded-md ps:border ps:border-zinc-600 ps:bg-zinc-950/90 ps:px-2.5 ps:py-1.5 ps:text-xs ps:text-white",
647
- children: "Close"
648
- })
649
- ]
650
- })
651
- })] })] });
472
+ }), /* @__PURE__ */ jsxs(Dialog.Portal, {
473
+ container: portal,
474
+ children: [/* @__PURE__ */ jsx(Dialog.Backdrop, { className: "ps:fixed ps:inset-0 ps:z-[100002] ps:bg-black/75 ps:backdrop-blur-sm" }), /* @__PURE__ */ jsx(Dialog.Viewport, {
475
+ className: "ps:fixed ps:inset-0 ps:z-[100003] ps:grid ps:place-items-center ps:p-8",
476
+ children: /* @__PURE__ */ jsxs(Dialog.Popup, {
477
+ className: "ps:relative ps:max-h-full ps:max-w-4xl ps:rounded-xl ps:border ps:border-[var(--ps-border)] ps:bg-[var(--ps-bg)] ps:p-3 ps:shadow-2xl",
478
+ children: [
479
+ /* @__PURE__ */ jsx(Dialog.Title, {
480
+ className: "ps:sr-only",
481
+ children: label
482
+ }),
483
+ /* @__PURE__ */ jsx("img", {
484
+ alt: label,
485
+ className: "ps:max-h-[80vh] ps:max-w-[80vw] ps:rounded-lg ps:object-contain",
486
+ src: preview.src
487
+ }),
488
+ /* @__PURE__ */ jsx(Dialog.Close, {
489
+ className: "ps:absolute ps:top-4 ps:right-4 ps:rounded-md ps:border ps:border-[var(--ps-border-strong)] ps:bg-[var(--ps-surface)] ps:px-2.5 ps:py-1.5 ps:text-xs ps:text-[var(--ps-text)]",
490
+ children: "Close"
491
+ })
492
+ ]
493
+ })
494
+ })]
495
+ })] });
652
496
  }
653
- function PropertyValuePreview({ ir, ontology, type, value }) {
497
+ const PropertyValuePreview = memo(function PropertyValuePreview({ ir, ontology, type, value }) {
654
498
  const resolved = resolvedType(ir, type);
655
499
  if (resolved.kind === "optional") return /* @__PURE__ */ jsx(PropertyValuePreview, {
656
500
  ir,
@@ -678,7 +522,7 @@ function PropertyValuePreview({ ir, ontology, type, value }) {
678
522
  attachment,
679
523
  ontology
680
524
  }, attachment.id)), attachments.length > 3 ? /* @__PURE__ */ jsxs("span", {
681
- className: "ps:text-zinc-500",
525
+ className: "ps:text-[var(--ps-muted)]",
682
526
  children: ["+", attachments.length - 3]
683
527
  }) : null]
684
528
  });
@@ -689,7 +533,7 @@ function PropertyValuePreview({ ir, ontology, type, value }) {
689
533
  title: formatted,
690
534
  children: formatted
691
535
  });
692
- }
536
+ });
693
537
  function defaultColumnSize(ir, type) {
694
538
  switch (resolvedType(ir, type).kind) {
695
539
  case "boolean": return 110;
@@ -724,6 +568,7 @@ const objectTableFeatures = tableFeatures({
724
568
  });
725
569
  const objectColumnHelper = createColumnHelper();
726
570
  function ObjectTable({ collection, objectType, ontology, pageSize }) {
571
+ const portal = usePanelPortal();
727
572
  const [sorting, setSorting] = useState([]);
728
573
  const [columnSizing, setColumnSizing] = useState({});
729
574
  const [columnVisibility, setColumnVisibility] = useState({});
@@ -731,19 +576,13 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
731
576
  const [draggedColumnId, setDraggedColumnId] = useState();
732
577
  const [dragOverColumnId, setDragOverColumnId] = useState();
733
578
  const selectedSort = sorting[0];
734
- const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useLiveInfiniteQuery((query) => {
579
+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useLiveInfiniteQuery((query) => {
735
580
  const from = query.from({ row: collection });
736
581
  const primaryKey = objectType.primaryKey;
737
582
  if (selectedSort && selectedSort.id !== primaryKey) return from.orderBy(({ row }) => row[selectedSort.id], selectedSort.desc ? "desc" : "asc").orderBy(({ row }) => row[primaryKey], "asc").select(({ row }) => row);
738
583
  return from.orderBy(({ row }) => row[primaryKey], selectedSort?.desc ? "desc" : "asc").select(({ row }) => row);
739
- }, { pageSize }, [
740
- collection.id,
741
- objectType.primaryKey,
742
- pageSize,
743
- selectedSort?.id,
744
- selectedSort?.desc
745
- ]);
746
- const rows = data;
584
+ }, { pageSize });
585
+ const rows = useDeferredValue(data);
747
586
  const columns = useMemo(() => objectType.properties.map((property) => objectColumnHelper.accessor((row) => row[property.name], {
748
587
  id: property.name,
749
588
  maxSize: 520,
@@ -755,7 +594,7 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
755
594
  /* @__PURE__ */ jsx(TypeIndicator, { type: property.type }),
756
595
  /* @__PURE__ */ jsx("span", { children: property.displayName }),
757
596
  property.name === objectType.primaryKey ? /* @__PURE__ */ jsx("span", {
758
- className: "ps:ml-1.5 ps:text-[9px] ps:font-bold ps:tracking-wide ps:text-rose-400",
597
+ className: "ps:ml-1.5 ps:text-[9px] ps:font-bold ps:tracking-wide ps:text-[var(--ps-accent)]",
759
598
  children: "PK"
760
599
  }) : null
761
600
  ]
@@ -792,17 +631,17 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
792
631
  return /* @__PURE__ */ jsxs("div", {
793
632
  className: "ps:flex ps:min-h-0 ps:min-w-0 ps:flex-1 ps:flex-col ps:overflow-hidden",
794
633
  children: [/* @__PURE__ */ jsxs("div", {
795
- className: "ps:flex ps:flex-none ps:items-center ps:border-b ps:border-zinc-500/20 ps:px-4 ps:py-2",
634
+ className: "ps:bg-[var(--ps-surface)] ps:flex ps:flex-none ps:items-center ps:border-b ps:border-[var(--ps-border)] ps:px-4 ps:py-2",
796
635
  children: [/* @__PURE__ */ jsxs("h2", {
797
636
  className: "ps:m-0 ps:flex ps:items-center ps:gap-2 ps:text-lg ps:font-semibold",
798
637
  children: [/* @__PURE__ */ jsx(ObjectTypeIcon, {
799
- className: "ps:size-5 ps:flex-none ps:text-rose-400",
638
+ className: "ps:size-5 ps:flex-none ps:text-[var(--ps-accent)]",
800
639
  objectType
801
640
  }), objectType.pluralDisplayName]
802
641
  }), /* @__PURE__ */ jsxs("div", {
803
642
  className: "ps:ml-auto ps:flex ps:items-center ps:gap-1.5",
804
643
  children: [/* @__PURE__ */ jsxs("button", {
805
- className: "ps:inline-flex ps:items-center ps:gap-1.5 ps:rounded-md ps:border-0 ps:bg-transparent ps:px-2 ps:py-1.5 ps:text-xs ps:text-zinc-400 ps:hover:bg-zinc-500/10 ps:hover:text-current ps:disabled:opacity-40",
644
+ className: "ps:inline-flex ps:items-center ps:gap-1.5 ps:rounded-md ps:border-0 ps:bg-transparent ps:px-2 ps:py-1.5 ps:text-xs ps:text-[var(--ps-muted)] ps:hover:bg-[var(--ps-hover)] ps:hover:text-current ps:disabled:opacity-40",
806
645
  disabled: Object.keys(columnSizing).length === 0,
807
646
  title: "Reset column widths",
808
647
  type: "button",
@@ -814,96 +653,96 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
814
653
  className: "ps:size-3.5"
815
654
  }), "Reset widths"]
816
655
  }), /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Menu.Trigger, {
817
- className: "ps:inline-flex ps:items-center ps:gap-1.5 ps:rounded-md ps:border ps:border-zinc-500/30 ps:bg-zinc-500/10 ps:px-2.5 ps:py-1.5 ps:text-xs ps:text-inherit ps:hover:border-zinc-500/60",
656
+ className: "ps:inline-flex ps:items-center ps:gap-1.5 ps:rounded-md ps:border ps:border-[var(--ps-border)] ps:bg-[var(--ps-hover)] ps:px-2.5 ps:py-1.5 ps:text-xs ps:text-inherit ps:hover:border-[var(--ps-border-strong)]",
818
657
  children: [/* @__PURE__ */ jsx(Columns3, {
819
658
  "aria-hidden": true,
820
659
  className: "ps:size-3.5"
821
660
  }), "Columns"]
822
- }), /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
823
- align: "end",
824
- className: "ps:z-[100001]",
825
- sideOffset: 6,
826
- children: /* @__PURE__ */ jsx(Menu.Popup, {
827
- className: "ps:min-w-48 ps:rounded-lg ps:border ps:border-zinc-700 ps:bg-zinc-900 ps:p-1.5 ps:text-xs ps:text-zinc-200 ps:shadow-2xl",
828
- children: /* @__PURE__ */ jsxs(Menu.Group, { children: [
829
- /* @__PURE__ */ jsx(Menu.GroupLabel, {
830
- className: "ps:px-2 ps:py-1.5 ps:text-[10px] ps:font-bold ps:tracking-wider ps:text-zinc-500 ps:uppercase",
831
- children: "Columns"
832
- }),
833
- allColumns.map((column, columnIndex) => /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
834
- "aria-label": objectType.properties.find((property) => property.name === column.id)?.displayName ?? column.id,
835
- checked: column.getIsVisible(),
836
- className: dragOverColumnId === column.id && draggedColumnId !== column.id ? "ps:flex ps:cursor-default ps:items-center ps:gap-2 ps:rounded-md ps:bg-rose-500/15 ps:px-2 ps:py-1.5 ps:outline-none" : "ps:flex ps:cursor-default ps:items-center ps:gap-2 ps:rounded-md ps:px-2 ps:py-1.5 ps:outline-none ps:data-[highlighted]:bg-zinc-700/70",
837
- draggable: true,
838
- label: objectType.properties.find((property) => property.name === column.id)?.displayName ?? column.id,
839
- onCheckedChange: (checked) => {
840
- column.toggleVisibility(checked);
841
- },
842
- onDragEnd: () => {
843
- setDraggedColumnId(void 0);
844
- setDragOverColumnId(void 0);
845
- },
846
- onDragOver: (event) => {
847
- event.preventDefault();
848
- event.dataTransfer.dropEffect = "move";
849
- setDragOverColumnId(column.id);
850
- },
851
- onDragStart: (event) => {
852
- event.dataTransfer.effectAllowed = "move";
853
- event.dataTransfer.setData("text/plain", column.id);
854
- setDraggedColumnId(column.id);
855
- },
856
- onDrop: (event) => {
857
- event.preventDefault();
858
- if (draggedColumnId && draggedColumnId !== column.id) setColumnOrder((current) => moveColumn(current, draggedColumnId, column.id));
859
- setDraggedColumnId(void 0);
860
- setDragOverColumnId(void 0);
861
- },
862
- onKeyDown: (event) => {
863
- if (!event.altKey || event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
864
- event.preventDefault();
865
- const targetIndex = event.key === "ArrowUp" ? columnIndex - 1 : columnIndex + 1;
866
- const target = allColumns[targetIndex];
867
- if (target) setColumnOrder((current) => moveColumn(current, column.id, target.id));
868
- },
869
- children: [
870
- /* @__PURE__ */ jsx("span", {
871
- "aria-hidden": "true",
872
- className: "ps:cursor-grab ps:text-zinc-500 ps:active:cursor-grabbing",
873
- title: "Drag to reorder",
874
- onClick: (event) => {
875
- event.stopPropagation();
876
- },
877
- children: /* @__PURE__ */ jsx(GripVertical, {
878
- "aria-hidden": true,
879
- className: "ps:size-3.5"
661
+ }), /* @__PURE__ */ jsx(Menu.Portal, {
662
+ container: portal,
663
+ children: /* @__PURE__ */ jsx(Menu.Positioner, {
664
+ align: "end",
665
+ className: "ps:z-[100001]",
666
+ sideOffset: 6,
667
+ children: /* @__PURE__ */ jsx(Menu.Popup, {
668
+ className: "ps:min-w-48 ps:rounded-lg ps:border ps:border-[var(--ps-border)] ps:bg-[var(--ps-raised)] ps:p-1.5 ps:text-xs ps:text-[var(--ps-text)] ps:shadow-2xl",
669
+ children: /* @__PURE__ */ jsxs(Menu.Group, { children: [
670
+ /* @__PURE__ */ jsx(Menu.GroupLabel, {
671
+ className: "ps:px-2 ps:py-1.5 ps:text-[10px] ps:font-bold ps:tracking-wider ps:text-[var(--ps-muted)] ps:uppercase",
672
+ children: "Columns"
673
+ }),
674
+ allColumns.map((column, columnIndex) => /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
675
+ "aria-label": objectType.properties.find((property) => property.name === column.id)?.displayName ?? column.id,
676
+ checked: column.getIsVisible(),
677
+ className: dragOverColumnId === column.id && draggedColumnId !== column.id ? "ps:flex ps:cursor-default ps:items-center ps:gap-2 ps:rounded-md ps:bg-[var(--ps-selected)] ps:px-2 ps:py-1.5 ps:outline-none" : "ps:flex ps:cursor-default ps:items-center ps:gap-2 ps:rounded-md ps:px-2 ps:py-1.5 ps:outline-none ps:data-[highlighted]:bg-[var(--ps-hover)]",
678
+ draggable: true,
679
+ label: objectType.properties.find((property) => property.name === column.id)?.displayName ?? column.id,
680
+ onCheckedChange: (checked) => {
681
+ column.toggleVisibility(checked);
682
+ },
683
+ onDragEnd: () => {
684
+ setDraggedColumnId(void 0);
685
+ setDragOverColumnId(void 0);
686
+ },
687
+ onDragOver: (event) => {
688
+ event.preventDefault();
689
+ event.dataTransfer.dropEffect = "move";
690
+ setDragOverColumnId(column.id);
691
+ },
692
+ onDragStart: (event) => {
693
+ event.dataTransfer.effectAllowed = "move";
694
+ event.dataTransfer.setData("text/plain", column.id);
695
+ setDraggedColumnId(column.id);
696
+ },
697
+ onDrop: (event) => {
698
+ event.preventDefault();
699
+ if (draggedColumnId && draggedColumnId !== column.id) setColumnOrder((current) => moveColumn(current, draggedColumnId, column.id));
700
+ setDraggedColumnId(void 0);
701
+ setDragOverColumnId(void 0);
702
+ },
703
+ onKeyDown: (event) => {
704
+ if (!event.altKey || event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
705
+ event.preventDefault();
706
+ const targetIndex = event.key === "ArrowUp" ? columnIndex - 1 : columnIndex + 1;
707
+ const target = allColumns[targetIndex];
708
+ if (target) setColumnOrder((current) => moveColumn(current, column.id, target.id));
709
+ },
710
+ children: [
711
+ /* @__PURE__ */ jsx("span", {
712
+ "aria-hidden": "true",
713
+ className: "ps:cursor-grab ps:text-[var(--ps-muted)] ps:active:cursor-grabbing",
714
+ title: "Drag to reorder",
715
+ onClick: (event) => {
716
+ event.stopPropagation();
717
+ },
718
+ children: /* @__PURE__ */ jsx(GripVertical, {
719
+ "aria-hidden": true,
720
+ className: "ps:size-3.5"
721
+ })
722
+ }),
723
+ /* @__PURE__ */ jsx("span", {
724
+ className: "ps:grid ps:size-4 ps:place-items-center ps:rounded ps:border ps:border-[var(--ps-border-strong)]",
725
+ children: column.getIsVisible() ? /* @__PURE__ */ jsx(Check, {
726
+ "aria-hidden": true,
727
+ className: "ps:size-3 ps:text-[var(--ps-accent)]"
728
+ }) : null
729
+ }),
730
+ /* @__PURE__ */ jsx("span", {
731
+ className: "ps:truncate",
732
+ children: objectType.properties.find((property) => property.name === column.id)?.displayName ?? column.id
880
733
  })
881
- }),
882
- /* @__PURE__ */ jsx("span", {
883
- className: "ps:grid ps:size-4 ps:place-items-center ps:rounded ps:border ps:border-zinc-600",
884
- children: column.getIsVisible() ? /* @__PURE__ */ jsx(Check, {
885
- "aria-hidden": true,
886
- className: "ps:size-3 ps:text-rose-400"
887
- }) : null
888
- }),
889
- /* @__PURE__ */ jsx("span", {
890
- className: "ps:truncate",
891
- children: objectType.properties.find((property) => property.name === column.id)?.displayName ?? column.id
892
- })
893
- ]
894
- }, column.id)),
895
- /* @__PURE__ */ jsx("p", {
896
- className: "ps:m-0 ps:px-2 ps:pt-2 ps:pb-1 ps:text-[10px] ps:text-zinc-500",
897
- children: "Drag to reorder · Alt+↑/↓ with keyboard"
898
- })
899
- ] })
734
+ ]
735
+ }, column.id)),
736
+ /* @__PURE__ */ jsx("p", {
737
+ className: "ps:m-0 ps:px-2 ps:pt-2 ps:pb-1 ps:text-[10px] ps:text-[var(--ps-muted)]",
738
+ children: "Drag to reorder · Alt+↑/↓ with keyboard"
739
+ })
740
+ ] })
741
+ })
900
742
  })
901
- }) })] })]
743
+ })] })]
902
744
  })]
903
- }), rows.length === 0 ? /* @__PURE__ */ jsx("div", {
904
- className: "ps:m-4 ps:grid ps:min-h-40 ps:place-items-center ps:rounded-xl ps:border ps:border-dashed ps:border-zinc-500/40 ps:text-sm ps:text-zinc-500",
905
- children: "No objects loaded"
906
- }) : /* @__PURE__ */ jsx("div", {
745
+ }), /* @__PURE__ */ jsx("div", {
907
746
  className: "ps-object-table-scroll ps:min-h-0 ps:flex-1 ps:overflow-auto",
908
747
  children: /* @__PURE__ */ jsxs("div", {
909
748
  className: "ps:relative ps:min-h-full",
@@ -921,9 +760,9 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
921
760
  children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => {
922
761
  const direction = header.column.getIsSorted();
923
762
  return /* @__PURE__ */ jsxs("th", {
924
- className: "ps:relative ps:border-b ps:border-zinc-500/30 ps:bg-zinc-950/95 ps:px-4 ps:py-3 ps:font-semibold ps:whitespace-nowrap ps:backdrop-blur ps:in-[.ps-theme-light]:bg-stone-50/95",
763
+ className: "ps:relative ps:border-b ps:border-[var(--ps-border)] ps:bg-[var(--ps-surface)] ps:px-4 ps:py-3 ps:font-semibold ps:whitespace-nowrap ps:backdrop-blur",
925
764
  children: [header.isPlaceholder ? null : /* @__PURE__ */ jsxs("button", {
926
- className: "ps:flex ps:w-full ps:items-center ps:gap-2 ps:border-0 ps:bg-transparent ps:p-0 ps:text-left ps:text-inherit ps:font-inherit ps:hover:text-rose-400",
765
+ className: "ps:flex ps:w-full ps:items-center ps:gap-2 ps:border-0 ps:bg-transparent ps:p-0 ps:text-left ps:text-inherit ps:font-inherit ps:hover:text-[var(--ps-accent)]",
927
766
  title: `Sort by ${header.column.id}`,
928
767
  type: "button",
929
768
  onClick: header.column.getToggleSortingHandler(),
@@ -931,13 +770,13 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
931
770
  flexRender(header.column.columnDef.header, header.getContext()),
932
771
  direction === "asc" ? /* @__PURE__ */ jsx(ChevronUp, {
933
772
  "aria-hidden": true,
934
- className: "ps:size-3.5 ps:flex-none ps:text-rose-400"
773
+ className: "ps:size-3.5 ps:flex-none ps:text-[var(--ps-accent)]"
935
774
  }) : direction === "desc" ? /* @__PURE__ */ jsx(ChevronDown, {
936
775
  "aria-hidden": true,
937
- className: "ps:size-3.5 ps:flex-none ps:text-rose-400"
776
+ className: "ps:size-3.5 ps:flex-none ps:text-[var(--ps-accent)]"
938
777
  }) : /* @__PURE__ */ jsx(ChevronsUpDown, {
939
778
  "aria-hidden": true,
940
- className: "ps:size-3.5 ps:flex-none ps:text-zinc-600"
779
+ className: "ps:size-3.5 ps:flex-none ps:text-[var(--ps-muted)]"
941
780
  }),
942
781
  /* @__PURE__ */ jsx("span", {
943
782
  className: "ps:sr-only",
@@ -975,19 +814,26 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
975
814
  }, header.id);
976
815
  }) }, headerGroup.id))
977
816
  }),
978
- /* @__PURE__ */ jsx("tbody", { children: table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx("tr", {
979
- className: "ps:hover:bg-zinc-500/8",
817
+ /* @__PURE__ */ jsxs("tbody", { children: [rows.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
818
+ colSpan: table.getVisibleLeafColumns().length,
819
+ className: "ps:h-40 ps:px-4 ps:pt-6 ps:align-top ps:text-[var(--ps-muted)]",
820
+ children: /* @__PURE__ */ jsx("output", { children: isLoading ? "Loading objects…" : "No objects loaded" })
821
+ }) }), table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx("tr", {
822
+ className: "ps-object-data-row ps:hover:bg-[var(--ps-hover)]",
980
823
  children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
981
- className: "ps:max-w-80 ps:border-b ps:border-zinc-500/15 ps:px-4 ps:py-3 ps:text-[11px] ps:whitespace-nowrap",
982
- children: flexRender(cell.column.columnDef.cell, cell.getContext())
824
+ className: "ps-object-data-cell ps:max-w-80 ps:border-b ps:border-[var(--ps-border)] ps:px-4 ps:text-[11px] ps:whitespace-nowrap",
825
+ children: /* @__PURE__ */ jsx("div", {
826
+ className: "ps-object-cell-content",
827
+ children: flexRender(cell.column.columnDef.cell, cell.getContext())
828
+ })
983
829
  }, cell.id))
984
- }, row.id)) })
830
+ }, row.id))] })
985
831
  ]
986
832
  }),
987
833
  hasNextPage ? /* @__PURE__ */ jsx("div", {
988
- className: "ps:sticky ps:left-0 ps:flex ps:w-full ps:justify-center ps:border-t ps:border-zinc-500/20 ps:bg-zinc-950/95 ps:p-3 ps:in-[.ps-theme-light]:bg-stone-50/95",
834
+ className: "ps:sticky ps:left-0 ps:flex ps:w-full ps:justify-center ps:border-t ps:border-[var(--ps-border)] ps:bg-[var(--ps-surface)] ps:p-3",
989
835
  children: /* @__PURE__ */ jsx("button", {
990
- className: "ps:rounded-md ps:border ps:border-zinc-600 ps:bg-zinc-900 ps:px-3 ps:py-1.5 ps:text-xs ps:text-zinc-200 ps:hover:border-rose-400 ps:hover:text-rose-300 ps:disabled:opacity-50",
836
+ className: "ps:rounded-md ps:border ps:border-[var(--ps-border-strong)] ps:bg-[var(--ps-raised)] ps:px-3 ps:py-1.5 ps:text-xs ps:text-[var(--ps-text)] ps:hover:border-[var(--ps-accent)] ps:hover:text-[var(--ps-accent)] ps:disabled:opacity-50",
991
837
  disabled: isFetchingNextPage,
992
838
  type: "button",
993
839
  onClick: () => void fetchNextPage(),
@@ -1006,26 +852,26 @@ function ObjectTable({ collection, objectType, ontology, pageSize }) {
1006
852
  })]
1007
853
  });
1008
854
  }
1009
- function ObjectsView({ ontology, pageSize = 50 }) {
855
+ const ObjectsView = memo(function ObjectsView({ ontology, pageSize = 50 }) {
1010
856
  const objectTypes = ontology.ir.objectTypes;
1011
857
  const [selectedName, setSelectedName] = useState(() => objectTypes[0]?.name);
1012
858
  const selected = objectTypes.find((objectType) => objectType.name === selectedName) ?? objectTypes[0];
1013
- const collection = selected ? ontology.objects[selected.name] : void 0;
859
+ const collection = selected ? ontology.cachedObjects[selected.name] : void 0;
1014
860
  if (!selected || !collection) return /* @__PURE__ */ jsx("div", {
1015
- className: "ps:grid ps:h-full ps:place-items-center ps:text-sm ps:text-zinc-500",
861
+ className: "ps:grid ps:h-full ps:place-items-center ps:text-sm ps:text-[var(--ps-muted)]",
1016
862
  children: "This ontology has no object types."
1017
863
  });
1018
864
  return /* @__PURE__ */ jsxs("div", {
1019
865
  className: "ps:flex ps:h-full ps:min-h-0 ps:w-full ps:min-w-0 ps:overflow-hidden",
1020
866
  children: [/* @__PURE__ */ jsxs("aside", {
1021
- className: "ps:w-44 ps:flex-none ps:overflow-y-auto ps:border-r ps:border-zinc-500/20 ps:p-3",
867
+ className: "ps:w-44 ps:flex-none ps:overflow-y-auto ps:border-r ps:border-[var(--ps-border)] ps:p-3",
1022
868
  children: [/* @__PURE__ */ jsx("p", {
1023
- className: "ps:mt-0 ps:mb-2 ps:px-2 ps:text-[10px] ps:font-bold ps:tracking-[0.14em] ps:text-zinc-500 ps:uppercase",
869
+ className: "ps:mt-0 ps:mb-2 ps:px-2 ps:text-[10px] ps:font-bold ps:tracking-[0.14em] ps:text-[var(--ps-muted)] ps:uppercase",
1024
870
  children: "Object types"
1025
871
  }), /* @__PURE__ */ jsx("div", {
1026
872
  className: "ps:flex ps:flex-col ps:gap-1",
1027
873
  children: objectTypes.map((objectType) => /* @__PURE__ */ jsxs("button", {
1028
- className: objectType.name === selected.name ? "ps:flex ps:items-center ps:gap-2 ps:rounded-lg ps:border-0 ps:bg-rose-500/15 ps:px-2.5 ps:py-2 ps:text-left ps:text-xs ps:font-semibold ps:text-rose-400" : "ps:flex ps:items-center ps:gap-2 ps:rounded-lg ps:border-0 ps:bg-transparent ps:px-2.5 ps:py-2 ps:text-left ps:text-xs ps:text-inherit ps:hover:bg-zinc-500/10",
874
+ className: objectType.name === selected.name ? "ps:flex ps:items-center ps:gap-2 ps:rounded-lg ps:border-0 ps:bg-[var(--ps-selected)] ps:px-2.5 ps:py-2 ps:text-left ps:text-xs ps:font-semibold ps:text-[var(--ps-accent)]" : "ps:flex ps:items-center ps:gap-2 ps:rounded-lg ps:border-0 ps:bg-transparent ps:px-2.5 ps:py-2 ps:text-left ps:text-xs ps:text-inherit ps:hover:bg-[var(--ps-hover)]",
1029
875
  type: "button",
1030
876
  onClick: () => {
1031
877
  setSelectedName(objectType.name);
@@ -1046,200 +892,28 @@ function ObjectsView({ ontology, pageSize = 50 }) {
1046
892
  pageSize
1047
893
  }, selected.name)]
1048
894
  });
1049
- }
1050
- const SCHEMA_CARD_WIDTH = 230;
1051
- const SCHEMA_CARD_HEIGHT = 176;
1052
- function schemaEdgeLabel(link) {
1053
- const label = `${link.source.displayName} · ${link.cardinality}`;
1054
- return {
1055
- label,
1056
- width: Math.min(180, Math.max(72, label.length * 6 + 16))
1057
- };
1058
- }
1059
- function layoutSchema(ir) {
1060
- const graph = new Graph({ multigraph: true }).setGraph({
1061
- marginx: 40,
1062
- marginy: 40,
1063
- nodesep: 72,
1064
- rankdir: "LR",
1065
- ranksep: 120
1066
- }).setDefaultEdgeLabel(() => ({ label: "" }));
1067
- for (const objectType of ir.objectTypes) graph.setNode(objectType.name, {
1068
- height: SCHEMA_CARD_HEIGHT,
1069
- width: SCHEMA_CARD_WIDTH
1070
- });
1071
- for (const link of ir.linkTypes) {
1072
- const edgeLabel = schemaEdgeLabel(link);
1073
- graph.setEdge(link.source.objectType, link.target.objectType, {
1074
- height: 24,
1075
- label: edgeLabel.label,
1076
- width: edgeLabel.width
1077
- }, link.id);
1078
- }
1079
- layout(graph);
1080
- const objectTypeByName = new Map(ir.objectTypes.map((objectType) => [objectType.name, objectType]));
1081
- const nodes = graph.nodes().map((name) => {
1082
- const objectType = objectTypeByName.get(name);
1083
- const node = graph.node(name);
1084
- if (!objectType || !node) return void 0;
1085
- return {
1086
- objectType,
1087
- x: (node.x ?? 0) - SCHEMA_CARD_WIDTH / 2,
1088
- y: (node.y ?? 0) - SCHEMA_CARD_HEIGHT / 2
1089
- };
1090
- }).filter((node) => node !== void 0);
1091
- const edges = graph.edges().map((edge) => {
1092
- const value = graph.edge(edge);
1093
- return {
1094
- id: edge.name ?? `${edge.v}-${edge.w}`,
1095
- label: value.label ?? "",
1096
- labelWidth: value.width ?? 72,
1097
- labelX: value.x ?? value.points?.[0]?.x ?? 0,
1098
- labelY: value.y ?? value.points?.[0]?.y ?? 0,
1099
- points: value.points ?? []
1100
- };
1101
- });
1102
- const graphSize = graph.graph();
1103
- return {
1104
- nodes,
1105
- edges,
1106
- width: Math.max(310, graphSize.width ?? 0),
1107
- height: Math.max(256, graphSize.height ?? 0)
1108
- };
1109
- }
1110
- function schemaEdgePath(points, cornerRadius = 12) {
1111
- if (points.length === 0) return "";
1112
- const first = points[0];
1113
- if (points.length === 1) return `M ${first.x} ${first.y}`;
1114
- const path = [`M ${first.x} ${first.y}`];
1115
- for (let index = 1; index < points.length - 1; index += 1) {
1116
- const previous = points[index - 1];
1117
- const current = points[index];
1118
- const next = points[index + 1];
1119
- const incoming = Math.hypot(current.x - previous.x, current.y - previous.y);
1120
- const outgoing = Math.hypot(next.x - current.x, next.y - current.y);
1121
- if (incoming === 0 || outgoing === 0) {
1122
- path.push(`L ${current.x} ${current.y}`);
1123
- continue;
1124
- }
1125
- const radius = Math.min(cornerRadius, incoming / 2, outgoing / 2);
1126
- const before = {
1127
- x: current.x + (previous.x - current.x) / incoming * radius,
1128
- y: current.y + (previous.y - current.y) / incoming * radius
1129
- };
1130
- const after = {
1131
- x: current.x + (next.x - current.x) / outgoing * radius,
1132
- y: current.y + (next.y - current.y) / outgoing * radius
1133
- };
1134
- path.push(`L ${before.x} ${before.y}`, `Q ${current.x} ${current.y} ${after.x} ${after.y}`);
1135
- }
1136
- const end = points.at(-1);
1137
- if (end) path.push(`L ${end.x} ${end.y}`);
1138
- return path.join(" ");
1139
- }
1140
- function SchemaView({ ir }) {
1141
- const schemaLayout = useMemo(() => layoutSchema(ir), [ir]);
1142
- const markerId = `ps-schema-arrow-${useId().replaceAll(":", "")}`;
1143
- if (ir.objectTypes.length === 0) return /* @__PURE__ */ jsx("div", {
1144
- className: "ps:grid ps:h-full ps:place-items-center ps:text-sm ps:text-zinc-500",
1145
- children: "This ontology has no schema."
1146
- });
1147
- return /* @__PURE__ */ jsx("div", {
1148
- className: "ps:h-full ps:overflow-auto ps:p-5",
1149
- children: /* @__PURE__ */ jsxs("div", {
1150
- className: "ps:relative ps:rounded-2xl ps:border ps:border-zinc-500/20 ps:bg-zinc-950/25 ps:in-[.ps-theme-light]:bg-white/45",
1151
- style: {
1152
- height: schemaLayout.height,
1153
- width: schemaLayout.width
1154
- },
1155
- children: [/* @__PURE__ */ jsxs("svg", {
1156
- "aria-label": "Ontology relations",
1157
- className: "ps:absolute ps:inset-0 ps:size-full ps:overflow-visible",
1158
- role: "img",
1159
- viewBox: `0 0 ${schemaLayout.width} ${schemaLayout.height}`,
1160
- children: [/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("marker", {
1161
- id: markerId,
1162
- markerHeight: "8",
1163
- markerWidth: "8",
1164
- orient: "auto",
1165
- refX: "7",
1166
- refY: "4",
1167
- children: /* @__PURE__ */ jsx("path", {
1168
- className: "ps:fill-rose-400",
1169
- d: "M0,0 L8,4 L0,8 Z"
1170
- })
1171
- }) }), schemaLayout.edges.map((edge) => /* @__PURE__ */ jsxs("g", { children: [
1172
- /* @__PURE__ */ jsx("path", {
1173
- className: "ps:fill-none ps:stroke-rose-400/80",
1174
- d: schemaEdgePath(edge.points),
1175
- markerEnd: `url(#${markerId})`,
1176
- strokeLinecap: "round",
1177
- strokeLinejoin: "round",
1178
- strokeWidth: "2"
1179
- }),
1180
- /* @__PURE__ */ jsx("rect", {
1181
- className: "ps:fill-zinc-900 ps:stroke-zinc-700 ps:in-[.ps-theme-light]:fill-white ps:in-[.ps-theme-light]:stroke-stone-300",
1182
- height: "22",
1183
- rx: "7",
1184
- width: edge.labelWidth,
1185
- x: edge.labelX - edge.labelWidth / 2,
1186
- y: edge.labelY - 11
1187
- }),
1188
- /* @__PURE__ */ jsx("text", {
1189
- className: "ps:fill-zinc-300 ps:text-[10px] ps:font-medium ps:in-[.ps-theme-light]:fill-stone-600",
1190
- dominantBaseline: "middle",
1191
- textAnchor: "middle",
1192
- x: edge.labelX,
1193
- y: edge.labelY,
1194
- children: edge.label
1195
- })
1196
- ] }, edge.id))]
1197
- }), schemaLayout.nodes.map(({ objectType, x, y }) => /* @__PURE__ */ jsxs("article", {
1198
- className: "ps:absolute ps:h-44 ps:w-[230px] ps:overflow-hidden ps:rounded-xl ps:border ps:border-zinc-500/30 ps:bg-zinc-900/95 ps:shadow-xl ps:in-[.ps-theme-light]:bg-white/95",
1199
- style: {
1200
- left: x,
1201
- top: y
1202
- },
1203
- children: [/* @__PURE__ */ jsxs("header", {
1204
- className: "ps:border-b ps:border-zinc-500/20 ps:px-3.5 ps:py-3",
1205
- children: [/* @__PURE__ */ jsxs("h3", {
1206
- className: "ps:m-0 ps:flex ps:items-center ps:gap-2 ps:text-sm ps:font-semibold",
1207
- children: [/* @__PURE__ */ jsx(ObjectTypeIcon, {
1208
- className: "ps:size-4 ps:flex-none ps:text-rose-400",
1209
- objectType
1210
- }), objectType.displayName]
1211
- }), /* @__PURE__ */ jsx("p", {
1212
- className: "ps:mt-0.5 ps:mb-0 ps:font-mono ps:text-[10px] ps:text-zinc-500",
1213
- children: objectType.name
1214
- })]
1215
- }), /* @__PURE__ */ jsx("div", {
1216
- className: "ps:max-h-28 ps:overflow-y-auto ps:px-3.5 ps:py-2",
1217
- children: objectType.properties.map((property) => /* @__PURE__ */ jsxs("div", {
1218
- className: "ps:flex ps:items-center ps:justify-between ps:gap-3 ps:py-1 ps:text-[11px]",
1219
- children: [/* @__PURE__ */ jsx("span", {
1220
- className: "ps:truncate",
1221
- children: property.displayName
1222
- }), property.name === objectType.primaryKey ? /* @__PURE__ */ jsx("span", {
1223
- className: "ps:flex-none ps:text-[9px] ps:font-bold ps:text-rose-400",
1224
- children: "PK"
1225
- }) : null]
1226
- }, property.name))
1227
- })]
1228
- }, objectType.name))]
895
+ });
896
+ function OntologyDevtoolsPanel(props) {
897
+ return /* @__PURE__ */ jsx(PanelBoundary, {
898
+ theme: props.theme ?? "dark",
899
+ children: /* @__PURE__ */ jsx(DbProvider, {
900
+ client: props.ontology.dbClient,
901
+ children: /* @__PURE__ */ jsx(OntologyDevtoolsContent, { ...props })
1229
902
  })
1230
903
  });
1231
904
  }
1232
- function OntologyDevtoolsPanel({ metaOntology, ontology, theme = "dark" }) {
905
+ function OntologyDevtoolsContent({ metaOntology, ontology, theme = "dark" }) {
1233
906
  const { data: outboxEntries } = useLiveQuery({ query: (query) => query.from({ entry: ontology.outbox.collection }) });
1234
907
  const outboxActivity = getOutboxActivity(outboxEntries);
1235
908
  return /* @__PURE__ */ jsx(Tooltip.Provider, { children: /* @__PURE__ */ jsxs(Tabs.Root, {
1236
- className: `ps-devtools ps-theme-${theme} ps:flex ps:h-full ps:min-h-0 ps:w-full ps:min-w-0 ps:flex-col ps:overflow-hidden ps:font-sans ps:text-[13px] ${theme === "dark" ? "ps:bg-zinc-950 ps:text-stone-200" : "ps:bg-stone-50 ps:text-stone-800"}`,
1237
- defaultValue: "outbox",
909
+ "data-ps-devtools": true,
910
+ className: `ps-devtools ps-theme-${theme} ps:flex ps:h-full ps:min-h-0 ps:w-full ps:min-w-0 ps:flex-col ps:overflow-hidden ps:font-sans ps:text-[13px]`,
911
+ defaultValue: "objects",
1238
912
  style: { contain: "inline-size" },
1239
913
  children: [
1240
914
  /* @__PURE__ */ jsx(Tabs.List, {
1241
915
  "aria-label": "Ontology devtools views",
1242
- className: "ps:flex ps:flex-none ps:items-center ps:gap-1 ps:border-b ps:border-zinc-500/20 ps:px-4",
916
+ className: "ps:bg-[var(--ps-surface)] ps:flex ps:flex-none ps:items-center ps:gap-1 ps:overflow-x-auto ps:border-b ps:border-[var(--ps-border)] ps:px-4",
1243
917
  style: { height: 40 },
1244
918
  children: [...ontologyViews, ...metaOntology ? [{
1245
919
  id: "meta",
@@ -1248,7 +922,7 @@ function OntologyDevtoolsPanel({ metaOntology, ontology, theme = "dark" }) {
1248
922
  }] : []].map((view) => {
1249
923
  const Icon = view.icon;
1250
924
  return /* @__PURE__ */ jsxs(Tabs.Tab, {
1251
- className: "ps:group ps:flex ps:h-full ps:items-center ps:gap-1.5 ps:border-x-0 ps:border-t-0 ps:border-b-2 ps:border-transparent ps:bg-transparent ps:px-3 ps:text-xs ps:font-medium ps:text-zinc-500 ps:hover:text-current ps:data-[active]:border-rose-400 ps:data-[active]:font-semibold ps:data-[active]:text-rose-400",
925
+ className: "ps:group ps:flex ps:h-full ps:shrink-0 ps:items-center ps:gap-1.5 ps:border-x-0 ps:border-t-0 ps:border-b-2 ps:border-transparent ps:bg-transparent ps:px-3 ps:text-xs ps:font-medium ps:text-[var(--ps-muted)] ps:hover:text-current ps:data-[active]:border-[var(--ps-accent)] ps:data-[active]:font-semibold ps:data-[active]:text-[var(--ps-accent)]",
1252
926
  value: view.id,
1253
927
  children: [
1254
928
  /* @__PURE__ */ jsx(Icon, {
@@ -1284,41 +958,51 @@ function OntologyDevtoolsPanel({ metaOntology, ontology, theme = "dark" }) {
1284
958
  /* @__PURE__ */ jsx(Tabs.Panel, {
1285
959
  className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
1286
960
  value: "schema",
1287
- children: /* @__PURE__ */ jsx(SchemaView, { ir: ontology.ir })
961
+ children: /* @__PURE__ */ jsx(SchemaView, {
962
+ ir: ontology.ir,
963
+ theme
964
+ })
1288
965
  }),
1289
966
  /* @__PURE__ */ jsx(Tabs.Panel, {
1290
967
  className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
1291
968
  value: "objects",
1292
969
  children: /* @__PURE__ */ jsx(ObjectsView, { ontology })
1293
970
  }),
971
+ /* @__PURE__ */ jsx(Tabs.Panel, {
972
+ className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
973
+ value: "tracing",
974
+ children: /* @__PURE__ */ jsx(Tracing, { ontology })
975
+ }),
976
+ /* @__PURE__ */ jsx(Tabs.Panel, {
977
+ className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
978
+ value: "queries",
979
+ children: /* @__PURE__ */ jsx(Queries, { ontology })
980
+ }),
981
+ /* @__PURE__ */ jsx(Tabs.Panel, {
982
+ className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
983
+ value: "pinned",
984
+ children: /* @__PURE__ */ jsx(Pinned, { ontology })
985
+ }),
986
+ /* @__PURE__ */ jsx(Tabs.Panel, {
987
+ className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
988
+ value: "storage",
989
+ children: /* @__PURE__ */ jsx(Storage, { ontology })
990
+ }),
1294
991
  metaOntology ? /* @__PURE__ */ jsx(Tabs.Panel, {
1295
992
  className: "ps:min-h-0 ps:min-w-0 ps:flex-1 ps:overflow-hidden",
1296
993
  value: "meta",
1297
- children: /* @__PURE__ */ jsx(ObjectsView, {
1298
- ontology: metaOntology,
1299
- pageSize: 25
994
+ children: /* @__PURE__ */ jsx(DbProvider, {
995
+ client: metaOntology.dbClient,
996
+ children: /* @__PURE__ */ jsx(ObjectsView, {
997
+ ontology: metaOntology,
998
+ pageSize: 25
999
+ })
1300
1000
  })
1301
1001
  }) : null
1302
1002
  ]
1303
1003
  }) });
1304
1004
  }
1305
- function createOntologyDevtoolsPlugin({ ontology, id = "party-stack-ontology", metaOntology, name, defaultOpen }) {
1306
- const [createPlugin] = createReactPlugin({
1307
- id,
1308
- name: "Ontology",
1309
- defaultOpen,
1310
- Component: ({ theme }) => /* @__PURE__ */ jsx(OntologyDevtoolsPanel, {
1311
- metaOntology,
1312
- ontology,
1313
- theme
1314
- })
1315
- });
1316
- return {
1317
- ...createPlugin(),
1318
- name: name ?? ((_element, { theme }) => /* @__PURE__ */ jsx(OntologyDevtoolsPluginName, { theme }))
1319
- };
1320
- }
1321
1005
  //#endregion
1322
- export { OntologyDevtoolsPanel, OntologyDevtoolsPluginName, OntologyDevtoolsTrigger, OntologyIcon, createOntologyDevtoolsPlugin, getOutboxActivity, layoutSchema, moveColumn, ontologyDevtoolsTrigger, schemaEdgePath, timestampPreview, typeDisplayName };
1006
+ export { OntologyDevtoolsPanel, OntologyIcon, OutboxEntryCard, getOutboxActivity, layoutSchema, moveColumn, timestampPreview, typeDisplayName };
1323
1007
 
1324
1008
  //# sourceMappingURL=OntologyDevtools.js.map