Skip to content

Make indexing opt-in#1353

Merged
kevin-dp merged 26 commits intomainfrom
indexing-renaming
Mar 24, 2026
Merged

Make indexing opt-in#1353
kevin-dp merged 26 commits intomainfrom
indexing-renaming

Conversation

@kevin-dp
Copy link
Contributor

@kevin-dp kevin-dp commented Mar 11, 2026

Summary

Makes indexing explicit and opt-in rather than automatic, allowing users to choose the right index type for their use case and enabling better tree-shaking.

Based on #950 with the ReadOptimizedIndex/WriteOptimizedIndex renaming reverted — keeps the original BasicIndex/BTreeIndex names.

Key changes

  • autoIndex now defaults to off instead of eager
  • To use createIndex() or autoIndex: 'eager', you must set defaultIndexType on the collection
  • Dev mode suggestions warn when indexes would help

Bundle size impact

  • No indexing: ~30% smaller bundle
  • BasicIndex only: ~5 KB (~1.3 KB gzipped)
  • BTreeIndex: ~33 KB (~7.8 KB gzipped)

Test plan

  • Build passes
  • All 2033 tests pass
  • Tests updated to set defaultIndexType where needed

🤖 Generated with Claude Code

@changeset-bot
Copy link

changeset-bot bot commented Mar 11, 2026

🦋 Changeset detected

Latest commit: 914c31a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@tanstack/db Minor
@tanstack/angular-db Patch
@tanstack/electric-db-collection Patch
@tanstack/offline-transactions Patch
@tanstack/powersync-db-collection Patch
@tanstack/query-db-collection Patch
@tanstack/react-db Patch
@tanstack/rxdb-db-collection Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db Patch
todos Patch
@tanstack/db-example-paced-mutations-demo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@kevin-dp kevin-dp mentioned this pull request Mar 11, 2026
@kevin-dp kevin-dp force-pushed the indexing-renaming branch 2 times, most recently from 8c77252 to b011fe2 Compare March 11, 2026 13:42
- Make indexing explicit with BasicIndex and BTreeIndex
- autoIndex defaults to 'off', dev mode suggestions warn when indexes would help
- New @tanstack/db/indexing entry point for tree-shakeable indexing
- BasicIndex: lightweight Map + sorted Array for equality and range queries
- BTreeIndex: full-featured O(log n) index for large collections
- Fix pagination when indexes aren't available
- Remove docs folder (now CI-generated)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kevin-dp kevin-dp force-pushed the indexing-renaming branch from b011fe2 to 9c047aa Compare March 11, 2026 13:45
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 11, 2026

More templates

@tanstack/angular-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/angular-db@1353

@tanstack/db

npm i https://pkg.pr.new/TanStack/db/@tanstack/db@1353

@tanstack/db-browser-wa-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-browser-wa-sqlite-persisted-collection@1353

@tanstack/db-capacitor-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-capacitor-sqlite-persisted-collection@1353

@tanstack/db-cloudflare-do-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-cloudflare-do-sqlite-persisted-collection@1353

@tanstack/db-electron-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-electron-sqlite-persisted-collection@1353

@tanstack/db-expo-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-expo-sqlite-persisted-collection@1353

@tanstack/db-ivm

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-ivm@1353

@tanstack/db-node-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-node-sqlite-persisted-collection@1353

@tanstack/db-react-native-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-react-native-sqlite-persisted-collection@1353

@tanstack/db-sqlite-persisted-collection-core

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-sqlite-persisted-collection-core@1353

@tanstack/db-tauri-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-tauri-sqlite-persisted-collection@1353

@tanstack/electric-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/electric-db-collection@1353

@tanstack/offline-transactions

npm i https://pkg.pr.new/TanStack/db/@tanstack/offline-transactions@1353

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/powersync-db-collection@1353

@tanstack/query-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/query-db-collection@1353

@tanstack/react-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/react-db@1353

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/rxdb-db-collection@1353

@tanstack/solid-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/solid-db@1353

@tanstack/svelte-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/svelte-db@1353

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/trailbase-db-collection@1353

@tanstack/vue-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/vue-db@1353

commit: 9681751

@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

Size Change: +1.53 kB (+1.38%)

Total Size: 112 kB

