* wip
* generalize
* refactor
* Extract SearchResultIcon for command bar results
Both search action builders rendered the same document icon inline. Move it
into a shared component alongside the other command bar pieces, forwarding
size so the command bar can continue to size icons via cloneElement.
Also drop the redundant charAt(0).toUpperCase() on the initial, as the Icon
component already normalizes it.
Co-Authored-By: Claude <noreply@anthropic.com>
* PR feedback
Prevent same doc showing twice in cmd k
Improve result ordering in main app command bar
Refactor to flattenTree
* Upgrade Fuse to 7.5.0, use workers
* fix: Re-register search actions when index is enriched
Include result contexts in the command bar registration key so that
snippets refresh when the same documents are enriched, and only mark a
server search as cached once its results are actually fed to the index.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: preserve diagrams.net source through API markdown round-trip
Images with source: "diagrams.net" (draw.io embeds) lost their editability
when updated through the API (documents.create/update with text). The
markdown serializer/deserializer had no slot for the source attribute, so
every round-trip through markdown stripped it, downgrading editable diagrams
to static images.
Encode source as a "source=<value>" token in the markdown title attribute,
which already carries layoutClass and size. The token is extracted on parse
and emitted on serialize, surviving the full API round-trip.
* fix: address image source review feedback
Authored-by: Terminus (AI Assistant) <raisalpwardana+terminus@gmail.com>
* fix: narrow image test node attributes
Authored-by: Terminus (AI Assistant) <raisalpwardana+terminus@gmail.com>
* fix: narrow image test attributes
Authored-by: Terminus (AI Assistant) <raisalpwardana+terminus@gmail.com>
---------
Co-authored-by: Raisal P Wardana <IEatCodeDaily@users.noreply.github.com>
* chore: Audit and move inline actions to definitions
* fix: Reuse existing smart-quote translation key in emoji delete dialog
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove two usages of 'Link copied' translation
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix: Temporary directory left behind after S3 storage file handle
* Remove unused ZipHelper.extract
Use pipeline everywhere instead of manually wiring streams
* fix: Cleanup failure should not mask original error
Removing the temporary directory is best-effort, log the failure and
propagate the underlying error instead.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* perf: Bound MutexLock retries and de-dupe same-key cache misses
MutexLock configured redlock with retryCount: 120, retryDelay: 1000 — a
2-minute retry window for locks with a 4s default TTL. Under cache-miss
storms (e.g. websocket reconnects all missing user.collectionIds) N
contenders piled onto one lock key, retaining ~K²/2 error objects plus
pending timers/promises. Bound retries to ~the lock TTL (retryCount: 15,
retryDelay: 250) and add a per-process in-flight de-dupe in
CacheHelper.getDataOrSet so N same-key misses share one lock acquisition
and callback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: Return falsy cached values instead of treating them as misses
getDataOrSet checked `if (cache)`, so a cached null/false/0/"" was treated
as a miss and re-populated on every read (e.g. Collection.getCachedDocument
Structure caches NavigationNode[] | null via the AfterSave hook). Check for
undefined — the only value getData returns on a genuine miss — so falsy
cached values are returned without an extra lock and DB query.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* deslop
* fix: Scope bounded lock retries to cache locks only
The tightened retry window (15×250ms) was set on the shared Redlock
instance, so it also affected long-lived callers — notably the 10-minute
"migrations" lock in checkMigrations, which fatal-exits on acquire failure
and would crash concurrent boots. Restore the generous default on the
shared instance and pass a bounded retry override (MutexLock.cacheRetry
Settings) only from the cache path via a new per-acquire retry option.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: Cache falsy callback results in getDataOrSet
populate only cached truthy callback results, so a valid null (e.g. from
Collection.getCachedDocumentStructure) was never stored and every miss
re-ran the lock + DB query. Skip caching only when the result is undefined,
and guard the CacheResult detection against null (typeof null === "object").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* CMD+enter to open in split view
* Fall back to normal navigation when location state is present
Location state cannot be represented in the split query parameter, so
opening in the secondary pane would silently drop it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>