Skip to content

Latest commit

 

History

History
72 lines (59 loc) · 7.53 KB

File metadata and controls

72 lines (59 loc) · 7.53 KB

v1.1.3

06/24/2026

    • Guests can now use the polling fallback on public channels — the channel pull and publish endpoints accept anonymous requests and let each channel's own access check decide
    • A failing push transport no longer stops messages from reaching the other transports, so the polling fallback keeps working while a hub is down
    • Collaborative editing now works on child pages of a hidden home route, instead of failing to find the page, when "Hide home route in URLs" is enabled (getgrav/grav-plugin-api#10)
    • Save notifications now reach collaborators editing child pages of a hidden home route, so they no longer keep seeing phantom unsaved changes after a peer saves (getgrav/grav-plugin-admin2#59)

v1.1.2

06/08/2026

    • New sync:page-saved:<roomId> broadcast channel. Fires whenever a page is saved through the api plugin so peer editors in the same collab room can advance their dirty baseline and stop showing phantom unsaved changes. Subscribers need api.pages.read on the page. Used by admin-next to fix getgrav/grav-plugin-admin2#25.
    • Collaborative editing now uses regular page permissions instead of a separate api.collab.* permission. Anyone who can read or write a page via the API can do the same collaboratively — no extra grant needed. Fixes getgrav/grav-plugin-admin2#24.
    • Fixed a 404 error when an editor subscribed to a page's save-notification channel before the first save had happened.
    • Fixed a 403 error that wrongly blocked super admins from subscribing to a page's save-notification channel.

v1.1.1

05/18/2026

    • Removed vendor from .gitignore file, so it's included in package

v1.1.0

05/13/2026

    • New Transport Preference Order setting in the Sync admin. Reorder which installed transport handles live delivery (e.g. put Ably above Mercure) without uninstalling plugins. The dropdown is populated from transports currently registered in this instance, so deployers only see options they actually have.
    • New SQLite storage backend for Yjs update logs and snapshots. One database per room under user/data/sync/storage/, with WAL mode and writer-locked transactions — eliminates the file-lock contention the file backend can hit under heavy multi-user editing.
    • storage.adapter defaults to auto, which picks SQLite when the pdo_sqlite PHP extension is available and falls back to the file backend otherwise. Existing installs that have adapter: file saved keep using file storage.
    • Public pub/sub facade $grav['sync']. Plugins can register channels and publish messages without coupling to a specific transport.
    • Three message types: crdt (Yjs binary updates), broadcast (arbitrary payload with optional TTL replay), awareness (ephemeral presence).
    • Transport-provider registry. External plugins (Mercure, Ably) plug in via the new onSyncRegisterTransports event. Built-in polling stays as the universal fallback.
    • Per-channel auth delegation via callback or the new onSyncCheckAccess event.
    • New onSyncBeforeCrdtChannelRegistered event so plugins can attach proper permission gating to a page's CRDT channel before sync falls back to its permissive auto-register.
    • New endpoints GET /sync/channels/pull?id=<channelId> and POST /sync/channels/publish?id=<channelId> for the broadcast pub/sub model. Available under both the api-plugin route prefix and the legacy /sync/* dispatcher. The channel id rides in the query string (not a path segment) so colons in ids — common, e.g. comments-pro:blog/post-1 — are not eaten by Grav's URI param parser.
    • New onSyncResolveChannel event. Fired by the pull/publish handler when an incoming request names a channel the in-process registry hasn't seen yet, giving owner plugins one last chance to lazy-register before sync 404s.
    • Legacy /sync/* HTTP path now uses the api plugin's full auth chain (X-API-Token, Authorization Bearer) when api is loaded, in addition to session auth. The mutex with /api/v1/sync/* is unchanged; this enables forward-compat for sites that choose to expose both prefixes.
    • Capabilities response now lists every registered transport with id, name, priority, and supported message types, plus a preferred field. The existing polling and presence sub-blocks are unchanged.
    • Transport plugins (Mercure, Ably) now reliably land in the transport registry — previously they could register too late and only appear in the capabilities response as a stub entry.
    • Presence room membership is no longer corrupted when three or more peers heartbeat at once. Three browsers editing the same page used to each see a different subset of peers (one would even see only itself) because concurrent load-modify-save writes on the shared presence cache key clobbered each other; an exclusive flock around the heartbeat critical section keeps every peer's entry intact.
    • Polling transport's pull/publish URLs now honor Grav's base path, and route through the api plugin's prefix when api is loaded — fixes 404s on Grav installs mounted at a subpath.
    • Legacy /sync/* dispatcher now matches correctly on subpath installs (it stripped the wrong portion of the path before checking the /sync/ prefix).
    • The CRDT path used by editor-pro is unchanged. All existing endpoints, events (onSyncUpdate, onSyncAwareness, onSyncCapabilities), and storage layouts remain compatible.

v1.0.2

05/09/2026

    • Sync now runs on Grav 1.7 in addition to 2.0. The api plugin is no longer a hard dependency. When api is installed sync's endpoints are still served at /api/v1/sync/* exactly as before; otherwise sync provides its own minimal HTTP layer at /sync/*.
    • Self-contained PSR-7 HTTP base class (Grav\Plugin\Sync\Http\AbstractSyncController) replaces the prior dependency on the api plugin's AbstractApiController. Plugin authors extending sync's controllers should target the new base class.
    • Composer dependencies updated to declare PSR-7 message and server-request packages directly. Run composer install inside the plugin after updating.

v1.0.1

05/05/2026

    • Sync data no longer lands inside user/pages/. Per-room logs and snapshots used to be written next to the page they belonged to (e.g. user/pages/02.typography/.sync/), and the page route was used as a literal folder name — so language variants ended up in spurious siblings like user/pages/typography.en/, which Grav then listed in admin as extra pages. Storage now lives under user/data/sync/<md5(route)>/ with a meta.json for reverse lookup, and language is encoded as a filename suffix (default.en.log) rather than baked into the folder name. Existing rooms under user/pages/**/.sync/ should be deleted; the next edit reseeds cleanly.
    • Room ids no longer fold the language into the route segment. The format is now <route>@<template> (default language) or <route>@<template>@<lang> (explicit), matching the cleanly separated route/template/lang model the storage layer already used internally. Routes carrying a .<lang> suffix were a footgun for both the storage path and clients computing topic names.

v1.0.0

04/25/2026

    • Initial Release