Skip to content

Releases: arkstack-hq/arkstack

0.16.0

28 Jun 13:33

Choose a tag to compare

What's New

Inertia for create-arkstack

Scaffold an Inertia app on any runtime — no per-combination templates.

  • New InertiaStack step in the wizard (None / React / Vue / Svelte):
    Runtime → Lean/Full → Name → Description → Location → InertiaStack → Alpha.
    Also available as --s|stack <none|react|vue|svelte>.
  • The chosen runtime (Express or H3) is layered with Inertia automatically —
    everything ark publish --package @arkstack/inertia does, plus the wiring it
    leaves to you, with no extra prompts: adapter config, root Edge template,
    stylesheet, Vite client types, the framework client entry / vite.config.ts /
    Pages/Index.*, the required dependencies, dev:client/build:client
    scripts, the inertia() middleware (after resora()), the root route, and
    tsconfig.json (JSX for React, include: resources).
  • Fixed: dependency auto-install ran in the CLI's working directory instead
    of the new project, so node_modules never landed in the scaffold.
  • Resilience: the generated root template is normalized to guarantee the
    React @viteReactRefresh preamble and the correct client-entry extension
    (app.tsx), even when the downloaded stub predates them.

@arkstack/inertia

  • First-class client scaffolding publishable via ark publish — React, Vue,
    and Svelte stubs (client entry, vite.config.ts, Pages/Index.*,
    vite-env.d.ts), an adapter config, a styled root template, and a starter
    app.css.
  • Hydration-safe page payload: the initial page object is now emitted as a
    JSON <script> element rather than a data-page attribute.
  • appName shared on every page from config('app.name') — without
    clobbering an explicitly shared value or adding an empty key when no app config
    is loaded.

@arkstack/view

  • New @viteReactRefresh Edge tag (and viteReactRefresh() helper): emits
    the React Refresh preamble in development, nothing in production. Required with
    @vitejs/plugin-react when Edge renders the page — otherwise React throws
    "can't detect preamble." Place it immediately before @vite.

Interactive publish confirmations (@arkstack/console + @arkstack/common)

  • Packages can now drive what and how they publish via Publisher.confirm():
    prompt the user to pick an option, gate tags behind that choice, and transform
    each published stub through a callback.
  • ark publish honors --tag (bypasses the prompt, still applies the callback)
    and --no-interaction (skips prompts; gated tags stay unpublished).

Optional arkormx

  • @arkstack/common, @arkstack/console, and @arkstack/http now load without
    arkormx installed (marked an optional peer dependency) — prepare no longer
    fails in production deployments that don't use the ORM.

Templates & tooling

  • New express-inertia reference template; Express/H3 templates and tsdown
    configs updated.
  • Test harness exposes a deterministic config() global (testsSetup.ts) so
    config-dependent code is testable.

Full Changelog: 0.15.3...0.16.0

0.15.3

28 Jun 04:20

Choose a tag to compare

Edge tags: @vite, @inertia, @inertiaHead

Cleaner root templates — no more manual <script> wiring or {{{ ... }}}
interpolations for Inertia and Vite assets.

@arkstack/view@vite(...)

A first-class Vite asset tag:

@vite('resources/js/app.ts')
@vite(['resources/css/app.css', 'resources/js/app.ts'])
  • Development: emits the Vite dev-server client + module scripts.
  • Production: reads public/build/.vite/manifest.json and emits the hashed <script>/<link> tags, including a chunk's imported CSS. Throws a clear error if the manifest or an entry is missing.
  • Configurable via VITE_DEV_URL (dev server) and the exported viteTags(entries, options) helper (hot / devUrl / manifest / buildDir). Registered on every view factory.
  • Register your own tags too: view().tag(name, block, seekable, compile).

@arkstack/inertia@inertia and @inertiaHead

The root template now reads:

<head>
    @inertiaHead
    @vite('resources/js/app.ts')
</head>
<body>
    @inertia
</body>
  • @inertia — the mount element (or server-rendered markup with SSR).
  • @inertiaHead — SSR head tags (empty without SSR).
    Both fall back to empty output when absent (no stray undefined), and the published app.edge stub uses them out of the box.

Compatibility

Backward compatible: the adapter still passes inertia / inertiaHead data, so
existing templates using {{{ inertia }}} keep working.

Note: Edge tags are line-level — put @inertia, @inertiaHead, and @vite(...) each on their own line.

