Skip to content

Conversation

@VeskeR
Copy link
Contributor

@VeskeR VeskeR commented Nov 11, 2025

This marks full transition to path-based API for LiveObjects. Included in this PR:

  • resolve TODOs related to path-based API
  • update all LiveObjects tests to use path-based API
  • remove publicly exposed LiveObject, LiveMap and LiveCounter types from ably.d.ts
  • remove lifecycle subscriptions API for liveobjects (API and implementation). OBJECT_DELETE events are handled by regular subscription events.

Summary by CodeRabbit

Release Notes

  • New Features

    • Global object type customization support
    • Standardized JSON type system
  • API Changes

    • Updated subscription patterns with refined Subscription interfaces
    • get() method now returns path-wrapped objects instead of direct instances
    • Removed deprecated LiveObject lifecycle event methods (on, off, offAll)
    • Simplified generic type constraints for LiveMap operations

@coderabbitai
Copy link

coderabbitai bot commented Nov 11, 2025

Warning

Rate limit exceeded

@VeskeR has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 49 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between eb5afe1 and e7d734e.

📒 Files selected for processing (12)
  • ably.d.ts (7 hunks)
  • src/plugins/objects/batchcontext.ts (1 hunks)
  • src/plugins/objects/instance.ts (2 hunks)
  • src/plugins/objects/livemap.ts (11 hunks)
  • src/plugins/objects/livemapvaluetype.ts (2 hunks)
  • src/plugins/objects/liveobject.ts (3 hunks)
  • src/plugins/objects/objectmessage.ts (1 hunks)
  • src/plugins/objects/objectspool.ts (1 hunks)
  • src/plugins/objects/pathobject.ts (4 hunks)
  • src/plugins/objects/pathobjectsubscriptionregister.ts (2 hunks)
  • src/plugins/objects/realtimeobject.ts (1 hunks)
  • test/common/modules/private_api_recorder.js (0 hunks)

Walkthrough

This PR performs a comprehensive type system and API refactoring for the Ably objects module, removing legacy lifecycle event types, introducing Subscription-based abstractions, generalizing LiveMap value typing to standardized API.Value, adding global type configuration via AblyObjectsTypes, and restructuring object access patterns with PathObject wrapping.

Changes

