@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
package/dist/electron.cjs
CHANGED
|
@@ -73484,13 +73484,21 @@ var Server2 = class {
|
|
|
73484
73484
|
});
|
|
73485
73485
|
}
|
|
73486
73486
|
start() {
|
|
73487
|
-
return new Promise((resolve) => {
|
|
73488
|
-
|
|
73487
|
+
return new Promise((resolve, reject) => {
|
|
73488
|
+
const handleError = (error2) => {
|
|
73489
|
+
this.httpServer.off("listening", handleListening);
|
|
73490
|
+
reject(error2);
|
|
73491
|
+
};
|
|
73492
|
+
const handleListening = () => {
|
|
73493
|
+
this.httpServer.off("error", handleError);
|
|
73489
73494
|
const address = this.httpServer.address();
|
|
73490
73495
|
const resolvedPort = typeof address === "object" && address ? address.port : this.port;
|
|
73491
73496
|
this.baseURL = buildServerURL(this.host ?? DEFAULT_SERVER_HOST, resolvedPort);
|
|
73492
73497
|
resolve(this.httpServer);
|
|
73493
|
-
}
|
|
73498
|
+
};
|
|
73499
|
+
this.httpServer.once("error", handleError);
|
|
73500
|
+
this.httpServer.once("listening", handleListening);
|
|
73501
|
+
this.httpServer.listen(this.port, this.host);
|
|
73494
73502
|
});
|
|
73495
73503
|
}
|
|
73496
73504
|
getBaseURL() {
|
|
@@ -73641,15 +73649,29 @@ function isClientMessage(value) {
|
|
|
73641
73649
|
case "create-workspace":
|
|
73642
73650
|
return typeof message.id === "string" && typeof message.name === "string";
|
|
73643
73651
|
case "update-workspace":
|
|
73644
|
-
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(
|
|
73645
|
-
(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"
|
|
73646
|
-
));
|
|
73652
|
+
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));
|
|
73647
73653
|
case "delete-workspace":
|
|
73648
73654
|
return typeof message.workspaceID === "string";
|
|
73649
73655
|
default:
|
|
73650
73656
|
return false;
|
|
73651
73657
|
}
|
|
73652
73658
|
}
|
|
73659
|
+
function isLayoutNode(value) {
|
|
73660
|
+
if (typeof value !== "object" || value === null || !("type" in value)) {
|
|
73661
|
+
return false;
|
|
73662
|
+
}
|
|
73663
|
+
const node = value;
|
|
73664
|
+
switch (node.type) {
|
|
73665
|
+
case "card":
|
|
73666
|
+
return typeof node.id === "string" && typeof node.artifactID === "string" && (typeof node.width === "number" || node.width === "auto") && (typeof node.height === "number" || node.height === "auto");
|
|
73667
|
+
case "row":
|
|
73668
|
+
return typeof node.id === "string" && (typeof node.height === "number" || node.height === "auto") && Array.isArray(node.children) && node.children.every(isLayoutNode);
|
|
73669
|
+
case "stack":
|
|
73670
|
+
return typeof node.id === "string" && Array.isArray(node.children) && node.children.every(isLayoutNode);
|
|
73671
|
+
default:
|
|
73672
|
+
return false;
|
|
73673
|
+
}
|
|
73674
|
+
}
|
|
73653
73675
|
|
|
73654
73676
|
// node_modules/mitt/dist/mitt.mjs
|
|
73655
73677
|
function mitt_default(n) {
|
|
@@ -73701,54 +73723,324 @@ var import_node_crypto2 = require("node:crypto");
|
|
|
73701
73723
|
var import_node_fs2 = require("node:fs");
|
|
73702
73724
|
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
73703
73725
|
|
|
73726
|
+
// src/constants.ts
|
|
73727
|
+
var LAYOUT_FULL_WIDTH_UNITS = 4;
|
|
73728
|
+
var LAYOUT_FULL_HEIGHT_UNITS = 6;
|
|
73729
|
+
var MIN_LAYOUT_CARD_WIDTH_UNITS = 2;
|
|
73730
|
+
var MAX_LAYOUT_CARD_WIDTH_UNITS = LAYOUT_FULL_WIDTH_UNITS;
|
|
73731
|
+
var DEFAULT_LAYOUT_CARD_WIDTH = "auto";
|
|
73732
|
+
var DEFAULT_LAYOUT_CARD_HEIGHT = "auto";
|
|
73733
|
+
var DEFAULT_LAYOUT_UNIT = 120;
|
|
73734
|
+
var CARD_GAP = 16;
|
|
73735
|
+
var CARD_WIDTH = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_WIDTH_UNITS + CARD_GAP * (LAYOUT_FULL_WIDTH_UNITS - 1);
|
|
73736
|
+
var CARD_HEIGHT = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_HEIGHT_UNITS + CARD_GAP * (LAYOUT_FULL_HEIGHT_UNITS - 1);
|
|
73737
|
+
|
|
73704
73738
|
// src/types.ts
|
|
73705
|
-
|
|
73706
|
-
var DEFAULT_LAYOUT_CARD_ROWS = 6;
|
|
73707
|
-
var LAYOUT_COLS_NARROW = 1;
|
|
73708
|
-
var LAYOUT_ROW_SHORT = 2;
|
|
73709
|
-
var LAYOUT_ROW_MID = 3;
|
|
73710
|
-
var LAYOUT_ROW_TALL = 4;
|
|
73711
|
-
var ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
|
|
73712
|
-
var ALLOWED_ROWS = [
|
|
73713
|
-
LAYOUT_ROW_SHORT,
|
|
73714
|
-
LAYOUT_ROW_MID,
|
|
73715
|
-
LAYOUT_ROW_TALL,
|
|
73716
|
-
DEFAULT_LAYOUT_CARD_ROWS
|
|
73717
|
-
];
|
|
73718
|
-
function clampLayoutCols(cols) {
|
|
73719
|
-
const n = Math.round(cols);
|
|
73720
|
-
return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
|
|
73721
|
-
}
|
|
73722
|
-
function clampLayoutRows(rows) {
|
|
73723
|
-
const n = Math.round(rows);
|
|
73724
|
-
return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
|
|
73725
|
-
}
|
|
73726
|
-
function createLayoutCardRecord(artifactID) {
|
|
73739
|
+
function createCardNode(artifactID, overrides = {}) {
|
|
73727
73740
|
return {
|
|
73728
|
-
|
|
73741
|
+
id: overrides.id ?? ulid3(),
|
|
73742
|
+
type: "card",
|
|
73729
73743
|
artifactID,
|
|
73730
|
-
|
|
73731
|
-
|
|
73744
|
+
width: overrides.width ?? DEFAULT_LAYOUT_CARD_WIDTH,
|
|
73745
|
+
height: overrides.height ?? DEFAULT_LAYOUT_CARD_HEIGHT
|
|
73732
73746
|
};
|
|
73733
73747
|
}
|
|
73734
|
-
function
|
|
73748
|
+
function layoutContainsArtifactID(layout, artifactID) {
|
|
73749
|
+
return layout.some((node) => nodeContainsArtifactID(node, artifactID));
|
|
73750
|
+
}
|
|
73751
|
+
function nodeContainsArtifactID(node, artifactID) {
|
|
73752
|
+
switch (node.type) {
|
|
73753
|
+
case "card":
|
|
73754
|
+
return node.artifactID === artifactID;
|
|
73755
|
+
case "row":
|
|
73756
|
+
return node.children.some((child) => child.artifactID === artifactID);
|
|
73757
|
+
case "stack":
|
|
73758
|
+
return node.children.some((child) => nodeContainsArtifactID(child, artifactID));
|
|
73759
|
+
}
|
|
73760
|
+
}
|
|
73761
|
+
function getWorkspaceArtifactIDs(workspace) {
|
|
73762
|
+
return workspace.layout.flatMap(collectArtifactIDs);
|
|
73763
|
+
}
|
|
73764
|
+
function collectArtifactIDs(node) {
|
|
73765
|
+
switch (node.type) {
|
|
73766
|
+
case "card":
|
|
73767
|
+
return [node.artifactID];
|
|
73768
|
+
case "row":
|
|
73769
|
+
return node.children.map((child) => child.artifactID);
|
|
73770
|
+
case "stack":
|
|
73771
|
+
return node.children.flatMap(collectArtifactIDs);
|
|
73772
|
+
}
|
|
73773
|
+
}
|
|
73774
|
+
|
|
73775
|
+
// src/browser/ui/layout.ts
|
|
73776
|
+
var LEGACY_BAND_HEIGHT_ROWS = 6;
|
|
73777
|
+
var LEGACY_NARROW_COLS = 1;
|
|
73778
|
+
var LEGACY_FULL_COLS = 2;
|
|
73779
|
+
var LEGACY_ROW_SHORT = 2;
|
|
73780
|
+
var LEGACY_ROW_MID = 3;
|
|
73781
|
+
var LEGACY_ROW_TALL = 4;
|
|
73782
|
+
var LEGACY_ROW_FULL = 6;
|
|
73783
|
+
var LEGACY_ALLOWED_ROWS = [LEGACY_ROW_SHORT, LEGACY_ROW_MID, LEGACY_ROW_TALL, LEGACY_ROW_FULL];
|
|
73784
|
+
var LEGACY_LEFT_X = 0;
|
|
73785
|
+
var LEGACY_RIGHT_X = 1;
|
|
73786
|
+
function removeArtifactFromLayout(layout, artifactID) {
|
|
73787
|
+
return normalizeRootNodes(layout.flatMap((node) => removeArtifactFromNode(node, artifactID)));
|
|
73788
|
+
}
|
|
73789
|
+
function migrateLegacyLayout(cards) {
|
|
73790
|
+
const normalized = cards.map((card) => ({
|
|
73791
|
+
artifactID: card.artifactID,
|
|
73792
|
+
width: normalizeLegacyCols(card.width),
|
|
73793
|
+
height: normalizeLegacyRows(card.height)
|
|
73794
|
+
}));
|
|
73795
|
+
const bands = deriveLegacyBands(normalized);
|
|
73796
|
+
return normalizeRootNodes(bands.flatMap(buildNodesForLegacyBand));
|
|
73797
|
+
}
|
|
73798
|
+
function normalizeRootNodes(layout) {
|
|
73799
|
+
const normalized = [];
|
|
73800
|
+
for (const node of layout) {
|
|
73801
|
+
const entries = normalizeNode(node);
|
|
73802
|
+
for (const entry of entries) {
|
|
73803
|
+
if (entry.type === "row") {
|
|
73804
|
+
normalized.push(...entry.children.map(cloneCard));
|
|
73805
|
+
continue;
|
|
73806
|
+
}
|
|
73807
|
+
normalized.push(entry);
|
|
73808
|
+
}
|
|
73809
|
+
}
|
|
73810
|
+
return normalized;
|
|
73811
|
+
}
|
|
73812
|
+
function normalizeNode(node) {
|
|
73813
|
+
switch (node.type) {
|
|
73814
|
+
case "card":
|
|
73815
|
+
return [cloneCard(node)];
|
|
73816
|
+
case "row": {
|
|
73817
|
+
const children = node.children.map(cloneCard);
|
|
73818
|
+
if (children.length === 0) {
|
|
73819
|
+
return [];
|
|
73820
|
+
}
|
|
73821
|
+
if (children.length === 1) {
|
|
73822
|
+
return [children[0]];
|
|
73823
|
+
}
|
|
73824
|
+
return [{ ...node, children }];
|
|
73825
|
+
}
|
|
73826
|
+
case "stack": {
|
|
73827
|
+
const children = [];
|
|
73828
|
+
for (const child of node.children) {
|
|
73829
|
+
const normalizedChildren = normalizeNode(child);
|
|
73830
|
+
for (const normalizedChild of normalizedChildren) {
|
|
73831
|
+
if (normalizedChild.type === "stack") {
|
|
73832
|
+
children.push(...normalizedChild.children.map(cloneStackChild));
|
|
73833
|
+
continue;
|
|
73834
|
+
}
|
|
73835
|
+
if (normalizedChild.type === "row") {
|
|
73836
|
+
children.push({
|
|
73837
|
+
...normalizedChild,
|
|
73838
|
+
children: normalizedChild.children.map(cloneCard)
|
|
73839
|
+
});
|
|
73840
|
+
continue;
|
|
73841
|
+
}
|
|
73842
|
+
children.push(cloneCard(normalizedChild));
|
|
73843
|
+
}
|
|
73844
|
+
}
|
|
73845
|
+
if (children.length === 0) {
|
|
73846
|
+
return [];
|
|
73847
|
+
}
|
|
73848
|
+
if (children.length === 1) {
|
|
73849
|
+
return [cloneStackChild(children[0])];
|
|
73850
|
+
}
|
|
73851
|
+
return [{ ...node, children }];
|
|
73852
|
+
}
|
|
73853
|
+
}
|
|
73854
|
+
}
|
|
73855
|
+
function removeArtifactFromNode(node, artifactID) {
|
|
73856
|
+
switch (node.type) {
|
|
73857
|
+
case "card":
|
|
73858
|
+
return node.artifactID === artifactID ? [] : [cloneCard(node)];
|
|
73859
|
+
case "row": {
|
|
73860
|
+
const children = node.children.filter((child) => child.artifactID !== artifactID).map(cloneCard);
|
|
73861
|
+
if (children.length === 0) {
|
|
73862
|
+
return [];
|
|
73863
|
+
}
|
|
73864
|
+
if (children.length === 1) {
|
|
73865
|
+
return [children[0]];
|
|
73866
|
+
}
|
|
73867
|
+
return [{ ...node, children }];
|
|
73868
|
+
}
|
|
73869
|
+
case "stack": {
|
|
73870
|
+
const children = node.children.flatMap((child) => {
|
|
73871
|
+
const removed = removeArtifactFromNode(child, artifactID);
|
|
73872
|
+
return removed.filter((entry) => entry.type !== "stack");
|
|
73873
|
+
});
|
|
73874
|
+
if (children.length === 0) {
|
|
73875
|
+
return [];
|
|
73876
|
+
}
|
|
73877
|
+
if (children.length === 1) {
|
|
73878
|
+
return [cloneStackChild(children[0])];
|
|
73879
|
+
}
|
|
73880
|
+
return [{ ...node, children }];
|
|
73881
|
+
}
|
|
73882
|
+
}
|
|
73883
|
+
}
|
|
73884
|
+
function normalizeLegacyCols(width) {
|
|
73885
|
+
return Math.round(width) === LEGACY_NARROW_COLS ? LEGACY_NARROW_COLS : LEGACY_FULL_COLS;
|
|
73886
|
+
}
|
|
73887
|
+
function normalizeLegacyRows(height) {
|
|
73888
|
+
const rounded = Math.round(height);
|
|
73889
|
+
return LEGACY_ALLOWED_ROWS.includes(rounded) ? rounded : LEGACY_BAND_HEIGHT_ROWS;
|
|
73890
|
+
}
|
|
73891
|
+
function deriveLegacyBands(cards) {
|
|
73892
|
+
const bands = [];
|
|
73893
|
+
let current = null;
|
|
73894
|
+
for (const card of cards) {
|
|
73895
|
+
if (!current) {
|
|
73896
|
+
const placements = packLegacyBand([card], card.width);
|
|
73897
|
+
if (!placements) {
|
|
73898
|
+
continue;
|
|
73899
|
+
}
|
|
73900
|
+
current = {
|
|
73901
|
+
width: card.width,
|
|
73902
|
+
placements
|
|
73903
|
+
};
|
|
73904
|
+
continue;
|
|
73905
|
+
}
|
|
73906
|
+
const nextCards = current.placements.map((placement) => ({
|
|
73907
|
+
artifactID: placement.artifactID,
|
|
73908
|
+
width: placement.width,
|
|
73909
|
+
height: placement.height
|
|
73910
|
+
})).concat(card);
|
|
73911
|
+
let nextWidth = current.width;
|
|
73912
|
+
let packed = packLegacyBand(nextCards, nextWidth);
|
|
73913
|
+
if (!packed && current.width < LEGACY_FULL_COLS && card.width > current.width) {
|
|
73914
|
+
nextWidth = LEGACY_FULL_COLS;
|
|
73915
|
+
packed = packLegacyBand(nextCards, nextWidth);
|
|
73916
|
+
}
|
|
73917
|
+
if (packed) {
|
|
73918
|
+
current = {
|
|
73919
|
+
width: nextWidth,
|
|
73920
|
+
placements: packed
|
|
73921
|
+
};
|
|
73922
|
+
continue;
|
|
73923
|
+
}
|
|
73924
|
+
bands.push(current);
|
|
73925
|
+
const newPlacements = packLegacyBand([card], card.width);
|
|
73926
|
+
if (!newPlacements) {
|
|
73927
|
+
current = null;
|
|
73928
|
+
continue;
|
|
73929
|
+
}
|
|
73930
|
+
current = {
|
|
73931
|
+
width: card.width,
|
|
73932
|
+
placements: newPlacements
|
|
73933
|
+
};
|
|
73934
|
+
}
|
|
73935
|
+
if (current) {
|
|
73936
|
+
bands.push(current);
|
|
73937
|
+
}
|
|
73938
|
+
return bands;
|
|
73939
|
+
}
|
|
73940
|
+
function packLegacyBand(cards, width) {
|
|
73941
|
+
const occupied = Array.from(
|
|
73942
|
+
{ length: LEGACY_BAND_HEIGHT_ROWS },
|
|
73943
|
+
() => Array.from({ length: width }, () => false)
|
|
73944
|
+
);
|
|
73945
|
+
const placements = [];
|
|
73946
|
+
for (const card of cards) {
|
|
73947
|
+
const position = firstLegacyFit(occupied, width, card);
|
|
73948
|
+
if (!position) {
|
|
73949
|
+
return null;
|
|
73950
|
+
}
|
|
73951
|
+
const placement = {
|
|
73952
|
+
artifactID: card.artifactID,
|
|
73953
|
+
width: card.width,
|
|
73954
|
+
height: card.height,
|
|
73955
|
+
x: position.x,
|
|
73956
|
+
y: position.y
|
|
73957
|
+
};
|
|
73958
|
+
placeLegacyCard(occupied, placement);
|
|
73959
|
+
placements.push(placement);
|
|
73960
|
+
}
|
|
73961
|
+
return placements;
|
|
73962
|
+
}
|
|
73963
|
+
function firstLegacyFit(occupied, width, card) {
|
|
73964
|
+
if (card.width > width || card.height > LEGACY_BAND_HEIGHT_ROWS) {
|
|
73965
|
+
return null;
|
|
73966
|
+
}
|
|
73967
|
+
for (let y2 = 0; y2 <= LEGACY_BAND_HEIGHT_ROWS - card.height; y2 += 1) {
|
|
73968
|
+
for (let x2 = 0; x2 <= width - card.width; x2 += 1) {
|
|
73969
|
+
let fits = true;
|
|
73970
|
+
for (let yy = y2; yy < y2 + card.height && fits; yy += 1) {
|
|
73971
|
+
for (let xx = x2; xx < x2 + card.width; xx += 1) {
|
|
73972
|
+
if (occupied[yy]?.[xx]) {
|
|
73973
|
+
fits = false;
|
|
73974
|
+
break;
|
|
73975
|
+
}
|
|
73976
|
+
}
|
|
73977
|
+
}
|
|
73978
|
+
if (fits) {
|
|
73979
|
+
return { x: x2, y: y2 };
|
|
73980
|
+
}
|
|
73981
|
+
}
|
|
73982
|
+
}
|
|
73983
|
+
return null;
|
|
73984
|
+
}
|
|
73985
|
+
function placeLegacyCard(occupied, placement) {
|
|
73986
|
+
for (let yy = placement.y; yy < placement.y + placement.height; yy += 1) {
|
|
73987
|
+
for (let xx = placement.x; xx < placement.x + placement.width; xx += 1) {
|
|
73988
|
+
occupied[yy][xx] = true;
|
|
73989
|
+
}
|
|
73990
|
+
}
|
|
73991
|
+
}
|
|
73992
|
+
function buildNodesForLegacyBand(band) {
|
|
73993
|
+
const placements = [...band.placements].sort((a, b2) => a.y - b2.y || a.x - b2.x);
|
|
73994
|
+
const children = [];
|
|
73995
|
+
for (let index = 0; index < placements.length; index += 1) {
|
|
73996
|
+
const current = placements[index];
|
|
73997
|
+
const next = placements[index + 1];
|
|
73998
|
+
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) {
|
|
73999
|
+
children.push({
|
|
74000
|
+
id: ulid3(),
|
|
74001
|
+
type: "row",
|
|
74002
|
+
height: current.height,
|
|
74003
|
+
children: [migrateLegacyCard(current), migrateLegacyCard(next)]
|
|
74004
|
+
});
|
|
74005
|
+
index += 1;
|
|
74006
|
+
continue;
|
|
74007
|
+
}
|
|
74008
|
+
children.push(migrateLegacyCard(current));
|
|
74009
|
+
}
|
|
74010
|
+
if (children.length === 0) {
|
|
74011
|
+
return [];
|
|
74012
|
+
}
|
|
74013
|
+
if (children.length === 1) {
|
|
74014
|
+
const child = children[0];
|
|
74015
|
+
return child.type === "row" ? child.children.map(cloneCard) : [cloneCard(child)];
|
|
74016
|
+
}
|
|
74017
|
+
return [
|
|
74018
|
+
{
|
|
74019
|
+
id: ulid3(),
|
|
74020
|
+
type: "stack",
|
|
74021
|
+
children
|
|
74022
|
+
}
|
|
74023
|
+
];
|
|
74024
|
+
}
|
|
74025
|
+
function migrateLegacyCard(card) {
|
|
73735
74026
|
return {
|
|
73736
|
-
|
|
74027
|
+
id: ulid3(),
|
|
74028
|
+
type: "card",
|
|
73737
74029
|
artifactID: card.artifactID,
|
|
73738
|
-
|
|
73739
|
-
|
|
74030
|
+
width: card.width === LEGACY_NARROW_COLS ? MIN_LAYOUT_CARD_WIDTH_UNITS : MAX_LAYOUT_CARD_WIDTH_UNITS,
|
|
74031
|
+
height: card.height
|
|
73740
74032
|
};
|
|
73741
74033
|
}
|
|
73742
|
-
function
|
|
73743
|
-
const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => sanitizeLayoutCard(card)) : [];
|
|
74034
|
+
function cloneCard(node) {
|
|
73744
74035
|
return {
|
|
73745
|
-
|
|
73746
|
-
name: workspace.name,
|
|
73747
|
-
layout
|
|
74036
|
+
...node
|
|
73748
74037
|
};
|
|
73749
74038
|
}
|
|
73750
|
-
function
|
|
73751
|
-
return
|
|
74039
|
+
function cloneStackChild(node) {
|
|
74040
|
+
return node.type === "card" ? cloneCard(node) : {
|
|
74041
|
+
...node,
|
|
74042
|
+
children: node.children.map(cloneCard)
|
|
74043
|
+
};
|
|
73752
74044
|
}
|
|
73753
74045
|
|
|
73754
74046
|
// src/server/server-store.ts
|
|
@@ -73768,26 +74060,51 @@ function validateHTMLFragment(content) {
|
|
|
73768
74060
|
}
|
|
73769
74061
|
}
|
|
73770
74062
|
function migrateWorkspaceJson(raw) {
|
|
73771
|
-
if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
|
|
73772
|
-
return false;
|
|
73773
|
-
}
|
|
73774
74063
|
if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
|
|
73775
74064
|
raw.layout = raw.artifacts;
|
|
73776
74065
|
delete raw.artifacts;
|
|
73777
74066
|
return true;
|
|
73778
74067
|
}
|
|
73779
74068
|
if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
|
|
73780
|
-
raw.layout = raw.artifactIDs.map((id) => ({
|
|
73781
|
-
type: "artifact",
|
|
73782
|
-
artifactID: id,
|
|
73783
|
-
cols: DEFAULT_COLS,
|
|
73784
|
-
rows: DEFAULT_ROWS
|
|
73785
|
-
}));
|
|
74069
|
+
raw.layout = raw.artifactIDs.map((id) => ({ artifactID: id, width: DEFAULT_COLS, height: DEFAULT_ROWS }));
|
|
73786
74070
|
delete raw.artifactIDs;
|
|
73787
74071
|
return true;
|
|
73788
74072
|
}
|
|
73789
74073
|
return false;
|
|
73790
74074
|
}
|
|
74075
|
+
function deserializeWorkspaceData(workspace) {
|
|
74076
|
+
const rawLayout = workspace.layout;
|
|
74077
|
+
if (!Array.isArray(rawLayout)) {
|
|
74078
|
+
return {
|
|
74079
|
+
migrated: false,
|
|
74080
|
+
workspace: {
|
|
74081
|
+
id: workspace.id,
|
|
74082
|
+
name: workspace.name,
|
|
74083
|
+
layout: []
|
|
74084
|
+
}
|
|
74085
|
+
};
|
|
74086
|
+
}
|
|
74087
|
+
if (rawLayout.every(
|
|
74088
|
+
(node) => typeof node === "object" && node !== null && "type" in node && (node.type === "card" || node.type === "stack")
|
|
74089
|
+
)) {
|
|
74090
|
+
return {
|
|
74091
|
+
migrated: false,
|
|
74092
|
+
workspace: {
|
|
74093
|
+
id: workspace.id,
|
|
74094
|
+
name: workspace.name,
|
|
74095
|
+
layout: rawLayout
|
|
74096
|
+
}
|
|
74097
|
+
};
|
|
74098
|
+
}
|
|
74099
|
+
return {
|
|
74100
|
+
migrated: true,
|
|
74101
|
+
workspace: {
|
|
74102
|
+
id: workspace.id,
|
|
74103
|
+
name: workspace.name,
|
|
74104
|
+
layout: migrateLegacyLayout(rawLayout)
|
|
74105
|
+
}
|
|
74106
|
+
};
|
|
74107
|
+
}
|
|
73791
74108
|
var ServerStore = class extends Emitter {
|
|
73792
74109
|
dataDir;
|
|
73793
74110
|
workspaces = /* @__PURE__ */ new Map();
|
|
@@ -73821,7 +74138,7 @@ var ServerStore = class extends Emitter {
|
|
|
73821
74138
|
}
|
|
73822
74139
|
findArtifactWorkspaces(artifactID) {
|
|
73823
74140
|
return [...this.workspaces.values()].filter(
|
|
73824
|
-
(workspace) => workspace.layout
|
|
74141
|
+
(workspace) => layoutContainsArtifactID(workspace.layout, artifactID)
|
|
73825
74142
|
);
|
|
73826
74143
|
}
|
|
73827
74144
|
createArtifact(input) {
|
|
@@ -73839,7 +74156,7 @@ var ServerStore = class extends Emitter {
|
|
|
73839
74156
|
content: input.content
|
|
73840
74157
|
});
|
|
73841
74158
|
this.artifacts.set(artifact.id, artifact);
|
|
73842
|
-
workspace.layout.
|
|
74159
|
+
workspace.layout = [...workspace.layout, createCardNode(artifact.id)];
|
|
73843
74160
|
this.persistArtifact(artifact);
|
|
73844
74161
|
this.persistWorkspace(workspace);
|
|
73845
74162
|
this.emit("mutation", {
|
|
@@ -73872,11 +74189,11 @@ var ServerStore = class extends Emitter {
|
|
|
73872
74189
|
throw new Error(`Artifact not found: ${input.artifactID}`);
|
|
73873
74190
|
}
|
|
73874
74191
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
73875
|
-
if (!workspace.layout
|
|
74192
|
+
if (!layoutContainsArtifactID(workspace.layout, input.artifactID)) {
|
|
73876
74193
|
throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
|
|
73877
74194
|
}
|
|
73878
74195
|
this.artifacts.delete(input.artifactID);
|
|
73879
|
-
workspace.layout = workspace.layout
|
|
74196
|
+
workspace.layout = removeArtifactFromLayout(workspace.layout, input.artifactID);
|
|
73880
74197
|
this.persistWorkspace(workspace);
|
|
73881
74198
|
this.deleteArtifactFile(input.artifactID);
|
|
73882
74199
|
this.emit("mutation", {
|
|
@@ -73907,7 +74224,7 @@ var ServerStore = class extends Emitter {
|
|
|
73907
74224
|
nextFields.name = input.fields.name;
|
|
73908
74225
|
}
|
|
73909
74226
|
if (Array.isArray(input.fields.layout)) {
|
|
73910
|
-
workspace.layout = input.fields.layout.map((
|
|
74227
|
+
workspace.layout = input.fields.layout.map((node) => structuredClone(node));
|
|
73911
74228
|
nextFields.layout = workspace.layout;
|
|
73912
74229
|
}
|
|
73913
74230
|
this.persistWorkspace(workspace);
|
|
@@ -73945,10 +74262,10 @@ var ServerStore = class extends Emitter {
|
|
|
73945
74262
|
const filePath = import_node_path3.default.join(this.workspacesDir, file2);
|
|
73946
74263
|
const raw = this.readJsonFile(filePath);
|
|
73947
74264
|
if (!raw || typeof raw !== "object") continue;
|
|
73948
|
-
const
|
|
73949
|
-
const workspace =
|
|
74265
|
+
const renamedLegacyFields = migrateWorkspaceJson(raw);
|
|
74266
|
+
const { workspace, migrated } = deserializeWorkspaceData(raw);
|
|
73950
74267
|
this.workspaces.set(workspace.id, workspace);
|
|
73951
|
-
if (migrated) {
|
|
74268
|
+
if (renamedLegacyFields || migrated) {
|
|
73952
74269
|
this.persistWorkspace(workspace);
|
|
73953
74270
|
}
|
|
73954
74271
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telepath-computer/television",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/electron.cjs",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"dev": "npm run dev:server",
|
|
15
15
|
"dev:electron": "scripts/dev-electron.sh",
|
|
16
16
|
"dev:server": "scripts/dev-server.sh",
|
|
17
|
-
"
|
|
17
|
+
"layout": "vite --config config/vite.demo-layout.ts --host 127.0.0.1",
|
|
18
18
|
"build": "npm run build:artifact-runtime && npm run build:renderer && npm run build:cli && npm run build:electron",
|
|
19
19
|
"prepack": "npm run build",
|
|
20
20
|
"start": "npm run build && env -u ELECTRON_RUN_AS_NODE electron .",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
"lint:fix": "npm run lint -- --fix",
|
|
23
23
|
"type-check": "tsc --noEmit",
|
|
24
24
|
"test:setup": "playwright install chromium",
|
|
25
|
-
"test": "vitest run",
|
|
25
|
+
"test:core": "vitest run test/main.test.ts test/layout.test.ts test/television-client.test.ts test/workspace-service.test.ts test/browser-server.test.ts test/server-manager.test.ts test/server-store.test.ts test/artifacts.test.ts test/artifact-runtime.test.ts test/html-artifact-srcdoc.test.ts test/demo-layout-state.test.ts test/server.test.ts test/cli.test.ts",
|
|
26
|
+
"test:ui": "vitest run test/client-store.test.ts test/runtime.test.ts test/renderer.test.ts test/artifact-view.test.ts test/layout-stream.test.ts test/drag-controller.test.ts test/layout-mutations.test.ts test/workspace-view.test.ts test/app-root.test.ts",
|
|
27
|
+
"test": "npm run test:core && npm run test:ui",
|
|
26
28
|
"test:e2e": "playwright test --config=playwright.config.ts",
|
|
27
29
|
"test:electron": "npm run build && playwright test --config=playwright.electron.config.ts",
|
|
28
30
|
"test:all": "npm test && npm run test:e2e && npm run test:electron",
|