@ixo/editor 3.0.0-beta.21 → 3.0.0-beta.22

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.
@@ -1379,10 +1379,117 @@ var addLinkedEntityAction = {
1379
1379
  }
1380
1380
  };
1381
1381
 
1382
+ // src/core/lib/matrixDm.ts
1383
+ function getHomeserver(matrixClient) {
1384
+ const userId = matrixClient.getUserId();
1385
+ if (!userId) throw new Error("Matrix client has no user ID");
1386
+ const idx = userId.indexOf(":");
1387
+ if (idx === -1) throw new Error(`Invalid Matrix user ID: ${userId}`);
1388
+ return userId.substring(idx + 1);
1389
+ }
1390
+ function didToMatrixUserId(did, homeserver) {
1391
+ const localpart = did.replace(/:/g, "-");
1392
+ return `@${localpart}:${homeserver}`;
1393
+ }
1394
+ async function findOrCreateDMRoom(matrixClient, targetUserId) {
1395
+ try {
1396
+ const directEvent = matrixClient.getAccountData("m.direct");
1397
+ const directContent = directEvent?.getContent() || {};
1398
+ const existingRooms = directContent[targetUserId];
1399
+ if (existingRooms && existingRooms.length > 0) {
1400
+ return existingRooms[0];
1401
+ }
1402
+ } catch {
1403
+ }
1404
+ const response = await matrixClient.createRoom({
1405
+ is_direct: true,
1406
+ invite: [targetUserId],
1407
+ preset: "trusted_private_chat",
1408
+ initial_state: []
1409
+ });
1410
+ const roomId = response.room_id;
1411
+ try {
1412
+ const directEvent = matrixClient.getAccountData("m.direct");
1413
+ const directContent = directEvent?.getContent() || {};
1414
+ const updatedContent = {
1415
+ ...directContent,
1416
+ [targetUserId]: [...directContent[targetUserId] || [], roomId]
1417
+ };
1418
+ await matrixClient.setAccountData("m.direct", updatedContent);
1419
+ } catch (error) {
1420
+ console.warn("[MatrixDM] Failed to update m.direct account data:", error);
1421
+ }
1422
+ return roomId;
1423
+ }
1424
+ async function sendMatrixMessage(matrixClient, roomId, message) {
1425
+ await matrixClient.sendEvent(roomId, "m.room.message", {
1426
+ msgtype: "m.text",
1427
+ body: message
1428
+ });
1429
+ }
1430
+ async function sendDirectMessage(matrixClient, targetDid, message) {
1431
+ const homeserver = getHomeserver(matrixClient);
1432
+ const targetUserId = didToMatrixUserId(targetDid, homeserver);
1433
+ const roomId = await findOrCreateDMRoom(matrixClient, targetUserId);
1434
+ await sendMatrixMessage(matrixClient, roomId, message);
1435
+ return { roomId };
1436
+ }
1437
+
1438
+ // src/mantine/blocks/hooks/hookedActions/actionTypes/sendMatrixDM.ts
1439
+ var sendMatrixDMAction = {
1440
+ type: "sendMatrixDM",
1441
+ label: "Send Matrix DM",
1442
+ description: "Send a direct message via Matrix to an assigned user or a specified DID",
1443
+ configSchema: [
1444
+ {
1445
+ key: "targetDid",
1446
+ label: "Target DID",
1447
+ type: "string",
1448
+ required: true,
1449
+ placeholder: "{{payload.assignedActorDid}}",
1450
+ description: "DID of the recipient (can use payload variables)"
1451
+ },
1452
+ {
1453
+ key: "message",
1454
+ label: "Message",
1455
+ type: "string",
1456
+ required: true,
1457
+ placeholder: "You have a new task to complete",
1458
+ description: "Message body to send (can use payload variables)"
1459
+ }
1460
+ ],
1461
+ execute: async (actionConfig, payload, context) => {
1462
+ const { editor } = context;
1463
+ const { config } = actionConfig;
1464
+ const matrixClient = editor.getMatrixClient?.();
1465
+ if (!matrixClient) {
1466
+ console.warn("sendMatrixDM: Matrix client not available");
1467
+ return;
1468
+ }
1469
+ const resolvedDid = resolvePayloadValue(config.targetDid || "", payload);
1470
+ const resolvedMessage = resolvePayloadValue(config.message || "", payload);
1471
+ if (!resolvedDid) {
1472
+ console.warn("sendMatrixDM: Missing target DID after resolution");
1473
+ return;
1474
+ }
1475
+ if (!resolvedMessage) {
1476
+ console.warn("sendMatrixDM: Missing message after resolution");
1477
+ return;
1478
+ }
1479
+ try {
1480
+ await sendDirectMessage(matrixClient, resolvedDid, resolvedMessage);
1481
+ console.log("sendMatrixDM: DM sent successfully");
1482
+ } catch (error) {
1483
+ console.error("sendMatrixDM: Failed to send DM", error);
1484
+ }
1485
+ }
1486
+ };
1487
+
1382
1488
  // src/mantine/blocks/hooks/hookedActions/actionTypes/index.ts
1383
1489
  function registerBuiltInActionTypes() {
1384
1490
  registerHookedActionType(sendEmailAction);
1385
1491
  registerHookedActionType(addLinkedEntityAction);
1492
+ registerHookedActionType(sendMatrixDMAction);
1386
1493
  }
1387
1494
 
1388
1495
  // src/mantine/blocks/governanceGroup/actions.ts
@@ -30443,6 +30550,26 @@ var MatrixMetadataManager = class {
30443
30550
  }
30444
30551
  };
30445
30552
 
