@svadmin/ui 0.79.0 → 0.80.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.
@@ -1,8 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
3
  import { connectPanelChannel, type PanelChannel } from 'devframe/in-page-channel';
4
+ import { DEVTOOLS_CHANNEL } from '@vibeunion/devtools-devframe';
4
5
  import {
5
- SVADMIN_DEVFRAME_CHANNEL,
6
+ type DevtoolsCacheMutation,
6
7
  type DevtoolsQuerySelector,
7
8
  type SvadminDevframeProtocol,
8
9
  type SvadminDevtoolsSnapshot,
@@ -22,11 +23,14 @@
22
23
  ...(selectedOperation ? { operation: selectedOperation } : {}),
23
24
  });
24
25
 
25
- async function run(action: (selector?: DevtoolsQuerySelector) => Promise<void> | void): Promise<void> {
26
+ async function run(action: DevtoolsCacheMutation, selector?: DevtoolsQuerySelector): Promise<void> {
26
27
  if (!channel || !snapshot) return;
27
28
  busy = true;
28
29
  try {
29
- await action(Object.keys(selector).length > 0 ? selector : undefined);
30
+ await channel.call('cacheAction', {
31
+ action,
32
+ ...(selector && Object.keys(selector).length > 0 ? { selector } : {}),
33
+ });
30
34
  snapshot = await channel.call('getSnapshot');
31
35
  } finally {
32
36
  busy = false;
@@ -35,7 +39,7 @@
35
39
 
36
40
  onMount(() => {
37
41
  const nextChannel = connectPanelChannel<SvadminDevframeProtocol>({
38
- name: SVADMIN_DEVFRAME_CHANNEL,
42
+ name: DEVTOOLS_CHANNEL,
39
43
  functions: {},
40
44
  });
41
45
  channel = nextChannel;
@@ -109,13 +113,13 @@
109
113
  </ul>
110
114
  {/if}
111
115
  <div>
112
- <button type="button" disabled={busy} onclick={() => run((selector) => channel?.call('cacheInvalidate', selector))}>Invalidate</button>
113
- <button type="button" disabled={busy} onclick={() => run((selector) => channel?.call('cacheRefetch', selector))}>Refetch</button>
114
- <button type="button" disabled={busy} onclick={() => run((selector) => channel?.call('cacheCancel', selector))}>Cancel</button>
115
- <button type="button" disabled={busy} onclick={() => run((selector) => channel?.call('cacheReset', selector))}>Reset</button>
116
- <button type="button" disabled={busy} onclick={() => run((selector) => channel?.call('cacheRemove', selector))}>Remove</button>
117
- <button type="button" disabled={busy} onclick={() => run(() => channel?.call('cacheClear'))}>Clear cache</button>
118
- <button type="button" disabled={busy} onclick={() => run(() => channel?.call('clearMutations'))}>Clear mutations</button>
116
+ <button type="button" disabled={busy} onclick={() => run('invalidate', selector)}>Invalidate</button>
117
+ <button type="button" disabled={busy} onclick={() => run('refetch', selector)}>Refetch</button>
118
+ <button type="button" disabled={busy} onclick={() => run('cancel', selector)}>Cancel</button>
119
+ <button type="button" disabled={busy} onclick={() => run('reset', selector)}>Reset</button>
120
+ <button type="button" disabled={busy} onclick={() => run('remove', selector)}>Remove</button>
121
+ <button type="button" disabled={busy} onclick={() => run('clear')}>Clear cache</button>
122
+ <button type="button" disabled={busy} onclick={() => run('clearMutations')}>Clear mutations</button>
119
123
  </div>
120
124
  {:else}
121
125
  <p>Waiting for an svadmin page.</p>
@@ -1,22 +1,7 @@
1
- import type { DevtoolsQueryDiagnostic, SvadminDevtoolsSnapshot } from '@svadmin/devtools-contract';
2
- export declare const SVADMIN_DEVFRAME_CHANNEL = "svadmin:devtools";
1
+ import { type DevtoolsPageBridge } from '@vibeunion/devtools-devframe';
2
+ import type { DevtoolsCacheActionRequest, DevtoolsCacheActionResult, DevtoolsQueryDiagnostic, SvadminDevtoolsSnapshot } from '@svadmin/devtools-contract';
3
3
  export type { DevtoolsCacheDiagnostics, DevtoolsProviderDiagnostic, DevtoolsQueryDiagnostic, SvadminDevtoolsSnapshot, } from '@svadmin/devtools-contract';
4
- export type SvadminDevtoolsBridge = {
5
- getSnapshot: () => SvadminDevtoolsSnapshot | null;
6
- subscribe: (listener: (snapshot: SvadminDevtoolsSnapshot) => void) => () => void;
7
- cache: {
8
- cancel: (selector?: DevtoolsQuerySelector) => Promise<void>;
9
- invalidate: (selector?: DevtoolsQuerySelector) => Promise<void>;
10
- refetch: (selector?: DevtoolsQuerySelector) => Promise<void>;
11
- remove: (selector?: DevtoolsQuerySelector) => void;
12
- reset: (selector?: DevtoolsQuerySelector) => Promise<void>;
13
- clear: () => void;
14
- clearMutations: () => void;
15
- };
16
- devframe: {
17
- channelName: typeof SVADMIN_DEVFRAME_CHANNEL;
18
- };
19
- };
4
+ export type { DevtoolsCacheActionRequest, DevtoolsCacheActionResult, DevtoolsCacheMutation, } from '@svadmin/devtools-contract';
20
5
  export type DevtoolsQuerySelector = Partial<Pick<DevtoolsQueryDiagnostic, 'provider' | 'resource' | 'operation'>>;
21
6
  type QueryClientLike = {
22
7
  getQueryCache: () => {
@@ -43,19 +28,19 @@ type QueryClientLike = {
43
28
  }) => Promise<void>;
44
29
  getMutationCache: () => {
45
30
  clear: () => void;
31
+ getAll?: () => readonly unknown[];
46
32
  };
47
33
  };
34
+ /**
35
+ * Page-script protocol as seen by a panel. It mirrors the shared DevTools wire
36
+ * (`getSnapshot` + `cacheAction`); the shared bridge installs the same shape on
37
+ * `window.__VIBEUNION_DEVTOOLS__`.
38
+ */
48
39
  export type SvadminDevframeProtocol = {
49
40
  functions: {
50
41
  pageScript: {
51
42
  getSnapshot: () => SvadminDevtoolsSnapshot | null;
52
- cacheCancel: (selector?: DevtoolsQuerySelector) => Promise<void>;
53
- cacheInvalidate: (selector?: DevtoolsQuerySelector) => Promise<void>;
54
- cacheRefetch: (selector?: DevtoolsQuerySelector) => Promise<void>;
55
- cacheRemove: (selector?: DevtoolsQuerySelector) => void;
56
- cacheReset: (selector?: DevtoolsQuerySelector) => Promise<void>;
57
- cacheClear: () => void;
58
- clearMutations: () => void;
43
+ cacheAction: (request: DevtoolsCacheActionRequest) => Promise<DevtoolsCacheActionResult>;
59
44
  };
60
45
  };
61
46
  };
@@ -72,9 +57,10 @@ export declare function createSvadminDevtoolsCacheActions(): {
72
57
  clear: () => void;
73
58
  clearMutations: () => void | undefined;
74
59
  };
75
- export declare function installSvadminDevtoolsBridge(): void;
76
- declare global {
77
- interface Window {
78
- __SVADMIN_DEVTOOLS__?: SvadminDevtoolsBridge;
79
- }
80
- }
60
+ /**
61
+ * Executes a shared-protocol cache action against the attached query client and
62
+ * reports how many entries matched. Only the operations svadmin implements are
63
+ * accepted; mutation-variant operations the panel never advertises throw.
64
+ */
65
+ export declare function runSvadminDevtoolsCacheAction(request: DevtoolsCacheActionRequest): Promise<DevtoolsCacheActionResult>;
66
+ export declare function installSvadminDevtoolsBridge(): DevtoolsPageBridge | null;
@@ -1,11 +1,9 @@
1
1
  import { parseQueryKey } from '@svadmin/core';
2
- import { createPageScriptChannel } from 'devframe/in-page-channel';
2
+ import { installDevtoolsPageBridge, } from '@vibeunion/devtools-devframe';
3
3
  import { DEV } from 'esm-env';
4
- export const SVADMIN_DEVFRAME_CHANNEL = 'svadmin:devtools';
5
4
  const listeners = new Set();
6
5
  let snapshot = null;
7
6
  let queryClient = null;
8
- let devframeChannel = null;
9
7
  export function publishSvadminDevtoolsSnapshot(next) {
10
8
  snapshot = next;
11
9
  for (const listener of listeners)
@@ -58,35 +56,53 @@ export function createSvadminDevtoolsCacheActions() {
58
56
  clearMutations: () => queryClient?.getMutationCache().clear(),
59
57
  };
60
58
  }
61
- export function installSvadminDevtoolsBridge() {
62
- if (typeof window === 'undefined' || !DEV)
63
- return;
64
- if (!devframeChannel) {
65
- const cache = createSvadminDevtoolsCacheActions();
66
- devframeChannel = createPageScriptChannel({
67
- name: SVADMIN_DEVFRAME_CHANNEL,
68
- functions: {
69
- getSnapshot: { type: 'query', handler: getSvadminDevtoolsSnapshot },
70
- cacheCancel: { type: 'action', handler: cache.cancel },
71
- cacheInvalidate: { type: 'action', handler: cache.invalidate },
72
- cacheRefetch: { type: 'action', handler: cache.refetch },
73
- cacheRemove: { type: 'action', handler: cache.remove },
74
- cacheReset: { type: 'action', handler: cache.reset },
75
- cacheClear: { type: 'action', handler: cache.clear },
76
- clearMutations: { type: 'action', handler: cache.clearMutations },
77
- },
78
- });
59
+ /**
60
+ * Executes a shared-protocol cache action against the attached query client and
61
+ * reports how many entries matched. Only the operations svadmin implements are
62
+ * accepted; mutation-variant operations the panel never advertises throw.
63
+ */
64
+ export async function runSvadminDevtoolsCacheAction(request) {
65
+ const { action, selector } = request;
66
+ const actions = createSvadminDevtoolsCacheActions();
67
+ let matched;
68
+ switch (action) {
69
+ case 'cancel':
70
+ matched = matchingQueryKeys(selector).length;
71
+ await actions.cancel(selector);
72
+ break;
73
+ case 'invalidate':
74
+ matched = matchingQueryKeys(selector).length;
75
+ await actions.invalidate(selector);
76
+ break;
77
+ case 'refetch':
78
+ matched = matchingQueryKeys(selector).length;
79
+ await actions.refetch(selector);
80
+ break;
81
+ case 'remove':
82
+ matched = matchingQueryKeys(selector).length;
83
+ actions.remove(selector);
84
+ break;
85
+ case 'reset':
86
+ matched = matchingQueryKeys(selector).length;
87
+ await actions.reset(selector);
88
+ break;
89
+ case 'clear':
90
+ matched = matchingQueryKeys().length;
91
+ actions.clear();
92
+ break;
93
+ case 'clearMutations':
94
+ matched = queryClient?.getMutationCache().getAll?.().length ?? 0;
95
+ actions.clearMutations();
96
+ break;
97
+ default:
98
+ throw new Error(`Unsupported svadmin cache action: ${String(action)}`);
79
99
  }
80
- const bridge = {
100
+ return { action, matched, changed: matched };
101
+ }
102
+ export function installSvadminDevtoolsBridge() {
103
+ return installDevtoolsPageBridge({
104
+ development: DEV,
81
105
  getSnapshot: getSvadminDevtoolsSnapshot,
82
- subscribe: subscribeSvadminDevtools,
83
- cache: createSvadminDevtoolsCacheActions(),
84
- devframe: { channelName: SVADMIN_DEVFRAME_CHANNEL },
85
- };
86
- Object.defineProperty(window, '__SVADMIN_DEVTOOLS__', {
87
- configurable: true,
88
- enumerable: false,
89
- value: bridge,
90
- writable: false,
106
+ cacheAction: runSvadminDevtoolsCacheAction,
91
107
  });
92
108
  }
package/dist/index.d.ts CHANGED
@@ -48,8 +48,9 @@ export { default as Can } from './components/CanAccess.svelte';
48
48
  export { default as UndoableNotification } from './components/UndoableNotification.svelte';
49
49
  export { default as DevTools } from './components/DevTools.svelte';
50
50
  export { default as DevframePanel } from './components/DevframePanel.svelte';
51
- export { attachSvadminDevtoolsQueryClient, createSvadminDevtoolsCacheActions, getSvadminDevtoolsSnapshot, installSvadminDevtoolsBridge, publishSvadminDevtoolsSnapshot, subscribeSvadminDevtools, SVADMIN_DEVFRAME_CHANNEL, } from './devtools-bridge.js';
52
- export type { DevtoolsCacheDiagnostics, DevtoolsProviderDiagnostic, DevtoolsQueryDiagnostic, SvadminDevtoolsBridge, SvadminDevtoolsSnapshot, DevtoolsQuerySelector, SvadminDevframeProtocol, } from './devtools-bridge.js';
51
+ export { attachSvadminDevtoolsQueryClient, createSvadminDevtoolsCacheActions, getSvadminDevtoolsSnapshot, installSvadminDevtoolsBridge, publishSvadminDevtoolsSnapshot, runSvadminDevtoolsCacheAction, subscribeSvadminDevtools, } from './devtools-bridge.js';
52
+ export type { DevtoolsCacheDiagnostics, DevtoolsProviderDiagnostic, DevtoolsQueryDiagnostic, SvadminDevtoolsSnapshot, DevtoolsQuerySelector, SvadminDevframeProtocol, } from './devtools-bridge.js';
53
+ export type { DevtoolsPageBridge } from '@vibeunion/devtools-devframe';
53
54
  export { default as Authenticated } from './components/Authenticated.svelte';
54
55
  export { default as UpdatePasswordPage } from './components/UpdatePasswordPage.svelte';
55
56
  export { default as ProfilePage } from './components/ProfilePage.svelte';
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ export { default as Can } from './components/CanAccess.svelte';
42
42
  export { default as UndoableNotification } from './components/UndoableNotification.svelte';
43
43
  export { default as DevTools } from './components/DevTools.svelte';
44
44
  export { default as DevframePanel } from './components/DevframePanel.svelte';
45
- export { attachSvadminDevtoolsQueryClient, createSvadminDevtoolsCacheActions, getSvadminDevtoolsSnapshot, installSvadminDevtoolsBridge, publishSvadminDevtoolsSnapshot, subscribeSvadminDevtools, SVADMIN_DEVFRAME_CHANNEL, } from './devtools-bridge.js';
45
+ export { attachSvadminDevtoolsQueryClient, createSvadminDevtoolsCacheActions, getSvadminDevtoolsSnapshot, installSvadminDevtoolsBridge, publishSvadminDevtoolsSnapshot, runSvadminDevtoolsCacheAction, subscribeSvadminDevtools, } from './devtools-bridge.js';
46
46
  export { default as Authenticated } from './components/Authenticated.svelte';
47
47
  export { default as UpdatePasswordPage } from './components/UpdatePasswordPage.svelte';
48
48
  export { default as ProfilePage } from './components/ProfilePage.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/ui",
3
- "version": "0.79.0",
3
+ "version": "0.80.0",
4
4
  "description": "Pre-built admin UI components — AdminApp, AutoTable, AutoForm, Sidebar, Layout",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -139,7 +139,8 @@
139
139
  }
140
140
  },
141
141
  "dependencies": {
142
- "@svadmin/devtools-contract": "^0.2.0",
142
+ "@svadmin/devtools-contract": "^0.3.0",
143
+ "@vibeunion/devtools-devframe": "^0.1.0",
143
144
  "@sinclair/typebox": "^0.34.52",
144
145
  "@floating-ui/dom": "^1.8.0",
145
146
  "esm-env": "^1.2.2",