Skip to content

feat(upload): onUploadInit callback exposes uuid + recoveryToken pre-chunk#71

Merged
rubenhensen merged 1 commit into
mainfrom
feat/upload-init-callback
May 16, 2026
Merged

feat(upload): onUploadInit callback exposes uuid + recoveryToken pre-chunk#71
rubenhensen merged 1 commit into
mainfrom
feat/upload-init-callback

Conversation

@dobby-coder
Copy link
Copy Markdown
Contributor

@dobby-coder dobby-coder Bot commented May 16, 2026

Summary

  • Adds onUploadInit?: (info: { uuid: string; recoveryToken: string }) => void to UploadOptions and CreateEnvelopeOptions.
  • Fires once, synchronously after upload_init resolves and before the first chunk PUT, so consumers (Outlook / Thunderbird addons) can persist {uuid, recoveryToken} to durable storage and rehydrate via the existing resumeUpload export after a process restart.
  • Threaded through Sealed.uploadencryptPipelinecreateUploadStream, and forwarded through createEnvelope.

Resolves #68. Unblocks encryption4all/postguard-tb-addon#103 and encryption4all/postguard-outlook-addon#82.

Why a callback rather than widening UploadResult?

The whole point is the restart-mid-upload case — the process can be killed, the network can drop permanently, or the chunk PUT can hang past the user closing the app. By the time Sealed.upload resolves it is too late; the token has to be persistable from the moment upload_init returns. A future additive change can still widen UploadResult / EnvelopeResult to also include recoveryToken on the success path if useful for post-upload status queries — out of scope here.

Notes

  • Callback is intentionally synchronous-friendly: it runs inside the WritableStream start handler. A throw will error the stream — documented in the JSDoc. Consumers should keep the body short (a chrome.storage.local.set is fine).
  • No changes to the resume / idempotent-retry paths shipped in feat(api): capture recovery_token and add resumeUpload for cross-restart resume #66 — those already work; this PR just exposes the missing piece so external callers can drive them.

Test plan

  • npm test — 91/91 pass (2 new tests in tests/api.test.ts: callback fires once with the expected payload before the first PUT; callback is not called when upload_init fails).
  • npm run build — clean; dist/index.d.mts now carries onUploadInit on both UploadOptions and CreateEnvelopeOptions.
  • Manual integration via the Thunderbird addon once this lands and is released.

🤖 Generated with Claude Code

…chunk

Adds `onUploadInit?: (info: { uuid: string; recoveryToken: string }) => void`
to `UploadOptions` and `CreateEnvelopeOptions`. Fires once, synchronously
after `upload_init` resolves and before the first chunk PUT, so callers
(Outlook/Thunderbird addons) can persist `{uuid, recoveryToken}` to durable
storage and rehydrate via `resumeUpload` after a process restart.

Threaded through Sealed.upload → encryptPipeline → createUploadStream, and
forwarded through createEnvelope.

Closes #68
Refs encryption4all/postguard-tb-addon#103
Refs encryption4all/postguard-outlook-addon#82

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@rubenhensen rubenhensen merged commit dcdd659 into main May 16, 2026
2 checks passed
@rubenhensen rubenhensen deleted the feat/upload-init-callback branch May 16, 2026 12:48
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 1.8.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Copy link
Copy Markdown
Contributor Author

@dobby-coder dobby-coder Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Post-merge review for the pipeline:

  • Threading correct through Sealed.upload → encryptPipeline → createUploadStream, plus forwarding via createEnvelope.
  • Callback fires inside the WritableStream start handler after initUpload resolves and before any chunk PUT — test asserts ordering (only the init fetch has happened when the callback runs).
  • Failure path covered: when upload_init rejects, the callback is not invoked.
  • JSDoc on both UploadOptions.onUploadInit and CreateEnvelopeOptions.onUploadInit correctly warns that a throw errors the stream and that it no-ops when no upload happens.
  • API surface is purely additive — no breaking change.

Approving in spirit; cannot --approve own PR via the API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose recoveryToken from Sealed.upload / createEnvelope so callers can resume across restarts

1 participant