Skip to content

Make accessor required for table-level index defs in typescript#4525

Merged
clockwork-labs-bot merged 8 commits intomasterfrom
joshua/fix/ts-index-accessor
Mar 3, 2026
Merged

Make accessor required for table-level index defs in typescript#4525
clockwork-labs-bot merged 8 commits intomasterfrom
joshua/fix/ts-index-accessor

Conversation

@joshua-spacetime
Copy link
Collaborator

@joshua-spacetime joshua-spacetime commented Mar 3, 2026

Description of Changes

This patch contains two main changes:

  1. It makes accessor a required argument for table-level index defs in typescript to align with rust.

  2. It removes unsound index typing in the TypeScript bindings by splitting index data into two explicit representations:

    • indexes: declarative user config (IndexOpts) used for type inference
    • resolvedIndexes: normalized runtime metadata (UntypedIndex) derived from RawTableDefV10

    TableCacheImpl now builds index accessors from resolvedIndexes instead of re-casting indexes at runtime.

    This addressed the following comment:

    // TODO: horrible horrible horrible. we smuggle this `Array<UntypedIndex>`
    // by casting it to an `Array<IndexOpts>` as `TableToSchema` expects.
    // This is then used in `TableCacheImpl.constructor` and who knows where else.
    // We should stop lying about our types.
    

    Why?

    We were conflating two different concepts under tableDef.indexes:

    1. declared table-level index options authored by users
    2. resolved runtime index definitions (including field-level inferred indexes)

    This required unsafe casts (T['idxs'] / UntypedIndex) and made the type model unsound.

Note, (2) was largely ai assisted.

API and ABI breaking changes

Technically breaks the module api, although I believe this is the behavior that is outlined in the spec, and so the current behavior should really be considered a bug.

Expected complexity level and risk

2

Testing

Added unit tests covering the following:

  1. Table-level explicit index without accessor throws.
  2. Table-level duplicate accessor throws.
  3. Table-level explicit accessor is accepted and used.
  4. Field-level .index(...) derives accessor from the field name (displayName).

@joshua-spacetime joshua-spacetime changed the title Make accessor required for table-level index defs in typescript Make accessor required for table-level index defs in typescript Mar 3, 2026
@joshua-spacetime joshua-spacetime linked an issue Mar 3, 2026 that may be closed by this pull request
@joshua-spacetime
Copy link
Collaborator Author

@Shubham8287 has approved (1). I've added @coolreader18 for review of (2).

@clockwork-labs-bot clockwork-labs-bot added this pull request to the merge queue Mar 3, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 3, 2026
@clockwork-labs-bot clockwork-labs-bot added this pull request to the merge queue Mar 3, 2026
Merged via the queue into master with commit 33f3ea1 Mar 3, 2026
32 of 33 checks passed
@joshua-spacetime joshua-spacetime added the api-break A PR that makes an API breaking change label Mar 3, 2026
Centril pushed a commit that referenced this pull request Mar 3, 2026
)

# Description of Changes

This patch contains two main changes:

1. It makes `accessor` a required argument for table-level index defs in
typescript to align with rust.

2. It removes unsound index typing in the TypeScript bindings by
splitting index data into two explicit representations:

- `indexes`: declarative user config (`IndexOpts`) used for type
inference
- `resolvedIndexes`: normalized runtime metadata (`UntypedIndex`)
derived from `RawTableDefV10`

`TableCacheImpl` now builds index accessors from `resolvedIndexes`
instead of re-casting `indexes` at runtime.

    This addressed the following comment:
    ```
// TODO: horrible horrible horrible. we smuggle this
`Array<UntypedIndex>`
// by casting it to an `Array<IndexOpts>` as `TableToSchema` expects.
// This is then used in `TableCacheImpl.constructor` and who knows where
else.
    // We should stop lying about our types.
    ```

    > Why?

    We were conflating two different concepts under `tableDef.indexes`:

      1. declared table-level index options authored by users
2. resolved runtime index definitions (including field-level inferred
indexes)

This required unsafe casts (`T['idxs']` / `UntypedIndex`) and made the
type model unsound.

Note, (2) was largely ai assisted.

# API and ABI breaking changes

Technically breaks the module api, although I believe this is the
behavior that is outlined in the spec, and so the current behavior
should really be considered a bug.

# Expected complexity level and risk

2

# Testing

Added unit tests covering the following:
1. Table-level explicit index without accessor throws.
2. Table-level duplicate accessor throws.
3. Table-level explicit accessor is accepted and used.
4. Field-level `.index(...)` derives accessor from the field name
(`displayName`).
github-merge-queue bot pushed a commit that referenced this pull request Mar 4, 2026
# Description of Changes

Make `Accessor` a required argument for table-level index defs in C# to
align with rust and typescript. The same change was done for typescript
in #4525.

# API and ABI breaking changes

Technically breaks the module api, although I believe this is the
behavior that is outlined in the spec, and so the current behavior
should really be considered a bug.

# Expected complexity level and risk

1

# Testing

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

Labels

api-break A PR that makes an API breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError in makeTableView due to 'filter' property conflict

3 participants