@telepath-computer/television 0.1.8 → 0.1.10
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-AgM_sD_q.js +394 -0
- package/dist/browser/assets/index-CmOTsDN-.css +1 -0
- package/dist/browser/index.html +2 -2
- package/dist/cli.cjs +497 -139
- package/dist/electron.cjs +497 -139
- package/package.json +6 -5
- package/dist/browser/assets/index-C3ygXWMh.js +0 -396
- package/dist/browser/assets/index-nGpvLl78.css +0 -1
package/dist/electron.cjs
CHANGED
|
@@ -54682,7 +54682,7 @@ var require_event_target = __commonJS({
|
|
|
54682
54682
|
var kTarget = Symbol("kTarget");
|
|
54683
54683
|
var kType = Symbol("kType");
|
|
54684
54684
|
var kWasClean = Symbol("kWasClean");
|
|
54685
|
-
var
|
|
54685
|
+
var Event2 = class {
|
|
54686
54686
|
/**
|
|
54687
54687
|
* Create a new `Event`.
|
|
54688
54688
|
*
|
|
@@ -54706,9 +54706,9 @@ var require_event_target = __commonJS({
|
|
|
54706
54706
|
return this[kType];
|
|
54707
54707
|
}
|
|
54708
54708
|
};
|
|
54709
|
-
Object.defineProperty(
|
|
54710
|
-
Object.defineProperty(
|
|
54711
|
-
var CloseEvent = class extends
|
|
54709
|
+
Object.defineProperty(Event2.prototype, "target", { enumerable: true });
|
|
54710
|
+
Object.defineProperty(Event2.prototype, "type", { enumerable: true });
|
|
54711
|
+
var CloseEvent = class extends Event2 {
|
|
54712
54712
|
/**
|
|
54713
54713
|
* Create a new `CloseEvent`.
|
|
54714
54714
|
*
|
|
@@ -54750,7 +54750,7 @@ var require_event_target = __commonJS({
|
|
|
54750
54750
|
Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true });
|
|
54751
54751
|
Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true });
|
|
54752
54752
|
Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true });
|
|
54753
|
-
var ErrorEvent = class extends
|
|
54753
|
+
var ErrorEvent = class extends Event2 {
|
|
54754
54754
|
/**
|
|
54755
54755
|
* Create a new `ErrorEvent`.
|
|
54756
54756
|
*
|
|
@@ -54780,7 +54780,7 @@ var require_event_target = __commonJS({
|
|
|
54780
54780
|
};
|
|
54781
54781
|
Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true });
|
|
54782
54782
|
Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true });
|
|
54783
|
-
var MessageEvent = class extends
|
|
54783
|
+
var MessageEvent = class extends Event2 {
|
|
54784
54784
|
/**
|
|
54785
54785
|
* Create a new `MessageEvent`.
|
|
54786
54786
|
*
|
|
@@ -54801,7 +54801,7 @@ var require_event_target = __commonJS({
|
|
|
54801
54801
|
}
|
|
54802
54802
|
};
|
|
54803
54803
|
Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
|
|
54804
|
-
var
|
|
54804
|
+
var EventTarget2 = {
|
|
54805
54805
|
/**
|
|
54806
54806
|
* Register an event listener.
|
|
54807
54807
|
*
|
|
@@ -54850,7 +54850,7 @@ var require_event_target = __commonJS({
|
|
|
54850
54850
|
};
|
|
54851
54851
|
} else if (type === "open") {
|
|
54852
54852
|
wrapper = function onOpen() {
|
|
54853
|
-
const event = new
|
|
54853
|
+
const event = new Event2("open");
|
|
54854
54854
|
event[kTarget] = this;
|
|
54855
54855
|
callListener(handler, this, event);
|
|
54856
54856
|
};
|
|
@@ -54884,8 +54884,8 @@ var require_event_target = __commonJS({
|
|
|
54884
54884
|
module2.exports = {
|
|
54885
54885
|
CloseEvent,
|
|
54886
54886
|
ErrorEvent,
|
|
54887
|
-
Event,
|
|
54888
|
-
EventTarget,
|
|
54887
|
+
Event: Event2,
|
|
54888
|
+
EventTarget: EventTarget2,
|
|
54889
54889
|
MessageEvent
|
|
54890
54890
|
};
|
|
54891
54891
|
function callListener(listener, thisArg, event) {
|
|
@@ -73479,18 +73479,26 @@ var Server2 = class {
|
|
|
73479
73479
|
this.handleClientMessage(socket, data.toString());
|
|
73480
73480
|
});
|
|
73481
73481
|
});
|
|
73482
|
-
this.store.
|
|
73483
|
-
this.broadcast(event);
|
|
73482
|
+
this.store.addEventListener("store-change", (event) => {
|
|
73483
|
+
this.broadcast(event.message);
|
|
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,114 +73649,415 @@ 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
|
}
|
|
73653
|
-
|
|
73654
|
-
|
|
73655
|
-
|
|
73656
|
-
|
|
73657
|
-
|
|
73658
|
-
|
|
73659
|
-
|
|
73660
|
-
|
|
73661
|
-
|
|
73662
|
-
|
|
73663
|
-
|
|
73664
|
-
|
|
73665
|
-
|
|
73666
|
-
|
|
73667
|
-
|
|
73668
|
-
});
|
|
73669
|
-
} };
|
|
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
|
+
}
|
|
73670
73674
|
}
|
|
73671
73675
|
|
|
73672
|
-
// node_modules/@rupertsworld/
|
|
73673
|
-
var
|
|
73674
|
-
|
|
73675
|
-
|
|
73676
|
-
|
|
73677
|
-
|
|
73676
|
+
// node_modules/@rupertsworld/event-target/dist/index.js
|
|
73677
|
+
var RESERVED_EVENT_KEYS = /* @__PURE__ */ new Set([
|
|
73678
|
+
"target",
|
|
73679
|
+
"currentTarget",
|
|
73680
|
+
"eventPhase",
|
|
73681
|
+
"defaultPrevented",
|
|
73682
|
+
"isTrusted",
|
|
73683
|
+
"timeStamp",
|
|
73684
|
+
"srcElement",
|
|
73685
|
+
"returnValue",
|
|
73686
|
+
"cancelBubble",
|
|
73687
|
+
"NONE",
|
|
73688
|
+
"CAPTURING_PHASE",
|
|
73689
|
+
"AT_TARGET",
|
|
73690
|
+
"BUBBLING_PHASE",
|
|
73691
|
+
"composedPath",
|
|
73692
|
+
"stopPropagation",
|
|
73693
|
+
"stopImmediatePropagation",
|
|
73694
|
+
"preventDefault",
|
|
73695
|
+
"initEvent"
|
|
73696
|
+
]);
|
|
73697
|
+
function assertNoReservedPayloadKeys(props) {
|
|
73698
|
+
for (const key of Object.keys(props)) {
|
|
73699
|
+
if (RESERVED_EVENT_KEYS.has(key)) {
|
|
73700
|
+
throw new Error(`Event payload key "${key}" is reserved; choose a different property name`);
|
|
73701
|
+
}
|
|
73678
73702
|
}
|
|
73679
|
-
|
|
73680
|
-
|
|
73681
|
-
|
|
73682
|
-
|
|
73683
|
-
|
|
73684
|
-
|
|
73685
|
-
|
|
73703
|
+
}
|
|
73704
|
+
function assignPayload(target, props) {
|
|
73705
|
+
assertNoReservedPayloadKeys(props);
|
|
73706
|
+
for (const key of Object.keys(props)) {
|
|
73707
|
+
Object.defineProperty(target, key, {
|
|
73708
|
+
value: props[key],
|
|
73709
|
+
writable: true,
|
|
73710
|
+
enumerable: true,
|
|
73711
|
+
configurable: true
|
|
73712
|
+
});
|
|
73686
73713
|
}
|
|
73687
|
-
|
|
73688
|
-
|
|
73689
|
-
|
|
73690
|
-
|
|
73691
|
-
|
|
73692
|
-
|
|
73693
|
-
|
|
73694
|
-
|
|
73695
|
-
|
|
73714
|
+
}
|
|
73715
|
+
function defineEvent() {
|
|
73716
|
+
class DefinedEvent extends Event {
|
|
73717
|
+
constructor(type, init) {
|
|
73718
|
+
const { type: initType, bubbles, cancelable, composed, ...payload } = init ?? {};
|
|
73719
|
+
if (initType !== void 0) {
|
|
73720
|
+
throw new Error(`Do not pass "type" in init; use the constructor argument instead`);
|
|
73721
|
+
}
|
|
73722
|
+
super(type, { bubbles, cancelable, composed });
|
|
73723
|
+
assignPayload(this, payload);
|
|
73724
|
+
}
|
|
73696
73725
|
}
|
|
73726
|
+
return DefinedEvent;
|
|
73727
|
+
}
|
|
73728
|
+
var EventTarget = class extends globalThis.EventTarget {
|
|
73697
73729
|
};
|
|
73698
73730
|
|
|
73731
|
+
// src/events.ts
|
|
73732
|
+
var ChangeEvent = defineEvent();
|
|
73733
|
+
var ServerMessageEvent = defineEvent();
|
|
73734
|
+
var LayoutMutationEvent = defineEvent();
|
|
73735
|
+
var LayoutScrollEvent = defineEvent();
|
|
73736
|
+
var StoreChangeEvent = defineEvent();
|
|
73737
|
+
|
|
73699
73738
|
// src/server/server-store.ts
|
|
73700
73739
|
var import_node_crypto2 = require("node:crypto");
|
|
73701
73740
|
var import_node_fs2 = require("node:fs");
|
|
73702
73741
|
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
73703
73742
|
|
|
73743
|
+
// src/constants.ts
|
|
73744
|
+
var LAYOUT_FULL_WIDTH_UNITS = 4;
|
|
73745
|
+
var LAYOUT_FULL_HEIGHT_UNITS = 6;
|
|
73746
|
+
var MIN_LAYOUT_CARD_WIDTH_UNITS = 2;
|
|
73747
|
+
var MAX_LAYOUT_CARD_WIDTH_UNITS = LAYOUT_FULL_WIDTH_UNITS;
|
|
73748
|
+
var DEFAULT_LAYOUT_CARD_WIDTH = "auto";
|
|
73749
|
+
var DEFAULT_LAYOUT_CARD_HEIGHT = "auto";
|
|
73750
|
+
var DEFAULT_LAYOUT_UNIT = 120;
|
|
73751
|
+
var CARD_GAP = 16;
|
|
73752
|
+
var CARD_WIDTH = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_WIDTH_UNITS + CARD_GAP * (LAYOUT_FULL_WIDTH_UNITS - 1);
|
|
73753
|
+
var CARD_HEIGHT = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_HEIGHT_UNITS + CARD_GAP * (LAYOUT_FULL_HEIGHT_UNITS - 1);
|
|
73754
|
+
|
|
73704
73755
|
// 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) {
|
|
73756
|
+
function createCardNode(artifactID, overrides = {}) {
|
|
73727
73757
|
return {
|
|
73728
|
-
|
|
73758
|
+
id: overrides.id ?? ulid3(),
|
|
73759
|
+
type: "card",
|
|
73729
73760
|
artifactID,
|
|
73730
|
-
|
|
73731
|
-
|
|
73761
|
+
width: overrides.width ?? DEFAULT_LAYOUT_CARD_WIDTH,
|
|
73762
|
+
height: overrides.height ?? DEFAULT_LAYOUT_CARD_HEIGHT
|
|
73732
73763
|
};
|
|
73733
73764
|
}
|
|
73734
|
-
function
|
|
73765
|
+
function layoutContainsArtifactID(layout, artifactID) {
|
|
73766
|
+
return layout.some((node) => nodeContainsArtifactID(node, artifactID));
|
|
73767
|
+
}
|
|
73768
|
+
function nodeContainsArtifactID(node, artifactID) {
|
|
73769
|
+
switch (node.type) {
|
|
73770
|
+
case "card":
|
|
73771
|
+
return node.artifactID === artifactID;
|
|
73772
|
+
case "row":
|
|
73773
|
+
return node.children.some((child) => child.artifactID === artifactID);
|
|
73774
|
+
case "stack":
|
|
73775
|
+
return node.children.some((child) => nodeContainsArtifactID(child, artifactID));
|
|
73776
|
+
}
|
|
73777
|
+
}
|
|
73778
|
+
function getWorkspaceArtifactIDs(workspace) {
|
|
73779
|
+
return workspace.layout.flatMap(collectArtifactIDs);
|
|
73780
|
+
}
|
|
73781
|
+
function collectArtifactIDs(node) {
|
|
73782
|
+
switch (node.type) {
|
|
73783
|
+
case "card":
|
|
73784
|
+
return [node.artifactID];
|
|
73785
|
+
case "row":
|
|
73786
|
+
return node.children.map((child) => child.artifactID);
|
|
73787
|
+
case "stack":
|
|
73788
|
+
return node.children.flatMap(collectArtifactIDs);
|
|
73789
|
+
}
|
|
73790
|
+
}
|
|
73791
|
+
|
|
73792
|
+
// src/browser/ui/layout.ts
|
|
73793
|
+
var LEGACY_BAND_HEIGHT_ROWS = 6;
|
|
73794
|
+
var LEGACY_NARROW_COLS = 1;
|
|
73795
|
+
var LEGACY_FULL_COLS = 2;
|
|
73796
|
+
var LEGACY_ROW_SHORT = 2;
|
|
73797
|
+
var LEGACY_ROW_MID = 3;
|
|
73798
|
+
var LEGACY_ROW_TALL = 4;
|
|
73799
|
+
var LEGACY_ROW_FULL = 6;
|
|
73800
|
+
var LEGACY_ALLOWED_ROWS = [LEGACY_ROW_SHORT, LEGACY_ROW_MID, LEGACY_ROW_TALL, LEGACY_ROW_FULL];
|
|
73801
|
+
var LEGACY_LEFT_X = 0;
|
|
73802
|
+
var LEGACY_RIGHT_X = 1;
|
|
73803
|
+
function removeArtifactFromLayout(layout, artifactID) {
|
|
73804
|
+
return normalizeRootNodes(layout.flatMap((node) => removeArtifactFromNode(node, artifactID)));
|
|
73805
|
+
}
|
|
73806
|
+
function migrateLegacyLayout(cards) {
|
|
73807
|
+
const normalized = cards.map((card) => ({
|
|
73808
|
+
artifactID: card.artifactID,
|
|
73809
|
+
width: normalizeLegacyCols(card.width),
|
|
73810
|
+
height: normalizeLegacyRows(card.height)
|
|
73811
|
+
}));
|
|
73812
|
+
const bands = deriveLegacyBands(normalized);
|
|
73813
|
+
return normalizeRootNodes(bands.flatMap(buildNodesForLegacyBand));
|
|
73814
|
+
}
|
|
73815
|
+
function normalizeRootNodes(layout) {
|
|
73816
|
+
const normalized = [];
|
|
73817
|
+
for (const node of layout) {
|
|
73818
|
+
const entries = normalizeNode(node);
|
|
73819
|
+
for (const entry of entries) {
|
|
73820
|
+
if (entry.type === "row") {
|
|
73821
|
+
normalized.push(...entry.children.map(cloneCard));
|
|
73822
|
+
continue;
|
|
73823
|
+
}
|
|
73824
|
+
normalized.push(entry);
|
|
73825
|
+
}
|
|
73826
|
+
}
|
|
73827
|
+
return normalized;
|
|
73828
|
+
}
|
|
73829
|
+
function normalizeNode(node) {
|
|
73830
|
+
switch (node.type) {
|
|
73831
|
+
case "card":
|
|
73832
|
+
return [cloneCard(node)];
|
|
73833
|
+
case "row": {
|
|
73834
|
+
const children = node.children.map(cloneCard);
|
|
73835
|
+
if (children.length === 0) {
|
|
73836
|
+
return [];
|
|
73837
|
+
}
|
|
73838
|
+
if (children.length === 1) {
|
|
73839
|
+
return [children[0]];
|
|
73840
|
+
}
|
|
73841
|
+
return [{ ...node, children }];
|
|
73842
|
+
}
|
|
73843
|
+
case "stack": {
|
|
73844
|
+
const children = [];
|
|
73845
|
+
for (const child of node.children) {
|
|
73846
|
+
const normalizedChildren = normalizeNode(child);
|
|
73847
|
+
for (const normalizedChild of normalizedChildren) {
|
|
73848
|
+
if (normalizedChild.type === "stack") {
|
|
73849
|
+
children.push(...normalizedChild.children.map(cloneStackChild));
|
|
73850
|
+
continue;
|
|
73851
|
+
}
|
|
73852
|
+
if (normalizedChild.type === "row") {
|
|
73853
|
+
children.push({
|
|
73854
|
+
...normalizedChild,
|
|
73855
|
+
children: normalizedChild.children.map(cloneCard)
|
|
73856
|
+
});
|
|
73857
|
+
continue;
|
|
73858
|
+
}
|
|
73859
|
+
children.push(cloneCard(normalizedChild));
|
|
73860
|
+
}
|
|
73861
|
+
}
|
|
73862
|
+
if (children.length === 0) {
|
|
73863
|
+
return [];
|
|
73864
|
+
}
|
|
73865
|
+
if (children.length === 1) {
|
|
73866
|
+
return [cloneStackChild(children[0])];
|
|
73867
|
+
}
|
|
73868
|
+
return [{ ...node, children }];
|
|
73869
|
+
}
|
|
73870
|
+
}
|
|
73871
|
+
}
|
|
73872
|
+
function removeArtifactFromNode(node, artifactID) {
|
|
73873
|
+
switch (node.type) {
|
|
73874
|
+
case "card":
|
|
73875
|
+
return node.artifactID === artifactID ? [] : [cloneCard(node)];
|
|
73876
|
+
case "row": {
|
|
73877
|
+
const children = node.children.filter((child) => child.artifactID !== artifactID).map(cloneCard);
|
|
73878
|
+
if (children.length === 0) {
|
|
73879
|
+
return [];
|
|
73880
|
+
}
|
|
73881
|
+
if (children.length === 1) {
|
|
73882
|
+
return [children[0]];
|
|
73883
|
+
}
|
|
73884
|
+
return [{ ...node, children }];
|
|
73885
|
+
}
|
|
73886
|
+
case "stack": {
|
|
73887
|
+
const children = node.children.flatMap((child) => {
|
|
73888
|
+
const removed = removeArtifactFromNode(child, artifactID);
|
|
73889
|
+
return removed.filter((entry) => entry.type !== "stack");
|
|
73890
|
+
});
|
|
73891
|
+
if (children.length === 0) {
|
|
73892
|
+
return [];
|
|
73893
|
+
}
|
|
73894
|
+
if (children.length === 1) {
|
|
73895
|
+
return [cloneStackChild(children[0])];
|
|
73896
|
+
}
|
|
73897
|
+
return [{ ...node, children }];
|
|
73898
|
+
}
|
|
73899
|
+
}
|
|
73900
|
+
}
|
|
73901
|
+
function normalizeLegacyCols(width) {
|
|
73902
|
+
return Math.round(width) === LEGACY_NARROW_COLS ? LEGACY_NARROW_COLS : LEGACY_FULL_COLS;
|
|
73903
|
+
}
|
|
73904
|
+
function normalizeLegacyRows(height) {
|
|
73905
|
+
const rounded = Math.round(height);
|
|
73906
|
+
return LEGACY_ALLOWED_ROWS.includes(rounded) ? rounded : LEGACY_BAND_HEIGHT_ROWS;
|
|
73907
|
+
}
|
|
73908
|
+
function deriveLegacyBands(cards) {
|
|
73909
|
+
const bands = [];
|
|
73910
|
+
let current = null;
|
|
73911
|
+
for (const card of cards) {
|
|
73912
|
+
if (!current) {
|
|
73913
|
+
const placements = packLegacyBand([card], card.width);
|
|
73914
|
+
if (!placements) {
|
|
73915
|
+
continue;
|
|
73916
|
+
}
|
|
73917
|
+
current = {
|
|
73918
|
+
width: card.width,
|
|
73919
|
+
placements
|
|
73920
|
+
};
|
|
73921
|
+
continue;
|
|
73922
|
+
}
|
|
73923
|
+
const nextCards = current.placements.map((placement) => ({
|
|
73924
|
+
artifactID: placement.artifactID,
|
|
73925
|
+
width: placement.width,
|
|
73926
|
+
height: placement.height
|
|
73927
|
+
})).concat(card);
|
|
73928
|
+
let nextWidth = current.width;
|
|
73929
|
+
let packed = packLegacyBand(nextCards, nextWidth);
|
|
73930
|
+
if (!packed && current.width < LEGACY_FULL_COLS && card.width > current.width) {
|
|
73931
|
+
nextWidth = LEGACY_FULL_COLS;
|
|
73932
|
+
packed = packLegacyBand(nextCards, nextWidth);
|
|
73933
|
+
}
|
|
73934
|
+
if (packed) {
|
|
73935
|
+
current = {
|
|
73936
|
+
width: nextWidth,
|
|
73937
|
+
placements: packed
|
|
73938
|
+
};
|
|
73939
|
+
continue;
|
|
73940
|
+
}
|
|
73941
|
+
bands.push(current);
|
|
73942
|
+
const newPlacements = packLegacyBand([card], card.width);
|
|
73943
|
+
if (!newPlacements) {
|
|
73944
|
+
current = null;
|
|
73945
|
+
continue;
|
|
73946
|
+
}
|
|
73947
|
+
current = {
|
|
73948
|
+
width: card.width,
|
|
73949
|
+
placements: newPlacements
|
|
73950
|
+
};
|
|
73951
|
+
}
|
|
73952
|
+
if (current) {
|
|
73953
|
+
bands.push(current);
|
|
73954
|
+
}
|
|
73955
|
+
return bands;
|
|
73956
|
+
}
|
|
73957
|
+
function packLegacyBand(cards, width) {
|
|
73958
|
+
const occupied = Array.from(
|
|
73959
|
+
{ length: LEGACY_BAND_HEIGHT_ROWS },
|
|
73960
|
+
() => Array.from({ length: width }, () => false)
|
|
73961
|
+
);
|
|
73962
|
+
const placements = [];
|
|
73963
|
+
for (const card of cards) {
|
|
73964
|
+
const position = firstLegacyFit(occupied, width, card);
|
|
73965
|
+
if (!position) {
|
|
73966
|
+
return null;
|
|
73967
|
+
}
|
|
73968
|
+
const placement = {
|
|
73969
|
+
artifactID: card.artifactID,
|
|
73970
|
+
width: card.width,
|
|
73971
|
+
height: card.height,
|
|
73972
|
+
x: position.x,
|
|
73973
|
+
y: position.y
|
|
73974
|
+
};
|
|
73975
|
+
placeLegacyCard(occupied, placement);
|
|
73976
|
+
placements.push(placement);
|
|
73977
|
+
}
|
|
73978
|
+
return placements;
|
|
73979
|
+
}
|
|
73980
|
+
function firstLegacyFit(occupied, width, card) {
|
|
73981
|
+
if (card.width > width || card.height > LEGACY_BAND_HEIGHT_ROWS) {
|
|
73982
|
+
return null;
|
|
73983
|
+
}
|
|
73984
|
+
for (let y2 = 0; y2 <= LEGACY_BAND_HEIGHT_ROWS - card.height; y2 += 1) {
|
|
73985
|
+
for (let x2 = 0; x2 <= width - card.width; x2 += 1) {
|
|
73986
|
+
let fits = true;
|
|
73987
|
+
for (let yy = y2; yy < y2 + card.height && fits; yy += 1) {
|
|
73988
|
+
for (let xx = x2; xx < x2 + card.width; xx += 1) {
|
|
73989
|
+
if (occupied[yy]?.[xx]) {
|
|
73990
|
+
fits = false;
|
|
73991
|
+
break;
|
|
73992
|
+
}
|
|
73993
|
+
}
|
|
73994
|
+
}
|
|
73995
|
+
if (fits) {
|
|
73996
|
+
return { x: x2, y: y2 };
|
|
73997
|
+
}
|
|
73998
|
+
}
|
|
73999
|
+
}
|
|
74000
|
+
return null;
|
|
74001
|
+
}
|
|
74002
|
+
function placeLegacyCard(occupied, placement) {
|
|
74003
|
+
for (let yy = placement.y; yy < placement.y + placement.height; yy += 1) {
|
|
74004
|
+
for (let xx = placement.x; xx < placement.x + placement.width; xx += 1) {
|
|
74005
|
+
occupied[yy][xx] = true;
|
|
74006
|
+
}
|
|
74007
|
+
}
|
|
74008
|
+
}
|
|
74009
|
+
function buildNodesForLegacyBand(band) {
|
|
74010
|
+
const placements = [...band.placements].sort((a, b2) => a.y - b2.y || a.x - b2.x);
|
|
74011
|
+
const children = [];
|
|
74012
|
+
for (let index = 0; index < placements.length; index += 1) {
|
|
74013
|
+
const current = placements[index];
|
|
74014
|
+
const next = placements[index + 1];
|
|
74015
|
+
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) {
|
|
74016
|
+
children.push({
|
|
74017
|
+
id: ulid3(),
|
|
74018
|
+
type: "row",
|
|
74019
|
+
height: current.height,
|
|
74020
|
+
children: [migrateLegacyCard(current), migrateLegacyCard(next)]
|
|
74021
|
+
});
|
|
74022
|
+
index += 1;
|
|
74023
|
+
continue;
|
|
74024
|
+
}
|
|
74025
|
+
children.push(migrateLegacyCard(current));
|
|
74026
|
+
}
|
|
74027
|
+
if (children.length === 0) {
|
|
74028
|
+
return [];
|
|
74029
|
+
}
|
|
74030
|
+
if (children.length === 1) {
|
|
74031
|
+
const child = children[0];
|
|
74032
|
+
return child.type === "row" ? child.children.map(cloneCard) : [cloneCard(child)];
|
|
74033
|
+
}
|
|
74034
|
+
return [
|
|
74035
|
+
{
|
|
74036
|
+
id: ulid3(),
|
|
74037
|
+
type: "stack",
|
|
74038
|
+
children
|
|
74039
|
+
}
|
|
74040
|
+
];
|
|
74041
|
+
}
|
|
74042
|
+
function migrateLegacyCard(card) {
|
|
73735
74043
|
return {
|
|
73736
|
-
|
|
74044
|
+
id: ulid3(),
|
|
74045
|
+
type: "card",
|
|
73737
74046
|
artifactID: card.artifactID,
|
|
73738
|
-
|
|
73739
|
-
|
|
74047
|
+
width: card.width === LEGACY_NARROW_COLS ? MIN_LAYOUT_CARD_WIDTH_UNITS : MAX_LAYOUT_CARD_WIDTH_UNITS,
|
|
74048
|
+
height: card.height
|
|
73740
74049
|
};
|
|
73741
74050
|
}
|
|
73742
|
-
function
|
|
73743
|
-
const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => sanitizeLayoutCard(card)) : [];
|
|
74051
|
+
function cloneCard(node) {
|
|
73744
74052
|
return {
|
|
73745
|
-
|
|
73746
|
-
name: workspace.name,
|
|
73747
|
-
layout
|
|
74053
|
+
...node
|
|
73748
74054
|
};
|
|
73749
74055
|
}
|
|
73750
|
-
function
|
|
73751
|
-
return
|
|
74056
|
+
function cloneStackChild(node) {
|
|
74057
|
+
return node.type === "card" ? cloneCard(node) : {
|
|
74058
|
+
...node,
|
|
74059
|
+
children: node.children.map(cloneCard)
|
|
74060
|
+
};
|
|
73752
74061
|
}
|
|
73753
74062
|
|
|
73754
74063
|
// src/server/server-store.ts
|
|
@@ -73768,27 +74077,52 @@ function validateHTMLFragment(content) {
|
|
|
73768
74077
|
}
|
|
73769
74078
|
}
|
|
73770
74079
|
function migrateWorkspaceJson(raw) {
|
|
73771
|
-
if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
|
|
73772
|
-
return false;
|
|
73773
|
-
}
|
|
73774
74080
|
if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
|
|
73775
74081
|
raw.layout = raw.artifacts;
|
|
73776
74082
|
delete raw.artifacts;
|
|
73777
74083
|
return true;
|
|
73778
74084
|
}
|
|
73779
74085
|
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
|
-
}));
|
|
74086
|
+
raw.layout = raw.artifactIDs.map((id) => ({ artifactID: id, width: DEFAULT_COLS, height: DEFAULT_ROWS }));
|
|
73786
74087
|
delete raw.artifactIDs;
|
|
73787
74088
|
return true;
|
|
73788
74089
|
}
|
|
73789
74090
|
return false;
|
|
73790
74091
|
}
|
|
73791
|
-
|
|
74092
|
+
function deserializeWorkspaceData(workspace) {
|
|
74093
|
+
const rawLayout = workspace.layout;
|
|
74094
|
+
if (!Array.isArray(rawLayout)) {
|
|
74095
|
+
return {
|
|
74096
|
+
migrated: false,
|
|
74097
|
+
workspace: {
|
|
74098
|
+
id: workspace.id,
|
|
74099
|
+
name: workspace.name,
|
|
74100
|
+
layout: []
|
|
74101
|
+
}
|
|
74102
|
+
};
|
|
74103
|
+
}
|
|
74104
|
+
if (rawLayout.every(
|
|
74105
|
+
(node) => typeof node === "object" && node !== null && "type" in node && (node.type === "card" || node.type === "stack")
|
|
74106
|
+
)) {
|
|
74107
|
+
return {
|
|
74108
|
+
migrated: false,
|
|
74109
|
+
workspace: {
|
|
74110
|
+
id: workspace.id,
|
|
74111
|
+
name: workspace.name,
|
|
74112
|
+
layout: rawLayout
|
|
74113
|
+
}
|
|
74114
|
+
};
|
|
74115
|
+
}
|
|
74116
|
+
return {
|
|
74117
|
+
migrated: true,
|
|
74118
|
+
workspace: {
|
|
74119
|
+
id: workspace.id,
|
|
74120
|
+
name: workspace.name,
|
|
74121
|
+
layout: migrateLegacyLayout(rawLayout)
|
|
74122
|
+
}
|
|
74123
|
+
};
|
|
74124
|
+
}
|
|
74125
|
+
var ServerStore = class extends EventTarget {
|
|
73792
74126
|
dataDir;
|
|
73793
74127
|
workspaces = /* @__PURE__ */ new Map();
|
|
73794
74128
|
artifacts = /* @__PURE__ */ new Map();
|
|
@@ -73821,7 +74155,7 @@ var ServerStore = class extends Emitter {
|
|
|
73821
74155
|
}
|
|
73822
74156
|
findArtifactWorkspaces(artifactID) {
|
|
73823
74157
|
return [...this.workspaces.values()].filter(
|
|
73824
|
-
(workspace) => workspace.layout
|
|
74158
|
+
(workspace) => layoutContainsArtifactID(workspace.layout, artifactID)
|
|
73825
74159
|
);
|
|
73826
74160
|
}
|
|
73827
74161
|
createArtifact(input) {
|
|
@@ -73839,14 +74173,18 @@ var ServerStore = class extends Emitter {
|
|
|
73839
74173
|
content: input.content
|
|
73840
74174
|
});
|
|
73841
74175
|
this.artifacts.set(artifact.id, artifact);
|
|
73842
|
-
workspace.layout.
|
|
74176
|
+
workspace.layout = [...workspace.layout, createCardNode(artifact.id)];
|
|
73843
74177
|
this.persistArtifact(artifact);
|
|
73844
74178
|
this.persistWorkspace(workspace);
|
|
73845
|
-
this.
|
|
73846
|
-
|
|
73847
|
-
|
|
73848
|
-
|
|
73849
|
-
|
|
74179
|
+
this.dispatchEvent(
|
|
74180
|
+
new StoreChangeEvent("store-change", {
|
|
74181
|
+
message: {
|
|
74182
|
+
type: "artifact-created",
|
|
74183
|
+
workspaceID: workspace.id,
|
|
74184
|
+
artifact
|
|
74185
|
+
}
|
|
74186
|
+
})
|
|
74187
|
+
);
|
|
73850
74188
|
return artifact;
|
|
73851
74189
|
}
|
|
73852
74190
|
updateArtifact(input) {
|
|
@@ -73856,11 +74194,15 @@ var ServerStore = class extends Emitter {
|
|
|
73856
74194
|
}
|
|
73857
74195
|
Object.assign(artifact, input.fields);
|
|
73858
74196
|
this.persistArtifact(artifact);
|
|
73859
|
-
this.
|
|
73860
|
-
|
|
73861
|
-
|
|
73862
|
-
|
|
73863
|
-
|
|
74197
|
+
this.dispatchEvent(
|
|
74198
|
+
new StoreChangeEvent("store-change", {
|
|
74199
|
+
message: {
|
|
74200
|
+
type: "artifact-updated",
|
|
74201
|
+
artifactID: input.artifactID,
|
|
74202
|
+
fields: input.fields
|
|
74203
|
+
}
|
|
74204
|
+
})
|
|
74205
|
+
);
|
|
73864
74206
|
return artifact;
|
|
73865
74207
|
}
|
|
73866
74208
|
removeArtifact(input) {
|
|
@@ -73872,18 +74214,22 @@ var ServerStore = class extends Emitter {
|
|
|
73872
74214
|
throw new Error(`Artifact not found: ${input.artifactID}`);
|
|
73873
74215
|
}
|
|
73874
74216
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
73875
|
-
if (!workspace.layout
|
|
74217
|
+
if (!layoutContainsArtifactID(workspace.layout, input.artifactID)) {
|
|
73876
74218
|
throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
|
|
73877
74219
|
}
|
|
73878
74220
|
this.artifacts.delete(input.artifactID);
|
|
73879
|
-
workspace.layout = workspace.layout
|
|
74221
|
+
workspace.layout = removeArtifactFromLayout(workspace.layout, input.artifactID);
|
|
73880
74222
|
this.persistWorkspace(workspace);
|
|
73881
74223
|
this.deleteArtifactFile(input.artifactID);
|
|
73882
|
-
this.
|
|
73883
|
-
|
|
73884
|
-
|
|
73885
|
-
|
|
73886
|
-
|
|
74224
|
+
this.dispatchEvent(
|
|
74225
|
+
new StoreChangeEvent("store-change", {
|
|
74226
|
+
message: {
|
|
74227
|
+
type: "artifact-removed",
|
|
74228
|
+
artifactID: input.artifactID,
|
|
74229
|
+
workspaceID: workspace.id
|
|
74230
|
+
}
|
|
74231
|
+
})
|
|
74232
|
+
);
|
|
73887
74233
|
}
|
|
73888
74234
|
createWorkspace(input) {
|
|
73889
74235
|
const workspace = {
|
|
@@ -73893,10 +74239,14 @@ var ServerStore = class extends Emitter {
|
|
|
73893
74239
|
};
|
|
73894
74240
|
this.workspaces.set(workspace.id, workspace);
|
|
73895
74241
|
this.persistWorkspace(workspace);
|
|
73896
|
-
this.
|
|
73897
|
-
|
|
73898
|
-
|
|
73899
|
-
|
|
74242
|
+
this.dispatchEvent(
|
|
74243
|
+
new StoreChangeEvent("store-change", {
|
|
74244
|
+
message: {
|
|
74245
|
+
type: "workspace-created",
|
|
74246
|
+
workspace
|
|
74247
|
+
}
|
|
74248
|
+
})
|
|
74249
|
+
);
|
|
73900
74250
|
return workspace;
|
|
73901
74251
|
}
|
|
73902
74252
|
updateWorkspace(input) {
|
|
@@ -73907,15 +74257,19 @@ var ServerStore = class extends Emitter {
|
|
|
73907
74257
|
nextFields.name = input.fields.name;
|
|
73908
74258
|
}
|
|
73909
74259
|
if (Array.isArray(input.fields.layout)) {
|
|
73910
|
-
workspace.layout = input.fields.layout.map((
|
|
74260
|
+
workspace.layout = input.fields.layout.map((node) => structuredClone(node));
|
|
73911
74261
|
nextFields.layout = workspace.layout;
|
|
73912
74262
|
}
|
|
73913
74263
|
this.persistWorkspace(workspace);
|
|
73914
|
-
this.
|
|
73915
|
-
|
|
73916
|
-
|
|
73917
|
-
|
|
73918
|
-
|
|
74264
|
+
this.dispatchEvent(
|
|
74265
|
+
new StoreChangeEvent("store-change", {
|
|
74266
|
+
message: {
|
|
74267
|
+
type: "workspace-updated",
|
|
74268
|
+
workspaceID: input.workspaceID,
|
|
74269
|
+
fields: nextFields
|
|
74270
|
+
}
|
|
74271
|
+
})
|
|
74272
|
+
);
|
|
73919
74273
|
}
|
|
73920
74274
|
removeWorkspace(input) {
|
|
73921
74275
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
@@ -73928,10 +74282,14 @@ var ServerStore = class extends Emitter {
|
|
|
73928
74282
|
this.deleteArtifactFile(artifactID);
|
|
73929
74283
|
}
|
|
73930
74284
|
this.deleteWorkspaceFile(workspace.id);
|
|
73931
|
-
this.
|
|
73932
|
-
|
|
73933
|
-
|
|
73934
|
-
|
|
74285
|
+
this.dispatchEvent(
|
|
74286
|
+
new StoreChangeEvent("store-change", {
|
|
74287
|
+
message: {
|
|
74288
|
+
type: "workspace-removed",
|
|
74289
|
+
workspaceID: workspace.id
|
|
74290
|
+
}
|
|
74291
|
+
})
|
|
74292
|
+
);
|
|
73935
74293
|
}
|
|
73936
74294
|
requireWorkspace(workspaceID) {
|
|
73937
74295
|
const workspace = this.workspaces.get(workspaceID);
|
|
@@ -73945,10 +74303,10 @@ var ServerStore = class extends Emitter {
|
|
|
73945
74303
|
const filePath = import_node_path3.default.join(this.workspacesDir, file2);
|
|
73946
74304
|
const raw = this.readJsonFile(filePath);
|
|
73947
74305
|
if (!raw || typeof raw !== "object") continue;
|
|
73948
|
-
const
|
|
73949
|
-
const workspace =
|
|
74306
|
+
const renamedLegacyFields = migrateWorkspaceJson(raw);
|
|
74307
|
+
const { workspace, migrated } = deserializeWorkspaceData(raw);
|
|
73950
74308
|
this.workspaces.set(workspace.id, workspace);
|
|
73951
|
-
if (migrated) {
|
|
74309
|
+
if (renamedLegacyFields || migrated) {
|
|
73952
74310
|
this.persistWorkspace(workspace);
|
|
73953
74311
|
}
|
|
73954
74312
|
}
|