Skip to content

[AIT-324] Apply operations on ACK#118

Open
lawrence-forooghian wants to merge 1 commit intomainfrom
AIT-324-apply-on-ACK
Open

[AIT-324] Apply operations on ACK#118
lawrence-forooghian wants to merge 1 commit intomainfrom
AIT-324-apply-on-ACK

Conversation

@lawrence-forooghian
Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian commented Feb 27, 2026

When you call a LiveObjects mutation method (e.g. map.set()), the SDK now applies the effects of this operation to the local LiveObjects data as soon as it receives the server's acknowledgement of this operation. This is an improvement over earlier versions, in which the SDK did not apply such an operation until receiving the operation's echo.

Supporting PRs:

Related PRs:

Summary by CodeRabbit

Release Notes

  • New Features

    • Improved operation acknowledgment handling with apply-on-ACK mechanism for faster object state synchronization.
    • Enhanced synchronization waiter infrastructure for better coordination during channel state transitions.
  • Bug Fixes

    • Fixed reliability issues with operation application during network edge cases and channel state changes.
  • Tests

    • Added comprehensive test coverage for operation synchronization and apply-on-ACK scenarios.

@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects February 27, 2026 14:58 Inactive
@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Walkthrough

This PR implements a publish-and-apply pattern for live objects where operations are applied locally upon ACK from the Realtime channel. It introduces operation source tracking, a PublishResult type, InternalRealtimeObjectsProtocol abstraction, and synchronization infrastructure for coordinating local applies with channel state changes.

Changes

Cohort / File(s) Summary
Package Dependencies
AblyLiveObjects.xcworkspace/xcshareddata/swiftpm/Package.resolved, Package.swift, Package.resolved
Updated ably-cocoa and ably-cocoa-plugin-support to git-based revisions instead of explicit version pins, with TODO comments marking unpinning before release.
Core SDK & Plugin
Sources/AblyLiveObjects/Internal/CoreSDK.swift, Sources/AblyLiveObjects/Internal/DefaultInternalPlugin.swift
Modified nosync_publish callback to return PublishResult instead of Void. Added nosync_onChannelStateChanged routing and siteCode handling in DefaultInternalPlugin. Added runtime checks for PublishResult-returning operations.
Realtime Objects Protocol & Infrastructure
Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift, Sources/AblyLiveObjects/Internal/ObjectsOperationSource.swift, Sources/AblyLiveObjects/Internal/PublishResult.swift
Introduced InternalRealtimeObjectsProtocol and nosync_publishAndApply mechanism. Added PublishAndApplySyncWaiterOutcome enum and waiter drainage infrastructure. Implemented siteCode management and appliedOnAckSerials tracking to prevent double-applies.
Live Objects Core
Sources/AblyLiveObjects/Internal/InternalDefaultLiveCounter.swift, Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift, Sources/AblyLiveObjects/Internal/ObjectsPool.swift
Added source parameter to apply methods and realtimeObjects dependency to set/increment/decrement operations. Changed apply methods to return Bool indicating success. Removed getOrCreateCounter/getOrCreateMap helpers.
Error Handling
Sources/AblyLiveObjects/Utility/Errors.swift
Added publishAndApplyFailedChannelStateChanged and newlyCreatedObjectNotInPool error cases with cause property to propagate underlying errors via userInfo.
Message Protocol
Sources/AblyLiveObjects/Protocol/InboundObjectMessage+Synthetic.swift, Sources/AblyLiveObjects/Protocol/ObjectMessage.swift
Introduced createSynthetic factory method to construct inbound messages from outbound ACK payloads. Added documentation note about updating synthetic creation on new field additions.
Public API Wrappers
Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultLiveCounter.swift, Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultLiveMap.swift, Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultRealtimeObjects.swift, Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicObjectsStore.swift, Sources/AblyLiveObjects/Public/Public Proxy Objects/InternalLiveMapValue+ToPublic.swift
Updated constructors and method signatures to accept realtimeObjects parameter instead of/alongside delegate. Modified creation args to propagate realtimeObjects throughout object lifecycle.
Unit Tests
Tests/AblyLiveObjectsTests/InternalDefaultLiveCounterTests.swift, Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift, Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
Added extensive tests for publish-and-apply flows, source parameter handling, siteTimeserial updates, and channel state changes during sync. Introduced BufferOperationTests and ApplyOnAck scenario coverage.
Integration Tests
Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsIntegrationTests.swift, Tests/AblyLiveObjectsTests/JS Integration Tests/TestProxyTransport.swift
Added test-only utilities (EchoInterceptor, AckInterceptor) to simulate message delays. Introduced comprehensive Apply-on-ACK test scenarios with double-apply prevention and subscription validation. Updated ARTConnectionDetails usage with siteCode parameter.
Test Mocks
Tests/AblyLiveObjectsTests/Mocks/MockCoreSDK.swift, Tests/AblyLiveObjectsTests/Mocks/MockRealtimeObjects.swift
Added MockRealtimeObjects conforming to InternalRealtimeObjectsProtocol. Extended MockCoreSDK with setPublishCallbackHandler and updated publish handlers to return PublishResult instead of Void.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client Code
    participant PublicAPI as Public API
    participant InternalRT as InternalRealtimeObjects
    participant CoreSDK as CoreSDK
    participant Channel as Realtime Channel
    participant LocalPool as Local Object Pool

    Client->>PublicAPI: increment()/set()
    PublicAPI->>InternalRT: nosync_publishAndApply()
    
    par Publish Path
        InternalRT->>CoreSDK: nosync_publish(callback:)
        CoreSDK->>Channel: Send ObjectMessage
    and Buffer Path
        InternalRT->>InternalRT: Store PublishAndApplySyncWaiter
    end
    
    Channel-->>CoreSDK: ACK with PublishResult
    CoreSDK-->>InternalRT: Callback(PublishResult)
    
    rect rgba(100, 200, 100, 0.5)
        InternalRT->>InternalRT: createSynthetic message from PublishResult
        InternalRT->>LocalPool: Apply with source: .local
        LocalPool-->>InternalRT: Confirm applied (Bool)
        InternalRT->>InternalRT: Track in appliedOnAckSerials
    end
    
    InternalRT->>InternalRT: Drain PublishAndApplySyncWaiters(outcome: .synced)
    InternalRT-->>PublicAPI: Callback with success
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 A publish dance with ACK in hand,
Operations now apply as planned,
Local sources, channel flows align,
State and sync in perfect design,
Objects hop through realtime's land! 🐇

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'AIT-324 Apply operations on ACK' directly summarizes the main change: operations are now applied locally upon receiving server ACKs instead of waiting for echoes.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch AIT-324-apply-on-ACK

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.

@lawrence-forooghian lawrence-forooghian changed the base branch from main to make-CoreSDK-use-callbacks March 2, 2026 14:32
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 2, 2026 16:06 Inactive
lawrence-forooghian added a commit that referenced this pull request Mar 2, 2026
- Package.swift: restore dependency URLs (remove .git suffix), add
  TODO comments to unpin before release
- PublishResult: remove explicit Sendable (inferred by Swift 6)
- Remove @discardableResult from nosync_apply methods; update tests
  to capture and assert on the return value
- siteCode: change from pull to push pattern — remove
  nosync_siteCode() from CoreSDK, push from
  DefaultInternalPlugin.nosync_onConnected via nosync_setSiteCode
- Replace NSSelectorFromString with #selector
- Introduce InternalDefaultRealtimeObjectsProtocol extending
  LiveMapObjectsPoolDelegate, consolidating the separate delegate
  and realtimeObjects fields in public proxy objects; create
  MockRealtimeObjects to simplify map/counter publish tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 2, 2026 17:53 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 2, 2026 20:18 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 2, 2026 21:10 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 19:15 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 20:06 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 20:08 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 21:29 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 22:05 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 3, 2026 22:49 Inactive
@lawrence-forooghian lawrence-forooghian marked this pull request as ready for review March 3, 2026 23:50
@lawrence-forooghian
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 4

🧹 Nitpick comments (5)
Tests/AblyLiveObjectsTests/JS Integration Tests/TestProxyTransport.swift (1)

407-407: Use implicit .init for inferred ARTConnectionDetails construction.

Type inference is available for the connectionDetails property assignment on line 407. The codebase already uses this pattern in similar contexts (see ObjectsIntegrationTests.swift lines 3913 and 3941).