Cohort / File(s) Summary
Type definitions
ably.d.ts
Removed legacy lifecycle types (LiveObjectLifecycleEvent, LiveObjectLifecycleEventCallback, LiveObjectLifecycleEvents, OnLiveObjectLifecycleEventResponse, SubscribeResponse). Added new Subscription and StatusSubscription interfaces. Introduced global AblyObjectsTypes interface and AblyDefaultObject conditional type for user-defined object typing. Added JSON type suite (Json, JsonScalar, JsonArray, JsonObject). Updated RealtimeObject.get to return Promise<PathObject<LiveMap<T>>> and Objects.on() to return StatusSubscription. Updated PathObjectBase.subscribe to return Subscription.
Type re-exports
objects.d.ts
Added re-exports of LiveMapType as LiveMap and LiveCounterType as LiveCounter.
LiveMap value generalization
src/plugins/objects/livemap.ts, src/plugins/objects/livemapvaluetype.ts, src/plugins/objects/objectmessage.ts
Replaced API.LiveMapType with Record<string, API.Value> as the generic constraint for LiveMap. Updated static methods (zeroValue, fromObjectState, createMapSetMessage, createMapRemoveMessage, validateKeyValue) to remove generic type parameters and use API.Value. Changed ObjectData.value from PrimitiveObjectValue to API.Primitive. Removed PrimitiveObjectValue export. Updated value handling and type assertions throughout.
Subscription type refactoring
src/plugins/objects/instance.ts, src/plugins/objects/liveobject.ts, src/plugins/objects/pathobject.ts, src/plugins/objects/pathobjectsubscriptionregister.ts
Replaced SubscribeResponse return type with Subscription across all subscription methods. Updated imports to use new Subscription interface. Removed lifecycle event methods (on, off, offAll) from LiveObject.
Object access pattern restructuring
src/plugins/objects/realtimeobject.ts, src/plugins/objects/objectspool.ts
Updated RealtimeObject.get() to return Promise<API.PathObject<API.LiveMap<T>>> instead of Promise<LiveMap<T>>. Removed getPathObject() method. Simplified ObjectsPool.getRoot() from generic signature to non-generic, returning bare LiveMap.
Minor updates
src/plugins/objects/batchcontext.ts, src/plugins/objects/pathobject.ts, test/common/modules/private_api_recorder.js
Removed explicit type cast in createMapSetMessage call. Removed API namespace import and switched to direct LiveMap usage. Removed private API identifier for call.LiveObject.getObjectId from recorder.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant RealtimeObject
    participant DefaultPathObject
    participant LiveMap
    participant Subscription

    rect rgb(220, 240, 230)
    Note over Client,Subscription: New object access pattern
    Client->>RealtimeObject: get<T>()
    RealtimeObject->>LiveMap: getRoot()
    LiveMap-->>RealtimeObject: LiveMap instance
    RealtimeObject->>DefaultPathObject: new DefaultPathObject(root)
    DefaultPathObject-->>RealtimeObject: PathObject<LiveMap<T>>
    RealtimeObject-->>Client: Promise<PathObject<LiveMap<T>>>
    end

    rect rgb(240, 220, 230)
    Note over Client,Subscription: Legacy lifecycle removal
    Note over Client,Subscription: on/off(LiveObjectLifecycleEvent) removed<br/>subscribe(listener) replaces lifecycle events
    Client->>Subscription: subscribe(listener)
    Subscription-->>Client: Subscription (with unsubscribe())
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • ably.d.ts: Large-scale type system refactoring with multiple new global type definitions, conditional type logic for AblyDefaultObject, and broad API surface changes across subscription and object typing abstractions.
  • LiveMap and value typing cascade: Changes to LiveMap class signature, static method signatures, and value resolution paths affect multiple dependent files (livemapvaluetype.ts, objectmessage.ts, batchcontext.ts).
  • Subscription abstraction rollout: Replacement of SubscribeResponse with Subscription across four files (instance.ts, liveobject.ts, pathobject.ts, pathobjectsubscriptionregister.ts) requires consistent verification of contract changes.
  • API surface restructuring: RealtimeObject.get() now returns PathObject wrapping instead of direct LiveMap, fundamentally changing the caller interaction pattern and requiring careful validation of backward compatibility implications.
  • Lifecycle event removal: Complete removal of on/off/offAll lifecycle event API from LiveObject and associated types; verify no dangling references or user-facing impact.

Possibly related PRs

  • ably-js#1950: Modifies objects/liveobjects code including LiveMap/LiveObject APIs and message-creation methods (createMapSetMessage, createMapRemoveMessage, validateKeyValue), suggesting overlap in the objects module refactoring effort.

Suggested reviewers

  • mschristensen

Poem

🐰 Hops through the type trees with glee,
Where lifecycle events used to be,
Now Subscriptions dance bright,
PathObjects wrap tight,
And AblyDefaultObject sets types free!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main objective: transitioning LiveObjects to a path-based API by removing non-path-based public APIs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

@github-actions github-actions bot temporarily deployed to staging/pull/2108/features November 11, 2025 09:05 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/2108/bundle-report November 11, 2025 09:05 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/2108/typedoc November 11, 2025 09:05 Inactive
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ccf87e5 and eb5afe1.

📒 Files selected for processing (13)
  • ably.d.ts (7 hunks)
  • objects.d.ts (1 hunks)
  • src/plugins/objects/batchcontext.ts (1 hunks)
  • src/plugins/objects/instance.ts (2 hunks)
  • src/plugins/objects/livemap.ts (11 hunks)
  • src/plugins/objects/livemapvaluetype.ts (2 hunks)
  • src/plugins/objects/liveobject.ts (3 hunks)
  • src/plugins/objects/objectmessage.ts (1 hunks)
  • src/plugins/objects/objectspool.ts (1 hunks)
  • src/plugins/objects/pathobject.ts (4 hunks)
  • src/plugins/objects/pathobjectsubscriptionregister.ts (2 hunks)
  • src/plugins/objects/realtimeobject.ts (1 hunks)
  • test/common/modules/private_api_recorder.js (0 hunks)