Full Changelog: 0.15.1...0.15.3

0.15.1

27 Jun 19:27

Choose a tag to compare

What's New

ark dev — local network & HTTPS

The development server gains two flags for testing on real devices and over
secure connections.

Highlights

  • --host expose the dev server on your local network. The dev server
    now binds 127.0.0.1 by default (local-only); --host switches it to
    0.0.0.0 and prints the detected LAN URL alongside the local one, so you can
    open the app from your phone or another machine.
  • --s|secure serves the dev server over HTTPS using an auto-generated,
    in-memory self-signed certificate (no setup; browsers show the usual
    self-signed warning).
  • Both compose with the existing --t|tunnel (Ngrok) flag.

Examples

ark dev                 # http://127.0.0.1:3000  (local only)
ark dev --host          # + Network: http://192.168.1.20:3000
ark dev --secure        # https://127.0.0.1:3000 (self-signed)
ark dev --host --secure # HTTPS, exposed on the LAN

Full Changelog: 0.15.0...0.15.1

0.15.0

27 Jun 18:29

Choose a tag to compare

What's New

@arkstack/inertia — Server-side rendering

The Inertia adapter now supports SSR, so the initial page load is fully
rendered HTML (great for first paint and crawlers) and the client hydrates it.
Subsequent Inertia visits stay client-side.

