Skip to content

[LiveObjects] Implement path-based LiveObjects public API#1213

Open
sacOO7 wants to merge 4 commits into
feature/path-based-liveobjects-implementationfrom
feature/path-based-liveobjects-final-public-api
Open

[LiveObjects] Implement path-based LiveObjects public API#1213
sacOO7 wants to merge 4 commits into
feature/path-based-liveobjects-implementationfrom
feature/path-based-liveobjects-final-public-api

Conversation

@sacOO7

@sacOO7 sacOO7 commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Out of scope

  • Default implementation for interface methods ( This will be handled by downstream kotlin classes )

  • Integration with channel.object

    Reason: Current public API only focuses on new path-based liveobjects interface. It's intentionally kept clean and currently doesn't interfare with existing objects interfaces

Summary by CodeRabbit

  • New Features
    • Added comprehensive LiveObjects API supporting live maps and counters for real-time collaborative data management
    • Introduced dual access patterns: path-based navigation for flexible queries and instance-based views for direct object access
    • Added subscription support with listeners and events to monitor updates to LiveObjects values and structures

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR introduces the LiveObjects public API for the Ably Java client library. It adds contracts for accessing live maps and counters through two access patterns: path-based navigation and instance-based identity-addressed views, with comprehensive message/operation structures, listener callbacks, subscription handles, and write-side value holders for mutations.

Changes

LiveObjects Type System and API