💤 Files with no reviewable changes (1)
  • test/common/modules/private_api_recorder.js
🧰 Additional context used
🧬 Code graph analysis (11)
src/plugins/objects/objectmessage.ts (1)
ably.d.ts (1)
  • Primitive (2373-2381)
src/plugins/objects/pathobject.ts (2)
ably.d.ts (3)
  • LiveMap (2415-2418)
  • Subscription (1680-1689)
  • Value (2438-2438)
src/plugins/objects/livemap.ts (1)
  • LiveMap (48-983)
src/plugins/objects/pathobjectsubscriptionregister.ts (1)
ably.d.ts (1)
  • Subscription (1680-1689)
src/plugins/objects/batchcontext.ts (1)
src/plugins/objects/livemap.ts (1)
  • LiveMap (48-983)
src/plugins/objects/liveobject.ts (2)
ably.d.ts (2)
  • EventCallback (1653-1653)
  • Subscription (1680-1689)
src/plugins/objects/instance.ts (1)
  • InstanceEvent (22-25)
src/plugins/objects/objectspool.ts (3)
ably.d.ts (1)
  • LiveMap (2415-2418)
objects.d.ts (1)
  • LiveMap (19-31)
src/plugins/objects/livemap.ts (1)
  • LiveMap (48-983)
src/plugins/objects/realtimeobject.ts (1)
ably.d.ts (3)
  • Value (2438-2438)
  • AblyDefaultObject (2487-3539)
  • LiveMap (2415-2418)
src/plugins/objects/instance.ts (1)
ably.d.ts (4)
  • EventCallback (1653-1653)
  • InstanceSubscriptionEvent (3688-3693)
  • Subscription (1680-1689)
  • LiveObject (2431-2431)
src/plugins/objects/livemapvaluetype.ts (2)
src/plugins/objects/livemap.ts (2)
  • LiveMap (48-983)
  • ValueObjectData (24-27)
ably.d.ts (2)
  • LiveMap (2415-2418)
  • Primitive (2373-2381)
src/plugins/objects/livemap.ts (4)
ably.d.ts (6)
  • Primitive (2373-2381)
  • Value (2438-2438)
  • LiveMap (2415-2418)
  • LiveObject (2431-2431)
  • ObjectMessage (3754-3801)
  • CompactedValue (2444-2469)
src/plugins/objects/liveobject.ts (1)
  • LiveObjectUpdate (18-26)
src/plugins/objects/realtimeobject.ts (1)
  • RealtimeObject (38-489)
src/plugins/objects/objectmessage.ts (1)
  • ObjectMessage (358-462)
ably.d.ts (4)
objects.d.ts (1)
  • LiveMap (19-31)
src/plugins/objects/livemap.ts (1)
  • LiveMap (48-983)
src/plugins/objects/realtimeobject.ts (1)
  • ObjectsEventCallback (32-32)
test/package/browser/template/src/index-objects.ts (1)
  • AblyObjectsTypes (27-29)
🪛 GitHub Actions: Test NPM package
objects.d.ts

[error] 14-14: Cannot redeclare exported variable 'LiveMap'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: test-browser (firefox)
  • GitHub Check: test-browser (webkit)
  • GitHub Check: test-browser (chromium)
  • GitHub Check: test-node (18.x)
  • GitHub Check: test-node (20.x)
  • GitHub Check: test-node (16.x)
🔇 Additional comments (11)
src/plugins/objects/batchcontext.ts (1)

84-84: LGTM! Correct alignment with function signature.

The removal of the cast to Primitive is correct, as LiveMap.createMapSetMessage expects value: API.Value, which can be a primitive, LiveCounterValueType, or LiveMapValueType.

