@floegence/floe-webapp-core 0.35.59 → 0.36.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 (62) hide show
  1. package/dist/components/deck/DeckCell.js +47 -50
  2. package/dist/components/deck/DeckContextMenu.d.ts +22 -0
  3. package/dist/components/deck/DeckContextMenu.js +73 -0
  4. package/dist/components/deck/DeckGrid.js +147 -104
  5. package/dist/components/deck/DeckTopBar.js +74 -96
  6. package/dist/components/deck/WidgetFrame.d.ts +7 -1
  7. package/dist/components/deck/WidgetFrame.js +60 -52
  8. package/dist/components/deck/index.d.ts +1 -0
  9. package/dist/components/layout/DisplayModePageShell.d.ts +8 -0
  10. package/dist/components/layout/DisplayModePageShell.js +22 -0
  11. package/dist/components/layout/DisplayModeSwitcher.d.ts +7 -0
  12. package/dist/components/layout/DisplayModeSwitcher.js +52 -0
  13. package/dist/components/layout/index.d.ts +2 -0
  14. package/dist/components/ui/InfiniteCanvas.d.ts +2 -0
  15. package/dist/components/ui/InfiniteCanvas.js +43 -37
  16. package/dist/components/workbench/WorkbenchCanvas.d.ts +29 -0
  17. package/dist/components/workbench/WorkbenchCanvas.js +83 -0
  18. package/dist/components/workbench/WorkbenchContextMenu.d.ts +24 -0
  19. package/dist/components/workbench/WorkbenchContextMenu.js +44 -0
  20. package/dist/components/workbench/WorkbenchFilterBar.d.ts +17 -0
  21. package/dist/components/workbench/WorkbenchFilterBar.js +267 -0
  22. package/dist/components/workbench/WorkbenchHud.d.ts +6 -0
  23. package/dist/components/workbench/WorkbenchHud.js +17 -0
  24. package/dist/components/workbench/WorkbenchLockButton.d.ts +6 -0
  25. package/dist/components/workbench/WorkbenchLockButton.js +49 -0
  26. package/dist/components/workbench/WorkbenchOverlay.d.ts +18 -0
  27. package/dist/components/workbench/WorkbenchOverlay.js +107 -0
  28. package/dist/components/workbench/WorkbenchSurface.d.ts +34 -0
  29. package/dist/components/workbench/WorkbenchSurface.js +200 -0
  30. package/dist/components/workbench/WorkbenchWidget.d.ts +26 -0
  31. package/dist/components/workbench/WorkbenchWidget.js +192 -0
  32. package/dist/components/workbench/index.d.ts +7 -0
  33. package/dist/components/workbench/types.d.ts +56 -0
  34. package/dist/components/workbench/types.js +11 -0
  35. package/dist/components/workbench/useWorkbenchModel.d.ts +83 -0
  36. package/dist/components/workbench/useWorkbenchModel.js +284 -0
  37. package/dist/components/workbench/widgets/CodeEditorWidget.d.ts +1 -0
  38. package/dist/components/workbench/widgets/CodeEditorWidget.js +144 -0
  39. package/dist/components/workbench/widgets/FileBrowserWidget.d.ts +1 -0
  40. package/dist/components/workbench/widgets/FileBrowserWidget.js +142 -0
  41. package/dist/components/workbench/widgets/LogViewerWidget.d.ts +1 -0
  42. package/dist/components/workbench/widgets/LogViewerWidget.js +86 -0
  43. package/dist/components/workbench/widgets/SystemMonitorWidget.d.ts +1 -0
  44. package/dist/components/workbench/widgets/SystemMonitorWidget.js +122 -0
  45. package/dist/components/workbench/widgets/TerminalWidget.d.ts +1 -0
  46. package/dist/components/workbench/widgets/TerminalWidget.js +70 -0
  47. package/dist/components/workbench/widgets/widgetRegistry.d.ts +14 -0
  48. package/dist/components/workbench/widgets/widgetRegistry.js +71 -0
  49. package/dist/components/workbench/workbenchHelpers.d.ts +26 -0
  50. package/dist/components/workbench/workbenchHelpers.js +139 -0
  51. package/dist/deck.js +14 -12
  52. package/dist/display-mode.css +70 -0
  53. package/dist/full.js +475 -468
  54. package/dist/hooks/useDeckDrag.js +15 -15
  55. package/dist/layout.js +32 -27
  56. package/dist/styles.css +1 -1
  57. package/dist/tailwind.css +2 -0
  58. package/dist/ui.css +4 -0
  59. package/dist/workbench.css +1220 -0
  60. package/dist/workbench.d.ts +1 -0
  61. package/dist/workbench.js +23 -0
  62. package/package.json +5 -1
