Giter Site home page Giter Site logo

yornaath / batshit Goto Github PK

View Code? Open in Web Editor NEW
103.0 103.0 4.0 63.31 MB

A batch manager that will deduplicate and batch requests for a certain data type made within a window. Useful to batch requests made from multiple react components that uses react-query

Home Page: https://batshit-example.vercel.app/

License: MIT License

TypeScript 92.44% JavaScript 6.76% HTML 0.80%
async batch-processing concurrency deduplication fetch react react-query tanstack typescript

batshit's People

Contributors

alexanderprod avatar hugodelahousse avatar thesharpieone avatar yornaath avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

batshit's Issues

How to limit the number of merge requests

I want to limit the number of merge requests.

Ex: I want to get details of 100 posts, and in scheduler =10ms, batshit will batch about 20-30 requests into one request. But I want to In a batch, it only batches up to 8 requests at a time, instead of combining all requests within 10ms.

Then instead of having 1 request with 20 postIds, I will have 3 requests with

  • Request 1: 8 postId,
  • Request 2: 8 postId,
  • Request 3: 4 postId

License?

Can you please include a license. MIT would be nice :)

Typescript non-array responses

Thanks for the awesome library. I was adding some typescript typings through the generics and noticed that it expects an array to be returned by the fetcher. In the README example (copied below for convenience) the user is an object with an id and a name and I am guessing the client.users.where(...) function would return an array of those user objects [{id: 1, name: 'yornaath'}, {id: 2, name: 'TheSharpieOne'}]. That is great

type User = { id: number; name: string };

const users = create<User, number>({
  fetcher: async (ids) => {
    return client.users.where({
      id_in: ids,
    });
  },
  resolver: keyResolver("id"),
  scheduler: windowScheduler(10), // Default and can be omitted.
});

But what if the API was returning an object with the keys being the ids that were searched {1: {id: 1, name: 'yornaath'}, 2: {id: 2, name: 'TheSharpieOne'}}. Yes, the ids are kind of duplicated in the response. I was trying to match the example, this is not my exact use-case... so thus more generically: an response object containing more data based on some query params that can be combined together.

The restriction on expecting the result to be an array only seems to apply to keyResolver; which does a .find. Nowhere else does the type seem to matter / need to be an array. Maybe keyResolver can check for array vs object and attempt to use the value as the object key.

Perhaps the array can be added by the dev-user if they expect an array to be returned. Making the example above be const users = create<User[], number>({ That seems like a breaking type change, but it also seems better than having T[] | T through the code since it's not as explicit.

React: `fetcher` within a hook

I access my client through a React hook, const client = useClient(). This is because the client has authentication and other details provided by Contexts further up in my application.

I am curious to know if you have any ideas on how to consume a hook in the fetch. Perhaps fetch could be changed to allow passing a function instead of relying on the fetcher function? Currently, I'm overriding the reference client each time the hook is invoked and cleaning up when it unmounts. Maybe others have ideas. Thank you.

let client; // store reference to client

const userBatcher = createBatcher({
  fetcher: async (ids: number[]) => {
    return await client.usersById(ids);
  },
  resolver: keyResolver('id'),
  scheduler: windowScheduler(50),
});

export const useUserId = (id: number) => {
  client = useClient(); // update reference

  useEffect(() => {
    return () => {
        client = undefined;  // remove client ref on unmonut
    }
  });

  return useQuery(['user', 'id',],  async () => {
      return userBatcher.fetch(id);
    })
};

useSuspenseQuery only fetches on client side

It seems like that when using the Tanstack Query hook useSuspenseQuery it only fetches on client side and streaming actually never happens.
Would it not be possible to make an option in Batshit to use the cache (https://react.dev/reference/react/cache) in React instead of the windowMs so you know on serverside what need to be batched?
An example of streaming with Tanstack Query would be https://tanstack.com/query/latest/docs/framework/react/examples/nextjs-suspense-streaming

Permit keyResolver customization

The type definition of fetcher indicates it accepts a generic Q, which is actually constrained to string | number given the implementation of keyResolver which just tries to match a data property against the query value.

https://github.com/yornaath/batshit/blob/master/packages/batshit/src/index.ts#L192

A batch manager that will deduplicate and batch requests for a certain data type made within a window. - I think for this to be true, either keyResolver needs to be customizeable (e.g. allow to match queries against data items) or the type should be changed to e.g. <Q extends string | number> to correspond to the current implementation.

I'm passing in objects and with the current implementation there's no way to resolve the data.

Feature: Change devtools location

Currently it's always located in the bottom right, would be nice and useful if it could be moved with a prop, or even the possibility to apply own styles for it.

keyResolver - using index

Howdy,

I'm trying to batch up some search requests. The individual requests would look something like this:

"a" => 123,
"b" => 456,
"c" => 789

The batched request would look something like this:

["a", "b", "c"] => [123, 456, 789]

I want to "de-batch" based on an index. Is that currently possible?

I saw indexedResolver, but it doesn't seem to do what I want it to do (or I may be totally misunderstanding it).

Thanks,
Rand

compile targets

In one project I have problems importing the library due to the compiled targets. We use webpack 4.x (yep, it's an old one), and it doesn't like optional chaining in the generated js files (babel/acorn has issues)

Unfortunately I can not update webpack right now (time / complexity etc). So is it possible to look at the target settings, when building npm packages?

ERROR in /home/tbowmo/projects/FrontEnd/node_modules/@yornaath/batshit/dist/index.esm.js 14:30
Module parse failed: Unexpected token (14:30)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|  */
| const create = (config, memory) => {
>     const name = config.name ?? `batcher:${Math.random().toString(16).slice(2)})`;
|     const scheduler = config.scheduler ?? windowScheduler(10);
|     const devtools = globalThis.__BATSHIT_DEVTOOLS__?.for(name);

keyResolver returns undefined

If the keyresolver can't find a match for the key, it returns undefined, resulting in reactQuery throwing up.

Perhaps it should coalesce to null instead?

Is the name intentional?

I don't know how safe I feel, by including a library in my projects that refers to bat poop :)

Is it intentionally called batshit? Or is it just a typo?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.