search: a write reads only its folder, and the match is lit

`file_text::catch_up` read every file without a row, which after a write meant
walking every file node there is to find the one or two just put in. It now
takes the part of the tree to look in: an upload asks about the folder it went
into, an import about the folder it was poured into, an SFTP save about the
folder it landed in, a decrypt about what was decrypted. Only an import at the
root and the pass at start look at everything.

The excerpt of a file found by its text marks each matched word between
U+0002 and U+0003, which no text file has a use for, and the list draws them
lit. A cut through a match leaves an opening without its close, and the rest
is lit to the end rather than the marker shown.

The screenshots are taken again, so the search one shows it.
This commit is contained in:
nvrl committed 2026-10-21 12:53:37 +02:00
1 parent 767dd076dd
commit c72b65fc38
28 files changed
+100 -30

No files matched your search

+2 -2
View File
@@ -507,7 +507,7 @@ limit at least that large too.
of every file that is text — by its type, or by its first 8 KiB reading as
UTF-8 without a NUL — is indexed, up to its first 256 KiB, the same part the
viewer shows. A file found that way lists the words around the match under its
name. The text is read when a file arrives, by upload, import or the SFTP
name, the words that matched lit. The text is read when a file arrives, by upload, import or the SFTP
mount, again when its bytes change, and at start for any file still without
it. PDFs, office documents and images are not read.
@@ -848,7 +848,7 @@ sealed or not.
| `GET` | `/api/sessions` | every signed-in browser, the one seen last first |
| `DELETE` | `/api/sessions/{id}` | sign another browser out, and lock the vault |
| `GET`/`POST` | `/api/spaces` | the spaces / create one |
| `GET`/`POST` | `/api/nodes` | children (`?parent=`) or search (`?q=`, `?space=`; a file matched by its text has `in_text` and the words around the match as `excerpt`) / create, from a template with `template_id` |
| `GET`/`POST` | `/api/nodes` | children (`?parent=`) or search (`?q=`, `?space=`; a file matched by its text has `in_text` and the words around the match as `excerpt`, each matched word between U+0002 and U+0003) / create, from a template with `template_id` |
| `GET`/`PUT`/`DELETE` | `/api/nodes/{id}` | read / update only the fields sent — `name`, `body`, `created_at`, `has_board`; with `base_updated_at`, refused with `409` once it was saved since / delete into the trash, subtree and all — or for good, for something already in it |
| `GET`/`DELETE` | `/api/trash` | what was deleted, the last first / empty it |
| `DELETE` | `/api/trash/{id}` | delete one thing in the trash for good |