@lunora/studio 1.0.0-alpha.5 → 1.0.0-alpha.51

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 (198) hide show
  1. package/LICENSE.md +6 -0
  2. package/__assets__/package-og.svg +1 -1
  3. package/dist/index.d.ts +45 -23
  4. package/dist/index.js +31 -31
  5. package/dist/mount.d.ts +1 -1
  6. package/dist/mount.js +3 -2
  7. package/dist/{packem_shared/ApiTab-W3no0KOj.js → packem_chunks/ApiTab.js} +5 -5
  8. package/dist/{packem_shared/AuditPanel-Bq4o_IqT.js → packem_chunks/AuditPanel.js} +29 -41
  9. package/dist/{packem_shared/ExportImportPanel-dxY56TDF.js → packem_chunks/ExportImportPanel.js} +16 -11
  10. package/dist/{packem_shared/FileBrowser-Dhy4zES8.js → packem_chunks/FileBrowser.js} +55 -32
  11. package/dist/{packem_shared/FunctionRunner--fQJRPAD.js → packem_chunks/FunctionRunner.js} +15 -32
  12. package/dist/{packem_shared/FunctionStatsPanel-BjRUA_G3.js → packem_chunks/FunctionStatsPanel.js} +153 -208
  13. package/dist/{packem_shared/HealthPanel-PxclMWmA.js → packem_chunks/HealthPanel.js} +37 -29
  14. package/dist/{packem_shared/InsightsPanel-CWS_C-xW.js → packem_chunks/InsightsPanel.js} +108 -69
  15. package/dist/{packem_shared/LogsPanel-CTW8CFcM.js → packem_chunks/LogsPanel.js} +46 -58
  16. package/dist/{packem_shared/MailPanel-BwkvfIHF.js → packem_chunks/MailPanel.js} +45 -139
  17. package/dist/{packem_shared/MetricsPanel-BLuOhZQ4.js → packem_chunks/MetricsPanel.js} +41 -322
  18. package/dist/{packem_shared/MigrationsPanel-DT3lnwHF.js → packem_chunks/MigrationsPanel.js} +44 -51
  19. package/dist/{packem_shared/PitrPanel-CdErL7EJ.js → packem_chunks/PitrPanel.js} +9 -9
  20. package/dist/{packem_shared/SchemaViewer-LJDcmNIO.js → packem_chunks/SchemaViewer.js} +17 -16
  21. package/dist/{packem_shared/SecurityAdvisorPanel-C_ETsPih.js → packem_chunks/SecurityAdvisorPanel.js} +47 -31
  22. package/dist/packem_chunks/SettingsPanel.js +391 -0
  23. package/dist/{packem_shared/sql-editor-panel-BFRpzj6r.js → packem_chunks/SqlEditorPanel.js} +179 -401
  24. package/dist/{packem_shared/TableEditor-ChfUOZec.js → packem_chunks/TableEditor.js} +13 -94
  25. package/dist/packem_chunks/agents-panel.js +326 -0
  26. package/dist/packem_chunks/analytics-panel.js +261 -0
  27. package/dist/packem_chunks/auth-config-panel.js +365 -0
  28. package/dist/packem_chunks/auth-sessions-panel.js +175 -0
  29. package/dist/packem_chunks/containers-panel.js +261 -0
  30. package/dist/packem_chunks/dashboards-panel.js +781 -0
  31. package/dist/packem_chunks/fanout-panel.js +482 -0
  32. package/dist/packem_chunks/flags-panel.js +176 -0
  33. package/dist/packem_chunks/issues-panel.js +188 -0
  34. package/dist/packem_chunks/kv-browser.js +1896 -0
  35. package/dist/packem_chunks/log-drains-panel.js +273 -0
  36. package/dist/packem_chunks/organizations-panel.js +3178 -0
  37. package/dist/packem_chunks/payments-panel.js +186 -0
  38. package/dist/packem_chunks/permissions-panel.js +805 -0
  39. package/dist/packem_chunks/queues-panel.js +1075 -0
  40. package/dist/packem_chunks/rls-panel.js +315 -0
  41. package/dist/packem_chunks/schedule-panel.js +831 -0
  42. package/dist/packem_chunks/sparkline.js +79 -0
  43. package/dist/packem_chunks/storage-rules-panel.js +140 -0
  44. package/dist/packem_chunks/subscriptions-panel.js +238 -0
  45. package/dist/packem_chunks/users-panel.js +1731 -0
  46. package/dist/packem_chunks/vector-browser.js +281 -0
  47. package/dist/packem_chunks/workflows-panel.js +562 -0
  48. package/dist/packem_shared/{ADMIN_FUNCTIONS-DmBqMZ-z.js → ADMIN_FUNCTIONS-DNeyYtUN.js} +8 -0
  49. package/dist/packem_shared/{ApiDocsPanel-C5-yJ1p7.js → ApiDocsPanel-_aEZxAMX.js} +2 -2
  50. package/dist/packem_shared/{ApiReferencePanel-1vubqG5s.js → ApiReferencePanel-Dd8pcswz.js} +2 -1
  51. package/dist/packem_shared/{CommandPalette-BtgkBzZI.js → CommandPalette-BXV4eKf5.js} +1 -1
  52. package/dist/packem_shared/{DataBrowser-CtBe1So9.js → DataBrowser-C8hejnub.js} +201 -250
  53. package/dist/packem_shared/{DataFilters-FNquMaiu.js → DataFilters-B1Q7mrt7.js} +6 -2
  54. package/dist/packem_shared/{GlobalDataBrowser-BTEmGrph.js → GlobalDataBrowser-f5Ll2AQK.js} +43 -68
  55. package/dist/packem_shared/HomePanel-Ye8PaqQL.js +14 -0
  56. package/dist/packem_shared/{OpenRpcReferencePanel-vbcYbv3V.js → OpenRpcReferencePanel-CWaf0ZtX.js} +2 -1
  57. package/dist/packem_shared/{ScheduledJobs-CabfKbyM.js → ScheduledJobs-dHMgnJbx.js} +163 -60
  58. package/dist/packem_shared/{ShardInput-gx_DZXXn.js → ShardInput-CZnpHILL.js} +1 -1
  59. package/dist/packem_shared/Studio-BNGjxLVo.js +16 -0
  60. package/dist/packem_shared/{StudioApp-D4azxYBu.js → StudioApp-K9dn1Q9d.js} +75 -24
  61. package/dist/packem_shared/{advisor-view-CGcfMiPq.js → advisor-view-Cx21PS_T.js} +6 -6
  62. package/dist/packem_shared/alert-CdAET2K_.js +68 -0
  63. package/dist/packem_shared/{app.d-CCmwDEVs.d.ts → app.d-CGdOmLTm.d.ts} +1 -1
  64. package/dist/packem_shared/{bar-chart-CzJAgqkp.js → bar-chart-DSwcWIRy.js} +5 -4
  65. package/dist/packem_shared/browser-storage-L4gOP5gJ.js +105 -0
  66. package/dist/packem_shared/{cf-links-2cktDedA.js → cf-links-BZfRdxSE.js} +1 -1
  67. package/dist/packem_shared/{data-grid-B5CaV3wS.js → data-grid-C9I16KWr.js} +1 -1
  68. package/dist/packem_shared/data-view-params-Cd6yRVbv.js +96 -0
  69. package/dist/packem_shared/error-alert-vIPQoN3Y.js +114 -0
  70. package/dist/packem_shared/{grid-features-CzUfqgsM.js → grid-features-B_fZH4iQ.js} +133 -164
  71. package/dist/packem_shared/home-panel-D62G8108.js +1889 -0
  72. package/dist/packem_shared/internal-zwBoOv24.js +122 -0
  73. package/dist/packem_shared/modal-shell-hyaJvIJ6.js +100 -0
  74. package/dist/packem_shared/{reference-view-B4E49Lip.js → reference-view-DUULLuOi.js} +8 -61
  75. package/dist/packem_shared/result-chart-DZradBAS.js +119 -0
  76. package/dist/packem_shared/scroll-area-DLhcy-ml.js +93 -0
  77. package/dist/packem_shared/select-UkNYCT3s.js +273 -0
  78. package/dist/packem_shared/shard-history-AxiJ1WPP.js +16 -0
  79. package/dist/packem_shared/skeleton-CGhL0p20.js +45 -0
  80. package/dist/packem_shared/{sparkline-10dG-_f0.js → sparkline-BnA1kC9X.js} +1 -1
  81. package/dist/packem_shared/studio-Cd21fp4v.js +4090 -0
  82. package/dist/packem_shared/{table-_RzNvy3R.js → table-DsCa9Qp9.js} +1 -1
  83. package/dist/packem_shared/{table-list-sidebar-Bg7uzbvC.js → table-list-sidebar-huX4VmgI.js} +19 -9
  84. package/dist/packem_shared/use-admin-query-BGJ010yZ.js +106 -0
  85. package/dist/packem_shared/use-async-submit-DGCtuDyz.js +91 -0
  86. package/dist/standalone/chunk-22C6COGE.js +13 -0
  87. package/dist/standalone/chunk-2K47A3P6.js +1 -0
  88. package/dist/standalone/chunk-2MLA6WFH.js +1 -0
  89. package/dist/standalone/chunk-2NGUNNGW.js +1 -0
  90. package/dist/standalone/chunk-2ZL6MXBC.js +4 -0
  91. package/dist/standalone/chunk-3GXGLNKW.js +1 -0
  92. package/dist/standalone/chunk-3OA7PECS.js +6 -0
  93. package/dist/standalone/chunk-4PC7IXNY.js +1 -0
  94. package/dist/standalone/chunk-4QA5TWYJ.js +1 -0
  95. package/dist/standalone/chunk-4QHKBC77.js +1 -0
  96. package/dist/standalone/chunk-5OIBXYZM.js +1 -0
  97. package/dist/standalone/chunk-6TYT447C.js +1 -0
  98. package/dist/standalone/chunk-7SN6J4DZ.js +1 -0
  99. package/dist/standalone/chunk-7TJJXVSE.js +1 -0
  100. package/dist/standalone/chunk-A3ZJACVT.js +4 -0
  101. package/dist/standalone/chunk-AHILM3ZP.js +1 -0
  102. package/dist/standalone/chunk-AITOCPML.js +1 -0
  103. package/dist/standalone/chunk-AJ2B326V.js +1 -0
  104. package/dist/standalone/chunk-APSSZB6Z.js +1 -0
  105. package/dist/standalone/chunk-AVONJCNY.js +4 -0
  106. package/dist/standalone/chunk-BE24FXAK.js +1 -0
  107. package/dist/standalone/chunk-BJGBHGK3.js +1 -0
  108. package/dist/standalone/chunk-CKSHCYGC.js +2 -0
  109. package/dist/standalone/chunk-CP2EQVLU.js +1 -0
  110. package/dist/standalone/chunk-DTPFXYHG.js +1 -0
  111. package/dist/standalone/chunk-DWDILV2E.js +1 -0
  112. package/dist/standalone/chunk-E3FVNRH7.js +1 -0
  113. package/dist/standalone/chunk-EEWKIQUE.js +1 -0
  114. package/dist/standalone/chunk-EOE5NDMK.js +1 -0
  115. package/dist/standalone/chunk-FJV4UNYY.js +1 -0
  116. package/dist/standalone/chunk-FWTZYHX4.js +1 -0
  117. package/dist/standalone/chunk-G465LTLD.js +1 -0
  118. package/dist/standalone/chunk-G6URLCRC.js +3 -0
  119. package/dist/standalone/chunk-G7ZBM54M.js +1 -0
  120. package/dist/standalone/chunk-GTM65MVX.js +1 -0
  121. package/dist/standalone/chunk-HV7G6DFP.js +5 -0
  122. package/dist/standalone/chunk-IMZKGRPW.js +1 -0
  123. package/dist/standalone/chunk-ITQKVEP7.js +19 -0
  124. package/dist/standalone/chunk-IZN4TYMN.js +1 -0
  125. package/dist/standalone/chunk-J6J54MBP.js +1 -0
  126. package/dist/standalone/chunk-JM7XBQVK.js +1 -0
  127. package/dist/standalone/chunk-JPILGFXT.js +1 -0
  128. package/dist/standalone/chunk-JSEXCW5Q.js +1 -0
  129. package/dist/standalone/chunk-KDZJ5A3R.js +1 -0
  130. package/dist/standalone/chunk-KEGAWN6Y.js +1 -0
  131. package/dist/standalone/chunk-KGQGNJJ2.js +1 -0
  132. package/dist/standalone/chunk-KJJ3WM6H.js +4 -0
  133. package/dist/standalone/chunk-KKJZL75J.js +1 -0
  134. package/dist/standalone/chunk-KZ6INM5M.js +1 -0
  135. package/dist/standalone/chunk-L2YBC2BV.js +11 -0
  136. package/dist/standalone/chunk-L7SK4ZZD.js +1 -0
  137. package/dist/standalone/chunk-LAK5VSPI.js +1 -0
  138. package/dist/standalone/chunk-LDEVBRDZ.js +1 -0
  139. package/dist/standalone/chunk-LUP4YTBS.js +1 -0
  140. package/dist/standalone/chunk-LVH4KLXS.js +13 -0
  141. package/dist/standalone/chunk-MDTNVR3G.js +1 -0
  142. package/dist/standalone/chunk-N4NG7HGI.js +1 -0
  143. package/dist/standalone/chunk-O3NAGRTR.js +1 -0
  144. package/dist/standalone/chunk-ONSKQCYN.js +3 -0
  145. package/dist/standalone/chunk-OQE56NBE.js +1 -0
  146. package/dist/standalone/chunk-OSPEOESV.js +8 -0
  147. package/dist/standalone/chunk-Q7PYLDZU.js +1 -0
  148. package/dist/standalone/chunk-Q7TKOAGT.js +1 -0
  149. package/dist/standalone/chunk-QAFAJBAW.js +1 -0
  150. package/dist/standalone/chunk-RRCPZMC2.js +22 -0
  151. package/dist/standalone/chunk-RXVQJ4DO.js +1 -0
  152. package/dist/standalone/chunk-S5NTGHCG.js +1 -0
  153. package/dist/standalone/chunk-SDQE2IUJ.js +1 -0
  154. package/dist/standalone/chunk-SEU5V7I6.js +1 -0
  155. package/dist/standalone/chunk-SHERR7ZP.js +1 -0
  156. package/dist/standalone/chunk-T3UCZ5PJ.js +1 -0
  157. package/dist/standalone/chunk-TAD43CG5.js +1 -0
  158. package/dist/standalone/chunk-TAQM5WML.js +1 -0
  159. package/dist/standalone/chunk-TO6D2PJC.js +6 -0
  160. package/dist/standalone/chunk-TQ36RWOP.js +1 -0
  161. package/dist/standalone/chunk-TSLR3ZU2.js +1 -0
  162. package/dist/standalone/chunk-UK64ZSUW.js +1 -0
  163. package/dist/standalone/chunk-UX53GWGU.js +1 -0
  164. package/dist/standalone/chunk-V43BLH4J.js +1 -0
  165. package/dist/standalone/chunk-VC5RNEHU.js +1 -0
  166. package/dist/standalone/chunk-VL23Y44O.js +4 -0
  167. package/dist/standalone/chunk-VLIRTNLA.js +4 -0
  168. package/dist/standalone/chunk-VLXV72QE.js +1 -0
  169. package/dist/standalone/chunk-VN2PDOMK.js +1 -0
  170. package/dist/standalone/chunk-VZFJI6XE.js +1 -0
  171. package/dist/standalone/chunk-W6JKUZKD.js +1 -0
  172. package/dist/standalone/chunk-WI7GWFEG.js +1 -0
  173. package/dist/standalone/chunk-WJ6OBCUM.js +1 -0
  174. package/dist/standalone/chunk-WUFVFVHJ.js +1 -0
  175. package/dist/standalone/chunk-WVTPZ6CM.js +1 -0
  176. package/dist/standalone/chunk-X4QFAAZ5.js +76 -0
  177. package/dist/standalone/chunk-XNJNSCLM.js +1 -0
  178. package/dist/standalone/chunk-XOANGJJP.js +1 -0
  179. package/dist/standalone/chunk-YA6POZJD.js +1 -0
  180. package/dist/standalone/chunk-ZECNJ4FG.js +1 -0
  181. package/dist/standalone/chunk-ZETIKSQJ.js +1 -0
  182. package/dist/standalone/chunk-ZHVTQ37P.js +1 -0
  183. package/dist/standalone/chunk-ZIGWVHCS.js +1 -0
  184. package/dist/standalone/chunk-ZPP2KOR4.js +1 -0
  185. package/dist/standalone/chunk-ZPUO7FNI.js +1 -0
  186. package/dist/standalone/chunk-ZZMGCPXE.js +2 -0
  187. package/dist/standalone/studio.js +104 -246
  188. package/dist/styles.css +2 -2
  189. package/package.json +17 -15
  190. package/dist/packem_shared/HomePanel-Cw16stjq.js +0 -1273
  191. package/dist/packem_shared/SettingsPanel-C0uLRf5P.js +0 -176
  192. package/dist/packem_shared/SqlEditorPanel-CguV7otm.js +0 -13
  193. package/dist/packem_shared/Studio-BmSGSIuY.js +0 -33
  194. package/dist/packem_shared/internal-rXJEAhXS.js +0 -68
  195. package/dist/packem_shared/shard-history-DyebH1R5.js +0 -38
  196. package/dist/packem_shared/studio-H9fuQgSj.js +0 -10303
  197. package/dist/packem_shared/use-live-admin-Dq6g3daN.js +0 -73
  198. package/dist/packem_shared/use-live-shard-seed-Cuk3dnH0.js +0 -76
