@telepath-computer/television 0.1.1 → 0.1.2

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.
@@ -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-C0a55XYe.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-C0onxKEP.css">
7
+ <script type="module" crossorigin src="./assets/index-DZhAP0Dt.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-BmwVdck9.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,77 @@ 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 ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
75328
+ var ALLOWED_ROWS = [LAYOUT_ROW_SHORT, LAYOUT_ROW_MID, DEFAULT_LAYOUT_CARD_ROWS];
75329
+ function clampLayoutCols(cols) {
75330
+ const n = Math.round(cols);
75331
+ return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
75332
+ }
75333
+ function clampLayoutRows(rows) {
75334
+ const n = Math.round(rows);
75335
+ return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
75336
+ }
75337
+ function createLayoutCardRecord(artifactID) {
75338
+ return {
75339
+ type: "artifact",
75340
+ artifactID,
75341
+ cols: DEFAULT_LAYOUT_CARD_COLS,
75342
+ rows: DEFAULT_LAYOUT_CARD_ROWS
75343
+ };
75344
+ }
75345
+ function normalizeLayoutCardRecord(card) {
75346
+ return {
75347
+ type: "artifact",
75348
+ artifactID: card.artifactID,
75349
+ cols: clampLayoutCols(card.cols ?? DEFAULT_LAYOUT_CARD_COLS),
75350
+ rows: clampLayoutRows(card.rows ?? DEFAULT_LAYOUT_CARD_ROWS)
75351
+ };
75352
+ }
75353
+ function normalizeWorkspace(workspace) {
75354
+ const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => normalizeLayoutCardRecord(card)) : [];
75355
+ return {
75356
+ id: workspace.id,
75357
+ name: workspace.name,
75358
+ layout
75359
+ };
75360
+ }
75361
+ function getWorkspaceArtifactIDs(workspace) {
75362
+ return workspace.layout.map((card) => card.artifactID);
75363
+ }
75364
+
75365
+ // src/server/workspace-store.ts
75318
75366
  var JSON_INDENT_SPACES = 2;
75319
75367
  var AUTH_TOKEN_BYTES = 32;