Highlights

  • SSR rendering — when ssr.enabled, the initial visit is rendered by an
    external Node SSR server (your built SSR bundle); the markup and head tags are
    embedded in the response. If the SSR server is unreachable, the adapter falls
    back to client-side rendering, so SSR can never take a request down.
  • ark inertia:ssr — a new command that runs and supervises the SSR bundle,
    restarting it if it crashes (--bundle <path>, --no-restart). Auto-discovered
    like other package commands.
  • Inertia.configure({ ... }) — override Inertia config at runtime (e.g.
    enable SSR programmatically); handy for tests and custom setups.
  • New configssr.url (render endpoint, default http://127.0.0.1:13714/render)
    and ssr.bundle (default dist-ssr/ssr.js).
  • ExportsrenderViaSsr(), superviseProcess(), resolveSsrBundle(),
    DEFAULT_SSR_URL, DEFAULT_SSR_BUNDLE, plus SsrResponse/SuperviseOptions types.

Setup

  1. Add an SSR entry (src/ssr.ts) using your client adapter's server renderer.
  2. Build it: vite build --ssr src/ssr.ts --outDir dist-ssr.
  3. Run it: ark inertia:ssr.
  4. Enable it: set ssr.enabled (or INERTIA_SSR=true) in src/config/inertia.ts.

Verified

SSR shipped with 8 unit tests (markup/head injection, fallbacks) plus a real
browser E2E (Vue 3 SSR server + hydration, no full reload). The inertia:ssr
command adds 8 more tests — real-process restart/stop/failure coverage — and a
smoke test supervising the live SSR bundle (health → crash → restart → health →
clean stop).

See the Inertia guide.

Full Changelog: 0.14.22...0.15.0

0.14.22

27 Jun 16:50

Choose a tag to compare

What's new

Custom error response bodies (@arkstack/common)

AppException (and any subclass) can now define a body property that is merged
into the serialized error payload. This lets you extend the framework's standard
error shape — { status, code, message, errors?, stack? } — with your own fields,
or override the defaults entirely.

import { AppException } from '@arkstack/common'

class PaymentException extends AppException {
    body = { error_code: 'PAYMENT_FAILED', retryable: true }
}

throw new PaymentException('Payment failed', 402)
// → { status: 'error', code: 402, message: 'Payment failed',
//     error_code: 'PAYMENT_FAILED', retryable: true }

**Full Changelog**: https://github.com/arkstack-hq/arkstack/compare/0.14.19...0.14.22

0.14.19: fix(common): fall back to the alternate build output when loading config

26 Jun 00:38

Choose a tag to compare

What's Changed

Features

  • Typed env() return values. Added an augmentable EnvRegistry interface mapping known environment variables to their coerced types, with env() (and EnvLoader.get()) inferring returns from it:
    • Known keys infer their type, env('APP_PORT')number, env('NODE_ENV')'development' | 'production' | 'test', env('MAIL_SECURE')boolean.
    • Unknown keys fall back to string; a provided default is unioned into the result.
    • An explicit value type still wins (env<boolean>('FLAG')), and applications can extend EnvRegistry via declaration merging.
    • New exported helper types: EnvRegistry, EnvKey, EnvLookup, EnvReturn.
  • Auto-generated env types. prepare/build now generates an EnvRegistry augmentation from the application's .env.example (falling back to .env) into .arkstack/ark.d.ts, mirroring config-interface generation. Each variable's type is inferred (number / boolean / string), and framework-owned keys are skipped so the generated declaration never conflicts with the curated baseline, your app-specific variables get types automatically. Exposed via BuildInterfaces.env() and the pure BuildInterfaces.envRegistryFromEnv().

Fixes

  • Environment loading is no longer import-order dependent. .env is now loaded lazily on the first env() read instead of relying on a side-effect import 'dotenv/config'. Linters/bundlers that reorder imports could previously place an env-reading module before dotenv populated process.env, leaving it with default/stale values. (dotenv is loaded with { quiet: true } and never overrides already-set variables.)
  • No duplicate export {} in generated .arkstack/ark.d.ts. The env-registry block no longer emits its own module marker; the generator ensures the combined declaration file has exactly one.

Refactor

  • EnvLoader and ConfigLoader classes. Environment and configuration handling were extracted from system.ts into dedicated EnvLoader and ConfigLoader classes (new exports, with shared envLoader / configLoader singletons). env() and config() now delegate to these instances; their call signatures and return values are unchanged.
  • Dropped now-redundant explicit generics at call sites that pass a default (NODE_ENV, TUNNEL, SESSION_LIFETIME) so they infer from EnvRegistry, and coerced appUrl's numeric port for url.port.

Internal

  • Added dotenv as a direct dependency of @arkstack/common.
  • New tests: EnvLoader coercion and the env-registry generator.

Full Changelog: 0.14.17...0.14.19

0.14.17

25 Jun 10:21

Choose a tag to compare

What's Changed

Features

  • Production module resolution. Application modules — models, route groups, and console commands — now resolve from the compiled build output (dist) in production and from TypeScript source in development. A production deploy can ship only dist (no src); the build strips the leading src/ segment (src/app/models/User.tsdist/app/models/User.js) and the framework remaps paths accordingly.
    • New @arkstack/common helpers:
      • resolveRuntimeModule(sourcePath) — resolves a source module path to an importable file (source in dev, compiled output in prod), choosing the correct extension.
      • resolveRuntimeDir(sourcePath) — directory counterpart of the above, for resolving source directories (e.g. src/routes) to their runtime location.
      • toOutputPath(sourcePath) — pure path transform mapping a source path to its build-output counterpart.
    • getModel(), console command discovery, and the Express/H3 route-group loaders now use these resolvers, fixing failures in production deploys that previously reached for src/ files at runtime.

Docs

  • New Deployment guide covering build output, NODE_ENV, output directories, and the runtime resolution helpers.

Requires NODE_ENV=production in production (the same assumption the config loader already makes).

Full Changelog: 0.14.16...0.14.17

0.14.16

25 Jun 09:47

Choose a tag to compare

What's Changed

Fixes

  • Production module resolution. The framework no longer reaches for src/ files at runtime in production. Models, console commands, and route groups now resolve from the build output (dist) when running compiled, falling back to source in development. Previously a production deploy that shipped only dist could fail to load models (getModel) and route groups because the loaders imported src/... paths directly, even though the build strips the src/ segment (src/app/models/User.tsdist/app/models/User.js).
    • New resolveRuntimeModule() / toOutputPath() helpers in @arkstack/common map a source path to its compiled counterpart and pick the right file per environment (production prefers dist, development prefers source).
    • getModel() resolves the configured model path through the new resolver.
    • discoverCommands() orders its candidate directories by environment instead of always preferring src.
    • The Express and H3 drivers resolve routes/api and routes/web route groups through the resolver instead of joining src/routes/* directly.

Note: this relies on NODE_ENV=production being set in production (the same assumption the config loader already makes).

Full Changelog: 0.14.15...0.14.16

0.14.15

25 Jun 06:07

Choose a tag to compare

What's Changed

  • Replace the --ignore flag with the global --no-interation flag KeyGenerateCommand

Full Changelog: 0.14.14...0.14.15

0.14.14

25 Jun 05:49

Choose a tag to compare

What's Changed

  • Add --ignore option to silently skip app key generation in KeyGenerateCommand

Full Changelog: 0.14.3...0.14.14