Filename Size Change
./packages/db/dist/esm/collection/index.js 3.61 kB -95 B (-2.56%)
./packages/db/dist/esm/collection/indexes.js 1.99 kB -357 B (-15.22%) 👏
./packages/db/dist/esm/collection/lifecycle.js 1.69 kB -66 B (-3.76%)
./packages/db/dist/esm/collection/subscription.js 3.74 kB +34 B (+0.92%)
./packages/db/dist/esm/index.js 2.98 kB +124 B (+4.34%)
./packages/db/dist/esm/indexes/auto-index.js 830 B +53 B (+6.82%) 🔍
./packages/db/dist/esm/indexes/base-index.js 729 B -37 B (-4.83%)
./packages/db/dist/esm/indexes/basic-index.js 2.05 kB +2.05 kB (new file) 🆕
./packages/db/dist/esm/indexes/index-registry.js 820 B +820 B (new file) 🆕
./packages/db/dist/esm/indexes/lazy-index.js 0 B -1.24 kB (removed) 🏆
./packages/db/dist/esm/query/builder/functions.js 771 B -21 B (-2.65%)
./packages/db/dist/esm/query/compiler/order-by.js 1.51 kB -4 B (-0.26%)
./packages/db/dist/esm/utils/array-utils.js 273 B +273 B (new file) 🆕
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection/change-events.js 1.39 kB
./packages/db/dist/esm/collection/changes.js 1.38 kB
./packages/db/dist/esm/collection/cleanup-queue.js 810 B
./packages/db/dist/esm/collection/events.js 434 B
./packages/db/dist/esm/collection/mutations.js 2.47 kB
./packages/db/dist/esm/collection/state.js 5.26 kB
./packages/db/dist/esm/collection/sync.js 2.88 kB
./packages/db/dist/esm/collection/transaction-metadata.js 144 B
./packages/db/dist/esm/deferred.js 207 B
./packages/db/dist/esm/errors.js 4.83 kB
./packages/db/dist/esm/event-emitter.js 748 B
./packages/db/dist/esm/indexes/btree-index.js 2.17 kB
./packages/db/dist/esm/indexes/reverse-index.js 538 B
./packages/db/dist/esm/local-only.js 890 B
./packages/db/dist/esm/local-storage.js 2.1 kB
./packages/db/dist/esm/optimistic-action.js 359 B
./packages/db/dist/esm/paced-mutations.js 496 B
./packages/db/dist/esm/proxy.js 3.75 kB
./packages/db/dist/esm/query/builder/index.js 5.15 kB
./packages/db/dist/esm/query/builder/ref-proxy.js 1.05 kB
./packages/db/dist/esm/query/compiler/evaluators.js 1.62 kB
./packages/db/dist/esm/query/compiler/expressions.js 430 B
./packages/db/dist/esm/query/compiler/group-by.js 2.69 kB
./packages/db/dist/esm/query/compiler/index.js 3.62 kB
./packages/db/dist/esm/query/compiler/joins.js 2.11 kB
./packages/db/dist/esm/query/compiler/select.js 1.11 kB
./packages/db/dist/esm/query/effect.js 4.78 kB
./packages/db/dist/esm/query/expression-helpers.js 1.43 kB
./packages/db/dist/esm/query/ir.js 784 B
./packages/db/dist/esm/query/live-query-collection.js 360 B
./packages/db/dist/esm/query/live/collection-config-builder.js 7.63 kB
./packages/db/dist/esm/query/live/collection-registry.js 264 B
./packages/db/dist/esm/query/live/collection-subscriber.js 1.94 kB
./packages/db/dist/esm/query/live/internal.js 145 B
./packages/db/dist/esm/query/live/utils.js 1.57 kB
./packages/db/dist/esm/query/optimizer.js 2.62 kB
./packages/db/dist/esm/query/predicate-utils.js 2.97 kB
./packages/db/dist/esm/query/query-once.js 359 B
./packages/db/dist/esm/query/subset-dedupe.js 960 B
./packages/db/dist/esm/scheduler.js 1.3 kB
./packages/db/dist/esm/SortedMap.js 1.3 kB
./packages/db/dist/esm/strategies/debounceStrategy.js 247 B
./packages/db/dist/esm/strategies/queueStrategy.js 428 B
./packages/db/dist/esm/strategies/throttleStrategy.js 246 B
./packages/db/dist/esm/transactions.js 2.9 kB
./packages/db/dist/esm/utils.js 927 B
./packages/db/dist/esm/utils/browser-polyfills.js 304 B
./packages/db/dist/esm/utils/btree.js 5.61 kB
./packages/db/dist/esm/utils/comparison.js 1.05 kB
./packages/db/dist/esm/utils/cursor.js 457 B
./packages/db/dist/esm/utils/index-optimization.js 1.54 kB
./packages/db/dist/esm/utils/type-guards.js 157 B
./packages/db/dist/esm/virtual-props.js 360 B

