8000 fix: move non-action exports out of "use server" actions.ts so the app builds by aaronjmars · Pull Request #71 · aeonfun/minitor · GitHub
[go: up one dir, main page]

Skip to content

fix: move non-action exports out of "use server" actions.ts so the app builds - #71

Merged
aaronjmars merged 1 commit into
mainfrom
fix/use-server-non-action-exports
Jun 12, 2026
Merged

aaronjmars merged 1 commit into
mainfrom
fix/use-server-non-action-exports

Conversation

@aaronjmars
Copy link
Copy Markdown
Collaborator

What

main does not build. next build fails with 62 errors, all cascading from a single root cause in app/actions.ts.

That file carries the "use server" directive, and Next/Turbopack permits a "use server" module to export only async functions. But it also exported six plain values:

  • REFRESH_INTERVAL_OPTIONS (const)
  • isAllowedRefreshInterval (sync function)
  • TAB_GROUP_MAX (const)
  • COLOR_HEX_RE (const)
  • normalizeColumnColor (sync function)
  • DECK_EXPORT_VERSION (const)

Turbopack rejects these with "Only async functions are allowed to be exported in a 'use server' file", which makes the entire module fail to load — so every importer then errors with "The module has no exports at all", taking down the whole app build.

./app/actions.ts:316:1
Only async functions are allowed to be exported in a "use server" file.
> 316 | export const TAB_GROUP_MAX = 50;
...
Error: Turbopack build failed with 62 errors

tsc doesn't enforce the "use server" export rule — only next build does — which is how this slipped onto a green-looking main.

Why

A dead production build blocks every contributor and any deploy. This is the highest-priority thing to unblock on the repo right now.

Changes

  • lib/deck-rules.ts (new): a plain (non-"use server") module holding the shared deck/column validation rules — REFRESH_INTERVAL_OPTIONS + RefreshIntervalSeconds, isAllowedRefreshInterval, TAB_GROUP_MAX, COLOR_HEX_RE, normalizeColumnColor, DECK_EXPORT_VERSION. Code and doc-comments moved verbatim — no behavior change.
  • app/actions.ts: removed those declarations; imports them back from lib/deck-rules for internal use. The file now exports only Server Actions (plus type-only exports, which "use server" permits).
  • lib/store/use-deck-store.ts: the client store now imports isAllowedRefreshInterval / normalizeColumnColor / TAB_GROUP_MAX from lib/deck-rules instead of through the "use server" boundary — it gets the real synchronous values, which is what it was always calling them as.

The existing local copies of these constants in configure-column-dialog.tsx / deck-color-dialog.tsx are left untouched to keep the diff focused on the build fix.

Verification

  • next build — ✅ compiles + generates all 7 routes
  • tsc --noEmit — ✅ clean
  • eslint — ✅ clean

Built autonomously by Aeon

…p builds

`app/actions.ts` carries `"use server"`, where Next/Turbopack allows only
async-function exports. It also exported several plain values —
`REFRESH_INTERVAL_OPTIONS`, `isAllowedRefreshInterval`, `TAB_GROUP_MAX`,
`COLOR_HEX_RE`, `normalizeColumnColor`, `DECK_EXPORT_VERSION` — which trips
"Only async functions are allowed to be exported in a 'use server' file".
That makes the whole module fail to load, cascading into 62 build errors
("The module has no exports at all") across every importer, so `next build`
fails outright. `tsc` does not enforce this rule, which is how it landed on a
green-looking main.

Hoist the shared constants + sync validators into a new plain module
`lib/deck-rules.ts`, import them back into `actions.ts` for internal use, and
point the client store at the new module. `actions.ts` now exports only Server
Actions (plus erased type-only exports, which "use server" permits).

Verified: `next build` compiles + generates all routes, `tsc --noEmit` clean,
eslint clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@aaronjmars
aaronjmars merged commit 66b2a92 into main Jun 12, 2026
1 check passed
@aaronjmars
aaronjmars deleted the fix/use-server-non-action-exports branch June 12, 2026 13:39
aaronjmars added a commit that referenced this pull request Jun 18, 2026
minitor had no CI. This adds a single Build job that runs `npm ci`
followed by `next build` on push-to-main and every pull request, with a
concurrency group that cancels superseded runs.

`next build` compiles the production bundle and runs the TypeScript
checker — the same gate that would have caught the recent build breaks
(#66, #70, #71). It needs no secrets: with DATABASE_URL unset the app
uses the bundled PGlite driver, so the build runs on forks and external
PRs too.

Lint is intentionally left out of this gate for now: `npm run lint`
currently reports pre-existing violations across the plugin files, so a
lint job would be red from day one. Worth a focused follow-up.

Co-authored-by: aaronjmars <aaronjmars@users.noreply.github.com>
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

0