@lunora/studio 1.0.0-alpha.50 → 1.0.0-alpha.52

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 (57) hide show
  1. package/dist/index.js +3 -3
  2. package/dist/mount.js +1 -1
  3. package/dist/packem_chunks/SqlEditorPanel.js +20 -14
  4. package/dist/packem_chunks/TableEditor.js +1 -1
  5. package/dist/packem_chunks/kv-browser.js +1 -1
  6. package/dist/packem_shared/{GlobalDataBrowser-CxJxRRf2.js → GlobalDataBrowser-f5Ll2AQK.js} +6 -2
  7. package/dist/packem_shared/{Studio-xJLTlLpf.js → Studio-BNGjxLVo.js} +1 -1
  8. package/dist/packem_shared/{StudioApp-oCQholCL.js → StudioApp-K9dn1Q9d.js} +71 -5
  9. package/dist/packem_shared/{studio-WZUOecDv.js → studio-Cd21fp4v.js} +36 -15
  10. package/dist/standalone/{chunk-A66LI6OV.js → chunk-2ZL6MXBC.js} +2 -2
  11. package/dist/standalone/chunk-4ELN4RE4.js +1 -0
  12. package/dist/standalone/{chunk-PS3XCCZD.js → chunk-4QA5TWYJ.js} +1 -1
  13. package/dist/standalone/{chunk-HQM6MBPS.js → chunk-6TYT447C.js} +1 -1
  14. package/dist/standalone/{chunk-BGG56IF5.js → chunk-7SN6J4DZ.js} +1 -1
  15. package/dist/standalone/{chunk-JUDPYSJZ.js → chunk-AJ2B326V.js} +1 -1
  16. package/dist/standalone/chunk-AVONJCNY.js +4 -0
  17. package/dist/standalone/{chunk-X2TQRMQV.js → chunk-BE24FXAK.js} +1 -1
  18. package/dist/standalone/{chunk-U26QNHMO.js → chunk-CP2EQVLU.js} +1 -1
  19. package/dist/standalone/chunk-DANDBL6P.js +3 -0
  20. package/dist/standalone/{chunk-KJFFID72.js → chunk-DBLAQC32.js} +1 -1
  21. package/dist/standalone/{chunk-P2ERTKMB.js → chunk-DTPFXYHG.js} +1 -1
  22. package/dist/standalone/{chunk-NW6SZZ5O.js → chunk-E3FVNRH7.js} +1 -1
  23. package/dist/standalone/{chunk-YLHDKM2P.js → chunk-FJV4UNYY.js} +1 -1
  24. package/dist/standalone/{chunk-LX7KONE3.js → chunk-FWTZYHX4.js} +1 -1
  25. package/dist/standalone/{chunk-IO2XEI6T.js → chunk-G465LTLD.js} +1 -1
  26. package/dist/standalone/{chunk-2CCWLKQW.js → chunk-IMZKGRPW.js} +1 -1
  27. package/dist/standalone/{chunk-4BVRLBEW.js → chunk-KDZJ5A3R.js} +1 -1
  28. package/dist/standalone/{chunk-X4676IX6.js → chunk-KGQGNJJ2.js} +1 -1
  29. package/dist/standalone/{chunk-5OZQHQ26.js → chunk-KKJZL75J.js} +1 -1
  30. package/dist/standalone/chunk-L2YBC2BV.js +11 -0
  31. package/dist/standalone/{chunk-RS7S7XVP.js → chunk-LDEVBRDZ.js} +1 -1
  32. package/dist/standalone/{chunk-4AXW2ECS.js → chunk-LVH4KLXS.js} +1 -1
  33. package/dist/standalone/{chunk-TYN6SQ73.js → chunk-N4NG7HGI.js} +1 -1
  34. package/dist/standalone/{chunk-6ZBU3JWR.js → chunk-ONSKQCYN.js} +1 -1
  35. package/dist/standalone/{chunk-HAJSYWFT.js → chunk-OSPEOESV.js} +1 -1
  36. package/dist/standalone/{chunk-S7AB7Y75.js → chunk-Q7PYLDZU.js} +1 -1
  37. package/dist/standalone/{chunk-2JTPX3CV.js → chunk-Q7TKOAGT.js} +1 -1
  38. package/dist/standalone/{chunk-W666BB6V.js → chunk-RXVQJ4DO.js} +1 -1
  39. package/dist/standalone/{chunk-UTHHHJYS.js → chunk-T3UCZ5PJ.js} +1 -1
  40. package/dist/standalone/{chunk-SHJUAHC6.js → chunk-TSLR3ZU2.js} +1 -1
  41. package/dist/standalone/{chunk-DR6LGPXE.js → chunk-UX53GWGU.js} +1 -1
  42. package/dist/standalone/{chunk-CJXJIRSN.js → chunk-VC5RNEHU.js} +1 -1
  43. package/dist/standalone/{chunk-XJU5SRNL.js → chunk-VLIRTNLA.js} +1 -1
  44. package/dist/standalone/{chunk-3CPQ5IQU.js → chunk-VN2PDOMK.js} +1 -1
  45. package/dist/standalone/{chunk-7LDYSHOU.js → chunk-VZFJI6XE.js} +1 -1
  46. package/dist/standalone/{chunk-LJAAZNQ6.js → chunk-WJ6OBCUM.js} +1 -1
  47. package/dist/standalone/{chunk-VL6HOZHF.js → chunk-XOANGJJP.js} +1 -1
  48. package/dist/standalone/{chunk-NS23QR4W.js → chunk-YA6POZJD.js} +1 -1
  49. package/dist/standalone/{chunk-A2DBMISD.js → chunk-ZECNJ4FG.js} +1 -1
  50. package/dist/standalone/{chunk-FAUN4Z72.js → chunk-ZETIKSQJ.js} +1 -1
  51. package/dist/standalone/{chunk-6RREMPQX.js → chunk-ZZMGCPXE.js} +1 -1
  52. package/dist/standalone/studio.js +36 -36
  53. package/package.json +6 -6
  54. package/dist/standalone/chunk-HTQNZXDT.js +0 -1
  55. package/dist/standalone/chunk-K4S652EQ.js +0 -4
  56. package/dist/standalone/chunk-SDMZKBTD.js +0 -1
  57. package/dist/standalone/chunk-XWPZBZSZ.js +0 -3
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { StudioApp } from './packem_shared/StudioApp-oCQholCL.js';
1
+ export { StudioApp } from './packem_shared/StudioApp-K9dn1Q9d.js';
2
2
  export { CommandPalette, openCommandPalette } from './packem_shared/CommandPalette-BXV4eKf5.js';
