Skip to content

Version Packages - #1150

Merged
mikebarkmin merged 1 commit into
mainfrom
changeset-release/main
Jul 29, 2026
Merged

Version Packages#1150
mikebarkmin merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

hyperbook@0.100.4

Patch Changes

  • d91255b Thanks @mikebarkmin! - Improve the cloud sync indicator:

    • Each sync state now has its own badge shape on the toolbar icon. Every state
      previously rendered the identical person glyph, distinguished only by fill
      color, so amber "unsynced" and green "synced" were indistinguishable to a
      red-green color blind reader.
    • Sync states a reader can act on are now surfaced outside the user drawer.
      Being offline or failing to save was only visible in a drawer most readers
      never open. The notice offers a retry when a save fails, and says how much is
      waiting while offline. Successful saves stay silent.
    • A sync conflict no longer reloads the page without warning. The merge is
      explained first, with a "Reload now" button, and the reload follows a few
      seconds later. Reloading is still necessary because directives read the store
      once at startup, but it is no longer a surprise.
    • The toolbar button carries an accessible name that tracks the sync state, and
      the status line is an aria-live region, so a change is announced rather than
      only shown.
    • The status line reports what it already knew but discarded: how long ago the
      last save landed, and how many batches are waiting while offline. "Saved
      locally" alone read as "you are all done".
    • The toolbar icon no longer stops updating when the shell is rendered without
      the user drawer.
    • Status colors meet WCAG AA contrast and follow the light/dark theme; they
      were fixed mid-tones at roughly 2-3:1 on white.
    • hyperbook.i18n.get honors its fallback argument. Ten call sites in the
      cloud UI passed one, but the parameter did not exist, so a missing key
      rendered the raw key id.
    • The impersonation banner offsets only the element after it, not every
      following sibling, and builds its markup as nodes instead of interpolating
      the username into innerHTML.
  • d91255b Thanks @mikebarkmin! - Fix several data-loss and corruption bugs in cloud sync:

    • Loading from the cloud no longer fails whenever the server has events but no
      snapshot. The reconstruction the server builds from an event log alone
      carries a placeholder database version, which import rejected outright —
      so a user's work synced up but never came back down, silently, until
      something happened to post a full snapshot.
    • The event watermark is now stored per hyperbook. Two hyperbooks served from
      the same origin shared one localStorage key, so each sent the other's
      afterEventId and got stuck in a permanent conflict loop.
    • A sync conflict no longer discards local work. The client now pulls the
      server state, replays its pending events on top of it locally and remotely,
      and only then reloads.
    • Offline batches now chain onto the watermark each one returns. Every batch
      after the first previously carried a watermark recorded before the flush and
      was rejected, discarding the whole queue.
    • Events now carry their Dexie primary-key schema, so the server can replay
      onto a table it has no snapshot for without assuming the key field is id.
    • Ephemeral currentState (cursor, scroll, window size) is no longer included
      in cloud snapshots; it was already excluded from events.
    • A batch rejected with a 4xx is dropped instead of being retried forever, and
      a 404 from the cloud no longer throws a TypeError that looked transient.
    • Concurrent online events can no longer start two overlapping queue flushes.
    • Closing the tab now flushes pending changes with a keepalive request
      instead of only warning. Anything changed inside the debounce window was
      lost when the tab closed, and beforeunload never fires at all on mobile
      Safari or when a background tab is discarded.

@hyperbook/markdown@0.71.4

