mirror of
https://github.com/logos-co/logos-view-module-runtime.git
synced 2026-08-29 20:11:07 +00:00
serializeResultForTesting used QJsonValue::fromVariant, which cannot
convert the custom LogosResult metatype and silently degraded a
`result`-type return to the literal "null". A QML-only ui_qml plugin
calling a result-returning method through logos.callModule therefore
received null instead of {success, value, error}.
Replace the bespoke serialization with logos-protocol's canonical
logos::qvariantToNlohmann — the same converter every transport
(lp/std/cdylib) already uses. Now ALL types round-trip to QML/JS
identically: scalars as bare literals, containers preserved, integers
kept as integers (QJsonValue::fromVariant degraded them to double),
bytes in the tagged {"_bytes":...} form, and LogosResult as
{success, value, error} (empty error -> null). Fixes both sync
callModule and async callModuleAsync.
Adds test_logos_qml_bridge_result.cpp (regression) plus the
reproduction/isolation harnesses (e2e, gui, handshake, 2-process) built
while proving the long-suspected QML "sequential-call stall" is NOT an
SDK defect: every layer round-trips correctly under isolation, and the
only real bug was this result serialization.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
1.6 KiB
C++
47 lines
1.6 KiB
C++
// Process A of the 2-process reproduction: publishes echo_module +
|
|
// capability_module over QtRO local sockets (LogosInstance::id-derived, shared
|
|
// via the inherited LOGOS_INSTANCE_ID env), then runs its own event loop —
|
|
// exactly like real module subprocesses. Prints "READY" once both are published.
|
|
#include "test_2proc_common.h"
|
|
|
|
#include "remote_transport.h"
|
|
#include "logos_instance.h"
|
|
#include "logos_mode.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QTextStream>
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
QCoreApplication app(argc, argv);
|
|
using namespace twoproc;
|
|
|
|
LogosModeConfig::setMode(LogosMode::Remote);
|
|
|
|
EchoProvider echo;
|
|
echo.fireEvents = !qEnvironmentVariableIsEmpty("LOGOS_FIRE_EVENTS");
|
|
ModuleProxy echoProxy(&echo);
|
|
RemoteTransportHost echoHost(LogosInstance::id("echo_module"));
|
|
if (!echoHost.publishObject("echo_module", &echoProxy)) {
|
|
QTextStream(stderr) << "FAILED to publish echo_module\n";
|
|
return 1;
|
|
}
|
|
|
|
CapabilityProvider cap;
|
|
cap.echoProxy = &echoProxy;
|
|
cap.rotate = !qEnvironmentVariableIsEmpty("LOGOS_ROTATE_TOKENS");
|
|
ModuleProxy capProxy(&cap);
|
|
capProxy.saveToken(QStringLiteral("caller"), QStringLiteral("cap-token"));
|
|
RemoteTransportHost capHost(LogosInstance::id("capability_module"));
|
|
if (!capHost.publishObject("capability_module", &capProxy)) {
|
|
QTextStream(stderr) << "FAILED to publish capability_module\n";
|
|
return 1;
|
|
}
|
|
|
|
QTextStream out(stdout);
|
|
out << "READY " << LogosInstance::id("echo_module") << "\n";
|
|
out.flush();
|
|
|
|
return app.exec();
|
|
}
|