Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move cache snapshot loading to Visit#start() #1056

Merged
merged 4 commits into from
Nov 3, 2023
Merged

Conversation

afcapel
Copy link
Collaborator

@afcapel afcapel commented Oct 31, 2023

This fixes a problem introduced when the cache interface changed in #949

Since the cache can be loaded from disk using the browser Cache API, it is possible that the cache snapshot will be loaded asynchronously. This means that the calls to load cache snapshots need to be awaited.

Because of that we also changed visit.hasCachedSnapshot() to be async and return a Promise. However, hasCachedSnapshot is used in the iOS adapter and serialized into and data object we send to the native side via postMessage. When postMessage receives a Promise instead of a boolean value it fails with a DataCloneError because it can't serialize the Promise.

This commit moves the cache snapshot loading to Visit#start() and stores the result in a cachedSnapshot property. This allows us to keep the hasCachedSnapshot() method synchronous and return a boolean value.

It means that Visit.start is now async, but I haven't found any callers that rely on it being synchronous.

The cache interface changed in #949

Since the cache can be loaded from disk using the browser Cache API, it is
possible that the cache snapshot will be loaded asynchronously. This means
that the calls to load cache snapshots need to be awaited.

We also changed visit.hasCachedSnapshot() to be async and return a Promise.
However, [hasCachedSnapshot is used in the iOS adapter](https://github.com/hotwired/turbo-ios/blob/c476bac66f260adbfe930ed9a151e7637973ff99/Source/WebView/turbo.js#L119)
and serialized into and data object we send to the native side via
postMessage. When postMessagereceives a Promise instead of a boolean
value it fails with a DataCloneError since it can't serialize the Promise.

This commit moves the cache snapshot loading to Visit#start() and stores
the result in a cachedSnapshot property. This allows us to keep the
hasCachedSnapshot() method synchronous and return a boolean value.

It means that Visit.start is now async, but I haven't found any callers
that rely on it being synchronous.
* origin/main:
  Tests: remove `"test"` docstring prefix (#1052)
@domchristie
Copy link
Contributor

However, hasCachedSnapshot is used in the iOS adapter and serialized into and data object we send to the native side via postMessage. When postMessage receives a Promise instead of a boolean value it fails with a DataCloneError because it can't serialize the Promise.

This happened before (#720). Should we test that the object sent to the native adapters conforms to the structured clone algorithm?

@jayohms
Copy link
Collaborator

jayohms commented Nov 2, 2023

Good call @domchristie, I added a unit test to check that visit.hasCachedSnapshot() returns a boolean value. And I confirmed it would have failed before this change.

Copy link
Collaborator

@jayohms jayohms left a comment

Choose a reason for hiding this comment

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

Thank you, looks good to me @afcapel 👍

@afcapel afcapel merged commit e07639f into main Nov 3, 2023
2 checks passed
@afcapel afcapel deleted the sync-has-cached-snapshot branch November 3, 2023 14:39
@afcapel
Copy link
Collaborator Author

afcapel commented Nov 3, 2023

@domchristie agreed, this is a recurrent problem. It's too easy to make a mistake here 👍

Should we test that the object sent to the native adapters conforms to the structured clone algorithm?

How would that work? Do we add that to the iOS and Android adapters?

@domchristie
Copy link
Contributor

domchristie commented Nov 3, 2023

@afcapel I had a quick look into adding some unit tests on this repo to make sure that anything sent to the native adapter methods doesn't raise an error when passed to structuredClone (particularly Visit options, where it's inviting to add more). However it didn't look straightforward.

@kevinmcconnell and I discussed some ideas in #720, and it was suggested that the ideal solution would be something on the native adapter side, but backwards compatibility was an issue. (Perhaps less so with a Turbo 8 major version change?)

I implemented @kevinmcconnell's idea of adding a withTransferableVisitOptions, but it will just filter out non-transferable values, and would've quietly failed in the above case.

I am not a fan of types (and don't wish to bring up that debate again), but I think this might be a good place for them. In an earlier PR I added a StructuredCloneValue type, which might be useful to apply for the adapter methods. (Just suggesting this for possible inspiration.)

So there's my thoughts! Not sure what the best approach is really! :/

afcapel added a commit that referenced this pull request Nov 13, 2023
@afcapel afcapel mentioned this pull request Nov 13, 2023
afcapel pushed a commit that referenced this pull request Nov 13, 2023
* Revert "Move cache snapshot loading to Visit#start() (#1056)"

This reverts commit e07639f.

* Revert "Fix back navigation after POST form submission (#1014)"

This reverts commit c207f5b.

* Revert "Add disk cache store (#949)"

This reverts commit f86a376.

* Remove redudant test prefix

* Bring back test

Orginally added by @jayohms in

60cfbee
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.

3 participants