compressed-size-action::db-package-size

@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

Size Change: 0 B

Total Size: 4.23 kB

ℹ️ View Unchanged
Filename Size
./packages/react-db/dist/esm/index.js 249 B
./packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.32 kB
./packages/react-db/dist/esm/useLiveQuery.js 1.34 kB
./packages/react-db/dist/esm/useLiveQueryEffect.js 355 B
./packages/react-db/dist/esm/useLiveSuspenseQuery.js 559 B
./packages/react-db/dist/esm/usePacedMutations.js 401 B

compressed-size-action::react-db-package-size

Tests added on main were calling createIndex() or using autoIndex: 'eager'
without setting defaultIndexType, which is now required.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kevin-dp kevin-dp changed the title Revert BasicIndex/BTreeIndex renaming Make indexing opt-in Mar 11, 2026
@KyleAMathews
Copy link
Collaborator

PR Review Summary

Overall this is a well-designed simplification. Replacing IndexResolver (sync + async union) with IndexConstructor eliminates the 3-state lifecycle and ~250 lines of LazyIndexWrapper/IndexProxy. The tree-shaking story via @tanstack/db/indexing is clean. A few issues worth addressing before merge:


Critical

autoIndex: 'eager' without defaultIndexType silently does nothing in production
packages/db/src/indexes/auto-index.ts:18-27 — When a user explicitly requests autoIndex: 'eager' but forgets defaultIndexType, the console.warn is gated behind isDevModeEnabled() which returns false in production. The function silently returns false and indexing never happens — no error, no warning.

This is a deliberately-requested feature that silently degrades. Consider throwing CollectionConfigurationError at collection construction time (packages/db/src/collection/index.ts:~322) when this invalid configuration is detected:

if (config.autoIndex === 'eager' && !config.defaultIndexType) {
  throw new CollectionConfigurationError(
    `autoIndex: 'eager' requires defaultIndexType to be set. ` +
    `Import an index type and set it:\n` +
    `  import { BasicIndex } from '@tanstack/db/indexing'\n` +
    `  createCollection({ defaultIndexType: BasicIndex, autoIndex: 'eager', ... })`
  )
}

Important

  1. emitIndexSuggestion doesn't protect against onSuggestion callback errorspackages/db/src/indexes/index-registry.ts:76-77. User-provided callback is called without try-catch. A buggy callback could crash query execution with a confusing stack trace.

  2. BasicIndex.remove() swallows errors, leaving index inconsistentpackages/db/src/indexes/basic-index.ts:113-123. When evaluateIndexExpression throws during removal, the catch block returns without cleaning up indexedKeys, leaving phantom keys in the index. Should at minimum call this.indexedKeys.delete(key) in the catch block.

  3. createIndex throws generic Error instead of CollectionConfigurationErrorpackages/db/src/collection/indexes.ts:65-71. The project has a well-established error hierarchy; this should use CollectionConfigurationError to match the pattern and let users catch it with instanceof.


Suggestions

  • Type-level enforcement of autoIndex + defaultIndexType coupling — Currently { autoIndex: 'eager', defaultIndexType: undefined } compiles without error. A discriminated union config type could catch this at compile time:

    | { autoIndex?: 'off'; defaultIndexType?: IndexConstructor<TKey> }
    | { autoIndex: 'eager'; defaultIndexType: IndexConstructor<TKey> }
  • BasicIndex error re-throws lose original stack tracebasic-index.ts:82-86, 162-165. Using { cause: error } would preserve the original stack for debugging.

  • setSizeCallback is now set unconditionally in order-by.ts:282-288. Previously only set when an index existed. In the no-index path, loadNextItems calls requestSnapshot with a fixed limit, but there's no deduplication guard (the pendingOrderedLoadPromise only covers the indexed path). Could cause repeated identical snapshot requests.


