Runtime State Isolation
Use schema-dsl/runtime when a framework, worker, plugin host or multi-tenant process needs independent schema-dsl runtime state without mutating the root API.
schema-dsl/pure only avoids automatic String.prototype installation. It still uses the same global Locale, TypeRegistry, PATTERNS and default Validator state as the root API.
schema-dsl/runtime does not export a top-level s. Create a runtime first, then use runtime.s(...), runtime.s.email(), or runtime.s(...) from that isolated instance.
Quick start
createSchemaDslRuntime() and createSchemaDslAdapter() are equivalent aliases of createRuntime().
runtime.s and runtime.dsl are the same namespace object. Factories such as runtime.s.email() compile with the runtime's own type, pattern, message and validator scope.
What is isolated
Lifecycle API
Create a runtime at an app, plugin or worker lifecycle boundary. Request-level differences should be passed through validate(..., { locale, messages, messageProvider }), not by creating a new runtime per request.
Use configure(options, { mode }) for hot reload:
mergeadds new messages, types and patterns to the current runtime.replacereplaces the full runtime-local profile withoptionswhile preserving built-in pattern defaults.resetclears runtime-local messages, types, patterns and strict/type resolver state, then appliesoptions.
Use clearCache() to drop runtime-owned validator caches, getStats() to inspect message/type/pattern/cache counts, and dispose() during app shutdown, plugin unload or test teardown. dispose() is idempotent; using a disposed runtime throws [schema-dsl/runtime] Runtime has been disposed.
Per-call validation options follow the root helper conventions. Use { coerce: false }, { smartCoerce: false }, or { coerceTypes: false } when a runtime validation call must reject numeric or boolean strings instead of using schema-dsl smart coercion.
TypeScript hints
runtime.s.email(), runtime.s('string'), runtime.dsl('string'), and runtime.compileField('string') return the same chainable builder shape as the normal namespace path, so built-in chain methods keep their existing TypeScript hints.
For custom runtime DSL types, pass types, dynamicTypes or typeResolver to createRuntime(). For custom namespace factories, call runtime.registerExtension({ literal, factoryName, schema }). For custom chain methods, keep using TypeScript module augmentation for the builder interface and provide the runtime method implementation in your extension code.
Message provider contract
messageProvider receives:
The provider covers standard validation message tables, custom keywords, conditional validation, async custom validator fallback messages and runtime-created I18nError instances. Explicit messages still have priority over provider fallbacks.
When not to use it
Use schema-dsl/pure for the recommended public authoring path when you only need to avoid prototype mutation and do not need runtime-state isolation. Use the root schema-dsl entry only for compatibility code that intentionally keeps automatic String-chain installation.
Corresponding sample file
Example entry: runtime-isolation.ts
Description: Covers isolated createRuntime() state, runtime-scoped s factories, custom runtime extensions, message providers, cache lifecycle and validation behavior.