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

Improve TypeScript generated code (fixes and improvements) #603

Merged
merged 13 commits into from
Dec 9, 2023

Conversation

drogus
Copy link
Collaborator

@drogus drogus commented Nov 28, 2023

Description of Changes

This is a set of changes improving various parts of TypeScript autogen:

  • properly map u64 and i64 values to BigInt
  • change the way we handle client db in classes, which is needed for allowing to run multiple SpacetimeDB clients in TypeScript. The new API will allow to do sth like User.with(client).onInsert(...)
  • change in how reducers and tables are registered - instead of doing it automagically on import, we will now require explicit call to SpacetimeDBClient.registerReducers or .registerTables. The problem with doing it automagically is that it will sometimes fail. Node will filter out any imports that are unused, so if you import a table without actually using the class constant, but you do a subscribe, it would result in an error. With explicit include it's no longer a problem
  • now we will also export constants and/or functions for enum variants. So far using enum variants was cumbersome, cause given a reducer like foo(user_type: UserType) where UserType is an enum, in javascript you would have to do sth like FooReducer.call({ tag: "Admin", value: undefined }), which requires you to know how sum types are constructed in TypeScript. With the changes from the PR you can now do FooReducer.call(UserType.Admin). For an enum variant with value it would be sth like AnEnum.VariantA("a value") which will return { tag: "VariantA", value: "a value" }
  • I fixed a case where we converted __identity_bytes to camel case, which resulted in an error
  • changed the API for how reducer callbacks are defined. instead of providing an args: any[] array we now list all of the values with proper types. So for example given an add(u64, u64) reducer the callback signature for a callback would be sth like (reducerEvent: ReducerEvent, a: BigInt, b: BigInt)

API and ABI breaking changes

These changes will break the TypeScript SDK, so a new release will be needed when this is released.

Expected complexity level and risk

I think it's a 2, it's not overly complex and it will actually lower some of the complexity in the SDK (for example by being more explicit with registering reducers and tables)

Thanks to that devs could now use it more intuitively, similarly to
Rust, for example:

    let role = Role.Admin; // it returns { tag: "Admin", value: undefined };
    let role1 = Role.Custom("Foo") // returns { tag: "Custom", value: "Foo" };
In JS all numbers are 64bit floats, but that means integers are only up
to 53 bits. Thus any 64+ bits integers need to be handled as BigInts
@drogus drogus changed the title Drogus/typescript improvements Improve TypeScript generated code (fixes and improvements) Nov 28, 2023
Copy link
Contributor

@gefjon gefjon left a comment

Choose a reason for hiding this comment

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

I like all these changes. I'd like to see a corresponding docs PR to update the SDK ref (and quickstart, if necessary) to reflect the new interface. I'd especially like the docs on Table.with to be very clear about whether that mutates global state (I believe it doesn't), with an example that describes the behavior of:

MyTable.onInsert(someCallback)

MyTable.with(conn).onInsert(otherCallback)

MyTable.onInsert(thirdCallback)

I also notice that the corresponding TypeScript SDK PR doesn't update examples/quickstart. The main way I'll be convinced that this is ready for the big time is when the quickstart client builds and runs.

@drogus
Copy link
Collaborator Author

drogus commented Dec 4, 2023

@gefjon sorry for a late reply and thanks a lot for a review!

I updated the quickstart guide in the SDK PR, but there are almost no changes to make it work. The .with interface is only required if you want to create multiple clients, the default behaviour will be to use the first instantiated client. I will add more docs on the with method (like in the code + ref), but I don't think we should advertise it too much, like I would definitely not use it in the quickstart guide. It's only for unusual situations where you need to connect to multiple instances of SpacetimeDB or when you need multiple clients for the same database for some reason.

@drogus
Copy link
Collaborator Author

drogus commented Dec 4, 2023

So the only changes in the actual app code for quickstart is this diff, ie. adding registerTables and regusterReducers calls

@jdetter jdetter merged commit 3061cee into master Dec 9, 2023
5 checks passed
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.

3 participants