Suggested change
-        msg.connectionDetails = ARTConnectionDetails(clientId: clientId, connectionKey: "a8c10!t-3D0O4ejwTdvLkl-b33a8c10", maxMessageSize: 16384, maxFrameSize: 262_144, maxInboundRate: 250, connectionStateTtl: 60, serverId: "testServerId", maxIdleInterval: 15000, objectsGCGracePeriod: 86_400_000, siteCode: nil)
+        msg.connectionDetails = .init(clientId: clientId, connectionKey: "a8c10!t-3D0O4ejwTdvLkl-b33a8c10", maxMessageSize: 16384, maxFrameSize: 262_144, maxInboundRate: 250, connectionStateTtl: 60, serverId: "testServerId", maxIdleInterval: 15000, objectsGCGracePeriod: 86_400_000, siteCode: nil)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/AblyLiveObjectsTests/JS` Integration Tests/TestProxyTransport.swift at
line 407, The assignment to msg.connectionDetails uses an explicit
ARTConnectionDetails(...) constructor; change it to use type-inferred shorthand
by calling .init(...) so it matches the project's style (e.g., replace
ARTConnectionDetails(clientId:..., ...) with .init(clientId:..., ...)) at the
msg.connectionDetails assignment site to keep consistency with other tests using
inferred initialization.
Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift (2)

1797-1801: Prefer value-based assertions over reference identity for thrown errors.

At Line 1800, === can become brittle if error objects are bridged/reboxed. Comparing stable fields (code, statusCode, message) is more robust.

Suggested assertion update
-            `#expect`(thrownError === publishError)
+            `#expect`(thrownError.code == publishError.code)
+            `#expect`(thrownError.statusCode == publishError.statusCode)
+            `#expect`(thrownError.message == publishError.message)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift` around
lines 1797 - 1801, The test currently asserts thrownError === publishError
(reference identity) which is brittle; change the assertion to compare
ARTErrorInfo fields instead: extract the thrownError and publishError (both
ARTErrorInfo) returned by realtimeObjects.createMap and assert their .code,
.statusCode and .message (or equivalent stable properties) are equal to each
other so the test uses value-based equality rather than reference identity;
locate the check around thrownError, publishError and createMap to update the
assertion accordingly.

1334-1338: Consider extracting repeated “transition to synced state” setup.

The same prelude is repeated across multiple tests; a small helper would reduce drift and make intent clearer.

Also applies to: 1382-1386, 1417-1421, 1487-1491, 1528-1532, 1564-1568

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift` around
lines 1334 - 1338, Extract the repeated "transition to synced state" setup into
a small helper function (e.g., transitionToSyncedState or
makeRealtimeObjectsSynced) that calls internalQueue.ably_syncNoDeadlock {
realtimeObjects.nosync_onChannelAttached(hasObjects: false);
realtimeObjects.nosync_setSiteCode("site1") }, then replace the duplicated
blocks in the tests (locations referencing internalQueue.ably_syncNoDeadlock and
realtimeObjects.nosync_onChannelAttached / nosync_setSiteCode) with a single
call to that helper to reduce duplication and clarify intent.
Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsIntegrationTests.swift (1)

4507-4553: Use defer for interceptor restoration in these tests.

These tests restore interceptors manually. If the test throws before restore, hooks can leak for the rest of the test body. Use defer { interceptor.restore() } consistently after creation.

