@ytspar/devbar 1.0.0-canary.bf42899 → 1.0.0-canary.c511f13
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/dist/GlobalDevBar.d.ts +34 -0
- package/dist/GlobalDevBar.js +506 -93
- package/dist/constants.d.ts +30 -20
- package/dist/constants.js +37 -27
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7 -7
- package/dist/outline.js +43 -10
- package/dist/presets.d.ts +1 -1
- package/dist/schema.js +4 -3
- package/dist/settings.d.ts +150 -0
- package/dist/settings.js +292 -0
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +2 -2
- package/dist/ui/modals.d.ts +4 -0
- package/dist/ui/modals.js +53 -7
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
package/dist/settings.js
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DevBar Settings Persistence
|
|
3
|
+
*
|
|
4
|
+
* Handles saving and loading DevBar settings with Sweetlink server persistence
|
|
5
|
+
* and localStorage fallback.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Default Settings
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/** Default accent color (emerald) */
|
|
11
|
+
export const DEFAULT_ACCENT_COLOR = '#10b981';
|
|
12
|
+
/** Preset accent colors for the color picker */
|
|
13
|
+
export const ACCENT_COLOR_PRESETS = [
|
|
14
|
+
{ name: 'Emerald', value: '#10b981' },
|
|
15
|
+
{ name: 'Blue', value: '#3b82f6' },
|
|
16
|
+
{ name: 'Purple', value: '#a855f7' },
|
|
17
|
+
{ name: 'Pink', value: '#ec4899' },
|
|
18
|
+
{ name: 'Amber', value: '#f59e0b' },
|
|
19
|
+
{ name: 'Cyan', value: '#06b6d4' },
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Default settings used when no saved settings exist
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_SETTINGS = {
|
|
25
|
+
version: 1,
|
|
26
|
+
// Display
|
|
27
|
+
position: 'bottom-left',
|
|
28
|
+
themeMode: 'system',
|
|
29
|
+
compactMode: false,
|
|
30
|
+
accentColor: DEFAULT_ACCENT_COLOR,
|
|
31
|
+
// Features
|
|
32
|
+
showScreenshot: true,
|
|
33
|
+
showConsoleBadges: true,
|
|
34
|
+
showTooltips: true,
|
|
35
|
+
// Metrics visibility
|
|
36
|
+
showMetrics: {
|
|
37
|
+
breakpoint: true,
|
|
38
|
+
fcp: true,
|
|
39
|
+
lcp: true,
|
|
40
|
+
cls: true,
|
|
41
|
+
inp: true,
|
|
42
|
+
pageSize: true,
|
|
43
|
+
},
|
|
44
|
+
// Debug
|
|
45
|
+
debug: false,
|
|
46
|
+
};
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Storage Keys
|
|
49
|
+
// ============================================================================
|
|
50
|
+
/** LocalStorage key for DevBar settings fallback */
|
|
51
|
+
export const SETTINGS_STORAGE_KEY = 'devbar-settings';
|
|
52
|
+
/**
|
|
53
|
+
* SettingsManager handles loading and saving DevBar settings.
|
|
54
|
+
*
|
|
55
|
+
* Storage priority:
|
|
56
|
+
* 1. Sweetlink server (.devbar/settings.json) when connected
|
|
57
|
+
* 2. localStorage fallback when disconnected
|
|
58
|
+
*
|
|
59
|
+
* Settings are always saved to localStorage as a backup, ensuring
|
|
60
|
+
* settings persist even when Sweetlink is unavailable.
|
|
61
|
+
*/
|
|
62
|
+
export class SettingsManager {
|
|
63
|
+
constructor() {
|
|
64
|
+
this.ws = null;
|
|
65
|
+
this.sweetlinkConnected = false;
|
|
66
|
+
this.changeCallbacks = [];
|
|
67
|
+
this.saveTimeout = null;
|
|
68
|
+
this.pendingLoadResolvers = [];
|
|
69
|
+
this.settings = { ...DEFAULT_SETTINGS };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Set the WebSocket connection for Sweetlink communication
|
|
73
|
+
*/
|
|
74
|
+
setWebSocket(ws) {
|
|
75
|
+
this.ws = ws;
|
|
76
|
+
this.sweetlinkConnected = ws !== null && ws.readyState === WebSocket.OPEN;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Update connection status (called when WebSocket connects/disconnects)
|
|
80
|
+
*/
|
|
81
|
+
setConnected(connected) {
|
|
82
|
+
this.sweetlinkConnected = connected;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get current settings (synchronous)
|
|
86
|
+
*/
|
|
87
|
+
getSettings() {
|
|
88
|
+
return { ...this.settings };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get a specific setting value
|
|
92
|
+
*/
|
|
93
|
+
get(key) {
|
|
94
|
+
return this.settings[key];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Load settings from storage
|
|
98
|
+
*
|
|
99
|
+
* When Sweetlink is connected, requests settings from the server.
|
|
100
|
+
* Otherwise, loads from localStorage.
|
|
101
|
+
*/
|
|
102
|
+
async loadSettings() {
|
|
103
|
+
// Always start with localStorage to have immediate values
|
|
104
|
+
const localSettings = this.loadFromLocalStorage();
|
|
105
|
+
this.settings = localSettings;
|
|
106
|
+
// If Sweetlink is connected, request server settings
|
|
107
|
+
if (this.sweetlinkConnected && this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
108
|
+
try {
|
|
109
|
+
const serverSettings = await this.loadFromServer();
|
|
110
|
+
if (serverSettings) {
|
|
111
|
+
this.settings = serverSettings;
|
|
112
|
+
// Sync to localStorage as backup
|
|
113
|
+
this.saveToLocalStorage(this.settings);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.warn('[DevBar] Failed to load settings from server, using localStorage:', error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return this.settings;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Handle settings loaded from server (called by WebSocket message handler)
|
|
124
|
+
*/
|
|
125
|
+
handleSettingsLoaded(settings) {
|
|
126
|
+
if (settings) {
|
|
127
|
+
this.settings = this.migrateSettings(settings);
|
|
128
|
+
this.saveToLocalStorage(this.settings);
|
|
129
|
+
this.notifyChange();
|
|
130
|
+
}
|
|
131
|
+
// Resolve any pending load promises
|
|
132
|
+
const resolvers = this.pendingLoadResolvers;
|
|
133
|
+
this.pendingLoadResolvers = [];
|
|
134
|
+
for (const resolve of resolvers) {
|
|
135
|
+
resolve(this.settings);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Save settings (debounced)
|
|
140
|
+
*
|
|
141
|
+
* Saves to both Sweetlink server (if connected) and localStorage.
|
|
142
|
+
*/
|
|
143
|
+
saveSettings(partial) {
|
|
144
|
+
// Merge with current settings
|
|
145
|
+
this.settings = { ...this.settings, ...partial };
|
|
146
|
+
// Debounce saves to avoid excessive writes
|
|
147
|
+
if (this.saveTimeout) {
|
|
148
|
+
clearTimeout(this.saveTimeout);
|
|
149
|
+
}
|
|
150
|
+
this.saveTimeout = setTimeout(() => {
|
|
151
|
+
this.saveTimeout = null;
|
|
152
|
+
this.performSave();
|
|
153
|
+
}, SettingsManager.SAVE_DEBOUNCE_MS);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Save settings immediately without debouncing
|
|
157
|
+
*/
|
|
158
|
+
saveSettingsNow(partial) {
|
|
159
|
+
if (this.saveTimeout) {
|
|
160
|
+
clearTimeout(this.saveTimeout);
|
|
161
|
+
this.saveTimeout = null;
|
|
162
|
+
}
|
|
163
|
+
this.settings = { ...this.settings, ...partial };
|
|
164
|
+
this.performSave();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Reset settings to defaults
|
|
168
|
+
*/
|
|
169
|
+
resetToDefaults() {
|
|
170
|
+
this.settings = { ...DEFAULT_SETTINGS };
|
|
171
|
+
this.performSave();
|
|
172
|
+
this.notifyChange();
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Subscribe to settings changes
|
|
176
|
+
*/
|
|
177
|
+
onChange(callback) {
|
|
178
|
+
this.changeCallbacks.push(callback);
|
|
179
|
+
return () => {
|
|
180
|
+
this.changeCallbacks = this.changeCallbacks.filter((cb) => cb !== callback);
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Private Methods
|
|
185
|
+
// ============================================================================
|
|
186
|
+
performSave() {
|
|
187
|
+
// Always save to localStorage as backup
|
|
188
|
+
this.saveToLocalStorage(this.settings);
|
|
189
|
+
// Save to server if connected (saveToServer checks readyState internally)
|
|
190
|
+
if (this.sweetlinkConnected) {
|
|
191
|
+
this.saveToServer(this.settings);
|
|
192
|
+
}
|
|
193
|
+
this.notifyChange();
|
|
194
|
+
}
|
|
195
|
+
notifyChange() {
|
|
196
|
+
for (const callback of this.changeCallbacks) {
|
|
197
|
+
try {
|
|
198
|
+
callback(this.settings);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error('[DevBar] Settings change callback error:', error);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
loadFromLocalStorage() {
|
|
206
|
+
if (typeof localStorage === 'undefined') {
|
|
207
|
+
return { ...DEFAULT_SETTINGS };
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const stored = localStorage.getItem(SETTINGS_STORAGE_KEY);
|
|
211
|
+
if (!stored) {
|
|
212
|
+
return { ...DEFAULT_SETTINGS };
|
|
213
|
+
}
|
|
214
|
+
const parsed = JSON.parse(stored);
|
|
215
|
+
return this.migrateSettings(parsed);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
console.warn('[DevBar] Failed to parse localStorage settings:', error);
|
|
219
|
+
return { ...DEFAULT_SETTINGS };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
saveToLocalStorage(settings) {
|
|
223
|
+
if (typeof localStorage === 'undefined')
|
|
224
|
+
return;
|
|
225
|
+
try {
|
|
226
|
+
localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings));
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
console.warn('[DevBar] Failed to save settings to localStorage:', error);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async loadFromServer() {
|
|
233
|
+
return new Promise((resolve) => {
|
|
234
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
235
|
+
resolve(null);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Store resolver to be called when settings-loaded message arrives
|
|
239
|
+
this.pendingLoadResolvers.push(resolve);
|
|
240
|
+
// Request settings from server
|
|
241
|
+
this.ws.send(JSON.stringify({ type: 'load-settings' }));
|
|
242
|
+
// Timeout after 5 seconds
|
|
243
|
+
setTimeout(() => {
|
|
244
|
+
const index = this.pendingLoadResolvers.indexOf(resolve);
|
|
245
|
+
if (index !== -1) {
|
|
246
|
+
this.pendingLoadResolvers.splice(index, 1);
|
|
247
|
+
resolve(null);
|
|
248
|
+
}
|
|
249
|
+
}, 5000);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
saveToServer(settings) {
|
|
253
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
|
|
254
|
+
return;
|
|
255
|
+
this.ws.send(JSON.stringify({
|
|
256
|
+
type: 'save-settings',
|
|
257
|
+
data: { settings },
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Migrate settings from older versions and fill in missing defaults
|
|
262
|
+
*/
|
|
263
|
+
migrateSettings(partial) {
|
|
264
|
+
// Merge partial settings over defaults, then handle nested objects specially
|
|
265
|
+
return {
|
|
266
|
+
...DEFAULT_SETTINGS,
|
|
267
|
+
...partial,
|
|
268
|
+
// Always use current schema version
|
|
269
|
+
version: 1,
|
|
270
|
+
// Deep merge showMetrics to preserve unset defaults
|
|
271
|
+
showMetrics: {
|
|
272
|
+
...DEFAULT_SETTINGS.showMetrics,
|
|
273
|
+
...partial.showMetrics,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/** Debounce delay for saving settings (ms) */
|
|
279
|
+
SettingsManager.SAVE_DEBOUNCE_MS = 300;
|
|
280
|
+
/**
|
|
281
|
+
* Singleton settings manager instance
|
|
282
|
+
*/
|
|
283
|
+
let settingsManagerInstance = null;
|
|
284
|
+
/**
|
|
285
|
+
* Get the singleton SettingsManager instance
|
|
286
|
+
*/
|
|
287
|
+
export function getSettingsManager() {
|
|
288
|
+
if (!settingsManagerInstance) {
|
|
289
|
+
settingsManagerInstance = new SettingsManager();
|
|
290
|
+
}
|
|
291
|
+
return settingsManagerInstance;
|
|
292
|
+
}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Re-exports all UI utilities.
|
|
5
5
|
*/
|
|
6
|
+
export { createStyledButton, getButtonStyles } from './buttons.js';
|
|
6
7
|
export { createSvgIcon } from './icons.js';
|
|
7
|
-
export {
|
|
8
|
-
export { createModalOverlay, createModalBox, createModalHeader, createModalContent, createEmptyMessage, createInfoBox, type ModalConfig } from './modals.js';
|
|
8
|
+
export { createEmptyMessage, createInfoBox, createModalBox, createModalContent, createModalHeader, createModalOverlay, type ModalConfig, } from './modals.js';
|
package/dist/ui/index.js
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Re-exports all UI utilities.
|
|
5
5
|
*/
|
|
6
|
+
export { createStyledButton, getButtonStyles } from './buttons.js';
|
|
6
7
|
export { createSvgIcon } from './icons.js';
|
|
7
|
-
export {
|
|
8
|
-
export { createModalOverlay, createModalBox, createModalHeader, createModalContent, createEmptyMessage, createInfoBox } from './modals.js';
|
|
8
|
+
export { createEmptyMessage, createInfoBox, createModalBox, createModalContent, createModalHeader, createModalOverlay, } from './modals.js';
|
package/dist/ui/modals.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export interface ModalConfig {
|
|
|
13
13
|
onCopyMd: () => Promise<void>;
|
|
14
14
|
onSave?: () => void;
|
|
15
15
|
sweetlinkConnected: boolean;
|
|
16
|
+
/** Whether a save operation is in progress */
|
|
17
|
+
isSaving?: boolean;
|
|
18
|
+
/** Path where data was saved (shows confirmation) */
|
|
19
|
+
savedPath?: string | null;
|
|
16
20
|
}
|
|
17
21
|
/**
|
|
18
22
|
* Create modal overlay with click-outside-to-close behavior
|
package/dist/ui/modals.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Modal creation utilities for the DevBar UI.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { MODAL_BOX_BASE_STYLES, MODAL_OVERLAY_STYLES } from '../constants.js';
|
|
7
7
|
import { createStyledButton } from './buttons.js';
|
|
8
8
|
/**
|
|
9
9
|
* Create modal overlay with click-outside-to-close behavior
|
|
@@ -34,7 +34,7 @@ export function createModalBox(color) {
|
|
|
34
34
|
* Create modal header with title, copy/save/close buttons
|
|
35
35
|
*/
|
|
36
36
|
export function createModalHeader(config) {
|
|
37
|
-
const { color, title, onClose, onCopyMd, onSave, sweetlinkConnected } = config;
|
|
37
|
+
const { color, title, onClose, onCopyMd, onSave, sweetlinkConnected, isSaving, savedPath } = config;
|
|
38
38
|
const header = document.createElement('div');
|
|
39
39
|
Object.assign(header.style, {
|
|
40
40
|
display: 'flex',
|
|
@@ -42,6 +42,8 @@ export function createModalHeader(config) {
|
|
|
42
42
|
justifyContent: 'space-between',
|
|
43
43
|
padding: '16px 20px',
|
|
44
44
|
borderBottom: `1px solid ${color}40`,
|
|
45
|
+
flexWrap: 'wrap',
|
|
46
|
+
gap: '8px',
|
|
45
47
|
});
|
|
46
48
|
const titleEl = document.createElement('h2');
|
|
47
49
|
Object.assign(titleEl.style, {
|
|
@@ -53,14 +55,16 @@ export function createModalHeader(config) {
|
|
|
53
55
|
titleEl.textContent = title;
|
|
54
56
|
header.appendChild(titleEl);
|
|
55
57
|
const headerButtons = document.createElement('div');
|
|
56
|
-
Object.assign(headerButtons.style, { display: 'flex', gap: '10px' });
|
|
58
|
+
Object.assign(headerButtons.style, { display: 'flex', gap: '10px', alignItems: 'center' });
|
|
57
59
|
// Copy MD button
|
|
58
60
|
const copyBtn = createStyledButton({ color, text: 'Copy MD' });
|
|
59
61
|
copyBtn.onclick = async () => {
|
|
60
62
|
try {
|
|
61
63
|
await onCopyMd();
|
|
62
64
|
copyBtn.textContent = 'Copied!';
|
|
63
|
-
setTimeout(() => {
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
copyBtn.textContent = 'Copy MD';
|
|
67
|
+
}, 1500);
|
|
64
68
|
}
|
|
65
69
|
catch {
|
|
66
70
|
console.error('[GlobalDevBar] Failed to copy to clipboard');
|
|
@@ -69,8 +73,17 @@ export function createModalHeader(config) {
|
|
|
69
73
|
headerButtons.appendChild(copyBtn);
|
|
70
74
|
// Save button (if Sweetlink connected)
|
|
71
75
|
if (sweetlinkConnected && onSave) {
|
|
72
|
-
const saveBtn = createStyledButton({
|
|
73
|
-
|
|
76
|
+
const saveBtn = createStyledButton({
|
|
77
|
+
color,
|
|
78
|
+
text: isSaving ? 'Saving...' : 'Save',
|
|
79
|
+
});
|
|
80
|
+
if (isSaving) {
|
|
81
|
+
saveBtn.style.opacity = '0.6';
|
|
82
|
+
saveBtn.style.cursor = 'not-allowed';
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
saveBtn.onclick = onSave;
|
|
86
|
+
}
|
|
74
87
|
headerButtons.appendChild(saveBtn);
|
|
75
88
|
}
|
|
76
89
|
// Close button - use same padding as other buttons for consistent height
|
|
@@ -83,6 +96,39 @@ export function createModalHeader(config) {
|
|
|
83
96
|
closeBtn.onclick = onClose;
|
|
84
97
|
headerButtons.appendChild(closeBtn);
|
|
85
98
|
header.appendChild(headerButtons);
|
|
99
|
+
// Show saved path confirmation below buttons
|
|
100
|
+
if (savedPath) {
|
|
101
|
+
const savedConfirm = document.createElement('div');
|
|
102
|
+
Object.assign(savedConfirm.style, {
|
|
103
|
+
width: '100%',
|
|
104
|
+
marginTop: '4px',
|
|
105
|
+
padding: '8px 12px',
|
|
106
|
+
backgroundColor: `${color}15`,
|
|
107
|
+
border: `1px solid ${color}30`,
|
|
108
|
+
borderRadius: '6px',
|
|
109
|
+
fontSize: '0.75rem',
|
|
110
|
+
color: color,
|
|
111
|
+
display: 'flex',
|
|
112
|
+
alignItems: 'center',
|
|
113
|
+
gap: '6px',
|
|
114
|
+
});
|
|
115
|
+
// Checkmark icon
|
|
116
|
+
const checkmark = document.createElement('span');
|
|
117
|
+
checkmark.textContent = '✓';
|
|
118
|
+
Object.assign(checkmark.style, { fontWeight: '600' });
|
|
119
|
+
savedConfirm.appendChild(checkmark);
|
|
120
|
+
// Path text
|
|
121
|
+
const pathText = document.createElement('span');
|
|
122
|
+
Object.assign(pathText.style, {
|
|
123
|
+
color: '#9ca3af',
|
|
124
|
+
fontFamily: 'monospace',
|
|
125
|
+
fontSize: '0.6875rem',
|
|
126
|
+
wordBreak: 'break-all',
|
|
127
|
+
});
|
|
128
|
+
pathText.textContent = `Saved to ${savedPath}`;
|
|
129
|
+
savedConfirm.appendChild(pathText);
|
|
130
|
+
header.appendChild(savedConfirm);
|
|
131
|
+
}
|
|
86
132
|
return header;
|
|
87
133
|
}
|
|
88
134
|
/**
|
|
@@ -138,7 +184,7 @@ export function createInfoBox(color, title, content) {
|
|
|
138
184
|
box.appendChild(textEl);
|
|
139
185
|
}
|
|
140
186
|
else {
|
|
141
|
-
content.forEach(el => box.appendChild(el));
|
|
187
|
+
content.forEach((el) => box.appendChild(el));
|
|
142
188
|
}
|
|
143
189
|
return box;
|
|
144
190
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
* that would break browser/test environments.
|
|
9
9
|
*/
|
|
10
10
|
export { formatArg, formatArgs } from '@ytspar/sweetlink/browser/consoleCapture';
|
|
11
|
-
export { canvasToDataUrl,
|
|
11
|
+
export { canvasToDataUrl, copyCanvasToClipboard, delay, prepareForCapture, } from '@ytspar/sweetlink/browser/screenshotUtils';
|
package/dist/utils.js
CHANGED
|
@@ -10,4 +10,4 @@
|
|
|
10
10
|
// Re-export console formatting utilities from sweetlink's browser module
|
|
11
11
|
export { formatArg, formatArgs } from '@ytspar/sweetlink/browser/consoleCapture';
|
|
12
12
|
// Re-export screenshot utilities from sweetlink's browser module
|
|
13
|
-
export { canvasToDataUrl,
|
|
13
|
+
export { canvasToDataUrl, copyCanvasToClipboard, delay, prepareForCapture, } from '@ytspar/sweetlink/browser/screenshotUtils';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ytspar/devbar",
|
|
3
|
-
"version": "1.0.0-canary.
|
|
3
|
+
"version": "1.0.0-canary.c511f13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Development toolbar and utilities with Sweetlink integration - pure vanilla JS, no framework dependencies",
|