75368
+ var DEFAULT_COLS = 2;
75369
+ var DEFAULT_ROWS = 6;
75370
+ function migrateWorkspaceJson(raw) {
75371
+ if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
75372
+ return false;
75373
+ }
75374
+ if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
75375
+ raw.layout = raw.artifacts;
75376
+ delete raw.artifacts;
75377
+ return true;
75378
+ }
75379
+ if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
75380
+ raw.layout = raw.artifactIDs.map((id) => ({
75381
+ type: "artifact",
75382
+ artifactID: id,
75383
+ cols: DEFAULT_COLS,
75384
+ rows: DEFAULT_ROWS
75385
+ }));
75386
+ delete raw.artifactIDs;
75387
+ return true;
75388
+ }
75389
+ return false;
75390
+ }
75320
75391
  var WorkspaceStore = class extends Emitter {
75321
75392
  dataDir;
75322
75393
  workspaces = /* @__PURE__ */ new Map();
@@ -75343,10 +75414,12 @@ var WorkspaceStore = class extends Emitter {
75343
75414
  if (!workspace) {
75344
75415
  throw new Error(`Workspace not found: ${workspaceID}`);
75345
75416
  }
75346
- return workspace.artifactIDs.map((artifactID) => this.artifacts.get(artifactID)).filter((artifact) => artifact !== void 0);
75417
+ return getWorkspaceArtifactIDs(workspace).map((artifactID) => this.artifacts.get(artifactID)).filter((artifact) => artifact !== void 0);
75347
75418
  }
75348
75419
  findArtifactWorkspaces(artifactID) {
75349
- return [...this.workspaces.values()].filter((workspace) => workspace.artifactIDs.includes(artifactID));
75420
+ return [...this.workspaces.values()].filter(
75421
+ (workspace) => workspace.layout.some((card) => card.artifactID === artifactID)
75422
+ );
75350
75423
  }
75351
75424
  createArtifact(input) {
75352
75425
  if (!input.workspaceID) {
@@ -75360,7 +75433,7 @@ var WorkspaceStore = class extends Emitter {
75360
75433
  content: input.content
75361
75434
  };
75362
75435
  this.artifacts.set(artifact.id, artifact);
75363
- workspace.artifactIDs.push(artifact.id);
75436
+ workspace.layout.push(createLayoutCardRecord(artifact.id));
75364
75437
  this.persistArtifact(artifact);
75365
75438
  this.persistWorkspace(workspace);
75366
75439
  this.emit("mutation", {
@@ -75393,11 +75466,11 @@ var WorkspaceStore = class extends Emitter {
75393
75466
  throw new Error(`Artifact not found: ${input.artifactID}`);
75394
75467
  }
75395
75468
  const workspace = this.requireWorkspace(input.workspaceID);
75396
- if (!workspace.artifactIDs.includes(input.artifactID)) {
75469
+ if (!workspace.layout.some((card) => card.artifactID === input.artifactID)) {
75397
75470
  throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
75398
75471
  }
75399
75472
  this.artifacts.delete(input.artifactID);
75400
- workspace.artifactIDs = workspace.artifactIDs.filter((artifactID) => artifactID !== input.artifactID);
75473
+ workspace.layout = workspace.layout.filter((card) => card.artifactID !== input.artifactID);
75401
75474
  this.persistWorkspace(workspace);
75402
75475
  this.deleteArtifactFile(input.artifactID);
75403
75476
  this.emit("mutation", {
@@ -75410,7 +75483,7 @@ var WorkspaceStore = class extends Emitter {
75410
75483
  const workspace = {
75411
75484
  id: input.id ?? ulid3(),
75412
75485
  name: input.name,
75413
- artifactIDs: []
75486
+ layout: []
75414
75487
  };
75415
75488
  this.workspaces.set(workspace.id, workspace);
75416
75489
  this.persistWorkspace(workspace);
@@ -75422,18 +75495,26 @@ var WorkspaceStore = class extends Emitter {
75422
75495
  }
75423
75496
  updateWorkspace(input) {
75424
75497
  const workspace = this.requireWorkspace(input.workspaceID);
75425
- Object.assign(workspace, input.fields);
75498
+ const nextFields = {};
75499
+ if (typeof input.fields.name === "string") {
75500
+ workspace.name = input.fields.name;
75501
+ nextFields.name = input.fields.name;
75502
+ }
75503
+ if (Array.isArray(input.fields.layout)) {
75504
+ workspace.layout = input.fields.layout.map((card) => normalizeLayoutCardRecord(card));
75505
+ nextFields.layout = workspace.layout.map((card) => normalizeLayoutCardRecord(card));
75506
+ }
75426
75507
  this.persistWorkspace(workspace);
75427
75508
  this.emit("mutation", {
75428
75509
  type: "workspace-updated",
75429
75510
  workspaceID: input.workspaceID,
75430
- fields: input.fields
75511
+ fields: nextFields
75431
75512
  });
75432
75513
  }
75433
75514
  removeWorkspace(input) {
75434
75515
  const workspace = this.requireWorkspace(input.workspaceID);
75435
75516
  this.workspaces.delete(input.workspaceID);
75436
- for (const artifactID of workspace.artifactIDs) {
75517
+ for (const artifactID of getWorkspaceArtifactIDs(workspace)) {
75437
75518
  if (this.findArtifactWorkspaces(artifactID).length > 0) {
75438
75519
  continue;
75439
75520
  }
@@ -75455,9 +75536,15 @@ var WorkspaceStore = class extends Emitter {
75455
75536
  }
75456
75537
  load() {
75457
75538
  for (const file2 of this.readEntityFiles(this.workspacesDir)) {
75458
- const workspace = this.readJsonFile(import_node_path3.default.join(this.workspacesDir, file2));
75459
- if (!workspace) continue;
75539
+ const filePath = import_node_path3.default.join(this.workspacesDir, file2);
75540
+ const raw = this.readJsonFile(filePath);
75541
+ if (!raw || typeof raw !== "object") continue;
75542
+ const migrated = migrateWorkspaceJson(raw);
75543
+ const workspace = normalizeWorkspace(raw);
75460
75544
  this.workspaces.set(workspace.id, workspace);
75545
+ if (migrated) {
75546
+ this.persistWorkspace(workspace);
75547
+ }
75461
75548
  }
75462
75549
  for (const file2 of this.readEntityFiles(this.artifactsDir)) {
75463
75550
  const artifact = this.readJsonFile(import_node_path3.default.join(this.artifactsDir, file2));
@@ -75469,7 +75556,7 @@ var WorkspaceStore = class extends Emitter {
75469
75556
  const workspace = {
75470
75557
  id: ulid3(),
75471
75558
  name: "Default",
75472
- artifactIDs: []
75559
+ layout: []
75473
75560
  };
75474
75561
  this.workspaces.set(workspace.id, workspace);
75475
75562
  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,77 @@ 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 ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
71617
+ var ALLOWED_ROWS = [LAYOUT_ROW_SHORT, LAYOUT_ROW_MID, DEFAULT_LAYOUT_CARD_ROWS];
71618
+ function clampLayoutCols(cols) {
71619
+ const n = Math.round(cols);
71620
+ return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
71621
+ }
71622
+ function clampLayoutRows(rows) {
71623
+ const n = Math.round(rows);
71624
+ return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
71625
+ }
71626
+ function createLayoutCardRecord(artifactID) {
71627
+ return {
71628
+ type: "artifact",
71629
+ artifactID,
71630
+ cols: DEFAULT_LAYOUT_CARD_COLS,
71631
+ rows: DEFAULT_LAYOUT_CARD_ROWS
71632
+ };
71633
+ }
71634
+ function normalizeLayoutCardRecord(card) {
71635
+ return {
71636
+ type: "artifact",
71637
+ artifactID: card.artifactID,
71638
+ cols: clampLayoutCols(card.cols ?? DEFAULT_LAYOUT_CARD_COLS),
71639
+ rows: clampLayoutRows(card.rows ?? DEFAULT_LAYOUT_CARD_ROWS)
71640
+ };
71641
+ }
71642
+ function normalizeWorkspace(workspace) {
71643
+ const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => normalizeLayoutCardRecord(card)) : [];
71644
+ return {
71645
+ id: workspace.id,
71646
+ name: workspace.name,
71647
+ layout
71648
+ };
71649
+ }
71650
+ function getWorkspaceArtifactIDs(workspace) {
71651
+ return workspace.layout.map((card) => card.artifactID);
71652
+ }
71653
+
71654
+ // src/server/workspace-store.ts
71607
71655
  var JSON_INDENT_SPACES = 2;
71608
71656
  var AUTH_TOKEN_BYTES = 32;
71657
+ var DEFAULT_COLS = 2;
71658
+ var DEFAULT_ROWS = 6;
71659
+ function migrateWorkspaceJson(raw) {
71660
+ if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
71661
+ return false;
71662
+ }
71663
+ if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
71664
+ raw.layout = raw.artifacts;
71665
+ delete raw.artifacts;
71666
+ return true;
71667
+ }
71668
+ if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
71669
+ raw.layout = raw.artifactIDs.map((id) => ({
71670
+ type: "artifact",
71671
+ artifactID: id,
71672
+ cols: DEFAULT_COLS,
71673
+ rows: DEFAULT_ROWS
71674
+ }));
71675
+ delete raw.artifactIDs;
71676
+ return true;
71677
+ }
71678
+ return false;
71679
+ }
71609
71680
  var WorkspaceStore = class extends Emitter {
71610
71681
  dataDir;
71611
71682
  workspaces = /* @__PURE__ */ new Map();
@@ -71632,10 +71703,12 @@ var WorkspaceStore = class extends Emitter {
71632
71703
  if (!workspace) {
71633
71704
  throw new Error(`Workspace not found: ${workspaceID}`);
71634
71705
  }
71635
- return workspace.artifactIDs.map((artifactID) => this.artifacts.get(artifactID)).filter((artifact) => artifact !== void 0);
71706
+ return getWorkspaceArtifactIDs(workspace).map((artifactID) => this.artifacts.get(artifactID)).filter((artifact) => artifact !== void 0);
71636
71707
  }
71637
71708
  findArtifactWorkspaces(artifactID) {
71638
- return [...this.workspaces.values()].filter((workspace) => workspace.artifactIDs.includes(artifactID));
71709
+ return [...this.workspaces.values()].filter(
71710
+ (workspace) => workspace.layout.some((card) => card.artifactID === artifactID)
71711
+ );
71639
71712
  }
71640
71713
  createArtifact(input) {
71641
71714
  if (!input.workspaceID) {
@@ -71649,7 +71722,7 @@ var WorkspaceStore = class extends Emitter {
71649
71722
  content: input.content
71650
71723
  };
71651
71724
  this.artifacts.set(artifact.id, artifact);
71652
- workspace.artifactIDs.push(artifact.id);
71725
+ workspace.layout.push(createLayoutCardRecord(artifact.id));
71653
71726
  this.persistArtifact(artifact);
71654
71727
  this.persistWorkspace(workspace);
71655
71728
  this.emit("mutation", {
@@ -71682,11 +71755,11 @@ var WorkspaceStore = class extends Emitter {
71682
71755
  throw new Error(`Artifact not found: ${input.artifactID}`);
71683
71756
  }
71684
71757
  const workspace = this.requireWorkspace(input.workspaceID);
71685
- if (!workspace.artifactIDs.includes(input.artifactID)) {
71758
+ if (!workspace.layout.some((card) => card.artifactID === input.artifactID)) {
71686
71759
  throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
71687
71760
  }
71688
71761
  this.artifacts.delete(input.artifactID);
71689
- workspace.artifactIDs = workspace.artifactIDs.filter((artifactID) => artifactID !== input.artifactID);
71762
+ workspace.layout = workspace.layout.filter((card) => card.artifactID !== input.artifactID);
71690
71763
  this.persistWorkspace(workspace);
71691
71764
  this.deleteArtifactFile(input.artifactID);
71692
71765
  this.emit("mutation", {
@@ -71699,7 +71772,7 @@ var WorkspaceStore = class extends Emitter {
71699
71772
  const workspace = {
71700
71773
  id: input.id ?? ulid3(),
71701
71774
  name: input.name,
71702
- artifactIDs: []
71775
+ layout: []
71703
71776
  };
71704
71777
  this.workspaces.set(workspace.id, workspace);
71705
71778
  this.persistWorkspace(workspace);
@@ -71711,18 +71784,26 @@ var WorkspaceStore = class extends Emitter {
71711
71784
  }
71712
71785
  updateWorkspace(input) {
71713
71786
  const workspace = this.requireWorkspace(input.workspaceID);
71714
- Object.assign(workspace, input.fields);
71787
+ const nextFields = {};
71788
+ if (typeof input.fields.name === "string") {
71789
+ workspace.name = input.fields.name;
71790
+ nextFields.name = input.fields.name;
71791
+ }
71792
+ if (Array.isArray(input.fields.layout)) {
71793
+ workspace.layout = input.fields.layout.map((card) => normalizeLayoutCardRecord(card));
71794
+ nextFields.layout = workspace.layout.map((card) => normalizeLayoutCardRecord(card));
71795
+ }
71715
71796
  this.persistWorkspace(workspace);
71716
71797
  this.emit("mutation", {
71717
71798
  type: "workspace-updated",
71718
71799
  workspaceID: input.workspaceID,
71719
- fields: input.fields
71800
+ fields: nextFields
71720
71801
  });
71721
71802
  }
71722
71803
  removeWorkspace(input) {
71723
71804
  const workspace = this.requireWorkspace(input.workspaceID);
71724
71805
  this.workspaces.delete(input.workspaceID);
71725
- for (const artifactID of workspace.artifactIDs) {
71806
+ for (const artifactID of getWorkspaceArtifactIDs(workspace)) {
71726
71807
  if (this.findArtifactWorkspaces(artifactID).length > 0) {
71727
71808
  continue;
71728
71809
  }
@@ -71744,9 +71825,15 @@ var WorkspaceStore = class extends Emitter {
71744
71825
  }
71745
71826
  load() {
71746
71827
  for (const file2 of this.readEntityFiles(this.workspacesDir)) {
71747
- const workspace = this.readJsonFile(import_node_path2.default.join(this.workspacesDir, file2));
71748
- if (!workspace) continue;
71828
+ const filePath = import_node_path2.default.join(this.workspacesDir, file2);
71829
+ const raw = this.readJsonFile(filePath);
71830
+ if (!raw || typeof raw !== "object") continue;
71831
+ const migrated = migrateWorkspaceJson(raw);
71832
+ const workspace = normalizeWorkspace(raw);
71749
71833
  this.workspaces.set(workspace.id, workspace);
71834
+ if (migrated) {
71835
+ this.persistWorkspace(workspace);
71836
+ }
71750
71837
  }
71751
71838
  for (const file2 of this.readEntityFiles(this.artifactsDir)) {
71752
71839
  const artifact = this.readJsonFile(import_node_path2.default.join(this.artifactsDir, file2));
@@ -71758,7 +71845,7 @@ var WorkspaceStore = class extends Emitter {
71758
71845
  const workspace = {
71759
71846
  id: ulid3(),
71760
71847
  name: "Default",
71761
- artifactIDs: []
71848
+ layout: []
71762
71849
  };
71763
71850
  this.workspaces.set(workspace.id, workspace);
71764
71851
  this.persistWorkspace(workspace);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telepath-computer/television",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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:electron",
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 .",