1010import io .ably .lib .object .instance .types .LiveMapInstance ;
1111import io .ably .lib .object .instance .types .NumberInstance ;
1212import io .ably .lib .object .instance .types .StringInstance ;
13- import io .ably .lib .objects .ObjectsSubscription ;
14- import org .jetbrains .annotations .NonBlocking ;
1513import org .jetbrains .annotations .NotNull ;
1614
1715/**
18- * A direct-reference view of a single LiveObject (a {@code LiveMap} or {@code LiveCounter})
19- * or a primitive value. Unlike {@code PathObject}, which resolves a path lazily against
20- * the LiveObjects graph at every call, an {@code Instance} is bound to a specific
21- * underlying value and dereferenced in O(1).
16+ * A direct-reference view of a single resolved LiveObject ({@code LiveMap} or
17+ * {@code LiveCounter}) or primitive value.
2218 *
23- * <p>Java exposes type-specific sub-types ({@link LiveMapInstance},
24- * {@link LiveCounterInstance}, and the primitive {@code *Instance} types). Use the
25- * {@code as*} helpers to obtain a sub-type wrapper without performing type validation.
26- * Only {@link LiveMapInstance} and {@link LiveCounterInstance} expose an object id
27- * (via their own {@code getId()} methods); primitive instances are anonymous .
19+ * <p>Unlike {@code PathObject}, which re-resolves its path on every call, an
20+ * {@code Instance} is identity-addressed: it is bound to a specific underlying value
21+ * and dereferenced in O(1), regardless of where that value sits in the graph. Read
22+ * operations validate the access API preconditions and fail with an
23+ * {@code AblyException} if they are not satisfied .
2824 *
29- * <p>Spec: RTINS1
25+ * <p>This base type exposes only the methods whose behaviour is independent of the
26+ * wrapped type; everything else - including {@code subscribe} (RTTS7b) - is
27+ * partitioned onto the sub-types. Use the {@code as*} helpers to obtain a sub-type
28+ * view without type validation, or discriminate via {@link #getType()}.
29+ *
30+ * <p>Spec: RTINS1, RTTS7
31+ *
32+ * @see LiveMapInstance
33+ * @see LiveCounterInstance
34+ * @see InstanceListener
3035 */
3136public interface Instance {
3237
3338 /**
3439 * Returns the {@link ValueType} of the value wrapped by this instance. Use this
3540 * instead of dedicated {@code isLiveMap}/{@code isLiveCounter}/etc. checks.
3641 *
42+ * <p>An {@code Instance} is always constructed from a resolved value, so this never
43+ * returns {@link ValueType#UNKNOWN} in normal operation.
44+ *
45+ * <p>Spec: RTTS8a
46+ *
3747 * @return the wrapped value type
3848 */
3949 @ NotNull ValueType getType ();
@@ -45,38 +55,24 @@ public interface Instance {
4555 * always bound to a resolved value, so this always returns a non-null result;
4656 * failures of the access API preconditions are signalled via {@code AblyException}.
4757 *
48- * <p>Spec: RTINS11
58+ * <p>Spec: RTINS11 / RTINS11c (universal non-null invariant - Instance is bound
59+ * to an already-resolved value, so the path-resolution failure mode of
60+ * PathObject#compactJson does not apply) / RTTS7a (typed-SDK signature reflects
61+ * the universal invariant)
4962 *
5063 * @return the compacted JSON snapshot
5164 */
5265 @ NotNull JsonElement compactJson ();
5366
54- /**
55- * Subscribes a listener for updates on the underlying LiveObject. The listener is
56- * invoked whenever the wrapped object is changed by a local or remote operation.
57- * Call {@link ObjectsSubscription#unsubscribe()} on the returned handle to stop
58- * receiving events for this listener.
59- *
60- * <p>Subscribe is not supported on primitive instances; implementations may throw
61- * when called on {@link NumberInstance}, {@link StringInstance},
62- * {@link BooleanInstance}, {@link BinaryInstance}, {@link JsonObjectInstance} or
63- * {@link JsonArrayInstance}.
64- *
65- * <p>Spec: RTINS16
66- *
67- * @param listener the listener to invoke on updates
68- * @return a subscription handle that can be used to unsubscribe this listener
69- */
70- @ NonBlocking
71- @ NotNull ObjectsSubscription subscribe (@ NotNull Listener listener );
72-
7367 /**
7468 * Returns this instance wrapped as a {@link LiveMapInstance}.
7569 *
7670 * <p>Best-effort cast; does not validate the underlying type. Read operations on
7771 * the returned wrapper are always permitted; write/terminal operations will fail
7872 * at call time if the wrapped value is not a {@code LiveMap}.
7973 *
74+ * <p>Spec: RTTS9a
75+ *
8076 * @return a {@link LiveMapInstance} view of this instance
8177 */
8278 @ NotNull LiveMapInstance asLiveMap ();
@@ -85,6 +81,8 @@ public interface Instance {
8581 * Returns this instance wrapped as a {@link LiveCounterInstance}.
8682 * Best-effort cast; does not validate the underlying type.
8783 *
84+ * <p>Spec: RTTS9b
85+ *
8886 * @return a {@link LiveCounterInstance} view of this instance
8987 */
9088 @ NotNull LiveCounterInstance asLiveCounter ();
@@ -93,6 +91,8 @@ public interface Instance {
9391 * Returns this instance wrapped as a {@link NumberInstance}.
9492 * Best-effort cast; does not validate the underlying type.
9593 *
94+ * <p>Spec: RTTS9c
95+ *
9696 * @return a {@link NumberInstance} view of this instance
9797 */
9898 @ NotNull NumberInstance asNumber ();
@@ -101,6 +101,8 @@ public interface Instance {
101101 * Returns this instance wrapped as a {@link StringInstance}.
102102 * Best-effort cast; does not validate the underlying type.
103103 *
104+ * <p>Spec: RTTS9c
105+ *
104106 * @return a {@link StringInstance} view of this instance
105107 */
106108 @ NotNull StringInstance asString ();
@@ -109,6 +111,8 @@ public interface Instance {
109111 * Returns this instance wrapped as a {@link BooleanInstance}.
110112 * Best-effort cast; does not validate the underlying type.
111113 *
114+ * <p>Spec: RTTS9c
115+ *
112116 * @return a {@link BooleanInstance} view of this instance
113117 */
114118 @ NotNull BooleanInstance asBoolean ();
@@ -117,6 +121,8 @@ public interface Instance {
117121 * Returns this instance wrapped as a {@link BinaryInstance}.
118122 * Best-effort cast; does not validate the underlying type.
119123 *
124+ * <p>Spec: RTTS9c
125+ *
120126 * @return a {@link BinaryInstance} view of this instance
121127 */
122128 @ NotNull BinaryInstance asBinary ();
@@ -125,6 +131,8 @@ public interface Instance {
125131 * Returns this instance wrapped as a {@link JsonObjectInstance}.
126132 * Best-effort cast; does not validate the underlying type.
127133 *
134+ * <p>Spec: RTTS9c
135+ *
128136 * @return a {@link JsonObjectInstance} view of this instance
129137 */
130138 @ NotNull JsonObjectInstance asJsonObject ();
@@ -133,37 +141,9 @@ public interface Instance {
133141 * Returns this instance wrapped as a {@link JsonArrayInstance}.
134142 * Best-effort cast; does not validate the underlying type.
135143 *
144+ * <p>Spec: RTTS9c
145+ *
136146 * @return a {@link JsonArrayInstance} view of this instance
137147 */
138148 @ NotNull JsonArrayInstance asJsonArray ();
139-
140- /**
141- * Listener interface for {@link Instance#subscribe(Listener) instance
142- * subscriptions}.
143- *
144- * <p>Spec: RTINS16a1
145- */
146- interface Listener {
147- /**
148- * Invoked when the wrapped LiveObject is modified.
149- *
150- * @param event the event describing the change
151- */
152- void onUpdated (@ NotNull SubscriptionEvent event );
153- }
154-
155- /**
156- * Event delivered to {@link Listener#onUpdated(SubscriptionEvent)} when the wrapped
157- * LiveObject is updated.
158- *
159- * <p>Spec: RTINS16e
160- */
161- interface SubscriptionEvent {
162- /**
163- * Returns the {@link Instance} that was updated.
164- *
165- * @return the updated instance
166- */
167- @ NotNull Instance getInstance ();
168- }
169149}
0 commit comments