@kelphect/sdk-solidstart
@kelphect/sdk-solidstart 0.1.0 is the server-only SolidStart v2 integration for the shared @kelphect/sdk-native LNW/1 client. It adds Vite/runtime guards, request and response streaming, server-function helpers, lifecycle ownership, and redacted diagnostics. It does not encode frames, open sockets, or provide a JSON/S3 fallback.
Support matrix
| Build or deployment | Status |
|---|---|
| Built server on Node 22+ | supported |
| Built server on Bun 1.4+ | supported |
Nitro node_server / node_cluster | supported |
Nitro bun | supported |
| SolidStart v2 build/dev toolchain | Node 24+ currently required |
| Cloudflare, Netlify, edge, static, browser, unknown Nitro preset | refused before application modules load |
The package is source-shipped and test-qualified; pin @kelphect/sdk-native 0.1.0 alongside the adapter and verify the server commit. Edge targets remain refused until an authenticated binary streaming transport is qualified there.
Install and guard the build
npm install @kelphect/[email protected] @kelphect/[email protected]Only the root package is safe in universal Vite configuration. Put the guard next to SolidStart and Nitro, and make the declared preset match the resolved preset:
import { solidStart } from "@solidjs/start/config";
import { nitro } from "nitro/vite";
import { defineConfig } from "vite";
import { lockwellSolidStart } from "@kelphect/sdk-solidstart";
export default defineConfig({
plugins: [
solidStart(),
lockwellSolidStart({
solidStartVersion: "2.0.4",
deployment: { target: "nitro", preset: "node_server" },
}),
nitro(),
],
nitro: { preset: "node_server" },
});The guard rejects provider edge plugins, static builds, mismatched Nitro declarations, and unsupported runtime floors with LOCKWELL_SOLIDSTART_UNSUPPORTED_RUNTIME. There is no catch-and-fallback path.
Server-only client and routes
Import runtime helpers from @kelphect/sdk-solidstart/server (or /node and /bun) in *.server.ts modules. That entry carries SolidStart's server-only marker and resolves to a throwing denial module under the browser condition.
import env from "env:server/runtime";
import { createNodeLockwellSolidStartClient } from "@kelphect/sdk-solidstart/node";
export const lockwell = createNodeLockwellSolidStartClient({
instanceName: "web",
lifecycle: import.meta.env.DEV ? "development" : "production",
host: env.LOCKWELL_NATIVE_HOST ?? "localhost",
port: Number(env.LOCKWELL_NATIVE_PORT ?? "9444"),
tls: { ca: env.LOCKWELL_NATIVE_CA, serverName: "lockwell.internal" },
credentials: () => ({
accessKeyId: env.LOCKWELL_ACCESS_KEY_ID!,
secretKey: env.LOCKWELL_SECRET_KEY!,
}),
pool: { min: 0, max: 16, acquireTimeoutMs: 10_000, idleTimeoutMs: 30_000 },
retry: { maxAttempts: 3, baseDelayMs: 50, maxDelayMs: 2_000 },
requestTimeoutMs: 30_000,
});The public server surface includes bindLockwellRequest, createObjectRouteHandlers, getObjectResponse, headObjectResponse, putObjectResponse, uploadPartResponse, runLockwellServerFunction, runCurrentLockwellServerFunction, and runLockwellAction. Object routes preserve ReadableStream<Uint8Array> backpressure, canonical Content-Length, a single explicit byte range, request disconnect cancellation, validated traceparent, and bounded idempotency keys. Keep streamed bodies in API routes; server-function values are serialized.
The process-local lifecycle single-flights setup, survives development HMR while refreshing credential and telemetry providers, and closes once during production disposal. Changing non-secret configuration under the same instanceName fails with a stable collision error instead of reusing the wrong pool. Metrics, tracing, retry, logger, pool, TLS, host, port, and requestTimeoutMs are forwarded to the shared client rather than implemented a second time.
Security and errors
TLS hostname validation stays enabled; provide a private CA and set serverName to the certificate identity. Browser, static, edge, Cloudflare, Netlify, and unknown Nitro targets are denied. Error responses are bounded, no-store DTOs with stable native error codes; stacks, credentials, filesystem paths, and payloads are not reflected. Health and metrics are aggregate and should be protected by the deployment's operational policy.
The adapter inherits LNW upload admission (default process-wide 128), per-stream idle/duration bounds, flow control, Object Lock, ordered user metadata, checksums, ranges, multipart, tags, CORS, notifications, and signed capabilities from the shared client. SSE-C and ADMIN are absent. Choose S3 explicitly for SSE-C; never switch transports in an exception handler.
Example and evidence
The runnable external application is examples/solidstart-native:
src/routes/api/objects/[...path].tshandles GET, HEAD, range GET, and PUT streams.src/routes/api/multipart/[uploadId]/[partNumber]/[...path].tshandles streamed parts.src/actions.tsdemonstrates list, copy, version, multipart, retention, and legal-hold server actions.
Adapter tests cover runtime/preset denial, configuration, single-flight/HMR lifecycle, rotation, interrupted streams, ranges, size bounds, malformed errors, packed NodeNext consumers, browser denial, and secret/native-code scans. Oracle ARM64 Node/Bun live TLS and external SolidStart builds passed. The representative lifecycle benchmark (Node LNW 54.3 vs S3 77.2 MiB/s; Bun LNW 71.2 vs S3 126.6 MiB/s) is a bounded process-local sample, not a storage, durability, latency-SLO, or production-throughput claim. Local Windows Bun returned UNAVAILABLE for the stalled-handshake stress shape and is not part of the current qualification evidence.
Run the adapter checks from sdk/solidstart:
npm run test:node
npm run test:bun
npm run test:distributionRead the complete SolidStart contract for migration/rollback and the exact evidence ledger. The merged Next.js adapter has its own framework guide; Nuxt remains open source-owner work and is not claimed here. Rust is an explicit first-party SDK non-goal.