@powersync/nuxt 0.0.0-dev-20260128023420 → 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.
- package/{README → README.md} +46 -30
- package/dist/module.d.mts +2 -2
- package/dist/module.json +2 -2
- package/dist/module.mjs +22 -24
- package/dist/runtime/components/BucketsInspectorTab.d.vue.ts +1 -1
- package/dist/runtime/components/BucketsInspectorTab.vue +47 -149
- package/dist/runtime/components/BucketsInspectorTab.vue.d.ts +1 -1
- package/dist/runtime/components/ConfigInspectorTab.d.vue.ts +1 -1
- package/dist/runtime/components/ConfigInspectorTab.vue +11 -48
- package/dist/runtime/components/ConfigInspectorTab.vue.d.ts +1 -1
- package/dist/runtime/components/DataInspectorTab.d.vue.ts +1 -1
- package/dist/runtime/components/DataInspectorTab.vue +35 -149
- package/dist/runtime/components/DataInspectorTab.vue.d.ts +1 -1
- package/dist/runtime/components/LoadingSpinner.d.vue.ts +1 -1
- package/dist/runtime/components/LoadingSpinner.vue.d.ts +1 -1
- package/dist/runtime/components/LogsTab.d.vue.ts +1 -1
- package/dist/runtime/components/LogsTab.vue +42 -94
- package/dist/runtime/components/LogsTab.vue.d.ts +1 -1
- package/dist/runtime/components/PowerSyncInstanceTab.d.vue.ts +1 -1
- package/dist/runtime/components/PowerSyncInstanceTab.vue +1 -3
- package/dist/runtime/components/PowerSyncInstanceTab.vue.d.ts +1 -1
- package/dist/runtime/components/SyncStatusTab.d.vue.ts +1 -1
- package/dist/runtime/components/SyncStatusTab.vue +57 -168
- package/dist/runtime/components/SyncStatusTab.vue.d.ts +1 -1
- package/dist/runtime/composables/useDiagnosticsLogger.d.ts +1 -1
- package/dist/runtime/composables/useDiagnosticsLogger.js +16 -24
- package/dist/runtime/composables/usePowerSyncInspectorDiagnostics.js +13 -53
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/layouts/powersync-inspector-layout.d.vue.ts +1 -1
- package/dist/runtime/layouts/powersync-inspector-layout.vue +9 -36
- package/dist/runtime/layouts/powersync-inspector-layout.vue.d.ts +1 -1
- package/dist/runtime/pages/__powersync-inspector.d.vue.ts +1 -1
- package/dist/runtime/pages/__powersync-inspector.vue +8 -42
- package/dist/runtime/pages/__powersync-inspector.vue.d.ts +1 -1
- package/dist/runtime/utils/DynamicSchemaManager.js +3 -10
- package/dist/runtime/utils/RecordingStorageAdapter.js +4 -22
- package/dist/runtime/utils/TokenConnector.js +2 -7
- package/package.json +12 -10
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
border="t"
|
|
4
|
-
border-color="gray-100"
|
|
5
|
-
relative
|
|
6
|
-
n-bg="base"
|
|
7
|
-
flex="~ col"
|
|
8
|
-
h="screen"
|
|
9
|
-
overflow="hidden"
|
|
10
|
-
>
|
|
2
|
+
<div border="t" border-color="gray-100" relative n-bg="base" flex="~ col" h="screen" overflow="hidden">
|
|
11
3
|
<!-- Toolbar -->
|
|
12
|
-
<div
|
|
13
|
-
class="flex items-center justify-between gap-3 px-3 py-2 border-b border-gray-200 dark:border-neutral-700"
|
|
14
|
-
>
|
|
4
|
+
<div class="flex items-center justify-between gap-3 px-3 py-2 border-b border-gray-200 dark:border-neutral-700">
|
|
15
5
|
<div class="flex items-center gap-2 flex-1">
|
|
16
6
|
<NTextInput
|
|
17
7
|
v-model="searchQuery"
|
|
@@ -25,21 +15,12 @@
|
|
|
25
15
|
v-model="selectedLevel"
|
|
26
16
|
class="px-2 py-1 text-xs border border-gray-300 dark:border-neutral-600 rounded bg-white dark:bg-neutral-800"
|
|
27
17
|
>
|
|
28
|
-
<option value="all">
|
|
29
|
-
|
|
30
|
-
</option>
|
|
31
|
-
<option value="
|
|
32
|
-
|
|
33
|
-
</option>
|
|
34
|
-
<option value="warn">
|
|
35
|
-
Warning
|
|
36
|
-
</option>
|
|
37
|
-
<option value="info">
|
|
38
|
-
Info
|
|
39
|
-
</option>
|
|
40
|
-
<option value="debug">
|
|
41
|
-
Debug
|
|
42
|
-
</option>
|
|
18
|
+
<option value="all">All Levels</option>
|
|
19
|
+
<option value="error">Error</option>
|
|
20
|
+
<option value="warn">Warning</option>
|
|
21
|
+
<option value="info">Info</option>
|
|
22
|
+
<option value="debug">Debug</option>
|
|
23
|
+
<option value="trace">Trace</option>
|
|
43
24
|
</select>
|
|
44
25
|
</div>
|
|
45
26
|
|
|
@@ -47,63 +28,37 @@
|
|
|
47
28
|
<NBadge n="slate xs">
|
|
48
29
|
{{ filteredLogs.length }}
|
|
49
30
|
</NBadge>
|
|
50
|
-
<NButton
|
|
51
|
-
n="xs red"
|
|
52
|
-
icon="carbon:trash-can"
|
|
53
|
-
@click="clearLogs"
|
|
54
|
-
>
|
|
55
|
-
Clear
|
|
56
|
-
</NButton>
|
|
31
|
+
<NButton n="xs red" icon="carbon:trash-can" @click="clearLogs"> Clear </NButton>
|
|
57
32
|
</div>
|
|
58
33
|
</div>
|
|
59
34
|
|
|
60
35
|
<!-- Logs Table -->
|
|
61
36
|
<div class="flex-1 overflow-auto">
|
|
62
|
-
<div
|
|
63
|
-
|
|
64
|
-
class="text-center py-12"
|
|
65
|
-
>
|
|
66
|
-
<div class="text-gray-500 dark:text-gray-400 text-sm">
|
|
67
|
-
No logs found
|
|
68
|
-
</div>
|
|
37
|
+
<div v-if="filteredLogs.length === 0" class="text-center py-12">
|
|
38
|
+
<div class="text-gray-500 dark:text-gray-400 text-sm">No logs found</div>
|
|
69
39
|
</div>
|
|
70
40
|
|
|
71
|
-
<table
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<thead class="sticky top-0 bg-gray-50 dark:bg-neutral-900 border-b border-gray-200 dark:border-neutral-700 z-10">
|
|
41
|
+
<table v-else class="w-full">
|
|
42
|
+
<thead
|
|
43
|
+
class="sticky top-0 bg-gray-50 dark:bg-neutral-900 border-b border-gray-200 dark:border-neutral-700 z-10"
|
|
44
|
+
>
|
|
76
45
|
<tr>
|
|
77
46
|
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-8" />
|
|
78
|
-
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-32">
|
|
79
|
-
|
|
80
|
-
</th>
|
|
81
|
-
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400
|
|
82
|
-
Source
|
|
83
|
-
</th>
|
|
84
|
-
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-20">
|
|
85
|
-
Level
|
|
86
|
-
</th>
|
|
87
|
-
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400">
|
|
88
|
-
Message
|
|
89
|
-
</th>
|
|
47
|
+
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-32">Time</th>
|
|
48
|
+
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-20">Source</th>
|
|
49
|
+
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-20">Level</th>
|
|
50
|
+
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400">Message</th>
|
|
90
51
|
<th class="px-2 py-1.5 text-left text-xs font-medium text-gray-500 dark:text-gray-400 w-16" />
|
|
91
52
|
</tr>
|
|
92
53
|
</thead>
|
|
93
54
|
<tbody>
|
|
94
|
-
<template
|
|
95
|
-
v-for="log in filteredLogs"
|
|
96
|
-
:key="log.key"
|
|
97
|
-
>
|
|
55
|
+
<template v-for="log in filteredLogs" :key="log.key">
|
|
98
56
|
<tr
|
|
99
57
|
class="log-entry hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors cursor-pointer border-b border-b-gray-100 dark:border-b-neutral-800"
|
|
100
58
|
@click="toggleExpand(log.key)"
|
|
101
59
|
>
|
|
102
60
|
<td class="px-2 py-1.5">
|
|
103
|
-
<div
|
|
104
|
-
class="w-1.5 h-1.5 rounded-full"
|
|
105
|
-
:class="getLogDotClass(log)"
|
|
106
|
-
/>
|
|
61
|
+
<div class="w-1.5 h-1.5 rounded-full" :class="getLogDotClass(log)" />
|
|
107
62
|
</td>
|
|
108
63
|
<td class="px-2 py-1.5">
|
|
109
64
|
<span class="text-xs font-mono text-gray-600 dark:text-gray-400">
|
|
@@ -116,9 +71,7 @@
|
|
|
116
71
|
</div>
|
|
117
72
|
</td>
|
|
118
73
|
<td class="px-2 py-1.5">
|
|
119
|
-
<NBadge
|
|
120
|
-
:n="`${getLogBadgeColor(log)} xs`"
|
|
121
|
-
>
|
|
74
|
+
<NBadge :n="`${getLogBadgeColor(log)} xs`">
|
|
122
75
|
{{ getLogType(log) }}
|
|
123
76
|
</NBadge>
|
|
124
77
|
</td>
|
|
@@ -135,24 +88,17 @@
|
|
|
135
88
|
/>
|
|
136
89
|
</td>
|
|
137
90
|
</tr>
|
|
138
|
-
<tr
|
|
139
|
-
v-if="expandedLogs.has(log.key) && hasExtraData(log)"
|
|
140
|
-
class="bg-gray-50 dark:bg-neutral-900/50"
|
|
141
|
-
>
|
|
91
|
+
<tr v-if="expandedLogs.has(log.key) && hasExtraData(log)" class="bg-gray-50 dark:bg-neutral-900/50">
|
|
142
92
|
<td colspan="12">
|
|
143
93
|
<div class="px-10 py-2">
|
|
144
94
|
<div class="inline-flex items-center gap-2 mb-2">
|
|
145
|
-
<NIcon
|
|
146
|
-
n="sm"
|
|
147
|
-
icon="carbon:object"
|
|
148
|
-
/>
|
|
95
|
+
<NIcon n="sm" icon="carbon:object" />
|
|
149
96
|
<span class="text-xs text-gray-600 dark:text-gray-400">JSON</span>
|
|
150
97
|
</div>
|
|
151
|
-
<div
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
/>
|
|
98
|
+
<div
|
|
99
|
+
class="bg-white dark:bg-neutral-800 p-3 rounded border border-gray-200 dark:border-neutral-700 overflow-x-auto"
|
|
100
|
+
>
|
|
101
|
+
<div class="json-code-block text-xs" v-html="highlightedJson.get(log.key) ?? ''" />
|
|
156
102
|
</div>
|
|
157
103
|
</div>
|
|
158
104
|
</td>
|
|
@@ -211,17 +157,13 @@ const fuse = computed(() => {
|
|
|
211
157
|
const filteredLogs = computed(() => {
|
|
212
158
|
let filtered = logs.value || [];
|
|
213
159
|
if (selectedLevel.value !== "all") {
|
|
214
|
-
filtered = filtered.filter(
|
|
215
|
-
(log) => log.value?.type === selectedLevel.value
|
|
216
|
-
);
|
|
160
|
+
filtered = filtered.filter((log) => log.value?.type === selectedLevel.value);
|
|
217
161
|
}
|
|
218
162
|
if (searchQuery.value && fuse.value) {
|
|
219
163
|
const searchResults = fuse.value.search(searchQuery.value);
|
|
220
164
|
const searchedItems = searchResults.map((result) => result.item);
|
|
221
165
|
if (selectedLevel.value !== "all") {
|
|
222
|
-
filtered = filtered.filter(
|
|
223
|
-
(log) => searchedItems.some((item) => item.key === log.key)
|
|
224
|
-
);
|
|
166
|
+
filtered = filtered.filter((log) => searchedItems.some((item) => item.key === log.key));
|
|
225
167
|
} else {
|
|
226
168
|
filtered = searchedItems;
|
|
227
169
|
}
|
|
@@ -237,14 +179,14 @@ async function toggleExpand(key) {
|
|
|
237
179
|
const log = logs.value.find((l) => l.key === key);
|
|
238
180
|
if (log) {
|
|
239
181
|
const jsonStr = formatExtraData(log);
|
|
240
|
-
const html = await codeToHtml(jsonStr, {
|
|
182
|
+
const html = await codeToHtml(jsonStr || '""', {
|
|
241
183
|
lang: "json",
|
|
242
184
|
themes: {
|
|
243
185
|
light: "catppuccin-latte",
|
|
244
186
|
dark: "catppuccin-frappe"
|
|
245
187
|
}
|
|
246
188
|
});
|
|
247
|
-
highlightedJson.value.set(key, html);
|
|
189
|
+
highlightedJson.value.set(key, typeof html === "string" ? html : "");
|
|
248
190
|
}
|
|
249
191
|
}
|
|
250
192
|
}
|
|
@@ -254,14 +196,18 @@ function getLogMessage(log) {
|
|
|
254
196
|
return String(log.value.args[0] || "Empty log message");
|
|
255
197
|
}
|
|
256
198
|
function getLogSource(log) {
|
|
257
|
-
|
|
199
|
+
const context = log.value?.args[2];
|
|
200
|
+
return context?.name ?? "";
|
|
258
201
|
}
|
|
259
202
|
function hasExtraData(log) {
|
|
260
203
|
return !!(log.value?.args && log.value.args.length > 2 && log.value.args[1] && !(typeof log.value.args[1] === "object" && log.value.args[1] !== null && Object.keys(log.value.args[1]).length === 0));
|
|
261
204
|
}
|
|
262
205
|
function formatExtraData(log) {
|
|
263
206
|
if (!log.value?.args || log.value.args.length <= 1) return "";
|
|
264
|
-
|
|
207
|
+
const data = log.value.args[1];
|
|
208
|
+
if (data === void 0 || data === null) return "";
|
|
209
|
+
const str = JSON.stringify(data, null, 2);
|
|
210
|
+
return typeof str === "string" ? str : "";
|
|
265
211
|
}
|
|
266
212
|
function getSearchableExtraData(log) {
|
|
267
213
|
if (!log.value?.args || log.value.args.length <= 1) return "";
|
|
@@ -293,7 +239,8 @@ function getLogDotClass(log) {
|
|
|
293
239
|
error: "bg-red-500",
|
|
294
240
|
warn: "bg-yellow-500",
|
|
295
241
|
info: "bg-blue-500",
|
|
296
|
-
debug: "bg-gray-400"
|
|
242
|
+
debug: "bg-gray-400",
|
|
243
|
+
trace: "bg-gray-300 dark:bg-gray-500"
|
|
297
244
|
};
|
|
298
245
|
return classes[type] || classes.info;
|
|
299
246
|
}
|
|
@@ -303,7 +250,8 @@ function getLogBadgeColor(log) {
|
|
|
303
250
|
error: "red",
|
|
304
251
|
warn: "yellow",
|
|
305
252
|
info: "blue",
|
|
306
|
-
debug: "gray"
|
|
253
|
+
debug: "gray",
|
|
254
|
+
trace: "slate"
|
|
307
255
|
};
|
|
308
256
|
return colors[type] || colors.info;
|
|
309
257
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
2
|
declare const _default: typeof __VLS_export;
|
|
3
3
|
export default _default;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
2
|
declare const _default: typeof __VLS_export;
|
|
3
3
|
export default _default;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
2
|
declare const _default: typeof __VLS_export;
|
|
3
3
|
export default _default;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
2
|
declare const _default: typeof __VLS_export;
|
|
3
3
|
export default _default;
|
|
@@ -1,32 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
border="t"
|
|
4
|
-
border-color="gray-100"
|
|
5
|
-
relative
|
|
6
|
-
n-bg="base"
|
|
7
|
-
flex="~ col"
|
|
8
|
-
h="screen"
|
|
9
|
-
>
|
|
2
|
+
<div border="t" border-color="gray-100" relative n-bg="base" flex="~ col" h="screen">
|
|
10
3
|
<div flex="~ col gap-2">
|
|
11
|
-
<NSectionBlock
|
|
12
|
-
|
|
13
|
-
text="Data Flow"
|
|
14
|
-
>
|
|
15
|
-
<div
|
|
16
|
-
grid="~ cols-6 gap-4"
|
|
17
|
-
mb="4"
|
|
18
|
-
>
|
|
4
|
+
<NSectionBlock icon="carbon:data-share" text="Data Flow">
|
|
5
|
+
<div grid="~ cols-6 gap-4" mb="4">
|
|
19
6
|
<!-- Download Progress -->
|
|
20
7
|
<div flex="~ col gap-2">
|
|
21
8
|
<span text="sm gray-500">Download Progress</span>
|
|
22
9
|
<div flex="~ items-center gap-2">
|
|
23
10
|
<template v-if="downloadProgressDetails !== null">
|
|
24
|
-
<div
|
|
25
|
-
flex="1"
|
|
26
|
-
bg="gray-200"
|
|
27
|
-
rounded="full"
|
|
28
|
-
h="2"
|
|
29
|
-
>
|
|
11
|
+
<div flex="1" bg="gray-200" rounded="full" h="2">
|
|
30
12
|
<div
|
|
31
13
|
bg="blue-600"
|
|
32
14
|
h="2"
|
|
@@ -38,10 +20,7 @@
|
|
|
38
20
|
}"
|
|
39
21
|
/>
|
|
40
22
|
</div>
|
|
41
|
-
<span
|
|
42
|
-
text="sm"
|
|
43
|
-
font="medium"
|
|
44
|
-
>{{ totalDownloadProgress }}%</span>
|
|
23
|
+
<span text="sm" font="medium">{{ totalDownloadProgress }}%</span>
|
|
45
24
|
</template>
|
|
46
25
|
<template v-else>
|
|
47
26
|
<span text="sm gray-400">No active download</span>
|
|
@@ -54,50 +33,29 @@
|
|
|
54
33
|
<span text="sm gray-500">Status</span>
|
|
55
34
|
<NBadge
|
|
56
35
|
:n="downloadError ? 'red' : 'green'"
|
|
57
|
-
:icon="
|
|
58
|
-
downloadError ? 'carbon:warning-filled' : 'carbon:checkmark-filled'
|
|
59
|
-
"
|
|
36
|
+
:icon="downloadError ? 'carbon:warning-filled' : 'carbon:checkmark-filled'"
|
|
60
37
|
>
|
|
61
38
|
{{ downloadError ? "Error" : "Healthy" }}
|
|
62
39
|
</NBadge>
|
|
63
40
|
</div>
|
|
64
41
|
|
|
65
42
|
<!-- Error Details -->
|
|
66
|
-
<div
|
|
67
|
-
flex="~ col gap-2"
|
|
68
|
-
col="span-4"
|
|
69
|
-
>
|
|
43
|
+
<div flex="~ col gap-2" col="span-4">
|
|
70
44
|
<span text="sm gray-500">Error Message</span>
|
|
71
|
-
<NBadge
|
|
72
|
-
v-if="downloadError"
|
|
73
|
-
n="red sm"
|
|
74
|
-
icon="carbon:warning-filled"
|
|
75
|
-
>
|
|
45
|
+
<NBadge v-if="downloadError" n="red sm" icon="carbon:warning-filled">
|
|
76
46
|
{{ downloadError.message }}
|
|
77
47
|
</NBadge>
|
|
78
|
-
<NBadge
|
|
79
|
-
v-else
|
|
80
|
-
n="slate sm"
|
|
81
|
-
icon="carbon:checkmark-filled"
|
|
82
|
-
>
|
|
83
|
-
N/A
|
|
84
|
-
</NBadge>
|
|
48
|
+
<NBadge v-else n="slate sm" icon="carbon:checkmark-filled"> N/A </NBadge>
|
|
85
49
|
</div>
|
|
86
50
|
</div>
|
|
87
51
|
|
|
88
|
-
<div
|
|
89
|
-
grid="~ cols-6 gap-4"
|
|
90
|
-
mb="4"
|
|
91
|
-
>
|
|
52
|
+
<div grid="~ cols-6 gap-4" mb="4">
|
|
92
53
|
<!-- Upload Progress -->
|
|
93
54
|
<div flex="~ col gap-2">
|
|
94
55
|
<span text="sm gray-500">Upload Progress</span>
|
|
95
56
|
<div flex="~ items-center gap-2">
|
|
96
57
|
<span v-if="syncStatus?.dataFlowStatus.uploading">upload in progress...</span>
|
|
97
|
-
<span
|
|
98
|
-
v-else
|
|
99
|
-
text="sm gray-400"
|
|
100
|
-
>No active upload</span>
|
|
58
|
+
<span v-else text="sm gray-400">No active upload</span>
|
|
101
59
|
</div>
|
|
102
60
|
</div>
|
|
103
61
|
|
|
@@ -106,9 +64,7 @@
|
|
|
106
64
|
<span text="sm gray-500">Status</span>
|
|
107
65
|
<NBadge
|
|
108
66
|
:n="uploadError ? 'red' : 'green'"
|
|
109
|
-
:icon="
|
|
110
|
-
uploadError ? 'carbon:warning-filled' : 'carbon:checkmark-filled'
|
|
111
|
-
"
|
|
67
|
+
:icon="uploadError ? 'carbon:warning-filled' : 'carbon:checkmark-filled'"
|
|
112
68
|
>
|
|
113
69
|
{{ uploadError ? "Error" : "Healthy" }}
|
|
114
70
|
</NBadge>
|
|
@@ -127,133 +83,43 @@
|
|
|
127
83
|
</div>
|
|
128
84
|
|
|
129
85
|
<!-- Error Details -->
|
|
130
|
-
<div
|
|
131
|
-
flex="~ col gap-2"
|
|
132
|
-
col="span-2"
|
|
133
|
-
>
|
|
86
|
+
<div flex="~ col gap-2" col="span-2">
|
|
134
87
|
<span text="sm gray-500">Error Message</span>
|
|
135
|
-
<NBadge
|
|
136
|
-
v-if="uploadError"
|
|
137
|
-
n="red sm"
|
|
138
|
-
icon="carbon:warning-filled"
|
|
139
|
-
>
|
|
88
|
+
<NBadge v-if="uploadError" n="red sm" icon="carbon:warning-filled">
|
|
140
89
|
{{ uploadError.message }}
|
|
141
90
|
</NBadge>
|
|
142
|
-
<NBadge
|
|
143
|
-
v-else
|
|
144
|
-
n="slate sm"
|
|
145
|
-
icon="carbon:checkmark-filled"
|
|
146
|
-
>
|
|
147
|
-
N/A
|
|
148
|
-
</NBadge>
|
|
91
|
+
<NBadge v-else n="slate sm" icon="carbon:checkmark-filled"> N/A </NBadge>
|
|
149
92
|
</div>
|
|
150
93
|
</div>
|
|
151
94
|
</NSectionBlock>
|
|
152
95
|
|
|
153
|
-
<span
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
>
|
|
167
|
-
Make sure to extend your schema with the diagnostics schema using the
|
|
168
|
-
`diagnosticsSchema` from the `usePowerSyncInspector` composable.
|
|
169
|
-
</NTip>
|
|
170
|
-
<div
|
|
171
|
-
v-else
|
|
172
|
-
grid="~ cols-5 gap-4"
|
|
173
|
-
mb="4"
|
|
174
|
-
>
|
|
175
|
-
<div flex="~ col gap-2">
|
|
176
|
-
<span text="sm gray-500">Buckets Synced</span>
|
|
177
|
-
<span text="sm"> {{ totals?.buckets }} </span>
|
|
178
|
-
</div>
|
|
179
|
-
|
|
180
|
-
<div flex="~ col gap-2">
|
|
181
|
-
<span text="sm gray-500">Rows Synced</span>
|
|
182
|
-
<span text="sm"> {{ totals?.row_count }} </span>
|
|
183
|
-
</div>
|
|
184
|
-
|
|
185
|
-
<div flex="~ col gap-2">
|
|
186
|
-
<span text="sm gray-500">Data size</span>
|
|
187
|
-
<span text="sm">
|
|
188
|
-
{{ totals?.data_size }}
|
|
189
|
-
</span>
|
|
190
|
-
</div>
|
|
191
|
-
|
|
192
|
-
<div flex="~ col gap-2">
|
|
193
|
-
<span text="sm gray-500">Metadata size</span>
|
|
194
|
-
<span text="sm">
|
|
195
|
-
{{ totals?.metadata_size }}
|
|
196
|
-
</span>
|
|
197
|
-
</div>
|
|
198
|
-
|
|
199
|
-
<div flex="~ col gap-2">
|
|
200
|
-
<span text="sm gray-500">Download size</span>
|
|
201
|
-
<span text="sm">
|
|
202
|
-
{{ totals?.download_size }}
|
|
203
|
-
</span>
|
|
204
|
-
</div>
|
|
205
|
-
</div>
|
|
206
|
-
</NSectionBlock>
|
|
207
|
-
|
|
208
|
-
<span
|
|
209
|
-
border="b"
|
|
210
|
-
border-color="gray-100"
|
|
211
|
-
/>
|
|
212
|
-
|
|
213
|
-
<NSectionBlock
|
|
214
|
-
icon="carbon:data-share"
|
|
215
|
-
text="Operations"
|
|
216
|
-
>
|
|
217
|
-
<NTip
|
|
218
|
-
v-if="!isDiagnosticSchemaSetup"
|
|
219
|
-
n="red6 dark:red5"
|
|
220
|
-
icon="carbon:warning-alt"
|
|
221
|
-
>
|
|
222
|
-
Make sure to extend your schema with the diagnostics schema using the
|
|
223
|
-
`diagnosticsSchema` from the `usePowerSyncInspector` composable.
|
|
224
|
-
</NTip>
|
|
225
|
-
<div
|
|
226
|
-
v-else
|
|
227
|
-
grid="~ cols-2 gap-4"
|
|
228
|
-
mb="4"
|
|
229
|
-
>
|
|
230
|
-
<div flex="~ col gap-2">
|
|
231
|
-
<span text="sm gray-500">Total operations</span>
|
|
232
|
-
<span text="sm">
|
|
233
|
-
{{ totals?.total_operations }}
|
|
234
|
-
</span>
|
|
96
|
+
<span border="b" border-color="gray-100" />
|
|
97
|
+
|
|
98
|
+
<template v-for="(section, index) in metricSections" :key="section.text">
|
|
99
|
+
<NSectionBlock :icon="section.icon" :text="section.text">
|
|
100
|
+
<NTip v-if="!isDiagnosticSchemaSetup" n="red6 dark:red5" icon="carbon:warning-alt">
|
|
101
|
+
Make sure to extend your schema with the diagnostics schema using the `diagnosticsSchema` from the
|
|
102
|
+
`usePowerSyncInspector` composable.
|
|
103
|
+
</NTip>
|
|
104
|
+
<div v-else :grid="`~ cols-${section.cols} gap-4`" mb="4">
|
|
105
|
+
<div v-for="metric in section.metrics" :key="metric.label" flex="~ col gap-2">
|
|
106
|
+
<span text="sm gray-500">{{ metric.label }}</span>
|
|
107
|
+
<span text="sm">{{ metric.value }}</span>
|
|
108
|
+
</div>
|
|
235
109
|
</div>
|
|
110
|
+
</NSectionBlock>
|
|
236
111
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
<span text="sm">
|
|
240
|
-
{{ totals?.downloaded_operations }}
|
|
241
|
-
</span>
|
|
242
|
-
</div>
|
|
243
|
-
</div>
|
|
244
|
-
</NSectionBlock>
|
|
112
|
+
<span v-if="index < metricSections.length - 1" border="b" border-color="gray-100" />
|
|
113
|
+
</template>
|
|
245
114
|
|
|
246
|
-
<span
|
|
247
|
-
border="b"
|
|
248
|
-
border-color="gray-100"
|
|
249
|
-
/>
|
|
115
|
+
<span border="b" border-color="gray-100" />
|
|
250
116
|
</div>
|
|
251
117
|
</div>
|
|
252
118
|
</template>
|
|
253
119
|
|
|
254
120
|
<script setup>
|
|
255
121
|
import { usePowerSyncInspectorDiagnostics } from "#imports";
|
|
256
|
-
import { onMounted } from "vue";
|
|
122
|
+
import { computed, onMounted } from "vue";
|
|
257
123
|
const {
|
|
258
124
|
db,
|
|
259
125
|
isDiagnosticSchemaSetup,
|
|
@@ -266,7 +132,30 @@ const {
|
|
|
266
132
|
uploadQueueSize,
|
|
267
133
|
totals
|
|
268
134
|
} = usePowerSyncInspectorDiagnostics();
|
|
135
|
+
const metricSections = computed(() => [
|
|
136
|
+
{
|
|
137
|
+
icon: "carbon:data-volume",
|
|
138
|
+
text: "Data Size",
|
|
139
|
+
cols: 5,
|
|
140
|
+
metrics: [
|
|
141
|
+
{ label: "Buckets Synced", value: totals.value?.buckets },
|
|
142
|
+
{ label: "Rows Synced", value: totals.value?.row_count },
|
|
143
|
+
{ label: "Data size", value: totals.value?.data_size },
|
|
144
|
+
{ label: "Metadata size", value: totals.value?.metadata_size },
|
|
145
|
+
{ label: "Download size", value: totals.value?.download_size }
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
icon: "carbon:data-share",
|
|
150
|
+
text: "Operations",
|
|
151
|
+
cols: 2,
|
|
152
|
+
metrics: [
|
|
153
|
+
{ label: "Total operations", value: totals.value?.total_operations },
|
|
154
|
+
{ label: "Downloaded operations", value: totals.value?.downloaded_operations }
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
]);
|
|
269
158
|
onMounted(async () => {
|
|
270
|
-
await db
|
|
159
|
+
await db?.value?.waitForFirstSync();
|
|
271
160
|
});
|
|
272
161
|
</script>
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
2
|
declare const _default: typeof __VLS_export;
|
|
3
3
|
export default _default;
|
|
@@ -21,7 +21,7 @@ import { type ILogHandler } from '@powersync/web';
|
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export declare const useDiagnosticsLogger: (customHandler?: ILogHandler) => {
|
|
24
|
-
logger: import("
|
|
24
|
+
logger: import("@powersync/common").GlobalLogger;
|
|
25
25
|
logsStorage: import("unstorage").Storage<import("unstorage").StorageValue>;
|
|
26
26
|
emitter: import("mitt").Emitter<Record<import("mitt").EventType, unknown>>;
|
|
27
27
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createBaseLogger, LogLevel } from "@powersync/web";
|
|
2
|
-
import { createConsola } from "consola";
|
|
3
2
|
import { createStorage } from "unstorage";
|
|
4
3
|
import localStorageDriver from "unstorage/drivers/session-storage";
|
|
5
4
|
import mitt from "mitt";
|
|
@@ -7,34 +6,27 @@ const emitter = mitt();
|
|
|
7
6
|
const logsStorage = createStorage({
|
|
8
7
|
driver: localStorageDriver({ base: "powersync:" })
|
|
9
8
|
});
|
|
10
|
-
const consola = createConsola({
|
|
11
|
-
level: 5,
|
|
12
|
-
// trace
|
|
13
|
-
fancy: true,
|
|
14
|
-
formatOptions: {
|
|
15
|
-
columns: 80,
|
|
16
|
-
colors: true,
|
|
17
|
-
compact: false,
|
|
18
|
-
date: true
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
consola.addReporter({
|
|
22
|
-
log: async (logObject) => {
|
|
23
|
-
const key = `log:${logObject.date.toISOString()}`;
|
|
24
|
-
await logsStorage.set(key, logObject);
|
|
25
|
-
emitter.emit("log", { key, value: logObject });
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
9
|
export const useDiagnosticsLogger = (customHandler) => {
|
|
29
10
|
const logger = createBaseLogger();
|
|
30
|
-
logger.
|
|
11
|
+
const consoleHandler = logger.createDefaultHandler({
|
|
12
|
+
formatter: (messages, context) => {
|
|
13
|
+
messages.unshift(`[PowerSync]${context.name ? ` [${context.name}]` : ""}`);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
31
16
|
logger.setLevel(LogLevel.DEBUG);
|
|
32
17
|
logger.setHandler(async (messages, context) => {
|
|
33
|
-
|
|
18
|
+
consoleHandler(messages, context);
|
|
34
19
|
const messageArray = Array.from(messages);
|
|
35
|
-
const mainMessage = String(messageArray[0]
|
|
36
|
-
const
|
|
37
|
-
|
|
20
|
+
const mainMessage = String(messageArray[0] ?? "Empty log message");
|
|
21
|
+
const extra = messageArray.length > 1 ? messageArray.length === 2 ? messageArray[1] : messageArray.slice(1) : void 0;
|
|
22
|
+
const logObject = {
|
|
23
|
+
date: /* @__PURE__ */ new Date(),
|
|
24
|
+
type: context.level.name.toLowerCase(),
|
|
25
|
+
args: [mainMessage, extra, context]
|
|
26
|
+
};
|
|
27
|
+
const key = `log:${logObject.date.toISOString()}`;
|
|
28
|
+
await logsStorage.set(key, logObject);
|
|
29
|
+
emitter.emit("log", { key, value: logObject });
|
|
38
30
|
await customHandler?.(messages, context);
|
|
39
31
|
});
|
|
40
32
|
return { logger, logsStorage, emitter };
|