30553
+ // src/core/lib/flowEngine/dmNotificationState.ts
30554
+ var DM_NOTIFICATIONS_KEY = "__dm_notifications";
30555
+ function getDMNotificationState(runtimeMap) {
30556
+ const stored = runtimeMap.get(DM_NOTIFICATIONS_KEY);
30557
+ if (!stored || typeof stored !== "object") return {};
30558
+ return { ...stored };
30559
+ }
30560
+ function setDMNotificationRecord(runtimeMap, blockId, record) {
30561
+ const current = getDMNotificationState(runtimeMap);
30562
+ runtimeMap.set(DM_NOTIFICATIONS_KEY, {
30563
+ ...current,
30564
+ [blockId]: record
30565
+ });
30566
+ }
30567
+ function shouldNotify(state, blockId, currentAssignedDid) {
30568
+ const existing = state[blockId];
30569
+ if (!existing) return true;
30570
+ return existing.assignedDid !== currentAssignedDid;
30571
+ }
30572
+
30446
30573
  // src/mantine/hooks/useCollaborativeIxoEditor.ts
30447
30574
  var ROOT_CAPABILITY_KEY = "__root__";
30448
30575
  function useCreateCollaborativeIxoEditor(options) {
@@ -30823,6 +30950,59 @@ function useCreateCollaborativeIxoEditor(options) {
30823
30950
  awarenessInstance.setLocalState(null);
30824
30951
  };
30825
30952
  }, [awarenessInstance, connectionStatus, memoizedUser.id, memoizedUser.name, memoizedUser.color, memoizedUser.avatar]);
30953
+ const dmSentRef = useRef26(false);
30954
+ useEffect103(() => {
30955
+ if (!ixoEditor || connectionStatus !== "connected" || dmSentRef.current) return;
30956
+ if (ixoEditor.docType !== "flow") return;
30957
+ const mx = ixoEditor.getMatrixClient?.();
30958
+ const runtime = ixoEditor._yRuntime;
30959
+ const currentUserId = mx?.getUserId();
30960
+ if (!mx || !runtime || !currentUserId) return;
30961
+ dmSentRef.current = true;
30962
+ const sendNotifications = async () => {
30963
+ const blocks = ixoEditor.document || [];
30964
+ const dedupState = getDMNotificationState(runtime);
30965
+ const flowTitle = ixoEditor.getFlowMetadata?.()?.title || "Untitled Flow";
30966
+ const roomId = ixoEditor.getRoomId?.() || "";
30967
+ const selfDid = currentUserId.split(":")[0].replace("@", "").replace(/-/g, ":");
30968
+ const notifications = [];
30969
+ for (const block of blocks) {
30970
+ const props = block.props;
30971
+ if (!props?.assignment) continue;
30972
+ let assignment;
30973
+ try {
30974
+ assignment = typeof props.assignment === "string" ? JSON.parse(props.assignment) : props.assignment;
30975
+ } catch {
30976
+ continue;
30977
+ }
30978
+ const assignedDid = assignment?.assignedActor?.did;
30979
+ if (!assignedDid || assignedDid === selfDid) continue;
30980
+ if (!shouldNotify(dedupState, block.id, assignedDid)) continue;
30981
+ const blockType = block.type || "block";
30982
+ const blockId = block.id;
30983
+ const message = `Action needed: You have been assigned to a "${blockType}" block in flow "${flowTitle}".${roomId ? ` Room: ${roomId}` : ""}`;
30984
+ notifications.push(
30985
+ sendDirectMessage(mx, assignedDid, message).then(() => {
30986
+ setDMNotificationRecord(runtime, blockId, {
30987
+ assignedDid,
30988
+ notifiedAt: Date.now(),
30989
+ notifiedBy: currentUserId
30990
+ });
30991
+ console.log(`[FlowDM] Notified ${assignedDid} for block ${blockId}`);
30992
+ }).catch((error) => {
30993
+ console.error(`[FlowDM] Failed to notify ${assignedDid} for block ${blockId}:`, error);
30994
+ })
30995
+ );
30996
+ }
30997
+ if (notifications.length > 0) {
30998
+ await Promise.allSettled(notifications);
30999
+ console.log(`[FlowDM] Processed ${notifications.length} DM notification(s)`);
31000
+ }
31001
+ };
31002
+ sendNotifications().catch((error) => {
31003
+ console.error("[FlowDM] Unexpected error in sendNotifications:", error);
31004
+ });
31005
+ }, [ixoEditor, connectionStatus]);
30826
31006
  return {
30827
31007
  editor: ixoEditor,
30828
31008
  connectionStatus,
@@ -32838,6 +33018,10 @@ export {
32838
33018
  registerBlockActions,
32839
33019
  getBlockActions,
32840
33020
  useHookedActions,
33021
+ getHomeserver,
33022
+ didToMatrixUserId,
33023
+ findOrCreateDMRoom,
33024
+ sendDirectMessage,
32841
33025
  registerBuiltInActionTypes,
32842
33026
  initializeHookedActions,
32843
33027
  BlocknoteProvider,
@@ -32851,6 +33035,9 @@ export {
32851
33035
  AuthorizationTab,
32852
33036
  useNodeRuntime,
32853
33037
  CheckboxBlockSpec,
33038
+ getDMNotificationState,
33039
+ setDMNotificationRecord,
33040
+ shouldNotify,
32854
33041
  useCreateCollaborativeIxoEditor,
32855
33042
  BaseIconPicker,
32856
33043
  CoverImage,
@@ -32875,4 +33062,4 @@ export {
32875
33062
  getExtraSlashMenuItems,
32876
33063
  useCreateIxoEditor
32877
33064
  };
32878
- //# sourceMappingURL=chunk-4344EQ47.mjs.map
33065
+ //# sourceMappingURL=chunk-XGUFDDLJ.mjs.map