Layer / File(s) Summary
Core subscription and value type foundation
lib/src/main/java/io/ably/lib/object/Subscription.java, lib/src/main/java/io/ably/lib/object/ValueType.java, lib/src/main/java/io/ably/lib/object/package-info.java
Subscription interface enables listener deregistration and cleanup; ValueType enum defines all supported wrapped kinds (string, number, boolean, binary, JSON, live map/counter); root package documentation establishes the LiveObjects architecture.
Instance-addressed (direct) LiveObjects view and types
lib/src/main/java/io/ably/lib/object/instance/Instance.java, lib/src/main/java/io/ably/lib/object/instance/InstanceListener.java, lib/src/main/java/io/ably/lib/object/instance/InstanceSubscriptionEvent.java, lib/src/main/java/io/ably/lib/object/instance/types/LiveMapInstance.java, lib/src/main/java/io/ably/lib/object/instance/types/LiveCounterInstance.java, lib/src/main/java/io/ably/lib/object/instance/types/*.java (primitives), lib/src/main/java/io/ably/lib/object/instance/package-info.java
Instance provides identity-addressed access to resolved objects/primitives with type casting; LiveMapInstance/LiveCounterInstance expose typed operations (get/set/increment/decrement) and subscriptions; six primitive instance types wrap immutable values with read-only accessors.
Message and operation contracts for object updates
lib/src/main/java/io/ably/lib/object/message/ObjectMessage.java, lib/src/main/java/io/ably/lib/object/message/ObjectOperation.java, lib/src/main/java/io/ably/lib/object/message/ObjectOperationAction.java, lib/src/main/java/io/ably/lib/object/message/MapCreate.java, lib/src/main/java/io/ably/lib/object/message/MapSet.java, lib/src/main/java/io/ably/lib/object/message/MapRemove.java, lib/src/main/java/io/ably/lib/object/message/CounterCreate.java, lib/src/main/java/io/ably/lib/object/message/CounterInc.java, lib/src/main/java/io/ably/lib/object/message/ObjectDelete.java, lib/src/main/java/io/ably/lib/object/message/MapClear.java, lib/src/main/java/io/ably/lib/object/message/ObjectData.java, lib/src/main/java/io/ably/lib/object/message/ObjectsMapEntry.java, lib/src/main/java/io/ably/lib/object/message/ObjectsMapSemantics.java, lib/src/main/java/io/ably/lib/object/message/package-info.java
ObjectMessage is the user-facing entry point carrying metadata and an operation; ObjectOperation identifies the action and target object ID with nullable payload accessors; operation-specific types (MapCreate, MapSet, CounterInc, etc.) define payloads; ObjectData union exposes referenced objects or primitive/JSON values.
Path-addressed (lazy) LiveObjects view and types
lib/src/main/java/io/ably/lib/object/path/PathObject.java, lib/src/main/java/io/ably/lib/object/path/PathObjectListener.java, lib/src/main/java/io/ably/lib/object/path/PathObjectSubscriptionEvent.java, lib/src/main/java/io/ably/lib/object/path/PathObjectSubscriptionOptions.java, lib/src/main/java/io/ably/lib/object/path/types/LiveMapPathObject.java, lib/src/main/java/io/ably/lib/object/path/types/LiveCounterPathObject.java, lib/src/main/java/io/ably/lib/object/path/types/*.java (primitives), lib/src/main/java/io/ably/lib/object/path/package-info.java
PathObject provides lazy, dot-delimited path navigation with best-effort resolution semantics; LiveMapPathObject enables hierarchical get/at navigation and mutations; LiveCounterPathObject exposes increment/decrement operations; six primitive path types offer terminal read-only value access; subscription depth limiting via PathObjectSubscriptionOptions.
Value holders and factories for mutations
lib/src/main/java/io/ably/lib/object/value/LiveCounter.java, lib/src/main/java/io/ably/lib/object/value/LiveMap.java, lib/src/main/java/io/ably/lib/object/value/LiveMapValue.java, lib/src/main/java/io/ably/lib/object/value/package-info.java
LiveCounter and LiveMap are immutable factory wrappers that reflectively instantiate plugin implementations for use in mutations; LiveMapValue defines a type-safe union of allowed map entry values with boolean predicates, typed getters, and factory methods for each supported kind (boolean, binary, number, string, JSON array/object, LiveCounter, LiveMap).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

This PR introduces 50+ new public API interfaces and classes across a well-structured type hierarchy, with consistent nullability annotations, comprehensive Javadoc, and clear separation of concerns (instance vs. path views, message contracts, value holders). The changes are primarily API declarations with minimal implementation logic (reflection-based factory methods and union type wrappers). Review effort is moderate due to the breadth of the API surface and the need to verify consistency across the type system, but the homogeneous structure and clear conceptual organization keep complexity manageable.

Poem

🐰 A LiveObjects warren takes shape today,
With paths and instances to guide the way,
Maps and counters dance in subscribed delight,
Type-safe mutations shining crystal-bright,
Ably's graph now lives in Java's sight! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: implementing the path-based LiveObjects public API. The changeset adds numerous public interfaces and classes forming a complete path-based API layer, directly matching the title's focus.
Docstring Coverage ✅ Passed Docstring coverage is 81.61% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/path-based-liveobjects-final-public-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sacOO7 sacOO7 changed the base branch from main to feature/path-based-liveobjects-implementation June 8, 2026 12:41
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/features June 8, 2026 12:42 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/javadoc June 8, 2026 12:43 Inactive
@sacOO7 sacOO7 force-pushed the feature/path-based-liveobjects-final-public-api branch from a2531ed to 0410432 Compare June 8, 2026 12:50
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/features June 8, 2026 12:51 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/javadoc June 8, 2026 12:53 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/features June 9, 2026 10:45 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/javadoc June 9, 2026 10:46 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/features June 10, 2026 12:00 Inactive
@sacOO7 sacOO7 force-pushed the feature/path-based-liveobjects-final-public-api branch from 8264313 to 99d9dd9 Compare June 10, 2026 12:01
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/features June 10, 2026 12:02 Inactive
@github-actions github-actions Bot temporarily deployed to staging/pull/1213/javadoc June 10, 2026 12:04 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
lib/src/main/java/io/ably/lib/object/instance/types/BinaryInstance.java (1)

24-24: ⚡ Quick win

Inconsistent annotation style with other primitive instances.

All other primitive instance types (BooleanInstance, StringInstance, NumberInstance, JsonArrayInstance, JsonObjectInstance) place @NotNull on a separate line before the return type, but BinaryInstance uses inline type-use syntax byte @NotNull []. While both are valid, consistency improves maintainability.

♻️ Align with the annotation style used by other primitive instances
     /**
      * Returns the wrapped binary value.
      *
      * <p>Spec: RTINS4 / RTTS10c
      *
      * `@return` the wrapped bytes
      */
