flexdesk 0.1.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.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/THIRD_PARTY_LICENSES.md +53 -0
- package/css/base.css +3439 -0
- package/css/flexdesk.css +5797 -0
- package/css/overrides.css +2349 -0
- package/css/reset.css +46 -0
- package/css/tokens.css +137 -0
- package/dist/charts.js +780 -0
- package/dist/charts.js.map +7 -0
- package/dist/chunk-3PHCPZHT.js +222 -0
- package/dist/chunk-3PHCPZHT.js.map +7 -0
- package/dist/chunk-CT4YXXLP.js +1770 -0
- package/dist/chunk-CT4YXXLP.js.map +7 -0
- package/dist/chunk-DRYCDMEG.js +2217 -0
- package/dist/chunk-DRYCDMEG.js.map +7 -0
- package/dist/chunk-DVU44T77.js +855 -0
- package/dist/chunk-DVU44T77.js.map +7 -0
- package/dist/chunk-FL5KFNQH.js +640 -0
- package/dist/chunk-FL5KFNQH.js.map +7 -0
- package/dist/chunk-FOOS3T5L.js +117 -0
- package/dist/chunk-FOOS3T5L.js.map +7 -0
- package/dist/chunk-JYWURG5T.js +32 -0
- package/dist/chunk-JYWURG5T.js.map +7 -0
- package/dist/chunk-TLZUUFOE.js +276 -0
- package/dist/chunk-TLZUUFOE.js.map +7 -0
- package/dist/chunk-UCJ2WD4D.js +625 -0
- package/dist/chunk-UCJ2WD4D.js.map +7 -0
- package/dist/chunk-WVFGV5FT.js +205 -0
- package/dist/chunk-WVFGV5FT.js.map +7 -0
- package/dist/core.js +1098 -0
- package/dist/core.js.map +7 -0
- package/dist/editor.js +1661 -0
- package/dist/editor.js.map +7 -0
- package/dist/flexdesk.css +5797 -0
- package/dist/host.js +132 -0
- package/dist/host.js.map +7 -0
- package/dist/reset.css +46 -0
- package/dist/tile_registry-6WZPTUZV.js +28 -0
- package/dist/tile_registry-6WZPTUZV.js.map +7 -0
- package/dist/tiles.js +2068 -0
- package/dist/tiles.js.map +7 -0
- package/dist/tokens.css +137 -0
- package/dist/widgets.js +5438 -0
- package/dist/widgets.js.map +7 -0
- package/dist/wm.js +4830 -0
- package/dist/wm.js.map +7 -0
- package/package.json +80 -0
- package/src/charts/chart_types.js +699 -0
- package/src/charts/data_series_plot_window.js +761 -0
- package/src/charts/downsample.js +119 -0
- package/src/charts/plot_config.js +176 -0
- package/src/charts/plot_popout_window.js +1560 -0
- package/src/charts/plotly_wrapper.js +432 -0
- package/src/core/event_bus.js +230 -0
- package/src/core/logging.js +300 -0
- package/src/core/settings.js +813 -0
- package/src/core/state_guard.js +382 -0
- package/src/core/state_guard_config.js +309 -0
- package/src/core/state_machine.js +258 -0
- package/src/editor/editor_pane.js +264 -0
- package/src/editor/monaco_editor_factory.js +449 -0
- package/src/editor/monaco_loader.js +74 -0
- package/src/editor/notebook_search.js +460 -0
- package/src/editor/notebook_tab_bar.js +456 -0
- package/src/editor/notebook_undo_manager.js +108 -0
- package/src/editor/split_pane_container.js +197 -0
- package/src/help/help_modal.js +409 -0
- package/src/help/help_registry.js +65 -0
- package/src/host/host.js +69 -0
- package/src/host/pywebview_host.js +133 -0
- package/src/tiles/config_schema.js +256 -0
- package/src/tiles/layout_persistence.js +662 -0
- package/src/tiles/tile_base.js +785 -0
- package/src/tiles/tile_grid.js +905 -0
- package/src/tiles/tile_registry.js +136 -0
- package/src/tiling/command_palette.js +328 -0
- package/src/tiling/content_registry.js +110 -0
- package/src/tiling/desktops.js +133 -0
- package/src/tiling/entity_sources.js +179 -0
- package/src/tiling/keymap.js +156 -0
- package/src/tiling/kind_taxonomy.js +172 -0
- package/src/tiling/landing_table.js +717 -0
- package/src/tiling/loading_overlay.js +33 -0
- package/src/tiling/nav_panel.js +142 -0
- package/src/tiling/page_factory.js +215 -0
- package/src/tiling/panel_keys.js +145 -0
- package/src/tiling/shell.js +437 -0
- package/src/tiling/tile_breadcrumb.js +222 -0
- package/src/tiling/tile_renderer.js +459 -0
- package/src/tiling/tile_tab_menu.js +340 -0
- package/src/tiling/tile_tree.js +880 -0
- package/src/tiling/wm.js +1352 -0
- package/src/ui/base/component_base.js +30 -0
- package/src/ui/base/controller_base.js +48 -0
- package/src/ui/base/page_base.js +102 -0
- package/src/ui/components/about_dialog.js +224 -0
- package/src/ui/components/action_dropdown.js +389 -0
- package/src/ui/components/attribute_list_editor.js +652 -0
- package/src/ui/components/autocomplete_field.js +732 -0
- package/src/ui/components/computing_status_window.js +81 -0
- package/src/ui/components/confirm_dialog.js +307 -0
- package/src/ui/components/context_menu.js +87 -0
- package/src/ui/components/data_table.js +2228 -0
- package/src/ui/components/detail_header.js +177 -0
- package/src/ui/components/drag_reorder.js +0 -0
- package/src/ui/components/gallery_picker.js +147 -0
- package/src/ui/components/inline_renamer.js +129 -0
- package/src/ui/components/managed_window.js +804 -0
- package/src/ui/components/modal.js +512 -0
- package/src/ui/components/notification_history.js +264 -0
- package/src/ui/components/slide_out_panel.js +185 -0
- package/src/ui/components/slider_field.js +122 -0
- package/src/ui/components/sortable_list.js +309 -0
- package/src/ui/components/table_state_store.js +81 -0
- package/src/ui/components/toast.js +59 -0
- package/src/ui/components/tree_view.js +460 -0
- package/src/ui/components/window_taskbar.js +143 -0
- package/src/ui/controllers/panel_state_machine.js +634 -0
- package/src/ui/controllers/window_chrome_controller.js +659 -0
- package/src/ui/notification_center.js +576 -0
- package/src/ui/utils/overlay_scrollbar.js +492 -0
- package/src/ui/utils/raf_resize_observer.js +31 -0
- package/src/ui/utils/tooltip_service.js +406 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging + Telemetry Hub (js_new)
|
|
3
|
+
*
|
|
4
|
+
* Purpose
|
|
5
|
+
* -------
|
|
6
|
+
* Single sink for structured logs, metrics, and telemetry forwarding from all modules.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities
|
|
9
|
+
* - Normalize log payloads (level, namespace, metadata) before dispatching to host.
|
|
10
|
+
* - Publish `log:*` events for in-app diagnostics dashboards.
|
|
11
|
+
* - Replace scattered console/notify usage with a deterministic API.
|
|
12
|
+
*
|
|
13
|
+
* Source Material
|
|
14
|
+
* - html/js/logger.js (log formatting + transports).
|
|
15
|
+
* - html/js/debug_utils.js (runtime diagnostics + indicators).
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const LEVELS = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];
|
|
20
|
+
const LEVEL_INDEX = new Map(LEVELS.map((level, idx) => [level, idx]));
|
|
21
|
+
|
|
22
|
+
const DEFAULT_NAMESPACE = 'app';
|
|
23
|
+
|
|
24
|
+
// Quiet mode level - only warn and above during simulation
|
|
25
|
+
const QUIET_MODE_LEVEL = 'warn';
|
|
26
|
+
|
|
27
|
+
export class LoggingService {
|
|
28
|
+
constructor({
|
|
29
|
+
name = 'ecosim',
|
|
30
|
+
eventBus = null,
|
|
31
|
+
minLevel = 'info',
|
|
32
|
+
historyLimit = 500,
|
|
33
|
+
transports = [],
|
|
34
|
+
enableConsole = false,
|
|
35
|
+
namespaceLevels = null,
|
|
36
|
+
} = {}) {
|
|
37
|
+
this.name = name;
|
|
38
|
+
this.eventBus = eventBus;
|
|
39
|
+
this.historyLimit = historyLimit;
|
|
40
|
+
this.entries = [];
|
|
41
|
+
this.sequence = 0;
|
|
42
|
+
this.transports = new Set();
|
|
43
|
+
this.namespaceLevels = { ...(namespaceLevels || {}) };
|
|
44
|
+
this._quietMode = false;
|
|
45
|
+
this._savedLevel = null;
|
|
46
|
+
this.setLevel(minLevel);
|
|
47
|
+
|
|
48
|
+
transports.forEach((transport) => this.addTransport(transport));
|
|
49
|
+
if (enableConsole) {
|
|
50
|
+
this.addTransport(this._consoleTransport.bind(this));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
setLevel(level) {
|
|
55
|
+
const normalized = this._normalizeLevel(level);
|
|
56
|
+
this.minLevel = normalized;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getLevel() {
|
|
60
|
+
return this.minLevel;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Enter quiet mode - suppresses DEBUG/INFO logs during simulation.
|
|
65
|
+
* Only WARNING and above are logged.
|
|
66
|
+
*/
|
|
67
|
+
enterQuietMode() {
|
|
68
|
+
if (this._quietMode) return;
|
|
69
|
+
this._quietMode = true;
|
|
70
|
+
this._savedLevel = this.minLevel;
|
|
71
|
+
if (LEVEL_INDEX.get(this.minLevel) < LEVEL_INDEX.get(QUIET_MODE_LEVEL)) {
|
|
72
|
+
this.minLevel = QUIET_MODE_LEVEL;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Exit quiet mode - restores previous log level.
|
|
78
|
+
*/
|
|
79
|
+
exitQuietMode() {
|
|
80
|
+
if (!this._quietMode) return;
|
|
81
|
+
this._quietMode = false;
|
|
82
|
+
if (this._savedLevel !== null) {
|
|
83
|
+
this.minLevel = this._savedLevel;
|
|
84
|
+
this._savedLevel = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if quiet mode is active.
|
|
90
|
+
*/
|
|
91
|
+
isQuietMode() {
|
|
92
|
+
return this._quietMode;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setNamespaceLevel(namespace, level) {
|
|
96
|
+
if (!namespace) return;
|
|
97
|
+
this.namespaceLevels[namespace] = this._normalizeLevel(level);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setNamespaceLevels(map) {
|
|
101
|
+
if (!map || typeof map !== 'object') return;
|
|
102
|
+
Object.entries(map).forEach(([ns, lvl]) => {
|
|
103
|
+
if (ns) {
|
|
104
|
+
this.namespaceLevels[ns] = this._normalizeLevel(lvl);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
getNamespaceLevel(namespace) {
|
|
110
|
+
if (!namespace) return undefined;
|
|
111
|
+
return this.namespaceLevels[namespace];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
addTransport(transport) {
|
|
115
|
+
if (typeof transport !== 'function') {
|
|
116
|
+
throw new TypeError('Logging transport must be a function');
|
|
117
|
+
}
|
|
118
|
+
this.transports.add(transport);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
removeTransport(transport) {
|
|
122
|
+
this.transports.delete(transport);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
log(level, message, metadata = null, options = {}) {
|
|
126
|
+
const normalizedLevel = this._normalizeLevel(level);
|
|
127
|
+
const namespace = options.namespace || DEFAULT_NAMESPACE;
|
|
128
|
+
if (!this._shouldLog(normalizedLevel, namespace)) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const entry = this._buildEntry(normalizedLevel, message, metadata, options);
|
|
133
|
+
this._recordHistory(entry);
|
|
134
|
+
this._emit(entry);
|
|
135
|
+
this._dispatch(entry);
|
|
136
|
+
return entry;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
trace(message, metadata, options) {
|
|
140
|
+
return this.log('trace', message, metadata, options);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
debug(message, metadata, options) {
|
|
144
|
+
return this.log('debug', message, metadata, options);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
info(message, metadata, options) {
|
|
148
|
+
return this.log('info', message, metadata, options);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
warn(message, metadata, options) {
|
|
152
|
+
return this.log('warn', message, metadata, options);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
error(message, metadata, options) {
|
|
156
|
+
return this.log('error', message, metadata, options);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
fatal(message, metadata, options) {
|
|
160
|
+
return this.log('fatal', message, metadata, options);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
scoped(namespace) {
|
|
164
|
+
const ns = namespace || DEFAULT_NAMESPACE;
|
|
165
|
+
// Codebase convention: callers pass (subcategory, message, meta?) where
|
|
166
|
+
// subcategory is a short kebab-case tag and message is the human-readable
|
|
167
|
+
// string. Detect this pattern (two leading string args) and use the second
|
|
168
|
+
// string as the log message, discarding the subcategory (the scoped
|
|
169
|
+
// namespace already provides sufficient context).
|
|
170
|
+
// Also supports the standard (message, meta?) single-string form.
|
|
171
|
+
const make = (level) => (first, second, third) => {
|
|
172
|
+
if (typeof second === 'string') {
|
|
173
|
+
return this.log(level, second, third ?? null, { namespace: ns });
|
|
174
|
+
}
|
|
175
|
+
return this.log(level, first, second ?? null, { namespace: ns });
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
trace: make('trace'),
|
|
179
|
+
debug: make('debug'),
|
|
180
|
+
info: make('info'),
|
|
181
|
+
warn: make('warn'),
|
|
182
|
+
error: make('error'),
|
|
183
|
+
fatal: make('fatal'),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
getHistory() {
|
|
188
|
+
return [...this.entries];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
clearHistory() {
|
|
192
|
+
this.entries.length = 0;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
_normalizeLevel(level) {
|
|
196
|
+
const normalized = typeof level === 'string' ? level.toLowerCase() : '';
|
|
197
|
+
if (!LEVEL_INDEX.has(normalized)) {
|
|
198
|
+
throw new Error(`Unknown log level "${level}"`);
|
|
199
|
+
}
|
|
200
|
+
return normalized;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
_shouldLog(level, namespace) {
|
|
204
|
+
const effectiveLevel = this._resolveEffectiveLevel(namespace);
|
|
205
|
+
return LEVEL_INDEX.get(level) >= LEVEL_INDEX.get(effectiveLevel);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
_resolveEffectiveLevel(namespace) {
|
|
209
|
+
if (namespace && this.namespaceLevels?.[namespace]) {
|
|
210
|
+
return this.namespaceLevels[namespace];
|
|
211
|
+
}
|
|
212
|
+
return this.minLevel;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
_buildEntry(level, message, metadata, options) {
|
|
216
|
+
const namespace = options.namespace || DEFAULT_NAMESPACE;
|
|
217
|
+
const tags = options.tags || [];
|
|
218
|
+
const context = options.context || null;
|
|
219
|
+
const data = this._sanitizeMetadata(metadata);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
id: ++this.sequence,
|
|
223
|
+
timestamp: Date.now(),
|
|
224
|
+
service: this.name,
|
|
225
|
+
level,
|
|
226
|
+
namespace,
|
|
227
|
+
message,
|
|
228
|
+
data,
|
|
229
|
+
tags,
|
|
230
|
+
context,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
_sanitizeMetadata(metadata) {
|
|
235
|
+
if (!metadata) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
if (metadata instanceof Error) {
|
|
239
|
+
return this._errorToObject(metadata);
|
|
240
|
+
}
|
|
241
|
+
if (typeof metadata === 'object') {
|
|
242
|
+
const clone = { ...metadata };
|
|
243
|
+
if (metadata.error instanceof Error) {
|
|
244
|
+
clone.error = this._errorToObject(metadata.error);
|
|
245
|
+
}
|
|
246
|
+
return clone;
|
|
247
|
+
}
|
|
248
|
+
return { value: metadata };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
_errorToObject(error) {
|
|
252
|
+
return {
|
|
253
|
+
name: error.name,
|
|
254
|
+
message: error.message,
|
|
255
|
+
stack: error.stack,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
_recordHistory(entry) {
|
|
260
|
+
this.entries.push(entry);
|
|
261
|
+
if (this.entries.length > this.historyLimit) {
|
|
262
|
+
this.entries.shift();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
_emit(entry) {
|
|
267
|
+
if (!this.eventBus) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
try {
|
|
271
|
+
this.eventBus.emit('log:entry', entry);
|
|
272
|
+
} catch (err) {
|
|
273
|
+
this._consoleTransport({ ...entry, level: 'warn', message: `Failed to emit log entry: ${err.message}` });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
_dispatch(entry) {
|
|
278
|
+
for (const transport of this.transports) {
|
|
279
|
+
try {
|
|
280
|
+
transport(entry);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
this._consoleTransport({
|
|
283
|
+
...entry,
|
|
284
|
+
level: 'warn',
|
|
285
|
+
namespace: 'logging',
|
|
286
|
+
message: `Logging transport failed: ${err.message}`,
|
|
287
|
+
data: { transportError: this._errorToObject(err) },
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
_consoleTransport(entry) {
|
|
294
|
+
const prefix = `[${entry.service}][${entry.namespace}]`;
|
|
295
|
+
const method = (entry.level === 'trace' || entry.level === 'debug')
|
|
296
|
+
? console.log // eslint-disable-line no-console
|
|
297
|
+
: (console[entry.level] || console.log); // eslint-disable-line no-console
|
|
298
|
+
method(`${prefix} ${entry.message}`, entry.data ?? ''); // eslint-disable-line no-console
|
|
299
|
+
}
|
|
300
|
+
}
|