Compare commits
2
Commits
72918c7180
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04094a8cfb | ||
|
|
6a7a10f489 |
@@ -214,11 +214,23 @@ quak/
|
|||||||
auth/ login flow (SRP + email OTP + TOTP), key unwrap
|
auth/ login flow (SRP + email OTP + TOTP), key unwrap
|
||||||
model/ decrypted Collection, File, Metadata types + decrypt fns
|
model/ decrypted Collection, File, Metadata types + decrypt fns
|
||||||
download/ streaming file/thumbnail download + decryption
|
download/ streaming file/thumbnail download + decryption
|
||||||
|
library/ the cache-backed Library: metadata store, read
|
||||||
|
surface, records, content cache, precache, ML data
|
||||||
|
and search, request pools
|
||||||
backup.ts resilient full-account backup with dedup
|
backup.ts resilient full-account backup with dedup
|
||||||
|
metadata-backup.ts
|
||||||
|
backup-metadata: all decrypted metadata as JSON
|
||||||
|
mldata-fetch.ts fetch + decrypt per-file ML data
|
||||||
|
filename.ts safe file names from server metadata
|
||||||
errors.ts error types shared across layers
|
errors.ts error types shared across layers
|
||||||
retry.ts retry classifier + exponential backoff with jitter
|
retry.ts retry classifier + exponential backoff with jitter
|
||||||
thumbnails.ts detect + regenerate missing thumbnails
|
thumbnails.ts detect + regenerate missing thumbnails
|
||||||
client.ts high-level Client class assembled from the above
|
client.ts high-level Client class assembled from the above
|
||||||
|
cli-commands.ts the CLI's commands as functions returning exit codes
|
||||||
|
cli-output.ts how the CLI prints a file's title and time
|
||||||
|
cli-read.ts fresh reads for the CLI's read commands
|
||||||
|
cli-run.ts run a command, print its error, exit with its code
|
||||||
|
cli-session.ts read the saved session file back into a Client
|
||||||
index.ts public library exports
|
index.ts public library exports
|
||||||
bin/
|
bin/
|
||||||
quak.ts CLI entrypoint (commander.js)
|
quak.ts CLI entrypoint (commander.js)
|
||||||
@@ -493,8 +505,15 @@ the smallest does not.
|
|||||||
<name>/
|
<name>/
|
||||||
<title> -> ../../originals/<fileID>.<ext> (symlink)
|
<title> -> ../../originals/<fileID>.<ext> (symlink)
|
||||||
<name>.json collection metadata + file list
|
<name>.json collection metadata + file list
|
||||||
|
failures.json files that failed and have not yet succeeded
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`failures.json` records each failed file with the kind of failure, how many
|
||||||
|
times it has been tried and when it was last tried. A file leaves it once it
|
||||||
|
succeeds, or once it is no longer in the library or in the backup's scope. The
|
||||||
|
library's `lib.backup({ includeThumbnails: true })` also writes
|
||||||
|
`thumbnails/<fileID>.jpg` beside `originals/`; `quak backup` does not.
|
||||||
|
|
||||||
A collection's directory and JSON are named after the collection, and a symlink
|
A collection's directory and JSON are named after the collection, and a symlink
|
||||||
after the file's title, both with unsafe characters replaced. When two
|
after the file's title, both with unsafe characters replaced. When two
|
||||||
collections would get the same name, or two files in one collection the same
|
collections would get the same name, or two files in one collection the same
|
||||||
@@ -536,7 +555,12 @@ temporary file's permissions, not those of the file it replaced.
|
|||||||
errors
|
errors
|
||||||
- [x] Update the API reference section below to match the current implementation
|
- [x] Update the API reference section below to match the current implementation
|
||||||
- [x] `make docker` green
|
- [x] `make docker` green
|
||||||
- [ ] Tag `v1.0.0`
|
- [ ] Store live photos in a form a photo viewer can open
|
||||||
|
(https://git.eeqj.de/sneak/quak/issues/107), once sneak has chosen between
|
||||||
|
keeping the ZIP and unpacking it
|
||||||
|
|
||||||
|
Tagging and releases are decided by sneak alone, and happen only when he
|
||||||
|
declares one.
|
||||||
|
|
||||||
Future (desktop client, separate repo):
|
Future (desktop client, separate repo):
|
||||||
|
|
||||||
@@ -556,10 +580,11 @@ test suite is the canonical, executable documentation — `test/library/` and
|
|||||||
### Opening a library
|
### Opening a library
|
||||||
|
|
||||||
`Library.open(options)` loads the on-disk cache, starts the background refresh
|
`Library.open(options)` loads the on-disk cache, starts the background refresh
|
||||||
loop, and resolves to a `Library`. On an empty cache it awaits the first refresh
|
loop, and resolves to a `Library`. On an empty cache it awaits the first
|
||||||
so it never opens onto empty data; on an existing cache it returns immediately
|
refresh, so it opens onto the account's data whenever the server is reachable;
|
||||||
and refreshes in the background, so an unreachable server does not block
|
if that refresh fails, it opens with no data and records the error in
|
||||||
opening.
|
`lib.status()`. On an existing cache it returns immediately and refreshes in the
|
||||||
|
background, so an unreachable server does not block opening.
|
||||||
|
|
||||||
`LibraryOptions`:
|
`LibraryOptions`:
|
||||||
|
|
||||||
@@ -775,8 +800,10 @@ documents:
|
|||||||
markdown. Use `make fmt` to format. Use `yarn` not `npm`.
|
markdown. Use `make fmt` to format. Use `yarn` not `npm`.
|
||||||
|
|
||||||
- **Testing:** vitest. Tests go in `test/` mirroring the `src/` structure.
|
- **Testing:** vitest. Tests go in `test/` mirroring the `src/` structure.
|
||||||
`make test` must complete in under 20 seconds. Use `mkdtempSync` for temporary
|
`make test` must finish in under 60 seconds (the hard cap) and should finish
|
||||||
directories, never manual timestamp paths.
|
in under 20. The 90-second `timeout` in the `test` phase of the `Dockerfile`
|
||||||
|
is a backstop that catches a hung test, not the time limit. Use `mkdtempSync`
|
||||||
|
for temporary directories, never manual timestamp paths.
|
||||||
|
|
||||||
- **Code style:** `const` for everything, `let` if reassignment is needed, never
|
- **Code style:** `const` for everything, `let` if reassignment is needed, never
|
||||||
`var`. Avoid unnecessary comments. No hand-rolled crypto. The
|
`var`. Avoid unnecessary comments. No hand-rolled crypto. The
|
||||||
|
|||||||
@@ -14,10 +14,30 @@ pre-1.0
|
|||||||
|
|
||||||
# Next Step
|
# Next Step
|
||||||
|
|
||||||
Tag v1.0.0.
|
Store live photos in a form a photo viewer can open
|
||||||
|
(https://git.eeqj.de/sneak/quak/issues/107). This waits on sneak's choice
|
||||||
|
between keeping the ZIP and unpacking it into the image and the video.
|
||||||
|
|
||||||
|
Tagging and releases are decided by sneak alone, and happen only when he
|
||||||
|
declares one.
|
||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-09-23: Settled the package metadata (issue 6). quak is not published, so
|
||||||
|
`package.json` is marked `"private": true` and the `files` field is gone.
|
||||||
|
`engines.node` is `>=22`, the major version `script/bootstrap` and the
|
||||||
|
`Dockerfile` use. An `exports` map makes `.` and `./package.json` the only
|
||||||
|
importable paths; `runMetadataBackup`, the thumbnail helpers and their types
|
||||||
|
stay internal to the CLI.
|
||||||
|
|
||||||
|
- 2026-09-23: Brought the README and this file in line with the tree (issue
|
||||||
|
111). The layout lists `src/library/` and the other source files, the backup
|
||||||
|
layout names `failures.json` and the optional `thumbnails/`, "Opening a
|
||||||
|
library" says what happens when the first refresh fails, the Testing section
|
||||||
|
gives the 60-second hard cap and 20-second target for `make test` and names
|
||||||
|
the 90-second `timeout` in the `Dockerfile` as the backstop for a hung test,
|
||||||
|
and "Tag v1.0.0" is no longer listed as the next step.
|
||||||
|
|
||||||
- 2026-09-23: Tested `quak login` and `backup-metadata --exif` (issue 110).
|
- 2026-09-23: Tested `quak login` and `backup-metadata --exif` (issue 110).
|
||||||
`loginCommand` takes its login function and its prompts from `CliContext`, and
|
`loginCommand` takes its login function and its prompts from `CliContext`, and
|
||||||
`bin/quak.ts` passes `Client.login` and the terminal prompts. Tests cover a
|
`bin/quak.ts` passes `Client.login` and the terminal prompts. Tests cover a
|
||||||
|
|||||||
+11
-5
@@ -9,17 +9,23 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.eeqj.de/sneak/quak.git"
|
"url": "https://git.eeqj.de/sneak/quak.git"
|
||||||
},
|
},
|
||||||
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
"main": "./dist/src/index.js",
|
"main": "./dist/src/index.js",
|
||||||
"types": "./dist/src/index.d.ts",
|
"types": "./dist/src/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/src/index.d.ts",
|
||||||
|
"import": "./dist/src/index.js"
|
||||||
|
},
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"quak": "./dist/bin/quak.js"
|
"quak": "./dist/bin/quak.js"
|
||||||
},
|
},
|
||||||
"files": [
|
|
||||||
"dist/",
|
|
||||||
"README.md",
|
|
||||||
"LICENSE"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "script/build",
|
"build": "script/build",
|
||||||
"quak": "node ./dist/bin/quak.js",
|
"quak": "node ./dist/bin/quak.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user