-    byte `@NotNull` [] value();
+    `@NotNull`
+    byte[] value();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/main/java/io/ably/lib/object/instance/types/BinaryInstance.java` at
line 24, The annotation placement in BinaryInstance's value() method is
inconsistent—change the type-use form `byte `@NotNull` [] value()` to the same
style used by other primitives by placing `@NotNull` on its own line above the
return type so the signature reads with `@NotNull` on a separate line prior to
`byte[]` in the BinaryInstance interface's value() method to match
BooleanInstance, StringInstance, NumberInstance, JsonArrayInstance, and
JsonObjectInstance.
lib/src/main/java/io/ably/lib/object/message/ObjectData.java (1)

53-60: ⚡ Quick win

Clarify defensive-copy semantics for binary payloads.

Line 60 returns a mutable byte[]; without a copy/immutability contract, callers can mutate shared state if implementations return backing storage.

♻️ Suggested contract hardening
     /**
      * Returns the binary value.
      *
      * <p>Spec: OD2c
      *
-     * `@return` the binary value, or {`@code` null} if not applicable
+     * <p>Implementations should return a defensive copy (or otherwise guarantee
+     * immutability) so callers cannot mutate internal state.
+     *
+     * `@return` the binary value, or {`@code` null} if not applicable
      */
     byte `@Nullable` [] getBytes();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/main/java/io/ably/lib/object/message/ObjectData.java` around lines 53
- 60, The Javadoc for ObjectData.getBytes() is ambiguous about whether the
returned byte[] is a live backing array or a defensive copy; update the contract
in the getBytes() Javadoc of class ObjectData to state explicitly whether
callers may mutate the returned array or not and what implementations must do
(preferably: implementations must return a defensive copy of internal storage
and callers may freely modify the returned array), and mention performance
implications so implementers can optimize (e.g., offer an alternative method
like getBytesView() returning an unmodifiable/readonly view if needed);
reference the getBytes() method and ensure the Javadoc mentions nullability,
copy semantics, and responsibilities for callers and implementers.
lib/src/main/java/io/ably/lib/object/value/LiveMapValue.java (1)

289-306: ⚡ Quick win

Binary array stored and returned without defensive copies.

BinaryValue stores the byte[] reference directly (line 293) and returns it directly (line 305), allowing external code to mutate the array after construction or after calling getAsBinary(). This can lead to unexpected state changes in the LiveMapValue after it has been created or retrieved.

🛡️ Recommended fix: add defensive copies
 BinaryValue(byte `@NotNull` [] value) {
-    this.value = value;
+    this.value = value.clone();
 }

 `@Override`
 public byte `@NotNull` [] getAsBinary() { 
-    return value; 
+    return value.clone(); 
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/main/java/io/ably/lib/object/value/LiveMapValue.java` around lines
289 - 306, BinaryValue stores and exposes the mutable byte[] directly; to
prevent external mutation, make defensive copies: in the BinaryValue(byte[]
value) constructor copy the incoming array (e.g., Arrays.copyOf) into the
private field, and in both getValue() and getAsBinary() return a copy of the
internal array rather than the raw reference; update imports if needed and keep
the field final and type byte[].
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@lib/src/main/java/io/ably/lib/object/path/PathObjectSubscriptionOptions.java`:
- Around line 21-23: The constructor in PathObjectSubscriptionOptions currently
accepts zero and negative depths; update the
PathObjectSubscriptionOptions(Integer depth) constructor to enforce the
documented invariant by validating that if depth is non-null it must be > 0, and
throw an IllegalArgumentException (or similar) when depth <= 0; leave null
accepted as before and assign this.depth only after validation.

In `@lib/src/main/java/io/ably/lib/object/path/types/JsonObjectPathObject.java`:
- Around line 10-13: Update the Javadoc on JsonObjectPathObject to remove the
incorrect reference to “primitive resolution” (since this type represents a
JsonObject, not a primitive): reword the sentence that explains why
PathObject#instance() returns null to say that this is a terminal/object
resolution for JsonObject rather than a primitive resolution, and clarify that
navigation via at(...) is not available because it’s only defined on
LiveMapPathObject while value() and inherited read APIs remain available.

In `@lib/src/main/java/io/ably/lib/object/path/types/LiveMapPathObject.java`:
- Around line 48-53: The Javadoc example incorrectly chains
liveMapPath.get("a").get("b").get("c") even though get(...) returns PathObject,
so update the example to be consistent by either using at(...) for each step
(e.g., liveMapPath.at("a").at("b").at("c")) or show the explicit cast using
PathObject#asLiveMap between get calls (e.g.,
liveMapPath.get("a").asLiveMap().get("b")...), and adjust the surrounding text
to reference LiveMapPathObject, get, at, and PathObject#asLiveMap accordingly.

---

Nitpick comments:
In `@lib/src/main/java/io/ably/lib/object/instance/types/BinaryInstance.java`:
- Line 24: The annotation placement in BinaryInstance's value() method is
inconsistent—change the type-use form `byte `@NotNull` [] value()` to the same
style used by other primitives by placing `@NotNull` on its own line above the
return type so the signature reads with `@NotNull` on a separate line prior to
`byte[]` in the BinaryInstance interface's value() method to match
BooleanInstance, StringInstance, NumberInstance, JsonArrayInstance, and
JsonObjectInstance.

