SharedNumberSignal

When using SharedNumberSignal and trying to get value of signal within Signal.effect with get I expect to get a Double value. But an exception is thrown.

tools.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.lang.Double` from String "signalName": not a valid `Double` value
 at [No location information]

The SharedNumberSignal is created as a child in a SharedNodeSignal.

SharedNodeSignal root  = new SharedNodeSignal();
signal = root.insertChildWithValue("signalName", last()).signal().asNumber();

The Signals effect is triggered by a value change within a transaction.

Signal.runInTransaction(() -> {
	// other signals using the same root
	signal.incrementBy(1);
});

The first parameter to insertChildWithValue (i.e. "signalName") is the initial value, not the name of the node.

At the same time, I see some inconsistency in your example since you’re doing asValue(LocalDateTime.class) that gives a SharedValueSignal<LocalDateTime> without an incrementBy method rather than asNumber() that gives a SharedNumberSignal.

Hey Leif
That was a small typo, I copied the wrong signal from my demo application.
I meant to write .asNumber() instead of .asValue(LocalDateTime.class)

And yes when using the first parameter as the initial value rather than the name of the signal (wich is not needed as it seems) the example works perfectly.

But the documentation for the insertChildWithValue was not very clear to me. It just says «the value to insert». From this alone I thought I needed to give the name of the signal. The word «initial» really would have helped in this sentence. Also I think it would be really helpful to make this type safe. The way it is now, you only realize at runtime that it does not work. But when you would add a generic type to the api you could get an error at compile time.

asValue(Class valueType) could be replaced with a parameterless method, because the type is already clear from the initial value.

That is indeed a trade-off in the current API design. The underlying data is always arbitrary JSON which means that we can’t give any absolute guarantees. We could give some hints thorugh separate variants such as insertNumberChildWithValue along with similar variants for a couple of other methods. That’s around 30 new methods which would on the other hand make it more difficult to get an overview of the whole API.

A class literal is necessary behind the scenes for handling JSON deserialization. It’s not always feasible to get the right literal from the initial value in cases involving polymorphism or in the very common case of using null as the initial value.