Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .changeset/native-highlights-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Three native modules are new peer dependencies. They are autolinked, so a JS-onl
npx expo install expo-network expo-clipboard expo-application
```

`expo-network` is core's (the connectivity trigger for parked writes). `expo-clipboard` is UI's (the Copy fallback in the verse action sheet). `expo-application` is now a UI peer too — apps already using core have it.
`expo-network` is core's (the connectivity trigger for parked writes). `expo-clipboard` is UI's (the Copy fallback in the verse action sheet). `expo-application` is a new UI peer (the sign-in sheet's app display name) — core no longer depends on it.

**The Bible reader's default serif font changes from Source Serif 4 to Untitled Serif**, YouVersion's brand serif, following the Web SDK. A DOM component's WebView now makes a new outbound request to `api.youversion.com` for the stylesheet plus woff2 fetches from `cdn.youversion.com`. There is no opt-out and no new prop; if those hosts are blocked, serif text falls back to Source Serif 4 with no layout break. Readers who had explicitly chosen Source Serif are migrated. Any other `fontFamily` you pass or persist is left untouched.

Expand Down Expand Up @@ -74,7 +74,7 @@ The cached grant is a hint for choosing UI and skipping redundant prompts. The s

One addition to the auth context:

- `getAccessToken()` — the accessor that reports whether the refresh worked. It refreshes only when the token is at or near expiry, cheap enough to await on every user gesture unlike `refreshNow()` which always hits the token endpoint, then resolves an `AccessTokenResult`: `{ status: 'ok', token, userId }`, or `{ status: 'unavailable', reason: 'signed-out' | 'refresh-failed' }`. It never rejects, makes no network call when there is no refresh token to spend, and concurrent callers join one refresh. The `userId` is read in the same synchronous block as the token, so a caller holding an identity it captured earlier can tell whether the token it just got still belongs to that user — `userInfo` read from a render lags the token by a render on sign-in.
- `getAccessToken(options?: GetAccessTokenOptions)` — the accessor that reports whether the refresh worked. It refreshes only when the token is at or near expiry, cheap enough to await on every user gesture unlike `refreshNow()` which always hits the token endpoint, then resolves an `AccessTokenResult`: `{ status: 'ok', token, userId }`, or `{ status: 'unavailable', reason: 'signed-out' | 'refresh-failed' }`. Pass `{ force: true }` after a 401 to mint unconditionally and learn whether that mint landed — a force caller joins any in-flight refresh, then mints again, so `ok` is a token minted after this call. A failed force is `refresh-failed` even if an unexpired leftover remains. It never rejects, makes no network call when there is no refresh token to spend, and concurrent non-force callers join one refresh. The `userId` is read in the same synchronous block as the token, so a caller holding an identity it captured earlier can tell whether the token it just got still belongs to that user — `userInfo` read from a render lags the token by a render on sign-in.

`refresh-failed` leaves the tokens in storage: the session is intact and the user stays signed in. That matters because a token endpoint outage used to present to the user as a revoked permission. When the token was expired and the refresh failed for a reason that was not a revocation — a 5xx, a timeout, a captive portal — the write went out with the expired token anyway, came back 401, and the 401 read as a stale grant, so a valid `highlights` grant was invalidated and the user was asked to consent again; the re-consent minted with the same expired token and dead-ended as `not-permitted`. Both the highlights write path and `requestPermissions` now source their token from `getAccessToken()` and settle a `refresh-failed` as `transient` **without issuing the request**.

Expand Down Expand Up @@ -111,4 +111,4 @@ Two new props carry selection across the bridge:

## Dependencies

The Web SDK dependencies move to 2.5.0 — `@youversion/platform-core` (core, from 2.3.0) and `@youversion/platform-react-ui` (UI, from 2.2.0), which brings `@youversion/platform-core` and `@youversion/platform-react-hooks` 2.5.0 with it, so a single copy of each resolves across the workspace. Beyond the serif font change noted above, it supplies the reader's controlled highlights mode, the data-exchange primitives behind the just-in-time grant, and a core `ApiClient` fix reading an empty-body 2xx (what a successful highlight DELETE returns) as success rather than failure.
The Web SDK dependencies move to 2.6.2 — `@youversion/platform-core` (core, from 2.3.0) and `@youversion/platform-react-ui` (UI, from 2.2.0), which brings `@youversion/platform-core` and `@youversion/platform-react-hooks` 2.6.2 with it, so a single copy of each resolves across the workspace. Beyond the serif font change noted above, it supplies the reader's controlled highlights mode, the data-exchange primitives behind the just-in-time grant, and a core `ApiClient` fix reading an empty-body 2xx (what a successful highlight DELETE returns) as success rather than failure.
Loading