Test Coverage Gaps

Priority Gap
1 createIndex() error when no defaultIndexType and no explicit indexType — not tested
2 autoIndex: 'eager' without defaultIndexType behavior — not tested
3 Dev mode suggestion system (index-registry.ts, 170 lines) — zero test coverage
4 BasicIndex (503 lines, recommended default) — no dedicated tests

Strengths

  • Excellent architectural simplification — single indexes map replaces the dual lazyIndexes/resolvedIndexes maps
  • Clean entry point separation for tree-shaking (~30% smaller without indexing)
  • Actionable error messages in createIndex that tell users exactly what to import
  • Well-structured test updates with describe.each for both autoIndex modes

kevin-dp and others added 2 commits March 12, 2026 13:10
- Throw CollectionConfigurationError at construction when autoIndex: 'eager'
  is used without defaultIndexType (was silently degrading in production)
- Use CollectionConfigurationError instead of generic Error in createIndex
- Wrap onSuggestion callback in try-catch to prevent buggy callbacks from
  crashing query execution
- Clean up indexedKeys in BasicIndex.remove() catch block to prevent
  phantom keys when expression evaluation fails
- Preserve original stack traces with { cause: error } in BasicIndex
- Update tests to provide defaultIndexType where needed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Test that autoIndex: 'eager' without defaultIndexType throws
  CollectionConfigurationError at construction time
- Test that createIndex() without indexType or defaultIndexType throws
  CollectionConfigurationError

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kevin-dp
Copy link
Contributor Author

Addressed review feedback

Critical

  • autoIndex: 'eager' without defaultIndexType now throws at construction time (collection/index.ts) — instead of silently degrading in production, this now throws CollectionConfigurationError with an actionable message. The dead warning code in auto-index.ts was removed since it's no longer reachable.

Important

  1. emitIndexSuggestion callback errors (index-registry.ts) — wrapped onSuggestion callback in try-catch so a buggy callback can't crash query execution.
  2. BasicIndex.remove() phantom key cleanup (basic-index.ts) — when evaluateIndexExpression throws during removal, the catch block now calls this.indexedKeys.delete(key) and this.updateTimestamp() to keep the index consistent.
  3. createIndex error type (collection/indexes.ts) — changed from generic Error to CollectionConfigurationError to match the project's error hierarchy.

Suggestions

  • { cause: error } on re-throws (basic-index.ts) — added to both add() and build() error paths to preserve original stack traces.

Test coverage

  • Added test: autoIndex: 'eager' without defaultIndexType throws CollectionConfigurationError
  • Added test: createIndex() without indexType or defaultIndexType throws CollectionConfigurationError
  • Updated existing tests in query-while-syncing.test.ts and collection-change-events.test.ts to provide defaultIndexType where needed

Not addressed (needs discussion)

  • Type-level discriminated union for autoIndex + defaultIndexType — non-trivial config type change, runtime validation covers this now
  • setSizeCallback deduplication in no-index path — needs deeper investigation
  • Test coverage for dev mode suggestion system and BasicIndex — larger effort, tracked separately

kevin-dp and others added 14 commits March 12, 2026 15:37
CI will regenerate these docs files after merge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Index

Tests added on main use autoIndex: 'eager' but didn't set defaultIndexType,
which is now required after making indexing opt-in.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflicts between opt-in indexing (this branch) and main's
additions: virtual props, index metadata/events, collection-subscriber
refactoring, SQLite persistence, and includes subqueries.

Key conflict resolutions:
- Keep synchronous IndexConstructor approach, remove lazy-index.ts
- Add index metadata tracking and events to synchronous createIndex
- Add simplified removeIndex (accepts BaseIndex | number)
- Incorporate virtual props (WithVirtualProps, $synced, $origin, etc.)
- Take main's collection-subscriber refactoring (computeOrderedLoadCursor,
  trackBiggestSentValue, lastLoadRequestKey dedup)
