@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/cli.cjs
CHANGED
|
@@ -58109,7 +58109,7 @@ var require_event_target = __commonJS({
|
|
|
58109
58109
|
var kTarget = Symbol("kTarget");
|
|
58110
58110
|
var kType = Symbol("kType");
|
|
58111
58111
|
var kWasClean = Symbol("kWasClean");
|
|
58112
|
-
var
|
|
58112
|
+
var Event2 = class {
|
|
58113
58113
|
/**
|
|
58114
58114
|
* Create a new `Event`.
|
|
58115
58115
|
*
|
|
@@ -58133,9 +58133,9 @@ var require_event_target = __commonJS({
|
|
|
58133
58133
|
return this[kType];
|
|
58134
58134
|
}
|
|
58135
58135
|
};
|
|
58136
|
-
Object.defineProperty(
|
|
58137
|
-
Object.defineProperty(
|
|
58138
|
-
var CloseEvent = class extends
|
|
58136
|
+
Object.defineProperty(Event2.prototype, "target", { enumerable: true });
|
|
58137
|
+
Object.defineProperty(Event2.prototype, "type", { enumerable: true });
|
|
58138
|
+
var CloseEvent = class extends Event2 {
|
|
58139
58139
|
/**
|
|
58140
58140
|
* Create a new `CloseEvent`.
|
|
58141
58141
|
*
|
|
@@ -58177,7 +58177,7 @@ var require_event_target = __commonJS({
|
|
|
58177
58177
|
Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true });
|
|
58178
58178
|
Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true });
|
|
58179
58179
|
Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true });
|
|
58180
|
-
var ErrorEvent = class extends
|
|
58180
|
+
var ErrorEvent = class extends Event2 {
|
|
58181
58181
|
/**
|
|
58182
58182
|
* Create a new `ErrorEvent`.
|
|
58183
58183
|
*
|
|
@@ -58207,7 +58207,7 @@ var require_event_target = __commonJS({
|
|
|
58207
58207
|
};
|
|
58208
58208
|
Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true });
|
|
58209
58209
|
Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true });
|
|
58210
|
-
var MessageEvent = class extends
|
|
58210
|
+
var MessageEvent = class extends Event2 {
|
|
58211
58211
|
/**
|
|
58212
58212
|
* Create a new `MessageEvent`.
|
|
58213
58213
|
*
|
|
@@ -58228,7 +58228,7 @@ var require_event_target = __commonJS({
|
|
|
58228
58228
|
}
|
|
58229
58229
|
};
|
|
58230
58230
|
Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
|
|
58231
|
-
var
|
|
58231
|
+
var EventTarget2 = {
|
|
58232
58232
|
/**
|
|
58233
58233
|
* Register an event listener.
|
|
58234
58234
|
*
|
|
@@ -58277,7 +58277,7 @@ var require_event_target = __commonJS({
|
|
|
58277
58277
|
};
|
|
58278
58278
|
} else if (type === "open") {
|
|
58279
58279
|
wrapper = function onOpen() {
|
|
58280
|
-
const event = new
|
|
58280
|
+
const event = new Event2("open");
|
|
58281
58281
|
event[kTarget] = this;
|
|
58282
58282
|
callListener(handler, this, event);
|
|
58283
58283
|
};
|
|
@@ -58311,8 +58311,8 @@ var require_event_target = __commonJS({
|
|
|
58311
58311
|
module2.exports = {
|
|
58312
58312
|
CloseEvent,
|
|
58313
58313
|
ErrorEvent,
|
|
58314
|
-
Event,
|
|
58315
|
-
EventTarget,
|
|
58314
|
+
Event: Event2,
|
|
58315
|
+
EventTarget: EventTarget2,
|
|
58316
58316
|
MessageEvent
|
|
58317
58317
|
};
|
|
58318
58318
|
function callListener(listener, thisArg, event) {
|
|
@@ -77191,18 +77191,26 @@ var Server2 = class {
|
|
|
77191
77191
|
this.handleClientMessage(socket, data.toString());
|
|
77192
77192
|
});
|
|
77193
77193
|
});
|
|
77194
|
-
this.store.
|
|
77195
|
-
this.broadcast(event);
|
|
77194
|
+
this.store.addEventListener("store-change", (event) => {
|
|
77195
|
+
this.broadcast(event.message);
|
|
77196
77196
|
});
|
|
77197
77197
|
}
|
|
77198
77198
|
start() {
|
|
77199
|
-
return new Promise((resolve) => {
|
|
77200
|
-
|
|
77199
|
+
return new Promise((resolve, reject) => {
|
|
77200
|
+
const handleError = (error2) => {
|
|
77201
|
+
this.httpServer.off("listening", handleListening);
|
|
77202
|
+
reject(error2);
|
|
77203
|
+
};
|
|
77204
|
+
const handleListening = () => {
|
|
77205
|
+
this.httpServer.off("error", handleError);
|
|
77201
77206
|
const address = this.httpServer.address();
|
|
77202
77207
|
const resolvedPort = typeof address === "object" && address ? address.port : this.port;
|
|
77203
77208
|
this.baseURL = buildServerURL(this.host ?? DEFAULT_SERVER_HOST, resolvedPort);
|
|
77204
77209
|
resolve(this.httpServer);
|
|
77205
|
-
}
|
|
77210
|
+
};
|
|
77211
|
+
this.httpServer.once("error", handleError);
|
|
77212
|
+
this.httpServer.once("listening", handleListening);
|
|
77213
|
+
this.httpServer.listen(this.port, this.host);
|
|
77206
77214
|
});
|
|
77207
77215
|
}
|
|
77208
77216
|
getBaseURL() {
|
|
@@ -77353,114 +77361,415 @@ function isClientMessage(value) {
|
|
|
77353
77361
|
case "create-workspace":
|
|
77354
77362
|
return typeof message.id === "string" && typeof message.name === "string";
|
|
77355
77363
|
case "update-workspace":
|
|
77356
|
-
return typeof message.workspaceID === "string" && typeof message.fields === "object" && message.fields !== null && (!("name" in message.fields) || typeof message.fields.name === "string") && (!("layout" in message.fields) || Array.isArray(message.fields.layout) && message.fields.layout.every(
|
|
77357
|
-
(card) => typeof card === "object" && card !== null && "type" in card && card.type === "artifact" && "artifactID" in card && typeof card.artifactID === "string" && "cols" in card && typeof card.cols === "number" && "rows" in card && typeof card.rows === "number"
|
|
77358
|
-
));
|
|
77364
|
+
return typeof message.workspaceID === "string" && typeof message.fields === "object" && message.fields !== null && (!("name" in message.fields) || typeof message.fields.name === "string") && (!("layout" in message.fields) || Array.isArray(message.fields.layout) && message.fields.layout.every(isLayoutNode));
|
|
77359
77365
|
case "delete-workspace":
|
|
77360
77366
|
return typeof message.workspaceID === "string";
|
|
77361
77367
|
default:
|
|
77362
77368
|
return false;
|
|
77363
77369
|
}
|
|
77364
77370
|
}
|
|
77365
|
-
|
|
77366
|
-
|
|
77367
|
-
|
|
77368
|
-
|
|
77369
|
-
|
|
77370
|
-
|
|
77371
|
-
|
|
77372
|
-
|
|
77373
|
-
|
|
77374
|
-
|
|
77375
|
-
|
|
77376
|
-
|
|
77377
|
-
|
|
77378
|
-
|
|
77379
|
-
|
|
77380
|
-
});
|
|
77381
|
-
} };
|
|
77371
|
+
function isLayoutNode(value) {
|
|
77372
|
+
if (typeof value !== "object" || value === null || !("type" in value)) {
|
|
77373
|
+
return false;
|
|
77374
|
+
}
|
|
77375
|
+
const node = value;
|
|
77376
|
+
switch (node.type) {
|
|
77377
|
+
case "card":
|
|
77378
|
+
return typeof node.id === "string" && typeof node.artifactID === "string" && (typeof node.width === "number" || node.width === "auto") && (typeof node.height === "number" || node.height === "auto");
|
|
77379
|
+
case "row":
|
|
77380
|
+
return typeof node.id === "string" && (typeof node.height === "number" || node.height === "auto") && Array.isArray(node.children) && node.children.every(isLayoutNode);
|
|
77381
|
+
case "stack":
|
|
77382
|
+
return typeof node.id === "string" && Array.isArray(node.children) && node.children.every(isLayoutNode);
|
|
77383
|
+
default:
|
|
77384
|
+
return false;
|
|
77385
|
+
}
|
|
77382
77386
|
}
|
|
77383
77387
|
|
|
77384
|
-
// node_modules/@rupertsworld/
|
|
77385
|
-
var
|
|
77386
|
-
|
|
77387
|
-
|
|
77388
|
-
|
|
77389
|
-
|
|
77388
|
+
// node_modules/@rupertsworld/event-target/dist/index.js
|
|
77389
|
+
var RESERVED_EVENT_KEYS = /* @__PURE__ */ new Set([
|
|
77390
|
+
"target",
|
|
77391
|
+
"currentTarget",
|
|
77392
|
+
"eventPhase",
|
|
77393
|
+
"defaultPrevented",
|
|
77394
|
+
"isTrusted",
|
|
77395
|
+
"timeStamp",
|
|
77396
|
+
"srcElement",
|
|
77397
|
+
"returnValue",
|
|
77398
|
+
"cancelBubble",
|
|
77399
|
+
"NONE",
|
|
77400
|
+
"CAPTURING_PHASE",
|
|
77401
|
+
"AT_TARGET",
|
|
77402
|
+
"BUBBLING_PHASE",
|
|
77403
|
+
"composedPath",
|
|
77404
|
+
"stopPropagation",
|
|
77405
|
+
"stopImmediatePropagation",
|
|
77406
|
+
"preventDefault",
|
|
77407
|
+
"initEvent"
|
|
77408
|
+
]);
|
|
77409
|
+
function assertNoReservedPayloadKeys(props) {
|
|
77410
|
+
for (const key of Object.keys(props)) {
|
|
77411
|
+
if (RESERVED_EVENT_KEYS.has(key)) {
|
|
77412
|
+
throw new Error(`Event payload key "${key}" is reserved; choose a different property name`);
|
|
77413
|
+
}
|
|
77390
77414
|
}
|
|
77391
|
-
|
|
77392
|
-
|
|
77393
|
-
|
|
77394
|
-
|
|
77395
|
-
|
|
77396
|
-
|
|
77397
|
-
|
|
77415
|
+
}
|
|
77416
|
+
function assignPayload(target, props) {
|
|
77417
|
+
assertNoReservedPayloadKeys(props);
|
|
77418
|
+
for (const key of Object.keys(props)) {
|
|
77419
|
+
Object.defineProperty(target, key, {
|
|
77420
|
+
value: props[key],
|
|
77421
|
+
writable: true,
|
|
77422
|
+
enumerable: true,
|
|
77423
|
+
configurable: true
|
|
77424
|
+
});
|
|
77398
77425
|
}
|
|
77399
|
-
|
|
77400
|
-
|
|
77401
|
-
|
|
77402
|
-
|
|
77403
|
-
|
|
77404
|
-
|
|
77405
|
-
|
|
77406
|
-
|
|
77407
|
-
|
|
77426
|
+
}
|
|
77427
|
+
function defineEvent() {
|
|
77428
|
+
class DefinedEvent extends Event {
|
|
77429
|
+
constructor(type, init) {
|
|
77430
|
+
const { type: initType, bubbles, cancelable, composed, ...payload } = init ?? {};
|
|
77431
|
+
if (initType !== void 0) {
|
|
77432
|
+
throw new Error(`Do not pass "type" in init; use the constructor argument instead`);
|
|
77433
|
+
}
|
|
77434
|
+
super(type, { bubbles, cancelable, composed });
|
|
77435
|
+
assignPayload(this, payload);
|
|
77436
|
+
}
|
|
77408
77437
|
}
|
|
77438
|
+
return DefinedEvent;
|
|
77439
|
+
}
|
|
77440
|
+
var EventTarget = class extends globalThis.EventTarget {
|
|
77409
77441
|
};
|
|
77410
77442
|
|
|
77443
|
+
// src/events.ts
|
|
77444
|
+
var ChangeEvent = defineEvent();
|
|
77445
|
+
var ServerMessageEvent = defineEvent();
|
|
77446
|
+
var LayoutMutationEvent = defineEvent();
|
|
77447
|
+
var LayoutScrollEvent = defineEvent();
|
|
77448
|
+
var StoreChangeEvent = defineEvent();
|
|
77449
|
+
|
|
77411
77450
|
// src/server/server-store.ts
|
|
77412
77451
|
var import_node_crypto2 = require("node:crypto");
|
|
77413
77452
|
var import_node_fs3 = require("node:fs");
|
|
77414
77453
|
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
77415
77454
|
|
|
77455
|
+
// src/constants.ts
|
|
77456
|
+
var LAYOUT_FULL_WIDTH_UNITS = 4;
|
|
77457
|
+
var LAYOUT_FULL_HEIGHT_UNITS = 6;
|
|
77458
|
+
var MIN_LAYOUT_CARD_WIDTH_UNITS = 2;
|
|
77459
|
+
var MAX_LAYOUT_CARD_WIDTH_UNITS = LAYOUT_FULL_WIDTH_UNITS;
|
|
77460
|
+
var DEFAULT_LAYOUT_CARD_WIDTH = "auto";
|
|
77461
|
+
var DEFAULT_LAYOUT_CARD_HEIGHT = "auto";
|
|
77462
|
+
var DEFAULT_LAYOUT_UNIT = 120;
|
|
77463
|
+
var CARD_GAP = 16;
|
|
77464
|
+
var CARD_WIDTH = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_WIDTH_UNITS + CARD_GAP * (LAYOUT_FULL_WIDTH_UNITS - 1);
|
|
77465
|
+
var CARD_HEIGHT = DEFAULT_LAYOUT_UNIT * LAYOUT_FULL_HEIGHT_UNITS + CARD_GAP * (LAYOUT_FULL_HEIGHT_UNITS - 1);
|
|
77466
|
+
|
|
77416
77467
|
// src/types.ts
|
|
77417
|
-
|
|
77418
|
-
var DEFAULT_LAYOUT_CARD_ROWS = 6;
|
|
77419
|
-
var LAYOUT_COLS_NARROW = 1;
|
|
77420
|
-
var LAYOUT_ROW_SHORT = 2;
|
|
77421
|
-
var LAYOUT_ROW_MID = 3;
|
|
77422
|
-
var LAYOUT_ROW_TALL = 4;
|
|
77423
|
-
var ALLOWED_COLS = [LAYOUT_COLS_NARROW, DEFAULT_LAYOUT_CARD_COLS];
|
|
77424
|
-
var ALLOWED_ROWS = [
|
|
77425
|
-
LAYOUT_ROW_SHORT,
|
|
77426
|
-
LAYOUT_ROW_MID,
|
|
77427
|
-
LAYOUT_ROW_TALL,
|
|
77428
|
-
DEFAULT_LAYOUT_CARD_ROWS
|
|
77429
|
-
];
|
|
77430
|
-
function clampLayoutCols(cols) {
|
|
77431
|
-
const n = Math.round(cols);
|
|
77432
|
-
return ALLOWED_COLS.includes(n) ? n : DEFAULT_LAYOUT_CARD_COLS;
|
|
77433
|
-
}
|
|
77434
|
-
function clampLayoutRows(rows) {
|
|
77435
|
-
const n = Math.round(rows);
|
|
77436
|
-
return ALLOWED_ROWS.includes(n) ? n : DEFAULT_LAYOUT_CARD_ROWS;
|
|
77437
|
-
}
|
|
77438
|
-
function createLayoutCardRecord(artifactID) {
|
|
77468
|
+
function createCardNode(artifactID, overrides = {}) {
|
|
77439
77469
|
return {
|
|
77440
|
-
|
|
77470
|
+
id: overrides.id ?? ulid3(),
|
|
77471
|
+
type: "card",
|
|
77441
77472
|
artifactID,
|
|
77442
|
-
|
|
77443
|
-
|
|
77473
|
+
width: overrides.width ?? DEFAULT_LAYOUT_CARD_WIDTH,
|
|
77474
|
+
height: overrides.height ?? DEFAULT_LAYOUT_CARD_HEIGHT
|
|
77444
77475
|
};
|
|
77445
77476
|
}
|
|
77446
|
-
function
|
|
77477
|
+
function layoutContainsArtifactID(layout, artifactID) {
|
|
77478
|
+
return layout.some((node) => nodeContainsArtifactID(node, artifactID));
|
|
77479
|
+
}
|
|
77480
|
+
function nodeContainsArtifactID(node, artifactID) {
|
|
77481
|
+
switch (node.type) {
|
|
77482
|
+
case "card":
|
|
77483
|
+
return node.artifactID === artifactID;
|
|
77484
|
+
case "row":
|
|
77485
|
+
return node.children.some((child) => child.artifactID === artifactID);
|
|
77486
|
+
case "stack":
|
|
77487
|
+
return node.children.some((child) => nodeContainsArtifactID(child, artifactID));
|
|
77488
|
+
}
|
|
77489
|
+
}
|
|
77490
|
+
function getWorkspaceArtifactIDs(workspace) {
|
|
77491
|
+
return workspace.layout.flatMap(collectArtifactIDs);
|
|
77492
|
+
}
|
|
77493
|
+
function collectArtifactIDs(node) {
|
|
77494
|
+
switch (node.type) {
|
|
77495
|
+
case "card":
|
|
77496
|
+
return [node.artifactID];
|
|
77497
|
+
case "row":
|
|
77498
|
+
return node.children.map((child) => child.artifactID);
|
|
77499
|
+
case "stack":
|
|
77500
|
+
return node.children.flatMap(collectArtifactIDs);
|
|
77501
|
+
}
|
|
77502
|
+
}
|
|
77503
|
+
|
|
77504
|
+
// src/browser/ui/layout.ts
|
|
77505
|
+
var LEGACY_BAND_HEIGHT_ROWS = 6;
|
|
77506
|
+
var LEGACY_NARROW_COLS = 1;
|
|
77507
|
+
var LEGACY_FULL_COLS = 2;
|
|
77508
|
+
var LEGACY_ROW_SHORT = 2;
|
|
77509
|
+
var LEGACY_ROW_MID = 3;
|
|
77510
|
+
var LEGACY_ROW_TALL = 4;
|
|
77511
|
+
var LEGACY_ROW_FULL = 6;
|
|
77512
|
+
var LEGACY_ALLOWED_ROWS = [LEGACY_ROW_SHORT, LEGACY_ROW_MID, LEGACY_ROW_TALL, LEGACY_ROW_FULL];
|
|
77513
|
+
var LEGACY_LEFT_X = 0;
|
|
77514
|
+
var LEGACY_RIGHT_X = 1;
|
|
77515
|
+
function removeArtifactFromLayout(layout, artifactID) {
|
|
77516
|
+
return normalizeRootNodes(layout.flatMap((node) => removeArtifactFromNode(node, artifactID)));
|
|
77517
|
+
}
|
|
77518
|
+
function migrateLegacyLayout(cards) {
|
|
77519
|
+
const normalized = cards.map((card) => ({
|
|
77520
|
+
artifactID: card.artifactID,
|
|
77521
|
+
width: normalizeLegacyCols(card.width),
|
|
77522
|
+
height: normalizeLegacyRows(card.height)
|
|
77523
|
+
}));
|
|
77524
|
+
const bands = deriveLegacyBands(normalized);
|
|
77525
|
+
return normalizeRootNodes(bands.flatMap(buildNodesForLegacyBand));
|
|
77526
|
+
}
|
|
77527
|
+
function normalizeRootNodes(layout) {
|
|
77528
|
+
const normalized = [];
|
|
77529
|
+
for (const node of layout) {
|
|
77530
|
+
const entries = normalizeNode(node);
|
|
77531
|
+
for (const entry of entries) {
|
|
77532
|
+
if (entry.type === "row") {
|
|
77533
|
+
normalized.push(...entry.children.map(cloneCard));
|
|
77534
|
+
continue;
|
|
77535
|
+
}
|
|
77536
|
+
normalized.push(entry);
|
|
77537
|
+
}
|
|
77538
|
+
}
|
|
77539
|
+
return normalized;
|
|
77540
|
+
}
|
|
77541
|
+
function normalizeNode(node) {
|
|
77542
|
+
switch (node.type) {
|
|
77543
|
+
case "card":
|
|
77544
|
+
return [cloneCard(node)];
|
|
77545
|
+
case "row": {
|
|
77546
|
+
const children = node.children.map(cloneCard);
|
|
77547
|
+
if (children.length === 0) {
|
|
77548
|
+
return [];
|
|
77549
|
+
}
|
|
77550
|
+
if (children.length === 1) {
|
|
77551
|
+
return [children[0]];
|
|
77552
|
+
}
|
|
77553
|
+
return [{ ...node, children }];
|
|
77554
|
+
}
|
|
77555
|
+
case "stack": {
|
|
77556
|
+
const children = [];
|
|
77557
|
+
for (const child of node.children) {
|
|
77558
|
+
const normalizedChildren = normalizeNode(child);
|
|
77559
|
+
for (const normalizedChild of normalizedChildren) {
|
|
77560
|
+
if (normalizedChild.type === "stack") {
|
|
77561
|
+
children.push(...normalizedChild.children.map(cloneStackChild));
|
|
77562
|
+
continue;
|
|
77563
|
+
}
|
|
77564
|
+
if (normalizedChild.type === "row") {
|
|
77565
|
+
children.push({
|
|
77566
|
+
...normalizedChild,
|
|
77567
|
+
children: normalizedChild.children.map(cloneCard)
|
|
77568
|
+
});
|
|
77569
|
+
continue;
|
|
77570
|
+
}
|
|
77571
|
+
children.push(cloneCard(normalizedChild));
|
|
77572
|
+
}
|
|
77573
|
+
}
|
|
77574
|
+
if (children.length === 0) {
|
|
77575
|
+
return [];
|
|
77576
|
+
}
|
|
77577
|
+
if (children.length === 1) {
|
|
77578
|
+
return [cloneStackChild(children[0])];
|
|
77579
|
+
}
|
|
77580
|
+
return [{ ...node, children }];
|
|
77581
|
+
}
|
|
77582
|
+
}
|
|
77583
|
+
}
|
|
77584
|
+
function removeArtifactFromNode(node, artifactID) {
|
|
77585
|
+
switch (node.type) {
|
|
77586
|
+
case "card":
|
|
77587
|
+
return node.artifactID === artifactID ? [] : [cloneCard(node)];
|
|
77588
|
+
case "row": {
|
|
77589
|
+
const children = node.children.filter((child) => child.artifactID !== artifactID).map(cloneCard);
|
|
77590
|
+
if (children.length === 0) {
|
|
77591
|
+
return [];
|
|
77592
|
+
}
|
|
77593
|
+
if (children.length === 1) {
|
|
77594
|
+
return [children[0]];
|
|
77595
|
+
}
|
|
77596
|
+
return [{ ...node, children }];
|
|
77597
|
+
}
|
|
77598
|
+
case "stack": {
|
|
77599
|
+
const children = node.children.flatMap((child) => {
|
|
77600
|
+
const removed = removeArtifactFromNode(child, artifactID);
|
|
77601
|
+
return removed.filter((entry) => entry.type !== "stack");
|
|
77602
|
+
});
|
|
77603
|
+
if (children.length === 0) {
|
|
77604
|
+
return [];
|
|
77605
|
+
}
|
|
77606
|
+
if (children.length === 1) {
|
|
77607
|
+
return [cloneStackChild(children[0])];
|
|
77608
|
+
}
|
|
77609
|
+
return [{ ...node, children }];
|
|
77610
|
+
}
|
|
77611
|
+
}
|
|
77612
|
+
}
|
|
77613
|
+
function normalizeLegacyCols(width) {
|
|
77614
|
+
return Math.round(width) === LEGACY_NARROW_COLS ? LEGACY_NARROW_COLS : LEGACY_FULL_COLS;
|
|
77615
|
+
}
|
|
77616
|
+
function normalizeLegacyRows(height) {
|
|
77617
|
+
const rounded = Math.round(height);
|
|
77618
|
+
return LEGACY_ALLOWED_ROWS.includes(rounded) ? rounded : LEGACY_BAND_HEIGHT_ROWS;
|
|
77619
|
+
}
|
|
77620
|
+
function deriveLegacyBands(cards) {
|
|
77621
|
+
const bands = [];
|
|
77622
|
+
let current = null;
|
|
77623
|
+
for (const card of cards) {
|
|
77624
|
+
if (!current) {
|
|
77625
|
+
const placements = packLegacyBand([card], card.width);
|
|
77626
|
+
if (!placements) {
|
|
77627
|
+
continue;
|
|
77628
|
+
}
|
|
77629
|
+
current = {
|
|
77630
|
+
width: card.width,
|
|
77631
|
+
placements
|
|
77632
|
+
};
|
|
77633
|
+
continue;
|
|
77634
|
+
}
|
|
77635
|
+
const nextCards = current.placements.map((placement) => ({
|
|
77636
|
+
artifactID: placement.artifactID,
|
|
77637
|
+
width: placement.width,
|
|
77638
|
+
height: placement.height
|
|
77639
|
+
})).concat(card);
|
|
77640
|
+
let nextWidth = current.width;
|
|
77641
|
+
let packed = packLegacyBand(nextCards, nextWidth);
|
|
77642
|
+
if (!packed && current.width < LEGACY_FULL_COLS && card.width > current.width) {
|
|
77643
|
+
nextWidth = LEGACY_FULL_COLS;
|
|
77644
|
+
packed = packLegacyBand(nextCards, nextWidth);
|
|
77645
|
+
}
|
|
77646
|
+
if (packed) {
|
|
77647
|
+
current = {
|
|
77648
|
+
width: nextWidth,
|
|
77649
|
+
placements: packed
|
|
77650
|
+
};
|
|
77651
|
+
continue;
|
|
77652
|
+
}
|
|
77653
|
+
bands.push(current);
|
|
77654
|
+
const newPlacements = packLegacyBand([card], card.width);
|
|
77655
|
+
if (!newPlacements) {
|
|
77656
|
+
current = null;
|
|
77657
|
+
continue;
|
|
77658
|
+
}
|
|
77659
|
+
current = {
|
|
77660
|
+
width: card.width,
|
|
77661
|
+
placements: newPlacements
|
|
77662
|
+
};
|
|
77663
|
+
}
|
|
77664
|
+
if (current) {
|
|
77665
|
+
bands.push(current);
|
|
77666
|
+
}
|
|
77667
|
+
return bands;
|
|
77668
|
+
}
|
|
77669
|
+
function packLegacyBand(cards, width) {
|
|
77670
|
+
const occupied = Array.from(
|
|
77671
|
+
{ length: LEGACY_BAND_HEIGHT_ROWS },
|
|
77672
|
+
() => Array.from({ length: width }, () => false)
|
|
77673
|
+
);
|
|
77674
|
+
const placements = [];
|
|
77675
|
+
for (const card of cards) {
|
|
77676
|
+
const position = firstLegacyFit(occupied, width, card);
|
|
77677
|
+
if (!position) {
|
|
77678
|
+
return null;
|
|
77679
|
+
}
|
|
77680
|
+
const placement = {
|
|
77681
|
+
artifactID: card.artifactID,
|
|
77682
|
+
width: card.width,
|
|
77683
|
+
height: card.height,
|
|
77684
|
+
x: position.x,
|
|
77685
|
+
y: position.y
|
|
77686
|
+
};
|
|
77687
|
+
placeLegacyCard(occupied, placement);
|
|
77688
|
+
placements.push(placement);
|
|
77689
|
+
}
|
|
77690
|
+
return placements;
|
|
77691
|
+
}
|
|
77692
|
+
function firstLegacyFit(occupied, width, card) {
|
|
77693
|
+
if (card.width > width || card.height > LEGACY_BAND_HEIGHT_ROWS) {
|
|
77694
|
+
return null;
|
|
77695
|
+
}
|
|
77696
|
+
for (let y2 = 0; y2 <= LEGACY_BAND_HEIGHT_ROWS - card.height; y2 += 1) {
|
|
77697
|
+
for (let x2 = 0; x2 <= width - card.width; x2 += 1) {
|
|
77698
|
+
let fits = true;
|
|
77699
|
+
for (let yy = y2; yy < y2 + card.height && fits; yy += 1) {
|
|
77700
|
+
for (let xx = x2; xx < x2 + card.width; xx += 1) {
|
|
77701
|
+
if (occupied[yy]?.[xx]) {
|
|
77702
|
+
fits = false;
|
|
77703
|
+
break;
|
|
77704
|
+
}
|
|
77705
|
+
}
|
|
77706
|
+
}
|
|
77707
|
+
if (fits) {
|
|
77708
|
+
return { x: x2, y: y2 };
|
|
77709
|
+
}
|
|
77710
|
+
}
|
|
77711
|
+
}
|
|
77712
|
+
return null;
|
|
77713
|
+
}
|
|
77714
|
+
function placeLegacyCard(occupied, placement) {
|
|
77715
|
+
for (let yy = placement.y; yy < placement.y + placement.height; yy += 1) {
|
|
77716
|
+
for (let xx = placement.x; xx < placement.x + placement.width; xx += 1) {
|
|
77717
|
+
occupied[yy][xx] = true;
|
|
77718
|
+
}
|
|
77719
|
+
}
|
|
77720
|
+
}
|
|
77721
|
+
function buildNodesForLegacyBand(band) {
|
|
77722
|
+
const placements = [...band.placements].sort((a, b2) => a.y - b2.y || a.x - b2.x);
|
|
77723
|
+
const children = [];
|
|
77724
|
+
for (let index = 0; index < placements.length; index += 1) {
|
|
77725
|
+
const current = placements[index];
|
|
77726
|
+
const next = placements[index + 1];
|
|
77727
|
+
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) {
|
|
77728
|
+
children.push({
|
|
77729
|
+
id: ulid3(),
|
|
77730
|
+
type: "row",
|
|
77731
|
+
height: current.height,
|
|
77732
|
+
children: [migrateLegacyCard(current), migrateLegacyCard(next)]
|
|
77733
|
+
});
|
|
77734
|
+
index += 1;
|
|
77735
|
+
continue;
|
|
77736
|
+
}
|
|
77737
|
+
children.push(migrateLegacyCard(current));
|
|
77738
|
+
}
|
|
77739
|
+
if (children.length === 0) {
|
|
77740
|
+
return [];
|
|
77741
|
+
}
|
|
77742
|
+
if (children.length === 1) {
|
|
77743
|
+
const child = children[0];
|
|
77744
|
+
return child.type === "row" ? child.children.map(cloneCard) : [cloneCard(child)];
|
|
77745
|
+
}
|
|
77746
|
+
return [
|
|
77747
|
+
{
|
|
77748
|
+
id: ulid3(),
|
|
77749
|
+
type: "stack",
|
|
77750
|
+
children
|
|
77751
|
+
}
|
|
77752
|
+
];
|
|
77753
|
+
}
|
|
77754
|
+
function migrateLegacyCard(card) {
|
|
77447
77755
|
return {
|
|
77448
|
-
|
|
77756
|
+
id: ulid3(),
|
|
77757
|
+
type: "card",
|
|
77449
77758
|
artifactID: card.artifactID,
|
|
77450
|
-
|
|
77451
|
-
|
|
77759
|
+
width: card.width === LEGACY_NARROW_COLS ? MIN_LAYOUT_CARD_WIDTH_UNITS : MAX_LAYOUT_CARD_WIDTH_UNITS,
|
|
77760
|
+
height: card.height
|
|
77452
77761
|
};
|
|
77453
77762
|
}
|
|
77454
|
-
function
|
|
77455
|
-
const layout = Array.isArray(workspace.layout) ? workspace.layout.map((card) => sanitizeLayoutCard(card)) : [];
|
|
77763
|
+
function cloneCard(node) {
|
|
77456
77764
|
return {
|
|
77457
|
-
|
|
77458
|
-
name: workspace.name,
|
|
77459
|
-
layout
|
|
77765
|
+
...node
|
|
77460
77766
|
};
|
|
77461
77767
|
}
|
|
77462
|
-
function
|
|
77463
|
-
return
|
|
77768
|
+
function cloneStackChild(node) {
|
|
77769
|
+
return node.type === "card" ? cloneCard(node) : {
|
|
77770
|
+
...node,
|
|
77771
|
+
children: node.children.map(cloneCard)
|
|
77772
|
+
};
|
|
77464
77773
|
}
|
|
77465
77774
|
|
|
77466
77775
|
// src/server/server-store.ts
|
|
@@ -77480,27 +77789,52 @@ function validateHTMLFragment(content) {
|
|
|
77480
77789
|
}
|
|
77481
77790
|
}
|
|
77482
77791
|
function migrateWorkspaceJson(raw) {
|
|
77483
|
-
if ("layout" in raw && Array.isArray(raw.layout) && raw.layout.length > 0) {
|
|
77484
|
-
return false;
|
|
77485
|
-
}
|
|
77486
77792
|
if ("artifacts" in raw && Array.isArray(raw.artifacts)) {
|
|
77487
77793
|
raw.layout = raw.artifacts;
|
|
77488
77794
|
delete raw.artifacts;
|
|
77489
77795
|
return true;
|
|
77490
77796
|
}
|
|
77491
77797
|
if ("artifactIDs" in raw && Array.isArray(raw.artifactIDs)) {
|
|
77492
|
-
raw.layout = raw.artifactIDs.map((id) => ({
|
|
77493
|
-
type: "artifact",
|
|
77494
|
-
artifactID: id,
|
|
77495
|
-
cols: DEFAULT_COLS,
|
|
77496
|
-
rows: DEFAULT_ROWS
|
|
77497
|
-
}));
|
|
77798
|
+
raw.layout = raw.artifactIDs.map((id) => ({ artifactID: id, width: DEFAULT_COLS, height: DEFAULT_ROWS }));
|
|
77498
77799
|
delete raw.artifactIDs;
|
|
77499
77800
|
return true;
|
|
77500
77801
|
}
|
|
77501
77802
|
return false;
|
|
77502
77803
|
}
|
|
77503
|
-
|
|
77804
|
+
function deserializeWorkspaceData(workspace) {
|
|
77805
|
+
const rawLayout = workspace.layout;
|
|
77806
|
+
if (!Array.isArray(rawLayout)) {
|
|
77807
|
+
return {
|
|
77808
|
+
migrated: false,
|
|
77809
|
+
workspace: {
|
|
77810
|
+
id: workspace.id,
|
|
77811
|
+
name: workspace.name,
|
|
77812
|
+
layout: []
|
|
77813
|
+
}
|
|
77814
|
+
};
|
|
77815
|
+
}
|
|
77816
|
+
if (rawLayout.every(
|
|
77817
|
+
(node) => typeof node === "object" && node !== null && "type" in node && (node.type === "card" || node.type === "stack")
|
|
77818
|
+
)) {
|
|
77819
|
+
return {
|
|
77820
|
+
migrated: false,
|
|
77821
|
+
workspace: {
|
|
77822
|
+
id: workspace.id,
|
|
77823
|
+
name: workspace.name,
|
|
77824
|
+
layout: rawLayout
|
|
77825
|
+
}
|
|
77826
|
+
};
|
|
77827
|
+
}
|
|
77828
|
+
return {
|
|
77829
|
+
migrated: true,
|
|
77830
|
+
workspace: {
|
|
77831
|
+
id: workspace.id,
|
|
77832
|
+
name: workspace.name,
|
|
77833
|
+
layout: migrateLegacyLayout(rawLayout)
|
|
77834
|
+
}
|
|
77835
|
+
};
|
|
77836
|
+
}
|
|
77837
|
+
var ServerStore = class extends EventTarget {
|
|
77504
77838
|
dataDir;
|
|
77505
77839
|
workspaces = /* @__PURE__ */ new Map();
|
|
77506
77840
|
artifacts = /* @__PURE__ */ new Map();
|
|
@@ -77533,7 +77867,7 @@ var ServerStore = class extends Emitter {
|
|
|
77533
77867
|
}
|
|
77534
77868
|
findArtifactWorkspaces(artifactID) {
|
|
77535
77869
|
return [...this.workspaces.values()].filter(
|
|
77536
|
-
(workspace) => workspace.layout
|
|
77870
|
+
(workspace) => layoutContainsArtifactID(workspace.layout, artifactID)
|
|
77537
77871
|
);
|
|
77538
77872
|
}
|
|
77539
77873
|
createArtifact(input) {
|
|
@@ -77551,14 +77885,18 @@ var ServerStore = class extends Emitter {
|
|
|
77551
77885
|
content: input.content
|
|
77552
77886
|
});
|
|
77553
77887
|
this.artifacts.set(artifact.id, artifact);
|
|
77554
|
-
workspace.layout.
|
|
77888
|
+
workspace.layout = [...workspace.layout, createCardNode(artifact.id)];
|
|
77555
77889
|
this.persistArtifact(artifact);
|
|
77556
77890
|
this.persistWorkspace(workspace);
|
|
77557
|
-
this.
|
|
77558
|
-
|
|
77559
|
-
|
|
77560
|
-
|
|
77561
|
-
|
|
77891
|
+
this.dispatchEvent(
|
|
77892
|
+
new StoreChangeEvent("store-change", {
|
|
77893
|
+
message: {
|
|
77894
|
+
type: "artifact-created",
|
|
77895
|
+
workspaceID: workspace.id,
|
|
77896
|
+
artifact
|
|
77897
|
+
}
|
|
77898
|
+
})
|
|
77899
|
+
);
|
|
77562
77900
|
return artifact;
|
|
77563
77901
|
}
|
|
77564
77902
|
updateArtifact(input) {
|
|
@@ -77568,11 +77906,15 @@ var ServerStore = class extends Emitter {
|
|
|
77568
77906
|
}
|
|
77569
77907
|
Object.assign(artifact, input.fields);
|
|
77570
77908
|
this.persistArtifact(artifact);
|
|
77571
|
-
this.
|
|
77572
|
-
|
|
77573
|
-
|
|
77574
|
-
|
|
77575
|
-
|
|
77909
|
+
this.dispatchEvent(
|
|
77910
|
+
new StoreChangeEvent("store-change", {
|
|
77911
|
+
message: {
|
|
77912
|
+
type: "artifact-updated",
|
|
77913
|
+
artifactID: input.artifactID,
|
|
77914
|
+
fields: input.fields
|
|
77915
|
+
}
|
|
77916
|
+
})
|
|
77917
|
+
);
|
|
77576
77918
|
return artifact;
|
|
77577
77919
|
}
|
|
77578
77920
|
removeArtifact(input) {
|
|
@@ -77584,18 +77926,22 @@ var ServerStore = class extends Emitter {
|
|
|
77584
77926
|
throw new Error(`Artifact not found: ${input.artifactID}`);
|
|
77585
77927
|
}
|
|
77586
77928
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
77587
|
-
if (!workspace.layout
|
|
77929
|
+
if (!layoutContainsArtifactID(workspace.layout, input.artifactID)) {
|
|
77588
77930
|
throw new Error(`Artifact not linked to workspace: ${input.artifactID}`);
|
|
77589
77931
|
}
|
|
77590
77932
|
this.artifacts.delete(input.artifactID);
|
|
77591
|
-
workspace.layout = workspace.layout
|
|
77933
|
+
workspace.layout = removeArtifactFromLayout(workspace.layout, input.artifactID);
|
|
77592
77934
|
this.persistWorkspace(workspace);
|
|
77593
77935
|
this.deleteArtifactFile(input.artifactID);
|
|
77594
|
-
this.
|
|
77595
|
-
|
|
77596
|
-
|
|
77597
|
-
|
|
77598
|
-
|
|
77936
|
+
this.dispatchEvent(
|
|
77937
|
+
new StoreChangeEvent("store-change", {
|
|
77938
|
+
message: {
|
|
77939
|
+
type: "artifact-removed",
|
|
77940
|
+
artifactID: input.artifactID,
|
|
77941
|
+
workspaceID: workspace.id
|
|
77942
|
+
}
|
|
77943
|
+
})
|
|
77944
|
+
);
|
|
77599
77945
|
}
|
|
77600
77946
|
createWorkspace(input) {
|
|
77601
77947
|
const workspace = {
|
|
@@ -77605,10 +77951,14 @@ var ServerStore = class extends Emitter {
|
|
|
77605
77951
|
};
|
|
77606
77952
|
this.workspaces.set(workspace.id, workspace);
|
|
77607
77953
|
this.persistWorkspace(workspace);
|
|
77608
|
-
this.
|
|
77609
|
-
|
|
77610
|
-
|
|
77611
|
-
|
|
77954
|
+
this.dispatchEvent(
|
|
77955
|
+
new StoreChangeEvent("store-change", {
|
|
77956
|
+
message: {
|
|
77957
|
+
type: "workspace-created",
|
|
77958
|
+
workspace
|
|
77959
|
+
}
|
|
77960
|
+
})
|
|
77961
|
+
);
|
|
77612
77962
|
return workspace;
|
|
77613
77963
|
}
|
|
77614
77964
|
updateWorkspace(input) {
|
|
@@ -77619,15 +77969,19 @@ var ServerStore = class extends Emitter {
|
|
|
77619
77969
|
nextFields.name = input.fields.name;
|
|
77620
77970
|
}
|
|
77621
77971
|
if (Array.isArray(input.fields.layout)) {
|
|
77622
|
-
workspace.layout = input.fields.layout.map((
|
|
77972
|
+
workspace.layout = input.fields.layout.map((node) => structuredClone(node));
|
|
77623
77973
|
nextFields.layout = workspace.layout;
|
|
77624
77974
|
}
|
|
77625
77975
|
this.persistWorkspace(workspace);
|
|
77626
|
-
this.
|
|
77627
|
-
|
|
77628
|
-
|
|
77629
|
-
|
|
77630
|
-
|
|
77976
|
+
this.dispatchEvent(
|
|
77977
|
+
new StoreChangeEvent("store-change", {
|
|
77978
|
+
message: {
|
|
77979
|
+
type: "workspace-updated",
|
|
77980
|
+
workspaceID: input.workspaceID,
|
|
77981
|
+
fields: nextFields
|
|
77982
|
+
}
|
|
77983
|
+
})
|
|
77984
|
+
);
|
|
77631
77985
|
}
|
|
77632
77986
|
removeWorkspace(input) {
|
|
77633
77987
|
const workspace = this.requireWorkspace(input.workspaceID);
|
|
@@ -77640,10 +77994,14 @@ var ServerStore = class extends Emitter {
|
|
|
77640
77994
|
this.deleteArtifactFile(artifactID);
|
|
77641
77995
|
}
|
|
77642
77996
|
this.deleteWorkspaceFile(workspace.id);
|
|
77643
|
-
this.
|
|
77644
|
-
|
|
77645
|
-
|
|
77646
|
-
|
|
77997
|
+
this.dispatchEvent(
|
|
77998
|
+
new StoreChangeEvent("store-change", {
|
|
77999
|
+
message: {
|
|
78000
|
+
type: "workspace-removed",
|
|
78001
|
+
workspaceID: workspace.id
|
|
78002
|
+
}
|
|
78003
|
+
})
|
|
78004
|
+
);
|
|
77647
78005
|
}
|
|
77648
78006
|
requireWorkspace(workspaceID) {
|
|
77649
78007
|
const workspace = this.workspaces.get(workspaceID);
|
|
@@ -77657,10 +78015,10 @@ var ServerStore = class extends Emitter {
|
|
|
77657
78015
|
const filePath = import_node_path4.default.join(this.workspacesDir, file2);
|
|
77658
78016
|
const raw = this.readJsonFile(filePath);
|
|
77659
78017
|
if (!raw || typeof raw !== "object") continue;
|
|
77660
|
-
const
|
|
77661
|
-
const workspace =
|
|
78018
|
+
const renamedLegacyFields = migrateWorkspaceJson(raw);
|
|
78019
|
+
const { workspace, migrated } = deserializeWorkspaceData(raw);
|
|
77662
78020
|
this.workspaces.set(workspace.id, workspace);
|
|
77663
|
-
if (migrated) {
|
|
78021
|
+
if (renamedLegacyFields || migrated) {
|
|
77664
78022
|
this.persistWorkspace(workspace);
|
|
77665
78023
|
}
|
|
77666
78024
|
}
|