3
- export { S as Studio } from './packem_shared/studio-WZUOecDv.js';
3
+ export { S as Studio } from './packem_shared/studio-Cd21fp4v.js';
4
4
  export { ConfirmButton } from './packem_shared/ConfirmButton-C2eVi2Qv.js';
5
5
  export { default as ConnectionBadge } from './packem_shared/ConnectionBadge-B2DDM2Tn.js';
6
6
  export { ErrorBoundary } from './packem_shared/ErrorBoundary-BzAApI7J.js';
@@ -14,7 +14,7 @@ export { default as ApiTab } from './packem_chunks/ApiTab.js';
14
14
  export { default as OpenRpcReferencePanel } from './packem_shared/OpenRpcReferencePanel-CWaf0ZtX.js';
15
15
  export { DataBrowser } from './packem_shared/DataBrowser-C8hejnub.js';
16
16
  export { DataFilters, toFilterClauses } from './packem_shared/DataFilters-B1Q7mrt7.js';
17
- export { GlobalDataBrowser } from './packem_shared/GlobalDataBrowser-CxJxRRf2.js';
17
+ export { GlobalDataBrowser } from './packem_shared/GlobalDataBrowser-f5Ll2AQK.js';
18
18
  export { TableEditor } from './packem_chunks/TableEditor.js';