In `@lib/src/main/java/io/ably/lib/object/message/ObjectData.java`:
- Around line 53-60: The Javadoc for ObjectData.getBytes() is ambiguous about
whether the returned byte[] is a live backing array or a defensive copy; update
the contract in the getBytes() Javadoc of class ObjectData to state explicitly
whether callers may mutate the returned array or not and what implementations
must do (preferably: implementations must return a defensive copy of internal
storage and callers may freely modify the returned array), and mention
performance implications so implementers can optimize (e.g., offer an
alternative method like getBytesView() returning an unmodifiable/readonly view
if needed); reference the getBytes() method and ensure the Javadoc mentions
nullability, copy semantics, and responsibilities for callers and implementers.

In `@lib/src/main/java/io/ably/lib/object/value/LiveMapValue.java`:
- Around line 289-306: BinaryValue stores and exposes the mutable byte[]
directly; to prevent external mutation, make defensive copies: in the
BinaryValue(byte[] value) constructor copy the incoming array (e.g.,
Arrays.copyOf) into the private field, and in both getValue() and getAsBinary()
return a copy of the internal array rather than the raw reference; update
imports if needed and keep the field final and type byte[].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b9e4b17-fc76-48eb-92d3-5620a4a45e55

📥 Commits

Reviewing files that changed from the base of the PR and between 0e5e684 and 59a5ecc.

📒 Files selected for processing (48)
  • lib/src/main/java/io/ably/lib/object/Subscription.java
  • lib/src/main/java/io/ably/lib/object/ValueType.java
  • lib/src/main/java/io/ably/lib/object/instance/Instance.java
  • lib/src/main/java/io/ably/lib/object/instance/InstanceListener.java
  • lib/src/main/java/io/ably/lib/object/instance/InstanceSubscriptionEvent.java
  • lib/src/main/java/io/ably/lib/object/instance/package-info.java
  • lib/src/main/java/io/ably/lib/object/instance/types/BinaryInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/BooleanInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/JsonArrayInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/JsonObjectInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/LiveCounterInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/LiveMapInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/NumberInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/StringInstance.java
  • lib/src/main/java/io/ably/lib/object/instance/types/package-info.java
  • lib/src/main/java/io/ably/lib/object/message/CounterCreate.java
  • lib/src/main/java/io/ably/lib/object/message/CounterInc.java
  • lib/src/main/java/io/ably/lib/object/message/MapClear.java
  • lib/src/main/java/io/ably/lib/object/message/MapCreate.java
  • lib/src/main/java/io/ably/lib/object/message/MapRemove.java
  • lib/src/main/java/io/ably/lib/object/message/MapSet.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectData.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectDelete.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectMessage.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectOperation.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectOperationAction.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectsMapEntry.java
  • lib/src/main/java/io/ably/lib/object/message/ObjectsMapSemantics.java
  • lib/src/main/java/io/ably/lib/object/message/package-info.java
  • lib/src/main/java/io/ably/lib/object/package-info.java
  • lib/src/main/java/io/ably/lib/object/path/PathObject.java
  • lib/src/main/java/io/ably/lib/object/path/PathObjectListener.java
  • lib/src/main/java/io/ably/lib/object/path/PathObjectSubscriptionEvent.java
  • lib/src/main/java/io/ably/lib/object/path/PathObjectSubscriptionOptions.java
  • lib/src/main/java/io/ably/lib/object/path/package-info.java
  • lib/src/main/java/io/ably/lib/object/path/types/BinaryPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/BooleanPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/JsonArrayPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/JsonObjectPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/LiveCounterPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/LiveMapPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/NumberPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/StringPathObject.java
  • lib/src/main/java/io/ably/lib/object/path/types/package-info.java
  • lib/src/main/java/io/ably/lib/object/value/LiveCounter.java
  • lib/src/main/java/io/ably/lib/object/value/LiveMap.java
  • lib/src/main/java/io/ably/lib/object/value/LiveMapValue.java
  • lib/src/main/java/io/ably/lib/object/value/package-info.java