- Fix Store.subscribe() return type usage in electric-db-collection
- Update tests for opt-in indexing (add defaultIndexType/autoIndex where needed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve conflicts between opt-in indexing (this branch) and main's
additions: virtual props, index metadata/events, collection-subscriber
refactoring, SQLite persistence, and includes subqueries.

Key conflict resolutions:
- Keep synchronous IndexConstructor approach, remove lazy-index.ts
- Add index metadata tracking and events to synchronous createIndex
- Add simplified removeIndex (accepts BaseIndex | number)
- Incorporate virtual props (WithVirtualProps, $synced, $origin, etc.)
- Take main's collection-subscriber refactoring (computeOrderedLoadCursor,
  trackBiggestSentValue, lastLoadRequestKey dedup)
- Fix Store.subscribe() return type usage in electric-db-collection
- Update tests for opt-in indexing (add defaultIndexType/autoIndex where needed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
….9.x

The Store.subscribe() API changed in @tanstack/store 0.9.x to return
a Subscription object with .unsubscribe() instead of a plain function.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Multi-Column OrderBy with Incremental Loading tests use orderBy +
limit which requires indexes for the incremental loading path. Add
autoIndex: 'eager' and defaultIndexType to the on-demand collections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…test

The test creates indexes without specifying an indexType. Add
defaultIndexType: BasicIndex to the collection config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All useLiveInfiniteQuery tests use orderBy + limit which requires
indexes for incremental loading. Add autoIndex: 'eager' to all
collection configs in the test file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BTreeIndex from @tanstack/db/indexing doesn't structurally match
IndexConstructor from @tanstack/db in CI builds due to cross-package
type resolution. Use 'as any' cast in test helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…raints

BaseIndex, IndexInterface, and BTreeIndex had TKey constrained to
string | number | undefined, but collection keys are always
string | number. This caused BTreeIndex to not be assignable to
IndexConstructor<string | number> in cross-package type checking.

Narrow TKey to string | number across the index hierarchy, matching
BasicIndex and ReverseIndex which already used this constraint.
Remove as-any casts that were working around the mismatch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… internals

Protected members break structural type compatibility across package
boundaries in TypeScript monorepos. When BaseIndex is resolved from
different module paths (source vs built .d.ts), protected members
make subclasses like BasicIndex/BTreeIndex not assignable to
IndexConstructor.

Change protected members to public (marked @internal via JSDoc) to
enable structural compatibility while preserving the intent that
these are implementation details.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ck/db

The separate /indexing entry point caused cross-package type
incompatibility: TypeScript could resolve BaseIndex through different
declaration paths (main entry vs /indexing entry), breaking protected
member structural checks in consuming packages.

Modern bundlers (Rollup, esbuild, Vite) tree-shake unused exports
effectively, so a separate entry point is unnecessary for bundle size.

Changes:
- Move all exports from src/indexing.ts into src/index.ts
- Remove src/indexing.ts
- Remove ./indexing from package.json exports map
- Remove indexing.ts from vite build entry points
- Update all imports from @tanstack/db/indexing to @tanstack/db
- Restore protected visibility on BaseIndex internals

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
autofix-ci bot and others added 7 commits March 24, 2026 13:05
The "should handle GC correctly when queries are ordered and have a
LIMIT" test uses orderBy + limit which requires indexes. Add
autoIndex: 'eager' and defaultIndexType: BTreeIndex to the collection
config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 6 collections (3 eager, 3 on-demand) need autoIndex + defaultIndexType
for tests that use orderBy + limit. Without indexes, the requestLimitedSnapshot
path throws "no index found", causing tests to hang until CI timeout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add autoIndex: 'eager' and defaultIndexType: BTreeIndex to the
createPersistedCollection helper used by all e2e test collections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add autoIndex: 'eager' and defaultIndexType: BTreeIndex to collection
configs across all e2e test suites that were missing it:

- browser-wa-sqlite persisted collection
- capacitor-sqlite persisted collection
- expo-sqlite persisted collection
- react-native-sqlite persisted collection
- tauri-sqlite persisted collection
- trailbase collection
- query-db-collection offline-refresh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The docs were accidentally deleted in this branch. Restore them
from main.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kevin-dp kevin-dp merged commit b65d8f7 into main Mar 24, 2026
7 checks passed
@kevin-dp kevin-dp deleted the indexing-renaming branch March 24, 2026 15:16
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.

2 participants