diff --git a/Makefile b/Makefile index 7aa9867..3b43927 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,8 @@ MODULES_DIR ?= ./modules .PHONY: all build test clean setup-nix-merged \ build-module build-ui-plugin install install-module \ - build-kv-module install-kv-module install-all + build-kv-module install-kv-module \ + install-delivery-module install-all # ── Build ──────────────────────────────────────────────────────────────────── @@ -124,8 +125,20 @@ install-kv-module: build-kv-module echo '{"name":"kv_module","version":"0.1.0","type":"core","category":"storage","dependencies":[],"main":{"linux-x86_64":"kv_module_plugin.so","linux-aarch64":"kv_module_plugin.so","darwin-arm64":"kv_module_plugin.so"}}' > ~/.local/share/Logos/LogosAppNix/modules/kv_module/manifest.json @echo "kv_module installed to ~/.local/share/Logos/LogosAppNix/modules/kv_module/" -## Install everything: scala_ui + scala_module + kv_module -install-all: install install-module install-kv-module +# ── delivery_module (P2P messaging backend) ─────────────────────────────────── + +LGPM ?= /tmp/package-manager/bin/lgpm +DELIVERY_RELEASE ?= build-20260307-a751c91-69 + +## Install delivery_module via lgpm +install-delivery-module: + $(LGPM) --release $(DELIVERY_RELEASE) \ + --modules-dir ~/.local/share/Logos/LogosAppNix/modules \ + install logos-delivery-module + @echo "delivery_module installed to ~/.local/share/Logos/LogosAppNix/modules/delivery_module/" + +## Install everything: scala_ui + scala_module + kv_module + delivery_module +install-all: install install-module install-kv-module install-delivery-module @echo "" @echo "All installed! Run logos-app:" @echo " cd ~/logos-workspace && nix run .#logos-app-poc" diff --git a/manifest.json b/manifest.json index 46cd3f3..45a3369 100644 --- a/manifest.json +++ b/manifest.json @@ -8,5 +8,5 @@ "darwin-arm64": "scala_plugin.so", "darwin-x86_64": "scala_plugin.so" }, - "dependencies": ["kv_module", "messaging_module", "accounts_module"] + "dependencies": ["kv_module", "delivery_module", "accounts_module"] } diff --git a/metadata.json b/metadata.json index 020806f..6136d66 100644 --- a/metadata.json +++ b/metadata.json @@ -14,6 +14,6 @@ "darwin-arm64": "scala_module_plugin.dylib", "windows-x86_64": "scala_module_plugin.dll" }, - "dependencies": ["kv_module"], + "dependencies": ["kv_module", "delivery_module"], "capabilities": [] } diff --git a/module.yaml b/module.yaml index 5621fc0..796f74d 100644 --- a/module.yaml +++ b/module.yaml @@ -9,7 +9,7 @@ qt_version: "6" dependencies: - kv_module - - messaging_module + - delivery_module - accounts_module qml_files: diff --git a/src/calendar_module.cpp b/src/calendar_module.cpp index e943352..8788463 100644 --- a/src/calendar_module.cpp +++ b/src/calendar_module.cpp @@ -95,13 +95,13 @@ void LogosCalendar::initLogos(LogosAPI *logosAPIInstance) { // Skip optional module lookups in e2e/CI mode (they timeout ~20s each) if (qgetenv("SCALA_E2E_MINIMAL").isEmpty()) { - // Get messaging module client for sync - m_messagingClient = m_logosAPI->getClient("messaging_module"); - if (!m_messagingClient) { - qWarning() << "LogosCalendar: failed to get messaging_module client" + // Get delivery module client for P2P sync + m_deliveryClient = m_logosAPI->getClient("delivery_module"); + if (!m_deliveryClient) { + qWarning() << "LogosCalendar: failed to get delivery_module client" << "(sync will use stub)"; } else { - m_sync->setMessagingClient(m_messagingClient); + m_sync->setDeliveryClient(m_deliveryClient); } // Get identity from accounts module (optional — may not be loaded) diff --git a/src/calendar_module.h b/src/calendar_module.h index 23f1145..b1cc24a 100644 --- a/src/calendar_module.h +++ b/src/calendar_module.h @@ -140,6 +140,6 @@ class LogosCalendar final : public QObject, public ILogosCalendar { #ifdef LOGOS_CORE_AVAILABLE LogosAPI *m_logosAPI = nullptr; LogosAPIClient *m_kvClient = nullptr; - LogosAPIClient *m_messagingClient = nullptr; + LogosAPIClient *m_deliveryClient = nullptr; #endif }; diff --git a/src/calendar_sync.cpp b/src/calendar_sync.cpp index e794036..4f1abaf 100644 --- a/src/calendar_sync.cpp +++ b/src/calendar_sync.cpp @@ -89,8 +89,64 @@ bool CalendarSync::isSyncing(const QString &calendarId) const { } #ifdef LOGOS_CORE_AVAILABLE -void CalendarSync::setMessagingClient(LogosAPIClient *client) { - m_messagingClient = client; +void CalendarSync::setDeliveryClient(LogosAPIClient *client) { + m_deliveryClient = client; + + if (m_deliveryClient) { + ensureDeliveryNode(); + + // Listen for messageReceived events from delivery_module + QObject *replica = m_deliveryClient->requestObject("delivery_module"); + if (replica) { + m_deliveryClient->onEvent( + replica, this, QStringLiteral("messageReceived"), + [this](const QString &eventName, const QVariantList &args) { + Q_UNUSED(eventName) + if (args.size() >= 4) { + onDeliveryMessageReceived( + args.at(0).toString(), // hash + args.at(1).toString(), // topic + args.at(2).toString(), // payload_base64 + args.at(3).toLongLong() // timestamp + ); + } + }); + qInfo() << "CalendarSync: registered messageReceived event handler"; + } else { + qWarning() << "CalendarSync: failed to get delivery_module replica for events"; + } + } +} + +void CalendarSync::ensureDeliveryNode() { + if (m_deliveryNodeStarted || !m_deliveryClient) + return; + + // Create and start the delivery node with logos.dev preset + m_deliveryClient->invokeRemoteMethod( + "delivery_module", "createNode", + QStringLiteral("{\"logLevel\":\"INFO\",\"mode\":\"Core\",\"preset\":\"logos.dev\"}")); + m_deliveryClient->invokeRemoteMethod("delivery_module", "start"); + m_deliveryNodeStarted = true; + + qInfo() << "CalendarSync: delivery node created and started (logos.dev)"; +} + +void CalendarSync::onDeliveryMessageReceived(const QString &hash, const QString &topic, + const QString &payloadBase64, qint64 timestamp) { + Q_UNUSED(hash) + Q_UNUSED(timestamp) + + // Find which calendar this topic belongs to + for (auto it = m_activeTopics.constBegin(); it != m_activeTopics.constEnd(); ++it) { + if (topicForCalendar(it.key()) == topic) { + QByteArray payload = QByteArray::fromBase64(payloadBase64.toUtf8()); + SyncMessage msg = SyncMessage::fromBytes(payload); + emit messageReceived(it.key(), msg); + return; + } + } + qDebug() << "CalendarSync: received message for unknown topic" << topic; } #endif @@ -104,16 +160,17 @@ void CalendarSync::startSync(const QString &calendarId, const QString &encryptio m_activeTopics.insert(calendarId, encryptionKey); #ifdef LOGOS_CORE_AVAILABLE - if (m_messagingClient) { - // Subscribe to the topic via the messaging module - m_messagingClient->invokeRemoteMethod( - "messaging_module", "subscribe", topic, encryptionKey); + if (m_deliveryClient) { + ensureDeliveryNode(); + // Subscribe to the content topic via delivery_module + m_deliveryClient->invokeRemoteMethod( + "delivery_module", "subscribe", topic); qInfo() << "CalendarSync: subscribed to topic" << topic; emit syncStarted(calendarId); return; } - qWarning() << "CalendarSync: no messaging client, falling back to stub"; + qWarning() << "CalendarSync: no delivery client, falling back to stub"; #endif // Stub: emit syncStarted immediately for testing without Logos Core @@ -132,10 +189,9 @@ void CalendarSync::stopSync(const QString &calendarId) { m_activeTopics.remove(calendarId); #ifdef LOGOS_CORE_AVAILABLE - if (m_messagingClient) { - m_messagingClient->invokeRemoteMethod( - "messaging_module", "unsubscribe", topic); - + if (m_deliveryClient) { + // delivery_module does not have an explicit unsubscribe; + // topic is simply no longer tracked locally qInfo() << "CalendarSync: unsubscribed from topic" << topic; emit syncStopped(calendarId); return; @@ -157,12 +213,12 @@ void CalendarSync::sendMessage(const QString &calendarId, const SyncMessage &msg const QByteArray data = msg.toBytes(); #ifdef LOGOS_CORE_AVAILABLE - if (m_messagingClient) { - const QString &encryptionKey = m_activeTopics.value(calendarId); - m_messagingClient->invokeRemoteMethod( - "messaging_module", "publish", topic, data, encryptionKey); + if (m_deliveryClient) { + ensureDeliveryNode(); + m_deliveryClient->invokeRemoteMethod( + "delivery_module", "send", topic, data); - qDebug() << "CalendarSync: published" << SyncMessage::typeToString(msg.type) + qDebug() << "CalendarSync: sent" << SyncMessage::typeToString(msg.type) << "to" << topic << "(" << data.size() << "bytes)"; return; } diff --git a/src/calendar_sync.h b/src/calendar_sync.h index 8158189..d453283 100644 --- a/src/calendar_sync.h +++ b/src/calendar_sync.h @@ -71,7 +71,7 @@ class CalendarSync : public QObject { static QString topicForCalendar(const QString &calendarId); #ifdef LOGOS_CORE_AVAILABLE - void setMessagingClient(LogosAPIClient *client); + void setDeliveryClient(LogosAPIClient *client); #endif signals: @@ -85,6 +85,11 @@ class CalendarSync : public QObject { QMap m_activeTopics; #ifdef LOGOS_CORE_AVAILABLE - LogosAPIClient *m_messagingClient = nullptr; + LogosAPIClient *m_deliveryClient = nullptr; + bool m_deliveryNodeStarted = false; + + void ensureDeliveryNode(); + void onDeliveryMessageReceived(const QString &hash, const QString &topic, + const QString &payloadBase64, qint64 timestamp); #endif };