This guide is for adding or changing an official adapter package.
Before writing code, decide which family the new integration belongs to.
- Binder-backed adapter
- Bridges an external whole-store runtime into Coaction through
defineExternalStoreAdapter()or the compatibility aliascreateBinder() - Examples: Zustand, MobX, Pinia, Redux, Jotai, Valtio, XState
- Bridges an external whole-store runtime into Coaction through
- Middleware integration
- Extends a Coaction-owned store without replacing store ownership
- Examples: logger, persist, history, yjs
- Framework wrapper
- Adapts a Coaction store to framework-specific subscription and lifecycle behavior
If the integration needs to own its own external state runtime, it is usually a binder-backed adapter. If it only decorates a Coaction store, it is usually middleware.
Read these documents before implementation:
For binder-backed adapters, the key rule is unchanged:
- bind a whole store, not a slice
For a binder-backed adapter:
- Build the binding through
defineExternalStoreAdapter() - Normalize external state in
handleState - Wire Coaction lifecycle into the external runtime in
handleStore - Preserve the store contract when overriding
subscribe(),destroy(), orapply() - Call
internal.notifyStateChange()after direct external immutable writes that updateinternal.rootStatewithout usingstore.setState()orstore.apply()
Implementation expectations:
- keep
destroy()idempotent - make external write behavior explicit
- do not invent a second write authority for client mode
- avoid package-specific transport rules that bypass Coaction sequencing
Official binder-backed adapters must use the shared contract suite in packages/core/test/binderAdapterContract.ts.
Required:
- add a
test/contract.test.tsfile for the package - cover local whole-store behavior
- cover shared main/client behavior only if that mode is an official contract
- include a type-expectation test
Keep package-specific tests for unique behavior:
- adapter-specific errors
- integration quirks
- branch coverage around cleanup or edge cases
Every adapter change must update support-matrix.md when it changes any official guarantee:
- local support
- shared main/client support
- slices compatibility
- middleware or external-write guarantees
Do not merge new behavior without updating the declared support status.
At minimum:
- package README quick-start still works
- compatibility notes match the support matrix
- limitations are stated directly, not implied
If the adapter expands or narrows support, update the root README maintenance links when needed.