Skip to content

Generate schema-specific hooks and components API from tools module #50

Description

@jamesgpearce

With a schema it should be possible to generate domain-specific providers, hooks, and components, just like we do for store methods.

Activity

  1. WonderPanda commented on Jan 30, 2023

    @WonderPanda

    This would be a really great addition. Since we're building react applications we primarily interact through hooks for binding data so we're missing out on some typesafety

  2. jamesgpearce commented on Feb 3, 2023

    @jamesgpearce
    ContributorAuthor

    Working on this in the beta branch

  3. self-assigned this
    on Feb 3, 2023
  4. WonderPanda commented on Feb 16, 2023

    @WonderPanda

    Hey I saw that this is work in progress on the beta branch, but wanted to chime in on the potential approach being taken here.

    We're definitely not opposed to using some codegen tooling to bring more type safety to our TinyBase usage but I wanted to propose an alternative approach in terms of implementation from what exists currently.

    Right now, we end up with an enormous amount of individual functions granular all the way down to the cell level, eg: getUserNameCell() or I'm assuming for the hooks it'll end up being something like const name = useGetUserNameCell().

    From a developer consuming the generated API, it feels like a ton of overhead to keep thinking about the specific named function I'm going to need to import for a specific use case. Instead, I feel like it would be much nicer to have a typesafe API that's generated against the overall structure of the schema which would allow for something like this instead:

    const name = useCell('user', 'userId', 'name'); where both the table name and cell name are inherently type safe.

    I put together a super quick example in Typescript Playground here to show how it can be accomplished:

    type TinybaseSchema = Record<string, Record<string, string | number | boolean>>;
    
    type Schema = {
      users: {
        id: string;
        name: string;
        updated_at: string;
        age: number;
      };
    };
    
    type StoreWrapper<TSchema extends TinybaseSchema> = {
      getRow<TTable extends keyof TSchema>(
        tableName: TTable,
        id: string
      ): TSchema[TTable];
    
      getCell<TTable extends keyof TSchema, TCell extends keyof TSchema[TTable]>(
        tableName: TTable,
        id: string,
        cell: TCell
      ): TSchema[TTable][TCell];
    };
    
    const store = null as unknown as StoreWrapper<Schema>;
    
    const rowExample = store.getRow('users', '123');
    const cellExample = store.getCell('users', "123", 'name');
    const cellExample2 = store.getCell('users', '123', 'notACell') // error, 'notACell' is not valid
    const cellExample3 = store.getCell('user', '123', 'notACell') // error, 'user' is not valid
  5. jamesgpearce commented on Feb 18, 2023

    @jamesgpearce
    ContributorAuthor

    Definitely! The ORM autogenerated methods trope is pretty verbose (and getting worse) so generating type definitions for a casted store is an elegant alternative. I suspect we will end up with both options in 3.1.

  6. jamesgpearce commented on Mar 2, 2023

    @jamesgpearce
    ContributorAuthor

    OK, more or less finished with the explicit generated API (https://github.com/tinyplex/tinybase/releases/tag/v3.1.0-beta.2) - going to get the 'lighter' typing approach available for beta.3... coming soon!

  7. jamesgpearce commented on Mar 2, 2023

    @jamesgpearce
    ContributorAuthor

    Here's what I plan to implement for the types-only refinement approach:

    image

    As you might discern from adb9fb8 (see src/tools/refinement/core.ts), there's a full passthrough of the type definitions by default, so we only need to code-generate those that are refined by the schema, and everything else will still be present for importing.

    Fortunately the boilerplate for refining the whole module ends up being pretty slick, and the passthrough means we don't even need to take it to any or unknown and back!

  8. jamesgpearce commented on Mar 16, 2023

    @jamesgpearce
    ContributorAuthor
  9. jamesgpearce commented on Mar 30, 2023

    @jamesgpearce
    ContributorAuthor

    Pretty excited about the work leading up to c396b91 - I think I can go all in on the core module being schema-typed, and remove a bunch of codegen. New beta coming soon.

  10. jamesgpearce commented on Apr 30, 2023

    @jamesgpearce
    ContributorAuthor

    I think I can close this out with v3.1 https://tinybase.org/guides/releases/#v3-1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions