Skip to content

Conversation

@ttypic
Copy link
Contributor

@ttypic ttypic commented Feb 11, 2026

New API for LO

Summary by CodeRabbit

Documentation

  • Added comprehensive documentation for a planned path-based LiveObjects API for Java/Kotlin and Python. Includes API architecture overview, typed model system, usage examples for common operations, detailed migration guidance from the current approach, design decisions, and implementation roadmap.

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Walkthrough

A new comprehensive documentation file is added that specifies a planned path-based API architecture for LiveObjects in Java/Kotlin and Python. The specification details typed path objects, deferred resolution, subscriptions, and includes usage examples, design decisions, and migration guidance from the existing API.

Changes

Cohort / File(s) Summary
Path-Based API Specification
liveobjects/PATH_BASED_API_JAVA_PYTHON.md
New 987-line documentation defining complete path-based LiveObjects API architecture, including typed PathObject models, core behaviors, Java/Python examples, design decisions, migration steps, performance considerations, and open questions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A blueprint hops into view so bright,
Paths and objects dancing in the light,
Java, Python, living side-by-side,
With deferred resolution as our guide,
The API of the future—oh what a sight! 🌟

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'docs: add path-based LiveObjects API proposal' clearly and directly describes the main change: adding documentation for a new path-based LiveObjects API proposal.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch draft-new-lo-api

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@liveobjects/PATH_BASED_API_JAVA_PYTHON.md`:
- Around line 88-99: The fenced code block that begins with "Value (all types
that can be stored)" is missing a language tag (MD040); update the opening
triple-backtick to include a language identifier such as "text" or "console"
(e.g., ```text) so the block is language-tagged and markdownlint passes, leaving
the block content unchanged.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new design/proposal document describing a planned path-based LiveObjects API for Java/Kotlin and Python, including core concepts, proposed interfaces, examples, and migration notes.

Changes:

  • Introduces a comprehensive implementation plan + proposed type system and interfaces for a path-based LO API.
  • Adds end-to-end usage examples (creation, mutation, subscriptions, compact snapshots, instance API).
  • Documents migration guidance and open design questions/next steps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


**Java:**
```java
LiveMapPathObject myObject = channel.getObject().get(); // The singular object
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Java examples use both channel.getObject().get() and channel.object().get() to retrieve the root object; the document should pick one canonical API shape and use it consistently (and align Python/Java naming where intended).

Suggested change
LiveMapPathObject myObject = channel.getObject().get(); // The singular object
LiveMapPathObject myObject = channel.object().get(); // The singular object

Copilot uses AI. Check for mistakes.
Comment on lines +141 to +143
PathObject get(String key);
PathObject at(String path);
LiveMap instance() throws AblyException;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

LiveMapPathObject.instance() is declared as returning a non-null LiveMap, but the later example checks if (playerInstance != null). Clarify whether instance() can return null (and reflect that in the signature, e.g., @Nullable/Optional) or remove the null-check and describe the error behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +420 to +427
// Update primitive value
myObject.at("user.name").asLiveMap().set(
"name",
Primitive.create("Bob")
);

// Or navigate to parent and set
LiveMapPathObject user = myObject.get("user").asLiveMap();
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

This mutation example navigates to "user.name" (a primitive path) and then casts to LiveMap before calling set("name", ...), which is internally inconsistent. To update a primitive, the example should operate on the parent map path ("user") or the API should define a direct primitive setter for PathObject/StringPathObject.

Suggested change
// Update primitive value
myObject.at("user.name").asLiveMap().set(
"name",
Primitive.create("Bob")
);
// Or navigate to parent and set
LiveMapPathObject user = myObject.get("user").asLiveMap();
// Update primitive value via parent map path
myObject.at("user").asLiveMap().set(
"name",
Primitive.create("Bob")
);
// Or fetch parent map object and then set
LiveMapPathObject user = myObject.at("user").asLiveMap();

Copilot uses AI. Check for mistakes.
Comment on lines +827 to +831
# Update player position
move_options = MessageOptions(
id=f"move-{time.time()}",
extras={"action": "move", "timestamp": time.time()}
)
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The Python complete example uses time.time() when building move_options, but time is not imported in the snippet. Add import time (or avoid time usage) so the example runs as written.

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +23
```java
// Path to nested value
StringPathObject colour = myObject.at("shape.colour").asStringPrimitive();
String value = colour.value(); // "red"
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The document uses both colour and color as field/key names across examples (shape.colour vs later "color"). Pick one spelling for keys/paths and use it consistently to avoid implying different schema fields.

Copilot uses AI. Check for mistakes.
PathObject get(String key);
PathObject at(String path);
LiveMap instance() throws AblyException;

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

LiveMapPathObject.set/remove take a required MessageOptions options parameter here, but most Java examples call set(...)/remove(...) without providing options. Either document overloads/default options (e.g., options nullable or a MessageOptions.none()), or update the examples so they compile against the proposed signatures.

Suggested change
// Convenience overloads using default message options
void set(String key, Value value) throws AblyException;
void remove(String key) throws AblyException;
// Full-control overloads with explicit message options

Copilot uses AI. Check for mistakes.
Comment on lines +160 to +161
Double value() throws AblyException;
void increment(Number amount, MessageOptions options) throws AblyException;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

LiveCounterPathObject.increment/decrement require MessageOptions options here, but later examples call increment(1) / decrement(25) with no options. Align the method signatures and examples (overload vs optional/default options) so the sample code is implementable as written.

Suggested change
Double value() throws AblyException;
void increment(Number amount, MessageOptions options) throws AblyException;
Double value() throws AblyException;
void increment(Number amount) throws AblyException;
void increment(Number amount, MessageOptions options) throws AblyException;
void decrement(Number amount) throws AblyException;

Copilot uses AI. Check for mistakes.
}, SubscriptionOptions.depth(2));

// Update game state
game.at("state").asLiveMap().set("state", Primitive.create("started"));
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

game.at("state") refers to a string primitive (see initialization game.set("state", Primitive.create(...))), so casting it to asLiveMap() and setting a "state" key is inconsistent. This should update the root key (e.g., game.set("state", ...)) or operate on the correct parent map path.

Suggested change
game.at("state").asLiveMap().set("state", Primitive.create("started"));
game.set("state", Primitive.create("started"));

Copilot uses AI. Check for mistakes.
)

# Update game state
game.at("state").as_live_map().set("state", Primitive.create("started"))
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Python example updates state via game.at("state").as_live_map().set(...), but state was initialized as a primitive string. Adjust the example to set the root key directly or change the data model so state is a map if that’s the intention.

Suggested change
game.at("state").as_live_map().set("state", Primitive.create("started"))
game.at("state").as_primitive().set(Primitive.create("started"))

Copilot uses AI. Check for mistakes.
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