feat: Add Promise-based JMAP client wrapper for simplified API usage#18
Merged
feat: Add Promise-based JMAP client wrapper for simplified API usage#18
Conversation
Add a high-level client factory that hides Effect internals behind a Promise-based API. Consumers can now use `await createJMAPClient(url, token)` to get a client with `client.mailbox.getAll()`, `client.email.query()`, etc. - Auto-discovers primary accountId from session - Validates credentials on creation (async factory) - Namespaced API: mailbox, email, submission - ManagedRuntime for efficient layer caching - dispose() for cleanup - Existing Effect-based API unchanged - Renamed createJMAPClient (layer factory) to createJMAPClientLayer https://claude.ai/code/session_0152ZUp5oDUjuP7L1XevVMTr
JMAP Spec Coverage
Overall: 15/31 methods (48.4%) Blob (0/4)
Core (0/1)
Email (6/8)
EmailSubmission (5/5)
Identity (0/3)
Mailbox (4/5)
SearchSnippet (0/1)
Thread (0/2)
VacationResponse (0/2)
|
Preview Package PublishedPublished from commit c9c68c9 |
… calls Replace verbose generator pattern with pipe-friendly flatMap for two-line service calls in the wrapper (yield service, yield method). https://claude.ai/code/session_0152ZUp5oDUjuP7L1XevVMTr
JMAP Spec Coverage
Overall: 15/31 methods (48.4%) Blob (0/4)
Core (0/1)
Email (6/8)
EmailSubmission (5/5)
Identity (0/3)
Mailbox (4/5)
SearchSnippet (0/1)
Thread (0/2)
VacationResponse (0/2)
|
JMAP Spec Coverage
Overall: 15/31 methods (48.4%) Blob (0/4)
Core (0/1)
Email (6/8)
EmailSubmission (5/5)
Identity (0/3)
Mailbox (4/5)
SearchSnippet (0/1)
Thread (0/2)
VacationResponse (0/2)
|
Add `initialSession` option to JMAPClientConfig and `session` option to createJMAPClient() so consumers can pass a cached session, skipping the initial HTTP round-trip to the session endpoint. https://claude.ai/code/session_0152ZUp5oDUjuP7L1XevVMTr
JMAP Spec Coverage
Overall: 15/31 methods (48.4%) Blob (0/4)
Core (0/1)
Email (6/8)
EmailSubmission (5/5)
Identity (0/3)
Mailbox (4/5)
SearchSnippet (0/1)
Thread (0/2)
VacationResponse (0/2)
|
effect-jmap-release bot
pushed a commit
that referenced
this pull request
Feb 11, 2026
# [0.9.0](v0.8.0...v0.9.0) (2026-02-11) ### Features * Add Promise-based JMAP client wrapper (createJMAPClient) ([#18](#18)) ([76ae8d0](76ae8d0)), closes [hi#level](https://github.com/hi/issues/level)
|
🎉 This PR is included in version 0.9.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a new Promise-based client wrapper (
JMAPClientWrapper) that hides Effect-TS internals, making the library accessible to developers who don't want to work with Effect directly. The wrapper provides a familiar async/await API while maintaining full compatibility with the existing Effect-based architecture.Key Changes
New
wrapper.tsmodule: ImplementsJMAPClientWrapperinterface with three namespaces:MailboxNamespace: Promise-based mailbox operations (get, set, query, create, update, destroy, etc.)EmailNamespace: Promise-based email operations (get, set, query, search, mark read, flag, move, etc.)SubmissionNamespace: Promise-based email submission/sending operationsThree factory functions for creating the wrapper:
createJMAPClient(sessionUrl, bearerToken): Simple creation with default configcreateJMAPClientWithConfig(config): Creation with custom configurationcreateJMAPClientFromLayer(layer): Advanced usage with pre-built Effect layersAuto-discovered account ID: The wrapper automatically discovers and exposes the primary account ID from the JMAP session, allowing convenience methods to use it as a default
Low-level batch API: Exposes
batch()method for direct JMAP batch calls when neededResource management: Includes
dispose()method to clean up the underlying Effect runtimeComprehensive test suite: Added
client-wrapper.test.tswith tests for creation, mailbox operations, email operations, and resource disposalUpdated exports: Modified
src/client/index.tsto export the new wrapper types and functions, and renamed existing layer factories fromcreateJMAPClient→createJMAPClientLayerto avoid naming conflictsUpdated documentation: Enhanced README with Promise-based quick start example and reorganized Effect-based usage into a separate section
Implementation Details
ManagedRuntime.make()to create a single Effect runtime instance that persists across all method callsEffect.gen()generators and executed viaruntime.runPromise()accountIdparameters on convenience methods default to the auto-discovered primary account IDSchema.Schema.Typeutility for inferring types from Effect schemashttps://claude.ai/code/session_0152ZUp5oDUjuP7L1XevVMTr