@@ -0,0 +1,142 @@
1
+ import { insert as c, createComponent as r, template as g, memo as s, effect as h, setStyleProperty as k, delegateEvents as _ } from "solid-js/web";
2
+ import { createSignal as v, For as u } from "solid-js";
3
+ import { ChevronDown as p, ChevronRight as m, FolderOpen as x, Folder as $, FileCode as C } from "../../icons/index.js";
4
+ var F = /* @__PURE__ */ g("<button type=button class=workbench-widget-filebrowser__row><span class=workbench-widget-filebrowser__icon></span><span class=workbench-widget-filebrowser__name>"), S = /* @__PURE__ */ g("<span class=workbench-widget-filebrowser__chev>"), T = /* @__PURE__ */ g("<span class=workbench-widget-filebrowser__chev aria-hidden=true>"), j = /* @__PURE__ */ g("<div class=workbench-widget-filebrowser><div class=workbench-widget-filebrowser__toolbar><span class=workbench-widget-filebrowser__path>~/projects/floe-webapp</span></div><div class=workbench-widget-filebrowser__tree>");
5
+ const y = {
6
+ id: "root",
7
+ label: "floe-webapp",
8
+ kind: "folder",
9
+ children: [{
10
+ id: "src",
11
+ label: "src",
12
+ kind: "folder",
13
+ children: [{
14
+ id: "components",
15
+ label: "components",
16
+ kind: "folder",
17
+ children: [{
18
+ id: "app-tsx",
19
+ label: "App.tsx",
20
+ kind: "file"
21
+ }, {
22
+ id: "notes-tsx",
23
+ label: "NotesBoard.tsx",
24
+ kind: "file"
25
+ }, {
26
+ id: "workbench-tsx",
27
+ label: "WorkbenchOverlay.tsx",
28
+ kind: "file"
29
+ }]
30
+ }, {
31
+ id: "utils",
32
+ label: "utils",
33
+ kind: "folder",
34
+ children: [{
35
+ id: "animations",
36
+ label: "animations.ts",
37
+ kind: "file"
38
+ }, {
39
+ id: "cn",
40
+ label: "cn.ts",
41
+ kind: "file"
42
+ }]
43
+ }, {
44
+ id: "index",
45
+ label: "index.ts",
46
+ kind: "file"
47
+ }]
48
+ }, {
49
+ id: "public",
50
+ label: "public",
51
+ kind: "folder",
52
+ children: [{
53
+ id: "logo",
54
+ label: "logo.svg",
55
+ kind: "file"
56
+ }]
57
+ }, {
58
+ id: "pkgjson",
59
+ label: "package.json",
60
+ kind: "file"
61
+ }, {
62
+ id: "tsconfig",
63
+ label: "tsconfig.json",
64
+ kind: "file"
65
+ }]
66
+ }, f = (n) => {
67
+ const i = () => n.node.kind === "folder", o = () => n.expanded.has(n.node.id);
68
+ return [(() => {
69
+ var e = F(), d = e.firstChild, t = d.nextSibling;
70
+ return e.$$click = () => {
71
+ i() && n.onToggle(n.node.id);
72
+ }, c(e, (() => {
73
+ var l = s(() => !!i());
74
+ return () => l() ? (() => {
75
+ var a = S();
76
+ return c(a, (() => {
77
+ var b = s(() => !!o());
78
+ return () => b() ? r(p, {
79
+ class: "w-3 h-3"
80
+ }) : r(m, {
81
+ class: "w-3 h-3"
82
+ });
83
+ })()), a;
84
+ })() : T();
85
+ })(), d), c(d, (() => {
86
+ var l = s(() => !!i());
87
+ return () => l() ? s(() => !!o())() ? r(x, {
88
+ class: "w-3.5 h-3.5"
89
+ }) : r($, {
90
+ class: "w-3.5 h-3.5"
91
+ }) : r(C, {
92
+ class: "w-3.5 h-3.5"
93
+ });
94
+ })()), c(t, () => n.node.label), h((l) => {
95
+ var a = !!i(), b = !!(i() && o()), w = `${n.depth * 14 + 8}px`;
96
+ return a !== l.e && e.classList.toggle("is-folder", l.e = a), b !== l.t && e.classList.toggle("is-open", l.t = b), w !== l.a && k(e, "padding-left", l.a = w), l;
97
+ }, {
98
+ e: void 0,
99
+ t: void 0,
100
+ a: void 0
101
+ }), e;
102
+ })(), s(() => s(() => !!(i() && o() && n.node.children))() ? r(u, {
103
+ get each() {
104
+ return n.node.children;
105
+ },
106
+ children: (e) => r(f, {
107
+ node: e,
108
+ get depth() {
109
+ return n.depth + 1;
110
+ },
111
+ get expanded() {
112
+ return n.expanded;
113
+ },
114
+ get onToggle() {
115
+ return n.onToggle;
116
+ }
117
+ })
118
+ }) : null)];
119
+ };
120
+ function B() {
121
+ const [n, i] = v(/* @__PURE__ */ new Set(["root", "src", "components"])), o = (e) => {
122
+ i((d) => {
123
+ const t = new Set(d);
124
+ return t.has(e) ? t.delete(e) : t.add(e), t;
125
+ });
126
+ };
127
+ return (() => {
128
+ var e = j(), d = e.firstChild, t = d.nextSibling;
129
+ return c(t, r(f, {
130
+ node: y,
131
+ depth: 0,
132
+ get expanded() {
133
+ return n();
134
+ },
135
+ onToggle: o
136
+ })), e;
137
+ })();
138
+ }
139
+ _(["click"]);
140
+ export {
141
+ B as FileBrowserWidget
142
+ };
@@ -0,0 +1 @@
1
+ export declare function LogViewerWidget(): import("solid-js").JSX.Element;
@@ -0,0 +1,86 @@
1
+ import { insert as a, createComponent as _, effect as f, className as S, template as d } from "solid-js/web";
2
+ import { createSignal as b, onMount as $, onCleanup as k, For as y } from "solid-js";
3
+ var C = /* @__PURE__ */ d("<div class=workbench-widget-logviewer><div class=workbench-widget-logviewer__lines>"), L = /* @__PURE__ */ d("<div class=workbench-widget-logviewer__line><span class=workbench-widget-logviewer__ts></span><span></span><span class=workbench-widget-logviewer__msg>");
4
+ const i = [{
5
+ level: "info",
6
+ message: "Request GET /api/health 200 (12ms)"
7
+ }, {
8
+ level: "info",
9
+ message: "WebSocket ping/pong cycle OK (lat=38ms)"
10
+ }, {
11
+ level: "info",
12
+ message: 'Scheduled job "rotate-keys" completed'
13
+ }, {
14
+ level: "debug",
15
+ message: "Cache hit workbench:viewport -> fresh"
16
+ }, {
17
+ level: "warn",
18
+ message: "Slow query detected (234ms) on notes.topics"
19
+ }, {
20
+ level: "warn",
21
+ message: "Retry #2 for upstream call /v1/sync"
22
+ }, {
23
+ level: "error",
24
+ message: "Connection timeout on retry 3"
25
+ }, {
26
+ level: "info",
27
+ message: "Reconnected successfully after backoff"
28
+ }, {
29
+ level: "info",
30
+ message: "Applied migration 0042_user_schema"
31
+ }, {
32
+ level: "debug",
33
+ message: "GC pause 14ms (young)"
34
+ }], M = 1100, w = 10;
35
+ function p(s) {
36
+ const c = String(s.getHours()).padStart(2, "0"), g = String(s.getMinutes()).padStart(2, "0"), n = String(s.getSeconds()).padStart(2, "0");
37
+ return `${c}:${g}:${n}`;
38
+ }
39
+ function A() {
40
+ const s = (() => {
41
+ const t = /* @__PURE__ */ new Date();
42
+ return Array.from({
43
+ length: 6
44
+ }, (r, e) => {
45
+ const l = i[e * 3 % i.length], o = new Date(t.getTime() - (6 - e) * 4200);
46
+ return {
47
+ id: o.getTime() + e,
48
+ ts: p(o),
49
+ level: l.level,
50
+ message: l.message
51
+ };
52
+ });
53
+ })(), [c, g] = b(s);
54
+ let n = s.length, m;
55
+ const h = () => {
56
+ const t = i[n % i.length];
57
+ n += 1, g((r) => {
58
+ const e = [...r, {
59
+ id: n,
60
+ ts: p(/* @__PURE__ */ new Date()),
61
+ level: t.level,
62
+ message: t.message
63
+ }];
64
+ return e.length > w ? e.slice(e.length - w) : e;
65
+ });
66
+ };
67
+ return $(() => {
68
+ m = window.setInterval(h, M);
69
+ }), k(() => {
70
+ m !== void 0 && window.clearInterval(m);
71
+ }), (() => {
72
+ var t = C(), r = t.firstChild;
73
+ return a(r, _(y, {
74
+ get each() {
75
+ return c();
76
+ },
77
+ children: (e) => (() => {
78
+ var l = L(), o = l.firstChild, v = o.nextSibling, u = v.nextSibling;
79
+ return a(o, () => e.ts), a(v, () => e.level.toUpperCase()), a(u, () => e.message), f(() => S(v, `workbench-widget-logviewer__level workbench-widget-logviewer__level--${e.level}`)), l;
80
+ })()
81
+ })), t;
82
+ })();
83
+ }
84
+ export {
85
+ A as LogViewerWidget
86
+ };
@@ -0,0 +1 @@
1
+ export declare function SystemMonitorWidget(): import("solid-js").JSX.Element;
@@ -0,0 +1,122 @@
1
+ import { insert as d, createComponent as g, effect as A, className as L, setStyleProperty as N, template as b, setAttribute as S } from "solid-js/web";
2
+ import { createSignal as k, onMount as P, onCleanup as R, For as T } from "solid-js";
3
+ import { Cpu as B, Activity as E, Database as H } from "../../icons/index.js";
4
+ var K = /* @__PURE__ */ b("<div class=workbench-widget-sysmon>"), O = /* @__PURE__ */ b("<div class=workbench-widget-sysmon__row><div class=workbench-widget-sysmon__label><span></span></div><div class=workbench-widget-sysmon__bar><div></div></div><span class=workbench-widget-sysmon__value>%"), U = /* @__PURE__ */ b('<svg viewBox="0 0 72 22"width=72 height=22 preserveAspectRatio=none aria-hidden=true><path fill=none stroke=currentColor stroke-width=1.3 stroke-linejoin=round>');
5
+ const w = 28, W = 900;
6
+ function f(s, m, u, a) {
7
+ const e = (Math.random() - 0.5) * a;
8
+ return Math.min(u, Math.max(m, s + e));
9
+ }
10
+ function J() {
11
+ const s = () => Array.from({
12
+ length: w
13
+ }, () => 30 + Math.random() * 30), m = () => Array.from({
14
+ length: w
15
+ }, () => 55 + Math.random() * 18), u = () => Array.from({
16
+ length: w
17
+ }, () => 25 + Math.random() * 10), [a, e] = k({
18
+ value: 42,
19
+ history: s()
20
+ }), [l, r] = k({
21
+ value: 67,
22
+ history: m()
23
+ }), [i, o] = k({
24
+ value: 31,
25
+ history: u()
26
+ });
27
+ let c;
28
+ const I = () => {
29
+ e((n) => {
30
+ const t = f(n.value, 12, 92, 14);
31
+ return {
32
+ value: t,
33
+ history: [...n.history.slice(1), t]
34
+ };
35
+ }), r((n) => {
36
+ const t = f(n.value, 42, 88, 5);
37
+ return {
38
+ value: t,
39
+ history: [...n.history.slice(1), t]
40
+ };
41
+ }), o((n) => {
42
+ const t = f(n.value, 18, 64, 2.4);
43
+ return {
44
+ value: t,
45
+ history: [...n.history.slice(1), t]
46
+ };
47
+ });
48
+ };
49
+ P(() => {
50
+ c = window.setInterval(I, W);
51
+ }), R(() => {
52
+ c !== void 0 && window.clearInterval(c);
53
+ });
54
+ const D = [{
55
+ key: "cpu",
56
+ label: "CPU",
57
+ icon: B,
58
+ metric: a
59
+ }, {
60
+ key: "memory",
61
+ label: "Memory",
62
+ icon: E,
63
+ metric: l
64
+ }, {
65
+ key: "disk",
66
+ label: "Disk",
67
+ icon: H,
68
+ metric: i
69
+ }];
70
+ return (() => {
71
+ var n = K();
72
+ return d(n, g(T, {
73
+ each: D,
74
+ children: (t) => {
75
+ const F = t.icon;
76
+ return (() => {
77
+ var v = O(), y = v.firstChild, p = y.firstChild, _ = y.nextSibling, M = _.firstChild, $ = _.nextSibling, j = $.firstChild;
78
+ return d(y, g(F, {
79
+ class: "w-3.5 h-3.5"
80
+ }), p), d(p, () => t.label), d(v, g(Y, {
81
+ get points() {
82
+ return t.metric().history;
83
+ },
84
+ get variant() {
85
+ return t.key;
86
+ }
87
+ }), _), d($, () => Math.round(t.metric().value), j), A((h) => {
88
+ var C = `workbench-widget-sysmon__fill workbench-widget-sysmon__fill--${t.key}`, x = `${t.metric().value.toFixed(1)}%`;
89
+ return C !== h.e && L(M, h.e = C), x !== h.t && N(M, "width", h.t = x), h;
90
+ }, {
91
+ e: void 0,
92
+ t: void 0
93
+ }), v;
94
+ })();
95
+ }
96
+ })), n;
97
+ })();
98
+ }
99
+ function Y(s) {
100
+ const a = () => {
101
+ const e = s.points;
102
+ if (e.length === 0) return "";
103
+ const l = 72 / Math.max(1, e.length - 1);
104
+ return e.map((r, i) => {
105
+ const o = i * l, c = 22 - r / 100 * 22;
106
+ return `${i === 0 ? "M" : "L"}${o.toFixed(2)} ${c.toFixed(2)}`;
107
+ }).join(" ");
108
+ };
109
+ return (() => {
110
+ var e = U(), l = e.firstChild;
111
+ return A((r) => {
112
+ var i = `workbench-widget-sysmon__spark workbench-widget-sysmon__spark--${s.variant}`, o = a();
113
+ return i !== r.e && S(e, "class", r.e = i), o !== r.t && S(l, "d", r.t = o), r;
114
+ }, {
115
+ e: void 0,
116
+ t: void 0
117
+ }), e;
118
+ })();
119
+ }
120
+ export {
121
+ J as SystemMonitorWidget
122
+ };
@@ -0,0 +1 @@
1
+ export declare function TerminalWidget(): import("solid-js").JSX.Element;
@@ -0,0 +1,70 @@
1
+ import { insert as d, createComponent as x, memo as S, effect as C, template as w } from "solid-js/web";
2
+ import { createSignal as b, onMount as y, onCleanup as E, For as I } from "solid-js";
3
+ var M = /* @__PURE__ */ w('<div class=workbench-widget-terminal><div class=workbench-widget-terminal__toolbar><span class="workbench-widget-terminal__dot workbench-widget-terminal__dot--red"></span><span class="workbench-widget-terminal__dot workbench-widget-terminal__dot--yellow"></span><span class="workbench-widget-terminal__dot workbench-widget-terminal__dot--green"></span><span class=workbench-widget-terminal__path>~/projects/floe-webapp</span></div><div class=workbench-widget-terminal__body><div class=workbench-widget-terminal__line><span class=workbench-widget-terminal__prompt>$</span><span></span><span class=workbench-widget-terminal__cursor>'), N = /* @__PURE__ */ w("<div class=workbench-widget-terminal__line><span>"), A = /* @__PURE__ */ w("<span class=workbench-widget-terminal__prompt>$");
4
+ const k = [{
5
+ prompt: "pnpm dev",
6
+ outputs: ["VITE v7.3.2 ready in 342 ms", "➜ Local: http://localhost:5173/", "➜ Network: http://192.168.1.12:5173/"]
7
+ }, {
8
+ prompt: "git status",
9
+ outputs: ["On branch feat-workbench", "Changes not staged for commit:", " modified: apps/demo/src/App.tsx"]
10
+ }, {
11
+ prompt: "curl -s https://api.floe.dev/health | jq .status",
12
+ outputs: ['"ok"']
13
+ }], L = 42, f = 160, O = 1400;
14
+ function R() {
15
+ const [$, _] = b([]), [T, m] = b("");
16
+ let u = 0, s = 0, e, i = !1;
17
+ const h = () => {
18
+ if (i) return;
19
+ const t = k[u % k.length];
20
+ s = 0, m("");
21
+ const l = () => {
22
+ i || (s += 1, m(t.prompt.slice(0, s)), s < t.prompt.length ? e = window.setTimeout(l, L) : e = window.setTimeout(a, f));
23
+ }, a = () => {
24
+ if (i) return;
25
+ _((r) => [...r.slice(-6), {
26
+ id: `${Date.now()}-prompt`,
27
+ kind: "prompt",
28
+ text: t.prompt
29
+ }]), m("");
30
+ let n = 0;
31
+ const p = () => {
32
+ if (i) return;
33
+ if (n >= t.outputs.length) {
34
+ u += 1, e = window.setTimeout(h, O);
35
+ return;
36
+ }
37
+ const r = t.outputs[n];
38
+ _((o) => [...o.slice(-6), {
39
+ id: `${Date.now()}-${n}`,
40
+ kind: "muted",
41
+ text: r
42
+ }]), n += 1, e = window.setTimeout(p, f);
43
+ };
44
+ p();
45
+ };
46
+ l();
47
+ };
48
+ return y(() => {
49
+ e = window.setTimeout(h, 300);
50
+ }), E(() => {
51
+ i = !0, e !== void 0 && window.clearTimeout(e);
52
+ }), (() => {
53
+ var t = M(), l = t.firstChild, a = l.nextSibling, n = a.firstChild, p = n.firstChild, r = p.nextSibling;
54
+ return d(a, x(I, {
55
+ get each() {
56
+ return $();
57
+ },
58
+ children: (o) => (() => {
59
+ var c = N(), g = c.firstChild;
60
+ return d(c, (() => {
61
+ var v = S(() => o.kind === "prompt");
62
+ return () => v() ? A() : null;
63
+ })(), g), d(g, () => o.text), C(() => c.classList.toggle("workbench-widget-terminal__line--muted", o.kind === "muted")), c;
64
+ })()
65
+ }), n), d(r, T), t;
66
+ })();
67
+ }
68
+ export {
69
+ R as TerminalWidget
70
+ };
@@ -0,0 +1,14 @@
1
+ import type { Component } from 'solid-js';
2
+ import type { WorkbenchWidgetDefinition, WorkbenchWidgetType } from '../types';
3
+ export interface WidgetRegistryEntry extends WorkbenchWidgetDefinition {
4
+ label: string;
5
+ icon: Component<{
6
+ class?: string;
7
+ }>;
8
+ defaultTitle: string;
9
+ }
10
+ export declare const WIDGET_REGISTRY: readonly WidgetRegistryEntry[];
11
+ export declare function resolveWorkbenchWidgetDefinitions(widgetDefinitions?: readonly WorkbenchWidgetDefinition[]): readonly WorkbenchWidgetDefinition[];
12
+ export declare function createWorkbenchFilterState(widgetDefinitions?: readonly WorkbenchWidgetDefinition[], filters?: Partial<Record<WorkbenchWidgetType, boolean>>): Record<WorkbenchWidgetType, boolean>;
13
+ export declare function isValidWorkbenchWidgetType(type: unknown, widgetDefinitions?: readonly WorkbenchWidgetDefinition[]): type is WorkbenchWidgetType;
14
+ export declare function getWidgetEntry(type: WorkbenchWidgetType, widgetDefinitions?: readonly WorkbenchWidgetDefinition[]): WorkbenchWidgetDefinition;
@@ -0,0 +1,71 @@
1
+ import { Terminal as d, Folder as n, Cpu as a, Activity as f, FileCode as y } from "../../icons/index.js";
2
+ import { TerminalWidget as m } from "./TerminalWidget.js";
3
+ import { FileBrowserWidget as c } from "./FileBrowserWidget.js";
4
+ import { SystemMonitorWidget as p } from "./SystemMonitorWidget.js";
5
+ import { LogViewerWidget as u } from "./LogViewerWidget.js";
6
+ import { CodeEditorWidget as h } from "./CodeEditorWidget.js";
7
+ const g = [
8
+ {
9
+ type: "terminal",
10
+ label: "Terminal",
11
+ icon: d,
12
+ body: m,
13
+ defaultTitle: "Terminal",
14
+ defaultSize: { width: 480, height: 320 }
15
+ },
16
+ {
17
+ type: "file-browser",
18
+ label: "File Browser",
19
+ icon: n,
20
+ body: c,
21
+ defaultTitle: "File Browser",
22
+ defaultSize: { width: 360, height: 400 }
23
+ },
24
+ {
25
+ type: "system-monitor",
26
+ label: "System Monitor",
27
+ icon: a,
28
+ body: p,
29
+ defaultTitle: "System Monitor",
30
+ defaultSize: { width: 340, height: 280 }
31
+ },
32
+ {
33
+ type: "log-viewer",
34
+ label: "Log Viewer",
35
+ icon: f,
36
+ body: u,
37
+ defaultTitle: "Log Viewer",
38
+ defaultSize: { width: 500, height: 300 }
39
+ },
40
+ {
41
+ type: "code-editor",
42
+ label: "Code Editor",
43
+ icon: y,
44
+ body: h,
45
+ defaultTitle: "Code Editor",
46
+ defaultSize: { width: 520, height: 380 }
47
+ }
48
+ ];
49
+ function l(e) {
50
+ return e && e.length > 0 ? e : g;
51
+ }
52
+ function E(e, t) {
53
+ const o = l(e), i = {};
54
+ for (const r of o)
55
+ i[r.type] = typeof t?.[r.type] == "boolean" ? !!t[r.type] : !0;
56
+ return i;
57
+ }
58
+ function F(e, t) {
59
+ return typeof e == "string" && l(t).some((o) => o.type === e);
60
+ }
61
+ function v(e, t) {
62
+ const o = l(t);
63
+ return o.find((i) => i.type === e) ?? o[0];
64
+ }
65
+ export {
66
+ g as WIDGET_REGISTRY,
67
+ E as createWorkbenchFilterState,
68
+ v as getWidgetEntry,
69
+ F as isValidWorkbenchWidgetType,
70
+ l as resolveWorkbenchWidgetDefinitions
71
+ };
@@ -0,0 +1,26 @@
1
+ import { type WorkbenchState, type WorkbenchViewport, type WorkbenchWidgetDefinition, type WorkbenchWidgetItem, type WorkbenchWidgetType } from './types';
2
+ export declare function createWorkbenchId(): string;
3
+ export declare function sanitizeViewport(viewport: Partial<WorkbenchViewport> | undefined): WorkbenchViewport;
4
+ export declare function sanitizeFilters(filters: Partial<Record<WorkbenchWidgetType, boolean>> | undefined, widgetDefinitions?: readonly WorkbenchWidgetDefinition[]): Record<WorkbenchWidgetType, boolean>;
5
+ export interface SanitizeWorkbenchStateOptions {
6
+ widgetDefinitions?: readonly WorkbenchWidgetDefinition[];
7
+ createFallbackState?: () => WorkbenchState;
8
+ }
9
+ export declare function sanitizeWorkbenchState(input: unknown, options?: SanitizeWorkbenchStateOptions): WorkbenchState;
10
+ export declare function createDefaultWorkbenchState(widgetDefinitions?: readonly WorkbenchWidgetDefinition[]): WorkbenchState;
11
+ export declare const WORKBENCH_CANVAS_ZOOM_STEP = 1.18;
12
+ export declare const WORKBENCH_CONTEXT_MENU_WIDTH_PX = 200;
13
+ export declare function createContextMenuPosition(options: {
14
+ clientX: number;
15
+ clientY: number;
16
+ menuWidth: number;
17
+ menuHeight: number;
18
+ }): {
19
+ left: number;
20
+ top: number;
21
+ };
22
+ export declare function getTopZIndex(widgets: readonly WorkbenchWidgetItem[]): number;
23
+ /** Spatial navigation: find nearest widget in a direction. */
24
+ export declare function findNearestWidget(widgets: readonly WorkbenchWidgetItem[], currentId: string | null, direction: 'up' | 'down' | 'left' | 'right', filters: Record<WorkbenchWidgetType, boolean>): WorkbenchWidgetItem | null;
25
+ export declare function clampScale(scale: number, min?: number, max?: number): number;
26
+ export declare function estimateContextMenuHeight(actionCount: number, separatorCount?: number): number;
@@ -0,0 +1,139 @@
1
+ import { DEFAULT_WORKBENCH_VIEWPORT as g } from "./types.js";
2
+ import { resolveWorkbenchWidgetDefinitions as m, getWidgetEntry as x, createWorkbenchFilterState as b, isValidWorkbenchWidgetType as W } from "./widgets/widgetRegistry.js";
3
+ function F() {
4
+ const e = globalThis.crypto;
5
+ return e && typeof e.randomUUID == "function" ? `wb-${e.randomUUID()}` : `wb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
6
+ }
7
+ function M(e) {
8
+ return e ? {
9
+ x: Number.isFinite(e.x) ? e.x : 0,
10
+ y: Number.isFinite(e.y) ? e.y : 0,
11
+ scale: Number.isFinite(e.scale) && e.scale > 0 ? e.scale : 1
12
+ } : { ...g };
13
+ }
14
+ function k(e, n) {
15
+ return b(n, e);
16
+ }
17
+ function z(e, n = {}) {
18
+ const r = m(n.widgetDefinitions), a = n.createFallbackState ?? (() => N(r)), i = e;
19
+ if (!i || i.version !== 1 || !Array.isArray(i.widgets))
20
+ return a();
21
+ const s = i.widgets.filter(
22
+ (t) => !!t && typeof t.id == "string" && W(t.type, r) && typeof t.title == "string"
23
+ ).map((t) => {
24
+ const u = x(t.type, r);
25
+ return {
26
+ id: t.id,
27
+ type: t.type,
28
+ title: t.title,
29
+ x: Number.isFinite(t.x) ? t.x : 0,
30
+ y: Number.isFinite(t.y) ? t.y : 0,
31
+ width: Number.isFinite(t.width) && t.width > 0 ? t.width : u.defaultSize.width,
32
+ height: Number.isFinite(t.height) && t.height > 0 ? t.height : u.defaultSize.height,
33
+ z_index: Number.isFinite(t.z_index) && t.z_index >= 0 ? t.z_index : 1,
34
+ created_at_unix_ms: Number.isFinite(t.created_at_unix_ms) ? t.created_at_unix_ms : Date.now()
35
+ };
36
+ }), c = typeof i.selectedWidgetId == "string" && s.some((t) => t.id === i.selectedWidgetId) ? i.selectedWidgetId : null;
37
+ return {
38
+ version: 1,
39
+ widgets: s,
40
+ viewport: M(i.viewport),
41
+ locked: typeof i.locked == "boolean" ? i.locked : !1,
42
+ filters: k(i.filters, r),
43
+ selectedWidgetId: c
44
+ };
45
+ }
46
+ function N(e) {
47
+ const n = m(e), r = Date.now(), a = [
48
+ { type: "terminal", title: "dev · terminal", x: 80, y: 80 },
49
+ { type: "file-browser", title: "project · files", x: 600, y: 80 },
50
+ { type: "system-monitor", title: "host · system monitor", x: 80, y: 420 },
51
+ { type: "log-viewer", title: "services · logs", x: 540, y: 500 },
52
+ { type: "code-editor", title: "Counter.tsx", x: 1e3, y: 180 }
53
+ ], i = a.filter((s) => n.some((c) => c.type === s.type)).map((s, c) => {
54
+ const t = x(s.type, n);
55
+ return {
56
+ id: `wb-seed-${c + 1}`,
57
+ type: s.type,
58
+ title: s.title,
59
+ x: s.x,
60
+ y: s.y,
61
+ width: t.defaultSize.width,
62
+ height: t.defaultSize.height,
63
+ z_index: c + 1,
64
+ created_at_unix_ms: r - (a.length - c) * 6e5
65
+ };
66
+ });
67
+ return {
68
+ version: 1,
69
+ widgets: i,
70
+ viewport: { ...g },
71
+ locked: !1,
72
+ filters: b(n),
73
+ selectedWidgetId: i[0]?.id ?? null
74
+ };
75
+ }
76
+ const D = 1.18, I = 200;
77
+ function E(e) {
78
+ const n = typeof window < "u" ? window.innerWidth : 1280, r = typeof window < "u" ? window.innerHeight : 800;
79
+ let a = e.clientX, i = e.clientY;
80
+ return a + e.menuWidth > n && (a = Math.max(0, n - e.menuWidth - 8)), i + e.menuHeight > r && (i = Math.max(0, r - e.menuHeight - 8)), { left: a, top: i };
81
+ }
82
+ function H(e) {
83
+ return e.reduce((n, r) => Math.max(n, r.z_index), 1);
84
+ }
85
+ function T(e, n, r, a) {
86
+ const i = e.filter((o) => a[o.type]);
87
+ if (i.length === 0) return null;
88
+ if (!n) return i[0] ?? null;
89
+ const s = i.find((o) => o.id === n);
90
+ if (!s) return i[0] ?? null;
91
+ const c = s.x + s.width / 2, t = s.y + s.height / 2;
92
+ let u = null, f = 1 / 0;
93
+ for (const o of i) {
94
+ if (o.id === n) continue;
95
+ const d = o.x + o.width / 2 - c, l = o.y + o.height / 2 - t;
96
+ let h = !1;
97
+ switch (r) {
98
+ case "up":
99
+ h = l < -10;
100
+ break;
101
+ case "down":
102
+ h = l > 10;
103
+ break;
104
+ case "left":
105
+ h = d < -10;
106
+ break;
107
+ case "right":
108
+ h = d > 10;
109
+ break;
110
+ }
111
+ if (!h) continue;
112
+ const p = Math.sqrt(d * d + l * l), _ = Math.atan2(
113
+ Math.abs(r === "up" || r === "down" ? d : l),
114
+ Math.abs(r === "up" || r === "down" ? l : d)
115
+ ), y = p * (1 + _ * 1.5);
116
+ y < f && (f = y, u = o);
117
+ }
118
+ return u;
119
+ }
120
+ function C(e, n = 0.45, r = 2.2) {
121
+ return Math.max(n, Math.min(r, e));
122
+ }
123
+ function O(e, n = 0) {
124
+ return 16 + Math.max(1, e) * 32 + Math.max(0, n) * 9;
125
+ }
126
+ export {
127
+ D as WORKBENCH_CANVAS_ZOOM_STEP,
128
+ I as WORKBENCH_CONTEXT_MENU_WIDTH_PX,
129
+ C as clampScale,
130
+ E as createContextMenuPosition,
131
+ N as createDefaultWorkbenchState,
132
+ F as createWorkbenchId,
133
+ O as estimateContextMenuHeight,
134
+ T as findNearestWidget,
135
+ H as getTopZIndex,
136
+ k as sanitizeFilters,
137
+ M as sanitizeViewport,
138
+ z as sanitizeWorkbenchState
139
+ };