automerge / hypermerge

Build p2p collaborative applications without any server infrastructure in Node.js
MIT License
1.28k stars 66 forks source link

Use hopefully-soon-to-be-official Automerge types #21

Closed HerbCaudill closed 1 year ago

HerbCaudill commented 5 years ago

This PR replaces automerge.d.ts with the type definitions I've proposed for automerge here: https://github.com/automerge/automerge/pull/155

This type system differs from the existing one in that there is no Doc<T>, there is only T.

It also differs in that an entire Repo - and pretty much anything that pertains to that Repo - is bound to that T. So you'd do something like this:

interface MyState {
  ...
}

const repo = new Repo<MyState>({ storage })

const id = repo.create({...})

repo.doc(id, (state) => {
  // `state` has type `MyState`
}

Note that you don't need to specify repo.doc<MyState>(...) because anything coming out of that repo will be assumed to be of the same type.

pvh commented 5 years ago

Yikes -- that seems like not enough types to me. Do your repos only have a single document type? In our past projects we've basically had a type per react component.

HerbCaudill commented 5 years ago

Yikes -- that seems like not enough types to me. Do your repos only have a single document type?

Well, in a typical React/Redux app, you'd have have several types but a single state type that structures it all together in a single tree, e.g.

interface State {
  todos: Todo[]
  visiblityFilter: 'ALL' | 'ACTIVE' | 'COMPLETED'
  user: User
  isNetworkOnline: boolean
}

In our past projects we've basically had a type per react component.

In that case you can either not pass a type - I've set the default to any:

const repo = new Repo(...) // equivalent to `new Repo<any>(...)

or make a union type:

type ComponentState = CardState | AvatarState | DropdownState | PanelState
const repo = new Repo<ComponentState>({ storage })

Then you'd just cast the doc more specifically as needed.

repo.doc(id, (state: CardState) => {
  // `state` has type `CardState`
}