@telepath-computer/television 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/browser/assets/index-Ctq-tqkf.js +443 -0
- package/dist/browser/assets/index-W7D1rDld.css +1 -0
- package/dist/browser/index.html +2 -2
- package/dist/cli.cjs +106 -13
- package/dist/electron.cjs +106 -13
- package/package.json +3 -2
- package/dist/browser/assets/index-C0a55XYe.js +0 -413
- package/dist/browser/assets/index-C0onxKEP.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-y:auto;padding:16px 20px}.markdown-body{font-size:14px;line-height:1.6;color:var(--color-text)}.markdown-body>:first-child{margin-top:0}.markdown-body>:last-child{margin-bottom:0}.markdown-body h1,.markdown-body h2,.markdown-body h3{font-weight:600;margin:1.25em 0 .5em}.markdown-body h1{font-size:1.4em}.markdown-body h2{font-size:1.2em}.markdown-body h3{font-size:1.05em}.markdown-body p{margin:.75em 0}.markdown-body code{font-family:var(--font-mono);font-size:.9em;background:var(--color-interactive);padding:.15em .35em;border-radius:4px}.markdown-body pre{background:var(--color-interactive);border-radius:6px;padding:12px 14px;overflow-x:auto}.markdown-body pre code{background:none;padding:0}.markdown-body ul,.markdown-body ol{padding-left:1.5em;margin:.75em 0}.markdown-body blockquote{margin:.75em 0;padding-left:1em;border-left:3px solid var(--color-border);color:var(--color-text-muted)}.markdown-body a{color:var(--color-text);text-decoration:underline}.markdown-body hr{border:none;border-top:1px solid var(--color-border);margin:1em 0}layout-stream{width:100%;flex:1;min-width:0;min-height:0;display:flex;align-items:center;overflow:hidden;outline:none;position:relative;--layout-col-width: 300px;--layout-row-height: 133.33px;--layout-gap: 16px}layout-stream .track{display:flex;align-items:start;gap:var(--layout-gap);flex-shrink:0;width:max-content;will-change:transform;transition:transform .2s ease}layout-stream .band{display:grid;grid-template-rows:repeat(6,var(--layout-row-height));gap:var(--layout-gap);align-self:start}layout-stream .band[layout-band-cols="1"]{grid-template-columns:var(--layout-col-width);width:var(--layout-col-width)}layout-stream .band[layout-band-cols="2"]{grid-template-columns:repeat(2,var(--layout-col-width));width:calc(var(--layout-col-width) * 2 + var(--layout-gap))}layout-stream .card-slot{border-radius:12px;box-sizing:border-box;cursor:pointer;min-width:0;min-height:0}layout-stream .card-slot.placeholder{background:#94a3b829;border:2px dashed rgba(148,163,184,.7);box-shadow:inset 0 0 0 1px #0f172a0d}layout-stream .card-slot.dragging{position:fixed;z-index:100;opacity:.7;transform:rotate(2deg);pointer-events:none;cursor:grabbing}layout-stream .card-slot artifact-view{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}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}: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)}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-sm: 12px;--text-base: 14px;--text-lg: 16px;--leading-base: 1.5;--space-2: 2px;--space-4: 4px;--space-6: 6px;--space-8: 8px;--space-12: 12px;--space-16: 16px;--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);--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)}html,body{margin:0;padding:0;width:100%;height:100%}html{color-scheme:light}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)}code,pre{font-family:var(--font-mono)}h1,h2,h3,h4,h5,h6{color:var(--color-text)}[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{--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-Ctq-tqkf.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-W7D1rDld.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body></body>
|
|
11
11
|
</html>
|
package/dist/cli.cjs
CHANGED
|
@@ -75157,7 +75157,9 @@ function isClientMessage(value) {
|
|
|
75157
75157
|
case "create-workspace":
|
|
75158
75158
|
return typeof message.id === "string" && typeof message.name === "string";
|
|
75159
75159
|
case "update-workspace":
|
|
75160
|
-
return typeof message.workspaceID === "string" && typeof message.fields === "object" && message.fields !== null && (!("name" in message.fields) || typeof message.fields.name === "string")
|
|
75160
|
+
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(
|
|
75161
|
+
(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"
|
|
75162
|
+
));
|
|
75161
75163
|
case "delete-workspace":
|
|
75162
75164
|
return typeof message.workspaceID === "string";
|
|
75163
75165
|
default:
|
|
@@ -75315,8 +75317,83 @@ function ulid3(seedTime, prng) {
|
|
|
75315
75317
|
var import_node_crypto2 = require("node:crypto");
|
|
75316
75318
|
var import_node_fs2 = require("node:fs");
|
|
75317
75319
|
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
75320
|
+
|
|
75321
|
+
// src/types.ts
|
|
75322
|
+
var DEFAULT_LAYOUT_CARD_COLS = 2;
|
|
75323
|
+
var DEFAULT_LAYOUT_CARD_ROWS = 6;
|
|
75324
|
+
var LAYOUT_COLS_NARROW = 1;
|
|
75325
|
+
var LAYOUT_ROW_SHORT = 2;
|
|
75326
|
+
var LAYOUT_ROW_MID = 3;
|
|
75327
|
+
var LAYOUT_ROW_TALL = 4;
|
|
75328
|
+
var ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
|
|
75329
|
+
var ALLOWED_ROWS = [
|
|
75330
|
+
LAYOUT_ROW_SHORT,
|
|
75331
|
+
LAYOUT_ROW_MID,
|
|
75332
|
+
LAYOUT_ROW_TALL,
|
|
75333
|
+
DEFAULT_LAYOUT_CARD_ROWS
|
|
75334
|
+
];
|
|
75335
|
+
function clampLayoutCols(cols) {
|
|
75336
|
+
const n = Math.round(cols);
|
|
75337
|
+
return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
|
|
75338
|
+
}
|
|
75339
|
+
function clampLayoutRows(rows) {
|
|
75340
|
+
const n = Math.round(rows);
|
|
75341
|
+
return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
|
|
75342
|
+
}
|
|
75343
|
+
function createLayoutCardRecord(artifactID) {
|
|
75344
|
+
return {
|
|
75345
|
+
type: "artifact",
|
|
75346
|
+
artifactID,
|
|
75347
|
+
cols: DEFAULT_LAYOUT_CARD_COLS,
|
|
75348
|
+
rows: DEFAULT_LAYOUT_CARD_ROWS
|
|
75349
|
+
};
|
|
75350
|
+
}
|
|
75351
|
+
function normalizeLayoutCardRecord(card) {
|
|
75352
|
+
return {
|
|
75353
|
+
type: "artifact",
|
|
75354
|
+
artifactID: card.artifactID,
|
|
75355
|
+
cols: clampLayoutCols(card.cols ?? DEFAULT_LAYOUT_CARD_COLS),
|
|
75356
|
+
rows: clampLayoutRows(card.rows ?? DEFAULT_LAYOUT_CARD_ROWS)
|
|
75357
|
+
};
|
|
75358
|
+
}
|
|
75359
|
+
function normalizeWorkspace(workspace) {
|
|
75360
|
+
const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => normalizeLayoutCardRecord(card)) : [];
|
|
75361
|
+
return {
|
|
75362
|
+
id: workspace.id,
|
|
75363
|
+
name: workspace.name,
|
|
75364
|
+
layout
|
|
75365
|
+
};
|
|
75366
|
+
}
|
|
75367
|
+
function getWorkspaceArtifactIDs(workspace) {
|
|
75368
|
+
return workspace.layout.map((card) => card.artifactID);
|
|
75369
|
+
}
|
|
75370
|
+
|
|
75371
|
+
// src/server/workspace-store.ts
|
|
75318
75372
|
var JSON_INDENT_SPACES = 2;
|
|
75319
75373
|
var AUTH_TOKEN_BYTES = 32;
|
|
75374
|
+
var DEFAULT_COLS = 2;
|
|
75375
|
+
var DEFAULT_ROWS = 6;
|
|
75376
|
+
function migrateWorkspaceJson(raw) {
|
|
75377
|
+
if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
|
|
75378
|
+
return false;
|
|
75379
|
+
}
|
|
75380
|
+
if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
|
|
75381
|
+
raw.layout = raw.artifacts;
|
|
75382
|
+
delete raw.artifacts;
|
|
75383
|
+
return true;
|
|
75384
|
+
}
|
|
75385
|
+
if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
|
|
75386
|
+
raw.layout = raw.artifactIDs.map((id) => ({
|
|
75387
|
+
type: "artifact",
|
|
75388
|
+
artifactID: id,
|
|
75389
|
+
cols: DEFAULT_COLS,
|
|
75390
|
+
rows: DEFAULT_ROWS
|
|
75391
|
+
}));
|
|
75392
|
+
delete raw.artifactIDs;
|
|
75393
|
+
return true;
|
|
75394
|
+
}
|
|
75395
|
+
return false;
|
|
75396
|
+
}
|
|
75320
75397
|
var WorkspaceStore = class extends Emitter {
|
|
75321
75398
|
dataDir;
|
|
75322
75399
|
workspaces = /* @__PURE__ */ new Map();
|
|
@@ -75343,10 +75420,12 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75343
75420
|
if (!workspace) {
|
|
75344
75421
|
throw new Error(`Workspace not found: ${workspaceID}`);
|
|
75345
75422
|
}
|
|
75346
|
-
return workspace.
|
|
75423
|
+
return getWorkspaceArtifactIDs(workspace).map((artifactID) => this.artifacts.get(artifactID)).filter((artifact) => artifact !== void 0);
|
|
75347
75424
|
}
|
|
75348
75425
|
findArtifactWorkspaces(artifactID) {
|
|
75349
|
-
return [...this.workspaces.values()].filter(
|
|
75426
|
+
return [...this.workspaces.values()].filter(
|
|
75427
|
+
(workspace) => workspace.layout.some((card) => card.artifactID === artifactID)
|
|
75428
|
+
);
|
|
75350
75429
|
}
|
|
75351
75430
|
createArtifact(input) {
|
|
75352
75431
|
if (!input.workspaceID) {
|
|
@@ -75360,7 +75439,7 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75360
75439
|
content: input.content
|
|
75361
75440
|
};
|
|
75362
75441
|
this.artifacts.set(artifact.id, artifact);
|
|
75363
|
-
workspace.
|
|
75442
|
+
workspace.layout.push(createLayoutCardRecord(artifact.id));
|
|
75364
75443
|
this.persistArtifact(artifact);
|
|
75365
75444
|
this.persistWorkspace(workspace);
|
|
75366
75445
|
this.emit("mutation", {
|
|
@@ -75393,11 +75472,11 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75393
75472
|
throw new Error(`Artifact not found: ${input.artifactID}`);
|
|
75394
75473
|
}
|
|
75395
75474
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
75396
|
-
if (!workspace.
|
|
75475
|
+
if (!workspace.layout.some((card) => card.artifactID === input.artifactID)) {
|
|
75397
75476
|
throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
|
|
75398
75477
|
}
|
|
75399
75478
|
this.artifacts.delete(input.artifactID);
|
|
75400
|
-
workspace.
|
|
75479
|
+
workspace.layout = workspace.layout.filter((card) => card.artifactID !== input.artifactID);
|
|
75401
75480
|
this.persistWorkspace(workspace);
|
|
75402
75481
|
this.deleteArtifactFile(input.artifactID);
|
|
75403
75482
|
this.emit("mutation", {
|
|
@@ -75410,7 +75489,7 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75410
75489
|
const workspace = {
|
|
75411
75490
|
id: input.id ?? ulid3(),
|
|
75412
75491
|
name: input.name,
|
|
75413
|
-
|
|
75492
|
+
layout: []
|
|
75414
75493
|
};
|
|
75415
75494
|
this.workspaces.set(workspace.id, workspace);
|
|
75416
75495
|
this.persistWorkspace(workspace);
|
|
@@ -75422,18 +75501,26 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75422
75501
|
}
|
|
75423
75502
|
updateWorkspace(input) {
|
|
75424
75503
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
75425
|
-
|
|
75504
|
+
const nextFields = {};
|
|
75505
|
+
if (typeof input.fields.name === "string") {
|
|
75506
|
+
workspace.name = input.fields.name;
|
|
75507
|
+
nextFields.name = input.fields.name;
|
|
75508
|
+
}
|
|
75509
|
+
if (Array.isArray(input.fields.layout)) {
|
|
75510
|
+
workspace.layout = input.fields.layout.map((card) => normalizeLayoutCardRecord(card));
|
|
75511
|
+
nextFields.layout = workspace.layout.map((card) => normalizeLayoutCardRecord(card));
|
|
75512
|
+
}
|
|
75426
75513
|
this.persistWorkspace(workspace);
|
|
75427
75514
|
this.emit("mutation", {
|
|
75428
75515
|
type: "workspace-updated",
|
|
75429
75516
|
workspaceID: input.workspaceID,
|
|
75430
|
-
fields:
|
|
75517
|
+
fields: nextFields
|
|
75431
75518
|
});
|
|
75432
75519
|
}
|
|
75433
75520
|
removeWorkspace(input) {
|
|
75434
75521
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
75435
75522
|
this.workspaces.delete(input.workspaceID);
|
|
75436
|
-
for (const artifactID of workspace
|
|
75523
|
+
for (const artifactID of getWorkspaceArtifactIDs(workspace)) {
|
|
75437
75524
|
if (this.findArtifactWorkspaces(artifactID).length > 0) {
|
|
75438
75525
|
continue;
|
|
75439
75526
|
}
|
|
@@ -75455,9 +75542,15 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75455
75542
|
}
|
|
75456
75543
|
load() {
|
|
75457
75544
|
for (const file2 of this.readEntityFiles(this.workspacesDir)) {
|
|
75458
|
-
const
|
|
75459
|
-
|
|
75545
|
+
const filePath = import_node_path3.default.join(this.workspacesDir, file2);
|
|
75546
|
+
const raw = this.readJsonFile(filePath);
|
|
75547
|
+
if (!raw || typeof raw !== "object") continue;
|
|
75548
|
+
const migrated = migrateWorkspaceJson(raw);
|
|
75549
|
+
const workspace = normalizeWorkspace(raw);
|
|
75460
75550
|
this.workspaces.set(workspace.id, workspace);
|
|
75551
|
+
if (migrated) {
|
|
75552
|
+
this.persistWorkspace(workspace);
|
|
75553
|
+
}
|
|
75461
75554
|
}
|
|
75462
75555
|
for (const file2 of this.readEntityFiles(this.artifactsDir)) {
|
|
75463
75556
|
const artifact = this.readJsonFile(import_node_path3.default.join(this.artifactsDir, file2));
|
|
@@ -75469,7 +75562,7 @@ var WorkspaceStore = class extends Emitter {
|
|
|
75469
75562
|
const workspace = {
|
|
75470
75563
|
id: ulid3(),
|
|
75471
75564
|
name: "Default",
|
|
75472
|
-
|
|
75565
|
+
layout: []
|
|
75473
75566
|
};
|
|
75474
75567
|
this.workspaces.set(workspace.id, workspace);
|
|
75475
75568
|
this.persistWorkspace(workspace);
|
package/dist/electron.cjs
CHANGED
|
@@ -71446,7 +71446,9 @@ function isClientMessage(value) {
|
|
|
71446
71446
|
case "create-workspace":
|
|
71447
71447
|
return typeof message.id === "string" && typeof message.name === "string";
|
|
71448
71448
|
case "update-workspace":
|
|
71449
|
-
return typeof message.workspaceID === "string" && typeof message.fields === "object" && message.fields !== null && (!("name" in message.fields) || typeof message.fields.name === "string")
|
|
71449
|
+
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(
|
|
71450
|
+
(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"
|
|
71451
|
+
));
|
|
71450
71452
|
case "delete-workspace":
|
|
71451
71453
|
return typeof message.workspaceID === "string";
|
|
71452
71454
|
default:
|
|
@@ -71604,8 +71606,83 @@ function ulid3(seedTime, prng) {
|
|
|
71604
71606
|
var import_node_crypto2 = require("node:crypto");
|
|
71605
71607
|
var import_node_fs = require("node:fs");
|
|
71606
71608
|
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
71609
|
+
|
|
71610
|
+
// src/types.ts
|
|
71611
|
+
var DEFAULT_LAYOUT_CARD_COLS = 2;
|
|
71612
|
+
var DEFAULT_LAYOUT_CARD_ROWS = 6;
|
|
71613
|
+
var LAYOUT_COLS_NARROW = 1;
|
|
71614
|
+
var LAYOUT_ROW_SHORT = 2;
|
|
71615
|
+
var LAYOUT_ROW_MID = 3;
|
|
71616
|
+
var LAYOUT_ROW_TALL = 4;
|
|
71617
|
+
var ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
|
|
71618
|
+
var ALLOWED_ROWS = [
|
|
71619
|
+
LAYOUT_ROW_SHORT,
|
|
71620
|
+
LAYOUT_ROW_MID,
|
|
71621
|
+
LAYOUT_ROW_TALL,
|
|
71622
|
+
DEFAULT_LAYOUT_CARD_ROWS
|
|
71623
|
+
];
|
|
71624
|
+
function clampLayoutCols(cols) {
|
|
71625
|
+
const n = Math.round(cols);
|
|
71626
|
+
return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
|
|
71627
|
+
}
|
|
71628
|
+
function clampLayoutRows(rows) {
|
|
71629
|
+
const n = Math.round(rows);
|
|
71630
|
+
return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
|
|
71631
|
+
}
|
|
71632
|
+
function createLayoutCardRecord(artifactID) {
|
|
71633
|
+
return {
|
|
71634
|
+
type: "artifact",
|
|
71635
|
+
artifactID,
|
|
71636
|
+
cols: DEFAULT_LAYOUT_CARD_COLS,
|
|
71637
|
+
rows: DEFAULT_LAYOUT_CARD_ROWS
|
|
71638
|
+
};
|
|
71639
|
+
}
|
|
71640
|
+
function normalizeLayoutCardRecord(card) {
|
|
71641
|
+
return {
|
|
71642
|
+
type: "artifact",
|
|
71643
|
+
artifactID: card.artifactID,
|
|
71644
|
+
cols: clampLayoutCols(card.cols ?? DEFAULT_LAYOUT_CARD_COLS),
|
|
71645
|
+
rows: clampLayoutRows(card.rows ?? DEFAULT_LAYOUT_CARD_ROWS)
|
|
71646
|
+
};
|
|
71647
|
+
}
|
|
71648
|
+
function normalizeWorkspace(workspace) {
|
|
71649
|
+
const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => normalizeLayoutCardRecord(card)) : [];
|
|
71650
|
+
return {
|
|
71651
|
+
id: workspace.id,
|
|
71652
|
+
name: workspace.name,
|
|
71653
|
+
layout
|
|
71654
|
+
};
|
|
71655
|
+
}
|
|
71656
|
+
function getWorkspaceArtifactIDs(workspace) {
|
|
71657
|
+
return workspace.layout.map((card) => card.artifactID);
|
|
71658
|
+
}
|
|
71659
|
+
|
|
71660
|
+
// src/server/workspace-store.ts
|
|
71607
71661
|
var JSON_INDENT_SPACES = 2;
|
|
71608
71662
|
var AUTH_TOKEN_BYTES = 32;
|
|
71663
|
+
var DEFAULT_COLS = 2;
|
|
71664
|
+
var DEFAULT_ROWS = 6;
|
|
71665
|
+
function migrateWorkspaceJson(raw) {
|
|
71666
|
+
if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
|
|
71667
|
+
return false;
|
|
71668
|
+
}
|
|
71669
|
+
if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
|
|
71670
|
+
raw.layout = raw.artifacts;
|
|
71671
|
+
delete raw.artifacts;
|
|
71672
|
+
return true;
|
|
71673
|
+
}
|
|
71674
|
+
if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
|
|
71675
|
+
raw.layout = raw.artifactIDs.map((id) => ({
|
|
71676
|
+
type: "artifact",
|
|
71677
|
+
artifactID: id,
|
|
71678
|
+
cols: DEFAULT_COLS,
|
|
71679
|
+
rows: DEFAULT_ROWS
|
|
71680
|
+
}));
|
|
71681
|
+
delete raw.artifactIDs;
|
|
71682
|
+
return true;
|
|
71683
|
+
}
|
|
71684
|
+
return false;
|
|
71685
|
+
}
|
|
71609
71686
|
var WorkspaceStore = class extends Emitter {
|
|
71610
71687
|
dataDir;
|
|
71611
71688
|
workspaces = /* @__PURE__ */ new Map();
|
|
@@ -71632,10 +71709,12 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71632
71709
|
if (!workspace) {
|
|
71633
71710
|
throw new Error(`Workspace not found: ${workspaceID}`);
|
|
71634
71711
|
}
|
|
71635
|
-
return workspace.
|
|
71712
|
+
return getWorkspaceArtifactIDs(workspace).map((artifactID) => this.artifacts.get(artifactID)).filter((artifact) => artifact !== void 0);
|
|
71636
71713
|
}
|
|
71637
71714
|
findArtifactWorkspaces(artifactID) {
|
|
71638
|
-
return [...this.workspaces.values()].filter(
|
|
71715
|
+
return [...this.workspaces.values()].filter(
|
|
71716
|
+
(workspace) => workspace.layout.some((card) => card.artifactID === artifactID)
|
|
71717
|
+
);
|
|
71639
71718
|
}
|
|
71640
71719
|
createArtifact(input) {
|
|
71641
71720
|
if (!input.workspaceID) {
|
|
@@ -71649,7 +71728,7 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71649
71728
|
content: input.content
|
|
71650
71729
|
};
|
|
71651
71730
|
this.artifacts.set(artifact.id, artifact);
|
|
71652
|
-
workspace.
|
|
71731
|
+
workspace.layout.push(createLayoutCardRecord(artifact.id));
|
|
71653
71732
|
this.persistArtifact(artifact);
|
|
71654
71733
|
this.persistWorkspace(workspace);
|
|
71655
71734
|
this.emit("mutation", {
|
|
@@ -71682,11 +71761,11 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71682
71761
|
throw new Error(`Artifact not found: ${input.artifactID}`);
|
|
71683
71762
|
}
|
|
71684
71763
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
71685
|
-
if (!workspace.
|
|
71764
|
+
if (!workspace.layout.some((card) => card.artifactID === input.artifactID)) {
|
|
71686
71765
|
throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
|
|
71687
71766
|
}
|
|
71688
71767
|
this.artifacts.delete(input.artifactID);
|
|
71689
|
-
workspace.
|
|
71768
|
+
workspace.layout = workspace.layout.filter((card) => card.artifactID !== input.artifactID);
|
|
71690
71769
|
this.persistWorkspace(workspace);
|
|
71691
71770
|
this.deleteArtifactFile(input.artifactID);
|
|
71692
71771
|
this.emit("mutation", {
|
|
@@ -71699,7 +71778,7 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71699
71778
|
const workspace = {
|
|
71700
71779
|
id: input.id ?? ulid3(),
|
|
71701
71780
|
name: input.name,
|
|
71702
|
-
|
|
71781
|
+
layout: []
|
|
71703
71782
|
};
|
|
71704
71783
|
this.workspaces.set(workspace.id, workspace);
|
|
71705
71784
|
this.persistWorkspace(workspace);
|
|
@@ -71711,18 +71790,26 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71711
71790
|
}
|
|
71712
71791
|
updateWorkspace(input) {
|
|
71713
71792
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
71714
|
-
|
|
71793
|
+
const nextFields = {};
|
|
71794
|
+
if (typeof input.fields.name === "string") {
|
|
71795
|
+
workspace.name = input.fields.name;
|
|
71796
|
+
nextFields.name = input.fields.name;
|
|
71797
|
+
}
|
|
71798
|
+
if (Array.isArray(input.fields.layout)) {
|
|
71799
|
+
workspace.layout = input.fields.layout.map((card) => normalizeLayoutCardRecord(card));
|
|
71800
|
+
nextFields.layout = workspace.layout.map((card) => normalizeLayoutCardRecord(card));
|
|
71801
|
+
}
|
|
71715
71802
|
this.persistWorkspace(workspace);
|
|
71716
71803
|
this.emit("mutation", {
|
|
71717
71804
|
type: "workspace-updated",
|
|
71718
71805
|
workspaceID: input.workspaceID,
|
|
71719
|
-
fields:
|
|
71806
|
+
fields: nextFields
|
|
71720
71807
|
});
|
|
71721
71808
|
}
|
|
71722
71809
|
removeWorkspace(input) {
|
|
71723
71810
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
71724
71811
|
this.workspaces.delete(input.workspaceID);
|
|
71725
|
-
for (const artifactID of workspace
|
|
71812
|
+
for (const artifactID of getWorkspaceArtifactIDs(workspace)) {
|
|
71726
71813
|
if (this.findArtifactWorkspaces(artifactID).length > 0) {
|
|
71727
71814
|
continue;
|
|
71728
71815
|
}
|
|
@@ -71744,9 +71831,15 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71744
71831
|
}
|
|
71745
71832
|
load() {
|
|
71746
71833
|
for (const file2 of this.readEntityFiles(this.workspacesDir)) {
|
|
71747
|
-
const
|
|
71748
|
-
|
|
71834
|
+
const filePath = import_node_path2.default.join(this.workspacesDir, file2);
|
|
71835
|
+
const raw = this.readJsonFile(filePath);
|
|
71836
|
+
if (!raw || typeof raw !== "object") continue;
|
|
71837
|
+
const migrated = migrateWorkspaceJson(raw);
|
|
71838
|
+
const workspace = normalizeWorkspace(raw);
|
|
71749
71839
|
this.workspaces.set(workspace.id, workspace);
|
|
71840
|
+
if (migrated) {
|
|
71841
|
+
this.persistWorkspace(workspace);
|
|
71842
|
+
}
|
|
71750
71843
|
}
|
|
71751
71844
|
for (const file2 of this.readEntityFiles(this.artifactsDir)) {
|
|
71752
71845
|
const artifact = this.readJsonFile(import_node_path2.default.join(this.artifactsDir, file2));
|
|
@@ -71758,7 +71851,7 @@ var WorkspaceStore = class extends Emitter {
|
|
|
71758
71851
|
const workspace = {
|
|
71759
71852
|
id: ulid3(),
|
|
71760
71853
|
name: "Default",
|
|
71761
|
-
|
|
71854
|
+
layout: []
|
|
71762
71855
|
};
|
|
71763
71856
|
this.workspaces.set(workspace.id, workspace);
|
|
71764
71857
|
this.persistWorkspace(workspace);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telepath-computer/television",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/electron.cjs",
|
|
6
6
|
"bin": {
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
"dist/**"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"dev": "npm run dev:
|
|
13
|
+
"dev": "npm run dev:server",
|
|
14
14
|
"dev:electron": "scripts/dev-electron.sh",
|
|
15
15
|
"dev:server": "scripts/dev-server.sh",
|
|
16
|
+
"demo:layout": "vite --config vite.demo-layout.config.ts --host 127.0.0.1",
|
|
16
17
|
"build": "npm run build:renderer && npm run build:cli && npm run build:electron",
|
|
17
18
|
"prepack": "npm run build",
|
|
18
19
|
"start": "npm run build && env -u ELECTRON_RUN_AS_NODE electron .",
|