@@ -23,12 +23,16 @@ const OPERATORS = [{
23
23
  label: "contains",
24
24
  value: "contains"
25
25
  }];
26
+ const coerceFilterValue = (value) => {
27
+ const trimmed = value.trim();
28
+ const asNumber = Number(trimmed);
29
+ return trimmed !== "" && Number.isFinite(asNumber) && String(asNumber) === trimmed ? asNumber : value;
30
+ };
26
31
  const toFilterClauses = (filters) => filters.filter((filter) => filter.column !== "").map((filter) => {
27
- const numeric = filter.operator !== "contains" && filter.value.trim() !== "" && !Number.isNaN(Number(filter.value));
28
32
  return {
29
33
  column: filter.column,
30
34
  operator: filter.operator,
31
- value: numeric ? Number(filter.value) : filter.value
35
+ value: filter.operator === "contains" ? filter.value : coerceFilterValue(filter.value)
32
36
  };
33
37
  });
34
38
  const DataFilters = (t0) => {
@@ -1,13 +1,13 @@
1
1
  import { useLunora } from '@lunora/react';
2
2
  import { useState, useRef, useCallback, useEffect } from 'react';
3
3
  import { E as EmptyState } from './empty-state-DY_oe0k6.js';
4
- import { T as Table, a as TableHeader, b as TableRow, c as TableHead, d as TableBody, e as TableCell } from './table-_RzNvy3R.js';
4
+ import { T as Table, a as TableHeader, b as TableRow, c as TableHead, d as TableBody, e as TableCell } from './table-DsCa9Qp9.js';
5
+ import { a as useClientQuery } from './use-admin-query-BGJ010yZ.js';
5
6
  import { useAutoRefresh } from './DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js';
6
7
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
7
- import { b as CLOUDFLARE_D1_URL } from './cf-links-2cktDedA.js';
8
- import { e as errorMessage, f as fireAndForget } from './internal-rXJEAhXS.js';
9
- import { u as useFacets, T as TableListSidebar, G as GridPagination, D as DataFacets } from './table-list-sidebar-Bg7uzbvC.js';
10
- import { G as GridContainer, C as CellValue } from './data-grid-B5CaV3wS.js';
8
+ import { C as CLOUDFLARE_D1_URL } from './cf-links-BZfRdxSE.js';
9
+ import { u as useFacets, T as TableListSidebar, G as GridPagination, D as DataFacets } from './table-list-sidebar-huX4VmgI.js';
10
+ import { G as GridContainer, C as CellValue } from './data-grid-C9I16KWr.js';
11
11
  import { jsxDEV } from 'react/jsx-dev-runtime';
12
12
 
13
13
  const DEFAULT_PAGE_SIZE = 50;
@@ -37,13 +37,9 @@ const GlobalDataBrowser = ({
37
37
  } = {}) => {
38
38
  const client = useLunora();
39
39
  const t = useT();
40
- const [tables, setTables] = useState(null);
41
- const [tablesError, setTablesError] = useState(null);
42
40
  const [selectedTable, setSelectedTable] = useState(initialTable ?? null);
43
41
  const [offset, setOffset] = useState(0);
44
42
  const [pageSize, setPageSize] = useState(initialPageSize);
45
- const [page, setPage] = useState(null);
46
- const [pageError, setPageError] = useState(null);
47
43
  const [filters, setFilters] = useState([]);
48
44
  const filtersRef = useRef(filters);
49
45
  filtersRef.current = filters;
@@ -53,76 +49,53 @@ const GlobalDataBrowser = ({
53
49
  refetchFacets: refetchFacetsViaHook,
54
50
  toggleFacet
55
51
  } = useFacets();
56
- const fetchTables = useCallback(async () => {
57
- setTablesError(null);
58
- try {
59
- setTables(await client.listGlobalTables());
60
- } catch (error) {
61
- setTables(null);
62
- setTablesError(errorMessage(error));
63
- }
64
- }, [client]);
65
- const fetchSeqRef = useRef(0);
66
- const fetchPage = useCallback(async (table, nextOffset, limit = pageSize, activeFilters = filtersRef.current) => {
67
- fetchSeqRef.current += 1;
68
- const seq = fetchSeqRef.current;
69
- setPageError(null);
70
- try {
71
- const result = await client.readGlobalTablePage({
72
- filters: activeFilters,
73
- limit,
74
- offset: nextOffset,
75
- table
76
- });
77
- if (fetchSeqRef.current !== seq) {
78
- return;
79
- }
80
- setPage(result);
81
- setOffset(nextOffset);
82
- } catch (error_0) {
83
- if (fetchSeqRef.current !== seq) {
84
- return;
85
- }
86
- setPage(null);
87
- setPageError(errorMessage(error_0));
88
- }
89
- }, [client, pageSize]);
90
- const facetFetcher = (table_0, activeFilters_0) => (column) => client.facetGlobalColumn({
52
+ const tablesQuery = useClientQuery(["lunora-global-tables"], () => client.listGlobalTables());
53
+ const tables = tablesQuery.data ?? null;
54
+ const tablesError = tablesQuery.error;
55
+ const pageQuery = useClientQuery(["lunora-global-page", selectedTable ?? "", offset, pageSize, JSON.stringify(filters)], () => client.readGlobalTablePage({
56
+ filters,
57
+ limit: pageSize,
58
+ offset,
59
+ table: selectedTable ?? ""
60
+ }), {
61
+ enabled: selectedTable !== null,
62
+ keepPreviousData: false
63
+ });
64
+ const page = pageQuery.data ?? null;
65
+ const pageError = pageQuery.error;
66
+ const facetFetcher = (table, activeFilters) => (column) => client.facetGlobalColumn({
91
67
  column,
92
- filters: activeFilters_0,
93
- table: table_0
68
+ filters: activeFilters,
69
+ table
94
70
  });
95
- const refetchFacets = (table_1, activeFilters_1) => {
96
- refetchFacetsViaHook(facetFetcher(table_1, activeFilters_1));
71
+ const refetchFacets = (table_0, activeFilters_0) => {
72
+ refetchFacetsViaHook(facetFetcher(table_0, activeFilters_0));
97
73
  };
98
- useEffect(() => {
99
- fireAndForget(fetchTables());
100
- }, [fetchTables]);
101
74
  useAutoRefresh(() => {
102
- fireAndForget(fetchTables());
75
+ tablesQuery.refetch();
103
76
  if (selectedTable !== null) {
104
- fireAndForget(fetchPage(selectedTable, offset));
77
+ pageQuery.refetch();
105
78
  refetchFacets(selectedTable, filtersRef.current);
106
79
  }
107
80
  }, true);
108
81
  const appliedInitialTable = useRef(void 0);
109
- const selectTable = useCallback((table_2) => {
110
- setSelectedTable(table_2);
111
- appliedInitialTable.current = table_2;
82
+ const selectTable = useCallback((table_1) => {
83
+ setSelectedTable(table_1);
84
+ appliedInitialTable.current = table_1;
112
85
  setFilters([]);
113
86
  filtersRef.current = [];
114
87
  clearFacets();
115
- fireAndForget(fetchPage(table_2, 0, pageSize, []));
116
- onSelectTable?.(table_2);
117
- }, [clearFacets, fetchPage, onSelectTable, pageSize]);
88
+ setOffset(0);
89
+ onSelectTable?.(table_1);
90
+ }, [clearFacets, onSelectTable]);
118
91
  const onToggleFacet = (column_0) => {
119
92
  toggleFacet(column_0, selectedTable === null ? null : facetFetcher(selectedTable, filtersRef.current));
120
93
  };
121
94
  const applyFilters = (next) => {
122
95
  setFilters(next);
123
96
  filtersRef.current = next;
97
+ setOffset(0);
124
98
  if (selectedTable !== null) {
125
- fireAndForget(fetchPage(selectedTable, 0, pageSize, next));
126
99
  refetchFacets(selectedTable, next);
127
100
  }
128
101
  };
@@ -136,6 +109,10 @@ const GlobalDataBrowser = ({
136
109
  const index = Number(event.currentTarget.dataset["index"]);
137
110
  applyFilters(filtersRef.current.filter((_, position) => position !== index));
138
111
  };
112
+ const selectTableRef = useRef(selectTable);
113
+ useEffect(() => {
114
+ selectTableRef.current = selectTable;
115
+ });
139
116
  useEffect(() => {
140
117
  if (initialTable === void 0 || initialTable === "" || appliedInitialTable.current === initialTable) {
141
118
  return;
@@ -143,14 +120,14 @@ const GlobalDataBrowser = ({
143
120
  appliedInitialTable.current = initialTable;
144
121
  const target = initialTable;
145
122
  queueMicrotask(() => {
146
- selectTable(target);
123
+ selectTableRef.current(target);
147
124
  });
148
- }, [initialTable, selectTable]);
149
- const goToPage = (nextOffset_0) => {
125
+ }, [initialTable]);
126
+ const goToPage = (nextOffset) => {
150
127
  if (selectedTable === null) {
151
128
  return;
152
129
  }
153
- fireAndForget(fetchPage(selectedTable, Math.max(0, nextOffset_0)));
130
+ setOffset(Math.max(0, nextOffset));
154
131
  };
155
132
  const total = page?.total ?? 0;
156
133
  const hasPrevious = offset > 0;
@@ -158,7 +135,7 @@ const GlobalDataBrowser = ({
158
135
  const rangeStart = page === null || page.rows.length === 0 ? 0 : offset + 1;
159
136
  const rangeEnd = page === null ? 0 : offset + page.rows.length;
160
137
  const reloadTables = () => {
161
- fireAndForget(fetchTables());
138
+ tablesQuery.refetch();
162
139
  };
163
140
  const goPrevious = () => {
164
141
  goToPage(offset - pageSize);
@@ -171,9 +148,7 @@ const GlobalDataBrowser = ({
171
148
  };
172
149
  const changePageSize = (size) => {
173
150
  setPageSize(size);
174
- if (selectedTable !== null) {
175
- fireAndForget(fetchPage(selectedTable, 0, size));
176
- }
151
+ setOffset(0);
177
152
  };
178
153
  return /* @__PURE__ */ jsxDEV("div", {
179
154
  className: "flex h-full min-w-0",
@@ -0,0 +1,14 @@
1
+ import 'react/compiler-runtime';
2
+ import '@tanstack/react-router';
3
+ import 'react';
4
+ import './badge-B2PKA1-5.js';
5
+ import './card-DURq3ElK.js';
6
+ import './empty-state-DY_oe0k6.js';
7
+ import './use-admin-query-BGJ010yZ.js';
8
+ import './DEFAULT_LOCALE-CiX4W7Kr.js';
9
+ import './ADMIN_FUNCTIONS-DNeyYtUN.js';
10
+ import './internal-zwBoOv24.js';
11
+ import './utils-B05Dmz_H.js';
12
+ import './DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js';
13
+ export { H as HomePanel } from './home-panel-D62G8108.js';
14
+ import 'react/jsx-dev-runtime';
@@ -1,7 +1,8 @@
1
1
  import { c } from 'react/compiler-runtime';
2
2
  import { useLunora } from '@lunora/react';
3
3
  import { E as EmptyState } from './empty-state-DY_oe0k6.js';
4
- import { u as useAdminSpec, S as Skeleton, R as ReferenceView } from './reference-view-B4E49Lip.js';
4
+ import { S as Skeleton } from './skeleton-CGhL0p20.js';
5
+ import { u as useAdminSpec, R as ReferenceView } from './reference-view-DUULLuOi.js';
5
6
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
6
7
  import { jsxDEV } from 'react/jsx-dev-runtime';
7
8
 
@@ -1,79 +1,151 @@
1
+ import { c } from 'react/compiler-runtime';
1
2
  import { useLunora } from '@lunora/react';
2
- import { useState, useMemo, useEffect } from 'react';
3
+ import { useState, useEffect } from 'react';
3
4
  import { ConfirmButton } from './ConfirmButton-C2eVi2Qv.js';
4
5
  import { C as Card, a as CardContent } from './card-DURq3ElK.js';
5
6
  import { E as EmptyState } from './empty-state-DY_oe0k6.js';
6
- import { T as Table, a as TableHeader, b as TableRow, c as TableHead, d as TableBody, e as TableCell } from './table-_RzNvy3R.js';
7
+ import { T as Table, a as TableHeader, b as TableRow, c as TableHead, d as TableBody, e as TableCell } from './table-DsCa9Qp9.js';
8
+ import { a as useClientQuery } from './use-admin-query-BGJ010yZ.js';
7
9
  import { useAutoRefresh } from './DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js';
8
10
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
9
- import { f as fireAndForget, e as errorMessage, b as formatTimestamp } from './internal-rXJEAhXS.js';
11
+ import { f as fireAndForget, i as formatTimestamp, e as errorMessage } from './internal-zwBoOv24.js';
10
12
  import { jsxDEV } from 'react/jsx-dev-runtime';
11
13
 
12
14
  const formatScheduledFor = (value) => Number.isFinite(value) ? formatTimestamp(value, "—") : "—";
13
- const ScheduledJobs = ({
14
- cancelJob,
15
- loadJobs
16
- } = {}) => {
15
+ const sortByDue = (records) => records.toSorted((a, b) => a.scheduledFor - b.scheduledFor);
16
+ const ScheduledJobs = (t0) => {
17
+ const $ = c(33);
18
+ let t1;
19
+ if ($[0] !== t0) {
20
+ t1 = t0 === void 0 ? {} : t0;
21
+ $[0] = t0;
22
+ $[1] = t1;
23
+ } else {
24
+ t1 = $[1];
25
+ }
26
+ const {
27
+ cancelJob,
28
+ loadJobs
29
+ } = t1;
17
30
  const client = useLunora();
18
31
  const t = useT();
19
- const [jobs, setJobs] = useState(null);
20
- const [error, setError] = useState(null);
21
- const load = loadJobs ?? (() => client.listScheduledJobs());
22
- const cancelImpl = useMemo(() => {
23
- if (cancelJob !== void 0) {
24
- return cancelJob;
25
- }
26
- return loadJobs === void 0 ? (id) => client.cancelScheduledJob(id) : void 0;
27
- }, [cancelJob, client, loadJobs]);
28
- const refresh = async () => {
29
- setError(null);
30
- try {
31
- const records = await load();
32
- setJobs(records.toSorted((a, b) => a.scheduledFor - b.scheduledFor));
33
- } catch (error_) {
34
- setJobs(null);
35
- setError(errorMessage(error_));
36
- }
37
- };
38
- useEffect(() => {
39
- fireAndForget(refresh());
40
- }, []);
41
32
  const livePush = loadJobs === void 0;
42
- useEffect(() => {
43
- if (!livePush) {
44
- return void 0;
45
- }
46
- return client.subscribeScheduledJobs((records) => {
47
- setError(null);
48
- setJobs(records.toSorted((a, b) => a.scheduledFor - b.scheduledFor));
49
- });
50
- }, [livePush, client]);
51
- useAutoRefresh(() => {
52
- fireAndForget(refresh());
53
- }, !livePush);
54
- const cancel = async (id) => {
55
- if (cancelImpl === void 0) {
56
- return;
57
- }
58
- setError(null);
59
- try {
60
- await cancelImpl(id);
33
+ let t2;
34
+ if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
35
+ t2 = ["lunora-scheduled-jobs"];
36
+ $[2] = t2;
37
+ } else {
38
+ t2 = $[2];
39
+ }
40
+ let t3;
41
+ if ($[3] !== client || $[4] !== loadJobs) {
42
+ t3 = async () => {
43
+ const records = await (loadJobs ?? (() => client.listScheduledJobs()))();
44
+ return sortByDue(records);
45
+ };
46
+ $[3] = client;
47
+ $[4] = loadJobs;
48
+ $[5] = t3;
49
+ } else {
50
+ t3 = $[5];
51
+ }
52
+ const jobsQuery = useClientQuery(t2, t3);
53
+ const [liveJobs, setLiveJobs] = useState(void 0);
54
+ const [liveError, setLiveError] = useState(void 0);
55
+ let t4;
56
+ let t5;
57
+ if ($[6] !== client || $[7] !== livePush) {
58
+ t4 = () => {
61
59
  if (!livePush) {
62
- await refresh();
60
+ return;
63
61
  }
64
- } catch (error_) {
65
- setError(errorMessage(error_));
62
+ return client.subscribeScheduledJobs((records_0) => {
63
+ setLiveError(void 0);
64
+ setLiveJobs(sortByDue(records_0));
65
+ });
66
+ };
67
+ t5 = [livePush, client];
68
+ $[6] = client;
69
+ $[7] = livePush;
70
+ $[8] = t4;
71
+ $[9] = t5;
72
+ } else {
73
+ t4 = $[8];
74
+ t5 = $[9];
75
+ }
76
+ useEffect(t4, t5);
77
+ let t6;
78
+ if ($[10] !== jobsQuery) {
79
+ t6 = () => {
80
+ jobsQuery.refetch();
81
+ };
82
+ $[10] = jobsQuery;
83
+ $[11] = t6;
84
+ } else {
85
+ t6 = $[11];
86
+ }
87
+ useAutoRefresh(t6, !livePush);
88
+ let t7;
89
+ bb0: {
90
+ if (cancelJob !== void 0) {
91
+ t7 = cancelJob;
92
+ break bb0;
93
+ }
94
+ let t82;
95
+ if ($[12] !== client || $[13] !== loadJobs) {
96
+ t82 = loadJobs === void 0 ? (id) => client.cancelScheduledJob(id) : void 0;
97
+ $[12] = client;
98
+ $[13] = loadJobs;
99
+ $[14] = t82;
100
+ } else {
101
+ t82 = $[14];
66
102
  }
67
- };
68
- return /* @__PURE__ */ jsxDEV("div", {
69
- className: "flex flex-col gap-3",
70
- "data-testid": "lunora-scheduled-jobs",
71
- children: [error !== null && /* @__PURE__ */ jsxDEV("p", {
103
+ t7 = t82;
104
+ }
105
+ const cancelImpl = t7;
106
+ const jobs = liveJobs ?? jobsQuery.data;
107
+ const error = liveError ?? jobsQuery.error;
108
+ let t8;
109
+ if ($[15] !== cancelImpl || $[16] !== jobsQuery || $[17] !== livePush) {
110
+ t8 = async (id_0) => {
111
+ if (cancelImpl === void 0) {
112
+ return;
113
+ }
114
+ setLiveError(void 0);
115
+ try {
116
+ await cancelImpl(id_0);
117
+ if (!livePush) {
118
+ jobsQuery.refetch();
119
+ }
120
+ } catch (t92) {
121
+ const error_ = t92;
122
+ setLiveError(errorMessage(error_));
123
+ }
124
+ };
125
+ $[15] = cancelImpl;
126
+ $[16] = jobsQuery;
127
+ $[17] = livePush;
128
+ $[18] = t8;
129
+ } else {
130
+ t8 = $[18];
131
+ }
132
+ const cancel = t8;
133
+ let t9;
134
+ if ($[19] !== error) {
135
+ t9 = error !== null && /* @__PURE__ */ jsxDEV("p", {
72
136
  className: "text-sm text-destructive",
73
137
  "data-testid": "sj-error",
74
138
  role: "alert",
75
139
  children: error
76
- }, void 0, false), jobs !== null && jobs.length === 0 && /* @__PURE__ */ jsxDEV(EmptyState, {
140
+ }, void 0, false);
141
+ $[19] = error;
142
+ $[20] = t9;
143
+ } else {
144
+ t9 = $[20];
145
+ }
146
+ let t10;
147
+ if ($[21] !== jobs?.length || $[22] !== t) {
148
+ t10 = jobs?.length === 0 && /* @__PURE__ */ jsxDEV(EmptyState, {
77
149
  description: t("Jobs queued with runAfter / runAt will appear here."),
78
150
  icon: /* @__PURE__ */ jsxDEV("svg", {
79
151
  "aria-hidden": "true",
@@ -93,7 +165,16 @@ const ScheduledJobs = ({
93
165
  }, void 0, true),
94
166
  testId: "sj-empty",
95
167
  title: t("No scheduled jobs.")
96
- }, void 0, false), jobs !== null && jobs.length > 0 && /* @__PURE__ */ jsxDEV(Card, {
168
+ }, void 0, false);
169
+ $[21] = jobs?.length;
170
+ $[22] = t;
171
+ $[23] = t10;
172
+ } else {
173
+ t10 = $[23];
174
+ }
175
+ let t11;
176
+ if ($[24] !== cancel || $[25] !== cancelImpl || $[26] !== jobs || $[27] !== t) {
177
+ t11 = jobs !== void 0 && jobs.length > 0 && /* @__PURE__ */ jsxDEV(Card, {
97
178
  className: "overflow-hidden py-0",
98
179
  children: /* @__PURE__ */ jsxDEV(CardContent, {
99
180
  className: "px-0",
@@ -152,8 +233,30 @@ const ScheduledJobs = ({
152
233
  }, void 0, false)]
153
234
  }, void 0, true)
154
235
  }, void 0, false)
155
- }, void 0, false)]
156
- }, void 0, true);
236
+ }, void 0, false);
237
+ $[24] = cancel;
238
+ $[25] = cancelImpl;
239
+ $[26] = jobs;
240
+ $[27] = t;
241
+ $[28] = t11;
242
+ } else {
243
+ t11 = $[28];
244
+ }
245
+ let t12;
246
+ if ($[29] !== t10 || $[30] !== t11 || $[31] !== t9) {
247
+ t12 = /* @__PURE__ */ jsxDEV("div", {
248
+ className: "flex flex-col gap-3",
249
+ "data-testid": "lunora-scheduled-jobs",
250
+ children: [t9, t10, t11]
251
+ }, void 0, true);
252
+ $[29] = t10;
253
+ $[30] = t11;
254
+ $[31] = t9;
255
+ $[32] = t12;
256
+ } else {
257
+ t12 = $[32];
258
+ }
259
+ return t12;
157
260
  };
158
261
 
159
262
  export { ScheduledJobs };
@@ -1,7 +1,7 @@
1
1
  import { c } from 'react/compiler-runtime';
2
2
  import { useId, useState } from 'react';
3
3
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
4
- import { l as loadRecentShards } from './shard-history-DyebH1R5.js';
4
+ import { l as loadRecentShards } from './shard-history-AxiJ1WPP.js';
5
5
  import { I as Input } from './input-XH4r1Pt1.js';
6
6
  import { jsxDEV, Fragment } from 'react/jsx-dev-runtime';
7
7
 
@@ -0,0 +1,16 @@
1
+ import 'react/compiler-runtime';
2
+ import '@tanstack/react-router';
3
+ import 'react';
4
+ export { S as Studio } from './studio-Cd21fp4v.js';
5
+ import './ErrorBoundary-BzAApI7J.js';
6
+ import './badge-B2PKA1-5.js';
7
+ import './input-XH4r1Pt1.js';
8
+ import './skeleton-CGhL0p20.js';
9
+ import './home-panel-D62G8108.js';
10
+ import './DEFAULT_LOCALE-CiX4W7Kr.js';
11
+ import './StudioI18nProvider-B-tDCZIi.js';
12
+ import './data-view-params-Cd6yRVbv.js';
13
+ import './internal-zwBoOv24.js';
14
+ import './utils-B05Dmz_H.js';
15
+ import './CommandPalette-BXV4eKf5.js';
16
+ import 'react/jsx-dev-runtime';
@@ -3,33 +3,28 @@ import { LunoraClient } from '@lunora/client';
3
3
  import { LunoraProvider } from '@lunora/react';
4
4
  import { useState, useEffect } from 'react';
5
5
  import { ErrorBoundary } from './ErrorBoundary-BzAApI7J.js';
6
- import { u as useTheme, B as BrandMark, T as ThemeProvider, a as TooltipProvider, S as Studio } from './studio-H9fuQgSj.js';
6
+ import { u as useTheme, B as BrandMark, T as ThemeProvider, a as TooltipProvider, S as Studio } from './studio-Cd21fp4v.js';
7
7
  import useDebounced from './useDebounced-Dxncpg6z.js';
8
8
  import { useT, createStudioI18n } from './DEFAULT_LOCALE-CiX4W7Kr.js';
9
9
  import { StudioI18nProvider } from './StudioI18nProvider-B-tDCZIi.js';
10
+ import { r as resolveOrigin } from './internal-zwBoOv24.js';
10
11
  import STUDIO_ROOT_CLASS from './STUDIO_ROOT_CLASS-D12gX2dV.js';
12
+ import { a as storageOf } from './browser-storage-L4gOP5gJ.js';
11
13
  import { c as cn } from './utils-B05Dmz_H.js';
12
14
  import { B as Button } from './button-BhsN2uZH.js';
13
15
  import { I as Input } from './input-XH4r1Pt1.js';
14
16
  import { jsxDEV } from 'react/jsx-dev-runtime';
15
17
 
16
18
  const STORAGE_KEY = "lunora-studio-admin-token";
17
- const store = () => {
18
- try {
19
- return globalThis.sessionStorage;
20
- } catch {
21
- return void 0;
22
- }
23
- };
24
19
  const loadToken = () => {
25
20
  try {
26
- return store()?.getItem(STORAGE_KEY) ?? "";
21
+ return storageOf("session")?.getItem(STORAGE_KEY) ?? "";
27
22
  } catch {
28
23
  return "";
29
24
  }
30
25
  };
31
26
  const saveToken = (token) => {
32
- const storage = store();
27
+ const storage = storageOf("session");
33
28
  if (storage === void 0) {
34
29
  return;
35
30
  }
@@ -43,6 +38,66 @@ const saveToken = (token) => {
43
38
  }
44
39
  };
45
40
 
41
+ const WS_TOKEN_MINT_PATH = "/_lunora/admin/ws-token";
42
+ const REFRESH_MARGIN_MS = 1e4;
43
+ const isMintedWsToken = (body) => {
44
+ const candidate = body;
45
+ return typeof candidate?.token === "string" && candidate.token.length > 0 && typeof candidate.expiresAtMs === "number";
46
+ };
47
+ const createAdminWsTokenProvider = (options) => {
48
+ const {
49
+ adminToken,
50
+ baseUrl
51
+ } = options;
52
+ const fetchImpl = options.fetchImpl ?? fetch;
53
+ let origin = baseUrl;
54
+ while (origin.endsWith("/")) {
55
+ origin = origin.slice(0, -1);
56
+ }
57
+ const mintUrl = `${origin}${WS_TOKEN_MINT_PATH}`;
58
+ let cached;
59
+ let endpointMissing = false;
60
+ let inFlight;
61
+ const mint = async () => {
62
+ const response = await fetchImpl(mintUrl, {
63
+ headers: {
64
+ authorization: `Bearer ${adminToken}`
65
+ },
66
+ method: "POST"
67
+ });
68
+ if (response.status === 404 || response.status === 405) {
69
+ endpointMissing = true;
70
+ return adminToken;
71
+ }
72
+ if (!response.ok) {
73
+ throw new Error(`ws-token mint failed: ${String(response.status)}`);
74
+ }
75
+ const body = await response.json().catch(() => void 0);
76
+ if (!isMintedWsToken(body)) {
77
+ throw new Error("ws-token mint failed: malformed response body");
78
+ }
79
+ cached = body;
80
+ return body.token;
81
+ };
82
+ return {
83
+ getToken: async () => {
84
+ if (endpointMissing) {
85
+ return adminToken;
86
+ }
87
+ if (cached !== void 0 && cached.expiresAtMs - REFRESH_MARGIN_MS > Date.now()) {
88
+ return cached.token;
89
+ }
90
+ inFlight ??= mint().finally(() => {
91
+ inFlight = void 0;
92
+ });
93
+ return inFlight;
94
+ },
95
+ invalidate: () => {
96
+ cached = void 0;
97
+ }
98
+ };
99
+ };
100
+
46
101
  const StudioLoginForm = (t0) => {
47
102
  const $ = c(42);
48
103
  const {
@@ -312,16 +367,6 @@ const StudioLogin = (t0) => {
312
367
  return t5;
313
368
  };
314
369
 
315
- const resolveBaseUrl = (explicit) => {
316
- if (explicit !== void 0 && explicit !== "") {
317
- return explicit;
318
- }
319
- const loc = globalThis.location;
320
- if (loc?.origin !== void 0 && loc.origin !== "") {
321
- return loc.origin;
322
- }
323
- return "http://localhost:5173";
324
- };
325
370
  const StudioAppBody = (t0) => {
326
371
  const $ = c(23);
327
372
  const {
@@ -559,14 +604,20 @@ const StudioApp = (t0) => {
559
604
  }
560
605
  let created;
561
606
  if ($[7] !== baseUrl || $[8] !== debouncedToken) {
607
+ const origin = resolveOrigin(baseUrl);
608
+ const provider = debouncedToken === "" ? void 0 : createAdminWsTokenProvider({
609
+ adminToken: debouncedToken,
610
+ baseUrl: origin
611
+ });
562
612
  created = new LunoraClient({
563
- url: resolveBaseUrl(baseUrl),
564
- ...debouncedToken === "" ? {} : {
565
- wsToken: debouncedToken
613
+ url: origin,
614
+ ...provider === void 0 ? {} : {
615
+ wsToken: provider.getToken
566
616
  }
567
617
  });
568
- if (debouncedToken !== "") {
618
+ if (provider !== void 0) {
569
619
  created.setAuthToken(debouncedToken);
620
+ created.onTokenExpired(provider.invalidate);
570
621
  }
571
622
  $[7] = baseUrl;
572
623
  $[8] = debouncedToken;