Also applies to: 4587-4599

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/AblyLiveObjectsTests/JS` Integration
Tests/ObjectsIntegrationTests.swift around lines 4507 - 4553, After creating an
EchoInterceptor instance (symbol: EchoInterceptor and variable echoInterceptor),
add a defer { echoInterceptor.restore() } immediately so the interceptor is
always restored even if the test throws; remove or keep the later manual restore
calls (restore() at the end) as redundant but ensure restore happens after any
explicit releaseAll() call (method: releaseAll) so behavior is unchanged. Apply
the same change to the other test where EchoInterceptor is created (the second
block referenced) to avoid leaking hooks.
Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift (1)

11-15: Add explicit ACL on the protocol requirement.

nosync_publishAndApply should declare its access level explicitly to satisfy the project ACL rule.

💡 Proposed fix
 internal protocol InternalRealtimeObjectsProtocol: LiveMapObjectsPoolDelegate {
@@
-    func nosync_publishAndApply(
+    internal func nosync_publishAndApply(
         objectMessages: [OutboundObjectMessage],
         coreSDK: CoreSDK,
         callback: `@escaping` `@Sendable` (Result<Void, ARTErrorInfo>) -> Void,
     )
 }

As per coding guidelines, "Specify an explicit access control level (SwiftLint explicit_acl) for all declarations in Swift code (tests are exempt)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift` around
lines 11 - 15, The protocol requirement nosync_publishAndApply currently lacks
an explicit access control level; update its declaration to include the
appropriate ACL (for example `internal` or `public` depending on the protocol's
intended visibility) so it satisfies SwiftLint explicit_acl. Locate the
nosync_publishAndApply requirement in InternalDefaultRealtimeObjects (and the
corresponding protocol declaration if separate) and prepend the chosen access
modifier to the function signature, ensuring all matching
implementations/signatures across the codebase use the same access level.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift`:
- Around line 749-753: The no-`HAS_OBJECTS` sync-completion path currently calls
nosync_drainPublishAndApplySyncWaiters(outcome: .synced) but does not clear the
appliedOnAckSerials set, leaving stale ACK serials that can suppress later
OBJECTs; update the RTO4b no-HAS_OBJECTS branch to reset/clear
appliedOnAckSerials before or immediately after calling
nosync_drainPublishAndApplySyncWaiters (and make the identical change in the
other occurrence around the 861-863 region) so that ACK-tracking state is
cleared on this sync-complete path.

In `@Tests/AblyLiveObjectsTests/InternalDefaultLiveCounterTests.swift`:
- Around line 410-421: The comment is contradictory: it says the operation "will
be applied" though the test asserts it is discarded (applied == false). Update
the comment near the internalQueue.ably_syncNoDeadlock call and the
counter.nosync_apply invocation to state that the operation will be discarded
(not applied) because its serial "ts1" is lexicographically less than the
existing "ts2" and thus should be ignored in this discard-path case; ensure the
comment references the discard expectation so it matches the assertion
(!applied) and unchanged state checks.

In `@Tests/AblyLiveObjectsTests/JS` Integration
Tests/ObjectsIntegrationTests.swift:
- Around line 4461-4468: The test uses a fixed Task.sleep(2_000_000_000) to wait
for the ACK/publish-and-apply sequence, which is flaky; replace the hard sleep
with a deterministic wait for the actual event/state change (e.g., register an
interceptor or callback that signals when publishAndApply completes, or await an
AsyncContinuation/AsyncStream or XCTestExpectation fulfilled by the ACK handler)
so that the code calling counter.increment(5) proceeds only after the real
ACK/publishAndApply event is observed; locate the sleep call and the surrounding
usage of counter.increment and publishAndApply and replace the sleep with
awaiting the explicit signal from that interceptor/handler.
- Around line 4234-4702: Several new `@Test` functions in the Apply-on-ACK section
(applyOnAckScenarios, echoAfterAckDoesNotDoubleApply,
ackAfterEchoDoesNotDoubleApply, applyOnAckDoesNotUpdateSiteTimeserials,
operationBufferedDuringSyncIsAppliedAfterSyncCompletes,
appliedOnAckSerialsIsClearedOnSync,
publishAndApplyRejectsOnChannelStateChangeDuringSync,
subscriptionCallbacksFireForBothLocallyAppliedAndRealtimeReceivedOperations)
lack the required spec attribution comments; add the appropriate single-line
spec comment above each test using the exact format from CONTRIBUTING.md (use
`@spec` or `@specPartial` as appropriate), ensure you do not duplicate the same
`@spec` on multiple tests for the same spec point, and place the comment
immediately above the corresponding test declaration so metadata tooling picks
it up.

---

Nitpick comments:
In `@Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift`:
- Around line 11-15: The protocol requirement nosync_publishAndApply currently
lacks an explicit access control level; update its declaration to include the
appropriate ACL (for example `internal` or `public` depending on the protocol's
intended visibility) so it satisfies SwiftLint explicit_acl. Locate the
nosync_publishAndApply requirement in InternalDefaultRealtimeObjects (and the
corresponding protocol declaration if separate) and prepend the chosen access
modifier to the function signature, ensuring all matching
implementations/signatures across the codebase use the same access level.

In `@Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift`:
- Around line 1797-1801: The test currently asserts thrownError === publishError
(reference identity) which is brittle; change the assertion to compare
ARTErrorInfo fields instead: extract the thrownError and publishError (both
ARTErrorInfo) returned by realtimeObjects.createMap and assert their .code,
.statusCode and .message (or equivalent stable properties) are equal to each
other so the test uses value-based equality rather than reference identity;
locate the check around thrownError, publishError and createMap to update the
assertion accordingly.
- Around line 1334-1338: Extract the repeated "transition to synced state" setup
into a small helper function (e.g., transitionToSyncedState or
makeRealtimeObjectsSynced) that calls internalQueue.ably_syncNoDeadlock {
realtimeObjects.nosync_onChannelAttached(hasObjects: false);
realtimeObjects.nosync_setSiteCode("site1") }, then replace the duplicated
blocks in the tests (locations referencing internalQueue.ably_syncNoDeadlock and
realtimeObjects.nosync_onChannelAttached / nosync_setSiteCode) with a single
call to that helper to reduce duplication and clarify intent.

In `@Tests/AblyLiveObjectsTests/JS` Integration
Tests/ObjectsIntegrationTests.swift:
- Around line 4507-4553: After creating an EchoInterceptor instance (symbol:
EchoInterceptor and variable echoInterceptor), add a defer {
echoInterceptor.restore() } immediately so the interceptor is always restored
even if the test throws; remove or keep the later manual restore calls
(restore() at the end) as redundant but ensure restore happens after any
explicit releaseAll() call (method: releaseAll) so behavior is unchanged. Apply
the same change to the other test where EchoInterceptor is created (the second
block referenced) to avoid leaking hooks.

In `@Tests/AblyLiveObjectsTests/JS` Integration Tests/TestProxyTransport.swift:
- Line 407: The assignment to msg.connectionDetails uses an explicit
ARTConnectionDetails(...) constructor; change it to use type-inferred shorthand
by calling .init(...) so it matches the project's style (e.g., replace
ARTConnectionDetails(clientId:..., ...) with .init(clientId:..., ...)) at the
msg.connectionDetails assignment site to keep consistency with other tests using
inferred initialization.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 35850d9 and bf41108.

📒 Files selected for processing (26)
  • AblyLiveObjects.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • Package.resolved
  • Package.swift
  • Sources/AblyLiveObjects/Internal/CoreSDK.swift
  • Sources/AblyLiveObjects/Internal/DefaultInternalPlugin.swift
  • Sources/AblyLiveObjects/Internal/InternalDefaultLiveCounter.swift
  • Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift
  • Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift
  • Sources/AblyLiveObjects/Internal/ObjectsOperationSource.swift
  • Sources/AblyLiveObjects/Internal/ObjectsPool.swift
  • Sources/AblyLiveObjects/Internal/PublishResult.swift
  • Sources/AblyLiveObjects/Protocol/InboundObjectMessage+Synthetic.swift
  • Sources/AblyLiveObjects/Protocol/ObjectMessage.swift
  • Sources/AblyLiveObjects/Public/Public Proxy Objects/InternalLiveMapValue+ToPublic.swift
  • Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultLiveCounter.swift
  • Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultLiveMap.swift
  • Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultRealtimeObjects.swift
  • Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicObjectsStore.swift
  • Sources/AblyLiveObjects/Utility/Errors.swift
  • Tests/AblyLiveObjectsTests/InternalDefaultLiveCounterTests.swift
  • Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift
  • Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
  • Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsIntegrationTests.swift
  • Tests/AblyLiveObjectsTests/JS Integration Tests/TestProxyTransport.swift
  • Tests/AblyLiveObjectsTests/Mocks/MockCoreSDK.swift
  • Tests/AblyLiveObjectsTests/Mocks/MockRealtimeObjects.swift

@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 4, 2026 00:26 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 4, 2026 01:01 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/118/AblyLiveObjects March 4, 2026 01:11 Inactive
Instead of waiting for the server to echo back an operation before
applying it locally, operations are now applied immediately upon
receiving the ACK from Realtime.

Implements the behaviours from spec commit 56a0bba and ports the
corresponding integration tests from ably-js commit 6b1c2de, plus the
test fix in ably-js commit f9fbe8e (from [1]).

[1] ably/ably-js#2175

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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