Skip to content

feat(plugins): offer Turso as its own engine and hold the count in docs - #2561

Merged
datlechin merged 1 commit into
mainfrom
docs/engine-count-source-of-truth
Aug 27, 2026
Merged

feat(plugins): offer Turso as its own engine and hold the count in docs#2561
datlechin merged 1 commit into
mainfrom
docs/engine-count-source-of-truth

Conversation

@datlechin

Copy link
Copy Markdown
Member

The site is already ahead of the app. TableProApp/web#31 is merged and deployed, so
tablepro.app now says 29 engines. This PR is the half that makes that number true.

Merging this PR does not close the gap on its own. The shipping build is v0.68.1, where
allRegisteredTypeIds() returns 28 and Turso is absent from the New Connection picker until the
libSQL plugin is installed. The site and the app agree again at the next release, not at merge.

The guard existed and had disabled itself

docs/scripts/check-docs-against-source.py already counted database types out of
PluginMetadataRegistry*.swift and compared them against the docs. It never caught this drift for
two reasons:

counted = re.search(r"\b(\d+|Twenty-seven)\b engines", page.read_text())
if counted and counted.group(1) not in (str(len(registered)), "Twenty-seven"):

"Twenty-seven" is accepted unconditionally, so the docs could say twenty-seven forever. And the
search ran over databases/index.mdx alone, which was the one page already correct. The three wrong
numbers all sat on pages the check never opened.

That is the root cause. The numbers are the symptom. The site said 25, the docs said 27, the app
offered 28, and nothing in either repo could tell.

Turso was the reason the answer was not 28

reverseTypeIndex holds six aliases. Five of them (MariaDB, Redshift, CockroachDB, PGlite,
ScyllaDB) carry a curated entry of their own alongside the alias. Turso was the only one that did
not, and that gap was user-visible in two ways:

  • Turso was absent from the New Connection picker until the libSQL plugin was installed, and
    installing it needs a connection of that type. PluginMetadataRegistry+KafkaDefaults.swift
    already documents this exact trap for registry-only drivers.
  • Once installed, registerVariant found no curated entry and registered the libSQL plugin's
    snapshot under Turso, so the picker showed a Turso row wearing libSQL's icon and libSQL's
    tagline, "Distributed SQLite by Turso", directly under the libSQL row saying the same thing.

ScyllaDB is the precedent and it holds in both repos: an alias of Cassandra with a curated entry
all the same, and on the site a separate tile sharing the cassandra driver group.
PluginMetadataRegistry+TursoDefaults.swift gives Turso the same treatment, so 29 falls out of
the count rather than being asserted on top of it
.

Turso keeps libSQL's connection fields exactly, local-file mode included. The driver reads
libsqlMode and treats anything but local as remote, so a remote-only list would still connect,
but ConnectionStorage and ConnectionExportService derive Keychain migration and export
redaction from that list and Turso connections saved in local mode already exist in the field.
reverseTypeIndex["Turso"] = "libSQL" is untouched, so driver lookup is unchanged.

29 is the number of keys in allRegisteredTypeIds(), measured under XCTest rather than counted by
grep. 23 driver plugin targets serve those 29, because one plugin can serve several types.

Three places this went further than the brief, and why

The test counts the built-in defaults, not allRegisteredTypeIds(). Both answer 29. The
registry is a process-global singleton, SwitchDatabaseReconnectFailureTests registers a synthetic
type and withdraws it, and Swift Testing runs suites in parallel, so exact equality on the runtime
accessor is flaky by construction. A separate case asserts the runtime accessor is a superset,
which is stable and still catches a type that stops being offered.

Two of the three counts on index.mdx are deleted rather than corrected. STYLE.md 9: a number
in the source is owned by exactly one page. "Using all 27 engines" becomes "Every engine", and the
paragraph sitting directly under <DriverCounts /> no longer restates the snippet above it. Only
the frontmatter description keeps a number, because Mintlify prints it as page metadata where no
snippet can reach, and the new check verifies its arithmetic instead.

The snippet's defect was mixed units, not a wrong number. "Five drivers ship inside the app and
cover nine databases. Another 18 come from the registry" is nine engines plus eighteen plugins,
and a reader adds them to 27. The eighteen registry plugins cover twenty engines.

What the new check covers

engine counts scans every docs/**/*.mdx for a count of engines, and adds two checks for the
numbers a regex over prose cannot reach: the snippet's two halves have to add up to the registry
total, and the index.mdx frontmatter's named engines plus its and N more have to as well.
changelog.mdx is exempt; its entries state what a past release shipped.

Verification

  • Negative test: every count reverted to its pre-PR value, the script reports all five failures by
    name, including the missing Turso table row. Restored, green.
  • verify.sh docs PASS, both scripts.
  • PluginMetadataRegistryTypeCountTests (5 cases) plus DatabaseTreeCapabilityTests,
    PluginManagerVariantAccessorTests, DatabaseTypeTests, LibSQLConnectionFieldsTests,
    PluginMetadataRegistryBrandingTests, PluginMetadataRegistrySystemDatabaseTests,
    PluginMetadataSwitchRoutingTests, DriverPluginMetadataTests, PluginMetadataRegistryVariantTests,
    PluginMetadataRegistryDownloadableTests all green.
  • swiftlint lint --strict on all three Swift files, 0 violations. .swiftlint.yml only includes
    TablePro, so the test path was passed explicitly.
  • Grepped TableProTests, TableProUITests, docs/scripts, .github and scripts for any other
    assertion pinning an old engine count. The "Twenty-seven" escape hatch was the only one.

Turso lands in PluginMetadataRegistry+TursoDefaults.swift rather than in +RegistryDefaults.swift
because that file is at 1208 lines against a 1200-line SwiftLint warning, and +SurrealDBDefaults,
+KafkaDefaults and +ElasticsearchDefaults are the existing one-type-per-file precedent.

There is no turso-icon asset, so Turso reuses libsql-icon. Its tagline, name and URL scheme are
its own.

CHANGELOG

One entry under Added. This started as a docs-only change, where CLAUDE.md waives the entry, but
adding the Turso snapshot changes what the New Connection picker shows.

https://claude.ai/code/session_018HCNaxeFcFdzueFh6x33xj

@mintlify

mintlify Bot commented Aug 27, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Aug 27, 2026, 12:43 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin
datlechin merged commit 1cc3cba into main Aug 27, 2026
9 checks passed
@datlechin
datlechin deleted the docs/engine-count-source-of-truth branch August 27, 2026 12:43
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.

1 participant