src/plugins/objects/pathobjectsubscriptionregister.ts (1)

6-6: LGTM! Consistent with API refactoring.

The change from SubscribeResponse to Subscription aligns with the PR-wide transition to Subscription-based abstractions. The implementation correctly returns an object with an unsubscribe method matching the Subscription interface.

Also applies to: 63-63

src/plugins/objects/objectmessage.ts (1)

44-44: LGTM! Type standardization.

The change from PrimitiveObjectValue to API.Primitive standardizes primitive value typing across the codebase and aligns with the removal of the PrimitiveObjectValue alias.

src/plugins/objects/livemapvaluetype.ts (1)

77-77: LGTM! Consistent type handling.

Both changes correctly align with the removal of PrimitiveObjectValue and the standardization on API.Primitive. Line 77 removes an unnecessary cast since LiveMap.validateKeyValue expects value: API.Value, and line 141 correctly types primitive values as API.Primitive for ValueObjectData.

Also applies to: 141-141

src/plugins/objects/objectspool.ts (1)

33-34: LGTM! API simplification.

The removal of the generic type parameter simplifies the API and aligns with the broader refactoring to use non-generic LiveMap. This change is consistent with the PathObject-based access pattern introduced in the PR.

src/plugins/objects/pathobject.ts (1)

14-14: LGTM! Consistent API refactoring.

All changes align with the PR objectives:

  1. Lines 14, 354: Migration from SubscribeResponse to Subscription aligns with the new subscription-based abstractions.
  2. Line 34: Removing the generic type parameter from LiveMap simplifies the internal API.
  3. Line 385: Direct assignment is cleaner since this._root is already LiveMap, which extends Value.

These changes are consistent with the broader transition to PathObject-based access patterns.

Also applies to: 34-34, 354-354, 385-385

src/plugins/objects/instance.ts (1)

12-12: LGTM! Proper subscription delegation.

The changes correctly implement the migration to Subscription:

  1. Lines 12, 172: Import and return type updated to use Subscription.
  2. Line 176: Implementation properly delegates to the underlying LiveObject's subscribe method and transforms the internal InstanceEvent to the public InstanceSubscriptionEvent format, including converting ObjectMessage to its user-facing representation.

Also applies to: 172-172, 176-176

src/plugins/objects/realtimeobject.ts (1)

82-91: Return type upgrade looks solid.

Gating on the existing sync semaphore before handing back the DefaultPathObject keeps the old lifecycle guarantees while exposing the new path-based surface. Nicely done.

src/plugins/objects/liveobject.ts (1)

71-81: Subscription wrapper matches the new contract.

Switching to the { unsubscribe } shape plugs straight into the new Subscription interface without altering the underlying emitter behaviour. Looks good to me.

src/plugins/objects/livemap.ts (1)

499-525: compact still normalizes nested structures correctly.

Iterating via entries() means we continue to skip tombstoned keys and base64 wrap buffers, so the observable JSON footprint stays intact after the generics refactor.

ably.d.ts (1)

1670-1710: Typings line up with the runtime changes.

The new Subscription / StatusSubscription interfaces give consumers a consistent unsubscribe/off contract and match the objects returned in code. Looks good.

@VeskeR VeskeR force-pushed the PUB-2065/path-based-batch-api branch 2 times, most recently from aea9de3 to 80fd55e Compare November 11, 2025 09:22
@VeskeR VeskeR force-pushed the liveobjects/remove-non-path-based-api branch from eb5afe1 to 81e9e97 Compare November 11, 2025 09:23
This marks full transition to path-based API for LiveObjects.
Included in this PR:
- resolve TODOs related to path-based API
- update all LiveObjects tests to use path-based API
- remove publicly exposed LiveObject, LiveMap and LiveCounter types from
  ably.d.ts
- remove lifecycle subscriptions API for liveobjects (API and
  implementation). OBJECT_DELETE events are handled by regular
  subscription events.
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.

2 participants