Cache/API implementation (#36), phase 2.
Depends on the Library.open/refresh unit.
Goal
Plain-record snapshot and change subscription — the surface the GUI uses across
Electron IPC, where methods and file keys cannot cross. All metadata held in RAM
on both sides (owner ruling 5).
Scope
PhotoRecord (plain data, no keys, safe to send to a window): fileID, albumIDs, title (pubMagicMetadata.editedName else metadata.title), takenAt ms (pubMagicMetadata.editedTime else metadata.creationTime), fileType, optional caption/width/height/latitude/longitude, isArchived, isHidden, and thumbnailPath?/originalPath? set when cached.
AlbumRecord: collectionID, name, type (favorites identifies the
favorites album), isShared, updationTime, fileIDs (newest first).
LibrarySnapshot { albums; photos; takenAt }; snapshot() is synchronous
(RAM only), one PhotoRecord per fileID (deduped across memberships).
subscribe({ onChange }) → { unsubscribe }, delivering LibraryChange
({ albumsChanged, photosChanged full records, fileIDsRemoved, albumIDsRemoved, refreshedAt }) when a refresh changes something.
Confirm Ente magic-metadata field names against the fixtures before mapping caption/editedTime/editedName/width/height/visibility (design flags
these as unverified).
Definition of done
snapshot() returns deduped plain records with correct edited-name/time
precedence; no keys present.
subscribe fires on refresh changes with correct changed/removed sets; a
no-op refresh fires nothing.
Tested; make check green.
Grounding
src/library/. Depends on the refresh unit (it drives subscribe).
Dispatch notes: TDD; no scripted edits; no interactive questions; plain language.
Squash subject ends (closes #<this issue>). End every message with Model: opus-4-8.
Model: opus-4-8
Cache/API implementation (https://git.eeqj.de/sneak/quak/issues/36), phase 2.
Depends on the Library.open/refresh unit.
## Goal
Plain-record snapshot and change subscription — the surface the GUI uses across
Electron IPC, where methods and file keys cannot cross. All metadata held in RAM
on both sides (owner ruling 5).
## Scope
- `PhotoRecord` (plain data, no keys, safe to send to a window): `fileID`,
`albumIDs`, `title` (`pubMagicMetadata.editedName` else `metadata.title`),
`takenAt` ms (`pubMagicMetadata.editedTime` else `metadata.creationTime`),
`fileType`, optional `caption`/`width`/`height`/`latitude`/`longitude`,
`isArchived`, `isHidden`, and `thumbnailPath?`/`originalPath?` set when cached.
- `AlbumRecord`: `collectionID`, `name`, `type` (`favorites` identifies the
favorites album), `isShared`, `updationTime`, `fileIDs` (newest first).
- `LibrarySnapshot { albums; photos; takenAt }`; `snapshot()` is synchronous
(RAM only), one `PhotoRecord` per `fileID` (deduped across memberships).
- `subscribe({ onChange })` → `{ unsubscribe }`, delivering `LibraryChange`
({ `albumsChanged`, `photosChanged` full records, `fileIDsRemoved`,
`albumIDsRemoved`, `refreshedAt` }) when a refresh changes something.
- Confirm Ente magic-metadata field names against the fixtures before mapping
`caption`/`editedTime`/`editedName`/`width`/`height`/`visibility` (design flags
these as unverified).
## Definition of done
- `snapshot()` returns deduped plain records with correct edited-name/time
precedence; no keys present.
- `subscribe` fires on refresh changes with correct changed/removed sets; a
no-op refresh fires nothing.
- Tested; `make check` green.
## Grounding
`src/library/`. Depends on the refresh unit (it drives `subscribe`).
Dispatch notes: TDD; no scripted edits; no interactive questions; plain language.
Squash subject ends ` (closes #<this issue>)`. End every message with
`Model: opus-4-8`.
Model: opus-4-8
Implemented in #62 (branch issue-43-snapshot-subscribe, base next).
snapshot() is synchronous and RAM-only: deduped plain PhotoRecord/AlbumRecord (one per fileID, all album ids, newest first), no keys. subscribe({ onChange }) delivers a LibraryChange only when a refresh changes the projection; a no-op refresh delivers nothing. Edited-name/edited-time take precedence over basic metadata; takenAt is in milliseconds. Magic-metadata field names (w/h, visibility) confirmed against the repo fixtures; caption had no fixture and gets one in the new tests. make check is green.
Model: opus-4-8
Implemented in https://git.eeqj.de/sneak/quak/pulls/62 (branch `issue-43-snapshot-subscribe`, base `next`).
`snapshot()` is synchronous and RAM-only: deduped plain `PhotoRecord`/`AlbumRecord` (one per `fileID`, all album ids, newest first), no keys. `subscribe({ onChange })` delivers a `LibraryChange` only when a refresh changes the projection; a no-op refresh delivers nothing. Edited-name/edited-time take precedence over basic metadata; `takenAt` is in milliseconds. Magic-metadata field names (`w`/`h`, `visibility`) confirmed against the repo fixtures; `caption` had no fixture and gets one in the new tests. `make check` is green.
Model: opus-4-8
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Cache/API implementation (#36), phase 2.
Depends on the Library.open/refresh unit.
Goal
Plain-record snapshot and change subscription — the surface the GUI uses across
Electron IPC, where methods and file keys cannot cross. All metadata held in RAM
on both sides (owner ruling 5).
Scope
PhotoRecord(plain data, no keys, safe to send to a window):fileID,albumIDs,title(pubMagicMetadata.editedNameelsemetadata.title),takenAtms (pubMagicMetadata.editedTimeelsemetadata.creationTime),fileType, optionalcaption/width/height/latitude/longitude,isArchived,isHidden, andthumbnailPath?/originalPath?set when cached.AlbumRecord:collectionID,name,type(favoritesidentifies thefavorites album),
isShared,updationTime,fileIDs(newest first).LibrarySnapshot { albums; photos; takenAt };snapshot()is synchronous(RAM only), one
PhotoRecordperfileID(deduped across memberships).subscribe({ onChange })→{ unsubscribe }, deliveringLibraryChange({
albumsChanged,photosChangedfull records,fileIDsRemoved,albumIDsRemoved,refreshedAt}) when a refresh changes something.caption/editedTime/editedName/width/height/visibility(design flagsthese as unverified).
Definition of done
snapshot()returns deduped plain records with correct edited-name/timeprecedence; no keys present.
subscribefires on refresh changes with correct changed/removed sets; ano-op refresh fires nothing.
make checkgreen.Grounding
src/library/. Depends on the refresh unit (it drivessubscribe).Dispatch notes: TDD; no scripted edits; no interactive questions; plain language.
Squash subject ends
(closes #<this issue>). End every message withModel: opus-4-8.Model: opus-4-8
Implemented in #62 (branch
issue-43-snapshot-subscribe, basenext).snapshot()is synchronous and RAM-only: deduped plainPhotoRecord/AlbumRecord(one perfileID, all album ids, newest first), no keys.subscribe({ onChange })delivers aLibraryChangeonly when a refresh changes the projection; a no-op refresh delivers nothing. Edited-name/edited-time take precedence over basic metadata;takenAtis in milliseconds. Magic-metadata field names (w/h,visibility) confirmed against the repo fixtures;captionhad no fixture and gets one in the new tests.make checkis green.Model: opus-4-8