@qwik.dev/devtools 0.0.1

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 (65) hide show
  1. package/README.md +47 -0
  2. package/lib/index.qwik.cjs +4 -0
  3. package/lib/index.qwik.mjs +4 -0
  4. package/lib/kit/constants.qwik.cjs +4 -0
  5. package/lib/kit/constants.qwik.mjs +4 -0
  6. package/lib/kit/context.qwik.cjs +16 -0
  7. package/lib/kit/context.qwik.mjs +16 -0
  8. package/lib/kit/globals.qwik.cjs +6 -0
  9. package/lib/kit/globals.qwik.mjs +6 -0
  10. package/lib/kit/server.qwik.cjs +18 -0
  11. package/lib/kit/server.qwik.mjs +18 -0
  12. package/lib/kit/shared.qwik.cjs +4 -0
  13. package/lib/kit/shared.qwik.mjs +4 -0
  14. package/lib/plugin/assets/index.qwik.cjs +67 -0
  15. package/lib/plugin/assets/index.qwik.mjs +67 -0
  16. package/lib/plugin/index.qwik.cjs +49 -0
  17. package/lib/plugin/index.qwik.mjs +49 -0
  18. package/lib/plugin/npm/index.qwik.cjs +19 -0
  19. package/lib/plugin/npm/index.qwik.mjs +19 -0
  20. package/lib/plugin/routes/index.qwik.cjs +17 -0
  21. package/lib/plugin/routes/index.qwik.mjs +17 -0
  22. package/lib/plugin/rpc/index.qwik.cjs +14 -0
  23. package/lib/plugin/rpc/index.qwik.mjs +14 -0
  24. package/lib-types/devtools.d.ts +1 -0
  25. package/lib-types/entry.dev.d.ts +2 -0
  26. package/lib-types/entry.ssr.d.ts +2 -0
  27. package/lib-types/index.d.ts +1 -0
  28. package/lib-types/kit/client.d.ts +2 -0
  29. package/lib-types/kit/constants.d.ts +1 -0
  30. package/lib-types/kit/context.d.ts +10 -0
  31. package/lib-types/kit/globals.d.ts +20 -0
  32. package/lib-types/kit/index.d.ts +4 -0
  33. package/lib-types/kit/server.d.ts +2 -0
  34. package/lib-types/kit/shared.d.ts +1 -0
  35. package/lib-types/kit/types.d.ts +33 -0
  36. package/lib-types/plugin/assets/index.d.ts +5 -0
  37. package/lib-types/plugin/components/index.d.ts +0 -0
  38. package/lib-types/plugin/index.d.ts +2 -0
  39. package/lib-types/plugin/npm/index.d.ts +5 -0
  40. package/lib-types/plugin/routes/index.d.ts +5 -0
  41. package/lib-types/plugin/rpc/index.d.ts +3 -0
  42. package/lib-types/plugin/types/index.d.ts +5 -0
  43. package/lib-types/root.d.ts +2 -0
  44. package/package.json +70 -0
  45. package/src/devtools.css +558 -0
  46. package/src/devtools.tsx +411 -0
  47. package/src/entry.dev.tsx +17 -0
  48. package/src/entry.ssr.tsx +25 -0
  49. package/src/index.ts +1 -0
  50. package/src/kit/client.ts +21 -0
  51. package/src/kit/constants.ts +1 -0
  52. package/src/kit/context.ts +42 -0
  53. package/src/kit/globals.ts +22 -0
  54. package/src/kit/index.ts +4 -0
  55. package/src/kit/server.ts +21 -0
  56. package/src/kit/shared.ts +11 -0
  57. package/src/kit/types.ts +48 -0
  58. package/src/plugin/assets/index.ts +126 -0
  59. package/src/plugin/components/index.ts +0 -0
  60. package/src/plugin/index.ts +50 -0
  61. package/src/plugin/npm/index.ts +24 -0
  62. package/src/plugin/routes/index.ts +16 -0
  63. package/src/plugin/rpc/index.ts +14 -0
  64. package/src/plugin/types/index.ts +6 -0
  65. package/src/root.tsx +15 -0
