@telepath-computer/television 0.1.8 → 0.1.9
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/browser/assets/index-BEMTFjJ-.js +394 -0
- package/dist/browser/assets/index-CmOTsDN-.css +1 -0
- package/dist/browser/index.html +2 -2
- package/dist/cli.cjs +376 -59
- package/dist/electron.cjs +376 -59
- package/package.json +5 -3
- package/dist/browser/assets/index-C3ygXWMh.js +0 -396
- package/dist/browser/assets/index-nGpvLl78.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
artifact-view{background:var(--color-bg-muted);border:1px solid var(--color-border);border-radius:10px;box-sizing:border-box;width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.artifact-title-bar{display:flex;align-items:center;height:34px;padding:0 12px;flex-shrink:0;border-bottom:1px solid var(--color-border);-webkit-user-select:none;user-select:none}.artifact-title{flex:1;font-size:13px;font-weight:500;color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.artifact-close-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:6px;background:transparent;color:var(--color-text-muted);cursor:pointer;flex-shrink:0}.artifact-close-btn:hover{background:var(--color-interactive);color:var(--color-text)}.artifact-content{flex:1;min-height:0;overflow:hidden;padding:0}.artifact-html-frame{pointer-events:none}layout-view{width:100%;flex:1;min-width:0;min-height:0;display:flex;align-items:flex-start;overflow:hidden;outline:none;position:relative;--layout-unit-x: 120px;--layout-unit-y: 120px;--layout-gap: 16px;--layout-drag-transition-ms: 0ms;--color-drag-target: color-mix( in srgb, var(--color-border, var(--neutral-300, #cbd5e1)) 55%, transparent );--shadow-drag-card: 0 24px 48px color-mix(in srgb, var(--neutral-900, #0f172a) 28%, transparent)}layout-view .track{display:flex;align-items:start;gap:var(--layout-gap);flex-shrink:0;width:max-content;will-change:transform;transition:transform .2s ease}layout-view .node{display:grid;grid-template-columns:repeat(4,var(--layout-unit-x));grid-template-rows:repeat(6,var(--layout-unit-y));gap:var(--layout-gap);align-self:start;width:calc(var(--layout-unit-x) * 4 + var(--layout-gap) * 3);will-change:transform}layout-view .card-slot{border-radius:12px;box-sizing:border-box;cursor:default;min-width:0;min-height:0;position:relative;z-index:1}layout-view .card-slot artifact-view{width:100%;height:100%}layout-view .card-slot[data-layout-draggable=true]{cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none}layout-view .card-placeholder{border-radius:12px;background:var(--color-drag-target);position:relative;z-index:0}layout-view .card-placeholder[data-layout-placeholder-ghost=true]{background:transparent;border:0;opacity:0;pointer-events:none}layout-view .drag-preview{position:fixed;z-index:10;pointer-events:none;filter:drop-shadow(var(--shadow-drag-card))}layout-view .drag-preview>*{width:100%;height:100%}workspace-view{width:100%;flex:1;min-width:0;min-height:0;display:flex;flex-direction:column}workspace-view [data-testid=empty-workspace]{margin:0;padding:1rem}television-app{width:100%;height:100%;display:grid;grid-template-rows:auto 1fr;grid-template-areas:"header" "main"}television-app>header{grid-area:header;position:relative;z-index:10}television-app>main{grid-area:main;grid-row:1 / -1}body.electron television-app>header{-webkit-app-region:drag;padding-left:80px;border-bottom:1px solid var(--color-border)}header{display:flex;align-items:center;justify-content:space-between;height:34px;padding:0 12px;flex-shrink:0;-webkit-user-select:none;user-select:none}television-app>header>nav{display:flex;align-items:center;gap:8px;min-width:0}workspace-picker,workspace-picker [trigger],button[variant=toolbar],.settings-server-remove-button,.settings-submit-button,.settings-cancel-button,.settings-connect-button,.settings-field input{-webkit-app-region:no-drag}workspace-picker dropdown-menu::part(panel){min-width:18rem}workspace-picker [trigger],workspace-picker [trigger][data-dropdown-trigger]{min-width:0;padding:0;border:none;background:transparent;font-size:13px;font-weight:600}workspace-picker [trigger] .trigger-label{white-space:nowrap}dropdown-group{display:block;padding:4px 0}dropdown-label{display:block;padding:0 10px 4px;font-size:12px;color:color-mix(in srgb,currentColor 60%,transparent)}dropdown-item{display:block;padding:6px 10px;border-radius:4px;cursor:pointer}dropdown-item[selected]{background:color-mix(in srgb,var(--color-border) 70%,white)}dropdown-item[action]{color:color-mix(in srgb,currentColor 50%,transparent)}dropdown-item[danger]{color:#c74343}television-app>main{min-width:0;min-height:0;overflow:hidden;display:flex;flex-direction:column}television-app>main.auth-gate{display:flex;align-items:center;justify-content:center}.settings-panel{width:min(32rem,100%);display:flex;flex-direction:column;padding:20px;border:1px solid var(--color-border);border-radius:12px;background:var(--color-bg)}.workspace-modal,.auth-modal{width:min(24rem,100%);display:flex;flex-direction:column;padding:20px;border:1px solid var(--color-border);border-radius:12px;background:var(--color-bg)}.auth-form{display:flex;flex-direction:column;gap:12px}.auth-modal-title,.auth-modal-copy{margin:0}.auth-token-input-invalid{border-color:#c74343}.workspace-form{display:flex;flex-direction:column;gap:12px}.workspace-form-actions{display:flex;gap:8px}.workspace-modal-title,.workspace-delete-copy,.workspace-delete-warning,.workspace-delete-error{margin:0}.workspace-delete-warning,.workspace-delete-error{font-size:13px}.workspace-delete-error{color:#c74343}.settings-section-title{margin:0}.settings-section,.settings-server-list,.settings-add-server-form{display:flex;flex-direction:column;gap:12px}.settings-form-actions{display:flex;gap:8px}.settings-card{padding:12px;border:1px solid var(--color-border);border-radius:8px}.settings-server{display:flex;align-items:center;justify-content:space-between;gap:12px}.settings-server-details{min-width:0}.settings-server-name{font-weight:600}.settings-server-url{font-size:13px;word-break:break-word;color:color-mix(in srgb,currentColor 70%,transparent)}.settings-server-remove-button,.settings-submit-button,.settings-cancel-button,.settings-connect-button{padding:8px 12px;border-radius:8px}.settings-field{display:flex;flex-direction:column;gap:6px}.settings-field input{width:100%;padding:8px 10px;border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg);color:inherit;font:inherit;box-sizing:border-box}.settings-submit-button,.settings-cancel-button,.settings-connect-button{align-self:flex-start}dropdown-menu{position:relative;display:inline-block;color:inherit}dropdown-group{display:grid;gap:var(--space-4)}dropdown-label{display:block;padding:var(--space-4) var(--space-8);color:var(--color-text-muted);font:inherit;font-size:var(--text-sm);font-weight:600;letter-spacing:.04em;text-transform:uppercase}dropdown-divider{display:block;height:1px;margin:var(--space-4) 0;background:var(--color-border)}[data-dropdown-trigger],dropdown-item{color:inherit;font:inherit;line-height:1.2}[data-dropdown-trigger],dropdown-menu::part(trigger){display:inline-flex;align-items:center;gap:var(--space-8);margin:0;padding:.375rem .5rem;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);box-shadow:none;cursor:pointer}[data-dropdown-trigger]:hover,dropdown-menu::part(trigger):hover{background:var(--color-interactive-hover)}dropdown-menu[open] [data-dropdown-trigger],dropdown-menu[open]::part(trigger){background:var(--color-interactive)}[data-dropdown-trigger-label],dropdown-menu::part(trigger-label){min-width:0}[data-dropdown-trigger-icon],dropdown-menu::part(trigger-icon){display:inline-flex;align-items:center;justify-content:center;flex:none}[data-dropdown-trigger]:focus-visible,dropdown-menu::part(trigger):focus-visible,dropdown-item:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:2px}dropdown-menu::part(panel){position:absolute;top:calc(100% + var(--space-4));left:0;z-index:var(--layer-popover);min-width:12rem;padding:var(--space-4);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-popover)}dropdown-item{display:block;margin:0;padding:.375rem .5rem;border-radius:var(--radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none}dropdown-item:hover{background:var(--color-interactive-hover)}dropdown-item[selected]{background:var(--color-interactive)}panel-view{display:block}panel-view::part(panel){display:flex;flex-direction:column;gap:var(--space-16);color:var(--color-text)}panel-view::part(header){display:flex;align-items:center;justify-content:space-between;gap:var(--space-12)}panel-view::part(title-group){display:flex;align-items:center;gap:var(--space-8);min-width:0}panel-view::part(title){margin:0;font:inherit;font-size:var(--text-lg);font-weight:600;color:var(--color-text)}panel-view::part(button){display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;margin:0;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text);box-shadow:none;cursor:pointer}panel-view::part(button):hover{background:var(--color-interactive-hover)}panel-view::part(button):focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:2px}panel-view::part(icon){display:inline-flex;align-items:center;justify-content:center;flex:none}panel-view::part(back-icon){transform:rotate(90deg)}modal-overlay{color:inherit}modal-overlay::part(backdrop){position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--layer-modal);display:flex;align-items:center;justify-content:center;padding:var(--space-16);background:var(--color-overlay-backdrop)}*,*:before,*:after{box-sizing:border-box}:root{--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;--font-brand: var(--font-sans);--font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;--text-base: 14px;--text-scale: 1.125;--text-sm: round(calc(var(--text-base) / var(--text-scale)), 1px);--text-lg: round(calc(var(--text-base) * var(--text-scale)), 1px);--text-xl: round(calc(var(--text-lg) * var(--text-scale)), 1px);--leading-base: 1.5;--space-2: 2px;--space-4: 4px;--space-6: 6px;--space-8: 8px;--space-12: 12px;--space-16: 16px;--space-24: 24px;--space-32: 32px;--space-48: 48px;--space-64: 64px;--radius-sm: .375rem;--radius-md: .5rem;--layer-popover: 10;--layer-modal: 1000;--shadow-popover: 0 12px 32px rgb(0 0 0 / .14);--shadow-modal: 0 24px 64px rgb(0 0 0 / .2)}html,body{margin:0;padding:0;width:100%;height:100%}body{font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--leading-base);color:var(--color-text);background:var(--color-bg)}a{text-underline-offset:.15em;text-decoration-thickness:.08em}button,input,textarea,select{font:inherit;color:inherit}a{color:var(--color-link)}h1,h2,h3,h4,h5,h6,p,ul,ol,blockquote,pre,hr{margin:0}h1,h2,h3,h4,h5,h6{font-weight:600;color:var(--color-text)}code{font-family:var(--font-mono);font-size:.9em;background:var(--color-bg-muted);padding:var(--space-2) var(--space-4);border-radius:var(--radius-sm)}pre{font-family:var(--font-mono);background:var(--color-bg-muted);padding:var(--space-12);border-radius:var(--radius-md);overflow-x:auto}pre code{background:none;padding:0}blockquote{padding-left:var(--space-16);border-left:3px solid var(--color-border);color:var(--color-text-muted)}hr{border:none;border-top:1px solid var(--color-border)}table{border-collapse:collapse}th,td{padding:var(--space-8) var(--space-12);border:1px solid var(--color-border);text-align:left}th{background:var(--color-bg-muted);font-weight:600}.prose{line-height:var(--leading-base)}.prose h1{font-size:var(--text-xl);margin-bottom:var(--space-8)}.prose h2{font-size:var(--text-lg);margin-top:var(--space-24);margin-bottom:var(--space-8)}.prose h3,.prose h4,.prose h5,.prose h6{font-size:var(--text-base);margin-top:var(--space-24);margin-bottom:var(--space-8)}.prose p{margin:var(--space-12) 0}.prose ul,.prose ol{padding-left:var(--space-24);margin:var(--space-12) 0}.prose blockquote,.prose pre{margin:var(--space-12) 0}.prose hr{margin:var(--space-24) 0}.prose table{width:100%;margin:var(--space-12) 0}.prose img{max-width:100%;height:auto}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}[data-ui-icon]{display:inline-block;vertical-align:middle}button{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-6);border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-bg);color:inherit;cursor:pointer}button:hover{background:var(--color-interactive)}button[variant=toolbar]{border:none;background:transparent;color:var(--color-text-muted)}button[size=sm]{min-height:26px;padding:var(--space-2) var(--space-6)}button[size=md]{min-height:32px;padding:var(--space-6) var(--space-12)}:root{--black: #000000;--white: #ffffff;--neutral-50: oklch(.985 .001 106.423);--neutral-100: oklch(.97 .001 106.424);--neutral-200: oklch(.923 .003 48.717);--neutral-300: oklch(.869 .005 56.366);--neutral-400: oklch(.709 .01 56.259);--neutral-500: oklch(.553 .013 58.071);--neutral-600: oklch(.444 .011 73.639);--neutral-700: oklch(.374 .01 67.558);--neutral-800: oklch(.268 .007 34.298);--neutral-900: oklch(.216 .006 56.043);--neutral-950: oklch(.147 .004 49.25)}:root{--color-bg: var(--neutral-50);--color-bg-muted: var(--neutral-100);--color-surface: var(--white);--color-surface-muted: var(--neutral-100);--color-interactive: var(--neutral-200);--color-interactive-hover: var(--neutral-300);--color-border: var(--neutral-300);--color-border-muted: var(--neutral-200);--color-text: var(--neutral-900);--color-text-muted: var(--neutral-500);--color-link: inherit;--color-focus-ring: var(--neutral-500);--color-overlay-backdrop: rgb(0 0 0 / .5);color-scheme:light}:root{--color-bg: var(--neutral-200);--color-border: var(--neutral-300)}
|
package/dist/browser/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Television</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-BEMTFjJ-.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CmOTsDN-.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body></body>
|
|
11
11
|
</html>
|
package/dist/cli.cjs
CHANGED
|
@@ -77196,13 +77196,21 @@ var Server2 = class {
|
|
|
77196
77196
|
});
|
|
77197
77197
|
}
|
|
77198
77198
|
start() {
|
|
77199
|
-
return new Promise((resolve) => {
|
|
77200
|
-
|
|
77199
|
+
return new Promise((resolve, reject) => {
|
|
77200
|
+
const handleError = (error2) => {
|
|
77201
|
+
this.httpServer.off("listening", handleListening);
|
|
77202
|
+
reject(error2);
|
|
77203
|
+
};
|
|
77204
|
+
const handleListening = () => {
|
|
77205
|
+
this.httpServer.off("error", handleError);
|
|
77201
77206
|
const address = this.httpServer.address();
|
|
77202
77207
|
const resolvedPort = typeof address === "object" && address ? address.port : this.port;
|
|
77203
77208
|
this.baseURL = buildServerURL(this.host ?? DEFAULT_SERVER_HOST, resolvedPort);
|
|
77204
77209
|
resolve(this.httpServer);
|
|
77205
|
-
}
|
|
77210
|
+
};
|
|
77211
|
+
this.httpServer.once("error", handleError);
|
|
77212
|
+
this.httpServer.once("listening", handleListening);
|
|
77213
|
+
this.httpServer.listen(this.port, this.host);
|
|
77206
77214
|
});
|
|
77207
77215
|
}
|
|
77208
77216
|
getBaseURL() {
|
|
@@ -77353,15 +77361,29 @@ function isClientMessage(value) {
|
|
|
77353
77361
|
case "create-workspace":
|
|
77354
77362
|
return typeof message.id === "string" && typeof message.name === "string";
|
|
77355
77363
|
case "update-workspace":
|
|
77356
|
-
return typeof message.workspaceID === "string" && typeof message.fields === "object" && message.fields !== null && (!("name" in message.fields) || typeof message.fields.name === "string") && (!("layout" in message.fields) || Array.isArray(message.fields.layout) && message.fields.layout.every(
|
|
77357
|
-
(card) => typeof card === "object" && card !== null && "type" in card && card.type === "artifact" && "artifactID" in card && typeof card.artifactID === "string" && "cols" in card && typeof card.cols === "number" && "rows" in card && typeof card.rows === "number"
|
|
77358
|
-
));
|
|
77364
|
+
return typeof message.workspaceID === "string" && typeof message.fields === "object" && message.fields !== null && (!("name" in message.fields) || typeof message.fields.name === "string") && (!("layout" in message.fields) || Array.isArray(message.fields.layout) && message.fields.layout.every(isLayoutNode));
|
|
77359
77365
|
case "delete-workspace":
|
|
77360
77366
|
return typeof message.workspaceID === "string";
|
|
77361
77367
|
default:
|
|
77362
77368
|
return false;
|
|
77363
77369
|
}
|
|
77364
77370
|
}
|
|
77371
|
+
function isLayoutNode(value) {
|
|
77372
|
+
if (typeof value !== "object" || value === null || !("type" in value)) {
|
|
77373
|
+
return false;
|
|
77374
|
+
}
|
|
77375
|
+
const node = value;
|
|
77376
|
+
switch (node.type) {
|
|
77377
|
+
case "card":
|
|
77378
|
+
return typeof node.id === "string" && typeof node.artifactID === "string" && (typeof node.width === "number" || node.width === "auto") && (typeof node.height === "number" || node.height === "auto");
|
|
77379
|
+
case "row":
|
|
77380
|
+
return typeof node.id === "string" && (typeof node.height === "number" || node.height === "auto") && Array.isArray(node.children) && node.children.every(isLayoutNode);
|
|
77381
|
+
case "stack":
|
|
77382
|
+
return typeof node.id === "string" && Array.isArray(node.children) && node.children.every(isLayoutNode);
|
|
77383
|
+
default:
|
|
77384
|
+
return false;
|
|
77385
|
+
}
|
|
77386
|
+
}
|
|
77365
77387
|
|
|
77366
77388
|
// node_modules/mitt/dist/mitt.mjs
|
|
77367
77389
|
function mitt_default(n) {
|
|
@@ -77413,54 +77435,324 @@ var import_node_crypto2 = require("node:crypto");
|
|
|
77413
77435
|
var import_node_fs3 = require("node:fs");
|
|
77414
77436
|
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
77415
77437
|
|
|
77438
|
+
// src/constants.ts
|
|
77439
|
+
var LAYOUT_FULL_WIDTH_UNITS = 4;
|
|
77440
|
+
var LAYOUT_FULL_HEIGHT_UNITS = 6;
|
|
77441
|
+
var MIN_LAYOUT_CARD_WIDTH_UNITS = 2;
|
|
77442
|
+
var MAX_LAYOUT_CARD_WIDTH_UNITS = LAYOUT_FULL_WIDTH_UNITS;
|
|
77443
|
+
var DEFAULT_LAYOUT_CARD_WIDTH = "auto";
|
|
77444
|
+
var DEFAULT_LAYOUT_CARD_HEIGHT = "auto";
|
|
77445
|
+
var DEFAULT_LAYOUT_UNIT = 120;
|
|
77446
|
+
var CARD_GAP = 16;
|
|
77447
|
+
var CARD_WIDTH = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_WIDTH_UNITS + CARD_GAP * (LAYOUT_FULL_WIDTH_UNITS - 1);
|
|
77448
|
+
var CARD_HEIGHT = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_HEIGHT_UNITS + CARD_GAP * (LAYOUT_FULL_HEIGHT_UNITS - 1);
|
|
77449
|
+
|
|
77416
77450
|
// src/types.ts
|
|
77417
|
-
|
|
77418
|
-
var DEFAULT_LAYOUT_CARD_ROWS = 6;
|
|
77419
|
-
var LAYOUT_COLS_NARROW = 1;
|
|
77420
|
-
var LAYOUT_ROW_SHORT = 2;
|
|
77421
|
-
var LAYOUT_ROW_MID = 3;
|
|
77422
|
-
var LAYOUT_ROW_TALL = 4;
|
|
77423
|
-
var ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
|
|
77424
|
-
var ALLOWED_ROWS = [
|
|
77425
|
-
LAYOUT_ROW_SHORT,
|
|
77426
|
-
LAYOUT_ROW_MID,
|
|
77427
|
-
LAYOUT_ROW_TALL,
|
|
77428
|
-
DEFAULT_LAYOUT_CARD_ROWS
|
|
77429
|
-
];
|
|
77430
|
-
function clampLayoutCols(cols) {
|
|
77431
|
-
const n = Math.round(cols);
|
|
77432
|
-
return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
|
|
77433
|
-
}
|
|
77434
|
-
function clampLayoutRows(rows) {
|
|
77435
|
-
const n = Math.round(rows);
|
|
77436
|
-
return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
|
|
77437
|
-
}
|
|
77438
|
-
function createLayoutCardRecord(artifactID) {
|
|
77451
|
+
function createCardNode(artifactID, overrides = {}) {
|
|
77439
77452
|
return {
|
|
77440
|
-
|
|
77453
|
+
id: overrides.id ?? ulid3(),
|
|
77454
|
+
type: "card",
|
|
77441
77455
|
artifactID,
|
|
77442
|
-
|
|
77443
|
-
|
|
77456
|
+
width: overrides.width ?? DEFAULT_LAYOUT_CARD_WIDTH,
|
|
77457
|
+
height: overrides.height ?? DEFAULT_LAYOUT_CARD_HEIGHT
|
|
77444
77458
|
};
|
|
77445
77459
|
}
|
|
77446
|
-
function
|
|
77460
|
+
function layoutContainsArtifactID(layout, artifactID) {
|
|
77461
|
+
return layout.some((node) => nodeContainsArtifactID(node, artifactID));
|
|
77462
|
+
}
|
|
77463
|
+
function nodeContainsArtifactID(node, artifactID) {
|
|
77464
|
+
switch (node.type) {
|
|
77465
|
+
case "card":
|
|
77466
|
+
return node.artifactID === artifactID;
|
|
77467
|
+
case "row":
|
|
77468
|
+
return node.children.some((child) => child.artifactID === artifactID);
|
|
77469
|
+
case "stack":
|
|
77470
|
+
return node.children.some((child) => nodeContainsArtifactID(child, artifactID));
|
|
77471
|
+
}
|
|
77472
|
+
}
|
|
77473
|
+
function getWorkspaceArtifactIDs(workspace) {
|
|
77474
|
+
return workspace.layout.flatMap(collectArtifactIDs);
|
|
77475
|
+
}
|
|
77476
|
+
function collectArtifactIDs(node) {
|
|
77477
|
+
switch (node.type) {
|
|
77478
|
+
case "card":
|
|
77479
|
+
return [node.artifactID];
|
|
77480
|
+
case "row":
|
|
77481
|
+
return node.children.map((child) => child.artifactID);
|
|
77482
|
+
case "stack":
|
|
77483
|
+
return node.children.flatMap(collectArtifactIDs);
|
|
77484
|
+
}
|
|
77485
|
+
}
|
|
77486
|
+
|
|
77487
|
+
// src/browser/ui/layout.ts
|
|
77488
|
+
var LEGACY_BAND_HEIGHT_ROWS = 6;
|
|
77489
|
+
var LEGACY_NARROW_COLS = 1;
|
|
77490
|
+
var LEGACY_FULL_COLS = 2;
|
|
77491
|
+
var LEGACY_ROW_SHORT = 2;
|
|
77492
|
+
var LEGACY_ROW_MID = 3;
|
|
77493
|
+
var LEGACY_ROW_TALL = 4;
|
|
77494
|
+
var LEGACY_ROW_FULL = 6;
|
|
77495
|
+
var LEGACY_ALLOWED_ROWS = [LEGACY_ROW_SHORT, LEGACY_ROW_MID, LEGACY_ROW_TALL, LEGACY_ROW_FULL];
|
|
77496
|
+
var LEGACY_LEFT_X = 0;
|
|
77497
|
+
var LEGACY_RIGHT_X = 1;
|
|
77498
|
+
function removeArtifactFromLayout(layout, artifactID) {
|
|
77499
|
+
return normalizeRootNodes(layout.flatMap((node) => removeArtifactFromNode(node, artifactID)));
|
|
77500
|
+
}
|
|
77501
|
+
function migrateLegacyLayout(cards) {
|
|
77502
|
+
const normalized = cards.map((card) => ({
|
|
77503
|
+
artifactID: card.artifactID,
|
|
77504
|
+
width: normalizeLegacyCols(card.width),
|
|
77505
|
+
height: normalizeLegacyRows(card.height)
|
|
77506
|
+
}));
|
|
77507
|
+
const bands = deriveLegacyBands(normalized);
|
|
77508
|
+
return normalizeRootNodes(bands.flatMap(buildNodesForLegacyBand));
|
|
77509
|
+
}
|
|
77510
|
+
function normalizeRootNodes(layout) {
|
|
77511
|
+
const normalized = [];
|
|
77512
|
+
for (const node of layout) {
|
|
77513
|
+
const entries = normalizeNode(node);
|
|
77514
|
+
for (const entry of entries) {
|
|
77515
|
+
if (entry.type === "row") {
|
|
77516
|
+
normalized.push(...entry.children.map(cloneCard));
|
|
77517
|
+
continue;
|
|
77518
|
+
}
|
|
77519
|
+
normalized.push(entry);
|
|
77520
|
+
}
|
|
77521
|
+
}
|
|
77522
|
+
return normalized;
|
|
77523
|
+
}
|
|
77524
|
+
function normalizeNode(node) {
|
|
77525
|
+
switch (node.type) {
|
|
77526
|
+
case "card":
|
|
77527
|
+
return [cloneCard(node)];
|
|
77528
|
+
case "row": {
|
|
77529
|
+
const children = node.children.map(cloneCard);
|
|
77530
|
+
if (children.length === 0) {
|
|
77531
|
+
return [];
|
|
77532
|
+
}
|
|
77533
|
+
if (children.length === 1) {
|
|
77534
|
+
return [children[0]];
|
|
77535
|
+
}
|
|
77536
|
+
return [{ ...node, children }];
|
|
77537
|
+
}
|
|
77538
|
+
case "stack": {
|
|
77539
|
+
const children = [];
|
|
77540
|
+
for (const child of node.children) {
|
|
77541
|
+
const normalizedChildren = normalizeNode(child);
|
|
77542
|
+
for (const normalizedChild of normalizedChildren) {
|
|
77543
|
+
if (normalizedChild.type === "stack") {
|
|
77544
|
+
children.push(...normalizedChild.children.map(cloneStackChild));
|
|
77545
|
+
continue;
|
|
77546
|
+
}
|
|
77547
|
+
if (normalizedChild.type === "row") {
|
|
77548
|
+
children.push({
|
|
77549
|
+
...normalizedChild,
|
|
77550
|
+
children: normalizedChild.children.map(cloneCard)
|
|
77551
|
+
});
|
|
77552
|
+
continue;
|
|
77553
|
+
}
|
|
77554
|
+
children.push(cloneCard(normalizedChild));
|
|
77555
|
+
}
|
|
77556
|
+
}
|
|
77557
|
+
if (children.length === 0) {
|
|
77558
|
+
return [];
|
|
77559
|
+
}
|
|
77560
|
+
if (children.length === 1) {
|
|
77561
|
+
return [cloneStackChild(children[0])];
|
|
77562
|
+
}
|
|
77563
|
+
return [{ ...node, children }];
|
|
77564
|
+
}
|
|
77565
|
+
}
|
|
77566
|
+
}
|
|
77567
|
+
function removeArtifactFromNode(node, artifactID) {
|
|
77568
|
+
switch (node.type) {
|
|
77569
|
+
case "card":
|
|
77570
|
+
return node.artifactID === artifactID ? [] : [cloneCard(node)];
|
|
77571
|
+
case "row": {
|
|
77572
|
+
const children = node.children.filter((child) => child.artifactID !== artifactID).map(cloneCard);
|
|
77573
|
+
if (children.length === 0) {
|
|
77574
|
+
return [];
|
|
77575
|
+
}
|
|
77576
|
+
if (children.length === 1) {
|
|
77577
|
+
return [children[0]];
|
|
77578
|
+
}
|
|
77579
|
+
return [{ ...node, children }];
|
|
77580
|
+
}
|
|
77581
|
+
case "stack": {
|
|
77582
|
+
const children = node.children.flatMap((child) => {
|
|
77583
|
+
const removed = removeArtifactFromNode(child, artifactID);
|
|
77584
|
+
return removed.filter((entry) => entry.type !== "stack");
|
|
77585
|
+
});
|
|
77586
|
+
if (children.length === 0) {
|
|
77587
|
+
return [];
|
|
77588
|
+
}
|
|
77589
|
+
if (children.length === 1) {
|
|
77590
|
+
return [cloneStackChild(children[0])];
|
|
77591
|
+
}
|
|
77592
|
+
return [{ ...node, children }];
|
|
77593
|
+
}
|
|
77594
|
+
}
|
|
77595
|
+
}
|
|
77596
|
+
function normalizeLegacyCols(width) {
|
|
77597
|
+
return Math.round(width) === LEGACY_NARROW_COLS ? LEGACY_NARROW_COLS : LEGACY_FULL_COLS;
|
|
77598
|
+
}
|
|
77599
|
+
function normalizeLegacyRows(height) {
|
|
77600
|
+
const rounded = Math.round(height);
|
|
77601
|
+
return LEGACY_ALLOWED_ROWS.includes(rounded) ? rounded : LEGACY_BAND_HEIGHT_ROWS;
|
|
77602
|
+
}
|
|
77603
|
+
function deriveLegacyBands(cards) {
|
|
77604
|
+
const bands = [];
|
|
77605
|
+
let current = null;
|
|
77606
|
+
for (const card of cards) {
|
|
77607
|
+
if (!current) {
|
|
77608
|
+
const placements = packLegacyBand([card], card.width);
|
|
77609
|
+
if (!placements) {
|
|
77610
|
+
continue;
|
|
77611
|
+
}
|
|
77612
|
+
current = {
|
|
77613
|
+
width: card.width,
|
|
77614
|
+
placements
|
|
77615
|
+
};
|
|
77616
|
+
continue;
|
|
77617
|
+
}
|
|
77618
|
+
const nextCards = current.placements.map((placement) => ({
|
|
77619
|
+
artifactID: placement.artifactID,
|
|
77620
|
+
width: placement.width,
|
|
77621
|
+
height: placement.height
|
|
77622
|
+
})).concat(card);
|
|
77623
|
+
let nextWidth = current.width;
|
|
77624
|
+
let packed = packLegacyBand(nextCards, nextWidth);
|
|
77625
|
+
if (!packed && current.width < LEGACY_FULL_COLS && card.width > current.width) {
|
|
77626
|
+
nextWidth = LEGACY_FULL_COLS;
|
|
77627
|
+
packed = packLegacyBand(nextCards, nextWidth);
|
|
77628
|
+
}
|
|
77629
|
+
if (packed) {
|
|
77630
|
+
current = {
|
|
77631
|
+
width: nextWidth,
|
|
77632
|
+
placements: packed
|
|
77633
|
+
};
|
|
77634
|
+
continue;
|
|
77635
|
+
}
|
|
77636
|
+
bands.push(current);
|
|
77637
|
+
const newPlacements = packLegacyBand([card], card.width);
|
|
77638
|
+
if (!newPlacements) {
|
|
77639
|
+
current = null;
|
|
77640
|
+
continue;
|
|
77641
|
+
}
|
|
77642
|
+
current = {
|
|
77643
|
+
width: card.width,
|
|
77644
|
+
placements: newPlacements
|
|
77645
|
+
};
|
|
77646
|
+
}
|
|
77647
|
+
if (current) {
|
|
77648
|
+
bands.push(current);
|
|
77649
|
+
}
|
|
77650
|
+
return bands;
|
|
77651
|
+
}
|
|
77652
|
+
function packLegacyBand(cards, width) {
|
|
77653
|
+
const occupied = Array.from(
|
|
77654
|
+
{ length: LEGACY_BAND_HEIGHT_ROWS },
|
|
77655
|
+
() => Array.from({ length: width }, () => false)
|
|
77656
|
+
);
|
|
77657
|
+
const placements = [];
|
|
77658
|
+
for (const card of cards) {
|
|
77659
|
+
const position = firstLegacyFit(occupied, width, card);
|
|
77660
|
+
if (!position) {
|
|
77661
|
+
return null;
|
|
77662
|
+
}
|
|
77663
|
+
const placement = {
|
|
77664
|
+
artifactID: card.artifactID,
|
|
77665
|
+
width: card.width,
|
|
77666
|
+
height: card.height,
|
|
77667
|
+
x: position.x,
|
|
77668
|
+
y: position.y
|
|
77669
|
+
};
|
|
77670
|
+
placeLegacyCard(occupied, placement);
|
|
77671
|
+
placements.push(placement);
|
|
77672
|
+
}
|
|
77673
|
+
return placements;
|
|
77674
|
+
}
|
|
77675
|
+
function firstLegacyFit(occupied, width, card) {
|
|
77676
|
+
if (card.width > width || card.height > LEGACY_BAND_HEIGHT_ROWS) {
|
|
77677
|
+
return null;
|
|
77678
|
+
}
|
|
77679
|
+
for (let y2 = 0; y2 <= LEGACY_BAND_HEIGHT_ROWS - card.height; y2 += 1) {
|
|
77680
|
+
for (let x2 = 0; x2 <= width - card.width; x2 += 1) {
|
|
77681
|
+
let fits = true;
|
|
77682
|
+
for (let yy = y2; yy < y2 + card.height && fits; yy += 1) {
|
|
77683
|
+
for (let xx = x2; xx < x2 + card.width; xx += 1) {
|
|
77684
|
+
if (occupied[yy]?.[xx]) {
|
|
77685
|
+
fits = false;
|
|
77686
|
+
break;
|
|
77687
|
+
}
|
|
77688
|
+
}
|
|
77689
|
+
}
|
|
77690
|
+
if (fits) {
|
|
77691
|
+
return { x: x2, y: y2 };
|
|
77692
|
+
}
|
|
77693
|
+
}
|
|
77694
|
+
}
|
|
77695
|
+
return null;
|
|
77696
|
+
}
|
|
77697
|
+
function placeLegacyCard(occupied, placement) {
|
|
77698
|
+
for (let yy = placement.y; yy < placement.y + placement.height; yy += 1) {
|
|
77699
|
+
for (let xx = placement.x; xx < placement.x + placement.width; xx += 1) {
|
|
77700
|
+
occupied[yy][xx] = true;
|
|
77701
|
+
}
|
|
77702
|
+
}
|
|
77703
|
+
}
|
|
77704
|
+
function buildNodesForLegacyBand(band) {
|
|
77705
|
+
const placements = [...band.placements].sort((a, b2) => a.y - b2.y || a.x - b2.x);
|
|
77706
|
+
const children = [];
|
|
77707
|
+
for (let index = 0; index < placements.length; index += 1) {
|
|
77708
|
+
const current = placements[index];
|
|
77709
|
+
const next = placements[index + 1];
|
|
77710
|
+
if (current.width === LEGACY_NARROW_COLS && next && next.width === LEGACY_NARROW_COLS && next.y === current.y && next.height === current.height && current.x === LEGACY_LEFT_X && next.x === LEGACY_RIGHT_X) {
|
|
77711
|
+
children.push({
|
|
77712
|
+
id: ulid3(),
|
|
77713
|
+
type: "row",
|
|
77714
|
+
height: current.height,
|
|
77715
|
+
children: [migrateLegacyCard(current), migrateLegacyCard(next)]
|
|
77716
|
+
});
|
|
77717
|
+
index += 1;
|
|
77718
|
+
continue;
|
|
77719
|
+
}
|
|
77720
|
+
children.push(migrateLegacyCard(current));
|
|
77721
|
+
}
|
|
77722
|
+
if (children.length === 0) {
|
|
77723
|
+
return [];
|
|
77724
|
+
}
|
|
77725
|
+
if (children.length === 1) {
|
|
77726
|
+
const child = children[0];
|
|
77727
|
+
return child.type === "row" ? child.children.map(cloneCard) : [cloneCard(child)];
|
|
77728
|
+
}
|
|
77729
|
+
return [
|
|
77730
|
+
{
|
|
77731
|
+
id: ulid3(),
|
|
77732
|
+
type: "stack",
|
|
77733
|
+
children
|
|
77734
|
+
}
|
|
77735
|
+
];
|
|
77736
|
+
}
|
|
77737
|
+
function migrateLegacyCard(card) {
|
|
77447
77738
|
return {
|
|
77448
|
-
|
|
77739
|
+
id: ulid3(),
|
|
77740
|
+
type: "card",
|
|
77449
77741
|
artifactID: card.artifactID,
|
|
77450
|
-
|
|
77451
|
-
|
|
77742
|
+
width: card.width === LEGACY_NARROW_COLS ? MIN_LAYOUT_CARD_WIDTH_UNITS : MAX_LAYOUT_CARD_WIDTH_UNITS,
|
|
77743
|
+
height: card.height
|
|
77452
77744
|
};
|
|
77453
77745
|
}
|
|
77454
|
-
function
|
|
77455
|
-
const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => sanitizeLayoutCard(card)) : [];
|
|
77746
|
+
function cloneCard(node) {
|
|
77456
77747
|
return {
|
|
77457
|
-
|
|
77458
|
-
name: workspace.name,
|
|
77459
|
-
layout
|
|
77748
|
+
...node
|
|
77460
77749
|
};
|
|
77461
77750
|
}
|
|
77462
|
-
function
|
|
77463
|
-
return
|
|
77751
|
+
function cloneStackChild(node) {
|
|
77752
|
+
return node.type === "card" ? cloneCard(node) : {
|
|
77753
|
+
...node,
|
|
77754
|
+
children: node.children.map(cloneCard)
|
|
77755
|
+
};
|
|
77464
77756
|
}
|
|
77465
77757
|
|
|
77466
77758
|
// src/server/server-store.ts
|
|
@@ -77480,26 +77772,51 @@ function validateHTMLFragment(content) {
|
|
|
77480
77772
|
}
|
|
77481
77773
|
}
|
|
77482
77774
|
function migrateWorkspaceJson(raw) {
|
|
77483
|
-
if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
|
|
77484
|
-
return false;
|
|
77485
|
-
}
|
|
77486
77775
|
if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
|
|
77487
77776
|
raw.layout = raw.artifacts;
|
|
77488
77777
|
delete raw.artifacts;
|
|
77489
77778
|
return true;
|
|
77490
77779
|
}
|
|
77491
77780
|
if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
|
|
77492
|
-
raw.layout = raw.artifactIDs.map((id) => ({
|
|
77493
|
-
type: "artifact",
|
|
77494
|
-
artifactID: id,
|
|
77495
|
-
cols: DEFAULT_COLS,
|
|
77496
|
-
rows: DEFAULT_ROWS
|
|
77497
|
-
}));
|
|
77781
|
+
raw.layout = raw.artifactIDs.map((id) => ({ artifactID: id, width: DEFAULT_COLS, height: DEFAULT_ROWS }));
|
|
77498
77782
|
delete raw.artifactIDs;
|
|
77499
77783
|
return true;
|
|
77500
77784
|
}
|
|
77501
77785
|
return false;
|
|
77502
77786
|
}
|
|
77787
|
+
function deserializeWorkspaceData(workspace) {
|
|
77788
|
+
const rawLayout = workspace.layout;
|
|
77789
|
+
if (!Array.isArray(rawLayout)) {
|
|
77790
|
+
return {
|
|
77791
|
+
migrated: false,
|
|
77792
|
+
workspace: {
|
|
77793
|
+
id: workspace.id,
|
|
77794
|
+
name: workspace.name,
|
|
77795
|
+
layout: []
|
|
77796
|
+
}
|
|
77797
|
+
};
|
|
77798
|
+
}
|
|
77799
|
+
if (rawLayout.every(
|
|
77800
|
+
(node) => typeof node === "object" && node !== null && "type" in node && (node.type === "card" || node.type === "stack")
|
|
77801
|
+
)) {
|
|
77802
|
+
return {
|
|
77803
|
+
migrated: false,
|
|
77804
|
+
workspace: {
|
|
77805
|
+
id: workspace.id,
|
|
77806
|
+
name: workspace.name,
|
|
77807
|
+
layout: rawLayout
|
|
77808
|
+
}
|
|
77809
|
+
};
|
|
77810
|
+
}
|
|
77811
|
+
return {
|
|
77812
|
+
migrated: true,
|
|
77813
|
+
workspace: {
|
|
77814
|
+
id: workspace.id,
|
|
77815
|
+
name: workspace.name,
|
|
77816
|
+
layout: migrateLegacyLayout(rawLayout)
|
|
77817
|
+
}
|
|
77818
|
+
};
|
|
77819
|
+
}
|
|
77503
77820
|
var ServerStore = class extends Emitter {
|
|
77504
77821
|
dataDir;
|
|
77505
77822
|
workspaces = /* @__PURE__ */ new Map();
|
|
@@ -77533,7 +77850,7 @@ var ServerStore = class extends Emitter {
|
|
|
77533
77850
|
}
|
|
77534
77851
|
findArtifactWorkspaces(artifactID) {
|
|
77535
77852
|
return [...this.workspaces.values()].filter(
|
|
77536
|
-
(workspace) => workspace.layout
|
|
77853
|
+
(workspace) => layoutContainsArtifactID(workspace.layout, artifactID)
|
|
77537
77854
|
);
|
|
77538
77855
|
}
|
|
77539
77856
|
createArtifact(input) {
|
|
@@ -77551,7 +77868,7 @@ var ServerStore = class extends Emitter {
|
|
|
77551
77868
|
content: input.content
|
|
77552
77869
|
});
|
|
77553
77870
|
this.artifacts.set(artifact.id, artifact);
|
|
77554
|
-
workspace.layout.
|
|
77871
|
+
workspace.layout = [...workspace.layout, createCardNode(artifact.id)];
|
|
77555
77872
|
this.persistArtifact(artifact);
|
|
77556
77873
|
this.persistWorkspace(workspace);
|
|
77557
77874
|
this.emit("mutation", {
|
|
@@ -77584,11 +77901,11 @@ var ServerStore = class extends Emitter {
|
|
|
77584
77901
|
throw new Error(`Artifact not found: ${input.artifactID}`);
|
|
77585
77902
|
}
|
|
77586
77903
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
77587
|
-
if (!workspace.layout
|
|
77904
|
+
if (!layoutContainsArtifactID(workspace.layout, input.artifactID)) {
|
|
77588
77905
|
throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
|
|
77589
77906
|
}
|
|
77590
77907
|
this.artifacts.delete(input.artifactID);
|
|
77591
|
-
workspace.layout = workspace.layout
|
|
77908
|
+
workspace.layout = removeArtifactFromLayout(workspace.layout, input.artifactID);
|
|
77592
77909
|
this.persistWorkspace(workspace);
|
|
77593
77910
|
this.deleteArtifactFile(input.artifactID);
|
|
77594
77911
|
this.emit("mutation", {
|
|
@@ -77619,7 +77936,7 @@ var ServerStore = class extends Emitter {
|
|
|
77619
77936
|
nextFields.name = input.fields.name;
|
|
77620
77937
|
}
|
|
77621
77938
|
if (Array.isArray(input.fields.layout)) {
|
|
77622
|
-
workspace.layout = input.fields.layout.map((
|
|
77939
|
+
workspace.layout = input.fields.layout.map((node) => structuredClone(node));
|
|
77623
77940
|
nextFields.layout = workspace.layout;
|
|
77624
77941
|
}
|
|
77625
77942
|
this.persistWorkspace(workspace);
|
|
@@ -77657,10 +77974,10 @@ var ServerStore = class extends Emitter {
|
|
|
77657
77974
|
const filePath = import_node_path4.default.join(this.workspacesDir, file2);
|
|
77658
77975
|
const raw = this.readJsonFile(filePath);
|
|
77659
77976
|
if (!raw || typeof raw !== "object") continue;
|
|
77660
|
-
const
|
|
77661
|
-
const workspace =
|
|
77977
|
+
const renamedLegacyFields = migrateWorkspaceJson(raw);
|
|
77978
|
+
const { workspace, migrated } = deserializeWorkspaceData(raw);
|
|
77662
77979
|
this.workspaces.set(workspace.id, workspace);
|
|
77663
|
-
if (migrated) {
|
|
77980
|
+
if (renamedLegacyFields || migrated) {
|
|
77664
77981
|
this.persistWorkspace(workspace);
|
|
77665
77982
|
}
|
|
77666
77983
|
}
|