19
19
  export { ExportImportPanel } from './packem_chunks/ExportImportPanel.js';
20
20
  export { MigrationsPanel } from './packem_chunks/MigrationsPanel.js';
package/dist/mount.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { LunoraError } from '@lunora/errors';
2
2
  import { createRoot } from 'react-dom/client';
3
- import { StudioApp } from './packem_shared/StudioApp-oCQholCL.js';
3
+ import { StudioApp } from './packem_shared/StudioApp-K9dn1Q9d.js';
4
4
  import { jsxDEV } from 'react/jsx-dev-runtime';
5
5
 
6
6
  const mountStudio = (options = {}) => {
@@ -216,11 +216,17 @@ const useSqlAutocomplete = (schema, textareaRef, setValue) => {
216
216
  left: 0,
217
217
  top: 0
218
218
  } : caretOffset(node, caret);
219
- setState({
220
- active: 0,
221
- left,
222
- suggestions,
223
- top
219
+ setState((current) => {
220
+ const unchanged = current !== null && current.active === 0 && current.left === left && current.top === top && current.suggestions.length === suggestions.length && current.suggestions.every((existing, index) => {
221
+ const next = suggestions.at(index);
222
+ return existing.kind === next?.kind && existing.label === next.label && existing.detail === next.detail;
223
+ });
224
+ return unchanged ? current : {
225
+ active: 0,
226
+ left,
227
+ suggestions,
228
+ top
229
+ };
224
230
  });
225
231
  };
226
232
  $[0] = schema;
@@ -243,14 +249,14 @@ const useSqlAutocomplete = (schema, textareaRef, setValue) => {
243
249
  let t2;
244
250
  if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
245
251
  t2 = (delta) => {
246
- setState((current) => {
247
- if (current === null) {
248
- return current;
252
+ setState((current_0) => {
253
+ if (current_0 === null) {
254
+ return current_0;
249
255
  }
250
- const count = current.suggestions.length;
251
- const active = (current.active + delta + count) % count;
256
+ const count = current_0.suggestions.length;
257
+ const active = (current_0.active + delta + count) % count;
252
258
  return {
253
- ...current,
259
+ ...current_0,
254
260
  active
255
261
  };
256
262
  });
@@ -271,14 +277,14 @@ const useSqlAutocomplete = (schema, textareaRef, setValue) => {
271
277
  if (chosen === void 0) {
272
278
  return false;
273
279
  }
274
- const next = acceptSuggestion(textarea.value, textarea.selectionStart, chosen);
275
- setValue(next.value);
280
+ const next_0 = acceptSuggestion(textarea.value, textarea.selectionStart, chosen);
281
+ setValue(next_0.value);
276
282
  setState(null);
277
283
  requestAnimationFrame(() => {
278
284
  const node_0 = textareaRef.current;
279
285
  if (node_0 !== null) {
280
286
  node_0.focus();
281
- node_0.setSelectionRange(next.caret, next.caret);
287
+ node_0.setSelectionRange(next_0.caret, next_0.caret);
282
288
  }
283
289
  });
284
290
  return true;
@@ -8,7 +8,7 @@ import { s as searchToDataView, d as dataViewToSearch } from '../packem_shared/d
8
8
  import { f as fireAndForget } from '../packem_shared/internal-zwBoOv24.js';
9
9
  import { l as loadJsonArray, s as saveJson } from '../packem_shared/browser-storage-L4gOP5gJ.js';
10
10
  import { DataBrowser } from '../packem_shared/DataBrowser-C8hejnub.js';
11
- import { GlobalDataBrowser } from '../packem_shared/GlobalDataBrowser-CxJxRRf2.js';
11
+ import { GlobalDataBrowser } from '../packem_shared/GlobalDataBrowser-f5Ll2AQK.js';
12
12
  import { jsxDEV } from 'react/jsx-dev-runtime';
13
13
 
14
14
  const STORAGE_KEY = "lunora-studio-saved-queries";
@@ -8,7 +8,7 @@ import { f as fireAndForget, e as errorMessage, k as formatBytes, g as copyToCli
8
8
  import { B as Button } from '../packem_shared/button-BhsN2uZH.js';
9
9
  import { C as Checkbox } from '../packem_shared/checkbox-UNkzAxl-.js';
10
10
  import { I as Input } from '../packem_shared/input-XH4r1Pt1.js';
11
- import { b as Sheet, c as SheetContent, d as SheetHeader, e as SheetTitle } from '../packem_shared/studio-WZUOecDv.js';
11
+ import { b as Sheet, c as SheetContent, d as SheetHeader, e as SheetTitle } from '../packem_shared/studio-Cd21fp4v.js';
12
12
  import { c } from 'react/compiler-runtime';
13
13
  import { L as Label } from '../packem_shared/label-D8ykjn5J.js';
14
14
  import { T as Textarea } from '../packem_shared/textarea-D3gaCU_-.js';
@@ -109,6 +109,10 @@ const GlobalDataBrowser = ({
109
109
  const index = Number(event.currentTarget.dataset["index"]);
110
110
  applyFilters(filtersRef.current.filter((_, position) => position !== index));
111
111
  };
112
+ const selectTableRef = useRef(selectTable);
113
+ useEffect(() => {
114
+ selectTableRef.current = selectTable;
115
+ });
112
116
  useEffect(() => {
113
117
  if (initialTable === void 0 || initialTable === "" || appliedInitialTable.current === initialTable) {
114
118
  return;
@@ -116,9 +120,9 @@ const GlobalDataBrowser = ({
116
120
  appliedInitialTable.current = initialTable;
117
121
  const target = initialTable;
118
122
  queueMicrotask(() => {
119
- selectTable(target);
123
+ selectTableRef.current(target);
120
124
  });
121
- }, [initialTable, selectTable]);
125
+ }, [initialTable]);
122
126
  const goToPage = (nextOffset) => {
123
127
  if (selectedTable === null) {
124
128
  return;
@@ -1,7 +1,7 @@
1
1
  import 'react/compiler-runtime';
2
2
  import '@tanstack/react-router';
3
3
  import 'react';
4
- export { S as Studio } from './studio-WZUOecDv.js';
4
+ export { S as Studio } from './studio-Cd21fp4v.js';
5
5
  import './ErrorBoundary-BzAApI7J.js';
6
6
  import './badge-B2PKA1-5.js';
7
7
  import './input-XH4r1Pt1.js';
@@ -3,7 +3,7 @@ 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-WZUOecDv.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';
@@ -38,6 +38,66 @@ const saveToken = (token) => {
38
38
  }
39
39
  };
40
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
+
41
101
  const StudioLoginForm = (t0) => {
42
102
  const $ = c(42);
43
103
  const {
@@ -544,14 +604,20 @@ const StudioApp = (t0) => {
544
604
  }
545
605
  let created;
546
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
+ });
547
612
  created = new LunoraClient({
548
- url: resolveOrigin(baseUrl),
549
- ...debouncedToken === "" ? {} : {
550
- wsToken: debouncedToken
613
+ url: origin,
614
+ ...provider === void 0 ? {} : {
615
+ wsToken: provider.getToken
551
616
  }
552
617
  });
553
- if (debouncedToken !== "") {
618
+ if (provider !== void 0) {
554
619
  created.setAuthToken(debouncedToken);
620
+ created.onTokenExpired(provider.invalidate);
555
621
  }
556
622
  $[7] = baseUrl;
557
623
  $[8] = debouncedToken;
@@ -2,13 +2,13 @@
2
2
  import { c } from 'react/compiler-runtime';
3
3
  import { createRootRoute, createRoute, createBrowserHistory, createMemoryHistory, createRouter, useNavigate, useRouterState, useSearch, Outlet, RouterProvider } from '@tanstack/react-router';
4
4
  import * as React from 'react';
5
- import { useState, useEffect, createContext, use, lazy, Suspense } from 'react';
5
+ import { use, createContext, useState, useEffect, lazy, Suspense } from 'react';
6
6
  import { c as cn } from './utils-B05Dmz_H.js';
7
7
  import { jsxDEV, Fragment } from 'react/jsx-dev-runtime';
8
8
  import { ErrorBoundary } from './ErrorBoundary-BzAApI7J.js';
9
9
  import { useT } from './DEFAULT_LOCALE-CiX4W7Kr.js';
10
- import { motion } from 'motion/react';
11
10
  import { LunoraError } from '@lunora/errors';
11
+ import { motion } from 'motion/react';
12
12
  import { B as Badge } from './badge-B2PKA1-5.js';
13
13
  import { I as Input } from './input-XH4r1Pt1.js';
14
14
  import { Popover as Popover$1 } from '@base-ui/react/popover';
@@ -116,6 +116,25 @@ const ThemeProvider = ({
116
116
  children
117
117
  }, void 0, false);
118
118
  };
119
+ const EnsureThemeProvider = (t0) => {
120
+ const $ = c(3);
121
+ const {
122
+ children
123
+ } = t0;
124
+ const existing = use(ThemeContext);
125
+ let t1;
126
+ if ($[0] !== children || $[1] !== existing) {
127
+ t1 = existing === null ? /* @__PURE__ */ jsxDEV(ThemeProvider, {
128
+ children
129
+ }, void 0, false) : children;
130
+ $[0] = children;
131
+ $[1] = existing;
132
+ $[2] = t1;
133
+ } else {
134
+ t1 = $[2];
135
+ }
136
+ return t1;
137
+ };
119
138
  const useTheme = () => {
120
139
  const context = use(ThemeContext);
121
140
  if (context === null) {
@@ -4009,19 +4028,21 @@ const Studio = (t0) => {
4009
4028
  } = t0;
4010
4029
  let t1;
4011
4030
  if ($[0] !== basePath || $[1] !== chrome || $[2] !== dataEditable || $[3] !== functions || $[4] !== initialShardKey || $[5] !== openApiSpec || $[6] !== openRpcSpec || $[7] !== runAsIdentity || $[8] !== scheduledCancel || $[9] !== scheduledCron || $[10] !== scheduledLoad || $[11] !== schemaEditable) {
4012
- t1 = /* @__PURE__ */ jsxDEV(StudioShell, {
4013
- basePath,
4014
- chrome,
4015
- dataEditable,
4016
- functions,
4017
- initialShardKey,
4018
- openApiSpec,
4019
- openRpcSpec,
4020
- runAsIdentity,
4021
- scheduledCancel,
4022
- scheduledCron,
4023
- scheduledLoad,
4024
- schemaEditable
4031
+ t1 = /* @__PURE__ */ jsxDEV(EnsureThemeProvider, {
4032
+ children: /* @__PURE__ */ jsxDEV(StudioShell, {
4033
+ basePath,
4034
+ chrome,
4035
+ dataEditable,
4036
+ functions,
4037
+ initialShardKey,
4038
+ openApiSpec,
4039
+ openRpcSpec,
4040
+ runAsIdentity,
4041
+ scheduledCancel,
4042
+ scheduledCron,
4043
+ scheduledLoad,
4044
+ schemaEditable
4045
+ }, void 0, false)
4025
4046
  }, void 0, false);
4026
4047
  $[0] = basePath;
4027
4048
  $[1] = chrome;