Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support more strongly-typed ReadTransaction. #55

Merged
merged 1 commit into from
Sep 13, 2023

Conversation

aboodman
Copy link
Contributor

@aboodman aboodman commented Sep 13, 2023

Problem

useSubscribe() is used by both Replicache and Reflect. Reflect has added a new form of ReadTransaction that has a generic get method. We would like users of replicache-react to be able to use that.

However, currently replicache-react pulls in Replicache directly and uses its ReadTransaction. We could publish a new Replicache with the new signature, but then we would have a new problem: that head replicache-react only works with the latest Replicache/Reflect.

Solution

Decouple replicache-react and Replicache completely by defining an abstract Subscribable.

@arv arv self-requested a review September 13, 2023 07:53
Copy link
Contributor

@arv arv left a comment

Choose a reason for hiding this comment

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

LGTM

src/index.ts Outdated
import {useEffect, useState} from 'react';
import {unstable_batchedUpdates} from 'react-dom';

type Subscribable = Pick<Replicache, 'subscribe'>;
type Subscribable<Tx, Data> = {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be exported since it is part of the public API.

I think some tools report this but the tool we use for our dts bundling does not. One thing to think about it is that anything that can be reached from the public api should also be part of the public api.

export function useSubscribe<R extends ReadonlyJSONValue | undefined>(
rep: Subscribable | null | undefined,
query: (tx: ReadTransaction) => Promise<R>,
export function useSubscribe<Tx, D, R extends D>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you really need 3 type params? Doesn't the following work?

export function useSubscribe<Tx, R>(
  r: Subscribable<Tx, R> | null | undefined,
  query: (tx: Tx) => Promise<R>,
  def: R,
  deps: Array<unknown> = [],
): R {

Copy link
Contributor

Choose a reason for hiding this comment

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

I downloaded this PR and the proposed change works in isolation but it does not work for the tests, and the tests looks right to me. I guess the R extends D is the magic sauce to allow that to work.

useSubscribe() is used by both Replicache and Reflect. Reflect has
added a new form of ReadTransaction that has a generic get<T>
method. We would like users of replicache-react to be able to use
that.

However, currently replicache-react pulls in Replicache directly
and uses its ReadTransaction. We could publish a new Replicache
with the new signature, but then we would have a new problem:
that head replicache-react only works with the latest
Replicache/Reflect.

Solution:

Decouple replicache-react and Replicache completely by defining an
abstract Subscribable.
@aboodman aboodman merged commit a514654 into main Sep 13, 2023
@aboodman aboodman deleted the aa/support-typed-tx branch September 13, 2023 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants