diff --git a/docs/api-connect.md b/docs/api-connect.md
index c4c30ac..ffe6941 100644
--- a/docs/api-connect.md
+++ b/docs/api-connect.md
@@ -1,22 +1,30 @@
# connect
-`connect` is a mixin that "connects" a web component to the store. It provides two methods:
+The idiomatic expression for binding a component to a state store is to _connect_ it. Rdx's connect API comes in two flavours: One [for class based components](/api-connect?id=for-class-based-components-web-components) (e.g. web components), and one [for Svelte components](/api-connect?id=for-svelte-components).
-## mapState
+## For class based components (web components)
+
+```ts
+import { connect } from '@captaincodeman/rdx/components'
+```
+
+The `connect` mixin creates a new base class for your web component. It provides two methods:
+
+### mapState
`mapState(state: State)` passes the current store state to the component to allow it to extract the state it needs. It should return an object who's properties will be applied to the instance. It's good practice to use a package such as [reselect](https://github.com/reduxjs/reselect) to avoid unnecessary updates and also act as a buffer to insulate components from changes to the store state.
-## mapEvents
+### mapEvents
`mapEvents()` defines a mapping from events that the component will listen to, and actions that it can dispatch to the store. The method should return an object that maps the event names to listen to, to the functions that will be called (usually to dispatch an action to the store using details from the event).
-## Example
+### Example for web components
This example shows a simple counter component using [lit-element](https://lit-element.polymer-project.org/) connected to the store to display the current counter state and automatically dispatch actions to increment or decrement it. Not shown: the custom buttons would raise the `increment-counter` and `decrement-counter` custom events, or regular `@click` [lit-html event handlers](https://lit-html.polymer-project.org/) could be used to dispatch actions directly.
```ts
import { LitElement } from 'lit-element'
-import { connect } from '@captaincodeman/rdx'
+import { connect } from '@captaincodeman/rdx/components'
import { store, State } from './store'
export class CounterElement extends connect(store, LitElement) {
@@ -45,3 +53,30 @@ export class CounterElement extends connect(store, LitElement) {
}
}
```
+
+## For Svelte components
+
+```ts
+import { connect } from '@captaincodeman/rdx/svelte'
+```
+
+`connect` provides a [custom Svelte store](https://svelte.dev/tutorial/custom-stores) that your Svelte component can use to access the state in the store.
+
+
+### Example for Svelte
+
+This example shows a simple counter component in [Svelte](https://svelte.dev), connected to the store to display the current counter state (which is just the count) and dispatch actions to increment or decrement it.
+
+```svelte
+
+
+
+{count}
+
+```
\ No newline at end of file
diff --git a/package.json b/package.json
index 69072fd..f8443ef 100644
--- a/package.json
+++ b/package.json
@@ -59,5 +59,8 @@
},
"dependencies": {
"@captaincodeman/router": "^1.0.1"
+ },
+ "peerDependencies": {
+ "svelte": "^3.0.0"
}
}
diff --git a/readme.md b/readme.md
index d206a5b..461fe3a 100644
--- a/readme.md
+++ b/readme.md
@@ -34,7 +34,7 @@ While the aim isn't to be 100% compatible with Redux, it can work with the Redux
To create your state store:
```ts
-import { Store, combineReducers, connect, thunk, persist, devtools} from '@captaincodeman/rdx'
+import { Store, combineReducers, thunk, persist, devtools} from '@captaincodeman/rdx'
// a very simple reducer state
const counter = (state = 0, action) => {
diff --git a/rollup.config.js b/rollup.config.js
index f328ff0..b372c9b 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -9,14 +9,15 @@ export default {
index: 'src/index.ts',
combineReducers: 'src/combineReducers.ts',
compat: 'src/compat.ts',
+ components: 'src/components.ts',
const: 'src/const.ts',
createModel: 'src/createModel.ts',
createStore: 'src/createStore.ts',
- connect: 'src/connect.ts',
devtools: 'src/devtools.ts',
persist: 'src/persist.ts',
routing: 'src/routingPlugin.ts',
store: 'src/store.ts',
+ svelte: 'src/svelte.ts',
thunk: 'src/thunk.ts',
},
output: {
diff --git a/src/connect.ts b/src/components.ts
similarity index 99%
rename from src/connect.ts
rename to src/components.ts
index 1e597a9..9d5e994 100644
--- a/src/connect.ts
+++ b/src/components.ts
@@ -1,5 +1,5 @@
import { Store } from '../typings/store'
-import { Constructor, Connectable, DispatchMap } from '../typings/connect'
+import { Constructor, Connectable, DispatchMap } from '../typings/components'
import { stateEvent } from './const'
const dispatchMap: unique symbol = Symbol()
diff --git a/src/index.ts b/src/index.ts
index b964e0a..8d8a45f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,4 @@
export * from './combineReducers'
-export * from './connect'
export * from './const'
export * from './createModel'
export * from './createStore'
diff --git a/src/svelte.ts b/src/svelte.ts
new file mode 100644
index 0000000..35c682b
--- /dev/null
+++ b/src/svelte.ts
@@ -0,0 +1,17 @@
+import { readable } from 'svelte/store'
+import type { Store } from '../typings'
+
+export function connect(store: Store) {
+ const state = readable(store.state, (set) => {
+ const handler = () => {
+ set(store.state)
+ }
+ store.addEventListener('state', handler)
+ return () => store.removeEventListener('state', handler)
+ })
+
+ return {
+ subscribe: state.subscribe,
+ dispatch: store.dispatch,
+ }
+}
diff --git a/test/types/connect.ts b/test/types/components.ts
similarity index 79%
rename from test/types/connect.ts
rename to test/types/components.ts
index c0a7b57..3af6bbc 100644
--- a/test/types/connect.ts
+++ b/test/types/components.ts
@@ -1,6 +1,6 @@
import { assert, IsExact } from "conditional-type-checks"
-import { DispatchMap } from '../../typings/connect'
+import { DispatchMap } from '../../typings/components'
const map: DispatchMap = {
'click': (_e: Event) => {},
diff --git a/typings/connect.d.ts b/typings/components.d.ts
similarity index 100%
rename from typings/connect.d.ts
rename to typings/components.d.ts
diff --git a/typings/index.d.ts b/typings/index.d.ts
index 158be11..946f6cf 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -1,5 +1,4 @@
export * from './combineReducers'
-export * from './connect'
export * from './devtools'
export * from './model'
export * from './models'
diff --git a/typings/svelte.d.ts b/typings/svelte.d.ts
new file mode 100644
index 0000000..fb8c386
--- /dev/null
+++ b/typings/svelte.d.ts
@@ -0,0 +1,6 @@
+import type { Dispatch, Store } from './store'
+
+export declare function connect(store: Store): {
+ subscribe: (run: (value: S) => void, invalidate?: (value?: S) => void) => () => void
+ dispatch: Dispatch
+}