@@ -0,0 +1,411 @@
1
+ import {
2
+ component$,
3
+ useSignal,
4
+ useStore,
5
+ useVisibleTask$,
6
+ noSerialize,
7
+ NoSerialize,
8
+ useStyles$,
9
+ } from '@qwik.dev/core';
10
+ import { tryCreateHotContext } from 'vite-hot-client';
11
+ import {
12
+ HiBoltOutline,
13
+ HiCubeOutline,
14
+ HiPhotoOutline,
15
+ } from '@qwikest/icons/heroicons';
16
+ import { LuFolderTree } from '@qwikest/icons/lucide';
17
+ import {
18
+ createClientRpc,
19
+ getViteClientRpc,
20
+ setViteClientContext,
21
+ type NpmInfo,
22
+ type AssetInfo,
23
+ type RoutesInfo,
24
+ RouteType,
25
+ } from './kit';
26
+ // import { useLocation } from '@qwik.dev/router';
27
+ import styles from './devtools.css?inline';
28
+ function getClientRpcFunctions() {
29
+ return {
30
+ healthCheck: () => true,
31
+ };
32
+ }
33
+
34
+ interface State {
35
+ isOpen: boolean;
36
+ activeTab: 'overview' | 'components' | 'routes' | 'state' | 'assets';
37
+ npmPackages: NpmInfo;
38
+ assets: AssetInfo[];
39
+ routes: NoSerialize<RoutesInfo[]>;
40
+ }
41
+
42
+ export const QwikDevtools = component$(() => {
43
+ useStyles$(styles);
44
+ const state = useStore<State>({
45
+ isOpen: false,
46
+ activeTab: 'overview',
47
+ npmPackages: [],
48
+ assets: [],
49
+ routes: undefined,
50
+ });
51
+ const panelRef = useSignal<HTMLDivElement>();
52
+ const location = {
53
+ url: {
54
+ pathname: '/',
55
+ },
56
+ };
57
+
58
+ // eslint-disable-next-line qwik/no-use-visible-task
59
+ useVisibleTask$(async ({ cleanup, track }) => {
60
+ const hot = await tryCreateHotContext(undefined, ['/']);
61
+
62
+ if (!hot) {
63
+ throw new Error('Vite Hot Context not connected');
64
+ }
65
+
66
+ setViteClientContext(hot);
67
+ createClientRpc(getClientRpcFunctions());
68
+
69
+ track(() => {
70
+ if (state.isOpen) {
71
+ const rpc = getViteClientRpc();
72
+ rpc.getAssetsFromPublicDir().then((data) => {
73
+ state.assets = data;
74
+ });
75
+ rpc.getRoutes().then((data: RoutesInfo) => {
76
+ const children: RoutesInfo[] = data.children || [];
77
+ const directories: RoutesInfo[] = children.filter(
78
+ (child) => child.type === 'directory',
79
+ );
80
+
81
+ const values: RoutesInfo[] = [
82
+ {
83
+ relativePath: '',
84
+ name: 'index',
85
+ type: RouteType.DIRECTORY,
86
+ path: '',
87
+ isSymbolicLink: false,
88
+ children: undefined,
89
+ },
90
+ ...directories,
91
+ ];
92
+
93
+ console.log(values, noSerialize(values));
94
+
95
+ state.routes = noSerialize(values);
96
+ });
97
+
98
+ rpc.getQwikPackages().then((data: NpmInfo) => {
99
+ state.npmPackages = data;
100
+ });
101
+ }
102
+ });
103
+
104
+ // Add keyboard shortcut to toggle devtools
105
+ const handleKeyPress = (e: KeyboardEvent) => {
106
+ if (e.key === '`' && e.metaKey) {
107
+ state.isOpen = !state.isOpen;
108
+ }
109
+ // Add Escape key to close
110
+ if (e.key === 'Escape' && state.isOpen) {
111
+ state.isOpen = false;
112
+ }
113
+ };
114
+
115
+ // Handle click outside
116
+ const handleClickOutside = (e: MouseEvent) => {
117
+ if (
118
+ state.isOpen &&
119
+ panelRef.value &&
120
+ !panelRef.value.contains(e.target as Node)
121
+ ) {
122
+ state.isOpen = false;
123
+ }
124
+ };
125
+
126
+ window.addEventListener('keydown', handleKeyPress);
127
+ window.addEventListener('mousedown', handleClickOutside);
128
+
129
+ cleanup(() => {
130
+ window.removeEventListener('keydown', handleKeyPress);
131
+ window.removeEventListener('mousedown', handleClickOutside);
132
+ });
133
+ });
134
+
135
+ return (
136
+ <div
137
+ class={{
138
+ 'devtools-container': true,
139
+ 'devtools-open': state.isOpen,
140
+ }}
141
+ >
142
+ <div
143
+ class={{
144
+ 'devtools-toggle': true,
145
+ 'is-open': state.isOpen,
146
+ }}
147
+ onClick$={() => (state.isOpen = !state.isOpen)}
148
+ >
149
+ <img
150
+ width={20}
151
+ height={20}
152
+ src="https://qwik.dev/logos/qwik-logo.svg"
153
+ alt="Qwik Logo"
154
+ class="toggle-icon"
155
+ />
156
+ </div>
157
+
158
+ {state.isOpen && (
159
+ <div ref={panelRef} class="devtools-panel">
160
+ <div class="devtools-tabs">
161
+ <button
162
+ class={{ 'tab-active': state.activeTab === 'overview' }}
163
+ onClick$={() => (state.activeTab = 'overview')}
164
+ title="Overview"
165
+ >
166
+ <HiBoltOutline width={20} height={20} />
167
+ </button>
168
+ <button
169
+ class={{ 'tab-active': state.activeTab === 'components' }}
170
+ onClick$={() => (state.activeTab = 'components')}
171
+ title="Components"
172
+ >
173
+ <HiCubeOutline width={20} height={20} />
174
+ </button>
175
+ <button
176
+ class={{ 'tab-active': state.activeTab === 'routes' }}
177
+ onClick$={() => (state.activeTab = 'routes')}
178
+ title="Routes"
179
+ >
180
+ <LuFolderTree width={20} height={20} />
181
+ </button>
182
+ <button
183
+ class={{ 'tab-active': state.activeTab === 'state' }}
184
+ onClick$={() => (state.activeTab = 'state')}
185
+ title="State"
186
+ >
187
+ <svg
188
+ width="20"
189
+ height="20"
190
+ viewBox="0 0 24 24"
191
+ fill="none"
192
+ xmlns="http://www.w3.org/2000/svg"
193
+ >
194
+ <path
195
+ d="M12 2a7 7 0 0 1 7 7c0 2.38-1.19 4.47-3 5.74V17a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2.26C6.19 13.47 5 11.38 5 9a7 7 0 0 1 7-7zm0 2a5 5 0 0 0-5 5c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58a5 5 0 0 0-5-5z"
196
+ fill="currentColor"
197
+ />
198
+ <path d="M8 20v1h8v-1H8z" fill="currentColor" />
199
+ </svg>
200
+ </button>
201
+ <button
202
+ class={{ 'tab-active': state.activeTab === 'assets' }}
203
+ onClick$={() => (state.activeTab = 'assets')}
204
+ title="Assets"
205
+ >
206
+ <HiPhotoOutline width={20} height={20} />
207
+ </button>
208
+ </div>
209
+ <div class="devtools-content">
210
+ {state.activeTab === 'overview' && (
211
+ <div class="tab-content overview">
212
+ <div class="header-section">
213
+ <div class="title-container">
214
+ <img
215
+ width={32}
216
+ height={32}
217
+ src="https://qwik.dev/logos/qwik-logo.svg"
218
+ alt="Qwik Logo"
219
+ class="qwik-logo"
220
+ />
221
+ <h1>Qwik DevTools</h1>
222
+ </div>
223
+ <div class="version">
224
+ v
225
+ {state.npmPackages.find(([name]) =>
226
+ name.includes('core'),
227
+ )?.[1] || '0.0.0'}
228
+ </div>
229
+ </div>
230
+ <div class="metrics-grid">
231
+ <div class="metric-card">
232
+ <div class="metric-icon">
233
+ <LuFolderTree class="icon" />
234
+ </div>
235
+ <div class="metric-content">
236
+ <div class="metric-value">{state.routes?.length}</div>
237
+ <div class="metric-label">pages</div>
238
+ </div>
239
+ </div>
240
+
241
+ <div class="metric-card">
242
+ <div class="metric-icon">
243
+ <HiCubeOutline class="icon" />
244
+ </div>
245
+ <div class="metric-content">
246
+ <div class="metric-value">{state.assets.length}</div>
247
+ <div class="metric-label">components</div>
248
+ </div>
249
+ </div>
250
+
251
+ <div class="metric-card">
252
+ <div class="metric-icon">
253
+ <HiPhotoOutline class="icon" />
254
+ </div>
255
+ <div class="metric-content">
256
+ <div class="metric-value">{state.assets.length || 0}</div>
257
+ <div class="metric-label">assets</div>
258
+ </div>
259
+ </div>
260
+ </div>
261
+
262
+ <div class="packages-section">
263
+ <h3>Installed Packages</h3>
264
+ <div class="packages-grid">
265
+ {state.npmPackages.map(([name, version]) => (
266
+ <div key={name} class="package-item">
267
+ <div class="package-name">{name}</div>
268
+ <div class="package-version">v{version}</div>
269
+ </div>
270
+ ))}
271
+ </div>
272
+ </div>
273
+
274
+ <div class="performance-section">
275
+ <h3>Performance</h3>
276
+ <div class="performance-metrics">
277
+ <div class="perf-item">
278
+ <span>SSR to full load</span>
279
+ <span class="perf-value">-</span>
280
+ </div>
281
+ <div class="perf-item">
282
+ <span>Page load</span>
283
+ <span class="perf-value">-</span>
284
+ </div>
285
+ <div class="perf-item">
286
+ <span>Navigation</span>
287
+ <span class="perf-value">-</span>
288
+ </div>
289
+ </div>
290
+ </div>
291
+ </div>
292
+ )}
293
+ {state.activeTab === 'assets' && (
294
+ <div class="tab-content assets">
295
+ <div class="header-section">
296
+ <h3>Public Assets</h3>
297
+ <div class="assets-stats">
298
+ <span class="stat-item">
299
+ Total Size:{' '}
300
+ {(
301
+ state.assets?.reduce(
302
+ (acc, asset) => acc + asset.size,
303
+ 0,
304
+ ) / 1024
305
+ ).toFixed(2)}{' '}
306
+ KB
307
+ </span>
308
+ <span class="stat-item">
309
+ Count: {state.assets?.length || 0}
310
+ </span>
311
+ </div>
312
+ </div>
313
+ <div class="assets-grid">
314
+ {state.assets?.map((asset) => {
315
+ const isImage = asset.path.match(
316
+ /\.(jpg|jpeg|png|gif|svg|webp)$/i,
317
+ );
318
+ const fileExt = asset.path.split('.').pop()?.toUpperCase();
319
+
320
+ return (
321
+ <div class="asset-card" key={asset.filePath}>
322
+ {isImage ? (
323
+ <div class="asset-preview">
324
+ <img
325
+ width={176}
326
+ height={176}
327
+ src={asset.publicPath}
328
+ alt={asset.path}
329
+ />
330
+ </div>
331
+ ) : (
332
+ <div class="file-preview">
333
+ <span class="file-ext">{fileExt}</span>
334
+ </div>
335
+ )}
336
+ <div class="asset-info">
337
+ <div class="asset-path" title={asset.path}>
338
+ {asset.path.split('/').pop()}
339
+ </div>
340
+ <div class="asset-meta">
341
+ <span class="asset-size">
342
+ {(asset.size / 1024).toFixed(2)} KB
343
+ </span>
344
+ <span class="asset-type">{fileExt}</span>
345
+ </div>
346
+ </div>
347
+ </div>
348
+ );
349
+ })}
350
+ </div>
351
+ </div>
352
+ )}
353
+ {state.activeTab === 'components' && (
354
+ <div class="tab-content">
355
+ <h3>Components</h3>
356
+ </div>
357
+ )}
358
+ {state.activeTab === 'routes' && (
359
+ <div class="tab-content">
360
+ <h3>Application Routes</h3>
361
+ <div class="routes-table">
362
+ <div class="table-header">
363
+ <div class="col-route">Route Path</div>
364
+ <div class="col-route">Name</div>
365
+ <div class="col-route">Middleware</div>
366
+ <div class="col-route">Layout</div>
367
+ </div>
368
+ {state.routes?.map((route, i) => {
369
+ const children = route.children || [];
370
+ const layout =
371
+ route.relativePath !== '' &&
372
+ route.type === 'directory' &&
373
+ children.find((child) => child.name.startsWith('layout'));
374
+
375
+ return (
376
+ <div class="table-row" key={route.relativePath}>
377
+ <div class="col-route">
378
+ <span
379
+ class={
380
+ location.url.pathname ===
381
+ `/${route.relativePath}/`
382
+ ? 'active-route'
383
+ : ''
384
+ }
385
+ >
386
+ {route.relativePath === ''
387
+ ? '/'
388
+ : `/${route.relativePath}/`}
389
+ </span>
390
+ </div>
391
+ <div class="col-route">{route.name}</div>
392
+ <div class="col-route">-</div>
393
+ <div class="col-route">
394
+ <span class={layout && i > 0 ? 'custom-layout' : ''}>
395
+ {layout && i > 0
396
+ ? `${route.relativePath}/layout`
397
+ : 'default'}
398
+ </span>
399
+ </div>
400
+ </div>
401
+ );
402
+ })}
403
+ </div>
404
+ </div>
405
+ )}
406
+ </div>
407
+ </div>
408
+ )}
409
+ </div>
410
+ );
411
+ });
@@ -0,0 +1,17 @@
1
+ /*
2
+ * WHAT IS THIS FILE?
3
+ *
4
+ * Development entry point using only client-side modules:
5
+ * - Do not use this mode in production!
6
+ * - No SSR
7
+ * - No portion of the application is pre-rendered on the server.
8
+ * - All of the application is running eagerly in the browser.
9
+ * - More code is transferred to the browser than in SSR mode.
10
+ * - Optimizer/Serialization/Deserialization code is not exercised!
11
+ */
12
+ import { render, type RenderOptions } from "@qwik.dev/core";
13
+ import Root from "./root";
14
+
15
+ export default function (opts: RenderOptions) {
16
+ return render(document, <Root />, opts);
17
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * WHAT IS THIS FILE?
3
+ *
4
+ * SSR entry point, in all cases the application is rendered outside the browser, this
5
+ * entry point will be the common one.
6
+ *
7
+ * - Server (express, cloudflare...)
8
+ * - npm run start
9
+ * - npm run preview
10
+ * - npm run build
11
+ *
12
+ */
13
+ import { manifest } from "@qwik-client-manifest";
14
+ import {
15
+ renderToStream,
16
+ type RenderToStreamOptions,
17
+ } from "@qwik.dev/core/server";
18
+ import Root from "./root";
19
+
20
+ export default function (opts: RenderToStreamOptions) {
21
+ return renderToStream(<Root />, {
22
+ manifest,
23
+ ...opts,
24
+ });
25
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { qwikDevtools } from './plugin';
@@ -0,0 +1,21 @@
1
+ import SuperJSON from 'superjson';
2
+ import { ClientFunctions, ServerFunctions } from './types';
3
+ import { createBirpc } from 'birpc';
4
+ import { DEVTOOLS_VITE_MESSAGING_EVENT } from './constants';
5
+ import { getViteClientContext, setViteClientRpc } from './context';
6
+
7
+ export function createClientRpc(functions: ClientFunctions) {
8
+ const client = getViteClientContext();
9
+
10
+ const rpc = createBirpc<ServerFunctions, ClientFunctions>(functions, {
11
+ post: (data) =>
12
+ client.send(DEVTOOLS_VITE_MESSAGING_EVENT, SuperJSON.stringify(data)),
13
+ on: (fn) =>
14
+ client.on(DEVTOOLS_VITE_MESSAGING_EVENT, (data) => {
15
+ fn(SuperJSON.parse(data));
16
+ }),
17
+ timeout: 120_000,
18
+ });
19
+
20
+ setViteClientRpc(rpc);
21
+ }
@@ -0,0 +1 @@
1
+ export const DEVTOOLS_VITE_MESSAGING_EVENT = 'qwik_tools:vite_messaging_event';
@@ -0,0 +1,42 @@
1
+ import { target } from './shared';
2
+ import {
3
+ ViteClientContext,
4
+ CLIENT_CTX,
5
+ SERVER_CTX,
6
+ ViteServerContext,
7
+ SERVER_RPC,
8
+ CLIENT_RPC,
9
+ } from './globals';
10
+ import { ServerRpc, ClientRpc } from './types';
11
+
12
+ export function getViteClientContext(): ViteClientContext {
13
+ return target[CLIENT_CTX];
14
+ }
15
+
16
+ export function setViteClientContext(ctx: ViteClientContext) {
17
+ target[CLIENT_CTX] = ctx;
18
+ }
19
+
20
+ export function getViteServerContext() {
21
+ return target[SERVER_CTX];
22
+ }
23
+
24
+ export function setViteServerContext(ctx: ViteServerContext) {
25
+ target[SERVER_CTX] = ctx;
26
+ }
27
+
28
+ export function getViteServerRpc() {
29
+ return target[SERVER_RPC];
30
+ }
31
+
32
+ export function setViteServerRpc(rpc: ServerRpc) {
33
+ target[SERVER_RPC] = rpc;
34
+ }
35
+
36
+ export function getViteClientRpc() {
37
+ return target[CLIENT_RPC];
38
+ }
39
+
40
+ export function setViteClientRpc(rpc: ClientRpc) {
41
+ target[CLIENT_RPC] = rpc;
42
+ }
@@ -0,0 +1,22 @@
1
+ import { ViteDevServer } from 'vite';
2
+ import { ClientRpc, ServerRpc } from './types';
3
+
4
+ interface EventEmitter {
5
+ on: (name: string, handler: (data: any) => void) => void;
6
+ send: (name: string, ...args: any[]) => void;
7
+ }
8
+
9
+ export interface ViteClientContext extends EventEmitter {}
10
+ export type ViteServerContext = ViteDevServer;
11
+
12
+ export const CLIENT_CTX = '__qwik_client_ctx__';
13
+ export const SERVER_CTX = '__qwik_server_ctx__';
14
+ export const SERVER_RPC = '__qwik_server_rpc__';
15
+ export const CLIENT_RPC = '__qwik_client_rpc__';
16
+
17
+ declare global {
18
+ var __qwik_client_ctx__: ViteClientContext;
19
+ var __qwik_server_ctx__: ViteServerContext;
20
+ var __qwik_server_rpc__: ServerRpc;
21
+ var __qwik_client_rpc__: ClientRpc;
22
+ }
@@ -0,0 +1,4 @@
1
+ export * from './client';
2
+ export * from './server';
3
+ export * from './context';
4
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ import SuperJSON from 'superjson';
2
+ import { ClientFunctions, ServerFunctions } from './types';
3
+ import { createBirpc } from 'birpc';
4
+ import { DEVTOOLS_VITE_MESSAGING_EVENT } from './constants';
5
+ import { setViteServerRpc, getViteServerContext } from './context';
6
+
7
+ export function createServerRpc(functions: ServerFunctions) {
8
+ const server = getViteServerContext();
9
+
10
+ const rpc = createBirpc<ClientFunctions, ServerFunctions>(functions, {
11
+ post: (data) =>
12
+ server.ws.send(DEVTOOLS_VITE_MESSAGING_EVENT, SuperJSON.stringify(data)),
13
+ on: (fn) =>
14
+ server.ws.on(DEVTOOLS_VITE_MESSAGING_EVENT, (data) => {
15
+ fn(SuperJSON.parse(data));
16
+ }),
17
+ timeout: 120_000,
18
+ });
19
+
20
+ setViteServerRpc(rpc);
21
+ }
@@ -0,0 +1,11 @@
1
+ export const target = (
2
+ typeof window !== 'undefined'
3
+ ? window
4
+ : typeof globalThis !== 'undefined'
5
+ ? globalThis
6
+ : // eslint-disable-next-line no-restricted-globals
7
+ typeof global !== 'undefined'
8
+ ? // eslint-disable-next-line no-restricted-globals
9
+ global
10
+ : {}
11
+ ) as typeof globalThis;
@@ -0,0 +1,48 @@
1
+ import { BirpcReturn } from 'birpc';
2
+ import { type Dree } from 'dree';
3
+ export { Type as RouteType } from 'dree';
4
+
5
+ export interface ClientFunctions {
6
+ healthCheck(): boolean;
7
+ }
8
+
9
+ export interface ServerFunctions {
10
+ healthCheck(): boolean;
11
+ getAssetsFromPublicDir: () => Promise<AssetInfo[]>;
12
+ getRoutes: () => any;
13
+ getQwikPackages: () => Promise<[string, string][]>;
14
+ }
15
+
16
+ export type ServerRpc = BirpcReturn<ClientFunctions, ServerFunctions>;
17
+ export type ClientRpc = BirpcReturn<ServerFunctions, ClientFunctions>;
18
+
19
+ export type AssetType =
20
+ | 'image'
21
+ | 'font'
22
+ | 'video'
23
+ | 'audio'
24
+ | 'text'
25
+ | 'json'
26
+ | 'wasm'
27
+ | 'other';
28
+
29
+ export interface AssetInfo {
30
+ path: string;
31
+ type: AssetType;
32
+ publicPath: string;
33
+ relativePath: string;
34
+ filePath: string;
35
+ size: number;
36
+ mtime: number;
37
+ }
38
+
39
+ export interface ImageMeta {
40
+ width: number;
41
+ height: number;
42
+ orientation?: number;
43
+ type?: string;
44
+ mimeType?: string;
45
+ }
46
+
47
+ export type RoutesInfo = Dree;
48
+ export type NpmInfo = [string, string][];