Patch Changes

  • d91255b Thanks @mikebarkmin! - Improve the cloud sync indicator:

    • Each sync state now has its own badge shape on the toolbar icon. Every state
      previously rendered the identical person glyph, distinguished only by fill
      color, so amber "unsynced" and green "synced" were indistinguishable to a
      red-green color blind reader.
    • Sync states a reader can act on are now surfaced outside the user drawer.
      Being offline or failing to save was only visible in a drawer most readers
      never open. The notice offers a retry when a save fails, and says how much is
      waiting while offline. Successful saves stay silent.
    • A sync conflict no longer reloads the page without warning. The merge is
      explained first, with a "Reload now" button, and the reload follows a few
      seconds later. Reloading is still necessary because directives read the store
      once at startup, but it is no longer a surprise.
    • The toolbar button carries an accessible name that tracks the sync state, and
      the status line is an aria-live region, so a change is announced rather than
      only shown.
    • The status line reports what it already knew but discarded: how long ago the
      last save landed, and how many batches are waiting while offline. "Saved
      locally" alone read as "you are all done".
    • The toolbar icon no longer stops updating when the shell is rendered without
      the user drawer.
    • Status colors meet WCAG AA contrast and follow the light/dark theme; they
      were fixed mid-tones at roughly 2-3:1 on white.
    • hyperbook.i18n.get honors its fallback argument. Ten call sites in the
      cloud UI passed one, but the parameter did not exist, so a missing key
      rendered the raw key id.
    • The impersonation banner offsets only the element after it, not every
      following sibling, and builds its markup as nodes instead of interpolating
      the username into innerHTML.
  • d91255b Thanks @mikebarkmin! - Fix several data-loss and corruption bugs in cloud sync:

    • Loading from the cloud no longer fails whenever the server has events but no
      snapshot. The reconstruction the server builds from an event log alone
      carries a placeholder database version, which import rejected outright —
      so a user's work synced up but never came back down, silently, until
      something happened to post a full snapshot.
    • The event watermark is now stored per hyperbook. Two hyperbooks served from
      the same origin shared one localStorage key, so each sent the other's
      afterEventId and got stuck in a permanent conflict loop.
    • A sync conflict no longer discards local work. The client now pulls the
      server state, replays its pending events on top of it locally and remotely,
      and only then reloads.
    • Offline batches now chain onto the watermark each one returns. Every batch
      after the first previously carried a watermark recorded before the flush and
      was rejected, discarding the whole queue.
    • Events now carry their Dexie primary-key schema, so the server can replay
      onto a table it has no snapshot for without assuming the key field is id.
    • Ephemeral currentState (cursor, scroll, window size) is no longer included
      in cloud snapshots; it was already excluded from events.
    • A batch rejected with a 4xx is dropped instead of being retried forever, and
      a 404 from the cloud no longer throws a TypeError that looked transient.
    • Concurrent online events can no longer start two overlapping queue flushes.
    • Closing the tab now flushes pending changes with a keepalive request
      instead of only warning. Anything changed inside the debounce window was
      lost when the tab closed, and beforeunload never fires at all on mobile
      Safari or when a background tab is discarded.

@hyperbook/cloud@0.0.2

Patch Changes

  • 9df0010 Thanks @mikebarkmin! - Make the cloud server easier to run and safer to update:

    • Published as a container image per release. docker compose up -d is the
      whole deployment, and docker compose pull && docker compose up -d the whole
      update. An image tag is something to pin, which tracking main never was.
      docker-compose.yml, a Dockerfile and an ecosystem.config.js for
      non-container deployments are committed rather than pasted from the README.
    • The schema is versioned with PRAGMA user_version instead of re-deriving
      itself from CREATE TABLE IF NOT EXISTS and column probes on every boot.
      Each migration runs at most once, in order, and the version is recorded only
      after the step succeeds, so an interrupted upgrade retries rather than skips.
    • The database is copied aside before any migration that has work to do,
      with VACUUM INTO. If the copy cannot be written, the migration does not
      run. The five most recent backups are kept.
    • Starting a build older than the one that last wrote the database is refused,
      instead of silently reading a schema it does not understand.
    • In production the server refuses to start when JWT_SECRET is missing or
      still the placeholder, when it is shorter than 32 characters, when BASE_URL
      is unset, or when SMTP is half configured. It prints every problem at once
      and suggests a generated secret. Previously a deployment that forgot
      JWT_SECRET ran with a value published in this repository, and said nothing.
    • engines now records the Node versions better-sqlite3 can be built
      against, so a mismatch fails at install rather than at require.
  • d91255b Thanks @mikebarkmin! - Fix event replay corrupting the state it reconstructs:

    • The primary key is now parsed out of the Dexie schema string. Taking the
      first field verbatim left the markers on (++id, &email, *tags), so the
      key matched no row property at all and every update and delete missed
      silently while creates piled up duplicates. Compound keys ([a+b]) and
      outbound keys are handled too.
    • A created row can no longer end up without its primary key, which made it
      unreachable to every later event.
    • Primary keys keep their type. prim_key stored String(primKey), flattening
      numeric and compound keys so they no longer matched the rows they addressed;
      events now also carry prim_key_json.
    • Replay is idempotent. create appended unconditionally, so a retried or
      replayed batch duplicated rows; it now upserts.
    • Dexie's dotted update paths (update(id, {"state.zoom": 2})) are applied to
      the nested field instead of being written as a literal "state.zoom"
      property.
    • Events carry the client's Dexie primary-key schema, so a table with no prior
      snapshot is no longer assumed to be keyed by id. Tables keyed by something
      else — bookmarks by path, onlineide by scriptId — had a bogus id
      stamped onto every row.
    • The afterEventId check and the append now share one transaction. Two
      clients writing at the same moment could both pass the check and interleave.
    • A malformed batch is rejected with 400 instead of failing a CHECK constraint
      and returning 500, which the client treated as transient and retried forever.

    Both new columns are added by migration; existing databases keep working.

hyperbook-studio@0.51.7

Patch Changes

@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperbook-4fwa Ready Ready Preview Jul 29, 2026 8:22pm

@github-actions
github-actions Bot force-pushed the changeset-release/main branch from ff6e795 to 85ee23d Compare July 29, 2026 20:20
@mikebarkmin
mikebarkmin merged commit 7d9fab3 into main Jul 29, 2026
2 checks passed
@mikebarkmin
mikebarkmin deleted the changeset-release/main branch July 29, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant