14 Commits

Author SHA1 Message Date
Jason Larabie 14f79910ee Update C++ module bindings to RawModuleDefV10 (#4461)
# Description of Changes
- Migrated the C++ module-definition assembly path to V10-first
internals:
      - Added v10_builder and module_type_registration systems.
- Switched Module::__describe_module__ to serialize RawModuleDef with
V10 payload.
      - Updated macro registration pipeline to register through V10
- Added explicit naming support across macro surface (*_NAMED variants
for reducer/procedure/
        view and field/index macros).
- Reworked multi-column index macros (FIELD_MultiColumnIndex,
FIELD_MultiColumnIndex_NAMED) with
        migration alias.
- Added SPACETIMEDB_SETTING_CASE_CONVERSION(...) to support case
conversion policy
- Error-path hardening by adding explicit constraint-registration error
tracking and preinit validation
  - Codegen updates:
      - Updated C++ moduledef regen to V10 builder types.
- Adjusted C++ codegen duplicate-variant wrapper generation to emit
proper product-type
        wrappers.
  - Test/harness updates:
- type-isolation-test runner now defaults to focused V10 regression
checks; --v9 runs broader
        legacy/full suite.
      - Added focused modules for positive/negative V10 checks:
          - test_multicolumn_index_valid
          - error_multicolumn_missing_field
          - error_default_missing_field
- Re-enabled C++ paths in sdks/rust/tests/test.rs procedure/view/test
suites.

# API and ABI breaking changes

- Refactor of the underlying module definition
- New *_NAMED variant macros for explicit canonical naming
- FIELD_NamedMultiColumnIndex renamed to FIELD_MultiColumnIndex

# Expected complexity level and risk

3 - Large set of changes moving over to V10 with underlying changes to
make future updates a little easier

# Testing
- [x] Ran the type isolation test and expanded it
- [x] Ran the spacetimedb-sdk test framework to confirm no more drift
between C++ and other module languages
- [x] Ran Unreal test suite though not really applicable
- [x] New app creation with `spacetime init --template basic-cpp`
- [x] Ran describe module tests against Rust + C# matching with C++ on
the /modules/sdk-test* modules to find any possible mis-alignment

# Review
- [x] Another look at the new features with C++
- [x] Thoughts on *_NAMED macros, I couldn't come up with a better
solution with C++20
2026-02-28 07:05:50 +00:00
clockwork-labs-bot dd2c95f113 Move CaseConversionPolicy to public SpacetimeDB namespace (#4382)
Move `CaseConversionPolicy` from `SpacetimeDB.Internal` to the public
`SpacetimeDB` namespace so module authors can write:

```csharp
[SpacetimeDB.Settings]
public const CaseConversionPolicy CASE_CONVERSION_POLICY = CaseConversionPolicy.SnakeCase;
```

instead of the verbose:

```csharp
public const SpacetimeDB.Internal.CaseConversionPolicy CASE_CONVERSION_POLICY = SpacetimeDB.Internal.CaseConversionPolicy.SnakeCase;
```

### Changes
- Move enum definition from `SpacetimeDB.Internal` to `SpacetimeDB`
namespace in autogen
- Fully qualify all `Internal` references to
`SpacetimeDB.CaseConversionPolicy`
- Codegen source generator accepts both
`SpacetimeDB.CaseConversionPolicy` and
`SpacetimeDB.Internal.CaseConversionPolicy` for backward compatibility
- Updated test fixture and verified snapshots
- All 4 codegen tests pass

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-20 22:21:46 +00:00
Noa 178a7f0e60 Fix warnings in regen-cpp-moduledef (#4355)
# Description of Changes

This has been annoying me for a bit. We don't care if we use println in
a dev tool.

# Expected complexity level and risk

1

# Testing

- [x] The warnings are gone.
2026-02-19 21:34:27 +00:00
Jason Larabie c59ee1ddc3 [2.0 Breaking] Add --include-private and default private tables to not generate (#4241)
# Description of Changes
Updated the codegen table/function iteration functions to take in a
parameter to check visibility in all locations for the supported
languages.
- Updated the util.rs functions for iterating tables/functions to check
for a CodegenVisibility enum (IncludePrivate, or OnlyPublic)
- Added a new CodegenOptions struct to pass around the CodegenVisibility
and future flags, defaulted visibility to OnlyPublic
- Updated the CLI to return a list of all private tables not included
(added a TODO to check the --include-private opt):
```bash
Optimising module with wasm-opt...
Build finished successfully.
Skipping private tables during codegen: secret_note, secret_order, secret_person.
Generate finished successfully.
```

# API and ABI breaking changes

Technically API breaking as the private tables will no longer be
available. (GitHub labels are not working at the moment)

# Expected complexity level and risk

1 - Simple change the testing took longer

# Testing

Turns out when you remove private tables you invalidate most of the
module_bindings across the system!

- [x] Rust test SDK for all languages
- [x] C# SDK tests
- [x] C# dotnet tests
- [x] Updated and checked snap files
- [x] Updated Blackholio (Unreal + Unity) module_bindings and tested
- [x] Ran Unreal SDK tests

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
2026-02-12 03:08:54 +00:00
joshua-spacetime a78b056fcc Reorganize types generated for typescript clients (#4258)
NOTE: Cherry-picking
https://github.com/clockworklabs/SpacetimeDB/pull/4127 from the
`2.0-breaking-changes` branch.

## Original PR Description

This changes generated types in ts client bindings. We currently
generate a few different types of types: reducer args, procedure args,
rows, and user defined types. To avoid potential conflicts between these
types (for example, if a user defined a type called `FooRow`, and also
had a tabled named `foo`, we would end up with two types named
`FooRow`), this puts each set of types in a different file and
namespace. We also stopped exporting the `xxxRow` types, because there
is always another type generated for those. We now have a `types`
directory, which has an `index.ts` with user defined types, along with
`reducers.ts` and `procedures.ts` for the types generated for
reducer/procedure parameters.

```
import type * as Types from './module_bindings/types';

var currentMessages: Types.Message[] = [];
```

or

```
import { type Message } from './module_bindings/types';

var currentMessages: Message[] = [];
```

This has a couple other changes:
- For procedure and reducer types, this adds a suffix of `Args`, since
we may want types for the return values in the future.
- For all of the types, instead of exposing the schema object, we are
now giving the typescript type (e.g. `export type Message =
__Infer<typeof MessageRow>;`). I couldn't think of a reason for users to
want the schema object, so this should save users from needing to do all
of the `Infer` boilerplate.

This is a breaking change for v2.

2. This only changes typescript, and it should generally make thing
easier to use.

---------

Co-authored-by: Jeffrey Dallatezza <jeffreydallatezza@gmail.com>
2026-02-11 15:51:16 +00:00
Jason Larabie 52b6c66fa1 Add C++ Bindings (#3544)
# Description of Changes

This adds C++ server bindings (/crate/bindings-cpp) to allow writing C++
20 modules.

- Emscripten WASM build system integration with CMake
- Macro-based code generation (SPACETIMEDB_TABLE, SPACETIMEDB_REDUCER,
etc)
- All SpacetimeDB types supported (primitives, Timestamp, Identity,
Uuid, etc)
- Product types via SPACETIMEDB_STRUCT
- Sum types via SPACETIMEDB_ENUM
- Constraints marked with FIELD* macros

# API and ABI breaking changes

None

# Expected complexity level and risk

2 - Doesn't heavily impact any other areas but is complex macro C++
structure to support a similar developer experience, did have a small
impact on init command

# Testing

- [x] modules/module-test-cpp - heavily tested every reducer
- [x] modules/benchmarks-cpp - tested through the standalone (~6x faster
than C#, ~6x slower than Rust)
- [x] modules/sdk-test-cpp
- [x] modules/sdk-test-procedure-cpp
- [x] modules/sdk-test-view-cpp  
- [x] Wrote several test modules myself
- [x] Quickstart smoketest [Currently in progress]
- [ ] Write Blackholio C++ server module

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-02-07 04:26:45 +00:00
Jeffrey Dallatezza 9989416cd3 Update view ABI to support returning queries (#3685)
# Description of Changes

This adds some changes for how we return data from view functions.
Originally, we interpreted the output of a view function as a bsatn
encoding of an array of rows. Since we also want to be able to return
queries from view functions, we need to be able to return different
types too. At this point, this is effectively not a functional change,
since we don't use the new format, and we don't actually try to parse
the new format.

This introduces a new format for view returns, which is a
`ViewResultHeader`, potentially followed by additional data. For
example, if a view were returning rows directly, it would write a
`ViewResultHeader::RowData`, followed by an array of rows. Note that we
could have given that object a byte array with the rows instead of using
a header an a separate object, but that would force us create an extra
copy when encoding and when decoding.

To make this backward compatible with existing views, we have a
different way to return the new format. For v8 views, if they return a
byte array, we assume it is the old format. If they return an object, we
expect the `data` field of that object to be the actual return data.

For wasm views, we interpret a return code of 2 to mean that it uses the
new format.

On the host side, we handle this naively: we will perform the query, and
we will act as though the view has a read dependency on the tables in
the query. In follow up PRs we can make this more efficient.

# API and ABI breaking changes

This is not a breaking change, but it does make the ABI more complicated
(specifically to avoid breaking it).

# Expected complexity level and risk

1.5. This should not affect the existing return style.

# Testing

I've done manual testing of this with a version of the typescript
bindings that returns queries.
2025-12-03 19:56:41 +00:00
Noa cb3ac50bdf [TS] Http procedure API (#3731)
# Description of Changes

Provides a fetch-alike API on `ctx.http`. I guess it could just be
`ctx.fetch()` instead of `ctx.http.fetch()`, but I'm not sure if that's
a good idea.

# Expected complexity level and risk

2

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Need to verify that this actually works
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->
2025-11-25 01:26:27 +00:00
Tyler Cloutier ce543854e9 Unifies server module library and client SDK for TypeScript (and fixes several bugs) (#3559)
# Description of Changes

This PR is a very large change to the workings of the TypeScript SDK and
as such requires a higher bar of testing than other PRs. However, it
does several important things:

1. Unifies the API of the server and client so they not only have the
same API, but they actually implement it with the same TypeScript types.
This fixes several inconsistencies between them and fixes several small
bugs as well.
2. Closes https://github.com/clockworklabs/SpacetimeDB/issues/3365
3. Closes https://github.com/clockworklabs/SpacetimeDB/issues/3431
4. Closes https://github.com/clockworklabs/SpacetimeDB/issues/3435
5. Subsumes the work done in
https://github.com/clockworklabs/SpacetimeDB/pull/3447
6. Derives all type information on the client from a single
`RemoteModule` type which vastly cleans up the correctness of type
checking on the client and helped me to find several small bugs

It accomplishes this by changing code generation of TypeScript on the
client to code generation approximately what a developer would manually
write in their module. The ultimate goal would be to allow the developer
to use the types and functions that they define on in their module
directly on the client without needing to do any code generation at all,
provided they are using TypeScript on the server and client.

https://github.com/clockworklabs/SpacetimeDB/issues/3365 is resolved by
`.build()`ing the `DbConnection` inside a React `useEffect` rather than
doing it directly in line with the render of the provider. In order to
do that we needed to not expose the `DbConnection` directly to
developers by returning a different type from `useSpacetimeDB`.
`useSpacetimeDB` now returns a `ConnectionState` object which is stored
as React state and updates when any of the fields change. This change
also resolves https://github.com/clockworklabs/SpacetimeDB/issues/3431.

https://github.com/clockworklabs/SpacetimeDB/issues/3435 was the issue
that initially lead me down the rabbit hole of unifying the server and
the client because it was nearly impossible to track down all the
various type functions and how they connect to the values that we code
generate on the server. After several hours of attempting this, I
decided to clean up the types a bit to be more uniform.

Implementing the unification between the client and the server also
necessitated fully implemented parts of the API that were fully
implemented on the server, but were broken or missing on the client.

# API and ABI breaking changes

[Unification] -> Means that this is breaking behavior for the client
SDK, but that the new behavior is identical to the server's existing
behavior

## Breaking changes:

- Table accessor names and index accessor names are converted to
camelCase on the `ctx`, so `ctx.db.foo_bar` is now `ctx.db.fooBar`

- [Unification] On the client `my_table.iter()` returns
`IterableIterator` instead of an `Array`
- [Unification] `module_bindings` now export `TypeBuilder`s for all
types instead of a `type MyType` and object `MyType`, so instead of
using `MyType` as a type directly, you need to infer the type `MyType`
-> `Infer<typeof MyType>`.
- [Unification] We no longer generate and export `MyTypeVariants` for
sum types (these are now accessed by `Infer<typeof
MyType.variants.myVariant>`)
- [Unification] `MyType.getTypeScriptAlgebraicType()` has been replaced
with `MyType.algebraicType`

- `useSpacetimeDB()` no longer takes type parameters
- `useTable()` now takes a `TableDef` parameter and type params are
inferred
- `useTable()` now just returns an `Array` directly instead of a object
with `{ rows }`

- [Unification] `ctx.reducers.createPlayer(argA, argB)` ->
`ctx.reducers.createPlayer({ argA, argB })`
- [Unification] `ctx.reducers.onCreatePlayer(ctx, argA, argB)` ->
`ctx.reducers.onCreatePlayer(ctx, { argA, argB })`
- [Unification] `ctx.reducers.removeOnCreatePlayer(ctx, argA, argB)` ->
`ctx.reducers.removeOnCreatePlayer(ctx, { argA, argB })`
- [Unification] `myTable.count(): number` -> `myTable.count(): bigint`
 
## Additive changes:
- `Infer<>` now also does `InferTypeOfRow<>` if applicable
- Added a `useReducer()` React hook
- `module_bindings` now exports a `tables` object with references to all
the `TableDef`s
- `module_bindings` now exports a `reducers` object with references to
all the `ReducerDef`s
- Added a new `MyType.create('MyVariant', ...)` function in addition to
the `MyType.MyVariant(...)` constructors (this is private)

## Notable things that did not change:
- `MyType.serialize(writer: BinaryWriter, value: Infer<typeof MyType>)`
and `MyType.deserialize(reader: BinaryReader): Infer<typeof MyType>` are
still supported exactly as before.
- The `MyType.MyVariant(...)` constructor function on sum types is still
present, but implemented with the private `MyType.create('MyVariant',
...)`. We could choose to move away from this API later if we didn't
like the variants polluting the namespace


# Expected complexity level and risk

4 - This is a deep reaching an complex change for the SDK. For the
server, it is much less deep reaching since it reuses much of the same
machinery, although it does require thorough testing there as some of
the code was modified.

This change is fully localized to TypeScript and does not touch the host
(or other languages) at all, and therefore only impacts a beta aspect of
SpacetimeDB.

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [ ] Added regression test for
https://github.com/clockworklabs/SpacetimeDB/issues/3435
- [x] Manually tested `test-app` and `test-react-router-app`
- [ ] Add test cases for camelCase-ing

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Noa <coolreader18@gmail.com>
2025-11-19 02:53:41 +00:00
Tyler Cloutier 58d299ea42 Removed @clockworklabs/typescript-sdk in favor of spacetimedb (#3262)
# Description of Changes

This PR removes the `@clockworklabs/typescript-sdk` from the repository
and retains only `spacetimedb` in the `crates/bindings-typescript`
directory. Some files are migrated to `spacetimedb`. I have also updated
the appropriate READMEs.

In addition I have symlinked the old `sdks/typescript` directory to
point to `crates/bindings-typescript`.

# API and ABI breaking changes

This is not technically a breaking change of any kind, although it does
orphan and deprecate the
[@clockworklabs/spacetimedb-sdk](https://www.npmjs.com/package/@clockworklabs/spacetimedb-sdk)
npm package. This package will no longer work with SpacetimeDB.

Users should now install and use the `spacetimedb` package.

# Expected complexity level and risk

2, it's a straightforward change but affects many files.

# Testing

- [ ] I ran `pnpm test` in the `spacetimedb` package
- [ ] I ran the quickstart app

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2025-09-23 00:25:24 +00:00
Tyler Cloutier c83f55f65e Refactors TypeScript into a single spacetimedb package (#3248)
# Description of Changes

This PR moves most of the contents of `@clockworklabs/spacetimedb-sdk`
into the `spacetimedb` module. The `spacetimedb` module now exports
`sdk` and `server` as separate subpaths where `sdk` contains the code
which was previously in `@clockworklabs/spacetimedb-sdk`.

In particular it makes the following moves:

- `/sdks/typescript/packages/sdk` -> `/sdks/typescript`
- most of the contents of `/sdks/typescript/packages/sdk` ->
`crates/bindings-typescript`
- `/sdks/typescript/packages/test-app` ->
`crates/bindings-typescript/test-app`

The following packags was NOT moved:

`/sdks/typescript/examples/quickstart-chat`

## Motivation

In accordance with
https://github.com/clockworklabs/SpacetimeDB/issues/3250, we would like
to consolidate `@clockworklabs/spacetimedb-sdk` into a single
`spacetimedb` package so that users can import the different things they
need from a single package.

### Pros:
- allow users to install a single package with subpaths `spacetimedb`,
`spacetimedb/react`, `spacetimedb/sdk`, `spacetimedb/server`, etc.
- Is much simpler for bundling, etc.
- Is backwards compatible with `@clockworklabs/spacetimedb-sdk` which
now becomes a thin wrapper
- eventually allow us to break up the `spacetimedb` package into other
packages if we want to split them up (e.g. `@spacetimedb/lib`,
`@spacetimedb/sdk`, etc.) and we can solve the build complexity that
introduces when we get to it
- eventually allow us to move `bindings-csharp` out of the crates
directory where it probably doesn't belong anyway
- organizes all TypeScript packages into the packages directory where
you'd normally expect them, with the possible exception of
`/sdks/typescript` if we wanted to leave that separate

### Cons:
- The `sdk` directory is now a bit of a ruse as to where the code
actually lives since it's just a thin wrapper. If it eventually becomes
its own independent package, we'll also have to break up spacetimedb
into `@spacetimedb/lib` and `@spacetimedb/server` so that
`@clockworklabs/spacetimedb-sdk` can depend on `@spacetimedb/lib` while
being a dependency of `spacetimedb`.

Ideally this change would have been made later, however, it became
necessary for the following **heinously disastrous chain of forcing
moves**:

1. Adding `react` support necessitated shipping react as an optional
peer dependency under `@clockworklabs/spacetimedb-sdk/react`
2. This required adding a new build target/export/bundle
3. Previously `@clockworklabs/spacetimedb-sdk` was configured to have
`noExternal` for `spacetimedb` meaning it would collect the library into
the sdk bundle. I attempted to continue this for react support but...
4. Creating a new `react` bundle which also pulled in `spacetimedb`
caused their to be nominal type conflicts between classes in the
duplicate `spacetimedb` bundles.
5. Changing `spacetimedb` to be included as `external` caused compile
errors because `@clockworklabs/spacetimedb-sdk` is configured in
`tsconfig.json` to fail on unused variables and it was now including the
source of `spacetimedb` which is not configured to error on unused
variables and has "unused" private variables which are actually used by
us secretly, but not exposed to the clients.
> SIDE NOTE: The unused variables settings cannot be turned off on a
line by line basis, so it has to be turned off entirely, but in order to
maintain the linting checks we had I used `eslint` to enforce the rule
so that we could disable it line by line. (This caused me to discover
quite a lot of things that were broken that were caught by `eslint`
being applied to the entire project. `eslint` was previously only
applied to the `quickstart-chat` and the `crates/bindings-typescript`
library)
6. Changing the build to be external, now requires `spacetimedb` to also
be published to npm as its own module which
`@clockworklabs/spacetimedb-sdk` now imports, which requires that we add
`tsup` config to `spacetimedb` to publish a built version of the
library.
7. The only way to avoid that is to move the `sdk` and `react` code from
`@clockworklabs/spacetimedb-sdk` into the existing `spacetimedb` package
to avoid the duplicate import problem on step 4 and change
`@clockworklabs/spacetimedb-sdk` back to again use `noExternal` for its
`spacetimedb` dependency.

And here we are. I chose not to move `/crates/bindings-typescript` even
though that's probably not a great place long term. It would be better
to have it in `/packages/spacetimedb` or `/npm-packages/spacetimedb` or
`/ts-packages/spacetimedb` or something, and move all our TypeScript
packages in there. But that is a different matter.

The net result however is that we have a new `spacetimedb` package which
exports the different parts of the API under:

- `spacetimedb`
- `spacetimedb/server`
- `spacetimedb/sdk`
- `spacetimedb/react`

while still not breaking the existing deploy process, nor any
users/developers who are currently using
`@clockworklabs/spacetimedb-sdk`.

I think long term should we ever decide to split `spacetimedb` up into
multiple packages or if we have additional unrelated packages, we should
publish them to the `@spacetimedb` org which I reserved for us here:

https://www.npmjs.com/org/spacetimedb

> NOTE: `spacetimedb` is a package and `@spacetimedb` is an org.
`spacetimedb/sdk` is not a separate package, it's a subpath export of
the `spacetimedb` package, whereas `@spacetimedb/sdk` would be (and
would need to be) it's own separate package. You can certainly have both
`spacetimedb/sdk` and `@spacetimedb/sdk`. We could for example host the
code for the sdk at `@spacetimedb/sdk` and just reexport it from
`spacetimedb` under the `spacetimedb/sdk` subpath.

# API and ABI breaking changes

This should not change or modify the API or ABI in any way. If it does
so accidentally it is a bug, although I carefully went through the
exports.

# Expected complexity level and risk

3 because it changes how the SDK is built a bit and rearranges a lot of
paths.

# Testing

- [x] All of the CI passes
- [x] I also ran quickstart-chat to confirm that it is not broken
- [x] I also ran test-app
2025-09-19 19:33:45 +00:00
Tyler Cloutier df82bd8f46 Removed // @ts-ignore directive from generated files and fixes associated errors (#3228)
# Description of Changes

Previously all TypeScript generated code had a `// @ts-ignore` directive
at the top to suppress unused variable errors that users may have run
into with their generated code. This worked to suppress unused, but it
was too broad and suppressed actual errors with our generated code. This
PR removes that directive and fixes the latent errors.

Most notably this fixes the issue in the quickstart where we were
getting `serialize` is not a function.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] This PR increases the test surface only by now typechecking the
typescript generated code within our repository
2025-09-05 14:47:12 +00:00
Tyler Cloutier 5901fb5063 Separate out TypeScript module library from the SDK (#3182)
# Description of Changes

Please note, much of the code changed in this PR is generated code.

This change updates the TypeScript SDK to use a new `spacetimedb`
TypeScript library which lives under the `/crates/bindings-typescript`
folder alongside `/crates/bindings-csharp`. Just like with the C#
bindings library, the types for `AlgebraicType` and `RawModuleDef` are
now code generated with a script in `/crates/codegen/examples`.

Pulling this out into a library allows us to use the same types and
serialization code on both the server and the client for TypeScript
modules.

In the process of making this change I also found and fixed several
issues with the TypeScript code generation. Namely an issue with
recursive types and an issue with the `never` type. I also removed any
use of `namespace`s since those are a TypeScript only feature, and we
want to have JavaScript + types so that we can use the generated code
with ESBuild without TSC.

I have also improved the npm/pnpm scripts to be able to generate
TypeScript code for us automatically by running `pnpm generate` for any
place that we have to generate typescript code. Namely:

- Quickstart module bindings
- AlgebraicType/ModuleDef for TypeScript module library
- Client API messages for the TypeScript API
- TestApp module bindings

# API and ABI breaking changes

IMPORTANT! This is an API breaking change for clients, as such it should
be a major version change. However, I am going to see if I can shim in
the old API as best as possible to make it compatible.

Notably, we were previously exporting APIs that end users do not need,
and I don't think it would ever occur to them to use, namely the whole
`AlgebraicValue` API and also the `AlgebraicType` API. In principle, no
one should have a need for these, although it was technically possible
for them to use it.

Indeed, we could potentially even just remove AlgebraicType completely
from the API by directly code generating the serialization code.

Listed below are all of the **BREAKING** changes to the API and their
effect:

- `AlgebraicType` is now a structural union literal type instead of a
class (nominal type), this is a consequence of generating the type with
our code gen. Users did not have a reason to use `AlgebraicType`
directly.
- The `AlgebraicValue` type has been removed entirely. This was
previously a class that was exported from the SDK, but very unlikely to
be used by users.
- The `ProductValue` type has been removed.
- The `ReducerArgsAdapter` and `ValueAdapter` types, which were used
with AlgebraicValues have been removed.
- Generated code has changed incompatibly so users will have to
regenerate code when upgrading to this version. Technically a breaking
change, but pretty easy to fix.

Listed below are the non-breaking API changes:
- I am now exporting generated product types as the default export in
addition to how I was exporting them before
- For generated sum type `T`, I am now exporting a `TVariants` namespace
which has the types of all the variants for `T`. This was previously
exposed on the namespace `T`, but was inaccessible in modules other than
the one it was defined in because I also export a type `T` in addition
to namespace `T` and in the type position `T` was being interpreted as a
type rather than a namespace. It's unclear why TypeScript resolved it as
the `T` namespace within the module in which is was defined previously.
Anyway, since the old types were apparently unobservable to users, I've
replaced them with the types in `TVariants`. (Open to other names for
this namespace).
- I fixed a bug where never types (sum types with no variants) were not
correctly generated.

# Expected complexity level and risk

3. The most complex thing about the PR are the potential impacts to the
API. I am reasonably certain, but not 100% certain that I have accounted
for everything above.

# Testing

- [x] I ran `pnpm test` which runs all the tests in the repo including
an integration test which tests the connection to SpacetimeDB. I also
fixed broken tests.

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2025-09-03 21:12:14 +00:00
Noa 020d64c1f1 Split client codegen out into its own crate (#2593)
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2025-04-29 17:54:25 +00:00