Comment on lines +21 to +23
public PathObjectSubscriptionOptions(@Nullable Integer depth) {
this.depth = depth;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enforce the documented positive-depth invariant in the constructor.

Line 21 currently accepts 0 and negative values, even though the API contract says depth must be positive. That creates invalid PathObjectSubscriptionOptions instances and pushes failures downstream.

Suggested fix
 public PathObjectSubscriptionOptions(`@Nullable` Integer depth) {
+    if (depth != null && depth <= 0) {
+        throw new IllegalArgumentException("depth must be a positive integer");
+    }
     this.depth = depth;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public PathObjectSubscriptionOptions(@Nullable Integer depth) {
this.depth = depth;
}
public PathObjectSubscriptionOptions(`@Nullable` Integer depth) {
if (depth != null && depth <= 0) {
throw new IllegalArgumentException("depth must be a positive integer");
}
this.depth = depth;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/main/java/io/ably/lib/object/path/PathObjectSubscriptionOptions.java`
around lines 21 - 23, The constructor in PathObjectSubscriptionOptions currently
accepts zero and negative depths; update the
PathObjectSubscriptionOptions(Integer depth) constructor to enforce the
documented invariant by validating that if depth is non-null it must be > 0, and
throw an IllegalArgumentException (or similar) when depth <= 0; leave null
accepted as before and assign this.depth only after validation.

Comment on lines +10 to +13
* <p>This is a terminal type. {@link PathObject#instance()} returns {@code null}
* because a primitive resolution does not produce a wrapped LiveObject; navigation
* via {@code at(...)} is not available here because it is only defined on
* {@code LiveMapPathObject}. Only {@link #value()} and the inherited read APIs are

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix incorrect primitive wording in terminal-type Javadoc.

Line 10 says this returns null due to “primitive resolution,” but this type is for JsonObject, not a primitive. Please reword to avoid semantic confusion in the public API docs.

Proposed doc fix
- * <p>This is a terminal type. {`@link` PathObject#instance()} returns {`@code` null}
- * because a primitive resolution does not produce a wrapped LiveObject; navigation
+ * <p>This is a terminal type. {`@link` PathObject#instance()} returns {`@code` null}
+ * because this resolution does not produce a wrapped LiveObject instance; navigation
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* <p>This is a terminal type. {@link PathObject#instance()} returns {@code null}
* because a primitive resolution does not produce a wrapped LiveObject; navigation
* via {@code at(...)} is not available here because it is only defined on
* {@code LiveMapPathObject}. Only {@link #value()} and the inherited read APIs are
* <p>This is a terminal type. {`@link` PathObject#instance()} returns {`@code` null}
* because this resolution does not produce a wrapped LiveObject instance; navigation
* via {`@code` at(...)} is not available here because it is only defined on
* {`@code` LiveMapPathObject}. Only {`@link` `#value`()} and the inherited read APIs are
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/main/java/io/ably/lib/object/path/types/JsonObjectPathObject.java`
around lines 10 - 13, Update the Javadoc on JsonObjectPathObject to remove the
incorrect reference to “primitive resolution” (since this type represents a
JsonObject, not a primitive): reword the sentence that explains why
PathObject#instance() returns null to say that this is a terminal/object
resolution for JsonObject rather than a primitive resolution, and clarify that
navigation via at(...) is not available because it’s only defined on
LiveMapPathObject while value() and inherited read APIs remain available.

Comment on lines +48 to +53
* performed by this call. {@code liveMapPath.at("a.b.c")} is equivalent to
* {@code liveMapPath.get("a").get("b").get("c")}.
*
* <p>Available only on {@code LiveMapPathObject} because deeper navigation is only
* meaningful when the current resolved value is a {@code LiveMap}. To traverse from
* an arbitrary {@link PathObject}, first cast via {@link PathObject#asLiveMap()}.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Javadoc example conflicts with the declared get return type.

Line 49 shows liveMapPath.get("a").get("b").get("c"), but Line 40 returns PathObject, so this chain is inconsistent with the surrounding guidance (Lines 51-53). Please update the example to use at(...) only or include explicit asLiveMap() transitions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/main/java/io/ably/lib/object/path/types/LiveMapPathObject.java`
around lines 48 - 53, The Javadoc example incorrectly chains
liveMapPath.get("a").get("b").get("c") even though get(...) returns PathObject,
so update the example to be consistent by either using at(...) for each step
(e.g., liveMapPath.at("a").at("b").at("c")) or show the explicit cast using
PathObject#asLiveMap between get calls (e.g.,
liveMapPath.get("a").asLiveMap().get("b")...), and adjust the surrounding text
to reference LiveMapPathObject, get, at, and PathObject#asLiveMap accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant